How to solve an error with unordered access view?

Started by
1 comment, last by MJP 11 years, 11 months ago

[background=rgb(250, 251, 252)]I try to modidy and reorganize of OIT soure code, [/background]


http://www.yakiimo3d...ency-with-msaa/

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)], and the source code can be downloaded from [/background][/font]


http://yakiimo3d.cod...ases/view/49570

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]. But I get an error "[/background][/font]


The Unordered Access View in slot 1 of the Pixel Shader unit was not created with the D3D11_BUFFER_UAV_FLAG_RAW flag" when I rendered



HRESULT CreateFragmentLink( const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, ID3D11Device* pd3dDevice )
{
HRESULT hr;

const int NUM_ELEMENTS = pBackBufferSurfaceDesc->Width * pBackBufferSurfaceDesc->Height * 8;

// create a structured buffer
D3D11_BUFFER_DESC descBuf;
memset( &descBuf, 0, sizeof( descBuf ) );
descBuf.StructureByteStride = sizeof( FragmentLink );
descBuf.ByteWidth = NUM_ELEMENTS * descBuf.StructureByteStride;
descBuf.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; // indicates that this buffer will be used as a structured buffer
descBuf.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; // GPU read & write, CPU cannot write
V_RETURN( pd3dDevice->CreateBuffer( &descBuf, NULL, &g_pFragmentLink ) );

// create UAV
D3D11_UNORDERED_ACCESS_VIEW_DESC descUAV;
memset( &descUAV, 0, sizeof( descUAV ) );
descUAV.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
descUAV.Buffer.FirstElement = 0;
descUAV.Format = DXGI_FORMAT_UNKNOWN; // for structured buffer, this value must be used
descUAV.Buffer.NumElements = NUM_ELEMENTS;
descUAV.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_COUNTER; // To enable to use internal counter
V_RETURN( pd3dDevice->CreateUnorderedAccessView( g_pFragmentLink, &descUAV, &g_pFragmentLinkUAV ) );

// create SRV
D3D11_SHADER_RESOURCE_VIEW_DESC descSRV;
descSRV.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
descSRV.Buffer.FirstElement = 0;
descSRV.Format = DXGI_FORMAT_UNKNOWN;
descSRV.Buffer.NumElements = NUM_ELEMENTS;
V_RETURN( pd3dDevice->CreateShaderResourceView( g_pFragmentLink, &descSRV, &g_pFragmentLinkSRV ) );

return hr;
}

HRESULT CreateStartOffset( const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, ID3D11Device* pd3dDevice )
{
HRESULT hr = S_OK;
const int NUM_ELEMENTS = pBackBufferSurfaceDesc->Width * pBackBufferSurfaceDesc->Height;
// create a byte address buffer
D3D11_BUFFER_DESC descBuf;
memset( &descBuf, 0, sizeof( descBuf ) );
descBuf.StructureByteStride = sizeof( unsigned int );
descBuf.ByteWidth = NUM_ELEMENTS * descBuf.StructureByteStride;
descBuf.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; // allow to get the returned value in 4 bytes
descBuf.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
V_RETURN( pd3dDevice->CreateBuffer( &descBuf, NULL, &g_pStartOffsetBuffer ) );
// create UAV
D3D11_UNORDERED_ACCESS_VIEW_DESC descUAV;
memset( &descUAV, 0, sizeof( descUAV ) );
descUAV.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
descUAV.Buffer.FirstElement = 0;
descUAV.Format = DXGI_FORMAT_R32_TYPELESS;
descUAV.Buffer.NumElements = NUM_ELEMENTS;
descUAV.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
V_RETURN( pd3dDevice->CreateUnorderedAccessView( g_pStartOffsetBuffer, &descUAV, &g_pStartOffsetUAV ) );
// create SRV
D3D11_SHADER_RESOURCE_VIEW_DESC descSRV;
descSRV.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
descSRV.Buffer.FirstElement = 0;
descSRV.Format = DXGI_FORMAT_R32_UINT;
descSRV.Buffer.NumElements = NUM_ELEMENTS;
V_RETURN( pd3dDevice->CreateShaderResourceView( g_pStartOffsetBuffer, &descSRV, &g_pStartOffsetSRV ) );
return hr;
}


void StoreFragments::OnRender( ID3D11DeviceContext* pd3dImmediateContext, ID3D11Device* pd3dDevice, D3DXMATRIX* pmWorld, D3DXMATRIX* pmViewProj,
ID3D11UnorderedAccessView* pFragmentLinkUAV, ID3D11UnorderedAccessView* pStartOffsetUAV,
const DXGI_SURFACE_DESC* pBackBufferDesc ) {
HRESULT hr;

#pragma region clear Render target & depth stencil & UAV
float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView();
pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor );

ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView();
pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0f, 0.0f );

static const UINT clearValueUINT[1] = { 0xFFFFFFFF };
pd3dImmediateContext->ClearUnorderedAccessViewUint( pStartOffsetUAV, clearValueUINT );
#pragma endregion

#pragma region update constant buffers
D3D11_MAPPED_SUBRESOURCE MappedResource;
V( pd3dImmediateContext->Map( m_pVS_CB, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
VS_CB* pVS_CB = ( VS_CB* )MappedResource.pData;
D3DXMatrixTranspose( &pVS_CB->m_mWorldViewProjection, pmViewProj );
pd3dImmediateContext->Unmap( m_pVS_CB, 0 );
pd3dImmediateContext->VSSetConstantBuffers( 0, 1, &m_pVS_CB );

D3D11_MAPPED_SUBRESOURCE MappedResource2;
V( pd3dImmediateContext->Map( m_pPS_CB, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource2 ) );
PS_CB* pPS_CB = ( PS_CB* )MappedResource2.pData;
pPS_CB->nFrameWidth = pBackBufferDesc->Width;
pPS_CB->nFrameHeight = pBackBufferDesc->Height;
pd3dImmediateContext->Unmap( m_pPS_CB, 0 );
pd3dImmediateContext->PSSetConstantBuffers( 0, 1, &m_pPS_CB );
#pragma endregion

#pragma region set UAV & RTV
ID3D11UnorderedAccessView* pUAVs[2];
pUAVs[0] = pFragmentLinkUAV;
pUAVs[1] = pStartOffsetUAV;
UINT Indices[] = {0, 0};
pd3dImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews( 0, NULL, pDSV, 1, 2, pUAVs, Indices );
#pragma endregion

pd3dImmediateContext->OMSetDepthStencilState( m_pDepthStencilState, 0 );

#pragma region set VB & render
UINT uStrides = sizeof( SCENE_VERTEX );
UINT uOffsets = 0;
pd3dImmediateContext->IASetVertexBuffers( 0, 1, &m_pVB, &uStrides, &uOffsets );
//pd3dImmediateContext->IASetIndexBuffer( NULL, DXGI_FORMAT_R32_UINT, 0 );
pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
pd3dImmediateContext->IASetInputLayout( m_pVertexLayout );
pd3dImmediateContext->VSSetShader( m_pVS, NULL, 0 );
pd3dImmediateContext->PSSetShader( m_pPS, NULL, 0 );

pd3dImmediateContext->Draw( 12, 0 );
#pragma endregion
}


And this is the shader code

cbuffer cbPerObject : register( b0 )
{
matrix g_mWorldViewProjection : packoffset( c0 );
}
struct SceneVS_Input
{
float4 pos : POSITION;
float4 color : COLOR;
};
struct SceneVS_Output
{
float4 pos : SV_POSITION;
float4 color : COLOR0;
};
// Fragment And Link Buffer
RWStructuredBuffer< FragmentLink > FLBuffer : register( u0 );
// Start Offset Buffer
RWByteAddressBuffer StartOffsetBuffer : register( u1 );
SceneVS_Output SceneVS( SceneVS_Input input )
{
SceneVS_Output output;

output.color = input.color;
output.pos = mul(input.pos, g_mWorldViewProjection );

return output;
}
[earlydepthstencil]
void StoreFragmentsPS( SceneVS_Output input )
{
uint x = input.pos.x; // [0,g_nFrameWidth]
uint y = input.pos.y; // [0,g_nFrameHeight]
// Create fragment data.
uint4 nColor = saturate( input.color ) * 255;
FragmentLink element;
element.fragmentData.nColor = (nColor.x) | (nColor.y << 8) | (nColor.z << 16) | (nColor.a << 24);
element.fragmentData.fDepth = input.pos.z;
// Increment and get current pixel count.
uint nPixelCount= FLBuffer.IncrementCounter();
// Read and update Start Offset Buffer.
uint nIndex = y * g_nFrameWidth + x;
uint nStartOffsetAddress = 4 * nIndex;
uint nOldStartOffset;
StartOffsetBuffer.InterlockedExchange(
nStartOffsetAddress, nPixelCount, nOldStartOffset );
// Store fragment link.
element.nNext = nOldStartOffset;
FLBuffer[ nPixelCount ] = element;
}


With the error, I think that UAV in slot 1 is StartOffsetUAV but I used D3D11_BUFFER_UAV_FLAG_RAW flag as I was creating StartOffsetUAV, so why do I get this sort of error? Anybody help me, please?
Advertisement
I have already found out. In shader, I start from slot 0, but the parameters I used for [color=#660066][size=2]

[background=rgb(248, 248, 248)]OMSetRenderTargetsAndUnorderedAccessViews [/background]

function is star from slot 1 :(
It doesn't start from slot 1, it starts from the first slot not used by a render target. This is because UAV's and render targets share slots for pixel shaders. So if you had 3 render targets, your UAV's would start at slot 3.

This topic is closed to new replies.

Advertisement