From 56a1433d3f15bee4bd6daaff6d60d742b5048566 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Apr 2018 23:25:40 +0200 Subject: [PATCH] [d3d11] ClearUnorderedAccessViewUInt: Create temp view if necessary If this method is used to clear a view with a floating point format, we need to create a compatible view with an integer format in order to clear the resource with the correct value. Fixes some calls to this function in Rise of the Tomb Raider and other games. --- src/d3d11/d3d11_context.cpp | 42 +++++++++++++++++++++++++++++++------ src/dxvk/dxvk_buffer.h | 8 +++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index f2c82f24..4e901b1d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -531,6 +531,21 @@ namespace dxvk { if (uav == nullptr) return; + // Gather UAV format info. We'll use this to determine + // whether we need to create a temporary view or not. + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uav->GetDesc(&uavDesc); + + VkFormat uavFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_ANY).Format; + VkFormat rawFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_RAW).Format; + + // FIXME support packed formats + if (uavFormat != rawFormat && rawFormat == VK_FORMAT_UNDEFINED) { + Logger::err(str::format("D3D11: No raw format found for ", uavFormat)); + return; + } + + // Set up clear color struct VkClearColorValue clearValue; clearValue.uint32[0] = Values[0]; clearValue.uint32[1] = Values[1]; @@ -538,7 +553,10 @@ namespace dxvk { clearValue.uint32[3] = Values[3]; if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - const Rc bufferView = uav->GetBufferView(); + // In case of raw and structured buffers as well as typed + // buffers that can be used for atomic operations, we can + // use the fast Vulkan buffer clear function. + Rc bufferView = uav->GetBufferView(); if (bufferView->info().format == VK_FORMAT_R32_UINT || bufferView->info().format == VK_FORMAT_R32_SINT @@ -554,9 +572,14 @@ namespace dxvk { cClearValue); }); } else { - // FIXME Create integer-typed view if the - // buffer view has a floating point format - Rc bufferView = uav->GetBufferView(); + // Create a view with an integer format if necessary + if (uavFormat != rawFormat) { + DxvkBufferViewCreateInfo info = bufferView->info(); + info.format = rawFormat; + + bufferView = m_device->createBufferView( + bufferView->buffer(), info); + } EmitCs([ cClearValue = clearValue, @@ -569,10 +592,17 @@ namespace dxvk { }); } } else { - // FIXME Create integer-typed view if the - // image view has a floating point format + // Create a view with an integer format if necessary Rc imageView = uav->GetImageView(); + if (uavFormat != rawFormat) { + DxvkImageViewCreateInfo info = imageView->info(); + info.format = rawFormat; + + imageView = m_device->createImageView( + imageView->image(), info); + } + EmitCs([ cClearValue = clearValue, cDstView = imageView diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 3a15443e..66b18739 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -326,6 +326,14 @@ namespace dxvk { * \brief Underlying buffer object * \returns Underlying buffer object */ + Rc buffer() const { + return m_buffer; + } + + /** + * \brief Underlying buffer info + * \returns Underlying buffer info + */ const DxvkBufferCreateInfo& bufferInfo() const { return m_buffer->info(); }