-1

So I wanted to implement shadows in my D3D11 renderer. However, the Debug Layer gives me the warning

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM DepthStencil is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 1 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]
D3D11 WARNING: ID3D11DeviceContext::DrawIndexed: The Pixel Shader unit expects a Sampler to be set at Slot 1, but none is bound. This is perfectly valid, as a NULL Sampler maps to default Sampler state. However, the developer may not want to rely on the defaults.  [ EXECUTION WARNING #352: DEVICE_DRAW_SAMPLER_NOT_SET]
D3D11 WARNING: ID3D11DeviceContext::DrawIndexed: The Pixel Shader unit expects a Sampler to be set at Slot 1, but none is bound. This is perfectly valid, as a NULL Sampler maps to default Sampler state. However, the developer may not want to rely on the defaults.  [ EXECUTION WARNING #352: DEVICE_DRAW_SAMPLER_NOT_SET]

The relevant code is below :

void AppWindow::renderShadowMap()
{
    //GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->unbindSRV();
    //CLEAR THE RENDER TARGET AND DEPTH STENCIL
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->clearRenderTargetColor(shadow_map_rtv, 1.0, 1.0f, 1.0f, 1);
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->clearDepthStencil(shadow_map_dsv);
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->SetRenderTarget(shadow_map_rtv, shadow_map_dsv);
    //SET VIEWPORT OF RENDER TARGET IN WHICH WE HAVE TO DRAW
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->setViewportSize(1920, 1080);

    lightViewMatrix = Matrix4x4::lookAt(Vector3D(2,2,0), Vector3D(0, 0, 0), Vector3D(0, 1, 0));
    lightProjectionMatrix.setOrthoProj(20, 20, 1.0f, 10.0f);
    lightSpaceMatrix = lightProjectionMatrix;
    lightSpaceMatrix *= lightViewMatrix;

    updateModel(Vector3D(0, 0, 0), MAT_shadow_map);
    SM_mesh->drawMesh(MAT_shadow_map);

    updateModel(Vector3D(0, -0.5f, 0), MAT_shadow_map);
    SM_plane->drawMesh(MAT_shadow_map);

    SM_sky_mesh->drawMesh(MAT_shadow_map);

    //GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->SetRenderTarget(NULL, NULL);
}

void AppWindow::render()
{
    //CLEAR THE RENDER TARGET 
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->clearRenderTargetColor(this->m_swap_chain, 0.3f, 0.4f, 0.5f, 1);
    //SET VIEWPORT OF RENDER TARGET IN WHICH WE HAVE TO DRAW
    RECT rc = this->getClientWindowRect();
    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->setViewportSize(rc.right - rc.left, rc.bottom - rc.top);

    update();

    updateModel(Vector3D(0, 0, 0), MAT_mesh);
    SM_mesh->drawMesh(MAT_mesh);

    updateModel(Vector3D(0, -0.5f, 0), MAT_mesh);
    SM_plane->drawMesh(MAT_mesh);

    SM_sky_mesh->drawMesh(MAT_sky);

    m_swap_chain->present(true);

    oldDelta = newDelta;
    newDelta = ::GetTickCount();
    deltaTime = (oldDelta) ? ((newDelta - oldDelta) / 1000.0f) : 0.0f;
    time += deltaTime;

    GraphicsEngine::get()->getRenderSystem()->getImmediateDeviceContext()->unbindSRV();
}
void DeviceContext::unbindSRV()
{
    ID3D11ShaderResourceView* nullSRV[1] = { nullptr };
    m_device_context->PSSetShaderResources(0, 1, nullSRV);
}

I just need to know how and where do I unbind the shadow_map_rtv and shadow_map_dsv as that is what is causing the problem. Cannot find anything similar online.

  • Well I don't see any samplers bound so that would explain last two error messages. Regarding the first two, what is exactly inside SetRenderTarget of your Context abstraction and why did you uncomment it? – mateeeeeee Aug 09 '21 at 18:39

2 Answers2

0

I guess your shadow map render pipeline is wrong. First you should set render target to nullptr or NULL. Then create and bind a depth stencil for shadow map. Then clear the depth stencil and render your scene from light view. If you have any camera class in your program, you can create another camera for light. You can use depth stencil output texture as shadow map for shadow mapping shader. All the another stuff like sampler or primitive topology is optional for your rendering pipeline. I'll drop a piece of code.

ID3D11RenderTargetView* rtv[1] = { 0 };
pContext->OMSetRenderTargets(1, rtv, dsShadow->pDepthStencilView.Get());
dsShadow->Clear(pContext.Get());
RenderScene(pDirectLight->GetLightCamera());
Choi
  • 76
  • 1
  • 5
0

In the warning message, it seems you are setting your shadow map to slot 1 (when bound for reading in the pixel shader).

But your unbindSRV function only clears slot 0, so it's very likely that your shadow map is still bound there when you set it back for writing (via SetRenderTarget).

In that order it's ok, since the pipeline will unassign the Shader resource view for you (and issue a warning), but it's generally good practice to make pipeline happy indeed (you might miss important warnings later).

So you should have that function working as :

void DeviceContext::unbindSRV(int slot)
{
    ID3D11ShaderResourceView* nullSRV[1] = { nullptr };
    m_device_context->PSSetShaderResources(slot, 1, nullSRV);
}

Or do several unbinds at the same time if relevant, for example :

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

The second option is generally more efficient.

For the sampler issue, it seems that you don't attach a sampler state indeed (It's in slot 1 too, so maybe you set one to slot 0 by mistake)

It's also good practice to create one with the settings you want and then assign.

mrvux
  • 8,523
  • 1
  • 27
  • 61