【问题标题】:Can I change binding points in a compiled D3D shader?我可以在已编译的 D3D 着色器中更改绑定点吗?
【发布时间】:2016-04-25 19:44:06
【问题描述】:

我有一个 HLSL 着色器,它定义了一些资源,比如一个常量缓冲区:

cbuffer MyCB : register(b0);

如果我编译我的着色器,我将能够通过反射 API 查询寄存器。但是是否可以更改已编译着色器 blob 中的寄存器(例如,更改为 b3),就像在已编译的 OpenGL 程序中为资源分配绑定点一样?

【问题讨论】:

    标签: c++ direct3d direct3d11 direct3d12


    【解决方案1】:

    没有 API 可以在运行时更改已编译着色器中的着色器绑定。

    如果您跳过了很多困难,您也许可以在 Shader Model 5.0 中使用 dynamic shader linking 来实现这一点,尽管这将是很多工作而且并不值得,当有一个非常简单的替代方案时 - 只需创建一个具有所需绑定的新编译着色器。

    【讨论】:

    • 您还可以查看shader linking 技术——相当于旧的“FWLINK”技术的 Direct3D 11。
    • @MuertoExcobito 我确实想在运行时更改绑定。原因是在 D3D12 中,当来自不同着色器阶段(PS 和 VS)的资源映射到同一个寄存器时存在一个问题:这些资源必须放入不同的描述符表中。我希望我的所有资源都在一个描述符表中,我能想象的唯一方法是在编译的着色器中重新分配绑定,以便它们不会重叠。我认为可能会打扰字节码(timjones.tw/blog/archive/2015/09/02/...),但我希望有一种官方方法可以做到这一点。
    • 除非我理解错了,否则您可以编辑您的 HLSL 着色器,并确保绑定不重叠。直接编辑字节码是可能的,但很乏味,而且不一定向前兼容。
    • @MooseBoys - OP 询问是否有 API 可以更改已编译着色器 blob 中的着色器绑定 - 没有。虽然您的回答添加了一些有用的东西(它基本上扩展了我的第二部分),但我的回答并非“不正确”。
    【解决方案2】:

    您可以在 中通过在D3D12_DESCRIPTOR_RANGE 结构中指定除零以外的BaseShaderRegister 或使用不同的RegisterSpace 值来完成此操作。如果代码更改不可行,您可以通过设置根参数的ShaderVisibility 属性隐式隔离每组寄存器。例如,这将隔离 VS b0PS b0。更多详情,您可以查看该主题的developer video

    唯一遇到麻烦的情况是,如果您实际上已将两个资源显式绑定到同一个插槽和寄存器空间(通过使用着色器模型 5.1 语法显式指定它)。在这种情况下,您应该了解,在 D3D12 中,寄存器是跨阶段共享的,您需要确保没有冲突。

    在 D3D11 中,不会发生此问题,因为每个阶段都有自己的寄存器空间(VS b0PS b0 不同)并且您不能即使你想分享。尽管如此,如果您出于某种原因有一个硬编码的组件来将数据附加到 VS b0 但您的顶点着色器已经编译为在 b1 上期待它,那么您无能为力。

    【讨论】:

    • 我正在考虑做完全相同的事情:将不同的空间分配给不同的着色器阶段,以便将所有描述符放在一个表中。问题是我不想/无法访问着色器源代码。如果我能够更改着色器代码如下cbuffer CBinVS : register(b0,space0);cbuffer CBinPS : register(b0,space1);,那将解决我的问题。我所拥有的是带有我可能发生冲突的寄存器绑定的源代码。我想知道我是否可以通过编程方式纠正此类冲突而不更改源代码。
    • @Egor 除非您已经更改了源代码以明确指定寄存器空间,否则它们应该已经在不同的空间中。所有顶点着色器绑定都在空间 0 中,所有像素着色器绑定都在空间 4 中。
    • 所有顶点着色器绑定都在空间 0 中,所有像素着色器绑定都在空间 4 中 您是如何做到这一点的?这个MSDN page 专门说:如果省略“space”关键字,则默认空间索引0 被隐式分配给范围。我仔细检查了一下,所有着色器阶段中的所有绑定确实都在空间 0 中。
    • @Egor 你是对的。其目的实际上是使用SHADER_VISIBILITY 属性来隔离着色器阶段,这些阶段独立于寄存器空间。我会更新我的答案。
    • 要小心,当创建一个 PSO 的根签名不同于编译着色器时使用的根签名时,实际上,您实际上是在驱动程序中触发着色器编译。
    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多