1
0
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:
Philip Rebohle 2022-07-14 12:39:14 +02:00
parent ce48b57f94
commit 57445227ac
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -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;
} }