Skip to main content
创建放置在特定堆中的资源。放置资源是可用的最轻量级资源对象,创建和销毁速度最快。 您的应用程序可以通过在堆区域上重叠多个 Direct3D 放置资源和保留资源来重用视频内存。存在简单内存重用模型(在 备注 中描述),可澄清在任何给定时间哪个重叠资源有效。为了最大化图形工具支持,简单模型不支持数据继承;并且不支持更细粒度的平铺和子资源失效。仅发生完全重叠资源失效。

语法

参数

pHeap
类型:ID3D12Heap *
指向 ID3D12Heap 接口的指针,该接口表示放置资源的堆。 HeapOffset
类型:UINT64
资源的偏移量(以字节为单位)。HeapOffset 必须是资源对齐的倍数,且 HeapOffset 加上资源大小必须小于或等于堆大小。必须使用 GetResourceAllocationInfo 来了解纹理资源的大小。 pDesc
类型: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
类型: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
类型:const IID &
资源接口的全局唯一标识符 (GUID)。这是一个输入参数。 可以使用 __uuidof 宏获取资源接口的 REFIIDGUID。例如,__uuidof(ID3D12Resource) 获取资源接口的 GUID。虽然 riid 最常是 ID3D12Resource 的 GUID,但它也可以是任何接口的任何 GUID。如果资源对象不支持此 GUID 的接口,则创建失败并返回 E_NOINTERFACE ppvResource
类型:void **
指向内存块的指针,该内存块接收指向资源的指针。ppvResource 可以为 NULL,以启用功能测试。当 ppvResource 为 NULL 时,不会创建对象,并且当 pResourceDesc 和其他参数有效时将返回 S_FALSE。

返回值

类型:HRESULT 如果没有足够的内存来创建资源,则此方法返回 E_OUTOFMEMORY。有关其他可能的返回值,请参阅 Direct3D 12 返回代码

备注

CreatePlacedResource 类似于将保留资源完全映射到堆中的偏移量;但与堆关联的虚拟地址空间也可以重用。 放置资源比提交资源具有更轻量的创建和销毁开销。这是因为在这些操作期间不会创建或销毁堆。此外,放置资源支持一种比资源创建和销毁更加轻量的内存重用技术——即通过别名和别名屏障进行重用。多个放置资源可以在同一堆上同时相互重叠,但一次只能使用一个重叠资源。 有两种放置资源使用语义——简单模型和高级模型。我们建议您选择简单模型(它最大化了跨 GPU 生态系统的图形工具支持),除非您发现您的应用程序需要高级模型。

简单模型

在此模型中,您可以将放置资源视为处于两种状态之一:活动或不活动。GPU 读取或写入不活动资源均无效。放置资源以不活动状态创建。 若要使用命令列表上的别名屏障激活资源,您的应用程序必须在 D3D12_RESOURCE_ALIASING_BARRIER::pResourceAfter 中传递资源。pResourceBefore 可以在激活期间保留为 NULL。所有与激活资源共享物理内存的资源现在都变为不活动状态,其中包括重叠的放置资源和保留资源。 应对别名屏障进行分组并一起提交,以最大限度地提高效率。 激活后,具有渲染目标或深度模板标志的资源必须进一步初始化。请参阅下面有关所需资源初始化的说明。

所需资源初始化的说明

某些资源类型仍需要初始化。具有渲染目标或深度模板标志的资源必须使用清除操作或完整子资源副本的集合进行初始化。如果使用别名屏障来表示两个别名资源之间的转换,则必须在别名屏障之后进行初始化。每当资源在简单模型中被激活时,仍需要进行此初始化。 具有渲染目标或深度模板标志的放置资源和保留资源必须在支持其他操作之前使用以下操作之一进行初始化。 应用程序应优先选择导致修改的纹素数量最少的最明确操作。请考虑以下示例。
  • 使用深度缓冲区来解决像素可见性通常要求每个深度纹素以 1.0 或 0 开始。因此,清除 操作应该是别名深度缓冲区初始化的最有效选项。
  • 应用程序可能会使用别名渲染目标作为色调映射的目标。由于应用程序将在色调映射期间在每个像素上渲染,因此 DiscardResource 应该是初始化的最有效选项。

高级模型

在此模型中,您可以忽略活动/非活动状态抽象。相反,您必须遵守这些较低级别的规则。
  • 只要这些访问在同一 ExecuteCommandLists 调用中,则同一物理内存的两个不同 GPU 资源访问之间必须存在别名屏障。
  • 与简单模型一样,对某些类型的别名资源的第一个渲染操作必须仍然是初始化。
初始化操作必须发生在整个子资源上,或以 64KB 粒度进行。所有资源类型都支持整个子资源初始化。对于具有 64KB_UNDEFINED_SWIZZLE 或 64KB_STANDARD_SWIZZLE 纹理布局(请参阅 D3D12_TEXTURE_LAYOUT)的缓冲区和纹理,支持以 64KB 偏移量对齐的 64KB 初始化粒度。

别名屏障的说明

别名屏障可以为 pResourceAfterpResourceBefore 都设置 NULL。ExecuteCommandLists 的内存一致性定义与别名屏障相同,因此当访问位于两个不同的 ExecuteCommandLists 调用中时,两个到相同物理内存的别名访问不需要别名屏障。 对于 D3D12 高级使用模型,ExecuteCommandLists 的同步定义等同于别名屏障。因此,应用程序可以在重用物理内存之间插入别名屏障,或者确保物理内存的两个别名使用发生在对 ExecuteCommandLists 的两次单独调用中。 失效的量因资源属性而异。具有未定义内存布局的纹理是最坏的情况,因为整个纹理必须以原子方式失效。对于具有已定义布局的两个重叠资源,失效可能只导致资源的重叠对齐区域失效。数据继承甚至可以是明确定义的。有关详细信息,请参阅 内存别名和数据继承

要求

头文件: d3d12_xs.h 或 d3d12_x.h
库: d3d12_xs.lib 或 d3d12_x.lib
支持的平台:XBOX Series 主机和 XBOX One 系列

另请参阅

CreateCommittedResource CreateReservedResource ID3D12Device 共享堆
最后修改于 2026年8月24日