着色器可见描述符堆

着色器可见描述符堆是着色器可通过描述符表引用的描述符堆。

概述

着色器可以通过描述符表引用的描述符堆有几种风格:一种堆类型D3D12_SRV_UAV_CBV_DESCRIPTOR_HEAP,可以包含着色器资源视图、无序访问视图和常量缓冲区视图,所有这些内容都混合在一起。 堆中的任何给定位置都可以是列出的描述符类型之一。 另一个堆类型(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)仅存储采样器,这反映了以下事实:对于大多数硬件,采样器独立于 SRV、UAV、CBV 进行管理。

可能要求这些类型的描述符堆为着色器可见,也可能要求创建堆时为不可见(后者非着色器可见,对于在 CPU 上暂存描述符非常有用)。 要求为着色器可见时,上述每种堆类型都可能对任何单个描述符堆分配有硬件大小限制。

应用程序可以创建任意数量的描述符堆,并且非着色器可见描述符堆的大小不受限制。 如果应用程序创建的着色器可见描述符堆小于硬件大小限制,则驱动程序可以选择从较大的基础描述符堆中二次分配描述符堆,以便多个 API 描述符堆适合于一个硬件描述符堆。 可能发生这种情况的原因是,对于某些硬件,执行期间在硬件描述符堆之间进行切换需要 GPU 等待空闲(以确保对之前的描述符堆的 GPU 引用已经完成)。 如果应用程序创建的所有描述符堆都符合适用硬件堆的最大容量,那么渲染期间切换 API 描述符堆时就不会发生这种等待。 但应用程序必须考虑到切换当前描述符堆可能导致等待空闲的可能性。

为了避免切换描述符堆时受此可能发生的等待空闲影响,应用程序可以在渲染时利用时间间隔,而这将导致 GPU 在切换描述符堆时由于其他原因处于空闲状态,因为任何情况下等待空闲都会发生。

API 参考中介绍了用于在命令列表/捆绑记录期间将标识描述符堆标识为着色器的机制和语义。

示例

下图显示了两个描述符堆,它们引用了存储在大型默认堆的两个槽中的两个独立 2D 纹理。 图形管道(包括着色器)可以访问着色器可见的描述符堆,因此管道可以使用 2D 纹理。

可见和非可见描述符堆

注意

对于描述符堆,通常对 CPU 可写入的 GPU 本地内存(称为写组合内存)数量的 GPU 硬件有限制。 通常对于所有进程而言,此限制为 96MB 左右。 例如,具有 32 字节描述符的 100 万成员描述符堆将使用 32MB。 如果必要,驱动程序将转而依靠系统内存,但最好不要创建大量的大型描述符堆。

 

描述符堆