Home > Enterprise >  ID3D11RenderTargetView gets removed on ID3D11DeviceContext::OMSetRenderTargets()
ID3D11RenderTargetView gets removed on ID3D11DeviceContext::OMSetRenderTargets()

Time:10-10

I built a very simple, okay nothing, program that just clears the render target. Eventually when I call ID3D11DeviceContext::OMSetRenderTargets() the ID3D11RenderTargetView gets removed and I can't see why. My thought is somewhere at the creating of the IDXGISwapChain1 I specified something wrong.

Once:

UINT deviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef _DEBUG
deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

GFX_THROW_IF_FAILED(D3D11CreateDevice(
    nullptr,
    D3D_DRIVER_TYPE_HARDWARE,
    nullptr,
    deviceFlags,
    nullptr,
    0u,
    D3D11_SDK_VERSION,
    &m_pDevice,
    &m_featureLevel,
    &m_pContext
));

if (m_featureLevel < D3D_FEATURE_LEVEL_11_0)
    throw ExceptionMessage(__FILE__, __LINE__, "Graphics device does not support feature level 11.");

Microsoft::WRL::ComPtr<IDXGIFactory2> pFactory = {};
GFX_THROW_IF_FAILED(CreateDXGIFactory(IID_PPV_ARGS(&pFactory)));

DXGI_SWAP_CHAIN_DESC1 scDesc = {};
scDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scDesc.SampleDesc.Count = 1u;
scDesc.SampleDesc.Quality = 0u;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.BufferCount = sc_uBufferCount;
scDesc.Scaling = DXGI_SCALING_NONE;
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
scDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
scDesc.Flags = 0u;

GFX_THROW_IF_FAILED(pFactory->CreateSwapChainForHwnd(
    m_pDevice.Get(),
    t_hWnd,
    &scDesc,
    nullptr,
    nullptr,
    &m_pSwapChain
));

m_uWindowWidth = scDesc.Width;
m_uWindowHeight = scDesc.Height;


Microsoft::WRL::ComPtr<ID3D11Resource> pBackBuffer = {};
GFX_THROW_IF_FAILED(m_pSwapChain->GetBuffer(0u, IID_PPV_ARGS(&pBackBuffer)));
GFX_THROW_IF_FAILED(m_pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, &m_pTarget));

and the update method:

float color[] = { (252.0f / 255.0f), (186.0f / 255.0f), (3.0f / 255.0f), 1.0f };
m_pContext->ClearRenderTargetView(m_pTarget.Get(), color);

m_pContext->OMSetRenderTargets(1u, &m_pTarget, nullptr);
if (m_pTarget.Get() == nullptr)
    throw ExceptionMessage(__FILE__, __LINE__, "m_pTarget has been set to null");

GFX_THROW_IF_FAILED(m_pSwapChain->Present(1u, 0u));

CodePudding user response:

I assume that you are using Microsoft::WRL::ComPtr to manage m_pTarget. So when invoking m_pContext->OMSetRenderTargets(1u, &m_pTarget, nullptr); an overloaded operator & is being used rather than just taking an address of pointer to pass it as a pointer to first element of array containing a single pointer. Overloaded operator & is intended to be used when passing a pointer to pointer value to some initialization function so it releases ownership of the stored pointer therefore you are getting nulls.

You should use GetAddressOf method

m_pContext->OMSetRenderTargets(1u, m_pTarget.GetAddressOf(), nullptr);

or create a temporary array instead:

::std::array<::ID3D11RenderTargetView *> views{m_pTarget.Get()};
m_pContext->OMSetRenderTargets(views.size(), views.data(), nullptr);
  • Related