gpt4 book ai didi

directx-12 - 应该如何使用 SetDescriptorHeaps?

转载 作者:行者123 更新时间:2023-12-05 05:11:26 25 4
gpt4 key购买 nike

我正在尝试使用 DirectX12 中的新功能。到目前为止,我真的很喜欢其中的一些变化,例如管道状态。同时,其他一些变化有点令人困惑,例如描述符堆。

让我们从快速背景开始,以便您更好地理解我的要求。

在 DirectX11 中,我们创建了不同着色器的对象,然后在设置绘制调用时必须在实际运行时分别绑定(bind)它们中的每一个。这是一个伪示例:

deviceContext->VSSetShader(...);
deviceContext->HSSetShader(...);
deviceContext->DSSetShader(...);
deviceContext->PSSetShader(...);

在 DirectX12 中,他们更智能地实现了这一点,因为现在我们可以在初始化期间配置管道状态,然后通过单个 API 调用设置以上所有内容:

commandList->SetPipelineState(...);

非常简单、优雅且快捷。最重要的是,非常合乎逻辑。现在让我们看看描述符堆。我有点希望它遵循同样优雅的模式,这基本上就是我的问题。

在 DirectX11 中,我们创建了不同描述符( View )的对象,然后在实际运行时设置绘制调用时,我们必须为每个着色器分别绑定(bind)每个对象。又是一个伪例子:

deviceContext->PSSetConstantBuffers(0, n, ...);
deviceContext->PSSetShaderResources(0, n, ...);
deviceContext->PSSetSamplers(0, n, ...);

在 DirectX12 中,他们实现了称为描述符堆的东西。基本上它们是包含所有我们想要绑定(bind)的描述符的内存块,我们也可以在初始化期间设置它。到目前为止,它看起来与管道状态一样优雅,因为我们可以通过单个 API 调用设置所有内容:

commandList->SetDescriptorHeaps(n, ...);

或者我们可以吗?这就是困惑出现的地方,因为经过搜索我发现 this question指出:

Swapping descriptor heaps is a costly operation you want to avoid at all cost.

与此同时,MSDN documentation对于 SetDesciptorHeaps 没有说明此方法特别昂贵。

考虑到他们设计管道状态的优雅程度,我有点期待能够做到这一点:

commandList->SetPipelineState(...);
commandList->SetDescriptorHeaps(n, ...);
commandList->DrawInstanced(...);

commandList->SetPipelineState(...);
commandList->SetDescriptorHeaps(n, ...);
commandList->DrawInstanced(...);

commandList->SetPipelineState(...);
commandList->SetDescriptorHeaps(n, ...);
commandList->DrawInstanced(...);

但是如果 SetDescriptorHeaps 实际上是那么昂贵,这可能会提供非常糟糕的性能。或者会吗?如前所述,我在 MSDN 上找不到任何关于这实际上是个坏主意的声明。

所以我的问题是:

  • 如果以上被认为是不好的做法,应该如何使用 SetDescriptorHeaps
  • 如果这是 Nvidia 独有的性能问题,他们为什么不修复驱动程序?

基本上,我想做的是为每个管道状态设置两个描述符堆(CBV/SRV/UAV + 采样器)。从更改管道状态的成本来看,更改描述符堆同样便宜是合乎逻辑的。管道状态和描述符堆密切相关,即更改管道状态很可能需要一组不同的描述符。

我知道为每种类型的描述符使用一个巨大的描述符堆的策略。但考虑到跟踪每个单独的描述符索引所需的所有工作,这种方法感觉过于复杂。最重要的是,描述符表中的描述符需要在堆中连续。

最佳答案

描述符堆独立于管道;他们不必在每次抽奖/ dispatch 时受到约束。您也可以只拥有一个大的描述符堆并将其绑定(bind)。不过,这应该由根签名更正;它应该指向这个描述符堆中的正确偏移量。这意味着您可以在一个堆中拥有独特的纹理,并将您的根签名指向正确的描述符。您还可以将当前堆再分配到一个巨大的堆中。

关于directx-12 - 应该如何使用 SetDescriptorHeaps?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55440621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com