mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +01:00
[d3d11] Validate render targets before setting them up
Mimicks what native D3D11 does. Fixes validation errors in Nier:Automata with multisampling enabled in some situations.
This commit is contained in:
parent
fb288d8713
commit
a55bee9554
@ -2109,13 +2109,15 @@ namespace dxvk {
|
|||||||
UINT NumViews,
|
UINT NumViews,
|
||||||
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||||
ID3D11DepthStencilView* pDepthStencilView) {
|
ID3D11DepthStencilView* pDepthStencilView) {
|
||||||
|
// Native D3D11 does not change the render targets if
|
||||||
|
// the parameters passed to this method are invalid.
|
||||||
|
if (!ValidateRenderTargets(NumViews, ppRenderTargetViews, pDepthStencilView))
|
||||||
|
return;
|
||||||
|
|
||||||
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
||||||
D3D11RenderTargetView* view = nullptr;
|
m_state.om.renderTargetViews.at(i) = i < NumViews
|
||||||
|
? static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i])
|
||||||
if ((i < NumViews) && (ppRenderTargetViews[i] != nullptr))
|
: nullptr;
|
||||||
view = static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i]);
|
|
||||||
|
|
||||||
m_state.om.renderTargetViews.at(i) = view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state.om.depthStencilView = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
m_state.om.depthStencilView = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
||||||
@ -2966,6 +2968,48 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool D3D11DeviceContext::ValidateRenderTargets(
|
||||||
|
UINT NumViews,
|
||||||
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||||
|
ID3D11DepthStencilView* pDepthStencilView) {
|
||||||
|
Rc<DxvkImageView> refView;
|
||||||
|
|
||||||
|
if (pDepthStencilView != nullptr) {
|
||||||
|
refView = static_cast<D3D11DepthStencilView*>(
|
||||||
|
pDepthStencilView)->GetImageView();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < NumViews; i++) {
|
||||||
|
if (ppRenderTargetViews[i] != nullptr) {
|
||||||
|
auto curView = static_cast<D3D11RenderTargetView*>(
|
||||||
|
ppRenderTargetViews[i])->GetImageView();
|
||||||
|
|
||||||
|
if (refView != nullptr) {
|
||||||
|
// Render target views must all have the same
|
||||||
|
// size, sample count, layer count, and type
|
||||||
|
if (curView->info().type != refView->info().type
|
||||||
|
|| curView->info().numLayers != refView->info().numLayers)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (curView->imageInfo().sampleCount
|
||||||
|
!= refView->imageInfo().sampleCount)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (curView->mipLevelExtent(0)
|
||||||
|
!= refView->mipLevelExtent(0))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// Set reference view. All remaining views
|
||||||
|
// must be compatible to the reference view.
|
||||||
|
refView = curView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkDataSlice D3D11DeviceContext::AllocUpdateBufferSlice(size_t Size) {
|
DxvkDataSlice D3D11DeviceContext::AllocUpdateBufferSlice(size_t Size) {
|
||||||
constexpr size_t UpdateBufferSize = 4 * 1024 * 1024;
|
constexpr size_t UpdateBufferSize = 4 * 1024 * 1024;
|
||||||
|
|
||||||
|
@ -775,6 +775,11 @@ namespace dxvk {
|
|||||||
DxbcProgramType Stage,
|
DxbcProgramType Stage,
|
||||||
D3D11UnorderedAccessBindings& Bindings);
|
D3D11UnorderedAccessBindings& Bindings);
|
||||||
|
|
||||||
|
bool ValidateRenderTargets(
|
||||||
|
UINT NumViews,
|
||||||
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||||
|
ID3D11DepthStencilView* pDepthStencilView);
|
||||||
|
|
||||||
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
|
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
|
||||||
|
|
||||||
template<typename Cmd>
|
template<typename Cmd>
|
||||||
|
Loading…
Reference in New Issue
Block a user