From 383cde205100e1e473bdd6b35a859e6812bb6341 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 28 May 2021 17:28:30 +0200 Subject: [PATCH] [d3d11] Allow creation of render target views for planar images --- src/d3d11/d3d11_device.cpp | 11 ++++++++--- src/d3d11/d3d11_view_rtv.cpp | 32 ++++++++++++++++++++++---------- src/d3d11/d3d11_view_rtv.h | 6 +++++- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index fa4aa557..21f0d1b4 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -455,8 +455,10 @@ namespace dxvk { ID3D11RenderTargetView** ppRTView) { InitReturnPtr(ppRTView); + uint32_t plane = GetViewPlaneIndex(pResource, pDesc ? pDesc->Format : DXGI_FORMAT_UNKNOWN); + D3D11_RENDER_TARGET_VIEW_DESC1 desc = pDesc - ? D3D11RenderTargetView::PromoteDesc(pDesc) + ? D3D11RenderTargetView::PromoteDesc(pDesc, plane) : D3D11_RENDER_TARGET_VIEW_DESC1(); ID3D11RenderTargetView1* view = nullptr; @@ -505,12 +507,15 @@ namespace dxvk { return E_INVALIDARG; } - if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_RENDER_TARGET, desc.Format, 0)) { + uint32_t plane = D3D11RenderTargetView::GetPlaneSlice(&desc); + + if (!CheckResourceViewCompatibility(pResource, D3D11_BIND_RENDER_TARGET, desc.Format, plane)) { Logger::err(str::format("D3D11: Cannot create render target view:", "\n Resource type: ", resourceDesc.Dim, "\n Resource usage: ", resourceDesc.BindFlags, "\n Resource format: ", resourceDesc.Format, - "\n View format: ", desc.Format)); + "\n View format: ", desc.Format, + "\n View plane: ", plane)); return E_INVALIDARG; } diff --git a/src/d3d11/d3d11_view_rtv.cpp b/src/d3d11/d3d11_view_rtv.cpp index 0fffe59e..86460502 100644 --- a/src/d3d11/d3d11_view_rtv.cpp +++ b/src/d3d11/d3d11_view_rtv.cpp @@ -14,6 +14,8 @@ namespace dxvk { m_resource(pResource), m_desc(*pDesc), m_d3d10(this) { ResourceAddRefPrivate(m_resource); + auto texture = GetCommonTexture(pResource); + D3D11_COMMON_RESOURCE_DESC resourceDesc; GetCommonResourceDesc(pResource, &resourceDesc); @@ -87,6 +89,9 @@ namespace dxvk { throw DxvkError("D3D11: Invalid view dimension for RTV"); } + if (texture->GetPlaneCount() > 1) + viewInfo.aspect = vk::getPlaneAspect(GetPlaneSlice(pDesc)); + // Normalize view type so that we won't accidentally // bind 2D array views and 2D views at the same time if (viewInfo.numLayers == 1) { @@ -105,8 +110,7 @@ namespace dxvk { m_info.Image.NumLayers = viewInfo.numLayers; // Create the underlying image view object - m_view = pDevice->GetDXVKDevice()->createImageView( - GetCommonTexture(pResource)->GetImage(), viewInfo); + m_view = pDevice->GetDXVKDevice()->createImageView(texture->GetImage(), viewInfo); } @@ -272,7 +276,8 @@ namespace dxvk { D3D11_RENDER_TARGET_VIEW_DESC1 D3D11RenderTargetView::PromoteDesc( - const D3D11_RENDER_TARGET_VIEW_DESC* pDesc) { + const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, + UINT Plane) { D3D11_RENDER_TARGET_VIEW_DESC1 dstDesc; dstDesc.Format = pDesc->Format; dstDesc.ViewDimension = pDesc->ViewDimension; @@ -295,14 +300,14 @@ namespace dxvk { case D3D11_RTV_DIMENSION_TEXTURE2D: dstDesc.Texture2D.MipSlice = pDesc->Texture2D.MipSlice; - dstDesc.Texture2D.PlaneSlice = 0; + dstDesc.Texture2D.PlaneSlice = Plane; break; case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: dstDesc.Texture2DArray.MipSlice = pDesc->Texture2DArray.MipSlice; dstDesc.Texture2DArray.FirstArraySlice = pDesc->Texture2DArray.FirstArraySlice; dstDesc.Texture2DArray.ArraySize = pDesc->Texture2DArray.ArraySize; - dstDesc.Texture2DArray.PlaneSlice = 0; + dstDesc.Texture2DArray.PlaneSlice = Plane; break; case D3D11_RTV_DIMENSION_TEXTURE2DMS: @@ -396,16 +401,11 @@ namespace dxvk { break; case D3D11_RTV_DIMENSION_TEXTURE2D: - if (pDesc->Texture2D.PlaneSlice != 0) - return E_INVALIDARG; break; case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: if (pDesc->Texture2DArray.ArraySize > numLayers - pDesc->Texture2DArray.FirstArraySlice) pDesc->Texture2DArray.ArraySize = numLayers - pDesc->Texture2DArray.FirstArraySlice; - - if (pDesc->Texture2DArray.PlaneSlice != 0) - return E_INVALIDARG; break; case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: @@ -425,4 +425,16 @@ namespace dxvk { return S_OK; } + + UINT D3D11RenderTargetView::GetPlaneSlice(const D3D11_RENDER_TARGET_VIEW_DESC1* pDesc) { + switch (pDesc->ViewDimension) { + case D3D11_RTV_DIMENSION_TEXTURE2D: + return pDesc->Texture2D.PlaneSlice; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + return pDesc->Texture2DArray.PlaneSlice; + default: + return 0; + } + } + } diff --git a/src/d3d11/d3d11_view_rtv.h b/src/d3d11/d3d11_view_rtv.h index 1be76c0b..080146ec 100644 --- a/src/d3d11/d3d11_view_rtv.h +++ b/src/d3d11/d3d11_view_rtv.h @@ -66,12 +66,16 @@ namespace dxvk { D3D11_RENDER_TARGET_VIEW_DESC1* pDesc); static D3D11_RENDER_TARGET_VIEW_DESC1 PromoteDesc( - const D3D11_RENDER_TARGET_VIEW_DESC* pDesc); + const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, + UINT Plane); static HRESULT NormalizeDesc( ID3D11Resource* pResource, D3D11_RENDER_TARGET_VIEW_DESC1* pDesc); + static UINT GetPlaneSlice( + const D3D11_RENDER_TARGET_VIEW_DESC1* pDesc); + private: ID3D11Resource* m_resource;