Direct3D 11 / HLSL Texture3D <float3> False Error?</float3>

时间:2015-02-25 08:46:03

标签: direct3d hlsl

我收到此错误:

D3D11 ERROR: ID3D11DeviceContext::Dispatch: The Shader Resource View in slot 0 of the Compute Shader unit is using the Format (R32G32B32_FLOAT). This format does not support 'Sample', 'SampleLevel', 'SampleBias' or 'SampleGrad', at least one of which may being used on the Resource by the shader. This mismatch is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #371: DEVICE_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED]

这是我的工作代码:

Texture3D< float4 > g_VectorField;
float3 ... = g_VectorField.SampleLevel( ... ).rgb;

这是导致错误的代码:

Texture3D< float3 > g_VectorField;
float3 ... = g_VectorField.SampleLevel( ... );

当我没有捕获Direct3D错误时,我的应用程序正常工作(禁用D3D11_CREATE_DEVICE_DEBUG)。就我所见,SampleLevel的行为并未定义。它在 完全 中的行为与第一个代码段相同,但却给了我这个错误。 This format does not support 'SampleLevel'我的屁股。

似乎可以忽略此错误而不会导致未定义的行为,那么为什么会出错呢?

1 个答案:

答案 0 :(得分:2)

它完全适用于未定义的行为&#34;给你你期望的结果。问题是,它对于崩溃图形驱动程序或重新安装操作系统也是有效的,可以这么说。 &#34;警告&#34;来自DirectX,但实际操作由显卡执行。因此,您正在执行对DirectX 11无效的操作,但特定的GPU可能会支持它。其他人不必这样做。未来的卡也不必。并且它可能正在做一些非常愚蠢的事情,允许您使用采样或将资源转换为float4。

以C ++为例 - 函数参数的评估顺序是未定义的。这意味着虽然它可能正在执行您希望它在您的编译器和计算机上执行的操作,但它可能在不同的位置(例如,可能的不同优化)或不同的编译器/计算机上有所不同。代码不再可移植或可靠。

至于为什么这个特定的操作未定义,很难说。不同的纹理格式以非常不同的方式表现 - 一些重新校准伽马,一些预乘阿尔法...很可能没有人期望你的特定类型被广泛使用,所以它不值得规范中的额外分支。它可能是因为没有足够的GPU支持它,所以它们并没有将它包含在规范中。它实际上是否给您带来了可衡量的性能优势?例如,如果通过翻译纹理来完成支持,float3变体实际上可能会更慢。

当然,在一般计算中,存储数据时通常首选2的幂,因为它们使一些操作更容易。 GPU可能仍然依赖于老式的黑客来处理一些操作 - 128很好,96 ......不是那么多。也许他们仍然将数据存储在128位寄存器中,所以使用96也没有意义。也许,也许,也许一直都在:D

编辑:我在DirectX文档中找到了相关内容:

  

使用DXGI_FORMAT_R32G32B32系列格式声明的资源   不能同时用于顶点和纹理数据。那是,   您可能无法使用DXGI_FORMAT_R32G32B32创建缓冲区资源   使用以下任何绑定标志的格式系列:   D3D10_BIND_VERTEX_BUFFER,D3D10_BIND_INDEX_BUFFER,   D3D10_BIND_CONSTANT_BUFFER,或D3D10_BIND_STREAM_OUTPUT

因此,对于实际纹理使用R32G32B32似乎没什么问题,但对于顶点/索引/常量缓冲区则不行。