[Mesa-dev] [PATCH 2/3] anv: centralize PIPE_CONTROLs

Lionel Landwerlin lionel.g.landwerlin at intel.com
Wed Feb 22 12:12:04 UTC 2017


This allows us to monitor pipe controls and apply workarounds in a
single location if needed.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
 src/intel/vulkan/anv_genX.h        | 26 ++++++++++++++++++++++++++
 src/intel/vulkan/anv_private.h     |  8 ++++++++
 src/intel/vulkan/genX_blorp_exec.c |  4 ++--
 src/intel/vulkan/genX_cmd_buffer.c | 35 ++++++++++++++++++++++-------------
 src/intel/vulkan/genX_pipeline.c   |  2 +-
 src/intel/vulkan/genX_query.c      | 10 +++++-----
 6 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index 67147b0e92..2e7303405c 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -36,6 +36,27 @@
 #error This file is included by means other than anv_private.h
 #endif
 
+struct GENX(PIPE_CONTROL);
+
+#define anv_cmd_buffer_pipe_control(cmd_buffer, name)                   \
+   for ( struct GENX(PIPE_CONTROL) name =                               \
+            { GENX(PIPE_CONTROL_header) },                              \
+            *__continue = &name;                                        \
+         __continue != NULL;                                            \
+         ({ genX(emit_pipe_control((cmd_buffer)->device,                \
+                                   &(cmd_buffer)->batch, &name));       \
+            __continue = NULL;                                          \
+         }))
+
+#define anv_batch_pipe_control(device, batch, name)                     \
+   for ( struct GENX(PIPE_CONTROL) name =                               \
+            { GENX(PIPE_CONTROL_header) },                              \
+            *__continue = &name;                                        \
+         __continue != NULL;                                            \
+         ({ genX(emit_pipe_control(device, batch, &name));              \
+            __continue = NULL;                                          \
+         }))
+
 VkResult genX(init_device_state)(struct anv_device *device);
 
 void genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer);
@@ -64,6 +85,11 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
                      VkShaderStageFlags active_stages,
                      const unsigned entry_size[4]);
 
+void
+genX(emit_pipe_control)(struct anv_device *device,
+                        struct anv_batch *batch,
+                        const struct GENX(PIPE_CONTROL) *pc);
+
 void genX(cmd_buffer_gpu_memcpy)(struct anv_cmd_buffer *cmd_buffer,
                                  struct anv_bo *dst, uint32_t dst_offset,
                                  struct anv_bo *src, uint32_t src_offset,
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 2527c2cc5a..ac121c833e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1954,17 +1954,25 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule)
 #  include "anv_genX.h"
 #else
 #  define genX(x) gen7_##x
+#  define GENX(x) GEN7_##x
 #  include "anv_genX.h"
 #  undef genX
+#  undef GENX
 #  define genX(x) gen75_##x
+#  define GENX(x) GEN75_##x
 #  include "anv_genX.h"
 #  undef genX
+#  undef GENX
 #  define genX(x) gen8_##x
+#  define GENX(x) GEN8_##x
 #  include "anv_genX.h"
 #  undef genX
+#  undef GENX
 #  define genX(x) gen9_##x
+#  define GENX(x) GEN9_##x
 #  include "anv_genX.h"
 #  undef genX
+#  undef GENX
 #endif
 
 #endif /* ANV_PRIVATE_H */
diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c
index e2ed7e6d1c..ec63910c39 100644
--- a/src/intel/vulkan/genX_blorp_exec.c
+++ b/src/intel/vulkan/genX_blorp_exec.c
@@ -39,8 +39,8 @@ static void
 genX(blorp_emit_pipe_control)(struct blorp_batch *batch,
                               const struct GENX(PIPE_CONTROL) *pc)
 {
-   void *batch_pc = blorp_emit_dwords(batch, GENX(PIPE_CONTROL_length));
-   GENX(PIPE_CONTROL_pack)(batch, batch_pc, pc);
+   struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
+   genX(emit_pipe_control)(cmd_buffer->device, &cmd_buffer->batch, pc);
 }
 #endif
 
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 7af2b31679..856b58412a 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -31,6 +31,15 @@
 #include "genxml/gen_macros.h"
 #include "genxml/genX_pack.h"
 
+void
+genX(emit_pipe_control)(struct anv_device *device,
+                        struct anv_batch *batch,
+                        const struct GENX(PIPE_CONTROL) *pc)
+{
+   void *batch_pc = anv_batch_emit_dwords(batch, GENX(PIPE_CONTROL_length));
+   GENX(PIPE_CONTROL_pack)(batch, batch_pc, pc);
+}
+
 static void
 emit_lrm(struct anv_batch *batch,
          uint32_t reg, struct anv_bo *bo, uint32_t offset)
@@ -62,7 +71,7 @@ genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer)
     * this, we get GPU hangs when using multi-level command buffers which
     * clear depth, reset state base address, and then go render stuff.
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.DCFlushEnable = true;
       pc.RenderTargetCacheFlushEnable = true;
       pc.CommandStreamerStallEnable = true;
@@ -145,7 +154,7 @@ genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer)
     * units cache the binding table in the texture cache.  However, we have
     * yet to be able to actually confirm this.
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.TextureCacheInvalidationEnable = true;
       pc.ConstantCacheInvalidationEnable = true;
       pc.StateCacheInvalidationEnable = true;
@@ -723,7 +732,7 @@ genX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer,
     * while the pipeline is completely drained and the caches are flushed,
     * which involves a first PIPE_CONTROL flush which stalls the pipeline...
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.DCFlushEnable = true;
       pc.PostSyncOperation = NoWrite;
       pc.CommandStreamerStallEnable = true;
@@ -743,7 +752,7 @@ genX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer,
     * already guarantee that there is no concurrent GPGPU kernel execution
     * (see SKL HSD 2132585).
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.TextureCacheInvalidationEnable = true;
       pc.ConstantCacheInvalidationEnable = true;
       pc.InstructionCacheInvalidateEnable = true;
@@ -754,7 +763,7 @@ genX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer,
    /* Now send a third stalling flush to make sure that invalidation is
     * complete when the L3 configuration registers are modified.
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.DCFlushEnable = true;
       pc.PostSyncOperation = NoWrite;
       pc.CommandStreamerStallEnable = true;
@@ -877,7 +886,7 @@ genX(cmd_buffer_apply_pipe_flushes)(struct anv_cmd_buffer *cmd_buffer)
    }
 
    if (bits & (ANV_PIPE_FLUSH_BITS | ANV_PIPE_CS_STALL_BIT)) {
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pipe) {
          pipe.DepthCacheFlushEnable = bits & ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
          pipe.DCFlushEnable = bits & ANV_PIPE_DATA_CACHE_FLUSH_BIT;
          pipe.RenderTargetCacheFlushEnable =
@@ -912,7 +921,7 @@ genX(cmd_buffer_apply_pipe_flushes)(struct anv_cmd_buffer *cmd_buffer)
    }
 
    if (bits & ANV_PIPE_INVALIDATE_BITS) {
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pipe) {
          pipe.StateCacheInvalidationEnable =
             bits & ANV_PIPE_STATE_CACHE_INVALIDATE_BIT;
          pipe.ConstantCacheInvalidationEnable =
@@ -1551,7 +1560,7 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
        *    PIPE_CONTROL needs to be sent before any combination of VS
        *    associated 3DSTATE."
        */
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.DepthStallEnable  = true;
          pc.PostSyncOperation = WriteImmediateData;
          pc.Address           =
@@ -2090,7 +2099,7 @@ flush_pipeline_before_pipeline_select(struct anv_cmd_buffer *cmd_buffer,
        *   command to invalidate read only caches prior to programming
        *   MI_PIPELINE_SELECT command to change the Pipeline Select Mode.
        */
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.RenderTargetCacheFlushEnable  = true;
          pc.DepthCacheFlushEnable         = true;
          pc.DCFlushEnable                 = true;
@@ -2098,7 +2107,7 @@ flush_pipeline_before_pipeline_select(struct anv_cmd_buffer *cmd_buffer,
          pc.CommandStreamerStallEnable    = true;
       }
 
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.TextureCacheInvalidationEnable   = true;
          pc.ConstantCacheInvalidationEnable  = true;
          pc.StateCacheInvalidationEnable     = true;
@@ -2160,13 +2169,13 @@ genX(cmd_buffer_emit_gen7_depth_flush)(struct anv_cmd_buffer *cmd_buffer)
     *    guarantee that the pipeline from WM onwards is already flushed (e.g.,
     *    via a preceding MI_FLUSH)."
     */
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pipe) {
       pipe.DepthStallEnable = true;
    }
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pipe) {
       pipe.DepthCacheFlushEnable = true;
    }
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pipe) {
       pipe.DepthStallEnable = true;
    }
 }
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 2a7e552746..5e7a123ac3 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -259,7 +259,7 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
     *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
     *    needs to be sent before any combination of VS associated 3DSTATE."
     */
-   anv_batch_emit(batch, GEN7_PIPE_CONTROL, pc) {
+   anv_batch_pipe_control(device, batch, pc) {
       pc.DepthStallEnable  = true;
       pc.PostSyncOperation = WriteImmediateData;
       pc.Address           = (struct anv_address) { &device->workaround_bo, 0 };
diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c
index 830f867046..ba5e114a46 100644
--- a/src/intel/vulkan/genX_query.c
+++ b/src/intel/vulkan/genX_query.c
@@ -177,7 +177,7 @@ static void
 emit_ps_depth_count(struct anv_cmd_buffer *cmd_buffer,
                     struct anv_bo *bo, uint32_t offset)
 {
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.DestinationAddressType  = DAT_PPGTT;
       pc.PostSyncOperation       = WritePSDepthCount;
       pc.DepthStallEnable        = true;
@@ -192,7 +192,7 @@ static void
 emit_query_availability(struct anv_cmd_buffer *cmd_buffer,
                         struct anv_bo *bo, uint32_t offset)
 {
-   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+   anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
       pc.DestinationAddressType  = DAT_PPGTT;
       pc.PostSyncOperation       = WriteImmediateData;
       pc.Address                 = (struct anv_address) { bo, offset };
@@ -247,7 +247,7 @@ void genX(CmdBeginQuery)(
     */
    if (cmd_buffer->state.need_query_wa) {
       cmd_buffer->state.need_query_wa = false;
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.DepthCacheFlushEnable   = true;
          pc.DepthStallEnable        = true;
       }
@@ -316,7 +316,7 @@ void genX(CmdWriteTimestamp)(
 
    default:
       /* Everything else is bottom-of-pipe */
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.DestinationAddressType  = DAT_PPGTT;
          pc.PostSyncOperation       = WriteTimestamp;
          pc.Address = (struct anv_address) { &pool->bo, offset };
@@ -411,7 +411,7 @@ void genX(CmdCopyQueryPoolResults)(
    uint32_t slot_offset, dst_offset;
 
    if (flags & VK_QUERY_RESULT_WAIT_BIT) {
-      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
+      anv_cmd_buffer_pipe_control(cmd_buffer, pc) {
          pc.CommandStreamerStallEnable = true;
          pc.StallAtPixelScoreboard     = true;
       }
-- 
2.11.0



More information about the mesa-dev mailing list