diff options
| -rw-r--r-- | source/slang/glsl.meta.slang | 30 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 28 | ||||
| -rw-r--r-- | source/slang/slang-capabilities.capdef | 32 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 98 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-stdlib-textures.cpp | 2 | ||||
| -rw-r--r-- | tests/glsl-intrinsic/intrinsic-texture.slang | 24 | ||||
| -rw-r--r-- | tests/language-feature/capability/capability6.slang | 13 |
9 files changed, 145 insertions, 85 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang index ae6fbd67c..0078d39cb 100644 --- a/source/slang/glsl.meta.slang +++ b/source/slang/glsl.meta.slang @@ -1870,7 +1870,7 @@ public ivec3 textureSize(Sampler2DMSArray<vector<T,N>,sampleCount> sampler) __generic<T, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylod)] +[require(glsl_hlsl_metal_spirv, texture_querylod)] public vec2 textureQueryLod(__TextureImpl< T, __Shape1D, @@ -1903,7 +1903,7 @@ public vec2 textureQueryLod(__TextureImpl< __generic<T, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylod)] +[require(glsl_hlsl_metal_spirv, texture_querylod)] public vec2 textureQueryLod(__TextureImpl< T, Shape, @@ -1940,7 +1940,7 @@ public vec2 textureQueryLod(__TextureImpl< __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(Sampler1D<vector<T,N>> sampler) { int width; @@ -1951,7 +1951,7 @@ public int textureQueryLevels(Sampler1D<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(Sampler2D<vector<T,N>> sampler) { vector<int,2> dim; @@ -1962,7 +1962,7 @@ public int textureQueryLevels(Sampler2D<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(Sampler3D<vector<T,N>> sampler) { vector<int,3> dim; @@ -1973,7 +1973,7 @@ public int textureQueryLevels(Sampler3D<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(SamplerCube<vector<T,N>> sampler) { vector<int,2> dim; @@ -1984,7 +1984,7 @@ public int textureQueryLevels(SamplerCube<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(Sampler1DArray<vector<T,N>> sampler) { vector<int,2> dim; @@ -1995,7 +1995,7 @@ public int textureQueryLevels(Sampler1DArray<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(Sampler2DArray<vector<T,N>> sampler) { vector<int,3> dim; @@ -2006,7 +2006,7 @@ public int textureQueryLevels(Sampler2DArray<vector<T,N>> sampler) __generic<T:__BuiltinArithmeticType, let N:int> [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(SamplerCubeArray<vector<T,N>> sampler) { vector<int,3> dim; @@ -2016,7 +2016,7 @@ public int textureQueryLevels(SamplerCubeArray<vector<T,N>> sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(sampler1DShadow sampler) { int dim; @@ -2026,7 +2026,7 @@ public int textureQueryLevels(sampler1DShadow sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(sampler2DShadow sampler) { vector<int,2> dim; @@ -2036,7 +2036,7 @@ public int textureQueryLevels(sampler2DShadow sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(samplerCubeShadow sampler) { vector<int,2> dim; @@ -2046,7 +2046,7 @@ public int textureQueryLevels(samplerCubeShadow sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(sampler1DArrayShadow sampler) { vector<int,2> dim; @@ -2056,7 +2056,7 @@ public int textureQueryLevels(sampler1DArrayShadow sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(sampler2DArrayShadow sampler) { vector<int,3> dim; @@ -2066,7 +2066,7 @@ public int textureQueryLevels(sampler2DArrayShadow sampler) } [ForceInline] -[require(cpp_cuda_glsl_hlsl_spirv, texture_querylevels)] +[require(cpp_glsl_hlsl_metal_spirv, texture_querylevels)] public int textureQueryLevels(samplerCubeArrayShadow sampler) { vector<int,3> dim; diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index f50c63367..d83059b00 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -2901,7 +2901,6 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form [__readNone] [ForceInline] - [require(hlsl, texture_sm_4_1)] T Load(vector<int, Shape.dimensions+isArray> location, vector<int, Shape.dimensions+isArray> offset, out uint status) { __target_switch @@ -3124,7 +3123,6 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form [__readNone] [ForceInline] - [require(hlsl, texture_sm_4_1_compute_fragment)] T Load(vector<int, Shape.dimensions+isArray> location, int sampleIndex, vector<int, Shape.dimensions+isArray> offset, out uint status) { __target_switch @@ -3292,11 +3290,7 @@ ${{{{ if (shape == kStdlibShapeIndex3D && isArray == 1) continue; const char* textureTypeName = isCombined ? "Sampler" : "Texture"; - - StringBuilder requireStringBuilder; - auto requireString = requireStringBuilder.toString(); }}}} -$(requireString) typealias $(accessPrefix[access])$(textureTypeName)$(shapeTypeNames[shape])$(msPostFix[isMS])$(arrayPostFix[isArray])<T=float4, let sampleCount:int=0, let format:int=0> = __TextureImpl<T, __Shape$(shapeTypeNames[shape]), $(isArray), $(isMS), sampleCount, $(access), 0, $(isCombined), format>; ${{{{ } @@ -14117,7 +14111,7 @@ vector<T, N> WaveActive$(opName.hlslName)(vector<T, N> expr) } __generic<T : __BuiltinIntegerType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_arithmetic)] +[require(cuda_glsl_hlsl_spirv, subgroup_arithmetic)] matrix<T, N, M> WaveActive$(opName.hlslName)(matrix<T, N, M> expr) { __target_switch @@ -14189,7 +14183,7 @@ vector<T, N> WaveActive$(opName)(vector<T, N> expr) } __generic<T : __BuiltinArithmeticType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_arithmetic)] +[require(cuda_glsl_hlsl_spirv, subgroup_arithmetic)] matrix<T, N, M> WaveActive$(opName)(matrix<T, N, M> expr) { __target_switch @@ -14283,7 +14277,7 @@ vector<T,N> WaveActive$(opName.hlslName)(vector<T,N> expr) } __generic<T : __BuiltinArithmeticType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_arithmetic)] +[require(cuda_glsl_hlsl_spirv, subgroup_arithmetic)] matrix<T, N, M> WaveActive$(opName.hlslName)(matrix<T, N, M> expr) { __target_switch @@ -14600,7 +14594,7 @@ vector<T,N> WavePrefixProduct(vector<T,N> expr) } __generic<T : __BuiltinArithmeticType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_arithmetic)] +[require(cuda_glsl_hlsl_spirv, subgroup_arithmetic)] matrix<T, N, M> WavePrefixProduct(matrix<T, N, M> expr) { __target_switch @@ -14676,7 +14670,7 @@ vector<T,N> WavePrefixSum(vector<T,N> expr) } __generic<T : __BuiltinArithmeticType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_arithmetic)] +[require(cuda_glsl_hlsl_spirv, subgroup_arithmetic)] matrix<T,N,M> WavePrefixSum(matrix<T,N,M> expr) { __target_switch @@ -14732,7 +14726,7 @@ vector<T,N> WaveReadLaneFirst(vector<T,N> expr) } __generic<T : __BuiltinType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_ballot)] +[require(cuda_glsl_hlsl_spirv, subgroup_ballot)] matrix<T,N,M> WaveReadLaneFirst(matrix<T,N,M> expr) { __target_switch @@ -14796,7 +14790,7 @@ vector<T,N> WaveBroadcastLaneAt(vector<T,N> value, constexpr int lane) } __generic<T : __BuiltinType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_ballot)] +[require(cuda_glsl_hlsl_spirv, subgroup_ballot)] matrix<T, N, M> WaveBroadcastLaneAt(matrix<T, N, M> value, constexpr int lane) { __target_switch @@ -14857,7 +14851,7 @@ vector<T,N> WaveReadLaneAt(vector<T,N> value, int lane) } __generic<T : __BuiltinType, let N : int, let M : int> -[require(cuda_hlsl, subgroup_shuffle)] +[require(cuda_glsl_hlsl_spirv, subgroup_shuffle)] matrix<T, N, M> WaveReadLaneAt(matrix<T, N, M> value, int lane) { __target_switch @@ -15023,7 +15017,7 @@ uint4 WaveMatch(vector<T,N> value) } __generic<T : __BuiltinType, let N : int, let M : int> -[require(cuda_glsl_hlsl, subgroup_partitioned)] +[require(cuda_glsl_hlsl_spirv, subgroup_partitioned)] uint4 WaveMatch(matrix<T,N,M> value) { __target_switch @@ -16243,7 +16237,7 @@ void SetMeshOutputCounts(uint vertexCount, uint primitiveCount) // This function cannot be inlined due to a legalization pass happening mid-way through processing // and later more processing happening to the function which requires eventual inlining. [KnownBuiltin("DispatchMesh")] -[require(glsl_hlsl_spirv, meshshading)] +[require(glsl_hlsl_metal_spirv, meshshading)] [noRefInline] void DispatchMesh<P>(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ, __ref P meshPayload) { @@ -18533,7 +18527,7 @@ struct HitObject /// Returns the attributes of a hit. Valid if the hit object represents a hit or a miss. [ForceInline] - [require(glsl_spirv, ser_raygen_closesthit_miss)] + [require(glsl_hlsl_spirv, ser_raygen_closesthit_miss)] attr_t GetAttributes<attr_t>() { __target_switch diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef index 1511c3a08..140346163 100644 --- a/source/slang/slang-capabilities.capdef +++ b/source/slang/slang-capabilities.capdef @@ -401,7 +401,7 @@ alias rayquery = GL_EXT_ray_query | _sm_6_3; alias raytracing_motionblur = raytracing + motionblur | cuda; alias ser_motion = ser + motionblur; alias shaderclock = GL_EXT_shader_realtime_clock | hlsl_nvapi | cpp | cuda; -alias meshshading_internal = GL_EXT_mesh_shader | _sm_6_5; +alias meshshading_internal = GL_EXT_mesh_shader | _sm_6_5 | metal; alias meshshading = amplification_mesh + meshshading_internal; alias fragmentshaderinterlock = _GL_ARB_fragment_shader_interlock | hlsl_nvapi | spvFragmentShaderPixelInterlockEXT; alias atomic64 = GL_EXT_shader_atomic_int64 | _sm_6_6 | cpp | cuda; @@ -447,7 +447,7 @@ alias sm_4_0_version = _sm_4_0 ; alias sm_4_0 = sm_4_0_version | SPV_GOOGLE_user_type + spvMinLod - | GL_ARB_sparse_texture_clamp + GL_EXT_samplerless_texture_functions + GL_EXT_texture_query_lod + GL_EXT_texture_shadow_lod + GL_EXT_debug_printf + | GL_ARB_sparse_texture_clamp + GL_EXT_samplerless_texture_functions + GL_EXT_texture_query_lod + GL_EXT_texture_shadow_lod + GL_EXT_debug_printf + GL_ARB_shader_image_size ; alias sm_4_1_version = _sm_4_1 @@ -458,6 +458,7 @@ alias sm_4_1_version = _sm_4_1 | cpp ; alias sm_4_1 = sm_4_1_version + | GL_ARB_texture_gather + GL_ARB_texture_query_levels + GL_ARB_shader_texture_image_samples // previous | sm_4_0 ; @@ -737,6 +738,9 @@ alias consumestructuredbuffer = sm_5_0_version; alias fragmentprocessing = fragment + _sm_5_0 | fragment + glsl_spirv | raytracingstages_compute_amplification_mesh + GL_NV_compute_shader_derivatives + | fragment + metal + | fragment + cpp + | fragment + cuda ; alias fragmentprocessing_derivativecontrol = fragment + _sm_5_0 | fragment + GL_ARB_derivative_control @@ -758,15 +762,15 @@ alias texture_sm_4_1_samplerless = texture_sm_4_1 // supposedly works on only limited stages, support all stages for now alias texture_sm_4_1_compute_fragment = texture_sm_4_1; alias texture_sm_4_0_fragment = texture_sm_4_0; -alias texture_sm_4_1_clamp_fragment = texture_sm_4_0_fragment + GL_ARB_sparse_texture_clamp; +alias texture_sm_4_1_clamp_fragment = texture_sm_4_0_fragment | GL_ARB_sparse_texture_clamp; alias texture_sm_4_1_vertex_fragment_geometry = texture_sm_4_1; -alias texture_gather = texture_sm_4_1_vertex_fragment_geometry + GL_ARB_texture_gather; -alias image_samples = texture_sm_4_1_compute_fragment + GL_ARB_shader_texture_image_samples; -alias image_size = texture_sm_4_1_compute_fragment + GL_ARB_shader_image_size; -alias texture_size = texture_sm_4_1 + GL_ARB_shader_image_size; -alias texture_querylod = texture_sm_4_1 + GL_EXT_texture_query_lod; -alias texture_querylevels = texture_sm_4_1 + GL_ARB_texture_query_levels; -alias texture_shadowlod = texture_sm_4_1 + GL_EXT_texture_shadow_lod +alias texture_gather = texture_sm_4_1_vertex_fragment_geometry | GL_ARB_texture_gather; +alias image_samples = texture_sm_4_1_compute_fragment | GL_ARB_shader_texture_image_samples; +alias image_size = texture_sm_4_1_compute_fragment | GL_ARB_shader_image_size; +alias texture_size = texture_sm_4_1 | GL_ARB_shader_image_size; +alias texture_querylod = texture_sm_4_1 | GL_EXT_texture_query_lod; +alias texture_querylevels = texture_sm_4_1 | GL_ARB_texture_query_levels; +alias texture_shadowlod = texture_sm_4_1 | GL_EXT_texture_shadow_lod | texture_sm_4_1; alias atomic_glsl_float1 = GL_EXT_shader_atomic_float; @@ -803,19 +807,19 @@ alias subgroup_basic_ballot = glsl + GL_KHR_shader_subgroup_basic + subgroup_bal alias subgroup_vote = GL_KHR_shader_subgroup_vote | _sm_6_0 | _cuda_sm_7_0; alias shaderinvocationgroup = subgroup_vote; alias subgroup_arithmetic = GL_KHR_shader_subgroup_arithmetic | _sm_6_0 | _cuda_sm_7_0; -alias subgroup_shuffle = glsl + GL_KHR_shader_subgroup_shuffle | _sm_6_0 | _cuda_sm_7_0; +alias subgroup_shuffle = GL_KHR_shader_subgroup_shuffle | _sm_6_0 | _cuda_sm_7_0; alias subgroup_shufflerelative = GL_KHR_shader_subgroup_shuffle_relative | _sm_6_0 | _cuda_sm_7_0; alias subgroup_clustered = GL_KHR_shader_subgroup_clustered | _sm_6_0 | _cuda_sm_7_0; alias subgroup_quad = GL_KHR_shader_subgroup_quad | _sm_6_0 | _cuda_sm_7_0; -alias subgroup_partitioned = GL_NV_shader_subgroup_partitioned + subgroup_ballot_activemask | _sm_6_5; +alias subgroup_partitioned = GL_NV_shader_subgroup_partitioned + subgroup_ballot_activemask | _sm_6_5 | _cuda_sm_7_0; alias atomic_glsl_hlsl_nvapi_cuda_float1 = atomic_glsl_float1 | hlsl_nvapi + _sm_4_0 | _cuda_sm_2_0; alias atomic_glsl_hlsl_nvapi_cuda5_int64 = atomic_glsl_int64 | hlsl_nvapi + _sm_4_0 | _cuda_sm_6_0; alias atomic_glsl_hlsl_nvapi_cuda6_int64 = atomic_glsl_int64 | hlsl_nvapi + _sm_4_0 | _cuda_sm_6_0; alias atomic_glsl_hlsl_nvapi_cuda9_int64 = atomic_glsl_int64 | hlsl_nvapi + _sm_4_0 | _cuda_sm_9_0; -alias atomic_glsl_hlsl_cuda = atomic_glsl | _sm_5_0 | _cuda_sm_2_0; -alias atomic_glsl_hlsl_cuda9_int64 = atomic_glsl_int64 | _sm_6_6 | _cuda_sm_9_0; +alias atomic_glsl_hlsl_cuda = atomic_glsl | _sm_5_0 | _cuda_sm_2_0 | metal; +alias atomic_glsl_hlsl_cuda9_int64 = atomic_glsl_int64 | _sm_6_6 | _cuda_sm_9_0 | metal; alias helper_lane = _sm_6_0 + fragment | GL_EXT_demote_to_helper_invocation + fragment diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 74d08f8e5..c3074bc55 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -10095,6 +10095,11 @@ namespace Slang } } + static void _propagateSeeDefinitionOf(SemanticsVisitor* visitor, Decl* funcDecl, DiagnosticCategory diagnosticCategory) + { + maybeDiagnose(visitor->getSink(), visitor->getOptionSet(), diagnosticCategory, funcDecl, Diagnostics::seeDefinitionOf, funcDecl); + } + static void _propagateRequirement(SemanticsVisitor* visitor, CapabilitySet& resultCaps, SyntaxNode* userNode, SyntaxNode* referencedNode, const CapabilitySet& nodeCaps, SourceLoc referenceLoc) { auto referencedDecl = as<Decl>(referencedNode); @@ -10178,20 +10183,22 @@ namespace Slang CapabilitySet getStatementCapabilityUsage(SemanticsVisitor* visitor, Stmt* stmt); - template<typename ProcessFunc> + template<typename ProcessFunc, typename ParentDiagnosticFunc> struct CapabilityDeclReferenceVisitor - : public SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc>> + : public SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc, ParentDiagnosticFunc>> { - typedef SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc>> Base; + typedef SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc, ParentDiagnosticFunc>> Base; - const ProcessFunc& handleReferenceFunc; + const ProcessFunc handleProcessFunc; + const ParentDiagnosticFunc handleParentDiagnosticFunc; RequireCapabilityAttribute* maybeRequireCapability; SemanticsContext& outerContext; - CapabilityDeclReferenceVisitor(const ProcessFunc& processFunc, RequireCapabilityAttribute* maybeRequireCapability, SemanticsContext& outer) - : handleReferenceFunc(processFunc) + CapabilityDeclReferenceVisitor(const ProcessFunc& processFunc, const ParentDiagnosticFunc& parentDiagnosticFunc, RequireCapabilityAttribute* maybeRequireCapability, SemanticsContext& outer) + : handleProcessFunc(processFunc) + , handleParentDiagnosticFunc(parentDiagnosticFunc) , maybeRequireCapability(maybeRequireCapability) , outerContext(outer) - , SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc>>(outer) + , SemanticsDeclReferenceVisitor<CapabilityDeclReferenceVisitor<ProcessFunc, ParentDiagnosticFunc>>(outer) { } virtual void processReferencedDecl(Decl* decl) override @@ -10199,16 +10206,16 @@ namespace Slang SourceLoc loc = SourceLoc(); if (Base::sourceLocStack.getCount()) loc = Base::sourceLocStack.getLast(); - handleReferenceFunc(decl, decl->inferredCapabilityRequirements, loc); + handleProcessFunc(decl, decl->inferredCapabilityRequirements, loc); } virtual void processDeclModifiers(Decl* decl) override { if (decl) - handleReferenceFunc(decl, decl->inferredCapabilityRequirements, decl->loc); + handleProcessFunc(decl, decl->inferredCapabilityRequirements, decl->loc); } void visitDiscardStmt(DiscardStmt* stmt) { - handleReferenceFunc(stmt, CapabilitySet(CapabilityName::fragment), stmt->loc); + handleProcessFunc(stmt, CapabilitySet(CapabilityName::fragment), stmt->loc); } void visitTargetSwitchStmt(TargetSwitchStmt* stmt) { @@ -10247,6 +10254,19 @@ namespace Slang else { targetCap = CapabilitySet(CapabilityName(stmt->targetCases[targetCaseIndex]->capability)); + + if (maybeRequireCapability) + { + CapabilitySet testingForInvalid = maybeRequireCapability->capabilitySet; + // Ensure case statement is valid with parent `[require(...)]` + testingForInvalid.join(targetCap); + if (testingForInvalid.isInvalid()) + { + maybeDiagnose(Base::getSink(), outerContext.getOptionSet(), DiagnosticCategory::Capability, stmt->targetCases[targetCaseIndex]->loc, + Diagnostics::conflictingCapabilityDueToStatement, targetCap, maybeRequireCapability, maybeRequireCapability->capabilitySet); + handleParentDiagnosticFunc(DiagnosticCategory::Capability); + } + } } auto targetCase = stmt->targetCases[targetCaseIndex]; auto oldCap = targetCap; @@ -10255,22 +10275,23 @@ namespace Slang if (targetCap.isInvalid()) { maybeDiagnose(Base::getSink(), outerContext.getOptionSet(), DiagnosticCategory::Capability, targetCase->body->loc, Diagnostics::conflictingCapabilityDueToStatement, bodyCap, "target_switch", oldCap); + handleParentDiagnosticFunc(DiagnosticCategory::Capability); } set.unionWith(targetCap); } - handleReferenceFunc(stmt, set, stmt->loc); + handleProcessFunc(stmt, set, stmt->loc); } void visitRequireCapabilityDecl(RequireCapabilityDecl* decl) { - handleReferenceFunc(decl, decl->inferredCapabilityRequirements, decl->loc); + handleProcessFunc(decl, decl->inferredCapabilityRequirements, decl->loc); } }; - template<typename ProcessFunc> - void visitReferencedDecls(SemanticsContext& context, NodeBase* node, SourceLoc initialLoc, RequireCapabilityAttribute* maybeRequireCapability, const ProcessFunc& func) + template<typename ProcessFunc, typename ParentDiagnosticFunc> + void visitReferencedDecls(SemanticsContext& context, NodeBase* node, SourceLoc initialLoc, RequireCapabilityAttribute* maybeRequireCapability, const ProcessFunc& processFunc, const ParentDiagnosticFunc& parentDiagnosticFunc) { - CapabilityDeclReferenceVisitor<ProcessFunc> visitor(func, maybeRequireCapability, context); + CapabilityDeclReferenceVisitor<ProcessFunc, ParentDiagnosticFunc> visitor(processFunc, parentDiagnosticFunc, maybeRequireCapability, context); visitor.sourceLocStack.add(initialLoc); if (auto val = as<Val>(node)) @@ -10289,19 +10310,31 @@ namespace Slang return CapabilitySet(); CapabilitySet inferredRequirements; - visitReferencedDecls(*visitor, stmt, stmt->loc, nullptr, [&](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) - { - _propagateRequirement(visitor, inferredRequirements, stmt, node, nodeCaps, refLoc); - }); + visitReferencedDecls(*visitor, stmt, stmt->loc, nullptr, + [&](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) + { + _propagateRequirement(visitor, inferredRequirements, stmt, node, nodeCaps, refLoc); + }, + [](DiagnosticCategory category) + { + SLANG_UNUSED(category); + } + ); return inferredRequirements; } void SemanticsDeclCapabilityVisitor::checkVarDeclCommon(VarDeclBase* varDecl) { - visitReferencedDecls(*this, varDecl->type.type, varDecl->loc, varDecl->findModifier<RequireCapabilityAttribute>(), [this, varDecl](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) - { - _propagateRequirement(this, varDecl->inferredCapabilityRequirements, varDecl, node, nodeCaps, refLoc); - }); + visitReferencedDecls(*this, varDecl->type.type, varDecl->loc, varDecl->findModifier<RequireCapabilityAttribute>(), + [this, varDecl](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) + { + _propagateRequirement(this, varDecl->inferredCapabilityRequirements, varDecl, node, nodeCaps, refLoc); + }, + [this, varDecl](DiagnosticCategory category) + { + _propagateSeeDefinitionOf(this, varDecl, category); + } + ); } CapabilitySet SemanticsDeclCapabilityVisitor::getDeclaredCapabilitySet(Decl* decl) @@ -10351,8 +10384,8 @@ namespace Slang decl->inferredCapabilityRequirements = getDeclaredCapabilitySet(decl); } - template<typename ProcessFunc> - static inline void _dispatchCapabilitiesVisitorOfFunctionDecl(SemanticsVisitor* visitor, FunctionDeclBase* funcDecl, ProcessFunc propegateFuncForReferences) + template<typename ProcessFunc, typename ParentDiagnosticFunc> + static inline void _dispatchCapabilitiesVisitorOfFunctionDecl(SemanticsVisitor* visitor, FunctionDeclBase* funcDecl, const ProcessFunc& processFunc, const ParentDiagnosticFunc& parentDiagnosticFunc) { visitor->setParentFuncOfVisitor(funcDecl); @@ -10362,7 +10395,7 @@ namespace Slang _propagateRequirement(visitor, funcDecl->inferredCapabilityRequirements, funcDecl, member, member->inferredCapabilityRequirements, member->loc); } - visitReferencedDecls(*visitor, funcDecl->body, funcDecl->loc, funcDecl->findModifier<RequireCapabilityAttribute>(), propegateFuncForReferences); + visitReferencedDecls(*visitor, funcDecl->body, funcDecl->loc, funcDecl->findModifier<RequireCapabilityAttribute>(), processFunc, parentDiagnosticFunc); if (!isEffectivelyStatic(funcDecl)) { @@ -10378,10 +10411,15 @@ namespace Slang void SemanticsDeclCapabilityVisitor::visitFunctionDeclBase(FunctionDeclBase* funcDecl) { _dispatchCapabilitiesVisitorOfFunctionDecl(this, funcDecl, - [this, funcDecl](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) - { - _propagateRequirement(this, funcDecl->inferredCapabilityRequirements, funcDecl, node, nodeCaps, refLoc); - }); + [this, funcDecl](SyntaxNode* node, const CapabilitySet& nodeCaps, SourceLoc refLoc) + { + _propagateRequirement(this, funcDecl->inferredCapabilityRequirements, funcDecl, node, nodeCaps, refLoc); + }, + [this, funcDecl](DiagnosticCategory category) + { + _propagateSeeDefinitionOf(this, funcDecl, category); + } + ); auto declaredCaps = getDeclaredCapabilitySet(funcDecl); diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 7721fedbf..e91d2e45b 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -932,6 +932,8 @@ namespace Slang } } requireCapAttr->capabilitySet = CapabilitySet(capabilityNames); + if (requireCapAttr->capabilitySet.isInvalid()) + maybeDiagnose(getSink(), this->getOptionSet(), DiagnosticCategory::Capability, attr, Diagnostics::unexpectedCapability, attr, CapabilityName::Invalid); } else if (auto requirePreludeAttr = as<RequirePreludeAttribute>(attr)) { diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index cb994b904..496fb7e32 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -391,6 +391,7 @@ DIAGNOSTIC(36107, Error, entryPointUsesUnavailableCapability, "entrypoint '$0' r DIAGNOSTIC(36108, Error, declHasDependenciesNotCompatibleOnTarget, "'$0' has dependencies that are not compatible on the required target '$1'.") DIAGNOSTIC(36109, Error, invalidTargetSwitchCase, "'$0' cannot be used as a target_switch case.") DIAGNOSTIC(36110, Error, stageIsInCompatibleWithCapabilityDefinition, "'$0' is defined for stage '$1', which is incompatible with the declared capability set '$2'.") +DIAGNOSTIC(36111, Error, unexpectedCapability, "'$0' resolves into a disallowed `$1` Capability.") // Attributes DIAGNOSTIC(31000, Warning, unknownAttributeName, "unknown attribute '$0'") diff --git a/source/slang/slang-stdlib-textures.cpp b/source/slang/slang-stdlib-textures.cpp index 380ed1677..dd4df7d9c 100644 --- a/source/slang/slang-stdlib-textures.cpp +++ b/source/slang/slang-stdlib-textures.cpp @@ -453,7 +453,7 @@ void TextureTypeInfo::writeGetDimensionFunctions() sb << " __glsl_version(450)\n"; sb << " __glsl_extension(GL_EXT_samplerless_texture_functions)\n"; - sb << " [require(glsl_hlsl_metal_spirv, texture_sm_4_1)]\n"; + sb << " [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1)]\n"; writeFunc( "void", "GetDimensions", diff --git a/tests/glsl-intrinsic/intrinsic-texture.slang b/tests/glsl-intrinsic/intrinsic-texture.slang index 3b80b2d26..c40390c57 100644 --- a/tests/glsl-intrinsic/intrinsic-texture.slang +++ b/tests/glsl-intrinsic/intrinsic-texture.slang @@ -1,13 +1,13 @@ //TEST:SIMPLE(filecheck=HLSL): -allow-glsl -stage compute -entry computeMain -target hlsl -DHLSL //TEST:SIMPLE(filecheck=HLSL): -allow-glsl -stage fragment -entry fragMain -target hlsl -DHLSL -//TEST:SIMPLE(filecheck=GLSL): -allow-glsl -stage compute -entry computeMain -target glsl -//TEST:SIMPLE(filecheck=GLSL): -allow-glsl -stage fragment -entry fragMain -target glsl -//TEST:SIMPLE(filecheck=SPIR): -allow-glsl -stage compute -entry computeMain -target spirv -//TEST:SIMPLE(filecheck=SPIR): -allow-glsl -stage fragment -entry fragMain -target spirv -//TEST:SIMPLE(filecheck=CUDA): -allow-glsl -stage compute -entry computeMain -target cuda -//TEST:SIMPLE(filecheck=CUDA): -allow-glsl -stage fragment -entry fragMain -target cuda +//TEST:SIMPLE(filecheck=GLSL): -allow-glsl -stage compute -entry computeMain -target glsl -DGLSL +//TEST:SIMPLE(filecheck=GLSL): -allow-glsl -stage fragment -entry fragMain -target glsl -DGLSL +//TEST:SIMPLE(filecheck=SPIR): -allow-glsl -stage compute -entry computeMain -target spirv -DSPIRV +//TEST:SIMPLE(filecheck=SPIR): -allow-glsl -stage fragment -entry fragMain -target spirv -DSPIRV +//TEST:SIMPLE(filecheck=CUDA): -allow-glsl -stage compute -entry computeMain -target cuda -DCUDA +//TEST:SIMPLE(filecheck=CUDA): -allow-glsl -stage fragment -entry fragMain -target cuda -DCUDA -//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -output-using-type +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -output-using-type -xslang -DSPIRV // TODO: This test revealed a few problems for a path from GLSL to HLSL //T-EST(compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -compute -entry computeMain -allow-glsl -use-dxil -output-using-type -profile cs_6_6 -xslang -DHLSL @@ -1433,7 +1433,15 @@ bool textureFuncs( Sampler1D<vector<T,N>> gsampler1D ; } -[require(cpp_cuda_glsl_hlsl_spirv,compute,fragment)] +#if defined(HLSL) +[require(hlsl, sm_5_1, compute_fragment)] +#elif defined(GLSL) +[require(glsl, sm_5_1, compute_fragment)] +#elif defined(SPIRV) +[require(spirv, sm_5_1, compute_fragment)] +#elif defined(CUDA) +[require(cuda, sm_5_1, compute_fragment)] +#endif __extern_cpp void TEST_main() { // GLSL: void main( diff --git a/tests/language-feature/capability/capability6.slang b/tests/language-feature/capability/capability6.slang new file mode 100644 index 000000000..3d6642063 --- /dev/null +++ b/tests/language-feature/capability/capability6.slang @@ -0,0 +1,13 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly -entry computeMain -stage compute +//TEST:SIMPLE(filecheck=CHECK_IGNORE_CAPS): -target spirv -emit-spirv-directly -entry computeMain -stage compute -ignore-capabilities +// CHECK_IGNORE_CAPS-NOT: error 36104 + + + +[require(spirv, hlsl)] +// CHECK: error 36111 +// CHECK_IGNORE_CAPS-NOT: error 36111 +void computeMain() +{ + +} |
