anv: Add helper to create companion RCS command buffer
authorSagar Ghuge <sagar.ghuge@intel.com>
Thu, 11 May 2023 18:41:39 +0000 (11:41 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 7 Sep 2023 06:39:05 +0000 (06:39 +0000)
This helper takes the main command buffer as input and then create a
companion RCS command buffer.

v2:
- Rename anv_get_render_queue_index helper to
  anv_get_first_render_queue_index (Jose)
- Rename RCS command buffer to companion RCS command buffer (Lionel)
- Add early return in anv_get_first_render_queue_index (Lionel)
- Add lock around the function (Jose)
- Move companion rcs command pool creation in device create (Sagar)
- Reset companion RCS cmd buffer (Sagar)

Signed-off-by: Sagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23661>

src/intel/vulkan/anv_cmd_buffer.c
src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_private.h

index 2646ebe..6c7d150 100644 (file)
@@ -87,6 +87,33 @@ anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->last_compute_walker = NULL;
 }
 
+VkResult
+anv_create_companion_rcs_command_buffer(struct anv_cmd_buffer *cmd_buffer)
+{
+   VkResult result = VK_SUCCESS;
+   pthread_mutex_lock(&cmd_buffer->device->mutex);
+   if (cmd_buffer->companion_rcs_cmd_buffer == NULL) {
+      VK_FROM_HANDLE(vk_command_pool, pool,
+                     cmd_buffer->device->companion_rcs_cmd_pool);
+      assert(pool != NULL);
+
+      struct vk_command_buffer *tmp_cmd_buffer = NULL;
+      result = pool->command_buffer_ops->create(pool, &tmp_cmd_buffer);
+      if (result != VK_SUCCESS) {
+         pthread_mutex_unlock(&cmd_buffer->device->mutex);
+         return result;
+      }
+
+      cmd_buffer->companion_rcs_cmd_buffer =
+         container_of(tmp_cmd_buffer, struct anv_cmd_buffer, vk);
+      cmd_buffer->companion_rcs_cmd_buffer->vk.level = cmd_buffer->vk.level;
+      cmd_buffer->companion_rcs_cmd_buffer->is_companion_rcs_cmd_buffer = true;
+   }
+   pthread_mutex_unlock(&cmd_buffer->device->mutex);
+
+   return result;
+}
+
 static VkResult
 anv_create_cmd_buffer(struct vk_command_pool *pool,
                       struct vk_command_buffer **cmd_buffer_out)
@@ -96,8 +123,8 @@ anv_create_cmd_buffer(struct vk_command_pool *pool,
    struct anv_cmd_buffer *cmd_buffer;
    VkResult result;
 
-   cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
-                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
+                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (cmd_buffer == NULL)
       return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
 
@@ -139,6 +166,8 @@ anv_create_cmd_buffer(struct vk_command_pool *pool,
       goto fail_batch_bo;
 
    cmd_buffer->self_mod_locations = NULL;
+   cmd_buffer->companion_rcs_cmd_buffer = NULL;
+   cmd_buffer->is_companion_rcs_cmd_buffer = false;
 
    cmd_buffer->generation_jump_addr = ANV_NULL_ADDRESS;
    cmd_buffer->generation_return_addr = ANV_NULL_ADDRESS;
@@ -210,6 +239,7 @@ anv_cmd_buffer_reset(struct vk_command_buffer *vk_cmd_buffer,
 
    cmd_buffer->usage_flags = 0;
    cmd_buffer->perf_query_pool = NULL;
+   cmd_buffer->is_companion_rcs_cmd_buffer = false;
    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
    anv_cmd_state_reset(cmd_buffer);
 
index 5a28227..f8ef727 100644 (file)
@@ -54,6 +54,7 @@
 #include "util/u_string.h"
 #include "util/driconf.h"
 #include "git_sha1.h"
+#include "vk_common_entrypoints.h"
 #include "vk_util.h"
 #include "vk_deferred_operation.h"
 #include "vk_drm_syncobj.h"
@@ -3472,6 +3473,22 @@ VkResult anv_CreateDevice(
                                              4);
    p_atomic_set(&device->draw_call_count, 0);
 
+   /* Create a separate command pool for companion RCS command buffer. */
+   if (device->info->verx10 >= 125) {
+      VkCommandPoolCreateInfo pool_info = {
+         .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+         .queueFamilyIndex =
+             anv_get_first_render_queue_index(device->physical),
+      };
+
+      result = vk_common_CreateCommandPool(anv_device_to_handle(device),
+                                           &pool_info, NULL,
+                                           &device->companion_rcs_cmd_pool);
+      if (result != VK_SUCCESS) {
+         goto fail_internal_cache;
+      }
+   }
+
    anv_device_init_blorp(device);
 
    anv_device_init_border_colors(device);
@@ -3611,6 +3628,11 @@ void anv_DestroyDevice(
    if (ANV_SUPPORT_RT && device->info->has_ray_tracing)
       anv_device_release_bo(device, device->btd_fifo_bo);
 
+   if (device->info->verx10 >= 125) {
+      vk_common_DestroyCommandPool(anv_device_to_handle(device),
+                                   device->companion_rcs_cmd_pool, NULL);
+   }
+
 #ifdef HAVE_VALGRIND
    /* We only need to free these to prevent valgrind errors.  The backing
     * BO will go away in a couple of lines so we don't actually leak.
index a1c6141..346ecab 100644 (file)
@@ -1613,8 +1613,27 @@ struct anv_device {
      * initialization).
      */
     BITSET_DECLARE(gfx_dirty_state, ANV_GFX_STATE_MAX);
+
+    /*
+     * Command pool for companion RCS command buffer.
+     */
+    VkCommandPool                               companion_rcs_cmd_pool;
 };
 
+static inline uint32_t
+anv_get_first_render_queue_index(struct anv_physical_device *pdevice)
+{
+   assert(pdevice != NULL);
+
+   for (uint32_t i = 0; i < pdevice->queue.family_count; i++) {
+      if (pdevice->queue.families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+         return i;
+      }
+   }
+
+   unreachable("Graphics capable queue family not found");
+}
+
 static inline struct anv_state
 anv_binding_table_pool_alloc(struct anv_device *device)
 {
@@ -3456,6 +3475,18 @@ struct anv_cmd_buffer {
       struct anv_video_session *vid;
       struct anv_video_session_params *params;
    } video;
+
+   /**
+    * Companion RCS command buffer to support the MSAA operations on compute
+    * queue.
+    */
+   struct anv_cmd_buffer                        *companion_rcs_cmd_buffer;
+
+   /**
+    * Whether this command buffer is a companion command buffer of compute one.
+    */
+   bool                                         is_companion_rcs_cmd_buffer;
+
 };
 
 extern const struct vk_command_buffer_ops anv_cmd_buffer_ops;
@@ -4722,6 +4753,9 @@ anv_cmd_buffer_fill_area(struct anv_cmd_buffer *cmd_buffer,
                          VkDeviceSize size,
                          uint32_t data);
 
+VkResult
+anv_create_companion_rcs_command_buffer(struct anv_cmd_buffer *cmd_buffer);
+
 bool
 anv_can_hiz_clear_ds_view(struct anv_device *device,
                           const struct anv_image_view *iview,