DX11 - Write to Texture2D UAV, read from Texture2D SRV

Started by
8 comments, last by Alisdair101 7 years ago

Hello,
If anybody could please offer me some advice, I would be very grateful.

Currently, if it worked ideally: I write to a UAV Texture2D in the Pixel Shader. I then pass that Texture2D as an SRV into another shader to be read.
However currently, all that displays is the colour white that I clear the UAV with when I call the following line:

const float zero[4] = { 1, 1, 1, 1 };
DX11AppHelper::_pImmediateContext->ClearUnorderedAccessViewFloat(mUAV, zero);
I am currently rendering a fullscreen quad for the testing of this. Apologies if this forum post is done badly, I've never done one before.
Here is the the initialisation code for the Texture2D, the UAV and the SRV:
D3D11_TEXTURE2D_DESC dstex;
ZeroMemory(&dstex, sizeof(dstex));
dstex.Width = DX11AppHelper::_pRenderWidth;
dstex.Height = DX11AppHelper::_pRenderHeight;
dstex.MipLevels = 1;
dstex.ArraySize = 1;
dstex.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dstex.SampleDesc.Count = 1;
dstex.Usage = D3D11_USAGE_DEFAULT;
dstex.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
dstex.CPUAccessFlags = 0;
dstex.MiscFlags = 0;
if (FAILED(DX11AppHelper::_pd3dDevice->CreateTexture2D(&dstex, nullptr, &mOctreeStructure)))
{
return E_FAIL;
}
// Create the render target views.
D3D11_UNORDERED_ACCESS_VIEW_DESC UAVDesc;
ZeroMemory(&UAVDesc, sizeof(UAVDesc));
UAVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
UAVDesc.Texture2D.MipSlice = 0;
if (FAILED(DX11AppHelper::_pd3dDevice->CreateUnorderedAccessView(mOctreeStructure, &UAVDesc, &mUAV)))
{
return E_FAIL;
}
// Create the resource view.
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = 1;
if (FAILED(DX11AppHelper::_pd3dDevice->CreateShaderResourceView(mOctreeStructure, &SRVDesc, &mSRV)))
{
return E_FAIL;
}
Here is my Pixel Shader which I write to the UAV with:
RWTexture2D<float4> octree;
//--------------------------------------------------------------------------------------
// Pixel Shader Write
//--------------------------------------------------------------------------------------
void PS(VS_OUTPUT input)
{
//float4 finalColour = float4(0.0f, 0.0f, 0.0f, 1.0f);
octree[uint2(input.Tex.x, input.Tex.y)] = float4(0.0f, 1.0f, 0.0f, 0.0f);
//return finalColour;
}
Here is my Pixel Shader that I read the SRV with:
Texture2D txDiffuse : register(t0);
//--------------------------------------------------------------------------------------
// Pixel Shader Read
//--------------------------------------------------------------------------------------
float4 PS(VS_OUTPUT input) : SV_Target
{
float4 textureColour = txDiffuse.Sample(samLinear, input.Tex);
return textureColour;
}
Advertisement

Whenever you have any D3D problems, first check what the D3D debug layer has to say.
Create your D3D11 device using the D3D11_CREATE_DEVICE_DEBUG flag, and then enable break-on-error and break-on-warning, and then fix all the D3D errors/warnings:


ID3D11InfoQueue* debugInfoQueue = 0;
m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&debugInfoQueue);
if(debugInfoQueue) 
{
  m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_CORRUPTION, TRUE );
  m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, TRUE );
  m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_WARNING, TRUE );
  m_debugInfoQueue->Release();
}

For most of development you should have the debug layer enabled, and break-on-error / break-on-corruption enabled. Break-on-warning is less important, but still worth checking.

I also recommend using renderdoc to investigate why any particular D3D command isn't doing what you think it should be doing.

Apologies if this forum post is done badly, I've never done one before

Use:


[code][/code]

To format code sections properly :)

Do you un-bind the UAV before you bind the SRV? You're not allowed to have any particular resource simultaneously bound for writing (UAV/RTV/DSV) and for reading (SRV).

Hello, it's AlisdairTW, I had to create another account as gamedev didn't seem to respond to me signing in with Google today for some reason.

Anywho, I have the debug layer enabled, and I am not getting any errors or warnings from it.

I believe I am correctly unbinding and binding the SRV's and UAV's each time I use them, here is the code for when I call the full screen quad, which is the shader I use to write to the Texture2D with the UAV:


const float zero[4] = { 1, 1, 1, 1 }; 
DX11AppHelper::_pImmediateContext->ClearUnorderedAccessViewFloat(mUAV, zero); 
DX11AppHelper::_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 1, &mTexture2DUAV, 0);  // Bind the Texture2D UAV 
DX11AppHelper::_pImmediateContext->IASetInputLayout(mInputLayout);   
DX11AppHelper::_pImmediateContext->VSSetShader(mVertexShader, nullptr, 0); 
DX11AppHelper::_pImmediateContext->PSSetShader(mPixelShader, nullptr, 0);   
DX11AppHelper::_pImmediateContext->PSSetSamplers(0, 1, &mSamplerLinear);   
DX11AppHelper::_pImmediateContext->IASetVertexBuffers(0, 1, &mQuadVertexBuffer, &mQuadStride, &mQuadOffset); 
DX11AppHelper::_pImmediateContext->IASetIndexBuffer(mQuadIndexBuffer, DXGI_FORMAT_R16_UINT, 0);   
DX11AppHelper::_pImmediateContext->DrawIndexed(6, 0, 0);   ID3D11UnorderedAccessView* nullUAV = nullptr; 
DX11AppHelper::_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, nullptr, nullptr, 0, 1, &nullUAV, 0);  // UnBind the Texture2D UAV

Here is the code to then execute the second shader, and I am also binding and then unbinding the SRV before and after.


DX11AppHelper::_pImmediateContext->OMSetRenderTargets(1, &_pRenderTargetViews[0], nullptr);
DX11AppHelper::_pImmediateContext->ClearRenderTargetView(_pRenderTargetViews[0], _pClearColour);
DX11AppHelper::_pImmediateContext->IASetInputLayout(,InputLayout);
DX11AppHelper::_pImmediateContext->VSSetShader(mVertexShader, nullptr, 0);
 
DX11AppHelper::_pImmediateContext->PSSetShader(mPixelShader, nullptr, 0);
DX11AppHelper::_pImmediateContext->VSSetConstantBuffers(0, 1, &,ConstantBuffer);
DX11AppHelper::_pImmediateContext->PSSetConstantBuffers(0, 1, &,ConstantBuffer);
 
DX11AppHelper::_pImmediateContext->PSSetShaderResources(0, 1, &mTexture2DSRV)); // Bind SRV
DX11AppHelper::_pImmediateContext->IASetVertexBuffers(0, 1, &_pQuadVertexBuffer, &_pQuadStride, &_pQuadOffset);
DX11AppHelper::_pImmediateContext->IASetIndexBuffer(_pQuadIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
DX11AppHelper::_pImmediateContext->UpdateSubresource(DX11AppHelper::_pConstantBuffer, 0, nullptr, &cb, 0, 0);
DX11AppHelper::_pImmediateContext->DrawIndexed(6, 0, 0);
ID3D11ShaderResourceView* nullShaderResourceView nullShaderResourceView = nullptr;
DX11AppHelper::_pImmediateContext->PSSetShaderResources(0, 1, &nullShaderResourceView); // Unbind SRV

I believe I am doing it correctly?

All I am getting on my screen is the cleared white colour of the UAV from the line:

const float zero[4] = { 1, 1, 1, 1 };
DX11AppHelper::_pImmediateContext->ClearUnorderedAccessViewFloat(mUAV, zero); 

Which makes me think I am setting the UAV incorrectly for the first shader perhaps?

Same problem as another guy here recently, the bracket operator use non normalized coordinate, use trunc(sv_position.xy) for the writing.

That is amazing, thank you.

It is working in that regard now, however the endgame of my work is to selectively pick which pixel I want to write to, as I want to store non-image data in the Texture2D, I want to store quad tree data, and I am bit confused as to why I cannot just tell it to write to pixel (x, y) of my choosing.

e.g. octree[0, 0] = float4(0.0f, 1.0f, 0.0f, 0.0f);

then octree[0, 1] = float4(1.0f, 1.0f, 0.0f, 0.0f); and so on

How would I go about doing that, or is that not posssible?

That's possible, yes. In fact you demonstrated that you knew how to write it in your first post:

octree[uint2(0, 1)] = float4(1,1,0,0);

octree[uint2(9,12)] = somethingElse; etc

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

That is amazing, thank you.

It is working in that regard now, however the endgame of my work is to selectively pick which pixel I want to write to, as I want to store non-image data in the Texture2D, I want to store quad tree data, and I am bit confused as to why I cannot just tell it to write to pixel (x, y) of my choosing.

e.g. octree[0, 0] = float4(0.0f, 1.0f, 0.0f, 0.0f);

then octree[0, 1] = float4(1.0f, 1.0f, 0.0f, 0.0f); and so on

How would I go about doing that, or is that not posssible?

You can. What he is saying is that there's a very high chance that input.Tex.x & input.Tex.y are floats in range [0; 1] when they should be uint in range [0; texWidth) and range [0; texHeight).

So basically when you write to pixel location (0.75; 0.75) you end up writing to (0, 0) (the first pixel) instead of writing to (768; 384) of a 1024x512 texture.

Cheers for all the help guys, one last question.

I am writing to the UAV correctly, thanks again everyone. Is there any way of effectively debugging the data in the Texture3D?

Sorry, I mixed up Texture2D and 3D =(

No problem :) The main question has been solved, is it possible for someone else to mark it as solved as I cannot gain access to my original account as for some reason, as GameDev doesn't like my logging in with Google.

This topic is closed to new replies.

Advertisement