Allow nonuniformEXT() on sampler types.
Also add missing NonUniformEXT decoration on OpImageTexelPointer.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 9409dcc..5787e3d 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -4835,6 +4835,9 @@
resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
}
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
+ if (imageType.getQualifier().nonUniform) {
+ builder.addDecoration(pointer, spv::DecorationNonUniformEXT);
+ }
std::vector<spv::Id> operands;
operands.push_back(pointer);
diff --git a/Test/baseResults/spv.nonuniform3.frag.out b/Test/baseResults/spv.nonuniform3.frag.out
new file mode 100644
index 0000000..1e95b3e
--- /dev/null
+++ b/Test/baseResults/spv.nonuniform3.frag.out
@@ -0,0 +1,62 @@
+spv.nonuniform3.frag
+Validation failed
+// Module Version 10000
+// Generated by (magic number): 80008
+// Id's are bound by 32
+
+ Capability Shader
+ Capability ShaderNonUniformEXT
+ Capability RuntimeDescriptorArrayEXT
+ Extension "SPV_EXT_descriptor_indexing"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 9 16
+ ExecutionMode 4 OriginUpperLeft
+ Source GLSL 450
+ SourceExtension "GL_EXT_nonuniform_qualifier"
+ Name 4 "main"
+ Name 9 "FragColor"
+ Name 13 "uTex"
+ Name 16 "Index"
+ Name 23 "uSamp"
+ Decorate 9(FragColor) Location 0
+ Decorate 13(uTex) DescriptorSet 0
+ Decorate 13(uTex) Binding 0
+ Decorate 16(Index) Flat
+ Decorate 16(Index) Location 0
+ Decorate 23(uSamp) DescriptorSet 1
+ Decorate 23(uSamp) Binding 0
+ Decorate 27 DecorationNonUniformEXT
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypePointer Output 7(fvec4)
+ 9(FragColor): 8(ptr) Variable Output
+ 10: TypeImage 6(float) 2D sampled format:Unknown
+ 11: TypeRuntimeArray 10
+ 12: TypePointer UniformConstant 11
+ 13(uTex): 12(ptr) Variable UniformConstant
+ 14: TypeInt 32 1
+ 15: TypePointer Input 14(int)
+ 16(Index): 15(ptr) Variable Input
+ 18: TypePointer UniformConstant 10
+ 21: TypeSampler
+ 22: TypePointer UniformConstant 21
+ 23(uSamp): 22(ptr) Variable UniformConstant
+ 25: TypeSampledImage 10
+ 28: TypeVector 6(float) 2
+ 29: 6(float) Constant 1056964608
+ 30: 28(fvec2) ConstantComposite 29 29
+ 4(main): 2 Function None 3
+ 5: Label
+ 17: 14(int) Load 16(Index)
+ 19: 18(ptr) AccessChain 13(uTex) 17
+ 20: 10 Load 19
+ 24: 21 Load 23(uSamp)
+ 26: 25 SampledImage 20 24
+ 27: 25 CopyObject 26
+ 31: 7(fvec4) ImageSampleImplicitLod 27 30
+ Store 9(FragColor) 31
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/spv.nonuniform4.frag.out b/Test/baseResults/spv.nonuniform4.frag.out
new file mode 100644
index 0000000..a9dd520
--- /dev/null
+++ b/Test/baseResults/spv.nonuniform4.frag.out
@@ -0,0 +1,50 @@
+spv.nonuniform4.frag
+// Module Version 10000
+// Generated by (magic number): 80008
+// Id's are bound by 24
+
+ Capability Shader
+ Capability ImageBuffer
+ Capability ShaderNonUniformEXT
+ Capability RuntimeDescriptorArrayEXT
+ Capability StorageTexelBufferArrayNonUniformIndexingEXT
+ Extension "SPV_EXT_descriptor_indexing"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 13
+ ExecutionMode 4 OriginUpperLeft
+ Source GLSL 450
+ SourceExtension "GL_EXT_nonuniform_qualifier"
+ Name 4 "main"
+ Name 10 "data"
+ Name 13 "rIndex"
+ Decorate 10(data) DescriptorSet 0
+ Decorate 10(data) Binding 4
+ Decorate 13(rIndex) Flat
+ Decorate 13(rIndex) Location 3
+ Decorate 15 DecorationNonUniformEXT
+ Decorate 21 DecorationNonUniformEXT
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 0
+ 7: TypeImage 6(int) Buffer nonsampled format:R32ui
+ 8: TypeRuntimeArray 7
+ 9: TypePointer UniformConstant 8
+ 10(data): 9(ptr) Variable UniformConstant
+ 11: TypeInt 32 1
+ 12: TypePointer Input 11(int)
+ 13(rIndex): 12(ptr) Variable Input
+ 16: TypePointer UniformConstant 7
+ 18: 11(int) Constant 0
+ 19: 6(int) Constant 0
+ 20: TypePointer Image 6(int)
+ 22: 6(int) Constant 1
+ 4(main): 2 Function None 3
+ 5: Label
+ 14: 11(int) Load 13(rIndex)
+ 15: 11(int) CopyObject 14
+ 17: 16(ptr) AccessChain 10(data) 15
+ 21: 20(ptr) ImageTexelPointer 17 18 19
+ 23: 6(int) AtomicIAdd 21 22 19 19
+ Return
+ FunctionEnd
diff --git a/Test/spv.nonuniform3.frag b/Test/spv.nonuniform3.frag
new file mode 100644
index 0000000..e79865e
--- /dev/null
+++ b/Test/spv.nonuniform3.frag
@@ -0,0 +1,10 @@
+#version 450
+#extension GL_EXT_nonuniform_qualifier : require
+layout(set = 0, binding = 0) uniform texture2D uTex[];
+layout(set = 1, binding = 0) uniform sampler uSamp;
+layout(location = 0) flat in int Index;
+layout(location = 0) out vec4 FragColor;
+void main()
+{
+ FragColor = texture(nonuniformEXT(sampler2D(uTex[Index], uSamp)), vec2(0.5));
+}
diff --git a/Test/spv.nonuniform4.frag b/Test/spv.nonuniform4.frag
new file mode 100644
index 0000000..2eb98aa
--- /dev/null
+++ b/Test/spv.nonuniform4.frag
@@ -0,0 +1,8 @@
+#version 450
+#extension GL_EXT_nonuniform_qualifier : require
+layout(set=0,binding=4,r32ui) uniform uimageBuffer data[];
+layout(location = 3) in flat int rIndex;
+void main()
+{
+ imageAtomicAdd(data[nonuniformEXT(rIndex)], 0, 0);
+}
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 38fa742..d8bb3cf 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -3089,7 +3089,7 @@
error(loc, "constructor argument does not have a type", "constructor", "");
return true;
}
- if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) {
+ if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
error(loc, "cannot convert a sampler", "constructor", "");
return true;
}
diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp
index da4eeb4..dafff62 100644
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -356,6 +356,8 @@
"spv.nonSquare.vert",
"spv.nonuniform.frag",
"spv.nonuniform2.frag",
+ "spv.nonuniform3.frag",
+ "spv.nonuniform4.frag",
"spv.noWorkgroup.comp",
"spv.offsets.frag",
"spv.Operations.frag",