Mesa (main): anv: fix index buffer emission

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 21 17:04:14 UTC 2022


Module: Mesa
Branch: main
Commit: 4f10eddf77f64fd942c7e9b5852becfa3569924e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4f10eddf77f64fd942c7e9b5852becfa3569924e

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Sun Jun 12 23:54:12 2022 +0300

anv: fix index buffer emission

In the following case :

  vkCmdBindPipeline(compute_pipeline);
  vkCmdDispatch(...);
  vkCmdBindPipeline(graphics_pipeline);
  vkCmdBindIndexBuffer(buffer)
  vkCmdDraw(...);

We're emitting the 3DSTATE_INDEX_BUFFER instruction while the HW is
still in GPGPU mode, because we're dealing the pipeline selection to
vkCmdDraw().

Found while debugging Age Of Empire 4, HW is hung on
3DSTATE_INDEX_BUFFER instruction.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: mesa-stable
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17153>

---

 src/intel/vulkan/anv_private.h     |  8 ++---
 src/intel/vulkan/genX_cmd_buffer.c | 45 ++++++++++++++++++++++++
 src/intel/vulkan/gfx7_cmd_buffer.c | 56 +++--------------------------
 src/intel/vulkan/gfx8_cmd_buffer.c | 72 +++++++++-----------------------------
 4 files changed, 69 insertions(+), 112 deletions(-)

diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 144b8492e09..db73bd9842b 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2888,11 +2888,9 @@ struct anv_cmd_graphics_state {
 
    uint32_t primitive_topology;
 
-   struct {
-      struct anv_buffer *index_buffer;
-      uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
-      uint32_t index_offset;
-   } gfx7;
+   struct anv_buffer *index_buffer;
+   uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
+   uint32_t index_offset;
 };
 
 enum anv_depth_reg_mode {
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 7631489c404..8120bf7962f 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -7425,6 +7425,51 @@ void genX(CmdWaitEvents2)(
    cmd_buffer_barrier(cmd_buffer, pDependencyInfos, "wait event");
 }
 
+static uint32_t vk_to_intel_index_type(VkIndexType type)
+{
+   switch (type) {
+   case VK_INDEX_TYPE_UINT8_EXT:
+      return INDEX_BYTE;
+   case VK_INDEX_TYPE_UINT16:
+      return INDEX_WORD;
+   case VK_INDEX_TYPE_UINT32:
+      return INDEX_DWORD;
+   default:
+      unreachable("invalid index type");
+   }
+}
+
+static uint32_t restart_index_for_type(VkIndexType type)
+{
+   switch (type) {
+   case VK_INDEX_TYPE_UINT8_EXT:
+      return UINT8_MAX;
+   case VK_INDEX_TYPE_UINT16:
+      return UINT16_MAX;
+   case VK_INDEX_TYPE_UINT32:
+      return UINT32_MAX;
+   default:
+      unreachable("invalid index type");
+   }
+}
+
+void genX(CmdBindIndexBuffer)(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    VkIndexType                                 indexType)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   cmd_buffer->state.restart_index = restart_index_for_type(indexType);
+   cmd_buffer->state.gfx.index_buffer = buffer;
+   cmd_buffer->state.gfx.index_type = vk_to_intel_index_type(indexType);
+   cmd_buffer->state.gfx.index_offset = offset;
+
+   cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
+}
+
 VkResult genX(CmdSetPerformanceOverrideINTEL)(
     VkCommandBuffer                             commandBuffer,
     const VkPerformanceOverrideInfoINTEL*       pOverrideInfo)
diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c
index dc9a3cd94de..d9e6538478f 100644
--- a/src/intel/vulkan/gfx7_cmd_buffer.c
+++ b/src/intel/vulkan/gfx7_cmd_buffer.c
@@ -33,54 +33,6 @@
 #include "genxml/gen_macros.h"
 #include "genxml/genX_pack.h"
 
-#if GFX_VERx10 == 70
-#endif
-
-static uint32_t vk_to_intel_index_type(VkIndexType type)
-{
-   switch (type) {
-   case VK_INDEX_TYPE_UINT8_EXT:
-      return INDEX_BYTE;
-   case VK_INDEX_TYPE_UINT16:
-      return INDEX_WORD;
-   case VK_INDEX_TYPE_UINT32:
-      return INDEX_DWORD;
-   default:
-      unreachable("invalid index type");
-   }
-}
-
-static uint32_t restart_index_for_type(VkIndexType type)
-{
-   switch (type) {
-   case VK_INDEX_TYPE_UINT8_EXT:
-      return UINT8_MAX;
-   case VK_INDEX_TYPE_UINT16:
-      return UINT16_MAX;
-   case VK_INDEX_TYPE_UINT32:
-      return UINT32_MAX;
-   default:
-      unreachable("invalid index type");
-   }
-}
-
-void genX(CmdBindIndexBuffer)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    VkIndexType                                 indexType)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-
-   cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
-   if (GFX_VERx10 == 75)
-      cmd_buffer->state.restart_index = restart_index_for_type(indexType);
-   cmd_buffer->state.gfx.gfx7.index_buffer = buffer;
-   cmd_buffer->state.gfx.gfx7.index_type = vk_to_intel_index_type(indexType);
-   cmd_buffer->state.gfx.gfx7.index_offset = offset;
-}
-
 static uint32_t
 get_depth_format(struct anv_cmd_buffer *cmd_buffer)
 {
@@ -244,12 +196,12 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
       }
    }
 
-   if (cmd_buffer->state.gfx.gfx7.index_buffer &&
+   if (cmd_buffer->state.gfx.index_buffer &&
        cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
                                       ANV_CMD_DIRTY_INDEX_BUFFER |
                                       ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
-      struct anv_buffer *buffer = cmd_buffer->state.gfx.gfx7.index_buffer;
-      uint32_t offset = cmd_buffer->state.gfx.gfx7.index_offset;
+      struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
+      uint32_t offset = cmd_buffer->state.gfx.index_offset;
 
 #if GFX_VERx10 == 75
       anv_batch_emit(&cmd_buffer->batch, GFX75_3DSTATE_VF, vf) {
@@ -262,7 +214,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
 #if GFX_VERx10 != 75
          ib.CutIndexEnable        = d->primitive_restart_enable;
 #endif
-         ib.IndexFormat           = cmd_buffer->state.gfx.gfx7.index_type;
+         ib.IndexFormat           = cmd_buffer->state.gfx.index_type;
          ib.MOCS                  = anv_mocs(cmd_buffer->device,
                                              buffer->address.bo,
                                              ISL_SURF_USAGE_INDEX_BUFFER_BIT);
diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c
index 953b93dc0c3..efd0b1bdc6a 100644
--- a/src/intel/vulkan/gfx8_cmd_buffer.c
+++ b/src/intel/vulkan/gfx8_cmd_buffer.c
@@ -592,6 +592,23 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
       }
    }
 
+   if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_INDEX_BUFFER) {
+      struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
+      uint32_t offset = cmd_buffer->state.gfx.index_offset;
+      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
+         ib.IndexFormat           = cmd_buffer->state.gfx.index_type;
+         ib.MOCS                  = anv_mocs(cmd_buffer->device,
+                                             buffer->address.bo,
+                                             ISL_SURF_USAGE_INDEX_BUFFER_BIT);
+#if GFX_VER >= 12
+         ib.L3BypassDisable       = true;
+#endif
+         ib.BufferStartingAddress = anv_address_add(buffer->address, offset);
+         ib.BufferSize            = vk_buffer_range(&buffer->vk, offset,
+                                                    VK_WHOLE_SIZE);
+      }
+   }
+
 #if GFX_VERx10 >= 125
    if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
                                       ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
@@ -712,58 +729,3 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
 
    cmd_buffer->state.gfx.dirty = 0;
 }
-
-static uint32_t vk_to_intel_index_type(VkIndexType type)
-{
-   switch (type) {
-   case VK_INDEX_TYPE_UINT8_EXT:
-      return INDEX_BYTE;
-   case VK_INDEX_TYPE_UINT16:
-      return INDEX_WORD;
-   case VK_INDEX_TYPE_UINT32:
-      return INDEX_DWORD;
-   default:
-      unreachable("invalid index type");
-   }
-}
-
-static uint32_t restart_index_for_type(VkIndexType type)
-{
-   switch (type) {
-   case VK_INDEX_TYPE_UINT8_EXT:
-      return UINT8_MAX;
-   case VK_INDEX_TYPE_UINT16:
-      return UINT16_MAX;
-   case VK_INDEX_TYPE_UINT32:
-      return UINT32_MAX;
-   default:
-      unreachable("invalid index type");
-   }
-}
-
-void genX(CmdBindIndexBuffer)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    VkIndexType                                 indexType)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-
-   cmd_buffer->state.restart_index = restart_index_for_type(indexType);
-
-   anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
-      ib.IndexFormat           = vk_to_intel_index_type(indexType);
-      ib.MOCS                  = anv_mocs(cmd_buffer->device,
-                                          buffer->address.bo,
-                                          ISL_SURF_USAGE_INDEX_BUFFER_BIT);
-#if GFX_VER >= 12
-      ib.L3BypassDisable       = true;
-#endif
-      ib.BufferStartingAddress = anv_address_add(buffer->address, offset);
-      ib.BufferSize            = vk_buffer_range(&buffer->vk, offset,
-                                                 VK_WHOLE_SIZE);
-   }
-
-   cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
-}



More information about the mesa-commit mailing list