Skip to content

Commit

Permalink
Check argument constness with SparseTextureOffset functions
Browse files Browse the repository at this point in the history
There are a few checks that were missing for sparse variants of these
functions.
  • Loading branch information
rg3igalia committed Nov 5, 2024
1 parent b2ba7ec commit 2dcce0b
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 7 deletions.
194 changes: 194 additions & 0 deletions Test/baseResults/spv.sparsetextureoffset_non_const.vert.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
spv.sparsetextureoffset_non_const.vert
Validation failed
// 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
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions Test/spv.sparsetextureoffset_non_const.vert
Original file line number Diff line number Diff line change
@@ -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;
}
35 changes: 35 additions & 0 deletions Test/spv.sparsetextureoffset_non_const_fail.vert
Original file line number Diff line number Diff line change
@@ -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;
}
35 changes: 28 additions & 7 deletions glslang/MachineIndependent/ParseHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2541,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;
Expand All @@ -2578,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()) {
Expand All @@ -2598,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() &&
Expand Down
2 changes: 2 additions & 0 deletions gtests/Spv.FromFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ INSTANTIATE_TEST_SUITE_P(
"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
);
Expand Down

0 comments on commit 2dcce0b

Please sign in to comment.