HI all,
I'm currently stuck on something which should be rather simple. I'm trying to use the Stream Out functionality to offload a set of calculations to the GPU but I'm having enormous difficulties in getting it to work. The code that I have to create my buffer (once, not per frame) is as follows:
// Member variable..
Microsoft::WRL::ComPtr<ID3D11Buffer> _streamOutBuffer;
// Create the buffer which will be used to handle the stream output stage
{
D3D11_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.ByteWidth =
WATERMANAGER_GRIDX * _gameEngine->getWidth() *
WATERMANAGER_GRIDY * _gameEngine->getHeight() *
sizeof(WATERRENDERERERBASE_DROPLETINSTANCE_DETAILS); // This evaluates to 307200
bufferDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_STREAM_OUTPUT | D3D11_BIND_FLAG::D3D11_BIND_VERTEX_BUFFER;
hr = dxDevice->CreateBuffer(&bufferDesc, nullptr, &_streamOutBuffer);
if (hr != S_OK)
return;
}
The code that I have to use the buffer subsequently is:
// Set the target output
UINT offset = 0;
context->SOSetTargets(1, &_streamOutBuffer, &offset);
context->Draw(vertexCount, 0);
// Reset the buffers
ID3D11Buffer* buffers[1] = { 0 };
context->SOSetTargets(0, buffers, &offset);
The problem that I have is that on the first call to 'SOSetTargets' the value of _streamOutBuffer gets set to being a null pointer which I simply don't understand why. If I use an intermediate value to store a copy of the pointer, then on subsequent frames I get access violation exceptions so it appears that something destructive is happening to the object. NOte that manually calling 'AddRef' didn't stop this.
Looking on MSDN (Getting started and Method doc) it doesn't appear that I'm doing anything different to the examples that I can find (including Frank Luna's DX11 book).
Can anyone shed any light as to what could be going on here / point me in the right direction please?
If it's helpful, the following is the following per frame code:
// Set all the inputs
context->IASetInputLayout(_inputLayoutExpanding.Get());
context->VSSetShader(_vertexShaderExpanding->shader.Get(), nullptr, 0);
context->GSSetShader(_geometryShaderWithSO.Get(), nullptr, 0);
context->PSSetShader(nullptr, nullptr, 0);
auto pointer = _vertexBuffer.Get();
UINT vertexStride = sizeof(unsigned int);
UINT vertexOffset = 0;
context->IASetVertexBuffers(0, 1, &pointer, &vertexStride, &vertexOffset);
// Set the constant buffers
ID3D11Buffer* vertexShaderCBs[1] = { _vertexShaderConstantBuffer.Get() };
ID3D11Buffer* geometryShaderCBs[1] = { _geometryShaderConstantBuffer.Get() };
context->VSSetConstantBuffers(0, 1, vertexShaderCBs);
context->GSSetConstantBuffers(0, 1, geometryShaderCBs);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
// context->RSSetScissorRects(0, nullptr);
ID3D11DepthStencilState* depthStencilStates[1];
UINT stencilRef;
context->OMGetDepthStencilState(depthStencilStates, &stencilRef);
// Initialize the description of the stencil state.
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
Set up the description of the stencil state.
depthStencilDesc.DepthEnable = false;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
Microsoft::WRL::ComPtr<ID3D11DepthStencilState> noWriteDepthStencil;
this->_device->CreateDepthStencilState(&depthStencilDesc, &noWriteDepthStencil);
context->OMSetDepthStencilState(noWriteDepthStencil.Get(), 0);
// Set the target output
UINT offset = 0;
context->SOSetTargets(1, &_streamOutBuffer, &offset);
context->Draw(vertexCount, 0);
// Reset the buffers
ID3D11Buffer* buffers[1] = { 0 };
context->SOSetTargets(0, buffers, &offset);
context->VSSetShader(nullptr, nullptr, 0);
context->GSSetShader(nullptr, nullptr, 0);
context->OMSetDepthStencilState(depthStencilStates [ 0 ], stencilRef);
Thanks
Steve