[DirectX11] Multiple Render Target

Started by
10 comments, last by enigmagame 12 years, 11 months ago
Hi, I'm writing a demo that uses Deferred Shading in DirectX11 but I've some troubles with MTR.
Some info:
- I use DXUT;
- I've implemented a class that represent a RenderTarget (ID3D11Texture2D, ID3D11RenderTargetView, ID3D11ShaderResourceView);
In particular, when I debug with PIX, I get those output log, but I don't understand the problem:



Time EID Type Context Message
0 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD ]
1 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 0 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD ]
2 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 1 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD ]
3 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 1 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD ]
4 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 2 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD ]
5 126 Message Render D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 2 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD ]




Let me know if you need more info or some code.
Thanks.
Advertisement
You are likely using the texture resource(s) for those render targets for a shader, and still have them bound to that stage of the rendering pipeline. You can't have the resource bound for input and output at the same time in D3D11.

You are likely using the texture resource(s) for those render targets for a shader, and still have them bound to that stage of the rendering pipeline. You can't have the resource bound for input and output at the same time in D3D11.


Ok, I understand this. But how I can solve?
Basically in D3D11_TEXTURE2D_DESC as BindFlags I use D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE.
Now, as first step I need to write on the texture, and after I need to pass this texture to another shader. How can I proceed?
Thanks.
You cant have a texture bound as input (shader resource view) and output (render target) at the same time.

After you render whatever you want to render using a shader resource view, set the ID3D11EffectShaderResourceVariable* to NULL and apply.


(your ID3D11EffectShaderResourceVariable*)->SetResource(NULL);
(your ID3D10EffectTechnique*)->GetPassByIndex(0)->Apply(0);


So you can bound the render target again
Thanks[color="#1c2837"] TiagoCosta, I understood what you say, but I'm in the opposite situation. Ok, today I'm very, very tired.
[color="#1c2837"]Basically this is my situation:
[color="#1c2837"]

ID3D11RenderTargetView* renderTargetViewArray[3] =
{
m_colorRenderTarget,
m_normalRenderTarget,
m_depthRenderTarget
};

i_deviceContext->OMSetRenderTargets(3, renderTargetViewArray, depthStencilView);

// Clear render targets

// Draw

i_deviceContext->OMSetRenderTargets(1, &lightRenderTarget, NULL);

// Here I need to use the three textures filled by the precedent draw call


[color="#1c2837"]Maybe tomorrow, after a good sleep, I can solve this. biggrin.gif
I've not yet solved.sad.gif
Any suggestions?
Can you post the full code you use to set render targets, draw calls and set shader resources??

Can you post the full code you use to set render targets, draw calls and set shader resources??


This is the code sequence:


// Set render targets
ID3D11RenderTargetView* renderTargetViewArray[3] =
{
g_colorRenderTarget->GetRenderTarget(),
g_normalRenderTarget->GetRenderTarget(),
g_depthRenderTarget->GetRenderTarget()
};

ID3D11DepthStencilView* depthStencilView = DXUTGetD3D11DepthStencilView();

i_deviceContext->OMSetRenderTargets(3, renderTargetViewArray, depthStencilView);

// Clear render targets
const float clearColor[4] = {0.f, 0.f, 0.f, 0.f};
g_colorRenderTarget->Clear(i_deviceContext, clearColor);

const float clearNormal[4] = {0.5f, 0.5f, 0.5f, 0.f};
g_normalRenderTarget->Clear(i_deviceContext, clearNormal);

const float clearDepth[1] = {1.f};
g_depthRenderTarget->Clear(i_deviceContext, clearDepth);

i_deviceContext->ClearDepthStencilView(DXUTGetD3D11DepthStencilView(), D3D11_CLEAR_DEPTH, 1.0, 0);

// Draw Scene
g_RenderGBufferEffect->GetVariableByName("World")->AsMatrix()->SetMatrix(g_WorldCube);
g_RenderGBufferEffect->GetVariableByName("View")->AsMatrix()->SetMatrix((float*) &g_View);
g_RenderGBufferEffect->GetVariableByName("Projection")->AsMatrix()->SetMatrix((float*) &g_Projection);

SetMaterial(g_MaterialCube);

i_deviceContext->IASetInputLayout(g_pVertexLayout);
i_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

const UINT stride = sizeof(SimpleVertex);
const UINT offset = 0;
i_deviceContext->IASetVertexBuffers(0, 1, &g_pVertexBufferCube, &stride, &offset);
i_deviceContext->IASetIndexBuffer(g_pIndexBufferCube, DXGI_FORMAT_R32_UINT, 0);

D3DX11_TECHNIQUE_DESC techDesc;
g_RenderGBufferTechnique->GetDesc(&techDesc);

for(UINT p = 0; p < techDesc.Passes; ++p)
{
g_RenderGBufferTechnique->GetPassByIndex(p)->Apply(0, i_deviceContext);
i_deviceContext->DrawIndexed(36, 0, 0);
}

// Set and clear render target
const float clearLight[4] = {0.f, 0.f, 0.f, 0.f};

ID3D11RenderTargetView* lightRenderTarget = g_lightRenderTarget->GetRenderTarget();
i_deviceContext->OMSetRenderTargets(1, &lightRenderTarget, NULL);
g_lightRenderTarget->Clear(i_deviceContext, clearLight);

// Draw
g_pointLightEffect->GetVariableByName("colorTexture")->AsShaderResource()->SetResource(g_colorRenderTarget->GetResourceView());
g_pointLightEffect->GetVariableByName("normalTexture")->AsShaderResource()->SetResource(g_normalRenderTarget->GetResourceView());
g_pointLightEffect->GetVariableByName("depthTexture")->AsShaderResource()->SetResource(g_depthRenderTarget->GetResourceView());

i_deviceContext->IASetInputLayout(g_pointLightLayout);

D3DX11_TECHNIQUE_DESC techDesc;
g_pointLightTechnique->GetDesc( &techDesc );

for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pointLightTechnique->GetPassByIndex( p )->Apply(0,i_deviceContext);
g_MeshSphere.Render(i_deviceContext);
}

[quote name='TiagoCosta' timestamp='1304285362' post='4805174']
Can you post the full code you use to set render targets, draw calls and set shader resources??


This is the code sequence:


// Set render targets
ID3D11RenderTargetView* renderTargetViewArray[3] =
{
g_colorRenderTarget->GetRenderTarget(),
g_normalRenderTarget->GetRenderTarget(),
g_depthRenderTarget->GetRenderTarget()
};

ID3D11DepthStencilView* depthStencilView = DXUTGetD3D11DepthStencilView();

i_deviceContext->OMSetRenderTargets(3, renderTargetViewArray, depthStencilView);

// Clear render targets
const float clearColor[4] = {0.f, 0.f, 0.f, 0.f};
g_colorRenderTarget->Clear(i_deviceContext, clearColor);

const float clearNormal[4] = {0.5f, 0.5f, 0.5f, 0.f};
g_normalRenderTarget->Clear(i_deviceContext, clearNormal);

const float clearDepth[1] = {1.f};
g_depthRenderTarget->Clear(i_deviceContext, clearDepth);

i_deviceContext->ClearDepthStencilView(DXUTGetD3D11DepthStencilView(), D3D11_CLEAR_DEPTH, 1.0, 0);

// Draw Scene
g_RenderGBufferEffect->GetVariableByName("World")->AsMatrix()->SetMatrix(g_WorldCube);
g_RenderGBufferEffect->GetVariableByName("View")->AsMatrix()->SetMatrix((float*) &g_View);
g_RenderGBufferEffect->GetVariableByName("Projection")->AsMatrix()->SetMatrix((float*) &g_Projection);

SetMaterial(g_MaterialCube);

i_deviceContext->IASetInputLayout(g_pVertexLayout);
i_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

const UINT stride = sizeof(SimpleVertex);
const UINT offset = 0;
i_deviceContext->IASetVertexBuffers(0, 1, &g_pVertexBufferCube, &stride, &offset);
i_deviceContext->IASetIndexBuffer(g_pIndexBufferCube, DXGI_FORMAT_R32_UINT, 0);

D3DX11_TECHNIQUE_DESC techDesc;
g_RenderGBufferTechnique->GetDesc(&techDesc);

for(UINT p = 0; p < techDesc.Passes; ++p)
{
g_RenderGBufferTechnique->GetPassByIndex(p)->Apply(0, i_deviceContext);
i_deviceContext->DrawIndexed(36, 0, 0);
}

// Set and clear render target
const float clearLight[4] = {0.f, 0.f, 0.f, 0.f};

ID3D11RenderTargetView* lightRenderTarget = g_lightRenderTarget->GetRenderTarget();
i_deviceContext->OMSetRenderTargets(1, &lightRenderTarget, NULL);
g_lightRenderTarget->Clear(i_deviceContext, clearLight);

// Draw
g_pointLightEffect->GetVariableByName("colorTexture")->AsShaderResource()->SetResource(g_colorRenderTarget->GetResourceView());
g_pointLightEffect->GetVariableByName("normalTexture")->AsShaderResource()->SetResource(g_normalRenderTarget->GetResourceView());
g_pointLightEffect->GetVariableByName("depthTexture")->AsShaderResource()->SetResource(g_depthRenderTarget->GetResourceView());

i_deviceContext->IASetInputLayout(g_pointLightLayout);

D3DX11_TECHNIQUE_DESC techDesc;
g_pointLightTechnique->GetDesc( &techDesc );

for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pointLightTechnique->GetPassByIndex( p )->Apply(0,i_deviceContext);
g_MeshSphere.Render(i_deviceContext);
}

[/quote]

With the provided code those textures will still be bound on the input stage when another frame is rendered; you will have to clear them from the shader before drawing the next frame.

With the provided code those textures will still be bound on the input stage when another frame is rendered; you will have to clear them from the shader before drawing the next frame.


Yes, I've understand the problem, but not the solution, or rather, the pratical solution.

This topic is closed to new replies.

Advertisement