DX12描述符堆管理 [英] DX12 Descriptor Heaps management

查看:250
本文介绍了DX12描述符堆管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,在观看dx12绑定视频并阅读了一些文档之后,我不确定100%是否确定我正确理解了如何管理堆。

So after watching the dx12 binding videos and reading through some docs, I'm not 100% sure if I understood correctly how to manage my heaps.

让我解释我在应用程序中无法实现的目标:
在初始化期间,我将填充两堆,其中一堆容纳采样器,另一堆容纳SRV,CBV和UAV。
这些堆将包含应用程序在其生命周期内将使用的所有资源。

Let me explain what I wan't to achieve in my application: During the initialisation, I'll be filling two heaps, one holding Samplers and the other one holding SRV, CBV and UAV. Those heaps will contain all the resources the application will be using during its life time.

现在开始介绍有趣的部分。要构建根签名,我将主要使用根描述符表。

Now starts the interesting part. To build the Root Signatures, I'll be using for the most part Root Descriptor Tables.

我们知道,一个表将包含范围,范围是基础着色器广告位,描述符数量和其他设置。
让我向您展示示例:

As we know, a table will hold ranges, a range being a base shader slot, number of descriptors and other settings. Let me show you and example:

Root Parameters
0 - root_table 
1 - root_table

0 root_table
CBV b1
CBV b6
SRV t0
SRV t2

1 root_table
Sampler s1
Sampler s4

如示例所示,可能存在不连续的范围(例如b0,b1,b2和b3),但是在记录命令列表期间,我们只能执行以下操作:

As shown in the example, there can be ranges that are non sequential (for example b0,b1,b2 and b3) but, during command list recording, we can only do:

ID3D12DescriptorHeaps* heaps[2] = {mCbvSrvUavHeap,mSamplerHeap};
mCmdList->SetDescriptorHeaps(2,heaps);

mCmdList->SetGraphicsRootDescriptorTable(0, mCbvSrvUavHeapGpuHanleStart);
mCmdList->SetGraphicsRootDescriptorTable(1, mSamplerHandleHanleStart);

这意味着我们需要在 mCbvSrvUavHeap 中正确排序描述符和 mSamplerHeap

That means that we will need to have the descriptors properly ordered in mCbvSrvUavHeap and mSamplerHeap.

例如:

mCbvSrvUavHeap 
CBV
CBV
SRV
SRV

这是我的问题所在。就像我最初说的那样,我将使用应用程序的所有资源创建两个大堆,但是,我无法将这些堆设置到命令列表中,因为它们将具有不会使用的其他描述符!

Here is where the problem is for me. As I initially said, I'll be creating two big heaps with all the resource for the application, but, I cannot set those heaps to the command list as they will have other descriptors that won't be used!

我该如何处理?我是否需要制作一个仅包含将要使用的描述符的新堆?

How can I handle this? Do I need to make a new Heap containing only the descriptors I will be using?

希望我解释得很好!

推荐答案

您误会了。描述符堆不是不变的,而是一个随时变化的对象。绑定描述符表时,实际上是从任何偏移量开始绑定它。交换描述符堆是您要不惜一切代价避免的一项昂贵操作。

You are understanding it wrong. A descriptor heap is not something immutable but an always changing object. When you bind a descriptor table, you are in fact binding it from any offset. Swapping descriptor heaps is a costly operation you want to avoid at all cost.

这个想法是在非GPU可见堆中准备描述符(只要您愿意,它们就可以仅仅是一个CPU分配的对象),然后使用 CopyDescriptor CopyDescriptorSimple

The idea is to prepare the descriptors in non GPU visible heaps ( as many as you like, they are merely a CPU allocated object ) and copy on demand into the GPU visible one in a ring buffer fashion way with CopyDescriptor or CopyDescriptorSimple.

假设您的着色器使用的表包含2个CBV和2个SRV,它们在堆中必须是连续的,因此您将从堆中分配一个数组4,您会得到一个堆偏移量,复制所需的描述符并将其与 SetGraphicsRootDescriptorTable 绑定。

Let say your shader use a table with 2 CBVs and 2 SRVs, they have to be continuous in the heap, so you will allocate from your heap an array of 4, you get a heap offset, copy the needed descriptors and bind it with SetGraphicsRootDescriptorTable.

注意堆中描述符的生命周期,因为在GPU使用它们完成处理命令之前,您无法覆盖描述符。最后,如果许多着色器共享来自相似根签名的某些公用表,则可以通过分解更新来节省处理费用。

One thing you will have to be careful is the life duration of the descriptor in you heap, as you cannot overwrite them until the GPU is done processing the commands using them. And last, if many shader share some common tables, from similar root signature, you can save on processing by factorizing the updates.

这篇关于DX12描述符堆管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆