diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-17 09:27:34 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-17 09:27:34 -0700 |
| commit | fdab35e93082d6da4f9dbb4b6ec7b4c6dbce831c (patch) | |
| tree | 489534f470b3d2dcbb61660458bf473e0a2c0552 | |
| parent | eecb6c56da5792010e88f2a0d6d1503244b081a4 (diff) | |
| parent | 15aba2fe81fea44969e036e181a4cf252ff41963 (diff) | |
Merge pull request #106 from tfoleyNV/varying-integer
Handle `flat` interpolation cases in cross compilation
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 5 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 99 | ||||
| -rw-r--r-- | tests/cross-compile/integer-input.slang | 11 | ||||
| -rw-r--r-- | tests/cross-compile/integer-input.slang.glsl | 26 | ||||
| -rw-r--r-- | tests/cross-compile/nointerpolation-input.slang | 11 | ||||
| -rw-r--r-- | tests/cross-compile/nointerpolation-input.slang.glsl | 26 | ||||
| -rw-r--r-- | tools/slang-test/main.cpp | 78 |
8 files changed, 255 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore index 2e654c7bb..9267cfca3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ intermediate/ *.expected.png *.actual.png tests/render/*.expected +tests/cross-compile/*.expected # files generated by other shader compilers *.spv diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 88b80589a..7ffce2acd 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2667,11 +2667,12 @@ struct EmitVisitor else if(auto mod_##TYPE = mod.As<TYPE>()) Emit(#KEYWORD " ") #define CASE2(TYPE, HLSL_NAME, GLSL_NAME) \ - else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? GLSL_NAME : HLSL_NAME) + else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? (#GLSL_NAME " ") : (#HLSL_NAME " ")) CASE(RowMajorLayoutModifier, row_major); CASE(ColumnMajorLayoutModifier, column_major); - CASE(HLSLNoInterpolationModifier, nointerpolation); + + CASE2(HLSLNoInterpolationModifier, nointerpolation, flat); CASE(HLSLPreciseModifier, precise); CASE(HLSLEffectSharedModifier, shared); CASE(HLSLGroupSharedModifier, groupshared); diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index caa1ab075..856da9b6c 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -7,6 +7,19 @@ namespace Slang { +struct CloneVisitor + : ModifierVisitor<CloneVisitor, RefPtr<Modifier>> +{ +#define ABSTRACT_SYNTAX_CLASS(NAME, BASE) /* empty */ +#define SYNTAX_CLASS(NAME, BASE, ...) \ + RefPtr<NAME> visit ## NAME(NAME* obj) { return new NAME(*obj); } + +#include "object-meta-begin.h" +#include "modifier-defs.h" +#include "object-meta-end.h" + +}; + // template<typename V> @@ -2244,11 +2257,40 @@ struct LoweringVisitor IntVal* elementCount; }; + struct VaryingParameterVarChain + { + VaryingParameterVarChain* next = nullptr; + VarDeclBase* varDecl; + }; + + template<typename T> + T* findModifier(VaryingParameterVarChain* chain) + { + for (auto c = chain; c; c = c->next) + { + auto v = c->varDecl; + if (auto mod = v->FindModifier<T>()) + return mod; + } + return nullptr; + } + + RefPtr<Modifier> cloneModifier(Modifier* modifier) + { + if (!modifier) return nullptr; + + // For now we just do a shallow copy of the modifier + + CloneVisitor visitor; + return visitor.dispatch(modifier); + } + struct VaryingParameterInfo { String name; VaryingParameterDirection direction; VaryingParameterArraySpec* arraySpecs = nullptr; + VaryingParameterVarChain* varChain = nullptr; }; RefPtr<ExpressionSyntaxNode> createGLSLBuiltinRef( @@ -2259,6 +2301,33 @@ struct LoweringVisitor return globalVarRef; } + bool isIntegralType( + ExpressionType* type) + { + if (auto baseType = type->As<BasicExpressionType>()) + { + switch (baseType->BaseType) + { + default: + return false; + + case BaseType::Int: + case BaseType::UInt: + case BaseType::UInt64: + return true; + } + } + else if (auto vecType = type->As<VectorExpressionType>()) + { + return isIntegralType(vecType->elementType); + } + else if (auto matType = type->As<MatrixExpressionType>()) + { + return isIntegralType(matType->getElementType()); + } + + return false; + } void lowerSimpleShaderParameterToGLSLGlobal( VaryingParameterInfo const& info, @@ -2449,6 +2518,26 @@ struct LoweringVisitor break; } + // We want to copy certain modifiers from the declaration as given, + // over to the newly created global variable. The most important + // of these is any interpolation-mode modifier. + // + // Note that a shader parameter could have been nested inside + // a `struct` type, so we will look for interpolation modifiers + // starting on the "deepest" field, and working out way out. + + // Look for interpolation mode modifier + if (auto interpolationModeModifier = findModifier<InterpolationModeModifier>(info.varChain)) + { + addModifier(globalVarDecl, cloneModifier(interpolationModeModifier)); + } + // Otherwise, check if we need to add one: + else if (isIntegralType(varType)) + { + auto mod = new HLSLNoInterpolationModifier(); + addModifier(globalVarDecl, mod); + } + RefPtr<VarExpressionSyntaxNode> globalVarRef = new VarExpressionSyntaxNode(); globalVarRef->Position = globalVarDecl->Position; @@ -2554,8 +2643,13 @@ struct LoweringVisitor fieldExpr->declRef = fieldDeclRef; fieldExpr->BaseExpression = varExpr; + VaryingParameterVarChain fieldVarChain; + fieldVarChain.next = info.varChain; + fieldVarChain.varDecl = fieldDeclRef.getDecl(); + VaryingParameterInfo fieldInfo = info; fieldInfo.name = info.name + "_" + fieldDeclRef.GetName(); + fieldInfo.varChain = &fieldVarChain; // Need to find the layout for the given field... Decl* originalFieldDecl = nullptr; @@ -2598,9 +2692,14 @@ struct LoweringVisitor expr->declRef = declRef; expr->Type.type = GetType(declRef); + VaryingParameterVarChain varChain; + varChain.next = nullptr; + varChain.varDecl = localVarDecl; + VaryingParameterInfo info; info.name = name; info.direction = direction; + info.varChain = &varChain; // Ensure that we don't get name collisions on `inout` variables switch (direction) diff --git a/tests/cross-compile/integer-input.slang b/tests/cross-compile/integer-input.slang new file mode 100644 index 000000000..2069091c6 --- /dev/null +++ b/tests/cross-compile/integer-input.slang @@ -0,0 +1,11 @@ +//TEST:CROSS_COMPILE: -profile ps_5_0 -entry main -target spirv-assembly + +struct VS_OUT +{ + uint drawID : DRAW_ID; +}; + +float4 main(VS_OUT vsOut) : SV_Target +{ + return float4(float(vsOut.drawID)); +} diff --git a/tests/cross-compile/integer-input.slang.glsl b/tests/cross-compile/integer-input.slang.glsl new file mode 100644 index 000000000..ce6998a9a --- /dev/null +++ b/tests/cross-compile/integer-input.slang.glsl @@ -0,0 +1,26 @@ +//TEST_IGNORE_FILE: + +struct VS_OUT +{ + uint drawID; +}; + +in flat uint SLANG_in_vsOut_drawID; + +out vec4 SLANG_out_main_result; + +vec4 main_(VS_OUT vsOut) +{ + return vec4(float(vsOut.drawID)); +} + +void main() +{ + VS_OUT vsOut; + vsOut.drawID = SLANG_in_vsOut_drawID; + + vec4 main_result; + main_result = main_(vsOut); + + SLANG_out_main_result = main_result; +} diff --git a/tests/cross-compile/nointerpolation-input.slang b/tests/cross-compile/nointerpolation-input.slang new file mode 100644 index 000000000..c215f380a --- /dev/null +++ b/tests/cross-compile/nointerpolation-input.slang @@ -0,0 +1,11 @@ +//TEST:CROSS_COMPILE: -profile ps_5_0 -entry main -target spirv-assembly + +struct VS_OUT +{ + nointerpolation float drawID : DRAW_ID; +}; + +float4 main(VS_OUT vsOut) : SV_Target +{ + return float4(vsOut.drawID); +} diff --git a/tests/cross-compile/nointerpolation-input.slang.glsl b/tests/cross-compile/nointerpolation-input.slang.glsl new file mode 100644 index 000000000..279590fa5 --- /dev/null +++ b/tests/cross-compile/nointerpolation-input.slang.glsl @@ -0,0 +1,26 @@ +//TEST_IGNORE_FILE: + +struct VS_OUT +{ + float drawID; +}; + +in flat float SLANG_in_vsOut_drawID; + +out vec4 SLANG_out_main_result; + +vec4 main_(VS_OUT vsOut) +{ + return vec4(vsOut.drawID); +} + +void main() +{ + VS_OUT vsOut; + vsOut.drawID = SLANG_in_vsOut_drawID; + + vec4 main_result; + main_result = main_(vsOut); + + SLANG_out_main_result = main_result; +} diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index 2bca2f78d..6b7da5844 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -671,6 +671,83 @@ TestResult runSimpleTest(TestInput& input) return result; } +TestResult runCrossCompilerTest(TestInput& input) +{ + // need to execute the stand-alone Slang compiler on the file + // then on the same file + `.glsl` and compare output + + auto filePath = input.filePath; + auto outputStem = input.outputStem; + + OSProcessSpawner actualSpawner; + OSProcessSpawner expectedSpawner; + + actualSpawner.pushExecutablePath(String(options.binDir) + "slangc.exe"); + expectedSpawner.pushExecutablePath(String(options.binDir) + "slangc.exe"); + + actualSpawner.pushArgument(filePath); + expectedSpawner.pushArgument(filePath + ".glsl"); + + for( auto arg : input.testOptions->args ) + { + actualSpawner.pushArgument(arg); + expectedSpawner.pushArgument(arg); + } + expectedSpawner.pushArgument("-no-checking"); + + if (spawnAndWait(outputStem, expectedSpawner) != kOSError_None) + { + return kTestResult_Fail; + } + + String expectedOutput = getOutput(expectedSpawner); + String expectedOutputPath = outputStem + ".expected"; + try + { + Slang::File::WriteAllText(expectedOutputPath, expectedOutput); + } + catch (Slang::IOException) + { + return kTestResult_Fail; + } + + if (spawnAndWait(outputStem, actualSpawner) != kOSError_None) + { + return kTestResult_Fail; + } + String actualOutput = getOutput(actualSpawner); + + TestResult result = kTestResult_Pass; + + // Otherwise we compare to the expected output + if (actualOutput != expectedOutput) + { + result = kTestResult_Fail; + } + + // If the test failed, then we write the actual output to a file + // so that we can easily diff it from the command line and + // diagnose the problem. + if (result == kTestResult_Fail) + { + String actualOutputPath = outputStem + ".actual"; + Slang::File::WriteAllText(actualOutputPath, actualOutput); + + if (options.outputMode == kOutputMode_AppVeyor) + { + fprintf(stderr, "ERROR:\n" + "EXPECTED{{{\n%s}}}\n" + "ACTUAL{{{\n%s}}}\n", + expectedOutput.Buffer(), + actualOutput.Buffer()); + fflush(stderr); + } + } + + return result; +} + + #ifdef SLANG_TEST_SUPPORT_HLSL TestResult generateHLSLBaseline(TestInput& input) { @@ -1076,6 +1153,7 @@ TestResult runTest( { "COMPARE_HLSL_CROSS_COMPILE_RENDER", &runHLSLCrossCompileRenderComparisonTest}, { "COMPARE_HLSL_GLSL_RENDER", &runHLSLAndGLSLComparisonTest }, { "COMPARE_GLSL", &runGLSLComparisonTest }, + { "CROSS_COMPILE", &runCrossCompilerTest }, { nullptr, nullptr }, }; |
