Vulkan NonUniformResourceIndex in Vulkan glsl

Recommended Posts

I need to index into a texture array using indices which are not dynamically uniform. This works fine on NVIDIA chips but you can see the artifacts on AMD due to the wavefront problem. This means, a lot of pixel invocations get the wrong index value. I know you fix this by using NonUniformResourceIndex in hlsl. Is there an equivalent for Vulkan glsl?

This is the shader code for reference. As you can see, index is an arbitrary value for each pixel and is not dynamically uniform. I fix this for hlsl by using NonUniformResourceIndex(index)

layout(set = 0, binding = 0) uniform sampler textureSampler;
layout(set = 0, binding = 1) uniform texture2D albedoMaps[256];

layout(location = 0) out vec4 oColor;

void main()
	uint index = calculate_arbitrary_texture_index();
	vec2 texCoord = calculate_texcoord();
	vec4 albedo = texture(sampler2D(albedoMaps[index], textureSampler), texCoord);

	oColor = albedo;

Thank you

Edited by mark_braga

Share this post

Link to post
Share on other sites

I'm not a Vulkan guy, but I Googled it and came across this information. It should set you on the right path:


shaderSampledImageArrayDynamicIndexing indicates whether arrays of samplers or sampled images can be indexed by dynamically uniform integer expressions in shader code. If this feature is not enabled, resources with a descriptor type of VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, orVK_DESCRIPTOR_TYPE_SAMPLED_IMAGE must be indexed only by constant integral expressions when aggregated into arrays in shader code. This also indicates whether shader modules can declare theSampledImageArrayDynamicIndexing capability.

Chances are this bool is true for NVIDIA and false for AMD?

Share this post

Link to post
Share on other sites

Vulkan doesn't have this intrinsic.


You'll have to do by hand what the compiler does for you when shaderSampledImageArrayDynamicIndexing is set to False:

uint NonUniformResourceIndex( uint textureIdx )
	while (true)
		uint currentIdx = readFirstInvocationARB(textureIdx);

		if (currentIdx == textureIdx)
			return currentIdx;
	return 0; //Execution should never land here




Edited by Matias Goldberg

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now