diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 3bed67835..e41bb5de6 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -1448,7 +1448,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb); } - if (sourceExtensions.find("GL_EXT_ray_flags_primitive_culling") != sourceExtensions.end()) { + if (glslangIntermediate->getLayoutPrimitiveCulling()) { builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR); } diff --git a/Test/baseResults/spv.ext.RayPrimCull_Errors.rgen.out b/Test/baseResults/spv.ext.RayPrimCull_Errors.rgen.out new file mode 100644 index 000000000..23d1acf97 --- /dev/null +++ b/Test/baseResults/spv.ext.RayPrimCull_Errors.rgen.out @@ -0,0 +1,9 @@ +spv.ext.RayPrimCull_Errors.rgen +ERROR: 0:3: 'primitive culling' : required extension not requested: GL_EXT_ray_flags_primitive_culling +ERROR: 0:5: 'primitive_culling' : layout qualifier can not have storage qualifiers +ERROR: 0:6: 'primitive_culling' : can only be applied as standalone +ERROR: 0:7: 'primitive_culling' : can only be applied as standalone +ERROR: 4 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/rayQuery-allOps.comp b/Test/rayQuery-allOps.comp index 80f2593d6..3a2a8d0d2 100644 --- a/Test/rayQuery-allOps.comp +++ b/Test/rayQuery-allOps.comp @@ -2,6 +2,7 @@ #extension GL_EXT_ray_query : enable #extension GL_EXT_ray_flags_primitive_culling : enable +layout(primitive_culling); struct Ray { vec3 pos; diff --git a/Test/spv.ext.RayGenShader.rgen b/Test/spv.ext.RayGenShader.rgen index c92772ee6..27d450fb1 100644 --- a/Test/spv.ext.RayGenShader.rgen +++ b/Test/spv.ext.RayGenShader.rgen @@ -11,6 +11,7 @@ layout(shaderRecordEXT) buffer block vec3 origin; }; +layout(primitive_culling); void main() { uint lx = gl_LaunchIDEXT.x; diff --git a/Test/spv.ext.RayPrimCull_Errors.rgen b/Test/spv.ext.RayPrimCull_Errors.rgen new file mode 100644 index 000000000..0fceccff4 --- /dev/null +++ b/Test/spv.ext.RayPrimCull_Errors.rgen @@ -0,0 +1,10 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +layout(primitive_culling); +#extension GL_EXT_ray_flags_primitive_culling : enable +layout(primitive_culling) uniform; +layout(primitive_culling, binding = 2) uniform accelerationStructureEXT as; +layout(std140, binding = 2, primitive_culling) buffer block { int x; }; +void main() +{ +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index b2c416d10..235ea3f1d 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1235,6 +1235,7 @@ struct TShaderQualifiers { bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set + bool layoutPrimitiveCulling; // true if layout primitive_culling set TLayoutDepth getDepth() const { return layoutDepth; } #else TLayoutDepth getDepth() const { return EldNone; } @@ -1268,6 +1269,7 @@ struct TShaderQualifiers { layoutOverrideCoverage = false; layoutDerivativeGroupQuads = false; layoutDerivativeGroupLinear = false; + layoutPrimitiveCulling = false; primitives = TQualifier::layoutNotSet; interlockOrdering = EioNone; #endif @@ -1331,6 +1333,8 @@ struct TShaderQualifiers { primitives = src.primitives; if (src.interlockOrdering != EioNone) interlockOrdering = src.interlockOrdering; + if (src.layoutPrimitiveCulling) + layoutPrimitiveCulling = src.layoutPrimitiveCulling; #endif } }; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 39027d34a..a35d41a05 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -5173,6 +5173,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } } } + + if (id == "primitive_culling") { + requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling"); + publicType.shaderQualifiers.layoutPrimitiveCulling = true; + return; + } #endif error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); @@ -6104,6 +6110,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "num_views", ""); if (shaderQualifiers.interlockOrdering != EioNone) error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), ""); + if (shaderQualifiers.layoutPrimitiveCulling) + error(loc, "can only be applied as standalone", "primitive_culling", ""); #endif } @@ -8368,6 +8376,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con { checkIoArraysConsistency(loc); } + + if (publicType.shaderQualifiers.layoutPrimitiveCulling) { + if (publicType.qualifier.storage != EvqTemporary) + error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", ""); + else { + intermediate.setLayoutPrimitiveCulling(); + } + // Exit early as further checks are not valid + return; + } #endif const TQualifier& qualifier = publicType.qualifier; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 996e347fb..9f7b9977e 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -276,7 +276,8 @@ public: needToLegalize(false), binaryDoubleOutput(false), usePhysicalStorageBuffer(false), - uniformLocationBase(0) + uniformLocationBase(0), + layoutPrimitiveCulling(false) #endif { localSize[0] = 1; @@ -742,6 +743,8 @@ public: void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; } ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; } + void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; } + bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; } bool setPrimitives(int m) { if (primitives != TQualifier::layoutNotSet) @@ -974,6 +977,7 @@ protected: ComputeDerivativeMode computeDerivativeMode; int primitives; int numTaskNVBlocks; + bool layoutPrimitiveCulling; // Base shift values std::array shiftBinding; diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 1d061fb36..62941a474 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -337,6 +337,7 @@ INSTANTIATE_TEST_CASE_P( "spv.ext.IntersectShader_Errors.rint", "spv.ext.MissShader.rmiss", "spv.ext.MissShader_Errors.rmiss", + "spv.ext.RayPrimCull_Errors.rgen", "spv.ext.RayCallable.rcall", "spv.ext.RayCallable_Errors.rcall", "spv.ext.RayConstants.rgen",