From 77c032da5c0299bb426d740e463ab4c8171e15a6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 18:07:03 +0200 Subject: [PATCH] [d3d11] Move OM* functions to D3D11CommonContext We can get rid of the immediate context overload as well since we can just directly call FlushImplicit here. --- src/d3d11/d3d11_context.cpp | 325 ----------------------------- src/d3d11/d3d11_context.h | 60 ------ src/d3d11/d3d11_context_common.cpp | 306 ++++++++++++++++++++++++++- src/d3d11/d3d11_context_common.h | 56 +++++ src/d3d11/d3d11_context_imm.cpp | 27 --- src/d3d11/d3d11_context_imm.h | 14 -- 6 files changed, 360 insertions(+), 428 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 17656170d..0d4b27f55 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2353,215 +2353,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - OMSetRenderTargetsAndUnorderedAccessViews( - NumViews, ppRenderTargetViews, pDepthStencilView, - NumViews, 0, nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts) { - D3D10DeviceLock lock = LockContext(); - - if (TestRtvUavHazards(NumRTVs, ppRenderTargetViews, NumUAVs, ppUnorderedAccessViews)) - return; - - bool needsUpdate = false; - - if (likely(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)) { - // Native D3D11 does not change the render targets if - // the parameters passed to this method are invalid. - if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) - return; - - for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { - auto rtv = i < NumRTVs - ? static_cast(ppRenderTargetViews[i]) - : nullptr; - - if (m_state.om.renderTargetViews[i] != rtv) { - m_state.om.renderTargetViews[i] = rtv; - needsUpdate = true; - ResolveOmSrvHazards(rtv); - - if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - ResolveOmUavHazards(rtv); - } - } - - auto dsv = static_cast(pDepthStencilView); - - if (m_state.om.depthStencilView != dsv) { - m_state.om.depthStencilView = dsv; - needsUpdate = true; - ResolveOmSrvHazards(dsv); - } - - m_state.om.maxRtv = NumRTVs; - } - - if (unlikely(NumUAVs || m_state.om.maxUav)) { - uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); - uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); - - if (likely(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)) { - uint32_t newMaxUav = NumUAVs ? UAVStartSlot + NumUAVs : 0; - uint32_t oldMaxUav = std::exchange(m_state.om.maxUav, newMaxUav); - - for (uint32_t i = 0; i < std::max(oldMaxUav, newMaxUav); i++) { - D3D11UnorderedAccessView* uav = nullptr; - uint32_t ctr = ~0u; - - if (i >= UAVStartSlot && i < UAVStartSlot + NumUAVs) { - uav = static_cast(ppUnorderedAccessViews[i - UAVStartSlot]); - ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; - } - - if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { - m_state.ps.unorderedAccessViews[i] = uav; - - BindUnorderedAccessView( - uavSlotId + i, uav, - ctrSlotId + i, ctr); - - ResolveOmSrvHazards(uav); - - if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - needsUpdate |= ResolveOmRtvHazards(uav); - } - } - } - } - - if (needsUpdate) - BindFramebuffer(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetBlendState( - ID3D11BlendState* pBlendState, - const FLOAT BlendFactor[4], - UINT SampleMask) { - D3D10DeviceLock lock = LockContext(); - - auto blendState = static_cast(pBlendState); - - if (m_state.om.cbState != blendState - || m_state.om.sampleMask != SampleMask) { - m_state.om.cbState = blendState; - m_state.om.sampleMask = SampleMask; - - ApplyBlendState(); - } - - if (BlendFactor != nullptr) { - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendFactor[i] = BlendFactor[i]; - - ApplyBlendFactor(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetDepthStencilState( - ID3D11DepthStencilState* pDepthStencilState, - UINT StencilRef) { - D3D10DeviceLock lock = LockContext(); - - auto depthStencilState = static_cast(pDepthStencilState); - - if (m_state.om.dsState != depthStencilState) { - m_state.om.dsState = depthStencilState; - ApplyDepthStencilState(); - } - - if (m_state.om.stencilRef != StencilRef) { - m_state.om.stencilRef = StencilRef; - ApplyStencilRef(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView) { - D3D10DeviceLock lock = LockContext(); - - if (ppRenderTargetViews != nullptr) { - for (UINT i = 0; i < NumViews; i++) { - ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() - ? m_state.om.renderTargetViews[i].ref() - : nullptr; - } - } - - if (ppDepthStencilView != nullptr) - *ppDepthStencilView = m_state.om.depthStencilView.ref(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews) { - OMGetRenderTargets(NumRTVs, ppRenderTargetViews, ppDepthStencilView); - - D3D10DeviceLock lock = LockContext(); - - if (ppUnorderedAccessViews != nullptr) { - for (UINT i = 0; i < NumUAVs; i++) { - ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() - ? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() - : nullptr; - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetBlendState( - ID3D11BlendState** ppBlendState, - FLOAT BlendFactor[4], - UINT* pSampleMask) { - D3D10DeviceLock lock = LockContext(); - - if (ppBlendState != nullptr) - *ppBlendState = ref(m_state.om.cbState); - - if (BlendFactor != nullptr) - std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4); - - if (pSampleMask != nullptr) - *pSampleMask = m_state.om.sampleMask; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetDepthStencilState( - ID3D11DepthStencilState** ppDepthStencilState, - UINT* pStencilRef) { - D3D10DeviceLock lock = LockContext(); - - if (ppDepthStencilState != nullptr) - *ppDepthStencilState = ref(m_state.om.dsState); - - if (pStencilRef != nullptr) - *pStencilRef = m_state.om.stencilRef; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { D3D10DeviceLock lock = LockContext(); @@ -4385,122 +4176,6 @@ namespace dxvk { } - template - void D3D11DeviceContext::ResolveOmSrvHazards( - T* pView) { - if (!pView) return; - ResolveSrvHazards (pView, m_state.vs.shaderResources); - ResolveSrvHazards (pView, m_state.hs.shaderResources); - ResolveSrvHazards (pView, m_state.ds.shaderResources); - ResolveSrvHazards (pView, m_state.gs.shaderResources); - ResolveSrvHazards (pView, m_state.ps.shaderResources); - } - - - bool D3D11DeviceContext::ResolveOmRtvHazards( - D3D11UnorderedAccessView* pView) { - if (!pView || !pView->HasBindFlag(D3D11_BIND_RENDER_TARGET)) - return false; - - bool hazard = false; - - if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) { - m_state.om.depthStencilView = nullptr; - hazard = true; - } - - for (uint32_t i = 0; i < m_state.om.maxRtv; i++) { - if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) { - m_state.om.renderTargetViews[i] = nullptr; - hazard = true; - } - } - - return hazard; - } - - - void D3D11DeviceContext::ResolveOmUavHazards( - D3D11RenderTargetView* pView) { - if (!pView || !pView->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) - return; - - uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); - uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); - - for (uint32_t i = 0; i < m_state.om.maxUav; i++) { - if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { - m_state.ps.unorderedAccessViews[i] = nullptr; - - BindUnorderedAccessView( - uavSlotId + i, nullptr, - ctrSlotId + i, ~0u); - } - } - } - - - bool D3D11DeviceContext::ValidateRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - Rc refView; - - VkExtent3D dsvExtent = { 0u, 0u, 0u }; - VkExtent3D rtvExtent = { 0u, 0u, 0u }; - - if (pDepthStencilView != nullptr) { - refView = static_cast( - pDepthStencilView)->GetImageView(); - dsvExtent = refView->mipLevelExtent(0); - } - - for (uint32_t i = 0; i < NumViews; i++) { - if (ppRenderTargetViews[i] != nullptr) { - auto curView = static_cast( - ppRenderTargetViews[i])->GetImageView(); - - if (!rtvExtent.width) - rtvExtent = curView->mipLevelExtent(0); - - if (refView != nullptr) { - // Render target views must all have the same sample count, - // layer count, and type. The size can mismatch under certain - // conditions, the D3D11 documentation is wrong here. - if (curView->info().type != refView->info().type - || curView->info().numLayers != refView->info().numLayers) - return false; - - if (curView->imageInfo().sampleCount - != refView->imageInfo().sampleCount) - return false; - - // Color targets must all be the same size - VkExtent3D curExtent = curView->mipLevelExtent(0); - - if (curExtent.width != rtvExtent.width - || curExtent.height != rtvExtent.height) - return false; - } else { - // Set reference view. All remaining views - // must be compatible to the reference view. - refView = curView; - } - } - } - - // Based on testing, the depth-stencil target is allowed - // to be larger than all color targets, but not smaller - if (rtvExtent.width && dsvExtent.width) { - if (rtvExtent.width > dsvExtent.width - || rtvExtent.height > dsvExtent.height) - return false; - } - - return true; - } - - VkClearValue D3D11DeviceContext::ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 4e153f254..21e5d4c03 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -579,51 +579,6 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews); - void STDMETHODCALLTYPE OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - - void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts); - - void STDMETHODCALLTYPE OMSetBlendState( - ID3D11BlendState* pBlendState, - const FLOAT BlendFactor[4], - UINT SampleMask); - - void STDMETHODCALLTYPE OMSetDepthStencilState( - ID3D11DepthStencilState* pDepthStencilState, - UINT StencilRef); - - void STDMETHODCALLTYPE OMGetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView); - - void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews); - - void STDMETHODCALLTYPE OMGetBlendState( - ID3D11BlendState** ppBlendState, - FLOAT BlendFactor[4], - UINT* pSampleMask); - - void STDMETHODCALLTYPE OMGetDepthStencilState( - ID3D11DepthStencilState** ppDepthStencilState, - UINT* pStencilRef); - void STDMETHODCALLTYPE RSSetState( ID3D11RasterizerState* pRasterizerState); @@ -912,21 +867,6 @@ namespace dxvk { void ResolveCsSrvHazards( T* pView); - template - void ResolveOmSrvHazards( - T* pView); - - bool ResolveOmRtvHazards( - D3D11UnorderedAccessView* pView); - - void ResolveOmUavHazards( - D3D11RenderTargetView* pView); - - bool ValidateRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index ebbdc3ed8..3e7430598 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -10,8 +10,8 @@ namespace dxvk { const Rc& Device, DxvkCsChunkFlags CsFlags) : D3D11DeviceContext(pParent, Device, CsFlags), - m_contextExt(static_cast(this)), - m_annotation(static_cast(this), Device) { + m_contextExt(GetTypedContext()), + m_annotation(GetTypedContext(), Device) { } @@ -90,6 +90,162 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView) { + D3D10DeviceLock lock = LockContext(); + + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(true); + + SetRenderTargetsAndUnorderedAccessViews( + NumViews, ppRenderTargetViews, pDepthStencilView, + NumViews, 0, nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts) { + D3D10DeviceLock lock = LockContext(); + + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(true); + + SetRenderTargetsAndUnorderedAccessViews( + NumRTVs, ppRenderTargetViews, pDepthStencilView, + UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetBlendState( + ID3D11BlendState* pBlendState, + const FLOAT BlendFactor[4], + UINT SampleMask) { + D3D10DeviceLock lock = LockContext(); + + auto blendState = static_cast(pBlendState); + + if (m_state.om.cbState != blendState + || m_state.om.sampleMask != SampleMask) { + m_state.om.cbState = blendState; + m_state.om.sampleMask = SampleMask; + + ApplyBlendState(); + } + + if (BlendFactor != nullptr) { + for (uint32_t i = 0; i < 4; i++) + m_state.om.blendFactor[i] = BlendFactor[i]; + + ApplyBlendFactor(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetDepthStencilState( + ID3D11DepthStencilState* pDepthStencilState, + UINT StencilRef) { + D3D10DeviceLock lock = LockContext(); + + auto depthStencilState = static_cast(pDepthStencilState); + + if (m_state.om.dsState != depthStencilState) { + m_state.om.dsState = depthStencilState; + ApplyDepthStencilState(); + } + + if (m_state.om.stencilRef != StencilRef) { + m_state.om.stencilRef = StencilRef; + ApplyStencilRef(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView) { + OMGetRenderTargetsAndUnorderedAccessViews( + NumViews, ppRenderTargetViews, ppDepthStencilView, + NumViews, 0, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews) { + D3D10DeviceLock lock = LockContext(); + + if (ppRenderTargetViews) { + for (UINT i = 0; i < NumRTVs; i++) { + ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() + ? m_state.om.renderTargetViews[i].ref() + : nullptr; + } + } + + if (ppDepthStencilView) + *ppDepthStencilView = m_state.om.depthStencilView.ref(); + + if (ppUnorderedAccessViews) { + for (UINT i = 0; i < NumUAVs; i++) { + ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() + ? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() + : nullptr; + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetBlendState( + ID3D11BlendState** ppBlendState, + FLOAT BlendFactor[4], + UINT* pSampleMask) { + D3D10DeviceLock lock = LockContext(); + + if (ppBlendState) + *ppBlendState = ref(m_state.om.cbState); + + if (BlendFactor) + std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4); + + if (pSampleMask) + *pSampleMask = m_state.om.sampleMask; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetDepthStencilState( + ID3D11DepthStencilState** ppDepthStencilState, + UINT* pStencilRef) { + D3D10DeviceLock lock = LockContext(); + + if (ppDepthStencilState) + *ppDepthStencilState = ref(m_state.om.dsState); + + if (pStencilRef) + *pStencilRef = m_state.om.stencilRef; + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); @@ -459,6 +615,90 @@ namespace dxvk { } + template + void D3D11CommonContext::SetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts) { + if (TestRtvUavHazards(NumRTVs, ppRenderTargetViews, NumUAVs, ppUnorderedAccessViews)) + return; + + bool needsUpdate = false; + + if (likely(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)) { + // Native D3D11 does not change the render targets if + // the parameters passed to this method are invalid. + if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) + return; + + for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { + auto rtv = i < NumRTVs + ? static_cast(ppRenderTargetViews[i]) + : nullptr; + + if (m_state.om.renderTargetViews[i] != rtv) { + m_state.om.renderTargetViews[i] = rtv; + needsUpdate = true; + ResolveOmSrvHazards(rtv); + + if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + ResolveOmUavHazards(rtv); + } + } + + auto dsv = static_cast(pDepthStencilView); + + if (m_state.om.depthStencilView != dsv) { + m_state.om.depthStencilView = dsv; + needsUpdate = true; + ResolveOmSrvHazards(dsv); + } + + m_state.om.maxRtv = NumRTVs; + } + + if (unlikely(NumUAVs || m_state.om.maxUav)) { + uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); + uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); + + if (likely(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)) { + uint32_t newMaxUav = NumUAVs ? UAVStartSlot + NumUAVs : 0; + uint32_t oldMaxUav = std::exchange(m_state.om.maxUav, newMaxUav); + + for (uint32_t i = 0; i < std::max(oldMaxUav, newMaxUav); i++) { + D3D11UnorderedAccessView* uav = nullptr; + uint32_t ctr = ~0u; + + if (i >= UAVStartSlot && i < UAVStartSlot + NumUAVs) { + uav = static_cast(ppUnorderedAccessViews[i - UAVStartSlot]); + ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; + } + + if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { + m_state.ps.unorderedAccessViews[i] = uav; + + BindUnorderedAccessView( + uavSlotId + i, uav, + ctrSlotId + i, ctr); + + ResolveOmSrvHazards(uav); + + if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + needsUpdate |= ResolveOmRtvHazards(uav); + } + } + } + } + + if (needsUpdate) + BindFramebuffer(); + } + + template bool D3D11CommonContext::TestRtvUavHazards( UINT NumRTVs, @@ -593,6 +833,68 @@ namespace dxvk { } + template + bool D3D11CommonContext::ValidateRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView) { + Rc refView; + + VkExtent3D dsvExtent = { 0u, 0u, 0u }; + VkExtent3D rtvExtent = { 0u, 0u, 0u }; + + if (pDepthStencilView != nullptr) { + refView = static_cast( + pDepthStencilView)->GetImageView(); + dsvExtent = refView->mipLevelExtent(0); + } + + for (uint32_t i = 0; i < NumViews; i++) { + if (ppRenderTargetViews[i] != nullptr) { + auto curView = static_cast( + ppRenderTargetViews[i])->GetImageView(); + + if (!rtvExtent.width) + rtvExtent = curView->mipLevelExtent(0); + + if (refView != nullptr) { + // Render target views must all have the same sample count, + // layer count, and type. The size can mismatch under certain + // conditions, the D3D11 documentation is wrong here. + if (curView->info().type != refView->info().type + || curView->info().numLayers != refView->info().numLayers) + return false; + + if (curView->imageInfo().sampleCount + != refView->imageInfo().sampleCount) + return false; + + // Color targets must all be the same size + VkExtent3D curExtent = curView->mipLevelExtent(0); + + if (curExtent.width != rtvExtent.width + || curExtent.height != rtvExtent.height) + return false; + } else { + // Set reference view. All remaining views + // must be compatible to the reference view. + refView = curView; + } + } + } + + // Based on testing, the depth-stencil target is allowed + // to be larger than all color targets, but not smaller + if (rtvExtent.width && dsvExtent.width) { + if (rtvExtent.width > dsvExtent.width + || rtvExtent.height > dsvExtent.height) + return false; + } + + return true; + } + + // Explicitly instantiate here template class D3D11CommonContext; template class D3D11CommonContext; diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index f5e3ac1eb..6827063e8 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -85,6 +85,51 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + void STDMETHODCALLTYPE OMSetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView); + + void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts); + + void STDMETHODCALLTYPE OMSetBlendState( + ID3D11BlendState* pBlendState, + const FLOAT BlendFactor[4], + UINT SampleMask); + + void STDMETHODCALLTYPE OMSetDepthStencilState( + ID3D11DepthStencilState* pDepthStencilState, + UINT StencilRef); + + void STDMETHODCALLTYPE OMGetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView); + + void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews); + + void STDMETHODCALLTYPE OMGetBlendState( + ID3D11BlendState** ppBlendState, + FLOAT BlendFactor[4], + UINT* pSampleMask); + + void STDMETHODCALLTYPE OMGetDepthStencilState( + ID3D11DepthStencilState** ppDepthStencilState, + UINT* pStencilRef); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); protected: @@ -195,6 +240,17 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + bool ValidateRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView); + + private: + + ContextType* GetTypedContext() { + return static_cast(this); + } + }; } diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index c26b4ad3e..a32a1c775 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -321,34 +321,7 @@ namespace dxvk { } } - void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - FlushImplicit(TRUE); - - D3D11DeviceContext::OMSetRenderTargets( - NumViews, ppRenderTargetViews, pDepthStencilView); - } - - - void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts) { - FlushImplicit(TRUE); - D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( - NumRTVs, ppRenderTargetViews, pDepthStencilView, - UAVStartSlot, NumUAVs, ppUnorderedAccessViews, - pUAVInitialCounts); - } - - HRESULT D3D11ImmediateContext::MapBuffer( D3D11Buffer* pResource, D3D11_MAP MapType, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 1a0d3b762..ddc6304c2 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -78,20 +78,6 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); - void STDMETHODCALLTYPE OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - - void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE SwapDeviceContextState( ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState);