diff options
| author | Gangzheng Tong <tonggangzheng@gmail.com> | 2025-05-30 17:16:59 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-31 00:16:59 +0000 |
| commit | da5cf478c6be06c9e6c20917a7d472cbdcb624e3 (patch) | |
| tree | 7be790c85547c86b92fff80fa9340c89d71a167e /source | |
| parent | 3ca27faa23a92124f26875a6f00bcfc3a1c6431e (diff) | |
Add check for the variable requirement (#6677)
* Add check for the variable requirement
This change adds the capability check for the variables requirement.
With this check, the shader
```
[require(cpp_cuda_glsl_hlsl_metal_spirv)]
Buffer<float> InputTyped;
[require(cpp_cuda_glsl_hlsl_metal_spirv)]
RWBuffer<float> OutputTyped;
```
will issue error if targeting to WSGL
e.g. `.\build\Debug\bin\slangc .\tests\wgsl_no_buffer.slang -o
wgsl_no_buffer.txt -target wgsl -entry Main -stage compute`
.\tests\wgsl_no_buffer.slang(2): error 36108: 'InputTyped' has dependencies that are not compatible on the required target 'wgsl'.
Buffer<float> InputTyped;
^~~~~~~~~~
.\tests\wgsl_no_buffer.slang(4): error 36108: 'OutputTyped' has dependencies that are not compatible on the required target 'wgsl'.
RWBuffer<float> OutputTyped;
^~~~~~~~~~~
Fixes #6304
* Add var capability tests
* Do capability checks for global var only
* Add inferredCapabilityRequirements to var capability check
* Add requirement to the intrinsic types Buffer/RWBuffer
* format code
* Update capabliity test
* use DefaultDataLayout as default data layout
* Use visitMemberExpr to check the capabilities
* Update the cap tests to match the error messages
* update test to use the ScalarDataLayout for hlsl target
* Update tests check condition to use error number only
* Add default push_constant data layout type
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 7 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ast-type.h | 7 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 45 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 1 |
7 files changed, 53 insertions, 19 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index ad1a983dd..86cb84d6e 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -30,6 +30,12 @@ struct DefaultDataLayout : IBufferDataLayout {}; /// @category misc_types +__intrinsic_type($(kIROp_Std430BufferLayoutType)) +__magic_type(DefaultPushConstantDataLayoutType) +struct DefaultPushConstantDataLayout : IBufferDataLayout +{}; + +/// @category misc_types __intrinsic_type($(kIROp_Std140BufferLayoutType)) [require(spirv)] [require(glsl)] @@ -503,6 +509,7 @@ struct __ShapeCube : __ITextureShape /// @category misc_types __magic_type(TextureShapeBufferType) __intrinsic_type($(kIROp_TextureShapeBufferType)) +[require(cpp_cuda_glsl_hlsl_metal_spirv)] struct __ShapeBuffer : __ITextureShape { static const int flavor = $(SLANG_TEXTURE_BUFFER); diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp index 893d5e6d7..d3e99ee4b 100644 --- a/source/slang/slang-ast-builder.cpp +++ b/source/slang/slang-ast-builder.cpp @@ -289,6 +289,12 @@ Type* ASTBuilder::getDefaultLayoutType() { return getSpecializedBuiltinType({}, "DefaultDataLayoutType"); } + +Type* ASTBuilder::getDefaultPushConstantLayoutType() +{ + return getSpecializedBuiltinType({}, "DefaultPushConstantDataLayoutType"); +} + Type* ASTBuilder::getStd140LayoutType() { return getSpecializedBuiltinType({}, "Std140DataLayoutType"); diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h index a25fcea28..5990f90f1 100644 --- a/source/slang/slang-ast-builder.h +++ b/source/slang/slang-ast-builder.h @@ -486,6 +486,7 @@ public: Type* getSpecializedBuiltinType(ArrayView<Val*> genericArgs, const char* magicTypeName); Type* getDefaultLayoutType(); + Type* getDefaultPushConstantLayoutType(); Type* getStd140LayoutType(); Type* getStd430LayoutType(); Type* getScalarLayoutType(); diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h index 1b82fc63a..2d1a592da 100644 --- a/source/slang/slang-ast-type.h +++ b/source/slang/slang-ast-type.h @@ -134,6 +134,13 @@ class DefaultDataLayoutType : public DataLayoutType }; FIDDLE() +class DefaultPushConstantDataLayoutType : public DataLayoutType +{ + FIDDLE(...) +}; + + +FIDDLE() class Std430DataLayoutType : public DataLayoutType { FIDDLE(...) diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index cc65edd2f..081ccbb0b 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -720,6 +720,13 @@ struct SemanticsDeclReferenceVisitor : public SemanticsDeclVisitorBase, // Pass down the callee location processDeclModifiers(expr->declRef.getDecl(), expr->loc); } + + void visitMemberExpr(MemberExpr* expr) + { + dispatchIfNotNull(expr->baseExpression); + visitDeclRefExpr(expr); + } + void visitStaticMemberExpr(StaticMemberExpr* expr) { dispatchIfNotNull(expr->declRef.declRefBase); @@ -2009,7 +2016,7 @@ void SemanticsDeclHeaderVisitor::checkPushConstantBufferType(VarDeclBase* varDec { varDecl->type.type = getConstantBufferType( cbufferType->getElementType(), - m_astBuilder->getStd430LayoutType()); + m_astBuilder->getDefaultPushConstantLayoutType()); } } else if (isGlobalShaderParameter(varDecl)) @@ -2017,8 +2024,9 @@ void SemanticsDeclHeaderVisitor::checkPushConstantBufferType(VarDeclBase* varDec // If this is a global variable with [vk::push_constant] attribute, // we need to make sure to wrap it in a `ConstantBuffer`. // - varDecl->type.type = - getConstantBufferType(varDecl->type, m_astBuilder->getStd430LayoutType()); + varDecl->type.type = getConstantBufferType( + varDecl->type, + m_astBuilder->getDefaultPushConstantLayoutType()); } } } @@ -13660,8 +13668,12 @@ CapabilitySet SemanticsDeclCapabilityVisitor::getDeclaredCapabilitySet(Decl* dec // For every existing target, we want to join their requirements together. // If the the parent defines additional targets, we want to add them to the disjunction set. // For example: - // [require(glsl)] struct Parent { [require(glsl, glsl_ext_1)] [require(spirv)] void - // foo(); } + // [require(glsl)] + // struct Parent { + // [require(glsl, glsl_ext_1)] + // [require(spirv)] + // void foo(); + // } // The requirement for `foo` should be glsl+glsl_ext_1 | spirv. // CapabilitySet declaredCaps; @@ -14197,19 +14209,18 @@ void SemanticsDeclCapabilityVisitor::diagnoseUndeclaredCapability( } } - //// The second scenario is when the callee is using a capability that is not provided by - /// the - /// requirement. / For example: / [require(hlsl,b,c)] / void caller() / { / - /// useD(); - ///// require capability (hlsl,d) / } / In this case we should report that useD() is - /// using a - /// capability that is not declared by caller. - //// - - //// If we reach here, we are case 2. + // The second scenario is when the callee is using a capability that is not provided by the + // requirement. For example: + // [require(hlsl,b,c)] + // void caller() + // { + // useD(); // requires capability (hlsl,d) + // } + // In this case we should report that useD() is using a capability that is not declared by + // caller. If we reach here, we are case 2. We will produce all failed atoms. This is important + // since provenance of multiple atoms can come from multiple referenced items in a function + // body. - // We will produce all failed atoms. This is important since provenance of multiple atoms - // can come from multiple referenced items in a function body. HashSet<Decl*> printedDecls; auto simplifiedFailedAtomsSet = failedAtomsInsideAvailableSet.newSetWithoutImpliedAtoms(); for (auto i : simplifiedFailedAtomsSet) diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 9eb8c1391..439959827 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4976,8 +4976,9 @@ static DeclBase* ParseDeclWithModifiers( }; if (AdvanceIf(parser, "buffer")) { - decl = as<Decl>( - parseGLSLShaderStorageBufferDecl(parser, getLayoutArg("Std430DataLayout"))); + decl = as<Decl>(parseGLSLShaderStorageBufferDecl( + parser, + getLayoutArg("DefaultDataLayout"))); break; } else if (auto mod = findPotentialGLSLInterfaceBlockModifier(parser, modifiers)) diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 6ac3ba079..2c72b61de 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -1570,6 +1570,7 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules( case ASTNodeType::DefaultDataLayoutType: case ASTNodeType::Std140DataLayoutType: return &kStd140LayoutRulesImpl_; + case ASTNodeType::DefaultPushConstantDataLayoutType: case ASTNodeType::Std430DataLayoutType: return &kStd430LayoutRulesImpl_; case ASTNodeType::ScalarDataLayoutType: |
