diff options
| author | Yong He <yonghe@outlook.com> | 2024-02-12 13:19:35 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-12 13:19:35 -0800 |
| commit | 0c15582efcec6c7b163ae3a20c04e1aee958d24a (patch) | |
| tree | dcc3ed41eb993cf5202cc4d995383cd14cbba9f7 | |
| parent | 4f7d1f44a4b2a5eab2e2dec1edf3a156da78aae3 (diff) | |
Fix lowering of static consts in a generic function. (#3573)
* Fix lowering of static consts in a generic function.
* Fix.
* Fix.
* Fix lowering of shading rate builtin.
| -rw-r--r-- | source/slang/slang-ir-glsl-legalize.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 69 | ||||
| -rw-r--r-- | tests/language-feature/generics/generic-static-const.slang | 41 |
3 files changed, 84 insertions, 35 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index dd165769c..0f9e88d20 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -929,7 +929,14 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( } else if (semanticName == "sv_shadingrate") { - name = "gl_PrimitiveShadingRateEXT"; + if (kind == LayoutResourceKind::VaryingInput) + { + name = "gl_ShadingRateEXT"; + } + else + { + name = "gl_PrimitiveShadingRateEXT"; + } } if( name ) diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index f5d743bb1..8fef6f535 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -724,6 +724,31 @@ LoweredValInfo emitDeclRef( DeclRef<Decl> declRef, IRType* type); + +bool isFunctionVarDecl(VarDeclBase* decl) +{ + // The immediate parent of a function-scope variable + // declaration will be a `ScopeDecl`. + // + // TODO: right now the parent links for scopes are *not* + // set correctly, so we can't just scan up and look + // for a function in the parent chain... + auto parent = decl->parentDecl; + if (as<ScopeDecl>(parent)) + { + return true; + } + return false; +} + +bool isFunctionStaticVarDecl(VarDeclBase* decl) +{ + // Only a variable marked `static` can be static. + if (!decl->findModifier<HLSLStaticModifier>()) + return false; + return isFunctionVarDecl(decl); +} + IRInst* getSimpleVal(IRGenContext* context, LoweredValInfo lowered); int32_t getIntrinsicOp( @@ -7439,25 +7464,22 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> NestedContext nested(this); auto subBuilder = nested.getBuilder(); auto subContext = nested.getContext(); - IRGeneric* outerGeneric = emitOuterGenerics(subContext, decl, decl); - // TODO(JS): Is this right? - // - // If we *are* in a generic, then outputting this in the (current) generic scope would be correct. - // If we *aren't* we want to go the level above for insertion - // - // Just inserting into the parent doesn't work with a generic that holds a function that has a static const - // variable. - // + IRGeneric* outerGeneric = nullptr; + + // If we are static, then we need to insert the declaration before the parent. // This tries to match the behavior of previous `lowerFunctionStaticConstVarDecl` functionality - if (!outerGeneric && isFunctionStaticVarDecl(decl)) + if (isFunctionStaticVarDecl(decl)) { // We need to insert the constant at a level above // the function being emitted. This will usually // be the global scope, but it might be an outer // generic if we are lowering a generic function. - - subBuilder->setInsertInto(subBuilder->getFunc()->getParent()); + subBuilder->setInsertBefore(subBuilder->getFunc()); + } + else if (!isFunctionVarDecl(decl)) + { + outerGeneric = emitOuterGenerics(subContext, decl, decl); } auto initExpr = decl->initExpr; @@ -7613,27 +7635,6 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> return globalVal; } - bool isFunctionStaticVarDecl(VarDeclBase* decl) - { - // Only a variable marked `static` can be static. - if(!decl->findModifier<HLSLStaticModifier>()) - return false; - - // The immediate parent of a function-scope variable - // declaration will be a `ScopeDecl`. - // - // TODO: right now the parent links for scopes are *not* - // set correctly, so we can't just scan up and look - // for a function in the parent chain... - auto parent = decl->parentDecl; - if( as<ScopeDecl>(parent) ) - { - return true; - } - - return false; - } - struct NestedContext { IRGenEnv subEnvStorage; @@ -9782,7 +9783,7 @@ bool canDeclLowerToAGeneric(Decl* decl) { if (varDecl->hasModifier<HLSLStaticModifier>() && varDecl->hasModifier<ConstModifier>()) { - return true; + return !isFunctionVarDecl(varDecl); } } diff --git a/tests/language-feature/generics/generic-static-const.slang b/tests/language-feature/generics/generic-static-const.slang new file mode 100644 index 000000000..57c82a687 --- /dev/null +++ b/tests/language-feature/generics/generic-static-const.slang @@ -0,0 +1,41 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -d3d12 -shaderobj -output-using-type -use-dxil +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj -output-using-type + +//TEST_INPUT:set outputBuffer = out ubuffer(data=[0 0 0 0], stride=4) +RWStructuredBuffer<uint> outputBuffer; + +interface ITestB +{ + static void eval<let N : uint>(uint val[N], out uint res[N]); +}; + +struct TestB : ITestB +{ + static void eval<let N : uint>(uint val[N], out uint res[N]) + { + static const uint scale = 3 * N; + for (uint i = 0; i < N; i++) + res[i] = scale * val[i]; + } +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 threadID: SV_DispatchThreadID) +{ + const uint i = threadID.x; + + uint val[4] = { i, i + 1, i + 2, i + 3 }; + uint res[4]; + + TestB test; + test.eval<4>(val, res); + + // CHECK: 0 + outputBuffer[0] = res[0]; + // CHECK: 12 + outputBuffer[1] = res[1]; + // CHECK: 24 + outputBuffer[2] = res[2]; + // CHECK: 36 + outputBuffer[3] = res[3]; +}
\ No newline at end of file |
