diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp index a7a1a73a49..d1b411f29a 100644 --- a/SPIRV/SpvTools.cpp +++ b/SPIRV/SpvTools.cpp @@ -165,6 +165,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); + spvValidatorOptionsSetAllowOffsetTextureOperand(options, intermediate.usingTextureOffsetNonConst()); spvValidateWithOptions(context, options, &binary, &diagnostic); // report diff --git a/Test/baseResults/spv.sparsetextureoffset_non_const.vert.out b/Test/baseResults/spv.sparsetextureoffset_non_const.vert.out new file mode 100644 index 0000000000..817a04cadf --- /dev/null +++ b/Test/baseResults/spv.sparsetextureoffset_non_const.vert.out @@ -0,0 +1,193 @@ +spv.sparsetextureoffset_non_const.vert +// Module Version 10000 +// Generated by (magic number): 8000b +// Id's are bound by 114 + + Capability Shader + Capability ImageGatherExtended + Capability SparseResidency + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 14 27 31 45 75 90 98 106 + Source GLSL 450 + SourceExtension "GL_ARB_sparse_texture2" + SourceExtension "GL_EXT_texture_offset_non_const" + Name 4 "main" + Name 8 "gl_PerVertex" + MemberName 8(gl_PerVertex) 0 "gl_Position" + Name 10 "" + Name 14 "a_position" + Name 19 "ret0" + Name 23 "u_sampler" + Name 27 "a_in0" + Name 31 "offsetValue" + Name 34 "aux0" + Name 36 "ResType" + Name 40 "ret1" + Name 45 "a_in1" + Name 49 "aux1" + Name 54 "ret2" + Name 59 "aux2" + Name 63 "ret3" + Name 71 "aux3" + Name 75 "v_color0" + Name 77 "buf0" + MemberName 77(buf0) 0 "u_scale" + Name 79 "" + Name 84 "buf1" + MemberName 84(buf1) 0 "u_bias" + Name 86 "" + Name 90 "v_color1" + Name 98 "v_color2" + Name 106 "v_color3" + Decorate 8(gl_PerVertex) Block + MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position + Decorate 14(a_position) Location 0 + Decorate 23(u_sampler) Binding 0 + Decorate 23(u_sampler) DescriptorSet 0 + Decorate 27(a_in0) Location 4 + Decorate 31(offsetValue) Location 10 + Decorate 45(a_in1) Location 5 + Decorate 75(v_color0) RelaxedPrecision + Decorate 75(v_color0) Location 0 + Decorate 77(buf0) Block + MemberDecorate 77(buf0) 0 Offset 0 + Decorate 79 Binding 1 + Decorate 79 DescriptorSet 0 + Decorate 84(buf1) Block + MemberDecorate 84(buf1) 0 Offset 0 + Decorate 86 Binding 2 + Decorate 86 DescriptorSet 0 + Decorate 90(v_color1) RelaxedPrecision + Decorate 90(v_color1) Location 1 + Decorate 98(v_color2) RelaxedPrecision + Decorate 98(v_color2) Location 2 + Decorate 106(v_color3) RelaxedPrecision + Decorate 106(v_color3) Location 3 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(gl_PerVertex): TypeStruct 7(fvec4) + 9: TypePointer Output 8(gl_PerVertex) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: TypePointer Input 7(fvec4) + 14(a_position): 13(ptr) Variable Input + 16: TypePointer Output 7(fvec4) + 18: TypePointer Function 11(int) + 20: TypeImage 6(float) 2D sampled format:Unknown + 21: TypeSampledImage 20 + 22: TypePointer UniformConstant 21 + 23(u_sampler): 22(ptr) Variable UniformConstant + 25: TypeVector 6(float) 2 + 26: TypePointer Input 25(fvec2) + 27(a_in0): 26(ptr) Variable Input + 29: TypeVector 11(int) 2 + 30: TypePointer Input 29(ivec2) + 31(offsetValue): 30(ptr) Variable Input + 33: TypePointer Function 7(fvec4) + 35: 6(float) Constant 0 + 36(ResType): TypeStruct 11(int) 7(fvec4) + 44: TypePointer Input 6(float) + 45(a_in1): 44(ptr) Variable Input + 75(v_color0): 16(ptr) Variable Output + 77(buf0): TypeStruct 7(fvec4) + 78: TypePointer Uniform 77(buf0) + 79: 78(ptr) Variable Uniform + 80: TypePointer Uniform 7(fvec4) + 84(buf1): TypeStruct 7(fvec4) + 85: TypePointer Uniform 84(buf1) + 86: 85(ptr) Variable Uniform + 90(v_color1): 16(ptr) Variable Output + 98(v_color2): 16(ptr) Variable Output + 106(v_color3): 16(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 19(ret0): 18(ptr) Variable Function + 34(aux0): 33(ptr) Variable Function + 40(ret1): 18(ptr) Variable Function + 49(aux1): 33(ptr) Variable Function + 54(ret2): 18(ptr) Variable Function + 59(aux2): 33(ptr) Variable Function + 63(ret3): 18(ptr) Variable Function + 71(aux3): 33(ptr) Variable Function + 15: 7(fvec4) Load 14(a_position) + 17: 16(ptr) AccessChain 10 12 + Store 17 15 + 24: 21 Load 23(u_sampler) + 28: 25(fvec2) Load 27(a_in0) + 32: 29(ivec2) Load 31(offsetValue) + 37: 36(ResType) ImageSparseSampleExplicitLod 24 28 Lod Offset 35 32 + 38: 7(fvec4) CompositeExtract 37 1 + Store 34(aux0) 38 + 39: 11(int) CompositeExtract 37 0 + Store 19(ret0) 39 + 41: 21 Load 23(u_sampler) + 42: 25(fvec2) Load 27(a_in0) + 43: 29(ivec2) ConvertFToS 42 + 46: 6(float) Load 45(a_in1) + 47: 11(int) ConvertFToS 46 + 48: 29(ivec2) Load 31(offsetValue) + 50: 20 Image 41 + 51: 36(ResType) ImageSparseFetch 50 43 Lod Offset 47 48 + 52: 7(fvec4) CompositeExtract 51 1 + Store 49(aux1) 52 + 53: 11(int) CompositeExtract 51 0 + Store 40(ret1) 53 + 55: 21 Load 23(u_sampler) + 56: 25(fvec2) Load 27(a_in0) + 57: 6(float) Load 45(a_in1) + 58: 29(ivec2) Load 31(offsetValue) + 60: 36(ResType) ImageSparseSampleExplicitLod 55 56 Lod Offset 57 58 + 61: 7(fvec4) CompositeExtract 60 1 + Store 59(aux2) 61 + 62: 11(int) CompositeExtract 60 0 + Store 54(ret2) 62 + 64: 21 Load 23(u_sampler) + 65: 25(fvec2) Load 27(a_in0) + 66: 6(float) Load 45(a_in1) + 67: 25(fvec2) CompositeConstruct 66 66 + 68: 6(float) Load 45(a_in1) + 69: 25(fvec2) CompositeConstruct 68 68 + 70: 29(ivec2) Load 31(offsetValue) + 72: 36(ResType) ImageSparseSampleExplicitLod 64 65 Grad Offset 67 69 70 + 73: 7(fvec4) CompositeExtract 72 1 + Store 71(aux3) 73 + 74: 11(int) CompositeExtract 72 0 + Store 63(ret3) 74 + 76: 7(fvec4) Load 34(aux0) + 81: 80(ptr) AccessChain 79 12 + 82: 7(fvec4) Load 81 + 83: 7(fvec4) FMul 76 82 + 87: 80(ptr) AccessChain 86 12 + 88: 7(fvec4) Load 87 + 89: 7(fvec4) FAdd 83 88 + Store 75(v_color0) 89 + 91: 7(fvec4) Load 49(aux1) + 92: 80(ptr) AccessChain 79 12 + 93: 7(fvec4) Load 92 + 94: 7(fvec4) FMul 91 93 + 95: 80(ptr) AccessChain 86 12 + 96: 7(fvec4) Load 95 + 97: 7(fvec4) FAdd 94 96 + Store 90(v_color1) 97 + 99: 7(fvec4) Load 59(aux2) + 100: 80(ptr) AccessChain 79 12 + 101: 7(fvec4) Load 100 + 102: 7(fvec4) FMul 99 101 + 103: 80(ptr) AccessChain 86 12 + 104: 7(fvec4) Load 103 + 105: 7(fvec4) FAdd 102 104 + Store 98(v_color2) 105 + 107: 7(fvec4) Load 71(aux3) + 108: 80(ptr) AccessChain 79 12 + 109: 7(fvec4) Load 108 + 110: 7(fvec4) FMul 107 109 + 111: 80(ptr) AccessChain 86 12 + 112: 7(fvec4) Load 111 + 113: 7(fvec4) FAdd 110 112 + Store 106(v_color3) 113 + Return + FunctionEnd diff --git a/Test/baseResults/spv.sparsetextureoffset_non_const_fail.vert.out b/Test/baseResults/spv.sparsetextureoffset_non_const_fail.vert.out new file mode 100644 index 0000000000..e56029c30b --- /dev/null +++ b/Test/baseResults/spv.sparsetextureoffset_non_const_fail.vert.out @@ -0,0 +1,9 @@ +spv.sparsetextureoffset_non_const_fail.vert +ERROR: 0:26: 'texel offset' : argument must be compile-time constant +ERROR: 0:27: 'texel offset' : argument must be compile-time constant +ERROR: 0:28: 'texel offset' : argument must be compile-time constant +ERROR: 0:29: 'texel offset' : argument must be compile-time constant +ERROR: 4 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/spv.textureoffset_non_const.vert.out b/Test/baseResults/spv.textureoffset_non_const.vert.out new file mode 100644 index 0000000000..8a66e2fa35 --- /dev/null +++ b/Test/baseResults/spv.textureoffset_non_const.vert.out @@ -0,0 +1,212 @@ +spv.textureoffset_non_const.vert +// Module Version 10000 +// Generated by (magic number): 8000b +// Id's are bound by 140 + + Capability Shader + Capability ImageGatherExtended + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 14 18 26 30 47 52 64 80 92 107 122 + Source GLSL 450 + SourceExtension "GL_EXT_texture_offset_non_const" + Name 4 "main" + Name 8 "gl_PerVertex" + MemberName 8(gl_PerVertex) 0 "gl_Position" + Name 10 "" + Name 14 "a_position" + Name 18 "v_color0" + Name 22 "u_sampler" + Name 26 "a_in0" + Name 30 "offsetValue" + Name 34 "buf0" + MemberName 34(buf0) 0 "u_scale" + Name 36 "" + Name 41 "buf1" + MemberName 41(buf1) 0 "u_bias" + Name 43 "" + Name 47 "v_color1" + Name 52 "a_in1" + Name 64 "v_color2" + Name 80 "v_color3" + Name 92 "v_color4" + Name 107 "v_color5" + Name 122 "v_color6" + Decorate 8(gl_PerVertex) Block + MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position + Decorate 14(a_position) Location 0 + Decorate 18(v_color0) RelaxedPrecision + Decorate 18(v_color0) Location 0 + Decorate 22(u_sampler) Binding 0 + Decorate 22(u_sampler) DescriptorSet 0 + Decorate 26(a_in0) Location 4 + Decorate 30(offsetValue) Location 10 + Decorate 34(buf0) Block + MemberDecorate 34(buf0) 0 Offset 0 + Decorate 36 Binding 1 + Decorate 36 DescriptorSet 0 + Decorate 41(buf1) Block + MemberDecorate 41(buf1) 0 Offset 0 + Decorate 43 Binding 2 + Decorate 43 DescriptorSet 0 + Decorate 47(v_color1) RelaxedPrecision + Decorate 47(v_color1) Location 1 + Decorate 52(a_in1) Location 5 + Decorate 64(v_color2) RelaxedPrecision + Decorate 64(v_color2) Location 2 + Decorate 80(v_color3) RelaxedPrecision + Decorate 80(v_color3) Location 3 + Decorate 92(v_color4) RelaxedPrecision + Decorate 92(v_color4) Location 4 + Decorate 107(v_color5) RelaxedPrecision + Decorate 107(v_color5) Location 5 + Decorate 122(v_color6) RelaxedPrecision + Decorate 122(v_color6) Location 6 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(gl_PerVertex): TypeStruct 7(fvec4) + 9: TypePointer Output 8(gl_PerVertex) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: TypePointer Input 7(fvec4) + 14(a_position): 13(ptr) Variable Input + 16: TypePointer Output 7(fvec4) + 18(v_color0): 16(ptr) Variable Output + 19: TypeImage 6(float) 2D sampled format:Unknown + 20: TypeSampledImage 19 + 21: TypePointer UniformConstant 20 + 22(u_sampler): 21(ptr) Variable UniformConstant + 24: TypeVector 6(float) 2 + 25: TypePointer Input 24(fvec2) + 26(a_in0): 25(ptr) Variable Input + 28: TypeVector 11(int) 2 + 29: TypePointer Input 28(ivec2) + 30(offsetValue): 29(ptr) Variable Input + 32: 6(float) Constant 0 + 34(buf0): TypeStruct 7(fvec4) + 35: TypePointer Uniform 34(buf0) + 36: 35(ptr) Variable Uniform + 37: TypePointer Uniform 7(fvec4) + 41(buf1): TypeStruct 7(fvec4) + 42: TypePointer Uniform 41(buf1) + 43: 42(ptr) Variable Uniform + 47(v_color1): 16(ptr) Variable Output + 51: TypePointer Input 6(float) + 52(a_in1): 51(ptr) Variable Input + 64(v_color2): 16(ptr) Variable Output + 67: 6(float) Constant 1065353216 + 68: TypeVector 6(float) 3 + 80(v_color3): 16(ptr) Variable Output + 92(v_color4): 16(ptr) Variable Output + 107(v_color5): 16(ptr) Variable Output + 122(v_color6): 16(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 15: 7(fvec4) Load 14(a_position) + 17: 16(ptr) AccessChain 10 12 + Store 17 15 + 23: 20 Load 22(u_sampler) + 27: 24(fvec2) Load 26(a_in0) + 31: 28(ivec2) Load 30(offsetValue) + 33: 7(fvec4) ImageSampleExplicitLod 23 27 Lod Offset 32 31 + 38: 37(ptr) AccessChain 36 12 + 39: 7(fvec4) Load 38 + 40: 7(fvec4) FMul 33 39 + 44: 37(ptr) AccessChain 43 12 + 45: 7(fvec4) Load 44 + 46: 7(fvec4) FAdd 40 45 + Store 18(v_color0) 46 + 48: 20 Load 22(u_sampler) + 49: 24(fvec2) Load 26(a_in0) + 50: 28(ivec2) ConvertFToS 49 + 53: 6(float) Load 52(a_in1) + 54: 11(int) ConvertFToS 53 + 55: 28(ivec2) Load 30(offsetValue) + 56: 19 Image 48 + 57: 7(fvec4) ImageFetch 56 50 Lod Offset 54 55 + 58: 37(ptr) AccessChain 36 12 + 59: 7(fvec4) Load 58 + 60: 7(fvec4) FMul 57 59 + 61: 37(ptr) AccessChain 43 12 + 62: 7(fvec4) Load 61 + 63: 7(fvec4) FAdd 60 62 + Store 47(v_color1) 63 + 65: 20 Load 22(u_sampler) + 66: 24(fvec2) Load 26(a_in0) + 69: 6(float) CompositeExtract 66 0 + 70: 6(float) CompositeExtract 66 1 + 71: 68(fvec3) CompositeConstruct 69 70 67 + 72: 28(ivec2) Load 30(offsetValue) + 73: 7(fvec4) ImageSampleProjExplicitLod 65 71 Lod Offset 32 72 + 74: 37(ptr) AccessChain 36 12 + 75: 7(fvec4) Load 74 + 76: 7(fvec4) FMul 73 75 + 77: 37(ptr) AccessChain 43 12 + 78: 7(fvec4) Load 77 + 79: 7(fvec4) FAdd 76 78 + Store 64(v_color2) 79 + 81: 20 Load 22(u_sampler) + 82: 24(fvec2) Load 26(a_in0) + 83: 6(float) Load 52(a_in1) + 84: 28(ivec2) Load 30(offsetValue) + 85: 7(fvec4) ImageSampleExplicitLod 81 82 Lod Offset 83 84 + 86: 37(ptr) AccessChain 36 12 + 87: 7(fvec4) Load 86 + 88: 7(fvec4) FMul 85 87 + 89: 37(ptr) AccessChain 43 12 + 90: 7(fvec4) Load 89 + 91: 7(fvec4) FAdd 88 90 + Store 80(v_color3) 91 + 93: 20 Load 22(u_sampler) + 94: 24(fvec2) Load 26(a_in0) + 95: 6(float) CompositeExtract 94 0 + 96: 6(float) CompositeExtract 94 1 + 97: 68(fvec3) CompositeConstruct 95 96 67 + 98: 6(float) Load 52(a_in1) + 99: 28(ivec2) Load 30(offsetValue) + 100: 7(fvec4) ImageSampleProjExplicitLod 93 97 Lod Offset 98 99 + 101: 37(ptr) AccessChain 36 12 + 102: 7(fvec4) Load 101 + 103: 7(fvec4) FMul 100 102 + 104: 37(ptr) AccessChain 43 12 + 105: 7(fvec4) Load 104 + 106: 7(fvec4) FAdd 103 105 + Store 92(v_color4) 106 + 108: 20 Load 22(u_sampler) + 109: 24(fvec2) Load 26(a_in0) + 110: 6(float) Load 52(a_in1) + 111: 24(fvec2) CompositeConstruct 110 110 + 112: 6(float) Load 52(a_in1) + 113: 24(fvec2) CompositeConstruct 112 112 + 114: 28(ivec2) Load 30(offsetValue) + 115: 7(fvec4) ImageSampleExplicitLod 108 109 Grad Offset 111 113 114 + 116: 37(ptr) AccessChain 36 12 + 117: 7(fvec4) Load 116 + 118: 7(fvec4) FMul 115 117 + 119: 37(ptr) AccessChain 43 12 + 120: 7(fvec4) Load 119 + 121: 7(fvec4) FAdd 118 120 + Store 107(v_color5) 121 + 123: 20 Load 22(u_sampler) + 124: 24(fvec2) Load 26(a_in0) + 125: 6(float) CompositeExtract 124 0 + 126: 6(float) CompositeExtract 124 1 + 127: 68(fvec3) CompositeConstruct 125 126 67 + 128: 6(float) Load 52(a_in1) + 129: 24(fvec2) CompositeConstruct 128 128 + 130: 6(float) Load 52(a_in1) + 131: 24(fvec2) CompositeConstruct 130 130 + 132: 28(ivec2) Load 30(offsetValue) + 133: 7(fvec4) ImageSampleProjExplicitLod 123 127 Grad Offset 129 131 132 + 134: 37(ptr) AccessChain 36 12 + 135: 7(fvec4) Load 134 + 136: 7(fvec4) FMul 133 135 + 137: 37(ptr) AccessChain 43 12 + 138: 7(fvec4) Load 137 + 139: 7(fvec4) FAdd 136 138 + Store 122(v_color6) 139 + Return + FunctionEnd diff --git a/Test/spv.sparsetextureoffset_non_const.vert b/Test/spv.sparsetextureoffset_non_const.vert new file mode 100644 index 0000000000..699d2b8190 --- /dev/null +++ b/Test/spv.sparsetextureoffset_non_const.vert @@ -0,0 +1,36 @@ +#version 450 core +#extension GL_ARB_sparse_texture2 : enable +#extension GL_EXT_texture_offset_non_const : enable +layout(location = 0) in highp vec4 a_position; +layout(location = 4) in highp vec2 a_in0; +layout(location = 5) in highp float a_in1; +layout(location = 10) in highp ivec2 offsetValue; +layout(location = 0) out mediump vec4 v_color0; +layout(location = 1) out mediump vec4 v_color1; +layout(location = 2) out mediump vec4 v_color2; +layout(location = 3) out mediump vec4 v_color3; +layout(set = 0, binding = 0) uniform highp sampler2D u_sampler; +layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; }; +layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; }; +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() +{ + gl_Position = a_position; + vec4 aux0; + vec4 aux1; + vec4 aux2; + vec4 aux3; + + int ret0 = sparseTextureOffsetARB(u_sampler, a_in0, offsetValue, aux0); + int ret1 = sparseTexelFetchOffsetARB(u_sampler, ivec2(a_in0), int(a_in1), offsetValue, aux1); + int ret2 = sparseTextureLodOffsetARB(u_sampler, a_in0, a_in1, offsetValue, aux2); + int ret3 = sparseTextureGradOffsetARB(u_sampler, a_in0, vec2(a_in1, a_in1), vec2(a_in1, a_in1), offsetValue, aux3); + + v_color0 = aux0 * u_scale + u_bias; + v_color1 = aux1 * u_scale + u_bias; + v_color2 = aux2 * u_scale + u_bias; + v_color3 = aux3 * u_scale + u_bias; +} diff --git a/Test/spv.sparsetextureoffset_non_const_fail.vert b/Test/spv.sparsetextureoffset_non_const_fail.vert new file mode 100644 index 0000000000..706f1fffe1 --- /dev/null +++ b/Test/spv.sparsetextureoffset_non_const_fail.vert @@ -0,0 +1,35 @@ +#version 450 core +#extension GL_ARB_sparse_texture2 : enable +layout(location = 0) in highp vec4 a_position; +layout(location = 4) in highp vec2 a_in0; +layout(location = 5) in highp float a_in1; +layout(location = 10) in highp ivec2 offsetValue; +layout(location = 0) out mediump vec4 v_color0; +layout(location = 1) out mediump vec4 v_color1; +layout(location = 2) out mediump vec4 v_color2; +layout(location = 3) out mediump vec4 v_color3; +layout(set = 0, binding = 0) uniform highp sampler2D u_sampler; +layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; }; +layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; }; +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() +{ + gl_Position = a_position; + vec4 aux0; + vec4 aux1; + vec4 aux2; + vec4 aux3; + + int ret0 = sparseTextureOffsetARB(u_sampler, a_in0, offsetValue, aux0); + int ret1 = sparseTexelFetchOffsetARB(u_sampler, ivec2(a_in0), int(a_in1), offsetValue, aux1); + int ret2 = sparseTextureLodOffsetARB(u_sampler, a_in0, a_in1, offsetValue, aux2); + int ret3 = sparseTextureGradOffsetARB(u_sampler, a_in0, vec2(a_in1, a_in1), vec2(a_in1, a_in1), offsetValue, aux3); + + v_color0 = aux0 * u_scale + u_bias; + v_color1 = aux1 * u_scale + u_bias; + v_color2 = aux2 * u_scale + u_bias; + v_color3 = aux3 * u_scale + u_bias; +} diff --git a/Test/spv.textureoffset_non_const.vert b/Test/spv.textureoffset_non_const.vert new file mode 100644 index 0000000000..482e6dd0e7 --- /dev/null +++ b/Test/spv.textureoffset_non_const.vert @@ -0,0 +1,31 @@ +#version 450 core +#extension GL_EXT_texture_offset_non_const : enable +layout(location = 0) in highp vec4 a_position; +layout(location = 4) in highp vec2 a_in0; +layout(location = 5) in highp float a_in1; +layout(location = 10) in highp ivec2 offsetValue; +layout(location = 0) out mediump vec4 v_color0; +layout(location = 1) out mediump vec4 v_color1; +layout(location = 2) out mediump vec4 v_color2; +layout(location = 3) out mediump vec4 v_color3; +layout(location = 4) out mediump vec4 v_color4; +layout(location = 5) out mediump vec4 v_color5; +layout(location = 6) out mediump vec4 v_color6; +layout(set = 0, binding = 0) uniform highp sampler2D u_sampler; +layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; }; +layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; }; +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() +{ + gl_Position = a_position; + v_color0 = vec4(textureOffset(u_sampler, a_in0, offsetValue))*u_scale + u_bias; + v_color1 = vec4(texelFetchOffset(u_sampler, ivec2(a_in0), int(a_in1), offsetValue))*u_scale + u_bias; + v_color2 = vec4(textureProjOffset(u_sampler, vec3(a_in0, 1.0), offsetValue))*u_scale + u_bias; + v_color3 = vec4(textureLodOffset(u_sampler, a_in0, a_in1, offsetValue))*u_scale + u_bias; + v_color4 = vec4(textureProjLodOffset(u_sampler, vec3(a_in0, 1.0), a_in1, offsetValue))*u_scale + u_bias; + v_color5 = vec4(textureGradOffset(u_sampler, a_in0, vec2(a_in1, a_in1), vec2(a_in1, a_in1), offsetValue))*u_scale + u_bias; + v_color6 = vec4(textureProjGradOffset(u_sampler, vec3(a_in0, 1.0), vec2(a_in1, a_in1), vec2(a_in1, a_in1), offsetValue))*u_scale + u_bias; +} diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 41c6179b38..cb7d8367b7 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -44,6 +44,7 @@ #include +#include "Versions.h" #include "preprocessor/PpContext.h" extern int yyparse(glslang::TParseContext*); @@ -2540,18 +2541,34 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan case EOpTextureProjLodOffset: case EOpTextureGradOffset: case EOpTextureProjGradOffset: + case EOpSparseTextureOffset: + case EOpSparseTextureFetchOffset: + case EOpSparseTextureLodOffset: + case EOpSparseTextureGradOffset: { // Handle texture-offset limits checking // Pick which argument has to hold constant offsets int arg = -1; switch (callNode.getOp()) { - case EOpTextureOffset: arg = 2; break; - case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break; - case EOpTextureProjOffset: arg = 2; break; - case EOpTextureLodOffset: arg = 3; break; - case EOpTextureProjLodOffset: arg = 3; break; - case EOpTextureGradOffset: arg = 4; break; - case EOpTextureProjGradOffset: arg = 4; break; + case EOpSparseTextureOffset: + case EOpTextureOffset: + case EOpTextureProjOffset: + arg = 2; + break; + case EOpSparseTextureLodOffset: + case EOpTextureLodOffset: + case EOpTextureProjLodOffset: + arg = 3; + break; + case EOpSparseTextureGradOffset: + case EOpTextureGradOffset: + case EOpTextureProjGradOffset: + arg = 4; + break; + case EOpSparseTextureFetchOffset: + case EOpTextureFetchOffset: + arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; + break; default: assert(0); break; @@ -2563,8 +2580,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan arg0->getType().getSampler().shadow; if (f16ShadowCompare) ++arg; - if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant()) - error(loc, "argument must be compile-time constant", "texel offset", ""); + if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant()) { + if (!extensionTurnedOn(E_GL_EXT_texture_offset_non_const)) + error(loc, "argument must be compile-time constant", "texel offset", ""); + } else if ((*argp)[arg]->getAsConstantUnion()) { const TType& type = (*argp)[arg]->getAsTyped()->getType(); for (int c = 0; c < type.getVectorSize(); ++c) { @@ -2575,6 +2594,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } + // This check does not apply to sparse because + // GL_ARB_sparse_texture2 always includes this function. if (callNode.getOp() == EOpTextureOffset) { TSampler s = arg0->getType().getSampler(); if (s.is2D() && s.isArrayed() && s.isShadow()) { @@ -2595,6 +2616,9 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } + // This check does not apply to sparse because + // GL_ARB_sparse_texture2 does not define sparseTextureLodOffsetARB + // with a sampler2DArrayShadow. if (callNode.getOp() == EOpTextureLodOffset) { TSampler s = arg0->getType().getSampler(); if (s.is2D() && s.isArrayed() && s.isShadow() && @@ -3157,8 +3181,10 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn arg = 4; if (arg > 0) { - if (! callNode.getSequence()[arg]->getAsConstantUnion()) - error(loc, "argument must be compile-time constant", "texel offset", ""); + if (! callNode.getSequence()[arg]->getAsConstantUnion()) { + if (!extensionTurnedOn(E_GL_EXT_texture_offset_non_const)) + error(loc, "argument must be compile-time constant", "texel offset", ""); + } else { const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType(); for (int c = 0; c < type.getVectorSize(); ++c) { diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 88b7b1c076..bee9042b5b 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -373,6 +373,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable; extensionBehavior[E_GL_EXT_draw_instanced] = EBhDisable; extensionBehavior[E_GL_EXT_texture_array] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_offset_non_const] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; @@ -639,6 +640,11 @@ void TParseVersions::getPreamble(std::string& preamble) ; } + if ((!isEsProfile() && version >= 130) || + (isEsProfile() && version >= 300)) { + preamble += "#define GL_EXT_texture_offset_non_const 1\n"; + } + if (version >= 300 /* both ES and non-ES */) { preamble += "#define GL_OVR_multiview 1\n" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 7c3e0f828b..504c62bd62 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -4,6 +4,7 @@ // Copyright (C) 2017, 2022-2024 Arm Limited. // Copyright (C) 2015-2018 Google, Inc. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. +// Modifications Copyright (C) 2024 Valve Corporation. // // All rights reserved. // @@ -223,6 +224,7 @@ const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_re const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume"; const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2"; const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites"; +const char* const E_GL_EXT_texture_offset_non_const = "GL_EXT_texture_offset_non_const"; // Arrays of extensions for the above viewportEXTs duplications diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 2fae237a2f..0ab9e4b078 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -1035,11 +1035,11 @@ class TIntermediate { #endif bool usingScalarBlockLayout() const { - for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) { - if (*extIt == E_GL_EXT_scalar_block_layout) - return true; - } - return false; + return IsRequestedExtension(E_GL_EXT_scalar_block_layout); + } + + bool usingTextureOffsetNonConst() const { + return IsRequestedExtension(E_GL_EXT_texture_offset_non_const); } bool IsRequestedExtension(const char* extension) const diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index cf52bd8993..6399712221 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -561,6 +561,9 @@ INSTANTIATE_TEST_SUITE_P( "spv.atomicRvalue.error.vert", "spv.sampledImageBlock.frag", "spv.multiple.var.same.const.frag", + "spv.textureoffset_non_const.vert", + "spv.sparsetextureoffset_non_const.vert", + "spv.sparsetextureoffset_non_const_fail.vert", })), FileNameAsCustomTestSuffix ); diff --git a/known_good.json b/known_good.json index f2ed725b35..a6af44a378 100644 --- a/known_good.json +++ b/known_good.json @@ -5,7 +5,7 @@ "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Tools", "subdir" : "External/spirv-tools", - "commit": "4d2f0b40bfe290dea6c6904dafdf7fd8328ba346" + "commit": "066c3d52c2fca8d9df79ca37055c3f5eddf2ffce" }, { "name" : "spirv-tools/external/spirv-headers",