From 8208cedfa9c1777e284a9dfe02de225397d89f9b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 26 Aug 2019 14:46:40 +0200 Subject: [PATCH] [d3d11] Add common view info struct to all view types Will be used for hazard detection. --- src/d3d11/d3d11_view.h | 76 ++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_view_dsv.cpp | 19 +++++++++ src/d3d11/d3d11_view_dsv.h | 6 +++ src/d3d11/d3d11_view_rtv.cpp | 13 ++++++ src/d3d11/d3d11_view_rtv.h | 8 +++- src/d3d11/d3d11_view_srv.cpp | 22 +++++++++-- src/d3d11/d3d11_view_srv.h | 6 +++ src/d3d11/d3d11_view_uav.cpp | 22 +++++++++-- src/d3d11/d3d11_view_uav.h | 6 +++ 9 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 src/d3d11/d3d11_view.h diff --git a/src/d3d11/d3d11_view.h b/src/d3d11/d3d11_view.h new file mode 100644 index 000000000..eab73c5a4 --- /dev/null +++ b/src/d3d11/d3d11_view.h @@ -0,0 +1,76 @@ +#pragma once + +#include "d3d11_include.h" + +namespace dxvk { + + /** + * \brief Buffer view info + * + * Stores the byte range covered + * by a buffer view. + */ + struct D3D11_VK_BUFFER_VIEW_INFO { + VkDeviceSize Offset; + VkDeviceSize Length; + }; + + /** + * \brief Image view info + * + * Stores the subresource range + * covered by an image view. + */ + struct D3D11_VK_IMAGE_VIEW_INFO { + VkImageAspectFlags Aspects; + uint32_t MinLevel; + uint32_t MinLayer; + uint32_t NumLevels; + uint32_t NumLayers; + }; + + /** + * \brief Common view info + * + * Stores a pointer to the resource as + * well as the type-specific range that + * is affected by the view. + */ + struct D3D11_VK_VIEW_INFO { + ID3D11Resource* pResource; + D3D11_RESOURCE_DIMENSION Dimension; + UINT BindFlags; + union { + D3D11_VK_BUFFER_VIEW_INFO Buffer; + D3D11_VK_IMAGE_VIEW_INFO Image; + }; + }; + + /** + * \brief Checks whether two views overlap + * + * Overlapping views may conflict in case + * one or both views are used for writing. + * \param [in] a First view to check + * \param [in] b Second view to check + * \returns \c true if the views overlap + */ + inline bool CheckViewOverlap(const D3D11_VK_VIEW_INFO& a, const D3D11_VK_VIEW_INFO b) { + if (likely(a.pResource != b.pResource)) + return false; + + if (a.Dimension == D3D11_RESOURCE_DIMENSION_BUFFER) { + // Just check whether the buffer ranges overlap + return (a.Buffer.Offset < b.Buffer.Offset + b.Buffer.Length) + && (a.Buffer.Offset + a.Buffer.Length > b.Buffer.Offset); + } else { + // Check whether the subresource ranges overlap + return (a.Image.Aspects & b.Image.Aspects) + && (a.Image.MinLevel < b.Image.MinLevel + b.Image.NumLevels) + && (a.Image.MinLayer < b.Image.MinLayer + b.Image.NumLayers) + && (a.Image.MinLevel + a.Image.NumLevels > b.Image.MinLevel) + && (a.Image.MinLayer + a.Image.NumLayers > b.Image.MinLayer); + } + } + +} \ No newline at end of file diff --git a/src/d3d11/d3d11_view_dsv.cpp b/src/d3d11/d3d11_view_dsv.cpp index 9c79e0a76..9babf5b5c 100644 --- a/src/d3d11/d3d11_view_dsv.cpp +++ b/src/d3d11/d3d11_view_dsv.cpp @@ -13,6 +13,9 @@ namespace dxvk { : m_device(pDevice), m_resource(pResource), m_desc(*pDesc), m_d3d10(this) { ResourceAddRefPrivate(m_resource); + D3D11_COMMON_RESOURCE_DESC resourceDesc; + GetCommonResourceDesc(pResource, &resourceDesc); + DxvkImageViewCreateInfo viewInfo; viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_DEPTH).Format; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; @@ -78,6 +81,22 @@ namespace dxvk { if (viewInfo.type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; } + // Populate view info struct + m_info.pResource = pResource; + m_info.Dimension = resourceDesc.Dim; + m_info.BindFlags = resourceDesc.BindFlags; + m_info.Image.Aspects = viewInfo.aspect; + m_info.Image.MinLevel = viewInfo.minLevel; + m_info.Image.MinLayer = viewInfo.minLayer; + m_info.Image.NumLevels = viewInfo.numLevels; + m_info.Image.NumLayers = viewInfo.numLayers; + + if (m_desc.Flags & D3D11_DSV_READ_ONLY_DEPTH) + m_info.Image.Aspects &= ~VK_IMAGE_ASPECT_DEPTH_BIT; + + if (m_desc.Flags & D3D11_DSV_READ_ONLY_STENCIL) + m_info.Image.Aspects &= ~VK_IMAGE_ASPECT_STENCIL_BIT; + // Create the underlying image view object m_view = pDevice->GetDXVKDevice()->createImageView( GetCommonTexture(pResource)->GetImage(), viewInfo); diff --git a/src/d3d11/d3d11_view_dsv.h b/src/d3d11/d3d11_view_dsv.h index d0e57f69c..537a6e4e6 100644 --- a/src/d3d11/d3d11_view_dsv.h +++ b/src/d3d11/d3d11_view_dsv.h @@ -5,6 +5,7 @@ #include "../d3d10/d3d10_view_dsv.h" #include "d3d11_device_child.h" +#include "d3d11_view.h" namespace dxvk { @@ -36,6 +37,10 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc(D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc) final; + const D3D11_VK_VIEW_INFO& GetViewInfo() const { + return m_info; + } + D3D11_RESOURCE_DIMENSION GetResourceType() const { D3D11_RESOURCE_DIMENSION type; m_resource->GetType(&type); @@ -87,6 +92,7 @@ namespace dxvk { Com m_device; ID3D11Resource* m_resource; D3D11_DEPTH_STENCIL_VIEW_DESC m_desc; + D3D11_VK_VIEW_INFO m_info; Rc m_view; D3D10DepthStencilView m_d3d10; diff --git a/src/d3d11/d3d11_view_rtv.cpp b/src/d3d11/d3d11_view_rtv.cpp index c182117b9..2bcbfd39a 100644 --- a/src/d3d11/d3d11_view_rtv.cpp +++ b/src/d3d11/d3d11_view_rtv.cpp @@ -13,6 +13,9 @@ namespace dxvk { : m_device(pDevice), m_resource(pResource), m_desc(*pDesc), m_d3d10(this) { ResourceAddRefPrivate(m_resource); + D3D11_COMMON_RESOURCE_DESC resourceDesc; + GetCommonResourceDesc(pResource, &resourceDesc); + DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( pDesc->Format, DXGI_VK_FORMAT_MODE_COLOR); @@ -89,6 +92,16 @@ namespace dxvk { if (viewInfo.type == VK_IMAGE_VIEW_TYPE_1D_ARRAY) viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; if (viewInfo.type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; } + + // Populate view info struct + m_info.pResource = pResource; + m_info.Dimension = resourceDesc.Dim; + m_info.BindFlags = resourceDesc.BindFlags; + m_info.Image.Aspects = viewInfo.aspect; + m_info.Image.MinLevel = viewInfo.minLevel; + m_info.Image.MinLayer = viewInfo.minLayer; + m_info.Image.NumLevels = viewInfo.numLevels; + m_info.Image.NumLayers = viewInfo.numLayers; // Create the underlying image view object m_view = pDevice->GetDXVKDevice()->createImageView( diff --git a/src/d3d11/d3d11_view_rtv.h b/src/d3d11/d3d11_view_rtv.h index d75483c3c..dd589993e 100644 --- a/src/d3d11/d3d11_view_rtv.h +++ b/src/d3d11/d3d11_view_rtv.h @@ -5,6 +5,7 @@ #include "../d3d10/d3d10_view_rtv.h" #include "d3d11_device_child.h" +#include "d3d11_view.h" namespace dxvk { @@ -32,6 +33,10 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc(D3D11_RENDER_TARGET_VIEW_DESC* pDesc) final; + const D3D11_VK_VIEW_INFO& GetViewInfo() const { + return m_info; + } + D3D11_RESOURCE_DIMENSION GetResourceType() const { D3D11_RESOURCE_DIMENSION type; m_resource->GetType(&type); @@ -51,7 +56,7 @@ namespace dxvk { D3D10RenderTargetView* GetD3D10Iface() { return &m_d3d10; } - + static HRESULT GetDescFromResource( ID3D11Resource* pResource, D3D11_RENDER_TARGET_VIEW_DESC* pDesc); @@ -65,6 +70,7 @@ namespace dxvk { Com m_device; ID3D11Resource* m_resource; D3D11_RENDER_TARGET_VIEW_DESC m_desc; + D3D11_VK_VIEW_INFO m_info; Rc m_view; D3D10RenderTargetView m_d3d10; diff --git a/src/d3d11/d3d11_view_srv.cpp b/src/d3d11/d3d11_view_srv.cpp index dd673bd31..5d6875c83 100644 --- a/src/d3d11/d3d11_view_srv.cpp +++ b/src/d3d11/d3d11_view_srv.cpp @@ -13,10 +13,15 @@ namespace dxvk { : m_device(pDevice), m_resource(pResource), m_desc(*pDesc), m_d3d10(this) { ResourceAddRefPrivate(m_resource); - D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - pResource->GetType(&resourceDim); + D3D11_COMMON_RESOURCE_DESC resourceDesc; + GetCommonResourceDesc(pResource, &resourceDesc); - if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + // Basic view resource info + m_info.pResource = pResource; + m_info.Dimension = resourceDesc.Dim; + m_info.BindFlags = resourceDesc.BindFlags; + + if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) { auto buffer = static_cast(pResource); // Move buffer description to a common struct to @@ -57,6 +62,10 @@ namespace dxvk { viewInfo.rangeLength = formatInfo->elementSize * bufInfo.NumElements; } + // Populate view info struct + m_info.Buffer.Offset = viewInfo.rangeOffset; + m_info.Buffer.Length = viewInfo.rangeLength; + // Create underlying buffer view object m_bufferView = pDevice->GetDXVKDevice()->createBufferView( buffer->GetBuffer(), viewInfo); @@ -154,6 +163,13 @@ namespace dxvk { throw DxvkError("D3D11: Invalid view dimension for image SRV"); } + // Populate view info struct + m_info.Image.Aspects = viewInfo.aspect; + m_info.Image.MinLevel = viewInfo.minLevel; + m_info.Image.MinLayer = viewInfo.minLayer; + m_info.Image.NumLevels = viewInfo.numLevels; + m_info.Image.NumLayers = viewInfo.numLayers; + // Create the underlying image view object m_imageView = pDevice->GetDXVKDevice()->createImageView( GetCommonTexture(pResource)->GetImage(), viewInfo); diff --git a/src/d3d11/d3d11_view_srv.h b/src/d3d11/d3d11_view_srv.h index 37d6f76dd..58ec8d368 100644 --- a/src/d3d11/d3d11_view_srv.h +++ b/src/d3d11/d3d11_view_srv.h @@ -5,6 +5,7 @@ #include "../d3d10/d3d10_view_srv.h" #include "d3d11_device_child.h" +#include "d3d11_view.h" namespace dxvk { @@ -32,6 +33,10 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc(D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc) final; + const D3D11_VK_VIEW_INFO& GetViewInfo() const { + return m_info; + } + D3D11_RESOURCE_DIMENSION GetResourceType() const { D3D11_RESOURCE_DIMENSION type; m_resource->GetType(&type); @@ -69,6 +74,7 @@ namespace dxvk { Com m_device; ID3D11Resource* m_resource; D3D11_SHADER_RESOURCE_VIEW_DESC m_desc; + D3D11_VK_VIEW_INFO m_info; Rc m_bufferView; Rc m_imageView; D3D10ShaderResourceView m_d3d10; diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index d6dc8ecd8..be5343695 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -13,10 +13,15 @@ namespace dxvk { : m_device(pDevice), m_resource(pResource), m_desc(*pDesc) { ResourceAddRefPrivate(m_resource); - D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - pResource->GetType(&resourceDim); + D3D11_COMMON_RESOURCE_DESC resourceDesc; + GetCommonResourceDesc(pResource, &resourceDesc); - if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + // Basic view resource info + m_info.pResource = pResource; + m_info.Dimension = resourceDesc.Dim; + m_info.BindFlags = resourceDesc.BindFlags; + + if (resourceDesc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) { auto buffer = static_cast(pResource); DxvkBufferViewCreateInfo viewInfo; @@ -40,6 +45,10 @@ namespace dxvk { if (pDesc->Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)) m_counterSlice = pDevice->AllocUavCounterSlice(); + // Populate view info struct + m_info.Buffer.Offset = viewInfo.rangeOffset; + m_info.Buffer.Length = viewInfo.rangeLength; + m_bufferView = pDevice->GetDXVKDevice()->createBufferView( buffer->GetBuffer(), viewInfo); } else { @@ -99,6 +108,13 @@ namespace dxvk { throw DxvkError("D3D11: Invalid view dimension for image UAV"); } + // Populate view info struct + m_info.Image.Aspects = viewInfo.aspect; + m_info.Image.MinLevel = viewInfo.minLevel; + m_info.Image.MinLayer = viewInfo.minLayer; + m_info.Image.NumLevels = viewInfo.numLevels; + m_info.Image.NumLayers = viewInfo.numLayers; + m_imageView = pDevice->GetDXVKDevice()->createImageView( GetCommonTexture(pResource)->GetImage(), viewInfo); } diff --git a/src/d3d11/d3d11_view_uav.h b/src/d3d11/d3d11_view_uav.h index bc133d09f..5c7967f73 100644 --- a/src/d3d11/d3d11_view_uav.h +++ b/src/d3d11/d3d11_view_uav.h @@ -3,6 +3,7 @@ #include "../dxvk/dxvk_device.h" #include "d3d11_device_child.h" +#include "d3d11_view.h" namespace dxvk { @@ -34,6 +35,10 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc(D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) final; + const D3D11_VK_VIEW_INFO& GetViewInfo() const { + return m_info; + } + D3D11_RESOURCE_DIMENSION GetResourceType() const { D3D11_RESOURCE_DIMENSION type; m_resource->GetType(&type); @@ -65,6 +70,7 @@ namespace dxvk { Com m_device; ID3D11Resource* m_resource; D3D11_UNORDERED_ACCESS_VIEW_DESC m_desc; + D3D11_VK_VIEW_INFO m_info; Rc m_bufferView; Rc m_imageView; DxvkBufferSlice m_counterSlice;