anv: add a utility function to ensure command buffer space
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sat, 26 Feb 2022 11:07:18 +0000 (13:07 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 13 Dec 2022 19:22:02 +0000 (19:22 +0000)
Ensuring the space is contiguous.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20295>

src/intel/vulkan/anv_batch_chain.c
src/intel/vulkan/anv_private.h

index a1516b0..ad8c578 100644 (file)
@@ -213,8 +213,9 @@ anv_reloc_list_append(struct anv_reloc_list *list,
 void *
 anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
 {
-   if (batch->next + num_dwords * 4 > batch->end) {
-      VkResult result = batch->extend_cb(batch, batch->user_data);
+   uint32_t size = num_dwords * 4;
+   if (batch->next + size > batch->end) {
+      VkResult result = batch->extend_cb(batch, size, batch->user_data);
       if (result != VK_SUCCESS) {
          anv_batch_set_error(batch, result);
          return NULL;
@@ -229,6 +230,23 @@ anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
    return p;
 }
 
+/* Ensure enough contiguous space is available */
+VkResult
+anv_batch_emit_ensure_space(struct anv_batch *batch, uint32_t size)
+{
+   if (batch->next + size > batch->end) {
+      VkResult result = batch->extend_cb(batch, size, batch->user_data);
+      if (result != VK_SUCCESS) {
+         anv_batch_set_error(batch, result);
+         return result;
+      }
+   }
+
+   assert(batch->next + size <= batch->end);
+
+   return VK_SUCCESS;
+}
+
 struct anv_address
 anv_batch_address(struct anv_batch *batch, void *batch_location)
 {
@@ -247,7 +265,7 @@ anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other)
    assert(size % 4 == 0);
 
    if (batch->next + size > batch->end) {
-      VkResult result = batch->extend_cb(batch, batch->user_data);
+      VkResult result = batch->extend_cb(batch, size, batch->user_data);
       if (result != VK_SUCCESS) {
          anv_batch_set_error(batch, result);
          return;
@@ -548,13 +566,23 @@ anv_cmd_buffer_record_end_submit(struct anv_cmd_buffer *cmd_buffer)
 }
 
 static VkResult
-anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
+anv_cmd_buffer_chain_batch(struct anv_batch *batch, uint32_t size, void *_data)
 {
+   /* The caller should not need that much space. Otherwise it should split
+    * its commands.
+    */
+   assert(size <= ANV_MAX_CMD_BUFFER_BATCH_SIZE);
+
    struct anv_cmd_buffer *cmd_buffer = _data;
    struct anv_batch_bo *new_bbo = NULL;
+   /* Amount of reserved space at the end of the batch to account for the
+    * chaining instruction.
+    */
+   const uint32_t batch_padding = GFX8_MI_BATCH_BUFFER_START_length * 4;
    /* Cap reallocation to chunk. */
-   uint32_t alloc_size = MIN2(cmd_buffer->total_batch_size,
-                              ANV_MAX_CMD_BUFFER_BATCH_SIZE);
+   uint32_t alloc_size = MIN2(
+      MAX2(cmd_buffer->total_batch_size, size + batch_padding),
+      ANV_MAX_CMD_BUFFER_BATCH_SIZE);
 
    VkResult result = anv_batch_bo_create(cmd_buffer, alloc_size, &new_bbo);
    if (result != VK_SUCCESS)
@@ -573,7 +601,7 @@ anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
 
    list_addtail(&new_bbo->link, &cmd_buffer->batch_bos);
 
-   anv_batch_bo_start(new_bbo, batch, GFX8_MI_BATCH_BUFFER_START_length * 4);
+   anv_batch_bo_start(new_bbo, batch, batch_padding);
 
    return VK_SUCCESS;
 }
index 0b3d708..72b4355 100644 (file)
@@ -1444,7 +1444,7 @@ struct anv_batch {
    /* This callback is called (with the associated user data) in the event
     * that the batch runs out of space.
     */
-   VkResult (*extend_cb)(struct anv_batch *, void *);
+   VkResult (*extend_cb)(struct anv_batch *, uint32_t, void *);
    void *                                       user_data;
 
    /**
@@ -1458,6 +1458,7 @@ struct anv_batch {
 };
 
 void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords);
+VkResult anv_batch_emit_ensure_space(struct anv_batch *batch, uint32_t size);
 void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);
 struct anv_address anv_batch_address(struct anv_batch *batch, void *batch_location);