diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 9409dcc25e..5787e3d526 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -4835,6 +4835,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO 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 operands; operands.push_back(pointer); diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 6982205d02..b3b95224b4 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -2731,7 +2731,13 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu } // load through the access chain - id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment); + id = collapseAccessChain(); + // Apply nonuniform both to the access chain and the loaded value. + // Buffer accesses need the access chain decorated, and this is where + // loaded image types get decorated. TODO: This should maybe move to + // createImageTextureFunctionCall. + addDecoration(id, nonUniform); + id = createLoad(id, memoryAccess, scope, alignment); setPrecision(id, precision); addDecoration(id, nonUniform); } diff --git a/Test/baseResults/spv.RayGenShaderArray.rgen.out b/Test/baseResults/spv.RayGenShaderArray.rgen.out index e9143049d8..7a024ecf74 100644 --- a/Test/baseResults/spv.RayGenShaderArray.rgen.out +++ b/Test/baseResults/spv.RayGenShaderArray.rgen.out @@ -40,6 +40,7 @@ spv.RayGenShaderArray.rgen Decorate 60(accNV1) DescriptorSet 0 Decorate 60(accNV1) Binding 1 Decorate 75 DecorationNonUniformEXT + Decorate 76 DecorationNonUniformEXT Decorate 77 DecorationNonUniformEXT Decorate 88(payload) Location 0 2: TypeVoid diff --git a/Test/baseResults/spv.nonuniform.frag.out b/Test/baseResults/spv.nonuniform.frag.out index 32b64662a8..6b7d4073b5 100644 --- a/Test/baseResults/spv.nonuniform.frag.out +++ b/Test/baseResults/spv.nonuniform.frag.out @@ -59,16 +59,20 @@ spv.nonuniform.frag Name 203 "S" MemberName 203(S) 0 "a" Name 205 "s" + Decorate 9(nupi) DecorationNonUniformEXT Decorate 13 DecorationNonUniformEXT Decorate 17(nu_li) DecorationNonUniformEXT + Decorate 17(nu_li) DecorationNonUniformEXT Decorate 19 DecorationNonUniformEXT Decorate 24 DecorationNonUniformEXT Decorate 28 DecorationNonUniformEXT Decorate 29 DecorationNonUniformEXT Decorate 35(nu_inv4) Location 0 Decorate 35(nu_inv4) DecorationNonUniformEXT + Decorate 39 DecorationNonUniformEXT Decorate 40 DecorationNonUniformEXT Decorate 41(nu_gf) DecorationNonUniformEXT + Decorate 41(nu_gf) DecorationNonUniformEXT Decorate 42 DecorationNonUniformEXT Decorate 43 DecorationNonUniformEXT Decorate 47(inputAttachmentDyn) DescriptorSet 0 @@ -85,47 +89,71 @@ spv.nonuniform.frag Decorate 92(nu_ii) Flat Decorate 92(nu_ii) Location 1 Decorate 92(nu_ii) DecorationNonUniformEXT + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 93 DecorationNonUniformEXT + Decorate 95 DecorationNonUniformEXT Decorate 96 DecorationNonUniformEXT MemberDecorate 99(bname) 0 Offset 0 Decorate 99(bname) BufferBlock Decorate 102(storageBuffer) DescriptorSet 0 Decorate 102(storageBuffer) Binding 4 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 103 DecorationNonUniformEXT + Decorate 104 DecorationNonUniformEXT Decorate 105 DecorationNonUniformEXT Decorate 112(sampledImage) DescriptorSet 0 Decorate 112(sampledImage) Binding 5 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 113 DecorationNonUniformEXT + Decorate 115 DecorationNonUniformEXT Decorate 116 DecorationNonUniformEXT Decorate 127(storageImage) DescriptorSet 0 Decorate 127(storageImage) Binding 6 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 128 DecorationNonUniformEXT + Decorate 130 DecorationNonUniformEXT Decorate 131 DecorationNonUniformEXT Decorate 139(inputAttachment) DescriptorSet 0 Decorate 139(inputAttachment) Binding 7 Decorate 139(inputAttachment) InputAttachmentIndex 1 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 140 DecorationNonUniformEXT + Decorate 141 DecorationNonUniformEXT Decorate 142 DecorationNonUniformEXT Decorate 149(uniformTexelBuffer) DescriptorSet 0 Decorate 149(uniformTexelBuffer) Binding 8 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 150 DecorationNonUniformEXT + Decorate 151 DecorationNonUniformEXT Decorate 152 DecorationNonUniformEXT Decorate 160(storageTexelBuffer) DescriptorSet 0 Decorate 160(storageTexelBuffer) Binding 9 + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 161 DecorationNonUniformEXT + Decorate 162 DecorationNonUniformEXT Decorate 163 DecorationNonUniformEXT Decorate 170(v) DecorationNonUniformEXT + Decorate 172 DecorationNonUniformEXT Decorate 173 DecorationNonUniformEXT + Decorate 174 DecorationNonUniformEXT Decorate 175 DecorationNonUniformEXT + Decorate 179 DecorationNonUniformEXT Decorate 180 DecorationNonUniformEXT + Decorate 181 DecorationNonUniformEXT Decorate 182 DecorationNonUniformEXT + Decorate 92(nu_ii) DecorationNonUniformEXT Decorate 186 DecorationNonUniformEXT + Decorate 187 DecorationNonUniformEXT Decorate 188 DecorationNonUniformEXT + Decorate 189 DecorationNonUniformEXT Decorate 190 DecorationNonUniformEXT Decorate 195(m) DecorationNonUniformEXT + Decorate 196 DecorationNonUniformEXT Decorate 197 DecorationNonUniformEXT Decorate 205(s) DecorationNonUniformEXT + Decorate 206 DecorationNonUniformEXT Decorate 207 DecorationNonUniformEXT + Decorate 208 DecorationNonUniformEXT Decorate 209 DecorationNonUniformEXT 2: TypeVoid 3: TypeFunction 2 diff --git a/Test/baseResults/spv.nonuniform2.frag.out b/Test/baseResults/spv.nonuniform2.frag.out index db24f4177f..759f4c4ea8 100644 --- a/Test/baseResults/spv.nonuniform2.frag.out +++ b/Test/baseResults/spv.nonuniform2.frag.out @@ -25,6 +25,7 @@ spv.nonuniform2.frag Decorate 16(rIndex) Flat Decorate 16(rIndex) Location 3 Decorate 18 DecorationNonUniformEXT + Decorate 20 DecorationNonUniformEXT Decorate 21 DecorationNonUniformEXT 2: TypeVoid 3: TypeFunction 2 diff --git a/Test/baseResults/spv.nonuniform3.frag.out b/Test/baseResults/spv.nonuniform3.frag.out new file mode 100644 index 0000000000..93142619c0 --- /dev/null +++ b/Test/baseResults/spv.nonuniform3.frag.out @@ -0,0 +1,61 @@ +spv.nonuniform3.frag +// 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 0000000000..a9dd52080e --- /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/baseResults/spv.nonuniform5.frag.out b/Test/baseResults/spv.nonuniform5.frag.out new file mode 100644 index 0000000000..8ce131a847 --- /dev/null +++ b/Test/baseResults/spv.nonuniform5.frag.out @@ -0,0 +1,56 @@ +spv.nonuniform5.frag +// Module Version 10000 +// Generated by (magic number): 80008 +// Id's are bound by 23 + + Capability Shader + Capability ShaderNonUniformEXT + Capability RuntimeDescriptorArrayEXT + Capability UniformBufferArrayNonUniformIndexingEXT + 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 10 "UBO" + MemberName 10(UBO) 0 "v" + Name 13 "ubos" + Name 16 "Index" + Decorate 9(FragColor) Location 0 + MemberDecorate 10(UBO) 0 Offset 0 + Decorate 10(UBO) Block + Decorate 13(ubos) DescriptorSet 0 + Decorate 13(ubos) Binding 0 + Decorate 16(Index) Flat + Decorate 16(Index) Location 0 + Decorate 18 DecorationNonUniformEXT + Decorate 21 DecorationNonUniformEXT + Decorate 22 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(UBO): TypeStruct 7(fvec4) + 11: TypeRuntimeArray 10(UBO) + 12: TypePointer Uniform 11 + 13(ubos): 12(ptr) Variable Uniform + 14: TypeInt 32 1 + 15: TypePointer Input 14(int) + 16(Index): 15(ptr) Variable Input + 19: 14(int) Constant 0 + 20: TypePointer Uniform 7(fvec4) + 4(main): 2 Function None 3 + 5: Label + 17: 14(int) Load 16(Index) + 18: 14(int) CopyObject 17 + 21: 20(ptr) AccessChain 13(ubos) 18 19 + 22: 7(fvec4) Load 21 + Store 9(FragColor) 22 + Return + FunctionEnd diff --git a/Test/spv.nonuniform3.frag b/Test/spv.nonuniform3.frag new file mode 100644 index 0000000000..e79865e358 --- /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 0000000000..2eb98aa123 --- /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/Test/spv.nonuniform5.frag b/Test/spv.nonuniform5.frag new file mode 100644 index 0000000000..ef70779531 --- /dev/null +++ b/Test/spv.nonuniform5.frag @@ -0,0 +1,15 @@ +#version 450 +#extension GL_EXT_nonuniform_qualifier : require + +layout(location = 0) flat in int Index; +layout(location = 0) out vec4 FragColor; + +layout(set = 0, binding = 0) uniform UBO +{ + vec4 v; +} ubos[]; + +void main() +{ + FragColor = ubos[nonuniformEXT(Index)].v; +} diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 38fa742f68..d8bb3cf18c 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3089,7 +3089,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T 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 da4eeb48b1..110313e9f0 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -356,6 +356,9 @@ INSTANTIATE_TEST_CASE_P( "spv.nonSquare.vert", "spv.nonuniform.frag", "spv.nonuniform2.frag", + "spv.nonuniform3.frag", + "spv.nonuniform4.frag", + "spv.nonuniform5.frag", "spv.noWorkgroup.comp", "spv.offsets.frag", "spv.Operations.frag", diff --git a/known_good.json b/known_good.json index 8c0a4436e4..1f108db82e 100644 --- a/known_good.json +++ b/known_good.json @@ -5,7 +5,7 @@ "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Tools", "subdir" : "External/spirv-tools", - "commit" : "79f8caf9154a0328a87424354bd10ab69e811185" + "commit" : "dd3d91691f1e1dc4c0f42818756cf5e165c8918c" }, { "name" : "spirv-tools/external/spirv-headers",