From 8508994a63222955e8196b3751dc6ae7c6a8a911 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Apr 2018 23:42:11 +0200 Subject: [PATCH] [d3d11] Cap mip level count for textures and views Some games do not compute the number of mip levels of a texture or texture view correctly, so we should work around this by capping it to the highest possible value. --- src/d3d11/d3d11_texture.cpp | 11 ++++++----- src/d3d11/d3d11_view_dsv.cpp | 6 +++--- src/d3d11/d3d11_view_rtv.cpp | 8 ++++---- src/d3d11/d3d11_view_srv.cpp | 22 +++++++++++----------- src/d3d11/d3d11_view_uav.cpp | 6 +++--- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index e2195c39..b65fb05d 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -154,11 +154,12 @@ namespace dxvk { HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc) { - if (pDesc->MipLevels == 0) { - pDesc->MipLevels = pDesc->SampleDesc.Count <= 1 - ? util::computeMipLevelCount({ pDesc->Width, pDesc->Height, pDesc->Depth }) - : 1u; - } + uint32_t maxMipLevelCount = pDesc->SampleDesc.Count <= 1 + ? util::computeMipLevelCount({ pDesc->Width, pDesc->Height, pDesc->Depth }) + : 1u; + + if (pDesc->MipLevels == 0 || pDesc->MipLevels > maxMipLevelCount) + pDesc->MipLevels = maxMipLevelCount; return S_OK; } diff --git a/src/d3d11/d3d11_view_dsv.cpp b/src/d3d11/d3d11_view_dsv.cpp index 463b491e..de2847ae 100644 --- a/src/d3d11/d3d11_view_dsv.cpp +++ b/src/d3d11/d3d11_view_dsv.cpp @@ -160,17 +160,17 @@ namespace dxvk { switch (pDesc->ViewDimension) { case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: - if (pDesc->Texture1DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture1DArray.ArraySize > numLayers - pDesc->Texture1DArray.FirstArraySlice) pDesc->Texture1DArray.ArraySize = numLayers - pDesc->Texture1DArray.FirstArraySlice; break; case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - if (pDesc->Texture2DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DArray.ArraySize > numLayers - pDesc->Texture2DArray.FirstArraySlice) pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; break; case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - if (pDesc->Texture2DMSArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DMSArray.ArraySize > numLayers - pDesc->Texture2DMSArray.FirstArraySlice) pDesc->Texture2DMSArray.ArraySize = numLayers - pDesc->Texture2DMSArray.FirstArraySlice; break; diff --git a/src/d3d11/d3d11_view_rtv.cpp b/src/d3d11/d3d11_view_rtv.cpp index db343c38..0a8e1985 100644 --- a/src/d3d11/d3d11_view_rtv.cpp +++ b/src/d3d11/d3d11_view_rtv.cpp @@ -191,22 +191,22 @@ namespace dxvk { switch (pDesc->ViewDimension) { case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: - if (pDesc->Texture1DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture1DArray.ArraySize > numLayers - pDesc->Texture1DArray.FirstArraySlice) pDesc->Texture1DArray.ArraySize = numLayers - pDesc->Texture1DArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - if (pDesc->Texture2DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DArray.ArraySize > numLayers - pDesc->Texture2DArray.FirstArraySlice) pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - if (pDesc->Texture2DMSArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DMSArray.ArraySize > numLayers - pDesc->Texture2DMSArray.FirstArraySlice) pDesc->Texture2DMSArray.ArraySize = numLayers - pDesc->Texture2DMSArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE3D: - if (pDesc->Texture3D.WSize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture3D.WSize > numLayers - pDesc->Texture3D.FirstWSlice) pDesc->Texture3D.WSize = numLayers - pDesc->Texture3D.FirstWSlice; break; diff --git a/src/d3d11/d3d11_view_srv.cpp b/src/d3d11/d3d11_view_srv.cpp index c6be3f18..1c51024d 100644 --- a/src/d3d11/d3d11_view_srv.cpp +++ b/src/d3d11/d3d11_view_srv.cpp @@ -223,48 +223,48 @@ namespace dxvk { switch (pDesc->ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE1D: - if (pDesc->Texture1D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->Texture1D.MipLevels > mipLevels - pDesc->Texture1D.MostDetailedMip) pDesc->Texture1D.MipLevels = mipLevels - pDesc->Texture1D.MostDetailedMip; break; case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - if (pDesc->Texture1DArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->Texture1DArray.MipLevels > mipLevels - pDesc->Texture1DArray.MostDetailedMip) pDesc->Texture1DArray.MipLevels = mipLevels - pDesc->Texture1DArray.MostDetailedMip; - if (pDesc->Texture1DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture1DArray.ArraySize > numLayers - pDesc->Texture1DArray.FirstArraySlice) pDesc->Texture1DArray.ArraySize = numLayers - pDesc->Texture1DArray.FirstArraySlice; break; case D3D11_SRV_DIMENSION_TEXTURE2D: - if (pDesc->Texture2D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->Texture2D.MipLevels > mipLevels - pDesc->Texture2D.MostDetailedMip) pDesc->Texture2D.MipLevels = mipLevels - pDesc->Texture2D.MostDetailedMip; break; case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - if (pDesc->Texture2DArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->Texture2DArray.MipLevels > mipLevels - pDesc->Texture2DArray.MostDetailedMip) pDesc->Texture2DArray.MipLevels = mipLevels - pDesc->Texture2DArray.MostDetailedMip; - if (pDesc->Texture2DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DArray.ArraySize > numLayers - pDesc->Texture2DArray.FirstArraySlice) pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; break; case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - if (pDesc->Texture2DMSArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DMSArray.ArraySize > numLayers - pDesc->Texture2DMSArray.FirstArraySlice) pDesc->Texture2DMSArray.ArraySize = numLayers - pDesc->Texture2DMSArray.FirstArraySlice; break; case D3D11_SRV_DIMENSION_TEXTURECUBE: - if (pDesc->TextureCube.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->TextureCube.MipLevels > mipLevels - pDesc->TextureCube.MostDetailedMip) pDesc->TextureCube.MipLevels = mipLevels - pDesc->TextureCube.MostDetailedMip; break; case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: - if (pDesc->TextureCubeArray.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->TextureCubeArray.MipLevels > mipLevels - pDesc->TextureCubeArray.MostDetailedMip) pDesc->TextureCubeArray.MipLevels = mipLevels - pDesc->TextureCubeArray.MostDetailedMip; - if (pDesc->TextureCubeArray.NumCubes == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->TextureCubeArray.NumCubes > (numLayers - pDesc->TextureCubeArray.First2DArrayFace / 6)) pDesc->TextureCubeArray.NumCubes = (numLayers - pDesc->TextureCubeArray.First2DArrayFace / 6); break; case D3D11_SRV_DIMENSION_TEXTURE3D: - if (pDesc->Texture3D.MipLevels == D3D11_DXVK_USE_REMAINING_LEVELS) + if (pDesc->Texture3D.MipLevels > mipLevels - pDesc->Texture3D.MostDetailedMip) pDesc->Texture3D.MipLevels = mipLevels - pDesc->Texture3D.MostDetailedMip; break; diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index e60d555d..ddfe0ca3 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -204,17 +204,17 @@ namespace dxvk { switch (pDesc->ViewDimension) { case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: - if (pDesc->Texture1DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture1DArray.ArraySize > numLayers - pDesc->Texture1DArray.FirstArraySlice) pDesc->Texture1DArray.ArraySize = numLayers - pDesc->Texture1DArray.FirstArraySlice; break; case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: - if (pDesc->Texture2DArray.ArraySize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture2DArray.ArraySize > numLayers - pDesc->Texture2DArray.FirstArraySlice) pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; break; case D3D11_UAV_DIMENSION_TEXTURE3D: - if (pDesc->Texture3D.WSize == D3D11_DXVK_USE_REMAINING_LAYERS) + if (pDesc->Texture3D.WSize > numLayers - pDesc->Texture3D.FirstWSlice) pDesc->Texture3D.WSize = numLayers - pDesc->Texture3D.FirstWSlice; break;