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 中,做了三个重要方面不同于 …...
android13打基础: timepicker控件
public class Ch4_TimePickerActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {private TextView tv_time; // 声明一个文本视图对象private TimePicker tp_time; // 声明一个时间选择器对象Overrideprotected void onCreate(Nullable Bund…...
国产化板卡设计原理图:2330-基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡
基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡 一、板卡概述 本板卡基于 FPGAJFM7K325T 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8、64bit DDR3容量2GByte,HPC的FMC连接器,板卡支持PXIE标准协议,其中XJ3…...
Oracle SQL优化①——查看SQL执行计划的几种方法
前言 在日常的运维工作中,SQL优化是DBA的进阶技能,SQL优化的前提是要看SQL的执行计划是否正确,下面分享几种查看执行计划的方法,每一种方法都各有各的好处,可以根据特定场景选择某种方法。 一.使用AUTOTRACE查看执行…...
MySQL主从架构配合ShardingJdbc实现读写分离
文章目录 目录架构搭建读写分离pom.xmlfdy-live-user-provider 模块application.ymlfdy-db-sharding.yamlShardingJdbcDatasourceAutoInitConnectionConfig.java 目录 架构搭建 基于Docker去创建MySQL的主从架构 读写分离 pom.xml <dependency><groupId>mysql…...
MyBatis @Param 注解详解:多参数传递与正确使用方式
Param 注解主要用于 MyBatis 进行参数传递时给 SQL 语句中的参数 起别名,通常用于 多参数 方法,使参数在 XML Mapper 文件或注解 SQL 语句中更清晰易用。 1. 基本用法 在 Mapper 接口中使用 Param 来为参数命名,避免 MyBatis 解析时出现参数…...
【JAVA架构师成长之路】【Redis】第14集:Redis缓存穿透原理、规避、解决方案
30分钟自学教程:Redis缓存穿透原理与解决方案 目标 理解缓存穿透的成因及危害。掌握布隆过滤器、空值缓存等核心防御技术。能够通过代码实现请求拦截与缓存保护。学会限流降级、异步加载等应急方案。 教程内容 0~2分钟:缓存穿透的定义与核心原因 定义…...
mybatis报错org/apache/commons/lang3/tuple/Pair] with root cause
mybatis一对多查询配置resultMap映射报错org/apache/commons/lang3/tuple/Pair] with root cause 原因是mybatis依赖common-lang3这个包, 只需要添加common-lang3的依赖坐标即可: <dependency><groupId>org.apache.commons</groupId><artifactId>comm…...
supervisord管理Gunicorn进程,使用Nginx作为反向代理运行flask web项目
1. 安装 Gunicorn 在项目虚拟环境中安装 Gunicorn:2. 基本用法 配置文件 创建一个 Gunicorn 配置文件(如 gunicorn_config.py),方便管理复杂配置。 示例 gunicorn_config.py: bind "0.0.0.0:8000" #…...
STM32之软件SPI
SPI传输更快,最大可达80MHz,而I2C最大只有3.4MHz。输入输出是分开的,可以同时输出输入。是同步全双工。仅支持一主多从。SS是从机选择线。每个从机一根。SPI无应答机制的设计。 注意:所有设备需要共地,时钟线主机输出&…...
fastjson漏洞
fastjson漏洞 fastjson工作原理攻击原理补充 例子 fastjson工作原理 fastjson的作用是将JAVA对象转换成对应的json表示形式,也可以反过来将json转化为对应的Java对象。fastjson使用AutoType功能进行反序列化,AutoType使用type标记字符的原始类型&#x…...
【YOLOv12改进trick】医学图像分割网络CMUNeXt引入YOLOv12中,增强全局上下文信息实现涨点,含创新点Python代码,方便发论文
🍋改进模块🍋:医学全卷积U型网络(CMUNeXtBlock) 🍋解决问题🍋:CMUNeXtBlock模块解决了在医学图像分割任务中,传统的卷积操作由于其局部性限制,难以有效提取全局上下文信息的问题。 🍋改进优势🍋:利用大卷积核和倒置瓶颈结构,提取全局上下文信息,同时保持卷…...
机器学习的半监督学习,弱监督学习,自监督学习
半监督学习、弱监督学习和自监督学习是机器学习中利用不同形式监督信号的三种方法,它们的核心区别在于标注数据的数量、质量以及监督信号的来源。以下是它们的详细对比: 1. 半监督学习(Semi-Supervised Learning) 核心特点&#x…...
K8S学习之基础十七:k8s的蓝绿部署
蓝绿部署概述 蓝绿部署中,一共有两套系统,一套是正在提供服务的系统,一套是准备发布的系统。两套系统都是功能完善、正在运行的系统,只是版本和对外服务情况不同。 开发新版本,要用新版本替换线上的旧版本&…...
【计算机网络】计算机网络的性能指标——时延、时延带宽积、往返时延、信道利用率
计算机网络的性能指标 导读 大家好,很高兴又和大家见面啦!!! 在上一篇内容中我们介绍了计算机网络的三个性能指标——速率、带宽和吞吐量。用大白话来说就是:网速、最高网速和实时网速。 相信大家看到这三个词应该就…...
单片机如何用C语言重写vfprintf
在单片机中,标准库函数 vfprintf 可能不可用或占用过多资源(如内存或代码空间),因此我们可以通过自定义实现一个轻量级的 vfprintf 函数,专门用于单片机的串口输出。以下是一个用 C 语言重写 vfprintf 的示例ÿ…...
1.4 单元测试与热部署
本次实战实现Spring Boot的单元测试与热部署功能。单元测试方面,通过JUnit和Mockito等工具,结合SpringBootTest注解,可以模拟真实环境对应用组件进行独立测试,验证逻辑正确性,提升代码质量。具体演示了HelloWorld01和H…...
使用免费IP数据库离线查询IP归属地
一、准备工作 1.下载免费IP数据库 首先,访问 MaxMind官网(https://www.maxmind.com/en/home)如果你还没有MaxMind账号,可以通过此链接地址(https://www.maxmind.com/en/geolite2/signup)进行账号注册&…...
go语言数据类型
一.Go 语言有四大显著特点:高效性:编译与运行效率高。并发性:原生支持并发编程。简洁性:编程风格简洁直接,代码可读性与可维护性高。跨平台性:程序能在 Windows、Linux、Mac OS 等多系统运行。二.go的包:pa…...
操作系统 1.3-开机页面的产生
问题引入 从打开电源开始.. 这神秘的黑色背后发生着什么?... 设计思路 伟大的数学家图灵,设计了这样的一个模型: 首先我们计算机有一个控制器,他可以处理一系列提供给他的动作。我们将控制器动作,控制器状态,数据…...
单例模式:确保一个类只有一个实例
目录 引言 1. 单例模式的核心思想 2. 单例模式的实现方式 2.1 饿汉式单例 2.2 懒汉式单例 2.3 线程安全的懒汉式单例 2.4 双重检查锁定(Double-Checked Locking) 2.5 静态内部类实现单例 2.6 枚举实现单例 3. 单例模式的使用场景 4. 单例模式…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_modules
定义在 objs\ngx_modules.c #include <ngx_config.h> #include <ngx_core.h>extern ngx_module_t ngx_core_module; extern ngx_module_t ngx_errlog_module; extern ngx_module_t ngx_conf_module; extern ngx_module_t ngx_openssl_module; extern ngx_modul…...
vue3中 组合式~测试深入组件:事件 与 $emit()—setup() 上下文对象ctx.emit
一、语法(props) 第一步:在组件模板表达式中,可以直接用$emit()方法触发自定义事件, <!-- MyComponent --> <button click"$emit(someEvent)">Click Me</button> 第二步父组件可以通过 v-on (缩写为 ) 来监听…...
uniapp小程序对接腾讯IM即时通讯无ui集成(1)
首先需要完成一些准备工作。 1.注册腾讯云账号 腾讯云 注册账号后搜索im即时通讯,新创建一个应用。 2.uniapp创建项目 腾讯云无ui集成文档 按照文档步骤下载完这两个包后打开项目。有下图这两个包就算完成了开始工作。 3.APP目录进行引入和集成 <script…...
【YOLOv12改进trick】StarBlock引入YOLOv12,创新涨点优化,含创新点Python代码,方便发论文
🍋改进模块🍋:StarBlock 🍋解决问题🍋:采用StarBlock将输入数据映射到一个极高维的非线性特征空间,生成丰富的特征表示,使得模型在处理复杂数据时更加有效。 🍋改进优势🍋:简单粗暴的星型乘法涨点却很明显 🍋适用场景🍋:目标检测、语义分割、自然语言处理…...
机器学习之强化学习
引言 在人工智能的众多分支中,强化学习(Reinforcement Learning, RL) 因其独特的学习范式而备受关注。与依赖标注数据的监督学习或探索数据结构的无监督学习不同,强化学习的核心是智能体(Agent)通过与环境…...
天津大学02-深度解读DeepSeek:部署、使用、安全【文末附下载链接】
大模型风险与不当用例——价值观错位 大模型与人类价值观、期望之间的不一致而导致的安全问题,包含:• 社会偏见(Social Bias)LLM在生成文本时强化对特定社会群体的刻板印象,例如将穆斯林与恐怖主义关联,或…...
C# OPC DA获取DCS数据(提前配置DCOM)
OPC DA配置操作手册 配置完成后,访问远程ip,就能获取到服务 C#使用Interop.OPCAutomation采集OPC DA数据,支持订阅(数据变化)、单个读取、单个写入、断线重连...
ReAct论文阅读笔记总结
ReAct:Synergizing Reasoning and Acting in Language Models 背景 最近的研究结果暗示了在自主系统中结合语言推理与交互决策的可能性。 一方面,经过适当Prompt的大型语言模型(LLMs)已经展示了在算术、常识和符号推理任务中通…...
【计网】运输层
运输层 5.1 运输层概述5.2 运输层端口号、复用与分用5.3 UDP和TCP的区别5.4 TCP具体实现5.4.1 TCP的流量控制5.4.2 TCP的拥塞控制5.4.3 TCP超时重传时间的选择5.4.4 TCP可靠传输的实现5.4.5 TCP运输连接管理(一)TCP连接的建立(三报文握手&…...
计算机毕业设计SpringBoot+Vue.js多媒体素材库系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
MC9S12单片机的内存映射机制
地址空间 这是个16位的单片机。CPU的寻址空间最大为2^1664K。 这个64K是包括外设、RAM、EEPROM、和FLASH的。现在程序越来越大,64K的空间肯定是不够用的。因此,需要扩展。 扩展方法就是:分页。 把原来的64K空间,划分一块出来&a…...
鸿蒙HarmonyOS评论功能小demo
评论页面小demo 效果展示 1.拆解组件,分层搭建 我们将整个评论页面拆解为三个组件,分别是头部导航,评论项,回复三个部分,然后统一在index界面导入 2.头部导航界面搭建 Preview Component struct HmNavBar {// 属性&a…...
数据仓库为什么要分层
数据仓库分层架构是数据仓库设计中的一个重要概念,其主要目的是为了更好地组织和管理数据,提高数据仓库的可维护性、可扩展性和性能。分层架构将数据仓库划分为多个层次,每个层次都有其特定的职责和功能。以下是数据仓库分层的主要原因和好处…...
【powerjob】 powerjobserver注册服务IP错误
1、问题:powerjobserver 4.3.6 的服务器上有多个网卡对应多个ip,示例 eth0 :IP1 ,docker0:IP2 和worker 进行通信时 正确的应该时IP1 但是注册显示获取的确实IP2,导致 worker 通过ip2和server通信,网络不通,注册不上 2、解决方案 …...
JCRQ1河马算法+四模型对比!HO-CNN-GRU-Attention系列四模型多变量时序预测
JCRQ1河马算法四模型对比!HO-CNN-GRU-Attention系列四模型多变量时序预测 目录 JCRQ1河马算法四模型对比!HO-CNN-GRU-Attention系列四模型多变量时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于HO-CNN-GRU-Attention、CNN-GRU-Attent…...
智能硬件如何和应用层app连接?
现在比较方便的是一键配置方式,主要是使用蓝牙、smartconfig、ZigBee和声波配置。 蓝牙配置:比如蓝牙耳机、蓝牙鼠标,只能支持点对点连接,且对设备和app距离要求严格。 ZigBee配置方式:无法直接接入网络,…...
深度学习系列78:使用langchain的api进行RAG
用起来很麻烦,看api的工夫都已经能自己写完代码了。但现在有些开源api用的是langchain的接口,还是了解一下。参考官方文档:https://www.langchain.com.cn/docs/how_to/ 1. LLM和langserve示例 以openai接口为例,可以看到分为3步…...
海思Hi3516DV300交叉编译opencv
OpenCV是一个开源的跨平台计算机视觉库,支持C、Python等多种语言,适用于图像处理、目标检测、机器学习等任务。其核心由C编写,高效轻量,提供实时视觉处理功能,广泛应用于工业自动化、医疗影像等领域。 1 环境准备 1…...
责任链模式:优雅处理复杂流程的设计艺术
引言 在软件设计中,我们经常会遇到需要按特定顺序处理请求的场景。例如,一个订单处理系统可能需要经过验证、付款、物流安排和客户通知等多个步骤。如果我们将这些步骤硬编码在一个方法中,代码将变得臃肿且难以维护。这时,责任链…...
【DeepSeek】5分钟快速实现本地化部署教程
一、快捷部署 (1)下载ds大模型安装助手,下载后直接点击快速安装即可。 https://file-cdn-deepseek.fanqiesoft.cn/deepseek/deepseek_28348_st.exe (2)打开软件,点击立即激活 (3)选…...
HTML前端手册
HTML前端手册 记录前端框架在使用过程中遇到的各种问题和解决方案,供后续快速进行手册翻阅使用 文章目录 HTML前端手册1-前端框架1-TypeScript框架2-CSS框架 2-前端Demo1-Html常用代码 2-知云接力3-Live2D平面动画 3-前端运维1-NPM版本管理 1-前端框架 1-TypeScrip…...
【uniapp】图片添加canvas水印
目录 需求&背景实现地理位置添加水印 ios补充 需求&背景 需求:拍照后给图片添加水印, 水印包含经纬度、用户信息、公司logo等信息。 效果图: 方案:使用canvas添加水印。 具体实现:上传图片组件是项目里现有的ÿ…...
Java 大视界 -- Java 大数据在智能金融反欺诈中的技术实现与案例分析(114)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
机器学习数学基础:43.外生变量与内生变量
外生变量与内生变量:模型中的因果角色 在因果模型(像结构方程模型、回归分析这类)里,外生变量和内生变量是用来区分变量来源和相互关系的重要概念。下面从定义、实例、差异以及应用场景四个方面来详细介绍: 一、定义…...
Bean 的生命周期主要包括以下阶段:
Bean 的生命周期主要包括以下阶段: 定义 :在配置文件或注解中定义 Bean,包括其类、作用域等信息。 实例化 :Spring 容器根据定义创建 Bean 的实例。 属性赋值 :容器为 Bean 设置配置的属性值。 初始化 :…...
Unity游戏开发中的网格简化与LOD技术(Mesh Simplification LOD)
在Unity游戏开发中,网格简化(Mesh Simplification)和LOD(Level of Detail)技术是优化渲染性能的关键手段,尤其在处理复杂场景和高精度模型时至关重要。以下是一套系统的实现方案与优化策略: 一、…...
3.7[Q]CV
对于一个由cmake构建的项目,什么时候应该执行cmake指令?什么时候执行make指令?即,一个cmake构建的项目,各步骤的意义是什么?当我修改了部分代码后,重启项目该执行什么命令? view,mod…...
发行思考:全球热销榜的频繁变动
几点杂感: 1、单机游戏销量与在线人数的衰退是剧烈的,有明显的周期性,而在线游戏则稳定很多。 如去年的某明星游戏,最高200多万在线,如今在线人数是48名,3万多。 而近期热门的是MH,在线人数8…...
Springboot全局LocalDateTime时间格式化配置
我们对字段的日期格式化时一般会用注解: JsonFormat(pattern "yyyy-MM-dd HH:mm:ss", timezone "GMT8")private Date createDate;但是每个字段都要写也太麻烦了 不是我的全局化作风 在application.yml中配置全局时间格式化只会对Date类型有用: jackson:d…...