mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 00:48:44 +01:00
[d3d11] Fix render target validation (again)
This behaviour is rather obscure and undocumented, but testing shows that DSV <-> RTV mismatches are allowed under some circumstances. Fixes #2555.
This commit is contained in:
parent
ce48b57f94
commit
57445227ac
@ -4466,20 +4466,28 @@ namespace dxvk {
|
|||||||
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||||
ID3D11DepthStencilView* pDepthStencilView) {
|
ID3D11DepthStencilView* pDepthStencilView) {
|
||||||
Rc<DxvkImageView> refView;
|
Rc<DxvkImageView> refView;
|
||||||
|
|
||||||
|
VkExtent3D dsvExtent = { 0u, 0u, 0u };
|
||||||
|
VkExtent3D rtvExtent = { 0u, 0u, 0u };
|
||||||
|
|
||||||
if (pDepthStencilView != nullptr) {
|
if (pDepthStencilView != nullptr) {
|
||||||
refView = static_cast<D3D11DepthStencilView*>(
|
refView = static_cast<D3D11DepthStencilView*>(
|
||||||
pDepthStencilView)->GetImageView();
|
pDepthStencilView)->GetImageView();
|
||||||
|
dsvExtent = refView->mipLevelExtent(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < NumViews; i++) {
|
for (uint32_t i = 0; i < NumViews; i++) {
|
||||||
if (ppRenderTargetViews[i] != nullptr) {
|
if (ppRenderTargetViews[i] != nullptr) {
|
||||||
auto curView = static_cast<D3D11RenderTargetView*>(
|
auto curView = static_cast<D3D11RenderTargetView*>(
|
||||||
ppRenderTargetViews[i])->GetImageView();
|
ppRenderTargetViews[i])->GetImageView();
|
||||||
|
|
||||||
|
if (!rtvExtent.width)
|
||||||
|
rtvExtent = curView->mipLevelExtent(0);
|
||||||
|
|
||||||
if (refView != nullptr) {
|
if (refView != nullptr) {
|
||||||
// Render target views must all have the same
|
// Render target views must all have the same sample count,
|
||||||
// size, sample count, layer count, and type
|
// layer count, and type. The size can mismatch under certain
|
||||||
|
// conditions, the D3D11 documentation is wrong here.
|
||||||
if (curView->info().type != refView->info().type
|
if (curView->info().type != refView->info().type
|
||||||
|| curView->info().numLayers != refView->info().numLayers)
|
|| curView->info().numLayers != refView->info().numLayers)
|
||||||
return false;
|
return false;
|
||||||
@ -4488,11 +4496,11 @@ namespace dxvk {
|
|||||||
!= refView->imageInfo().sampleCount)
|
!= refView->imageInfo().sampleCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Color targets must all be the same size
|
||||||
VkExtent3D curExtent = curView->mipLevelExtent(0);
|
VkExtent3D curExtent = curView->mipLevelExtent(0);
|
||||||
VkExtent3D refExtent = refView->mipLevelExtent(0);
|
|
||||||
|
|
||||||
if (curExtent.width != refExtent.width
|
if (curExtent.width != rtvExtent.width
|
||||||
|| curExtent.height != refExtent.height)
|
|| curExtent.height != rtvExtent.height)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Set reference view. All remaining views
|
// Set reference view. All remaining views
|
||||||
@ -4501,7 +4509,15 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user