图形API学习工程(22):D3D12的“Committed Resources”和“Placed resources”

工程GIT地址:https://gitee.com/yaksue/yaksue-graphics

疑问

在之前的博客《图形API学习工程(21):使用CubeMap纹理》中,D3D12的版本我主要参考了《DirectX12(D3D12)基础教程(五)——理解和使用捆绑包,加载并使用DDS Cube Map_Gamebaby Rock Sun的博客-CSDN博客》的代码,而他使用了CreateHeapCreatePlacedResource这两个我之前没使用过的函数:
在这里插入图片描述
他用这种方法最终得到了一个“中间资源”(pITextureUploadSkybox),将作为UpdateSubresources函数的pIntermediate参数。
在这里插入图片描述
对比之前我创建普通纹理的时候,我是使用CreateCommittedResource创建出那个中间资源 的。
在这里插入图片描述

那么问题来了:

  • 这两种创建方式的区别是什么?
  • 他们能够互相替换吗?

官方文档上的解释

微软D3D12文档上有一些相关的说明,我搬运一些并尝试翻译。但是由于牵扯到一些我并不熟悉的概念,因此翻译的意思很可能是不准确的,待日后修正。


《Uploading Different Types of Resources》中,官方对“资源”有如下记录:

Resources are the D3D concept which abstracts the usage of GPU physical memory. Resources require GPU virtual address space to access physical memory. Resource creation is free-threaded.

“资源”是D3D中对GPU物理内存的抽象。资源需要一个“GPU虚拟地址空间”(GPU virtual address space)来访问物理内存。资源的创建是“线程自由的”(free-threaded)

There are three types of resources with respect to virtual address creation and flexibility in D3D12:

根据“虚拟地址的创建”和“灵活度”的不同,D3D12有三种类型的资源:

Committed resources

Committed resources are the most common idea of D3D resources over the generations. Creating such a resource allocates virtual address range, an implicit heap large enough to fit the whole resource, and commits the virtual address range to the physical memory encapsulated by the heap. The implicit heap properties must be passed to match functional parity with previous D3D versions. Refer to ID3D12Device::CreateCommittedResource.

“Committed resources”是最常见的资源概念。当创建这种资源的时候:

  • “虚拟地址范围”(virtual address range)被分配
  • 一个隐式的 被分配,它足够大可以容纳整个资源
  • 向GPU物理内存提交 “虚拟地址范围”是被 所封装的。

The implicit heap properties must be passed to match functional parity with previous D3D versions(?)

详见ID3D12Device::CreateCommittedResource

Reserved resources

Reserved resources are equivalent to D3D11 tiled resources. On their creation, only a virtual address range is allocated and not mapped to any heap. The application will map such resources to heaps later. The capabilities of such resources are currently unchanged over D3D11, as they can be mapped to a heap at a 64KB tile granularity with UpdateTileMappings. Refer to ID3D12Device::CreateReservedResource

“Reserved resources”等价于D3D11的“tiled resources”。在创建的时候:

  • 只有“虚拟地址范围”被分配
  • 而并没有映射到任何

应用来负责随后将这个资源映射到 中。这种资源的能力与D3D11相比没有变化,他们能以 64KB tile的粒度来映射到 中,使用UpdateTileMappings函数。

详见ID3D12Device::CreateReservedResource

Placed resources

New for D3D12, applications may create heaps separate from resources. Afterward, the application may locate multiple resources within a single heap. This can be done without creating tiled or reserved resources, enabling the capabilities for all resource types able to be created directly by applications. Multiple resources may overlap, and the application must use the TiledResourceBarrier to re-use physical memory correctly. Refer to ID3D12Device::CreatePlacedResource

对于D3D12,应用可以创建独立于资源的 。之后,应用可以将多个资源定位于同一个 中。这不必通过创建 tiled 或者 reserved 资源就能完成。使得应用获得了直接创建所有类型资源的能力。多个资源可能会重叠,因此应用必须使用 TiledResourceBarrier 来正确地复用GPU物理内存。

详见ID3D12Device::CreatePlacedResource


而对于CreateCommittedResourceCreatePlacedResource二者的文档上的介绍如下:

ID3D12Device::CreateCommittedResource

Creates both a resource and an implicit heap, such that the heap is big enough to contain the entire resource, and the resource is mapped to the heap.

创建资源的同时也创建一个隐式的 。这个 足够大可以容纳整个资源,并且资源会映射到这个 上。

ID3D12Device::CreatePlacedResource

Creates a resource that is placed in a specific heap. Placed resources are the lightest weight resource objects available, and are the fastest to create and destroy.

在指定的 中创建资源。Placed resources 是可用的最轻量级的资源对象,最快创建与销毁。


从上面的文档来看,我的理解是:“Committed Resources”的创建更方便,而“Placed resources”的性能更好,但对使用者要求更高。

实践:将“Placed resources”替换成“Committed Resources”

然而,当前比起性能,我更关注保持代码简单,因为这样更利于学习。(在龙书中似乎也没搜到CreatePlacedResource的使用)

因此,我想尝试将当前工程里D3D12的“普通纹理”与“CubeMap纹理”中创建的方式统一,即都变成“Committed Resources”的形式。
在这里插入图片描述

试验后发现没问题
在这里插入图片描述

未来问题

  • 官方文档中的“GPU虚拟地址空间”(GPU virtual address space)是什么意思?更深入的知识值得探究。
  • 如果未来要使用“Placed resources”,那么该如何去维护各种

后记关于DDS的探究

在稍微进行一些重构后,现在我的D3D12Interface::CreateCubeMapTextureFromDDS已经和D3D12Interface::CreateTexture在流程结构上相似了:
在这里插入图片描述
看来接下来如果想脱离DDS,问题的重点在于探究在LoadDDSTextureFromFile函数中:

  • std::vector<D3D12_SUBRESOURCE_DATA>& subresources中的数据如何得到
  • ID3D12Resource** texture怎么创建(因为后续需要通过它知道资源的大小以及像素格式)

猜你喜欢

转载自blog.csdn.net/u013412391/article/details/113360200