From a1827ee5e9b8088b23db3fa688b7bd62b7bbe9ac Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 23 Feb 2024 19:05:23 -0800 Subject: SPIRV Fixes. (#3622) * Use SpvSourceLanguageSlang enum. * Fix spirv entrypoint interface. * Cleanup. * Add error on unknown spirv opcode. * Fix CI. * Fix. --- .github/github_test.sh | 43 +++++++++++++++++++++++++++ .github/workflows/linux-arm64.yml | 2 +- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 1 + github_test.sh | 42 -------------------------- source/slang/core.meta.slang | 2 +- source/slang/slang-emit-spirv.cpp | 35 +++++++++------------- source/slang/slang-parser.cpp | 17 +++++++++++ tests/spirv/multi-entry-point-input-var.slang | 13 ++++++++ tests/spirv/unknown-opcode.slang | 16 ++++++++++ 11 files changed, 108 insertions(+), 67 deletions(-) create mode 100644 .github/github_test.sh delete mode 100644 github_test.sh create mode 100644 tests/spirv/multi-entry-point-input-var.slang create mode 100644 tests/spirv/unknown-opcode.slang diff --git a/.github/github_test.sh b/.github/github_test.sh new file mode 100644 index 000000000..ec6586114 --- /dev/null +++ b/.github/github_test.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + + +PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]') +ARCHITECTURE=$(uname -m) + +# Darwin is actually macosx (for paths etc) +if [ "${PLATFORM}" == "darwin" ]; then + PLATFORM="macosx" + + # Modern OSX is only 64 bit, so assume that + if [ "${ARCHITECTURE}" == "i386" ]; then + ARCHITECTURE="x64" + fi +fi + +if [ "${ARCHITECTURE}" == "x86_64" ]; then + ARCHITECTURE="x64" +fi + +# CONFIGURATION=release or debug +if [ "${CC}" == "gcc" ] && [ "${CONFIGURATION}" == "release" ] && [ "${ARCHITECTURE}" == "x64" ] +then + SLANG_TEST_CATEGORY=full +else + SLANG_TEST_CATEGORY=smoke +fi + +TARGET=${PLATFORM}-${ARCHITECTURE} + +OUTPUTDIR=bin/${TARGET}/${CONFIGURATION}/ + +if [ "${ARCHITECTURE}" == "x64" -a "${PLATFORM}" != "macosx" ]; then + unzip vk_swiftshader_linux_x64.zip -d $OUTPUTDIR +fi + +SLANG_TEST=${OUTPUTDIR}slang-test + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OUTPUTDIR +export PATH=$PATH:${OUTPUTDIR} +export SLANG_RUN_SPIRV_VALIDATION=1 +export SLANG_USE_SPV_SOURCE_LANGUAGE_UNKNOWN=1 +${SLANG_TEST} -bindir ${OUTPUTDIR} -travis -category ${SLANG_TEST_CATEGORY} ${SLANG_TEST_FLAGS} -api all-vk -expected-failure-list tests/expected-failure-github.txt diff --git a/.github/workflows/linux-arm64.yml b/.github/workflows/linux-arm64.yml index 0c18ffe6b..a35672c5f 100644 --- a/.github/workflows/linux-arm64.yml +++ b/.github/workflows/linux-arm64.yml @@ -56,4 +56,4 @@ jobs: CC=${{matrix.compiler}} ARCH=${{matrix.platform}} PATH="${PATH:+${PATH}:}$(pwd)/external/slang-binaries/spirv-tools/$(uname -m)-linux/bin" - source ./github_test.sh + source .github/github_test.sh diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 427823f6b..8180965f9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -72,4 +72,4 @@ jobs: CC=${{matrix.compiler}} ARCH=${{matrix.platform}} PATH="${PATH:+${PATH}:}$(pwd)/external/slang-binaries/spirv-tools/$(uname -m)-linux/bin" - source ./github_test.sh + source .github/github_test.sh diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 11d54a247..30a3fe003 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -69,4 +69,4 @@ jobs: CONFIGURATION=${{matrix.configuration}} CC=${{matrix.compiler}} ARCH=${{matrix.targetPlatform}} - source ./github_test.sh + source .github/github_test.sh diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 91843d4dd..3dc4abfb5 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -68,6 +68,7 @@ jobs: $spirvToolsBinDir = ".\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\"; $env:Path += ";$slangTestBinDir;$spirvToolsBinDir"; $env:SLANG_RUN_SPIRV_VALIDATION='1'; + $env:SLANG_USE_SPV_SOURCE_LANGUAGE_UNKNOWN='1'; Expand-Archive "vk_swiftshader_windows_${{matrix.testPlatform}}.zip" -DestinationPath $slangTestBinDir; & "$slangTestBinDir\slang-test.exe" -api all-dx12 -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} -expected-failure-list tests/expected-failure-github.txt 2>&1; diff --git a/github_test.sh b/github_test.sh deleted file mode 100644 index a970454d0..000000000 --- a/github_test.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - - -PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]') -ARCHITECTURE=$(uname -m) - -# Darwin is actually macosx (for paths etc) -if [ "${PLATFORM}" == "darwin" ]; then - PLATFORM="macosx" - - # Modern OSX is only 64 bit, so assume that - if [ "${ARCHITECTURE}" == "i386" ]; then - ARCHITECTURE="x64" - fi -fi - -if [ "${ARCHITECTURE}" == "x86_64" ]; then - ARCHITECTURE="x64" -fi - -# CONFIGURATION=release or debug -if [ "${CC}" == "gcc" ] && [ "${CONFIGURATION}" == "release" ] && [ "${ARCHITECTURE}" == "x64" ] -then - SLANG_TEST_CATEGORY=full -else - SLANG_TEST_CATEGORY=smoke -fi - -TARGET=${PLATFORM}-${ARCHITECTURE} - -OUTPUTDIR=bin/${TARGET}/${CONFIGURATION}/ - -if [ "${ARCHITECTURE}" == "x64" -a "${PLATFORM}" != "macosx" ]; then - unzip vk_swiftshader_linux_x64.zip -d $OUTPUTDIR -fi - -SLANG_TEST=${OUTPUTDIR}slang-test - -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OUTPUTDIR -export PATH=$PATH:${OUTPUTDIR} -export SLANG_RUN_SPIRV_VALIDATION=1 -${SLANG_TEST} -bindir ${OUTPUTDIR} -travis -category ${SLANG_TEST_CATEGORY} ${SLANG_TEST_FLAGS} -api all-vk -expected-failure-list tests/expected-failure-github.txt diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index b02a44c5c..3131224b1 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -624,7 +624,7 @@ ${{{{ case BaseType::Float: case BaseType::Double: }}}} - [TreatAsDifferentiable] + [Differentiable] static $(kBaseTypes[tt].name) getPi() { return $(kBaseTypes[tt].name)(3.14159265358979323846264338328); } __intrinsic_op($(kIROp_Less)) bool lessThan(This other); diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index b9e868b89..5761d3ec4 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -2816,18 +2816,6 @@ struct SPIRVEmitContext case kIROp_EntryPointDecoration: { auto section = getSection(SpvLogicalSectionID::EntryPoints); - - // TODO: The `OpEntryPoint` is required to list an varying - // input or output parameters (by ``) used by the entry point, - // although these are encoded as global variables in the IR. - // - // Currently we have a pass that moves entry-point varying - // parameters to global scope for the benefit of GLSL output, - // but we do not maintain a connection between those parameters - // and the original entry point. That pass should be updated - // to attach a decoration linking the original entry point - // to the new globals, which would be used in the SPIR-V emit case. - auto entryPointDecor = cast(decoration); auto entryPoint = as(decoration->getParent()); auto spvStage = mapStageToExecutionModel(entryPointDecor->getProfile().getStage()); @@ -2842,6 +2830,7 @@ struct SPIRVEmitContext { case kIROp_GlobalVar: case kIROp_GlobalParam: + case kIROp_SPIRVAsmOperandBuiltinVar: { SpvInst* spvGlobalInst; if (m_mapIRInstToSpvInst.tryGetValue(globalInst, spvGlobalInst)) @@ -2861,13 +2850,6 @@ struct SPIRVEmitContext break; } } - // Add remaining builtin variables that does not have a corresponding IR global var/param. - // These variables could be added from SPIRV ASM blocks. - for (auto builtinVar : m_builtinGlobalVars) - { - if (paramsSet.add(builtinVar.second)) - params.add(builtinVar.second); - } emitOpEntryPoint( section, decoration, @@ -3283,6 +3265,7 @@ struct SPIRVEmitContext } Dictionary m_builtinGlobalVars; + SpvInst* getBuiltinGlobalVar(IRType* type, SpvBuiltIn builtinVal) { SpvInst* result = nullptr; @@ -5273,9 +5256,19 @@ SlangResult emitSPIRVFromIR( } // Emit source language info. + // By default we will use SpvSourceLanguageSlang. + // However this will cause problems when using swiftshader. + // To workaround this problem, we allow overriding this behavior with an + // environment variable that will be set in the software testing environment. + auto sourceLanguage = SpvSourceLanguageSlang; + StringBuilder noSlangEnv; + PlatformUtil::getEnvironmentVariable(toSlice("SLANG_USE_SPV_SOURCE_LANGUAGE_UNKNOWN"), noSlangEnv); + if (noSlangEnv.produceString() == "1") + { + sourceLanguage = SpvSourceLanguageUnknown; + } context.emitInst(context.getSection(SpvLogicalSectionID::DebugStringsAndSource), nullptr, SpvOpSource, - // TODO: update this to SpvSourceLanguageSlang when a new release of spirv-tools is available. - SpvLiteralInteger::from32(0), // language identifier, should be SpvSourceLanguageSlang. + SpvLiteralInteger::from32(sourceLanguage), // language identifier, should be SpvSourceLanguageSlang. SpvLiteralInteger::from32(1)); // language version. for (auto irEntryPoint : irEntryPoints) diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index f2aff32ea..7ce710469 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7221,6 +7221,23 @@ namespace Slang break; } } + + if (ret.opcode.flavor == SPIRVAsmOperand::Flavor::NamedValue + && ret.opcode.knownValue == SpvOp(0xffffffff)) + { + if (ret.opcode.token.type == TokenType::IntegerLiteral) + { + Int intVal = -1; + StringUtil::parseInt(ret.opcode.token.getContent(), intVal); + ret.opcode.knownValue = (SpvWord)intVal; + } + else + { + parser->diagnose(ret.opcode.token, Diagnostics::unrecognizedSPIRVOpcode, ret.opcode.token); + return std::nullopt; + } + } + return ret; } diff --git a/tests/spirv/multi-entry-point-input-var.slang b/tests/spirv/multi-entry-point-input-var.slang new file mode 100644 index 000000000..9475f268f --- /dev/null +++ b/tests/spirv/multi-entry-point-input-var.slang @@ -0,0 +1,13 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv -fvk-use-entrypoint-name -emit-spirv-directly + +// CHECK: OpEntryPoint + +[shader("vertex")] +float4 vmain(uint vertex_id : SV_VertexID) : SV_Position { + return float4(vertex_id, 0, 0, 1); +} + +[shader("pixel")] +float4 pmain(float4 position : SV_Position) : SV_Target { + return position; +} \ No newline at end of file diff --git a/tests/spirv/unknown-opcode.slang b/tests/spirv/unknown-opcode.slang new file mode 100644 index 000000000..4358a5cd4 --- /dev/null +++ b/tests/spirv/unknown-opcode.slang @@ -0,0 +1,16 @@ + +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -stage compute -entry main -target spirv -emit-spirv-directly + +void main() +{ + spirv_asm + { + // CHECK: ([[#@LINE+1]]): error + unknownOpCode + }; + spirv_asm + { + // CHECK-NOT: ([[#@LINE+1]]): error + 5 + }; +} -- cgit v1.2.3