Read access violation on dumping UAV buffer contents

0

I'm trying to modify an existing example from Frank Luna's Introduction to 3D Game Programming with DirectX 11. The compute shader code originally takes two structured buffers via SRVs and adds them and writes them into a structured buffer via UAV. Instead, I'd like to load from one raw buffer and store directly into another raw buffer, both via UAV.

// declare buffers and views
ID3D11Buffer* mInputBuffer;
ID3D11Buffer* mOutputBuffer;
ID3D11Buffer* mOutputDebugBuffer;
ID3D11UnorderedAccessView* mInputUAV;
ID3D11UnorderedAccessView* mOutputUAV;

// fill vector of DWORDs
UINT mNumElements = 256;
std::vector<DWORD> inputData(mNumElements);
for (int i = 0; i < mNumElements; ++i)
{
    inputData[i] = 0xFFFFFFFF;
}

// buffer description
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(DWORD) * mNumElements;
bufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.StructureByteStride = sizeof(DWORD);
bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; // allow raw data

// Fill buffer with vector data
D3D11_SUBRESOURCE_DATA vinitDataInput;
vinitDataInput.pSysMem = &inputData[0];

// create buffers
HR(md3dDevice->CreateBuffer(&bufferDesc, &vinitDataInput, &mInputBuffer));
HR(md3dDevice->CreateBuffer(&bufferDesc, 0, &mOutputBuffer));

// create buffer to store output transferred from GPU to CPU
D3D11_BUFFER_DESC debugOutputDesc;
ZeroMemory(&debugOutputDesc, sizeof(D3D11_BUFFER_DESC));
debugOutputDesc.Usage = D3D11_USAGE_STAGING;
debugOutputDesc.BindFlags = 0;
debugOutputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
HR(md3dDevice->CreateBuffer(&bufferDesc, 0, &mOutputDebugBuffer));

// UAV description
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS; # DWORD
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW; // allow raw data
uavDesc.Buffer.NumElements = mNumElements;

// create views
md3dDevice->CreateUnorderedAccessView(mInputBuffer, &uavDesc, &mInputUAV);
md3dDevice->CreateUnorderedAccessView(mOutputBuffer, &uavDesc, &mOutputUAV);

// excerpt from Effect class
ID3DX11EffectUnorderedAccessViewVariable* Input;
ID3DX11EffectUnorderedAccessViewVariable* Output;
void SetInput(ID3D11UnorderedAccessView* uav) { Input->SetUnorderedAccessView(uav); }
void SetOutput(ID3D11UnorderedAccessView* uav) { Output->SetUnorderedAccessView(uav); }
Input = mFX->GetVariableByName("gInput")->AsUnorderedAccessView();
Output = mFX->GetVariableByName("gOutput")->AsUnorderedAccessView();
// end of excerpt from Effect class

// bind UAVs
Effects::VecAddFX->SetInput(mInputUAV);
Effects::VecAddFX->SetOutput(mOutputUAV);

// dispatch one TG
Effects::VecAddFX->VecAddTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
    ID3DX11EffectPass* pass = Effects::VecAddFX->VecAddTech->GetPassByIndex(p);
    pass->Apply(0, md3dImmediateContext);

    md3dImmediateContext->Dispatch(1, 1, 1);
}

// disable compute shader
ID3D11ShaderResourceView* nullSRV[1] = { 0 };
md3dImmediateContext->CSSetShaderResources( 0, 1, nullSRV );
ID3D11UnorderedAccessView* nullUAV[1] = { 0 };
md3dImmediateContext->CSSetUnorderedAccessViews( 0, 1, nullUAV, 0 );
md3dImmediateContext->CSSetShader(0, 0, 0);

// open results file
std::ofstream fout;
fout.open("results.txt", std::ios_base::app);

// copy output buffer to debug buffer
md3dImmediateContext->CopyResource(mOutputDebugBuffer, mOutputBuffer);

// map data
D3D11_MAPPED_SUBRESOURCE mappedData; 
md3dImmediateContext->Map(mOutputDebugBuffer, 0, D3D11_MAP_READ, 0, &mappedData);

// cast to DWORD and write to file
DWORD* dataView = reinterpret_cast<DWORD*>(mappedData.pData);
for (int i = 0; i < mNumElements; ++i)
{
    fout << std::hex << dataView[i] << std::endl;
}

md3dImmediateContext->Unmap(mOutputDebugBuffer, 0);

fout.close();

The shader is:

RWByteAddressBuffer gInput;
RWByteAddressBuffer gOutput;

[numthreads(256, 1, 1)]
void CS(int3 dtid : SV_DispatchThreadID, int3 tgid : SV_GroupThreadID)
{
    uint inData = gInput.Load(tgid.x);
    gOutput.Store(tgid.x, inData);
}

Unfortunately I get an error from fout << std::hex << dataView[i] << std::endl;.

Exception thrown: read access violation.
dataView was 0x1110112.

In the Autos window, dataView's value is 0x00000000 {???} and it indicates <Unable to read memory>.

What am I missing?

directx
hlsl
direct3d
compute-shader
asked on Stack Overflow Jul 20, 2020 by Colin

1 Answer

0

Thanks to Chuck's suggestion, I narrowed down the read access violation issue to:

// create buffer to store output transferred from GPU to CPU
D3D11_BUFFER_DESC debugOutputDesc;
ZeroMemory(&debugOutputDesc, sizeof(D3D11_BUFFER_DESC));
debugOutputDesc.Usage = D3D11_USAGE_STAGING;
debugOutputDesc.BindFlags = 0;
debugOutputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
HR(md3dDevice->CreateBuffer(&bufferDesc, 0, &mOutputDebugBuffer));

I created a debugOutputDesc but I used bufferDesc during CreateBuffer. The correct code should be:

// Create a system memory version of the buffer to read the results back from.
bufferDesc.Usage = D3D11_USAGE_STAGING;
bufferDesc.BindFlags = 0;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
bufferDesc.MiscFlags = 0;
HR(md3dDevice->CreateBuffer(&bufferDesc, 0, &mOutputDebugBuffer));
answered on Stack Overflow Jul 28, 2020 by Colin

User contributions licensed under CC BY-SA 3.0