ID3D12Device::CreatePlacedResource 方法 (d3d12.h)

创建放置在特定堆中的资源。 放置的资源是可用的最轻量资源对象,是创建和销毁速度最快的资源对象。

应用程序可以通过在堆区域中重叠多个 Direct3D 放置和保留的资源来重复使用视频内存。 简单的内存重用模型(备注中所述)存在,以阐明哪些重叠资源在任何给定时间都有效。 若要最大化图形工具支持,不支持简单的模型数据继承;不支持细化磁贴和子资源无效。 仅发生完全重叠的资源无效。

语法

HRESULT CreatePlacedResource(
  ID3D12Heap                *pHeap,
  UINT64                    HeapOffset,
  const D3D12_RESOURCE_DESC *pDesc,
  D3D12_RESOURCE_STATES     InitialState,
  const D3D12_CLEAR_VALUE   *pOptimizedClearValue,
  REFIID                    riid,
  void                      **ppvResource
);

参数

pHeap

类型:[in] ID3D12Heap*

指向 ID3D12Heap 接口的指针,该接口表示在其中放置资源的堆。

HeapOffset

类型:UINT64

资源的偏移量(以字节为单位)。 HeapOffset 必须是资源的多个对齐方式,HeapOffset 加上资源大小必须小于或等于堆大小。 GetResourceAllocationInfo 必须用于了解纹理资源的大小。

pDesc

类型:[in] const D3D12_RESOURCE_DESC*

指向描述资源的 D3D12_RESOURCE_DESC 结构的指针。

InitialState

类型:D3D12_RESOURCE_STATES

资源的初始状态,作为 D3D12_RESOURCE_STATES 枚举常量的按位 OR 组合。

当资源与 D3D12_HEAP_TYPE_UPLOAD 堆一起创建时,InitialState 必须 D3D12_RESOURCE_STATE_GENERIC_READ。 将资源与 D3D12_HEAP_TYPE_READBACK 堆一起创建时,InitialState 必须 D3D12_RESOURCE_STATE_COPY_DEST

pOptimizedClearValue

类型:[in, 可选] const D3D12_CLEAR_VALUE*

指定描述明色默认值的 D3D12_CLEAR_VALUE

pOptimizedClearValue 指定一个最优化清除操作的值。 当创建的资源是具有 D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGETD3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL 标志的纹理时,应用程序应选择最常调用清除操作的值。

可以使用其他值调用清除操作,但这些操作将不像值与传递到资源创建的值匹配时那样高效。

D3D12_RESOURCE_DIMENSION_BUFFER一起使用时,pOptimizedClearValue 必须为 NULL。

riid

类型:REFIID

资源接口的全局唯一标识符(GUID)。 这是一个输入参数。

可以使用 __uuidof 宏获取资源的接口 REFIIDGUID。 例如,__uuidof(ID3D12Resource) 获取资源接口的 GUID。 尽管 riid 通常是 ID3D12Resource的 GUID,但对于任何接口,它可能是任何 GUID。 如果资源对象不支持此 GUID的接口,则创建失败并 E_NOINTERFACE

ppvResource

类型:[out, optional] void**

指向接收指向资源的指针的内存块的指针。 ppvResource 可以为 NULL,以启用功能测试。 当 ppvResource 为 NULL 时,不会创建任何对象,并且当 pResourceDesc 和其他参数有效时,将返回S_FALSE。

返回值

类型:HRESULT

如果内存不足而无法创建资源,此方法将返回 E_OUTOFMEMORY。 有关其他可能的返回值,请参阅 Direct3D 12 返回代码

言论

CreatePlacedResource 类似于完全将保留资源映射到堆中的偏移量;但与堆关联的虚拟地址空间也可以重复使用。

放置的资源比已提交的资源更轻,可以创建和销毁资源。 这是因为这些操作期间不会创建任何堆,也不会销毁堆。 此外,放置的资源允许比资源创建和销毁更轻的权重技术重复使用内存,即通过别名和别名屏障重复使用。 多个放置的资源可以同时在同一堆上相互重叠,但一次只能使用一个重叠的资源。

有两个放置的资源使用语义-一个简单的模型和一个高级模型。 我们建议你选择简单的模型(它将图形工具支持最大化到各种 GPU 生态系统),除非你发现你需要应用的高级模型。

简单模型

在此模型中,可以将放置的资源视为处于两种状态之一:活动或非活动状态。 GPU 从非活动资源读取或写入无效。 放置的资源以非活动状态创建。

若要在命令列表中激活具有别名屏障的资源,应用程序必须在 D3D12_RESOURCE_ALIASING_BARRIER::p ResourceAfter中传递资源。 激活期间,pResourceBefore 可以为 NULL。 与激活的资源共享物理内存的所有资源现在变为非活动状态,其中包括重叠的放置和保留资源。

应将别名屏障组合在一起并提交,以最大限度地提高效率。

激活后,必须进一步初始化具有呈现目标或深度模具标志的资源。 请参阅以下有关所需资源初始化的说明。

有关所需资源初始化的说明

某些资源类型仍然需要初始化。 具有呈现目标或深度模具标志的资源必须使用清除操作或完整子资源副本的集合进行初始化。 如果使用别名屏障表示两个别名资源之间的转换,则必须在别名屏障之后进行初始化。 每当在简单模型中激活资源时,仍需要此初始化。

在支持其他操作之前,必须使用以下操作之一初始化具有呈现目标或深度模具标志的放置和保留资源。

应用程序应首选最显式的操作,这会导致修改的纹素量最少。 请考虑以下示例。

  • 使用深度缓冲区解决像素可见性通常需要每个深度纹素从 1.0 或 0 开始。 因此,对于别名深度缓冲区初始化,清除 操作应该是最有效的选项。
  • 应用程序可以使用别名呈现目标作为音调映射的目标。 由于应用程序将在音调映射期间在每个像素上呈现,因此 DiscardResource 应该是初始化最有效的选项。

高级模型

在此模型中,可以忽略活动/非活动状态抽象。 相反,必须遵循这些较低级别的规则。

  • 别名屏障必须位于同一物理内存的两个不同的 GPU 资源访问之间,前提是这些访问位于同一 ExecuteCommandLists 调用中。
  • 某些类型别名资源的第一个呈现操作仍必须是初始化,就像简单模型一样。

初始化操作必须发生在整个子资源或 64KB 粒度上。 所有资源类型都支持整个子资源初始化。 缓冲区和纹理具有64KB_UNDEFINED_SWIZZLE或64KB_STANDARD_SWIZZLE纹理布局的缓冲区和纹理支持 64KB 初始化粒度(请参阅 D3D12_TEXTURE_LAYOUT)。

有关别名屏障的说明

别名屏障可以为 pResourceAfterpResourceBefore设置 NULL。 ExecuteCommandLists 和别名屏障的内存一致性定义相同,因此,当访问位于两个不同的 ExecuteCommandLists 调用中时,两个对同一物理内存的别名访问无需别名屏障。

对于 D3D12 高级使用模型,ExecuteCommandLists 的同步定义等效于别名屏障。 因此,应用程序可以在重用物理内存之间插入别名屏障,或确保物理内存的两个别名用法在两个单独的调用中发生,ExecuteCommandLists

激活量因资源属性而异。 具有未定义内存布局的纹理是最糟糕的情况,因为整个纹理必须以原子方式激活。 对于具有定义的布局的两个重叠资源,停用只能导致资源的重叠对齐区域。 甚至可以很好地定义数据继承。 有关详细信息,请参阅 内存别名和数据继承

要求

要求 价值
目标平台 窗户
标头 d3d12.h
D3D12.lib
DLL D3D12.dll

另请参阅

CreateCommittedResource

CreateReservedResource

ID3D12Device

共享堆