3
\$\begingroup\$

After following the 22th tutorial of Rastertek. I and some others on the internet have had an error. Despite following the tutorial to the letter. However, the answers to this error message have been a bit diffuse. So for future reference and if anyone else founds this thread. Lets once and for all, settle this!

When debugging we get this error message:

ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input!

ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 0 to NULL.

So, here is some code;

   HRESULT Application::RenderToTexture()
    {
        HRESULT hr = S_OK;

        //Set render target to render to the texture inside mRenderTexture
//Inside this func we see this: _deviceContext->OMSetRenderTargets(1, &this->mRenderTargetView, _depthStencilView);
        this->mRenderTexture.SetRenderTarget(this->mDirectX.GetDeviceContext(), this->mDirectX.GetDepthStencilView());
        //clear it
        this->mRenderTexture.ClearRenderTarget(this->mDirectX.GetDeviceContext(), this->mDirectX.GetDepthStencilView(), 0.0f, 0.0f, 1.0f, 1.0f);

        // Render the scene now and it will draw to the render to texture instead of the back buffer.
        hr = RenderScene(); //Using the render target
        if(FAILED(hr))
            return hr;

        // Reset the render target back to the original back buffer and not the render to texture anymore.
        this->mDirectX.SetBackBufferRenderTarget();

        return hr;
    }

We need to take a look inside RenderTextureClass (mRenderTexture). It is focused on these membervariables.

class RenderTextureClass
{
private:
    ID3D11Texture2D*            mRenderTargetTexture; //This is the root of the issue
    ID3D11RenderTargetView*     mRenderTargetView;
    ID3D11ShaderResourceView*   mShaderResourceView;

If we are to understand the answers of others. They say that the RenderTargetView AND the ShaderResourceView is used both at the same time and is then unable to work properly.

Init function;

HRESULT RenderTextureClass::Initialize(ID3D11Device* _device, XMFLOAT2 _textureSize)
{
    HRESULT hr = S_OK;

    //Setup RenderTargetTexture
    D3D11_TEXTURE2D_DESC textureDesc;
    ZeroMemory(&textureDesc, sizeof(textureDesc));

    textureDesc.Width               = _textureSize.x;
    textureDesc.Height              = _textureSize.y;
    textureDesc.MipLevels           = 1;
    textureDesc.ArraySize           = 1;
    textureDesc.Format              = DXGI_FORMAT_R32G32B32A32_FLOAT;
    textureDesc.SampleDesc.Count    = 1;
    textureDesc.SampleDesc.Quality  = 0;
    textureDesc.Usage               = D3D11_USAGE_DEFAULT;
    textureDesc.BindFlags           = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    textureDesc.CPUAccessFlags      = 0;
    textureDesc.MiscFlags           = 0;

    hr = _device->CreateTexture2D(&textureDesc, NULL, &this->mRenderTargetTexture);
    if(FAILED(hr))
        return hr;

    //Setup RenderTargetView
    D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
    renderTargetViewDesc.Format             = textureDesc.Format;
    renderTargetViewDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
    renderTargetViewDesc.Texture2D.MipSlice = 0;

    hr = _device->CreateRenderTargetView(this->mRenderTargetTexture, &renderTargetViewDesc, &this->mRenderTargetView);
    if(FAILED(hr))
        return hr;

    //Setup Shader resourceview
    D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
    shaderResourceViewDesc.Format                       = textureDesc.Format;
    shaderResourceViewDesc.ViewDimension                = D3D11_SRV_DIMENSION_TEXTURE2D;
    shaderResourceViewDesc.Texture2D.MostDetailedMip    = 0;
    shaderResourceViewDesc.Texture2D.MipLevels          = 1;

    hr = _device->CreateShaderResourceView(this->mRenderTargetTexture, &shaderResourceViewDesc, &this->mShaderResourceView);
    if(FAILED(hr))
        return hr;

    return hr;
}

So to the question. How do we correct this in the most reasonable manner without breaking everything?

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You can't have the same texture bound as both an input and an output at the same time. The solution is to explicitly clear one binding before applying the new binding.

In the DirectX Tool Kit tutorial for post-processing:

m_d3dContext->OMSetRenderTargets(1, m_rt1RT.GetAddressOf(), nullptr);
// Draw using m_sceneSRV

m_d3dContext->OMSetRenderTargets(1, m_rt2RT.GetAddressOf(), nullptr);
// Draw using m_rt1SRV

ID3D11ShaderResourceView* null[] = { nullptr, nullptr };
m_d3dContext->PSSetShaderResources(0, 2, null);

m_d3dContext->OMSetRenderTargets(1, m_rt1RT.GetAddressOf(), nullptr);
// Draw using m_rt2SRV

m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), nullptr);
// Draw using m_rt1SRV

m_d3dContext->PSSetShaderResources(0, 2, null);

To avoid the same warning.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.