Practical Rendering and Computation with Direct3D 11
+ -

2.3.2复制资源

2024-06-17 3 0

许多情况下,必须将一个资源的内容复制到另一个资源。这可以用于特定算法的需要,或者将数据复制到具有不同访问能力的第二资源。在这两种情况下,都有多种方法可用于执行复制。我们将检查这些方法中的每一种,然后介绍它们可以用于的几种情况。这些方法与“操作资源”部分中介绍的方法不同,因为所有正在移动的数据都已在资源中定位,而以前的方法用于用CPU读写数据。

要将一个资源的完整内容复制到另一个资源,将使用设备上下文的复制资源方法。

void CopyResource(
    ID3DllResource *pDstResource,
    ID3DllResource *pSrcResource
);

这是一个相当简单的方法,只获取指向源和目标资源的指针。资源的类型和大小必须相同,并且具有兼容的格式。不可变资源和深度模具资源都不能作为目标。此外,多采样资源既不能用作源,也不能用作目标(我们将在本节稍后介绍如何检索多采样资源的内容)。

由于此方法复制完整的资源,因此最有可能用于将数据复制到具有所需使用配置的第二个资源。例如,如果使用computeshader生成数据缓冲区,并且应用程序需要将该缓冲区保存到硬盘,则无法直接映射和读取该缓冲区。这是因为用于无序访问视图的缓冲区必须具有默认用途,这意味着CPU无法读取该缓冲区。所有来自管道的输出都是如此——只有具有默认用法的资源才能从管道接收输出,并且CPU不能直接读取具有默认用途的资源。相反,将使用暂存使用创建第二个缓冲区资源,并将默认缓冲区的内容复制到暂存缓冲区。具有暂存用途的资源可以由CPU读取,这解决了将数据获取到应用程序的问题.

使用复制资源方法的一个示例是检索已由计算着色器的数据填充的附加结构化缓冲区的内容。由于追加结构化缓冲区具有默认的使用标志,因此需要使用CopyResource()方法将其内容复制到辅助暂存缓冲区。然后CPU可以使用暂存缓冲器来使用映射/取消映射方法读取内容。

复制子资源区域

复制资源的下一个技术是设备上下文的CopySubresourceRegion()方法。这种方法允许复制资源的一部分,而不是像上面描述的CopyResource()方法所要求的那样总是复制整个资源。清单2.53显示了该方法的原型

void CopySubresourceRegion(
    ID3D11Resource *pDstResource,
    UINT DstSubresource,
    UINT DstX,
    UINT DstY,
    UINT DstZ,
    ID3DllResource *pSrcResource,
    UINT SrcSubresource,
    const D3D11_B0X *pSrcBox
);

由于此方法允许将一个资源的子集复制到另一个资源,因此资源不需要具有相同的大小。但是,这两个资源必须具有相同的类型和兼容的格式。与源一样,目标可以是子源。这是通过在DstSubresource参数中使用从零开始的子资源索引来指定的。此外,可以在三个坐标中的每一个坐标中指定目标偏移量,以定位复制的数据。源资源数据也通过子资源索引来确定,并且要复制的区域通过D3D11_BOX选择来确定。

选择性地将资源的一部分复制到另一个资源的能力可以用于创建动态纹理图谱,该图谱将多个纹理组合成一个更大的纹理。这可以减少渲染场景所需的单个绘制调用的数量(第3章将更详细地讨论此类主题)。

复制结构计数Copy Structure Count

最后一种方法允许将一个资源的一部分复制到另一个资源中,尽管这是一种不太直接的复制技术。设备上下文的CopyStructureCount()方法允许将缓冲区资源的隐藏计数器复制到另一个资源中。方法原型如清单2.54所示。

void CopyStructureCount(
ID3DllBuffer *pDstBuffer,
UINT DstAlignedByteOffset,
ID3D11UnorderedAccessView *pSreView
)

正如我们在本章前面所看到的,有两个无序访问视图描述标志,它们创建了一个用于管理缓冲区内容的隐藏计数器。第一个是3DS11_BUFFER_UAV_FLAG_APPEND标志,它允许将缓冲区用作附加/消费缓冲区。第二个是D3Dll_BUFFER_UAV_FLAG_COUNTER标志,它直接添加隐藏的计数器,以便使用HLSL中的IncrementCounter()和DecrementCount()方法进行操作。CopyStructureCount()方法的工作原理是将指向包含计数器的UAV的指针作为源,然后将该值复制到DstAlignedByteOffset参数中指定的偏移量处的destinationbuffer中。

将计数器值复制到另一个缓冲区的功能在间接渲染操作中使用。当缓冲区由计算或像素着色器程序用顶点数据填充时,可以使用缓冲区资源间接渲染模型,该缓冲区资源指示要渲染的顶点数量。复制计数器值时,可以使用适当的索引将其放置在缓冲区的适当位置。然后,应用程序只需将间接缓冲区传递给draw调用。间接渲染在本章的“缓冲区资源”一节中进行了讨论,也在第3章中进行了介绍。

此功能也可用于暂存结构计数数据,以供CPU最终读取。这与我们在“复制资源”部分中描述的方式相同。

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!