diff --git a/Test/baseResults/spv.ext.texture_shadow_lod.error.frag.out b/Test/baseResults/spv.ext.texture_shadow_lod.error.frag.out new file mode 100644 index 00000000..b6aa88e3 --- /dev/null +++ b/Test/baseResults/spv.ext.texture_shadow_lod.error.frag.out @@ -0,0 +1,6 @@ +spv.ext.texture_shadow_lod.error.frag +ERROR: 0:11: 'textureLod' : required extension not requested: GL_EXT_texture_shadow_lod +ERROR: 1 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/spv.ext.texture_shadow_lod.frag.out b/Test/baseResults/spv.ext.texture_shadow_lod.frag.out new file mode 100644 index 00000000..0428f182 --- /dev/null +++ b/Test/baseResults/spv.ext.texture_shadow_lod.frag.out @@ -0,0 +1,94 @@ +spv.ext.texture_shadow_lod.frag +// Module Version 10000 +// Generated by (magic number): 8000b +// Id's are bound by 59 + + Capability Shader + Capability SampledCubeArray + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 8 16 + ExecutionMode 4 OriginUpperLeft + Source GLSL 450 + SourceExtension "GL_EXT_texture_shadow_lod" + Name 4 "main" + Name 8 "c" + Name 12 "s2da" + Name 16 "tc" + Name 24 "sca" + Name 47 "sc" + Decorate 8(c) Location 0 + Decorate 12(s2da) DescriptorSet 0 + Decorate 12(s2da) Binding 0 + Decorate 16(tc) Location 0 + Decorate 24(sca) DescriptorSet 0 + Decorate 24(sca) Binding 1 + Decorate 47(sc) DescriptorSet 0 + Decorate 47(sc) Binding 2 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Output 6(float) + 8(c): 7(ptr) Variable Output + 9: TypeImage 6(float) 2D depth array sampled format:Unknown + 10: TypeSampledImage 9 + 11: TypePointer UniformConstant 10 + 12(s2da): 11(ptr) Variable UniformConstant + 14: TypeVector 6(float) 4 + 15: TypePointer Input 14(fvec4) + 16(tc): 15(ptr) Variable Input + 18: 6(float) Constant 0 + 21: TypeImage 6(float) Cube depth array sampled format:Unknown + 22: TypeSampledImage 21 + 23: TypePointer UniformConstant 22 + 24(sca): 23(ptr) Variable UniformConstant + 30: TypeInt 32 1 + 31: TypeVector 30(int) 2 + 32: 30(int) Constant 0 + 33: 31(ivec2) ConstantComposite 32 32 + 44: TypeImage 6(float) Cube depth sampled format:Unknown + 45: TypeSampledImage 44 + 46: TypePointer UniformConstant 45 + 47(sc): 46(ptr) Variable UniformConstant + 4(main): 2 Function None 3 + 5: Label + 13: 10 Load 12(s2da) + 17: 14(fvec4) Load 16(tc) + 19: 6(float) CompositeExtract 17 3 + 20: 6(float) ImageSampleDrefImplicitLod 13 17 19 Bias 18 + Store 8(c) 20 + 25: 22 Load 24(sca) + 26: 14(fvec4) Load 16(tc) + 27: 6(float) ImageSampleDrefImplicitLod 25 26 18 + Store 8(c) 27 + 28: 10 Load 12(s2da) + 29: 14(fvec4) Load 16(tc) + 34: 6(float) CompositeExtract 29 3 + 35: 6(float) ImageSampleDrefImplicitLod 28 29 34 ConstOffset 33 + Store 8(c) 35 + 36: 10 Load 12(s2da) + 37: 14(fvec4) Load 16(tc) + 38: 6(float) CompositeExtract 37 3 + 39: 6(float) ImageSampleDrefImplicitLod 36 37 38 Bias ConstOffset 18 33 + Store 8(c) 39 + 40: 10 Load 12(s2da) + 41: 14(fvec4) Load 16(tc) + 42: 6(float) CompositeExtract 41 3 + 43: 6(float) ImageSampleDrefExplicitLod 40 41 42 Lod 18 + Store 8(c) 43 + 48: 45 Load 47(sc) + 49: 14(fvec4) Load 16(tc) + 50: 6(float) CompositeExtract 49 3 + 51: 6(float) ImageSampleDrefExplicitLod 48 49 50 Lod 18 + Store 8(c) 51 + 52: 22 Load 24(sca) + 53: 14(fvec4) Load 16(tc) + 54: 6(float) ImageSampleDrefExplicitLod 52 53 18 Lod 18 + Store 8(c) 54 + 55: 10 Load 12(s2da) + 56: 14(fvec4) Load 16(tc) + 57: 6(float) CompositeExtract 56 3 + 58: 6(float) ImageSampleDrefExplicitLod 55 56 57 Lod ConstOffset 18 33 + Store 8(c) 58 + Return + FunctionEnd diff --git a/Test/spv.ext.texture_shadow_lod.error.frag b/Test/spv.ext.texture_shadow_lod.error.frag new file mode 100644 index 00000000..ef6ec21d --- /dev/null +++ b/Test/spv.ext.texture_shadow_lod.error.frag @@ -0,0 +1,13 @@ +#version 450 + +layout(binding = 0) uniform sampler2DArrayShadow s2da; + +layout(location = 0) out vec4 c_out; + +layout(location = 0) in vec4 tc; + +void main() +{ + float c = textureLod(s2da, tc, 0); + c_out = vec4(c); +} diff --git a/Test/spv.ext.texture_shadow_lod.frag b/Test/spv.ext.texture_shadow_lod.frag new file mode 100644 index 00000000..2d9db7bb --- /dev/null +++ b/Test/spv.ext.texture_shadow_lod.frag @@ -0,0 +1,21 @@ +#version 450 +#extension GL_EXT_texture_shadow_lod : enable + +layout(binding = 0) uniform sampler2DArrayShadow s2da; +layout(binding = 1) uniform samplerCubeArrayShadow sca; +layout(binding = 2) uniform samplerCubeShadow sc; + +layout(location = 0) out float c; + +layout(location = 0) in vec4 tc; + +void main() { + c = texture(s2da, tc, 0.0); + c = texture(sca, tc, 0.0, 0.0); + c = textureOffset(s2da, tc, ivec2(0.0)); + c = textureOffset(s2da, tc, ivec2(0.0), 0.0); + c = textureLod(s2da, tc, 0.0); + c = textureLod(sc, tc, 0.0); + c = textureLod(sca, tc, 0.0, 0.0); + c = textureLodOffset(s2da, tc, 0.0, ivec2(0.0)); +} diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 2f8ce295..e3c54d0f 100755 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -4820,6 +4820,33 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + // GL_EXT_texture_shadow_lod overloads + if (profile == EEsProfile) { // ES + if (version >= 300) { + commonBuiltins.append("float texture(sampler2DArrayShadow, vec4, float);" + "float textureOffset(sampler2DArrayShadow, vec4, ivec2, float);" + "float textureLod(sampler2DArrayShadow, vec4, float);" + "float textureLodOffset(sampler2DArrayShadow, vec4, float, ivec2);" + "\n"); + } + if (version >= 320) { + commonBuiltins.append("float texture(samplerCubeArrayShadow, vec4, float, float);" + "float textureLod(samplerCubeShadow, vec4, float);" + "float textureLod(samplerCubeArrayShadow, vec4, float, float);" + "\n"); + } + } else if (version >= 130) { // Desktop + commonBuiltins.append("float texture(sampler2DArrayShadow, vec4, float);" + "float texture(samplerCubeArrayShadow, vec4, float, float);" + "float textureOffset(sampler2DArrayShadow, vec4, ivec2);" + "float textureOffset(sampler2DArrayShadow, vec4, ivec2, float);" + "float textureLod(sampler2DArrayShadow, vec4, float);" + "float textureLod(samplerCubeShadow, vec4, float);" + "float textureLod(samplerCubeArrayShadow, vec4, float, float);" + "float textureLodOffset(sampler2DArrayShadow, vec4, float, ivec2);" + "\n"); + } + //============================================================================ // // Standard Uniforms @@ -8741,6 +8768,36 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("textureBlockMatchSADQCOM", 1, &E_GL_QCOM_image_processing); symbolTable.setFunctionExtensions("textureBlockMatchSSDQCOM", 1, &E_GL_QCOM_image_processing); } + + // GL_EXT_texture_shadow_lod + // NOTE: These are the mangled names of individual overloads, since this extension adds overloads for + // existing built-in functions. + if (profile == EEsProfile) { + if (version >= 300) { + symbolTable.setSingleFunctionExtensions("texture(sAS21;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureOffset(sAS21;vf4;vi2;f1;", 1, + &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sAS21;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLodOffset(sAS21;vf4;f1;vi2;", 1, + &E_GL_EXT_texture_shadow_lod); + } + if (version >= 320) { + symbolTable.setSingleFunctionExtensions("texture(sASC1;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("texture(sASC1;vf4;f1;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sASC1;vf4;f1;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sSC1;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + } + } else if (version >= 130) { + symbolTable.setSingleFunctionExtensions("texture(sAS21;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("texture(sASC1;vf4;f1;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureOffset(sAS21;vf4;vi2;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureOffset(sAS21;vf4;vi2;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sAS21;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sASC1;vf4;f1;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLod(sSC1;vf4;f1;", 1, &E_GL_EXT_texture_shadow_lod); + symbolTable.setSingleFunctionExtensions("textureLodOffset(sAS21;vf4;f1;vi2;", 1, + &E_GL_EXT_texture_shadow_lod); + } break; case EShLangCompute: diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 1e007a71..dae5a8b9 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -318,6 +318,16 @@ void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const c } } +// Make a single function require an extension(s). i.e., this will only set the extensions for the symbol that matches 'name' exactly. +// This is different from setFunctionExtensions, which uses std::map::lower_bound to effectively set all symbols that start with 'name'. +// Should only be used for a version/profile that actually needs the extension(s). +void TSymbolTableLevel::setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]) +{ + if (auto candidate = level.find(name); candidate != level.end()) { + candidate->second->setExtensions(num, extensions); + } +} + // // Make all symbols in this table level read only. // diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index fc86ad62..edc79cb5 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -571,6 +571,7 @@ public: void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); + void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]); void dump(TInfoSink& infoSink, bool complete = false) const; TSymbolTableLevel* clone() const; void readOnly(); @@ -872,6 +873,12 @@ public: table[level]->setFunctionExtensions(name, num, extensions); } + void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]) + { + for (unsigned int level = 0; level < table.size(); ++level) + table[level]->setSingleFunctionExtensions(name, num, extensions); + } + void setVariableExtensions(const char* name, int numExts, const char* const extensions[]) { TSymbol* symbol = find(TString(name)); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 38cbf3e1..1bcd3884 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -359,6 +359,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable; extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable; extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 564995b2..aee53296 100755 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -333,6 +333,8 @@ const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2"; const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image"; +const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod"; + // Arrays of extensions for the above AEP duplications const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 4482161c..4dea5dd0 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -526,6 +526,8 @@ INSTANTIATE_TEST_SUITE_P( "spv.atomicAdd.bufferReference.comp", "spv.fragmentShaderBarycentric3.frag", "spv.fragmentShaderBarycentric4.frag", + "spv.ext.texture_shadow_lod.frag", + "spv.ext.texture_shadow_lod.error.frag", })), FileNameAsCustomTestSuffix );