I am getting this error:
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]
Here's my working code:
Texture3D< float4 > g_VectorField;
float3 ... = g_VectorField.SampleLevel( ... ).rgb;
Here's my code that is causing the error:
Texture3D< float3 > g_VectorField;
float3 ... = g_VectorField.SampleLevel( ... );
My application works just fine when I'm not catching Direct3D errors (disabled D3D11_CREATE_DEVICE_DEBUG). SampleLevel's behavior is not undefined as far as I can see. It's behaving in exactly the same as the first snippet, yet it is giving me this error. This format does not support 'SampleLevel'
my ass.
It seems that this error can be ignored without causing undefined behavior, so why is it an error?
It's perfectly valid for an "undefined behaviour" to give you the results you expected. The problem is that it's also perfactly valid for it to crash the graphics driver or reinstall your operating system, so to speak. The "warning" comes from DirectX, but the actual operation is performed by the graphics card. So you're doing an operation that's invalid for DirectX 11, but a specific GPU might support it. Others don't have to. Future cards don't have to either. And it might be doing something really stupid to allow you to use the sampling or converting the resource to float4.
Take C++ for example - the order of evaluation of function parameters is undefined. That means that while it might be doing the thing you expect it to do on your compiler and your computer, it might be different in a different place (different optimizations possible, for example), or on a different compiler / computer. The code is no longer portable or reliable.
As for why this particular operation is undefined, it's hard to tell. Different texture formats behave in very different ways - some recalibrate gamma, some premultiply the alpha... It might very well be that noone expected your particular type to be widely used, so it wasn't worth the extra branch in the specification. It might be that they didn't include it in the specification because enough GPUs didn't support it. Does it actually give you a measurable performance benefit? If the support is done by translating the texture, for example, the float3
variant might actually be slower.
Of course, in general computing, powers of two are usually preferred when storing data, because they make some operations much easier. GPUs might very well still depend on the old-school bit-hacks to handle some operations - 128 is nice, 96... not so much. Maybe they still store data in 128-bit registers, so there's no point in using 96. Maybe, maybe, maybe all the way :D
EDIT: I found something relevant in the DirectX documentation:
A resource declared with the DXGI_FORMAT_R32G32B32 family of formats cannot be used simultaneously for vertex and texture data. That is, you may not create a buffer resource with the DXGI_FORMAT_R32G32B32 family of formats that uses any of the following bind flags: D3D10_BIND_VERTEX_BUFFER, D3D10_BIND_INDEX_BUFFER, D3D10_BIND_CONSTANT_BUFFER, or D3D10_BIND_STREAM_OUTPUT
So it seems that it's fine to use R32G32B32
for an actual texture, but not for a vertex/index/constant buffer.