ConsumeStructuredBuffer, what am I doing wrong?
- by John
I'm trying to implement the 3rd exercise in chapter 12 of Introduction to 3D Game Programming with DirectX 11, that is:
Implement a Compute Shader to calculate the length of 64 vectors.
Previous exercises ask you to do the same with typed buffers and regular structured buffers and I had no problems with them.
For what I've read, [Consume|Append]StructuredBuffers are bound to the pipeline using UnorderedAccessViews (as long as they use the D3D11_BUFFER_UAV_FLAG_APPEND, and the buffers have both D3D11_BIND_SHADER_RESOURCE and D3D11_BIND_UNORDERED_ACCESS bind flags).
Problem is: my AppendStructuredBuffer works, since I can append data to it and retrieve it from the application to write to a results file, but the ConsumeStructuredBuffer always returns zeroed data. Data is in the buffer, since if I change the UAV to a ShaderResourceView and to a StructuredBuffer in the HLSL side it works.
I don't know what I am missing:
Should I initialize the ConsumeStructuredBuffer on the GPU, or can I do it when I create the buffer (as I amb currently doing).
Is it OK to bind the buffer with a UAV as described above? Do I need to bind it as a ShaderResourceView somehow?
Maybe I am missing some step?
This is the declaration of buffers in the Compute Shader:
struct Data
{
float3 v;
};
struct Result
{
float l;
};
ConsumeStructuredBuffer<Data> gInput;
AppendStructuredBuffer<Result> gOutput;
And here the creation of the buffer and UAV for input data:
D3D11_BUFFER_DESC inputDesc;
inputDesc.Usage = D3D11_USAGE_DEFAULT;
inputDesc.ByteWidth = sizeof(Data) * mNumElements;
inputDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
inputDesc.CPUAccessFlags = 0;
inputDesc.StructureByteStride = sizeof(Data);
inputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &data[0];
HR(md3dDevice->CreateBuffer(&inputDesc, &vinitData, &mInputBuffer));
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
uavDesc.Buffer.NumElements = mNumElements;
md3dDevice->CreateUnorderedAccessView(mInputBuffer, &uavDesc, &mInputUAV);
Initial data is an array of Data structs, which contain a XMFLOAT3 with random data.
I bind the UAV to the shader using the Effects framework:
ID3DX11EffectUnorderedAccessViewVariable* Input = mFX->GetVariableByName("gInput")->AsUnorderedAccessView();
Input->SetUnorderedAccessView(uav); // uav is mInputUAV
Any ideas?
Thank you.