DirectX12(D3D12)基础教程四 入门指南
本章主要讲了些D3D12概念和理论,对第一、二章相关概念的补充和纠正,要的理解D3D12概念和理论基础,结合代码加深理解。
命令队列和命令列表
为了实现渲染工作的重用和多线程缩放, 在 D3D12 中,做了三个重要方面不同于 早期版本的改变:
- 1. 消除了即时上下文。 这样可以实现多线程。
- 2. 应用现在拥有将渲染调用分组到图形处理单元 (GPU) 工作项中的方法。 这样可以重 复使用。
- 3. 应用现在显式控制何时将工作提交到 GPU。 这可实现第 1 项和第 2 项。
常用命令列表的类型 (D3D12_COMMAND_LIST_TYPE)
- 1直接命令列表 DIRECT
- 2.捆绑 BUNDLE
- 3计算命令列表 COMPUTE
- 4.复制命令列表COPY
typedef enum D3D12_COMMAND_LIST_TYPE{D3D12_COMMAND_LIST_TYPE_DIRECT = 0,D3D12_COMMAND_LIST_TYPE_BUNDLE = 1,D3D12_COMMAND_LIST_TYPE_COMPUTE = 2,D3D12_COMMAND_LIST_TYPE_COPY = 3,D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE = 4,D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS = 5,D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE = 6,D3D12_COMMAND_LIST_TYPE_NONE = -1}
命令列表的创建
- 命令列表是由命令分配器创建的,通过调用CreateCommandAllocator 创建命令分配器,再由命令分配器创建命令列表,关联一个图形管道状态(PSO)对象,如果此参数为 NULL,则使用默认状态。分配器的命令列表类型(由 D3D12_COMMAND_LIST_TYPE 指定)必须与所创建的命令列表类型匹配。如下:
void CD3D12Triangle::CreateGPUPipelineState(ComPtr<ID3D12PipelineState>& pipelineState, ComPtr<ID3D12CommandAllocator>& commandAllocator, ComPtr<ID3D12GraphicsCommandList>& commandList)
{
...ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator)));ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList)));
...}
-
ID3D12GraphicsCommandList::Close() 标记完成后再交给ID3D12CommandQueue::ExecuteCommandLists()执行,再次使用时要先ID3D12GraphicsCommandList::Reset()操作ID3D12GraphicsCommandList 中的大多数 API 不会返回错误。建命令列表期间遇到的错误将推迟到 ID3D12GraphicsCommandList::Close(),
-
对提供的命令列表调用 ID3D12GraphicsCommandList::Close,标记完成记录
-
大多数 D3D12 API 继续遵循 COM 约定使用引用计数。一个值得注意的例外情况是 ID3D12GraphicsCommandList 中的所有 API 不保留对传入 这些 API 的对象的引用。 这意味着,应用程序需负责确保永远不会提交引用已销毁资源的命令列表以供执行
命令队列
一般情况下,DIRECT 队列和命令列表接受任何命令,COMPUTE 队列和命令列表接受计算和复制相关的命令,COPY 队列和命令列表仅接受复制命令。
命令队列使用围栏同步命令列表执行
这种设计也意味着应用需要显式管理工作同步,尤其是当一个队列中的命令列表依赖于另一个命令队列操作的资源时。
多引擎同步(围栏)
大多数新式 GPU 都包含多个独立引擎,可提供专门的功能。 许多 GPU 拥有一个或多个 专用复制引擎和一个计算引擎,3D引擎。使用队列和命令列表提供对 3D 引擎、计算引擎和复制引擎访问, 这些引擎可以彼此并行执行命令。使用围栏同步命令执行。如纹理先用复制引擎然后用3D引擎显示.
围栏相关API
- ID3D12Fence::GetCompletedValue():返回围栏的当前值。
- ID3D12Fence::SetEventOnCompletion():围栏达到给定的值时激发事件。
- ID3D12Fence::Signal():从CPU端更新围栏值。
- ID3D12CommandQueue:Signal()从 GPU端更新围栏值, 在命令队列上完成所有其他操作后,将发生此更新。围栏使用代码:
void CD3D12Texture::WaitForPreviousFrame(void) {// m_fenceValue初值为1 const UINT64 fence = m_fenceValue;ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fence)); //在命令队列上完成所有其他操作后,将GPU端围栏值更新为1。m_fenceValue++;if (m_fence->GetCompletedValue() < fence){// 用一个事件去等GPU端围栏值更新ThrowIfFailed(m_fence->SetEventOnCompletion(fence, m_fenceEvent)); //围栏达到给定的值时激发事件m_fenceEventWaitForSingleObject(m_fenceEvent, INFINITE);}m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); }
命令队列使用资源屏障访问资源
在 D3D12 中,同步某些资源的状态是使用资源屏障实现的。 在每个资源屏障中, 应用声明资源的之前和之后状态。 一个常见示例是资源在着色器资源视图与渲染器目标 视图之间转换。
图形管道状态(PSO)
-
当几何图形提交到要绘制的图形处理单元 (GPU) 时,有各种硬件设置可用来确定如何解 释和呈现输入数据。 这些设置统称为图形管道状态,并包括光栅器状态、混合状态和深 度模具状态以及提交的 几何图形的基元拓扑类型和将用于呈现的着色器等常见设置。 在 D3D12 中,大多数图形管道状态是使用管道状态对象 (PSO) 设置的。 应用可以创建无限数量的这些对象,然后在呈现时,命令列表可以通过调用直接命令列表或捆绑中的
-
ID3D12GraphicsCommandList::SetPipelineState() 来设置活动 PSO,以便快速切换管道状 态的多个设置。
-
请注意,虽然大多数管道状态设置是使用 PSO 设置的,但有一些状态设置是使用 ID3D12GraphicsCommandList 提供的 API 单独设置的。
资源屏障
为了减少总体 CPU 使用率并启用驱动程序多线程和预处理,D3D12将按资 源状态管理的责任从图形驱动程序转移到应用程序。
资源屏障有三种类型
-
1.转换屏障
-
转换屏障指示不同用法之间的一组子资源转换。
-
2.失真屏障
- 失真屏障指示两个不同资源的用法之间的转换,这些资源在同一个堆中 存在重叠的映射。 这适用于保留的资源和定位的资源。
-
3.无序访问视图 (UAV) 屏障
- UAV 屏障指示对特定资源的所有 UAV 访问(读取或写 入)必须在任何后续 UAV 访问(读取或写入)之间完成。
性能影响
总而言之,每当其语义允许在不发出 ResourceBarrier 调用的情况下转换状态时,都请尝 试依赖于通用状态提升和衰减。
通用状态提升
-
访问时从D3D12_RESOURCE_STATE_COMMON隐式提升到相关状态
通用状态衰减
-
访问时从相关状态隐式降回到D3D12_RESOURCE_STATE_COMMON。
-
通用状态提升和衰减都是无开销的,因为不需要附加的同步。 将通用状态提升和 衰减相结合有助于消除许多不必要的 ResourceBarrier 转换。 在某些情况下,这可以大幅 提高性能。
资源提交方式
已提交资源CreateCommittedResource()
同时创建资源和堆。 堆是隐式的,不可直接访问。 堆的大小适当,可在其中放置整个资源。
已定位资源CreatePlacedResource()
允许将资源放在堆中的非零偏移位置。 已定位资源不能直接重新定位或重新映射到另一个堆;但 是,使用它们可在堆之间方便地重新定位资源数据。 在不同的堆中创建新的已定位 资源并复制资源数据后,必须对新的资源数据位置使用新的资源描述符。
已保留资源CreateReservedResource()
仅当适配器支持图块式资源层 1 或更高的层时,已保留资源才可用。 如果可用,它 们会提供可用的最先进驻留管理技术;但目前并非所有适配器都支持这些技术。
资源类型和视图
资源类型
- Texture1D/Texture2D/Texture3D
- 缓冲区(类型化、结构化和原始)
资源视图
- 常量缓冲区视图 (CBV)
- 无序访问视图 (UAV)
- 着色器资源视图 (SRV)
- 采样器
- 渲染器目标视图 (RTV)
-
深度模板视图 (DSV)
-
索引缓冲区视图 (IBV)
-
顶点缓冲区视图 (VBV)
-
流输出视图 (SOV)
-
着色器资源(例如纹理、常量表、图像、缓冲区等不会直接绑定到着色器管道,而是通过描述符进行引用。 描述符是包含有关一个资源的信息的小型对象。
-
描述符组合在一起构成了描述符表。
-
每个描述符表存储有关一个资源类型范围的信息。
-
例如: 常量缓冲区视图 (CBV) 无序访问视图 (UAV) 着色器资源视图 (SRV) 采样器 SRV、UAV 和 CBV 描述符可以合并到同一个描述符表中。
-
图形和计算管道通过按索引引用描述符表来获取对资源的访问权限。 描述符表存储在描述符堆中。 在理想情况下,描述符堆包含要渲染的一个或多个帧的所 有描述符(在描述符表中)。 所有资源将存储在用户模式堆中。
描述符种类
描述符由 API 调用创建并标识资源。
1.描述符数据
-
是一个相对较小的数据块,以 GPU 特定的不透明格式全面描述提交到 GPU 的对 象。 有多种不同类型,如:呈现目标视图 (RTV)、深度模具视图 (DSV)、着色器资源 视图 (SRV)、无序访问视图 (UAV)、常量缓冲区视图 (CBV) 和采样器,描述符的大小因 GPU 硬件而异。
-
可以通过调用 ID3D12Device::GetDescriptorHandleIncrementSize 来查询 SRV、UAV 或 CBV 的大小。
-
无需释放对象描述符。 驱动程序不会为描述符创建附加任何分配。 但是,描述符可能会 对应用程序永久拥有的其他分配的引用进行编码。 例如,SRV 的描述符必须包含 SRV 引 用的 D3D 资源(例如纹理)的虚拟地址。 由应用来确保在 SRV 描述符所依赖的基础 D3D 资源已被销毁或修改(例如,声明为非常驻)时不使用该描述符。 使用描述符的主要方法是将它们放置在描述符堆中,这些描述符堆是描述符的后备内存。
-
2.描述符句柄
-
描述符句柄是描述符的唯一地址。 它类似于指针,但不透明,因为其实现特定于硬件。 句柄在描述符堆唯一,例如,句柄数组可以引用多个堆中的描述符。
-
CPU 句柄可供立即使用,
-
GPU 句柄不可立即使用,它们从命令列表中确定位置,以便在 GPU 执行时使用。 必须保 留它们,直到引用它们的任何命令列表已完全执行为止。
-
请调用以下方法之一:
-
ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart 返回 CPU 可见描述符堆的 CPU 句柄。 如果描述 符堆对 CPU 不可见,则将返回 NULL 句柄(并且调试层将报告错误)。
-
ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart 返回着色器可见描述符堆的 GPU 句柄。 如果描 述符堆对着色器不可见,则将返回 NULL 句柄(并且调试层将报告错误)。
-
由于描述符大小因硬件而异,因此若要获得堆中的每个描述符之间的增量,请使用: ID3D12Device::GetDescriptorHandleIncrementSize 可以安全地使用若干增量偏移起始位置,复制句柄并将句柄传递到 API 调用数中。
3.Null 描述符
-
使用 API 调用创建描述符时,应用程序针对描述符定义中的资源指针传递 NULL 以达到被 着色器访问时未绑定的效果。
-
总之,若要创建 null 描述符,请在使用 CreateShaderResourceView 等方法创建视图时 针对 pResource 参数传递 null。 对于视图描述参数 pDesc,设置在资源不是 null 时可 行的配置(否则,某些硬件可能会崩溃)。
4.默认描述符
-
若要创建特定视图的默认描述符,请传入有效的 pResource 参数,以创建视图方法(例 如,CreateShaderResourceView),但为 pDesc 参数传入 null。 例如,如果资源包含 14 个 mip,则视图将包含 14 个 mip。 默认情况包含资源到视图的最明显映射。 这需要 资源分配有完全限定的格式名称(例如 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,而 不是 DXGI_FORMAT_R8G8B8A8_TYPELESS)
-
默认描述符不能与光线跟踪加速结构视图一起使用,因为提供的 pResource 参数必须为 NULL,并且必须通过 D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV传递位置。
描述符堆
描述符堆是描述符的连续分配的集合,每个描述符有一个分配。
描述符堆包含不属于管道状态对象 (PSO) 的许多对象类型,例如,着色器资源视图 (SRV)、无序访问视图 (UAV)、常量缓冲区视图 (CBV) 和取样器。
描述符堆的主要用途是包含所需的批量内存分配,用于存储着色器在尽可能大的渲染窗口 (最好是在整个渲染帧或更大的窗口)中引用的对象类型的描述符规范。
相同的描述符堆中存在一些限制。 CBV、UAV 和 SRV 条目可以位于相同的描述符堆中。 但是,取样器条目不能共享带有 CBV、UAV 或 SRV 条目的堆。 通常,有两组描述符堆, 一组用于公共资源,另一组用于取样器。
描述符堆只能由 CPU 立即编辑,没有选项可以由 GPU 编辑描述符堆。
绑定
任何时候最多可以绑定一个 CBV/SRV/UAV 组合堆和一个取样器堆。 这些堆在图形管道 和计算管道之间共享(如其 PSO 中所述)。
切换堆
可以接受应用程序使用 SetDescriptorHeaps 和 Reset API 在相同或不同的命令列表中切 换堆。 在某些硬件上,此操作开销巨大,需要 GPU 停滞才能刷新依赖于当前绑定的描述 符堆的所有工作。
着色器可见描述符堆
着色器可见描述符堆是着色器可通过描述符表引用的描述符堆。
可以包含着色器资源视图、无序访问视图和 常量缓冲区视图,所有这些内容都混合在一起。
另一个堆类型(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)仅存储采样器。
着色器不可见描述符堆
着色器无法通过描述符表引用部分描述符堆,但描述符堆的存在是为了帮助应用在记录命 令列表之前暂存描述符,或者是因为不需着色器可见堆。
创建描述符堆
若要创建和配置描述符堆,必须选择描述符堆类型,确定所包含的描述符数,并设置指示 CPU 是否可见和/或着色器是否可见的标志。
描述符表
描述符表在逻辑上是描述符数组。
每个描述符表存储一个或多个类型的描述符 - SRV、UAV、CBV 和采样器。 描述符表不是内存分配;它只是描述符堆中的偏移量和长度。
描述符表(每个表标识描述符堆中的一个范围)绑定在由命令列表上的当前根签名所 定义的槽中。
引用描述符表
图形管道通(pso)过根签名通过索引引用描述符表来获取对资源的访问权限。描述符表实际上只是描述符堆的子范围。 描述符堆表示一批描述符的基础内存分配。因此从一个描述符表中定义描述符表可以保证与将堆 中的区域标识到硬件一样便宜。不需要在 API 级别创建或销毁描述符表 - 系统仅会在堆 被引用时向驱动程序将它们标识为堆的偏移量和大小。
可共享相同的描述符表和堆
- 着色器资源视图
- 无序访问视图
- 常量缓冲区视图
不可共享相同的描述符表和堆(必须独立)
-
采样器
以下资源不在描述符表或堆中,而是使用命令列表直接绑定
- 索引缓冲区
- 顶点缓冲区
- 流输出缓冲区
- 呈现器目标
- 深度模具视图
根签名
根签名定义绑定到图形管道的资源类型。根签名由应用配置,并将命令列表链接到着色器所需的资源。 图形命令列表同时具有图形和计算根签名。 计算命令列表只具有一个计算根签名。 这些根签名彼此独立。
根签名是描述符表(包括其布局)、根常量和根描述符的任意排列集合的定义,包含嵌套结构的复杂数据结构。 这些结构可以使用以下数据结构定义(包括 帮助初始化成员的方法)以编程方式定义。 或者,可以使用高级着色语言 (HLSL) 编写它们,这样编译器会尽早验证布局是否与着色器兼容。“根签名”类似于 API 函数签名,它确定着色器应期望的数据类型,但不定义实际的内存或数据。
根形参和根实参
“根形参”是根签名中的一个条目。
在运行时设置和更改的根形参的实际值称为“根实参”。
根签名可以包含三种类型的形参;根常量(根实参中内联的常量),根描述符(根实参中 内联的描述符)和描述符表(指向描述符堆中一系列描述符的指针)。
根常量是内联 32 位值,在着色器中显示为常量缓冲区
内联根描述符应该包含访问频率最高的描述符,但仅限于 CBV、原始或结构化 UAV 或 SRV 缓冲区。
复杂的类型(如 2D texture SRV)不能用作根描述符。 根描述符不包含 大小限制,因此不能进行越界检查。
应用程序都应尽量使根签名尽可能小,以获得最大的效率。 应用程序可以在根签名中权衡使用更多描述符表,而为根常量预留更少空间。
创建根签名
根签名是可在 API 中通过手动规范创建的对象。 PSO 中的所有着色器都必须与使用 PSO 指定的根布局兼容,各个着色器必须包括相互匹配的嵌入式根布局;否则,PSO 创建将失败。
1.描述符表绑定类型
枚举 D3D12_DESCRIPTOR_RANGE_TYPE 定义可以作为描述符表布局定义的一部分引用 的描述符类型。
2.描述符范围
D3D12_DESCRIPTOR_RANGE 结构定义一系列给定类型的描述符。
3.描述符表布局
D3D12_ROOT_DESCRIPTOR_TABLE 结构将描述符表的布局声明为描述符范围集合,这些 范围从描述符堆的给定偏移量开始。 CBV/UAV/SRV 所在的同一个描述符表中不允许采样器。
若要设置图形(CBV、SRV、UAV、采样器)描述符表,
请使用 ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable。
若要设置计算描述符表,
请使用 ID3D12GraphicsCommandList::SetComputeRootDescriptorTable。
4.根常量
D3D12_ROOT_CONSTANTS 结构将根签名中的内联常量声明为一个常量缓冲区出现在着色器中。
5.根描述符
D3D12_ROOT_DESCRIPTOR 结构声明在着色器中显示的描述符 () 根签名中内联。
将根签名槽类型设置为
D3D12_ROOT_PARAMETER_TYPE_CBV、 D3D12_ROOT_PARAMETER_TYPE_SRV 或 着色器可见性 D3D12_ROOT_PARAMETER_TYPE_UAV 时,将使用此结构。
6.根签名定义
D3D12_ROOT_SIGNATURE_DESC结构可以包含描述符表和内联常量、由 D3D12_ROOT_PARAMETER结构和枚举D3D12_ROOT_PARAMETER_TYPE定义的每种槽类型。静态采样器在根签名中使用 D3D12_STATIC_SAMPLER 结构进行描述。
7.管道状态对象中的根签名
创建管道状态的方法 (ID3D12Device::CreateGraphicsPipelineState 和 ID3D12Device::CreateComputePipelineState ) 采用可选的 ID3D12RootSignature 接 口作为输入参数, (存储在 ) D3D12_GRAPHICS_PIPELINE_STATE_DESC 结构中。 这会重 写着色器中已存在的任何根签名。
8.静态采样器
静态采样器(状态完全定义且不可更改的采样器)是根签名的一部分, 如果可以将采样器定义为静态,则无需将采样器作为描述符堆的一部分。
使用静态采样器没有性能成本,根签名可以包含静态采样器(存储在根签名中,或存储在 某些硬件上的预留空间中)与动态采样器(存储在采样器描述符堆中)的混合。 描述符堆中的采样器可以动态分配和编制索引,而静态采样器不能。
9.直接在根签名中使用描述符
若要避免需要遍历描述符堆,可以将描述符直接放入根签名中。 这些描述符在根签名中 占用了大量空间,因此建议谨慎使用它们。 例如,在根布局中放置一个常量缓冲区视图, (每次绘图都会更改的 CBV) 。 这样一来, 应用程序不必按绘制 (分配描述符堆空间,并将指向描述符表保存在描述符堆) 的新位置。 通过将某些内容放入根签名中,应用程序只是将版本控制责任交给驱动程序;但这是 驱动程序已经拥有的基础结构。
10.静态和易失性标志
DESCRIPTORS_VOLATILE
设置此标志后,应用程序随时可以更改根描述符表指向的描述符堆中的描述符,但当绑定 描述符表的命令列表/捆绑已提交和未完成执行时则不可以。
DATA_STATIC
如果未设置DESCRIPTORS_VOLATILE 标志,则描述符为静态。如果设置此标志,记录期间在命令列表/捆绑中设置引用内存的根描述符或描述符表时, 将初始化描述符指向的数据,并且在命令列表/捆绑最后一次完成执行之前,该数据无法更改。
DATA_STATIC_WHILE_SET_AT_EXECUTE
设置此标志后,从在 GPU 时间线上执行期间在命令列表/捆绑中设置基础根描述符或描述 符表开始,到后续绘制/调度不再引用数据为止,描述符指向的数据无法更改。
Shader程序(HLSL)中的资源绑定
着色器模型 5 (SM5.0) 资源语法使用 register 关键字 (keyword) 将有关资源的重要信息 中继到 HLSL 编译器。 例如,以下语句声明在槽 t3、t4、t5 和 t6 中绑定的四个纹理的数 组。 t3 是唯一显示在该语句中的寄存器槽,而它仅仅是四个寄存器的数组中的第一个,如
Texture2D tex1[4] : register(t3)
HLSL 中的 D3D12 资源绑定到逻辑寄存器空间中的虚拟寄存器:
t – 表示着色器资源视图 (SRV)
s – 表示采样器
u – 表示无序访问视图 (UAV)
b – 表示常量缓冲区视图 (CBV)
资源和父堆具有对齐要求
用于多样本纹理 (4MB) D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT
对于单个样本纹理和缓冲区 64KB D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
线性子资源复制必须与D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT(512 字 节)对齐,行间距与D3D12_TEXTURE_DATA_PITCH_ALIGNMENT(256 字节)对 齐。
常量缓冲区视图必须与 D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT(256 字节)对齐。
类型化无序访问视图 (UAV) 加载
无序访问视图 (UAV) 类型化负载是着色器能够读取具有特定 DXGI_FORMAT的 UAV。无序访问视图 (UAV) 是无序访问资源的视图(可包括缓冲区、纹理和纹理数组,但无需 多次采样)。 使用 UAV 可通过多个线程临时进行无序读/写访问。 这意味着此资源类型 可由多个线程同时读/写,且不会产生内存冲突。 这种同时访问是通过使用 Atomic Functions(原子函数)来进行的。
在 HLSL 中指定根签名
如果在 HLSL 着色器模型 5.1 中指定根签名,则无需在 C++ 代码中指定这些根签名。
可在 HLSL 中将根签名指定为字符串。 该字符串包含一个逗号分隔的子句集合,这些子 句描述根签名的组成部分。 根签名在任何一个管道状态对象 (PSO) 的不同着色器中应该相同。
根签名指定为逗号分隔的子句序列。 子句的顺序非常重要,因为分析顺序决定了根签名中的槽位置。 每个子句采用一个或多个命名参数,参数的顺序并不重要。
RootFlags
可选的 RootFlags 子句采用 0 (默认值来指示没有) 标志,或者通过 OR“|”运算符连接的一 个或多个预定义根标志值。
RootFlags(0) RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT) RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT|DENY_VERTEX_SHADER_ROOT_ACCESS)
根常量RootConstants
RootConstants 子句指定根签名中的根常量。 两个必需的参数是:cbuffer 的 num32BitConstants 和 bReg(对应于 C++ API 中 BaseShaderRegister 的寄存器)。 space(C++ API 中的 RegisterSpace)和 visibility(C++ 中的 ShaderVisibility)参数是可选的,默认值为
RootConstants(num32BitConstants=N, bReg [, space=0, visibility=SHADER_VISIBILITY_ALL ])
根级 CBV
CBV(常量缓冲区视图)子句指定根级常量缓冲区 b-register 寄存器条目。 请注意,这是 一个标量条目;无法指定根级别的范围。
CBV(bReg [, space=0, visibility=SHADER_VISIBILITY_ALL ])
根级 SRV
SRV(着色器资源视图)子句指定根级 SRV t-register 寄存器条目。 请注意,这是一个标 量条目;无法指定根级别的范围。
SRV(tReg [, space=0, visibility=SHADER_VISIBILITY_ALL, // Version 1.1 flags=DATA_STATIC_WHILE_SET_AT_EXECUTE ])
根级 UAV
UAV(无序访问视图)子句指定根级 UAV u-register 寄存器条目。 请注意,这是一个标量 条目;无法指定根级别的范围。
UAV(uReg [, space=0, visibility=SHADER_VISIBILITY_ALL, // Version 1.1 flags=DATA_VOLATILE ])
描述符表DescriptorTable
DescriptorTable 子句本身是逗号分隔的描述符表子句列表,以及可选的可见性参数。 DescriptorTable 子句包括 CBV、SRV、UAV 和采样器。 请注意,其参数不同于根级子句 的参数。
DescriptorTable( DTClause1, [ DTClause2, … DTClauseN, visibility=SHADER_VISIBILITY_ALL ] )DescriptorTable(CBV(b0),SRV(t3, numDescriptors=unbounded))
编译 HLSL 根签名
可以使用两种机制来编译 HLSL 根签名。 首先,可以通过 RootSignature 属性将根签名字 符串附加到特定的着色器(以下示例使用 MyRS1 入口点):
[RootSignature(MyRS1)]
float4 main(float4 coord : COORD) : SV_Target{ … }
编译器将创建并验证着色器的根签名 Blob,并将它连同着色器字节码一起嵌入到着色器 Blob。 编译器支持着色器模型 5.0 及更高版本的根签名语法。
另一种机制是创建独立的根签名 Blob。也许可对大量的着色器重用该 Blob,以节省空 间。 效果编译器工具 (FXC) 支持rootsig_1_0和rootsig_1_1着色器模型。 通过常用的 /E 参 数指定定义字符串的名称。 例如: fxc.exe /T rootsig_1_1 MyRS1.hlsl /E MyRS1 /Fo MyRS1.fxo
多适配器系统
D3D12 对已安装多个适配器的系统的支持,包括应用程序明确使用多个 GPU 适配器的情况,以及驱动程序代表应用程序隐式使用多个 GPU 适配器的情况。
应用程序可以通过调用 ID3D12Device::GetNodeCount 来确定与给定设备关联的物理适 配器数量。 D3D12 中的许多 API 都接受节点掩码(位掩码),它表示 API 调用所指向的节点 集。 每个节点都有一个从 0 开始的索引。 但在节点掩码中,0 表示第 1 位;1 表示第 2 位;以此类推。
创建保留资源时,未指定节点索引或掩码。 可将保留资源映射到任何节点的堆上。 方法 MakeResident 在内部与适配器队列一起工作,应用程序无需为此指定任何内容。
在调用以下 ID3D12Device API 时,应用程序无需指定 API 调用将关联的节点集,因为 API 调用适用于所有节点。
感谢大家的支持,如要问题欢迎提问指正。
相关文章:

DirectX12(D3D12)基础教程四 入门指南
本章主要讲了些D3D12概念和理论,对第一、二章相关概念的补充和纠正,要的理解D3D12概念和理论基础,结合代码加深理解。 命令队列和命令列表 为了实现渲染工作的重用和多线程缩放, 在 D3D12 中,做了三个重要方面不同于 …...

C语言:确定进制
题目: 6942对于十进制来说是错误的,但是对于13进制来说是正确的。即, 6(13) 9(13) 42(13), 而 42(13)4131213054(10)。 任务是写一段程序,读入三个整数p、q和 r,然后确定一个进制 B(2<B<40) 使得 p q r。 如果…...

如何在 Windows 10 启用卓越性能模式及不同电源计划对比
在使用 powercfg -duplicatescheme 命令启用 “卓越性能模式”(即 Ultimate Performance 模式)之前,有几个前提条件需要注意: 前提条件: 系统版本要求:卓越性能模式 仅在 Windows 10 专业版 或更高版本&a…...

Unity Android出包
Unity Android出包 1.Android Studio版本 不能高于Unity的版本 2.so库 这个库需要自己拷贝到Android工程当中 3.JDK版本太老 编译可以正常,但无法运行 File->ProjectStructure->SDK Location->Gradle Setting->Gradle JDK->X:/Android Stuido/jre …...

Day04 模拟原生开发app过程 Androidstudio+逍遥模拟器
1、用Androidstudio打开已经写好了的music项目 2、逍遥模拟器打开apk后缀文件 3、在源文件搜索关键字 以后的测试中做资产收集...

2025人工智能AI新突破:PINN内嵌物理神经网络火了
最近在淘金的时候发现基于物理信息的神经网络(简称PINN)也是个研究热点,遂研读了几篇经典论文,深觉这也是个好发论文的方向,所以火速整理了一些个人认为很值得一读的PINN论文和同学们分享。 为了方面同学们更好地理解…...

通义万相 2.1 携手蓝耘云平台:开启影视广告创意新纪元
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...

【计算机网络】深入解析 HTTP 请求中的 header 类型:Cookie 的概念、特点和应用场景:登录和用户认证
网络原理— HTTP 请求“报头”(header) Cookie 是什么 HTTP报头中的Cookie,用大白话来说,就像你去餐厅吃饭时拿到的一张会员卡: 初次访问 (清除该网站的所有 Cookie 后重新访问该网站,效果相同): 当你第一次访问一个网…...

LeetCode 解题思路 11(Hot 100)
解题思路: 若相等: 直接返回 true。若当前元素大于目标值: 由于列递增,当前列下方所有元素均大于目标值,故排除该列(向左移动)。若当前元素小于目标值: 由于行递增,当前…...

警惕AI神话破灭:深度解析大模型缺陷与禁用场景指南
摘要 当前AI大模型虽展现强大能力,但其本质缺陷可能引发系统性风险。本文从认知鸿沟、数据困境、伦理雷区、技术瓶颈四大维度剖析大模型局限性,揭示医疗诊断、法律决策等8类禁用场景,提出可信AI建设框架与用户防护策略。通过理论分析与实操案…...

文件系统调用(上) ─── linux第17课
目录 linux 中man 2和man 3的区别 文件内容介绍 C语言文件接口 示例: 输出信息到显示器,你有哪些方法 总结: 系统文件I/O 文件类的系统调用接口介绍 示例 open 函数具体使用哪个,和具体应用场景相关, write read close lseek ,类比C文件相关接…...

go 标准库包学习笔记
本博文包含了go的math,net/http,fmt,io,csv,time.Time,strconv,strings,sync.Pool的学习,笔记多是其实战如何用,而非简单的函数式的讲解,可谓是收藏佳作,不时翻翻。 文章目录 1、math2、net/http3、fmt4、…...

Unity摄像机跟随物体
功能描述 实现摄像机跟随物体,并使物体始终保持在画面中心位置。 实现步骤 创建脚本:在Unity中创建一个新的C#脚本,命名为CameraFollow。 代码如下: using UnityEngine;public class CameraFollow : MonoBehaviour {public Tran…...

线程管理操作
1.创建两个线程,,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分 #include <head.h>#define SRC_FILE "./1.txt" #define DST_FILE "./2.txt" #define BUFFER_SIZE 4096struct copy_args {long start;l…...

VSCode 2025最新前端开发必备插件推荐汇总(提效指南)
🌟前言: 如果你是一名前端开发工程师,合适的开发工具能大大提高工作效率。Visual Studio Code (VSCode) 凭借其轻量级、高扩展性的特点,已成为众多前端开发者在win系电脑的首选IDE。 名人说:博观而约取,厚积而薄发。—…...

docker不停机部署
背景 最近做大疆项目时,后台更新部署时,机场和无人机就会掉线。设备自动重连注册时间比较长,应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像ÿ…...

鸿蒙应用开发—数据持久化之SQLite
文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库,占用资源很少,只有几百KB的大小,无需服务器支撑,是一个零配置、事务性的SQL数据库引擎。 相对…...

JSON对象处理工具类
目录 1. 工具类的功能设计 2. 工具类的实现 依赖配置 工具类代码 3. 工具类的使用示例 示例1:美化JSON打印 示例2:从JSON中提取数据 示例3:修改JSON数据 示例4:合并JSON对象 4. 总结 在现代软件开发中,JSON&…...

通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合
在这个科技日新月异的时代,人工智能不断刷新着我们对世界的认知。一次偶然的机会,我借助北京蓝耘科技股份有限公司提供的算力支持,踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技: 1.2通义万相 2.1…...

汽车一键启动按钮更换注意事项
汽车一键启动开关更换教程 一键启动开关是现代汽车中常见的便捷配置,但随着时间的推移,这个部件可能会出现失灵的情况。当一键启动开关发生故障时,许多车主选择自行更换。以下是整理的一键启动开关更换教程: 更换前的准备 选择匹…...

AI系统架构
在AI系统架构中,通常可以分为基础设施层、模型层和应用层。它们分别对应不同的技术和应用场景,具体如下: 1. 基础设施层(Infrastructure Layer) 这是AI系统的底层支持,主要涉及计算资源、存储、网络等基础…...

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头示例
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头…...

spring boot3.4.3+MybatisPlus3.5.5+swagger-ui2.7.0
使用 MyBatis-Plus 操作 books 表。我们将实现以下功能: 创建实体类 Book。 创建 Mapper 接口 BookMapper。 创建 Service 层 BookService 和 BookServiceImpl。 创建 Controller 层 BookController。 配置 MyBatis-Plus 和数据库连接。 1. 项目结构 src ├─…...

解决CentOS 8.5被恶意扫描的问题
CentOS 8 官方仓库已停止维护(EOL),导致一些常用依赖包如fail2ban 无法正常安装。 完整解决方案: 一、问题根源 CentOS 8 官方仓库已停更:2021 年底 CentOS 8 停止维护,默认仓库的包可能无法满足依赖关系。EPEL 仓库兼容性:EPEL 仓库可能未适配 CentOS 8.5 的旧版本依赖…...

laravel中 添加公共/通用 方法/函数
一,现在app 下面创建Common目录,然后在创建Common.php 文件 二,修改composer.json文件 添加这个到autoload 中 "files": ["app/Common/Common.php"]"autoload": {"psr-4": {"App\\": &quo…...

在vs中无法用QtDesigner打开ui文件的解决方法
解决方法 右键ui文件,选择打开方式,弹出如下界面。 点击添加,弹出如下界面 点击程序后边的三个点,去电脑查找designer.exe,我的位置为D:\Qt\Qt5.9.9\5.9.9\msvc2015_64\bin\designer.exe。 名称可以自己起一个名字,…...

springboot 文件下载
在springboot中,执行如下代码实现文件下载 GetMapping("/file/download/test")public void Download(HttpServletResponse response){try {String path "XXXXXXXXXXXX";//文件路径File file new File(path);// 读到流中InputStream inputStre…...

Nest.js全栈开发终极实践:TypeORM+微服务+Docker构建高可用企业级应用
文章目录 **第一部分:认识Nest.js与基础环境搭建****1.1 什么是Nest.js?****1.2 环境准备****1.3 创建第一个项目****1.4 启动开发服务器****1.5 核心文件解读** **第二部分:基础控制器与路由****2.1 控制器的作用****2.2 创建自定义控制器**…...

Go语言集成DeepSeek API和GoFly框架文本编辑器实现流式输出和对话(GoFly快速开发框架)
说明 本文是GoFly快速开发框架集成Go语言调用 DeepSeek API 插件,实现流式输出和对话功能。为了方便实现更多业务功能我们在Go服务端调用AI即DeepSeek接口,处理好业务后再用Gin框架实现流失流式输出到前端,前端使用fetch请求接收到流式的mar…...

Hexo博客Icarus主题不蒜子 UV、PV 统计数据初始化配置
文章首发于 不蒜子 UV、PV 统计数据初始化配置 适用场景 如果你有个运行的网站域名,采用了不蒜子统计 UV、PV等访客和阅读数据,但是有一天,你觉得想要换一个新的域名。当你将网站绑定到新的域名后,突然发现,所有的文章…...