From 871c96b13056f472c394378f2d9b5dc43f30cd5d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 5 Aug 2018 19:28:39 +0200 Subject: [PATCH] [d3d11] Refactor Unordered Access View Creation Part 4 / 4 of the refactor. --- src/d3d11/d3d11_device.cpp | 142 +++-------------------------------- src/d3d11/d3d11_view_uav.cpp | 113 +++++++++++++++++++++++----- src/d3d11/d3d11_view_uav.h | 15 +--- 3 files changed, 107 insertions(+), 163 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 299d0c43..3abf50dc 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -345,139 +345,17 @@ namespace dxvk { Logger::err(str::format("D3D11: Incompatible UAV format: ", desc.Format)); return E_INVALIDARG; } + + // Create the view if requested + if (ppUAView == nullptr) + return S_FALSE; - if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { - auto resource = static_cast(pResource); - - D3D11_BUFFER_DESC resourceDesc; - resource->GetDesc(&resourceDesc); - - DxvkBufferViewCreateInfo viewInfo; - - if (desc.Buffer.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW) { - viewInfo.format = VK_FORMAT_R32_UINT; - viewInfo.rangeOffset = sizeof(uint32_t) * desc.Buffer.FirstElement; - viewInfo.rangeLength = sizeof(uint32_t) * desc.Buffer.NumElements; - } else if (desc.Format == DXGI_FORMAT_UNKNOWN) { - viewInfo.format = VK_FORMAT_R32_UINT; - viewInfo.rangeOffset = resourceDesc.StructureByteStride * desc.Buffer.FirstElement; - viewInfo.rangeLength = resourceDesc.StructureByteStride * desc.Buffer.NumElements; - } else { - // Typed buffer view - must use an uncompressed color format - viewInfo.format = m_dxgiAdapter->LookupFormat( - desc.Format, DXGI_VK_FORMAT_MODE_COLOR).Format; - - const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); - viewInfo.rangeOffset = formatInfo->elementSize * desc.Buffer.FirstElement; - viewInfo.rangeLength = formatInfo->elementSize * desc.Buffer.NumElements; - - if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) { - Logger::err("D3D11Device: Compressed formats for buffer views not supported"); - return E_INVALIDARG; - } - } - - if (ppUAView == nullptr) - return S_FALSE; - - try { - // Fetch a buffer slice for atomic - // append/consume functionality. - DxvkBufferSlice counterSlice; - - if (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)) - counterSlice = AllocCounterSlice(); - - *ppUAView = ref(new D3D11UnorderedAccessView( - this, pResource, desc, - m_dxvkDevice->createBufferView( - resource->GetBufferSlice().buffer(), viewInfo), - counterSlice)); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_FAIL; - } - } else { - const D3D11CommonTexture* textureInfo = GetCommonTexture(pResource); - - // Fill in the view info. The view type depends solely - // on the view dimension field in the view description, - // not on the resource type. - const DXGI_VK_FORMAT_INFO formatInfo = m_dxgiAdapter - ->LookupFormat(desc.Format, textureInfo->GetFormatMode()); - - DxvkImageViewCreateInfo viewInfo; - viewInfo.format = formatInfo.Format; - viewInfo.aspect = formatInfo.Aspect; - viewInfo.swizzle = formatInfo.Swizzle; - viewInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT; - - switch (desc.ViewDimension) { - case D3D11_UAV_DIMENSION_TEXTURE1D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; - viewInfo.minLevel = desc.Texture1D.MipSlice; - viewInfo.numLevels = 1; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; - viewInfo.minLevel = desc.Texture1DArray.MipSlice; - viewInfo.numLevels = 1; - viewInfo.minLayer = desc.Texture1DArray.FirstArraySlice; - viewInfo.numLayers = desc.Texture1DArray.ArraySize; - break; - - case D3D11_UAV_DIMENSION_TEXTURE2D: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.minLevel = desc.Texture2D.MipSlice; - viewInfo.numLevels = 1; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - viewInfo.minLevel = desc.Texture2DArray.MipSlice; - viewInfo.numLevels = 1; - viewInfo.minLayer = desc.Texture2DArray.FirstArraySlice; - viewInfo.numLayers = desc.Texture2DArray.ArraySize; - break; - - case D3D11_UAV_DIMENSION_TEXTURE3D: - // FIXME we actually have to map this to a - // 2D array view in order to support W slices - viewInfo.type = VK_IMAGE_VIEW_TYPE_3D; - viewInfo.minLevel = desc.Texture3D.MipSlice; - viewInfo.numLevels = 1; - viewInfo.minLayer = 0; - viewInfo.numLayers = 1; - break; - - default: - Logger::err(str::format( - "D3D11: View dimension not supported for UAV: ", - desc.ViewDimension)); - return E_INVALIDARG; - } - - if (ppUAView == nullptr) - return S_FALSE; - - try { - *ppUAView = ref(new D3D11UnorderedAccessView( - this, pResource, desc, - m_dxvkDevice->createImageView( - textureInfo->GetImage(), - viewInfo), - DxvkBufferSlice())); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_FAIL; - } + try { + *ppUAView = ref(new D3D11UnorderedAccessView(this, pResource, &desc)); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; } } diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index ddfe0ca3..8f8da66d 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -6,25 +6,100 @@ namespace dxvk { D3D11UnorderedAccessView::D3D11UnorderedAccessView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc, - const Rc& bufferView, - const DxvkBufferSlice& counterSlice) - : m_device(device), m_resource(resource), - m_desc(desc), m_bufferView(bufferView), - m_counterSlice(counterSlice) { } - - - D3D11UnorderedAccessView::D3D11UnorderedAccessView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc, - const Rc& imageView, - const DxvkBufferSlice& counterSlice) - : m_device(device), m_resource(resource), - m_desc(desc), m_imageView(imageView), - m_counterSlice(counterSlice) { } + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc) + : m_device(pDevice), m_resource(pResource), m_desc(*pDesc) { + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&resourceDim); + + if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + auto buffer = static_cast(pResource); + + DxvkBufferViewCreateInfo viewInfo; + + if (pDesc->Buffer.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW) { + viewInfo.format = VK_FORMAT_R32_UINT; + viewInfo.rangeOffset = sizeof(uint32_t) * pDesc->Buffer.FirstElement; + viewInfo.rangeLength = sizeof(uint32_t) * pDesc->Buffer.NumElements; + } else if (pDesc->Format == DXGI_FORMAT_UNKNOWN) { + viewInfo.format = VK_FORMAT_R32_UINT; + viewInfo.rangeOffset = buffer->Desc()->StructureByteStride * pDesc->Buffer.FirstElement; + viewInfo.rangeLength = buffer->Desc()->StructureByteStride * pDesc->Buffer.NumElements; + } else { + viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_COLOR).Format; + + const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); + viewInfo.rangeOffset = formatInfo->elementSize * pDesc->Buffer.FirstElement; + viewInfo.rangeLength = formatInfo->elementSize * pDesc->Buffer.NumElements; + } + + if (pDesc->Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)) + m_counterSlice = pDevice->AllocCounterSlice(); + + m_bufferView = pDevice->GetDXVKDevice()->createBufferView( + buffer->GetBuffer(), viewInfo); + } else { + const DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( + pDesc->Format, GetCommonTexture(pResource)->GetFormatMode()); + + DxvkImageViewCreateInfo viewInfo; + viewInfo.format = formatInfo.Format; + viewInfo.aspect = formatInfo.Aspect; + viewInfo.swizzle = formatInfo.Swizzle; + viewInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT; + + switch (pDesc->ViewDimension) { + case D3D11_UAV_DIMENSION_TEXTURE1D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; + viewInfo.minLevel = pDesc->Texture1D.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + viewInfo.minLevel = pDesc->Texture1DArray.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = pDesc->Texture1DArray.FirstArraySlice; + viewInfo.numLayers = pDesc->Texture1DArray.ArraySize; + break; + + case D3D11_UAV_DIMENSION_TEXTURE2D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.minLevel = pDesc->Texture2D.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.minLevel = pDesc->Texture2DArray.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = pDesc->Texture2DArray.FirstArraySlice; + viewInfo.numLayers = pDesc->Texture2DArray.ArraySize; + break; + + case D3D11_UAV_DIMENSION_TEXTURE3D: + // FIXME we actually have to map this to a + // 2D array view in order to support W slices + viewInfo.type = VK_IMAGE_VIEW_TYPE_3D; + viewInfo.minLevel = pDesc->Texture3D.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + default: + throw DxvkError("D3D11: Invalid view dimension for image UAV"); + } + + m_imageView = pDevice->GetDXVKDevice()->createImageView( + GetCommonTexture(pResource)->GetImage(), viewInfo); + } + } D3D11UnorderedAccessView::~D3D11UnorderedAccessView() { diff --git a/src/d3d11/d3d11_view_uav.h b/src/d3d11/d3d11_view_uav.h index 8ef7bcf6..2facb8ac 100644 --- a/src/d3d11/d3d11_view_uav.h +++ b/src/d3d11/d3d11_view_uav.h @@ -20,18 +20,9 @@ namespace dxvk { public: D3D11UnorderedAccessView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc, - const Rc& bufferView, - const DxvkBufferSlice& counterSlice); - - D3D11UnorderedAccessView( - D3D11Device* device, - ID3D11Resource* resource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC& desc, - const Rc& imageView, - const DxvkBufferSlice& counterSlice); + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc); ~D3D11UnorderedAccessView();