Direct3D 12 - Watch out for non-uniform resource index!

Sep 2015

Direct3D 12 - Watch out for non-uniform resource index!

DirectX 12 allows us to use arrays of resources (descriptor tables) and refer to them from a shader code by an index. The index can be constant or variable. But there is a big trap waiting for shader developers doing that! Microsoft just updated their public documentation in this regard (see Resource Binding in HLSL), so now I can talk about it.

In D3D12, resource index is expected to be uniform (convergent) by default. It means the index, even if dynamic, should be the same across whole draw call (all vertices/pixels/etc.). For example, it can be a result of some calculations, which depend on parameters coming from a constant buffer. Example code:

Texture2D<float4> textures[16] : register(t0);
SamplerState samp : register(s0);
struct SConstantBuffer
    uint MaterialId;
ConstantBuffer<SConstantBuffer> cb : register(b0);

float4 PS(
    in float2 texCoords : TEXCOORD0 ) : SV_Target
    uint materialId = cb.MaterialId;
    return textures[materialId].Sample(samp, texCoords);

Why is it this way? That is because on low level, GPU-s are made of SIMD processors. Each of its small processors executes shader instructions over multiple "SIMD threads" (or "warps", or "wavefronts", however you call them), not a single (scalar) value. Because of that, knowing that the resource index will always be the same on all SIMD threads can result in some optimizations and more efficient execution.

Resource indices in Direct3D 12 actually can be non-uniform (divergent) - different in every vertex/pixel/etc., like when they are result of some calculations based on vertex attributes or pixel position. But they must be then surrounded by a special, "pseudo"-function in HLSL, called NonUniformResourceIndex. For example:

Texture2D<float4> textures[16] : register(t0);
SamplerState samp : register(s0);

float4 PS(
    in float2 texCoords : TEXCOORD0,
    in uint materialId : MATERIAL_ID ) : SV_Target
    return textures[NonUniformResourceIndex(materialId)].Sample(samp, texCoords);

This may look a bit unintuitive, so I expect many developers will make the mistake and omit this function. If you use a non-uniform value as resource index, but forget to mark it with NonUniformResourceIndex, HLSL compiler probably won't warn you about it. It may even work in some cases and on some GPU-s, while it will give invalid (undefined) results on others. So similarly to the issue with reduced precision in normalize/length operations in GLSL, this is a thing to be careful with when coding your shaders in HLSL using new Shader Model 5.1.

Comments (3) | Tags: directx | Author: Adam Sawicki | Share


Matias N. Goldberg
2015-09-28 16:49:54
Nice catch!

Somehow, I don't think NonUniformResourceIndex is supported by all tiers, since divergent addressing w/ bindless textures in OpenGL was undefined behavior (basically tip was "don't do it" because some HW would go kapput, others would return garbage, others would do the correct thing, particularly the newer models)

I'm guessing this "NonUniformResourceIndex" qualifier just means "we'll refuse to run if we encounter incompatible hardware". I doubt it will be used to correct rendering even on old HW, but I'll be glad to be mistaken.
Adam Sawicki
2015-09-28 21:18:17
Matias N. Goldberg: No, non-uniform resource indexing is supported even on older hardware and lower tiers, and the flag really is important.
2017-02-22 09:52:00
people's well-being, and give them a little more respect, a little more room, I believe that your friendly nature of the people will be able to exchange for a gentle fragrance. Man, to learn respectful and humble, with people, not easy to hurt anyone. A real meaning people, is never so self-righteous, seeking only their feelings in front of others abrupt aggressive, assertive and even blind head domineering! His cultivation will tell him what is appropriate retreat, brave moment, I can not be brave; courageous moderate, is a graceful, courageous if excessive, it appears arrogant.Life is like a station, gathering dispersed; yesterday, like a landscape, saw blurred; time is like a passing, remember the forgotten; life is like a funnel, has been He lost; friendship, like a banquet table, warm up the cold. And love is a kind of helpless, the heart will be pain; heartbreak, evolved into an attitude, indulgence convergence; life is a calm, cried laughed.Life, sometimes need to precipitation, but also need experience. Have enough time to reflect, but also has enough experience to grow, so as to allow yourself to become more perfect, more wise, more mature indifferent charm. The face of things, when you are no longer eager to deny error, you first learned an important lesson. Man to dare to dare, can be beneficial to himself, but to detract from him! The best in life is a pure good heart, honest. Do more, we shall have less; not complain, often smiling; not greedy, understand contentment!Does not float is not dry, do not fight do not rob, do not care about flashy things, not to care despicable person! Never let yourself get lost in someone else's words Fun Fun language, because no one can have a cute flower blooming invincible charm, it is not necessary because a person can easily change their word, insist on doing their own before It is unique!Through the years, there is always successful, there is always incomplete; ever desire, always burning, always in expansion; the original dream, always burst, always far away. I love hearts, always worried, always thinking about ......Life is a one-way trip to the car, the best thing to do is to treat yourself well, cherish today, looking forward to tomorrow. Those who walked, miss, have not come back; lost, and lost, are not complex ownership. So we do not go in a hurry, the love to Love; the left, and to retain good faith; to fully experience the feelings, to cherish the treasure. Under remember

Post comment

Nick *
Your name or nickname
Your contact information (optional, will not be shown)
Text *
Content of your comment
Calculate *
(* - required field)
STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2017 Adam Sawicki
Copyright © 2004-2017 Adam Sawicki