Advertisement

DX12 generic root signature performance implications

Started by October 01, 2024 07:46 AM
0 comments, last by graphicsprogrammer7869 3 months, 1 week ago

Hello.

Many if not most games seem to use the global root signature model to avoid the cost of switching root signatures. But from what I have seen, these root signatures lead to unnecessarily big descriptor tables leading to some memory waste.

Is there any disadvantage (memory/performance) of declaring a generic root signature such as this

"DescriptorTable("                                                      \
		"SRV(t0, numDescriptors = unbounded, space = 0", offset = 0),"  \
		"CBV(b0, numDescriptors = unbounded, space = 0", offset = 0),"  \
		"UAV(u0, numDescriptors = unbounded, space = 0", offset = 0))," \
"DescriptorTable("                                                      \
		"SRV(t0, numDescriptors = unbounded, space = 1", offset = 0),"  \
		"CBV(b0, numDescriptors = unbounded, space = 1", offset = 0),"  \
		"UAV(u0, numDescriptors = unbounded, space = 1", offset = 0))," \

With a layout like this, you won't be stuck with fixed descriptor table sizes (paying extra memory costs…) and still be able to use the same root signature throughout the render pipeline.

You can declare resources like this

// Table 0
Texture2D envMap : register(t0, space0);
Texture3D clut : register(t1, space0);
ConstantBuffer<PerFrame> frameData : register(b2, space0);

// Table 1
Texture2D albedoMap : register(t0, space1);
Texture2D normalMap : register(t1, space1);
ByteAddressBuffer materialData : register(t2, space1);
ConstantBuffer<Object> objectData : register(b3, space1);

So resource declaration basically follows Vulkan binding model in this case (to work with the register aliasing). And you can have descriptor tables of different sizes but same root signature

But is a root signature like this optimal on the driver side?

Thank you

This topic is closed to new replies.

Advertisement