We can't fast clear on compute queues.

Signed-off-by: Bas Nieuwenhuizen <ba...@google.com>
---
 src/amd/vulkan/radv_cmd_buffer.c | 40 ++++++++++++++++++++++++++++++++++++----
 src/amd/vulkan/radv_image.c      | 18 ++++++++++++++++--
 src/amd/vulkan/radv_meta_clear.c |  2 +-
 src/amd/vulkan/radv_private.h    | 10 +++++++++-
 4 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 3c5fe25ce6..0572cb85e5 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -36,6 +36,8 @@ static void radv_handle_image_transition(struct 
radv_cmd_buffer *cmd_buffer,
                                         struct radv_image *image,
                                         VkImageLayout src_layout,
                                         VkImageLayout dst_layout,
+                                        int src_family,
+                                        int dst_family,
                                         VkImageSubresourceRange range,
                                         VkImageAspectFlags pending_clears);
 
@@ -1207,7 +1209,7 @@ static void radv_handle_subpass_image_transition(struct 
radv_cmd_buffer *cmd_buf
        radv_handle_image_transition(cmd_buffer,
                                     view->image,
                                     
cmd_buffer->state.attachments[idx].current_layout,
-                                    att.layout, range,
+                                    att.layout, 0, 0, range,
                                     
cmd_buffer->state.attachments[idx].pending_clear_aspects);
 
        cmd_buffer->state.attachments[idx].current_layout = att.layout;
@@ -2386,6 +2388,8 @@ static void radv_handle_cmask_image_transition(struct 
radv_cmd_buffer *cmd_buffe
                                               struct radv_image *image,
                                               VkImageLayout src_layout,
                                               VkImageLayout dst_layout,
+                                              unsigned src_queue_mask,
+                                              unsigned dst_queue_mask,
                                               VkImageSubresourceRange range,
                                               VkImageAspectFlags 
pending_clears)
 {
@@ -2394,8 +2398,8 @@ static void radv_handle_cmask_image_transition(struct 
radv_cmd_buffer *cmd_buffe
                        radv_initialise_cmask(cmd_buffer, image, 0xccccccccu);
                else
                        radv_initialise_cmask(cmd_buffer, image, 0xffffffffu);
-       } else if (radv_layout_has_cmask(image, src_layout) &&
-                  !radv_layout_has_cmask(image, dst_layout)) {
+       } else if (radv_layout_has_cmask(image, src_layout, src_queue_mask) &&
+                  !radv_layout_has_cmask(image, dst_layout, dst_queue_mask)) {
                radv_fast_clear_flush_image_inplace(cmd_buffer, image);
        }
 }
@@ -2436,16 +2440,40 @@ static void radv_handle_image_transition(struct 
radv_cmd_buffer *cmd_buffer,
                                         struct radv_image *image,
                                         VkImageLayout src_layout,
                                         VkImageLayout dst_layout,
+                                        int src_family,
+                                        int dst_family,
                                         VkImageSubresourceRange range,
                                         VkImageAspectFlags pending_clears)
 {
+       if (image->exclusive && src_family != dst_family) {
+               /* This is an acquire or a release operation and there will be
+                * a corresponding release/acquire. Do the transition in the
+                * most flexible queue. */
+
+               assert(src_family == cmd_buffer->queue_family_index ||
+                      dst_family == cmd_buffer->queue_family_index);
+
+               if (cmd_buffer->queue_family_index == RADV_QUEUE_TRANSFER)
+                       return;
+
+               if (cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE &&
+                   (src_family == RADV_QUEUE_GENERAL ||
+                    dst_family == RADV_QUEUE_GENERAL))
+                       return;
+       }
+
+       unsigned src_queue_mask = radv_image_queue_family_mask(image, 
src_family);
+       unsigned dst_queue_mask = radv_image_queue_family_mask(image, 
dst_family);
+
        if (image->htile.size)
                radv_handle_depth_image_transition(cmd_buffer, image, 
src_layout,
                                                   dst_layout, range, 
pending_clears);
 
        if (image->cmask.size)
                radv_handle_cmask_image_transition(cmd_buffer, image, 
src_layout,
-                                                  dst_layout, range, 
pending_clears);
+                                                  dst_layout, src_queue_mask,
+                                                  dst_queue_mask, range,
+                                                  pending_clears);
 
        if (image->surface.dcc_size)
                radv_handle_dcc_image_transition(cmd_buffer, image, src_layout,
@@ -2509,6 +2537,8 @@ void radv_CmdPipelineBarrier(
                radv_handle_image_transition(cmd_buffer, image,
                                             pImageMemoryBarriers[i].oldLayout,
                                             pImageMemoryBarriers[i].newLayout,
+                                            
pImageMemoryBarriers[i].srcQueueFamilyIndex,
+                                            
pImageMemoryBarriers[i].dstQueueFamilyIndex,
                                             
pImageMemoryBarriers[i].subresourceRange,
                                             0);
        }
@@ -2639,6 +2669,8 @@ void radv_CmdWaitEvents(VkCommandBuffer commandBuffer,
                radv_handle_image_transition(cmd_buffer, image,
                                             pImageMemoryBarriers[i].oldLayout,
                                             pImageMemoryBarriers[i].newLayout,
+                                            
pImageMemoryBarriers[i].srcQueueFamilyIndex,
+                                            
pImageMemoryBarriers[i].dstQueueFamilyIndex,
                                             
pImageMemoryBarriers[i].subresourceRange,
                                             0);
        }
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index fee98ba94c..a0287fcb3e 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -698,6 +698,11 @@ radv_image_create(VkDevice _device,
        image->samples = pCreateInfo->samples;
        image->tiling = pCreateInfo->tiling;
        image->usage = pCreateInfo->usage;
+
+       image->exclusive = pCreateInfo->sharingMode == 
VK_SHARING_MODE_EXCLUSIVE;
+       for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
+               image->queue_family_mask |= 1u << 
pCreateInfo->pQueueFamilyIndices[i];
+
        radv_init_surface(device, &image->surface, create_info);
 
        device->ws->surface_init(device->ws, &image->surface);
@@ -887,10 +892,19 @@ bool radv_layout_can_expclear(const struct radv_image 
*image,
 }
 
 bool radv_layout_has_cmask(const struct radv_image *image,
-                          VkImageLayout layout)
+                          VkImageLayout layout,
+                          unsigned queue_mask)
 {
        return (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ||
-               layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+               layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) &&
+               queue_mask == (1u << RADV_QUEUE_GENERAL);
+}
+
+
+unsigned radv_image_queue_family_mask(const struct radv_image *image, int 
family) {
+       if (image->exclusive)
+               return 1u <<family;
+       return image->queue_family_mask;
 }
 
 VkResult
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index d6af29187f..b7263dde01 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -805,7 +805,7 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer,
        if (!cmd_buffer->device->allow_fast_clears)
                return false;
 
-       if (!radv_layout_has_cmask(iview->image, image_layout))
+       if (!radv_layout_has_cmask(iview->image, image_layout, 
radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index)))
                goto fail;
        if (vk_format_get_blocksizebits(iview->image->vk_format) > 64)
                goto fail;
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index e6f6c29c91..03d295986f 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1006,6 +1006,9 @@ struct radv_image {
        VkDeviceSize size;
        uint32_t alignment;
 
+       bool exclusive;
+       unsigned queue_family_mask;
+
        /* Set when bound */
        struct radeon_winsys_bo *bo;
        VkDeviceSize offset;
@@ -1027,7 +1030,12 @@ bool radv_layout_is_htile_compressed(const struct 
radv_image *image,
 bool radv_layout_can_expclear(const struct radv_image *image,
                               VkImageLayout layout);
 bool radv_layout_has_cmask(const struct radv_image *image,
-                          VkImageLayout layout);
+                          VkImageLayout layout,
+                          unsigned queue_mask);
+
+
+unsigned radv_image_queue_family_mask(const struct radv_image *image, int 
family);
+
 static inline uint32_t
 radv_get_layerCount(const struct radv_image *image,
                    const VkImageSubresourceRange *range)
-- 
2.11.0

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to