Open HansKristian-Work opened 5 years ago
Related to this, the Vulkan spec says:
If an instruction loads from or stores to a resource (including atomics and image instructions) and the resource descriptor being accessed is not dynamically uniform, then the operand corresponding to that resource (e.g. the pointer or sampled image operand) must be decorated with NonUniformEXT.
In the glslang test, spv.nonuniform2.frag:
#version 450
#extension GL_EXT_nonuniform_qualifier : require
layout(set=0,binding=4,rgba32f) uniform imageBuffer data[];
layout(location = 0) out vec4 FragColor;
layout(location = 3) in flat int rIndex;
void main()
{
FragColor = imageLoad(data[nonuniformEXT(rIndex)], 0);
}
Generates:
Decorate 18 DecorationNonUniformEXT
Decorate 21 DecorationNonUniformEXT
...
17: 14(int) Load 16(rIndex)
18: 14(int) CopyObject 17
20: 19(ptr) AccessChain 13(data) 18
21: 10 Load 20
It seems like id 20 should be decorated with NonUniformEXT according to the Vulkan spec.
@jeffbolznv any opinions on the specifics of what should be decorated with NonUniformEXT exactly?
The relevant part of the Vulkan SPIR-V environment is:
* If an instruction loads from or stores to a resource (including atomics
and image instructions) and the resource descriptor being accessed is
not dynamically uniform, then the operand corresponding to that resource
(e.g. the pointer or sampled image operand) must: be decorated with
code:NonUniformEXT.
So in the first shader id 39 should be NonUniformEXT, and in the second shader id 21 should be NonUniformEXT. Additional ids being NonUniformEXT is harmless, but doesn't really have any effect.
The motivation for this is that implementations may need to know at call time whether they need to loop over all the unique resources.
If I modify the second shader to be:
#version 450
#extension GL_EXT_nonuniform_qualifier : require
layout(set=0,binding=4,rgba32f) uniform imageBuffer data[];
layout(location = 0) out vec4 FragColor;
layout(location = 3) in flat int rIndex;
layout(set=1,binding=0) buffer bname { vec4 f; } ssbo_in[];
void main()
{
vec4 a = ssbo_in[nonuniformEXT(rIndex)].f;
FragColor = imageLoad(data[nonuniformEXT(rIndex)], 0);
}
I get:
Decorate 18 DecorationNonUniformEXT
Decorate 22 DecorationNonUniformEXT
...
17: 14(int) Load 16(rIndex)
18: 14(int) CopyObject 17
21: 20(ptr) AccessChain 13(ssbo_in) 18 19
22: 7(fvec4) Load 21
It seems like 21 should be decorated, but is not. Am I interpreting this correctly?
I agree, 21 should be decorated in that case.
I have this test shader:
Commit: 4b4b41a63499d34c527ee4f714dde8072f60c900. The SPIR-V spec says that the parameter passed to sampling instructions must be marked NonUniformEXT, but only the image and samplers are marked as such here.