[PATCH vkd3d 10/13] vkd3d: Re-implement ClearUnorderedAccessViewUint.

Philip Rebohle philip.rebohle at tu-dortmund.de
Mon Nov 11 10:03:45 CST 2019


Addresses the following limitations of the previous implementation:
- Only R32_{UINT,TYPELESS} were supported for buffers.
- Clearing an image UAV did not behave correctly for images with non-UINT formats.
- Due to the use of transfer operations, extra memory barriers were needed.

If necessary, this will create a temporary view with a bit-compatible
UINT format for the resource in order to perform a bit-exact clear.

Signed-off-by: Philip Rebohle <philip.rebohle at tu-dortmund.de>
---
 libs/vkd3d/command.c | 113 ++++++++++++++++---------------------------
 1 file changed, 41 insertions(+), 72 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 3648ea4..e5fe0ad 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -4930,96 +4930,65 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
         const UINT values[4], UINT rect_count, const D3D12_RECT *rects)
 {
     struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList1(iface);
-    const struct vkd3d_vk_device_procs *vk_procs;
-    const struct vkd3d_vulkan_info *vk_info;
-    const struct d3d12_desc *cpu_descriptor;
+    struct vkd3d_view *base_view, *uint_view;
+    struct vkd3d_texture_view_desc view_desc;
+    const struct vkd3d_format *uint_format;
     struct d3d12_resource *resource_impl;
-    VkBufferMemoryBarrier buffer_barrier;
-    VkImageMemoryBarrier image_barrier;
-    VkPipelineStageFlags stage_mask;
-    VkImageSubresourceRange range;
     VkClearColorValue color;
 
     TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n",
             iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects);
 
-    vk_procs = &list->device->vk_procs;
-    vk_info = &list->device->vk_info;
+    memcpy(color.uint32, values, sizeof(color.uint32));
 
     resource_impl = unsafe_impl_from_ID3D12Resource(resource);
 
-    d3d12_command_list_track_resource_usage(list, resource_impl);
+    base_view = d3d12_desc_from_cpu_handle(cpu_handle)->u.view;
+    uint_view = NULL;
 
-    if (rect_count)
+    if (base_view->format->type != VKD3D_FORMAT_TYPE_UINT)
     {
-        FIXME("Clear rects not supported.\n");
-        return;
-    }
-
-    d3d12_command_list_end_current_render_pass(list);
+        uint_format = vkd3d_find_uint_format(list->device, base_view->format->dxgi_format);
 
-    cpu_descriptor = d3d12_desc_from_cpu_handle(cpu_handle);
-
-    if (d3d12_resource_is_buffer(resource_impl))
-    {
-        if (cpu_descriptor->u.view->format->vk_format != VK_FORMAT_R32_UINT)
+        if (!uint_format)
         {
-            FIXME("Not supported for UAV descriptor %p.\n", cpu_descriptor);
+            ERR("Unhandled format %d.\n", base_view->format->dxgi_format);
             return;
         }
 
-        VK_CALL(vkCmdFillBuffer(list->vk_command_buffer, resource_impl->u.vk_buffer,
-                cpu_descriptor->u.view->info.buffer.offset, cpu_descriptor->u.view->info.buffer.size, values[0]));
-
-        buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
-        buffer_barrier.pNext = NULL;
-        buffer_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-        buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        buffer_barrier.buffer = resource_impl->u.vk_buffer;
-        buffer_barrier.offset = cpu_descriptor->u.view->info.buffer.offset;
-        buffer_barrier.size = cpu_descriptor->u.view->info.buffer.size;
-
-        vk_barrier_parameters_from_d3d12_resource_state(D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0,
-                resource_impl, list->vk_queue_flags, vk_info, &buffer_barrier.dstAccessMask, &stage_mask, NULL);
-
-        VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
-                VK_PIPELINE_STAGE_TRANSFER_BIT, stage_mask, 0,
-                0, NULL, 1, &buffer_barrier, 0, NULL));
+        if (d3d12_resource_is_texture(resource_impl))
+        {
+            memset(&view_desc, 0, sizeof(view_desc));
+            view_desc.view_type = base_view->info.texture.vk_view_type;
+            view_desc.format = uint_format;
+            view_desc.miplevel_idx = base_view->info.texture.miplevel_idx;
+            view_desc.miplevel_count = 1;
+            view_desc.layer_idx = base_view->info.texture.layer_idx;
+            view_desc.layer_count = base_view->info.texture.layer_count;
+            view_desc.allowed_swizzle = false;
+
+            if (!vkd3d_create_texture_view(list->device, resource_impl->u.vk_image, &view_desc, &uint_view))
+            {
+                ERR("Failed to create image view.\n");
+                return;
+            }
+        }
+        else
+        {
+            if (!vkd3d_create_buffer_view(list->device, resource_impl->u.vk_buffer, uint_format,
+                    base_view->info.buffer.offset, base_view->info.buffer.size, &uint_view))
+            {
+                ERR("Failed to create buffer view.\n");
+                return;
+            }
+        }
     }
-    else
-    {
-        color.uint32[0] = values[0];
-        color.uint32[1] = values[1];
-        color.uint32[2] = values[2];
-        color.uint32[3] = values[3];
-
-        range.aspectMask = cpu_descriptor->u.view->format->vk_aspect_mask;
-        range.baseMipLevel = cpu_descriptor->u.view->info.texture.miplevel_idx;
-        range.levelCount = 1;
-        range.baseArrayLayer = cpu_descriptor->u.view->info.texture.layer_idx;
-        range.layerCount = cpu_descriptor->u.view->info.texture.layer_count;
-
-        VK_CALL(vkCmdClearColorImage(list->vk_command_buffer,
-                resource_impl->u.vk_image, VK_IMAGE_LAYOUT_GENERAL, &color, 1, &range));
-
-        image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
-        image_barrier.pNext = NULL;
-        image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-        image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
-        image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
-        image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        image_barrier.image = resource_impl->u.vk_image;
-        image_barrier.subresourceRange = range;
-
-        vk_barrier_parameters_from_d3d12_resource_state(D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0,
-                resource_impl, list->vk_queue_flags, vk_info, &image_barrier.dstAccessMask, &stage_mask, NULL);
 
-        VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
-                VK_PIPELINE_STAGE_TRANSFER_BIT, stage_mask, 0,
-                0, NULL, 0, NULL, 1, &image_barrier));
-    }
+    d3d12_command_list_clear_unordered_access_view(list, resource_impl,
+      uint_view ? uint_view : base_view, &color, rect_count, rects);
+
+    if (uint_view)
+        vkd3d_view_decref(uint_view, list->device);
 }
 
 static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList1 *iface,
-- 
2.24.0




More information about the wine-devel mailing list