[Mesa-dev] [PATCH 02/20] i965: Enable gather push constants

Abdiel Janulgue abdiel.janulgue at linux.intel.com
Fri Sep 11 01:33:16 PDT 2015


The 3DSTATE_GATHER_POOL_ALLOC is used to enable or disable the gather
push constants feature within a context. This patch provides the toggle
functionality of using gather push constants to program constant data
within a batch.

Using gather push constants require that a gather pool be allocated so
that the resource streamer can flush the packed constants it gathered.
The pool is later referenced by the 3DSTATE_CONSTANT_* command to
program the push constant data.

Also introduce INTEL_UBO_GATHER to selectively enable which shader stage
uses gather constants for ubo fetches.

v2: GEN8 support.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_binding_tables.c | 59 ++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_context.c        | 39 ++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_context.h        | 10 +++++
 src/mesa/drivers/dri/i965/brw_state.h          |  1 +
 4 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/brw_binding_tables.c b/src/mesa/drivers/dri/i965/brw_binding_tables.c
index 508f1f0..aa16b6d 100644
--- a/src/mesa/drivers/dri/i965/brw_binding_tables.c
+++ b/src/mesa/drivers/dri/i965/brw_binding_tables.c
@@ -276,6 +276,60 @@ gen7_update_binding_table_from_array(struct brw_context *brw,
    ADVANCE_BATCH();
 }
 
+static void
+gen7_init_gather_pool(struct brw_context *brw)
+{
+   if (!brw->use_resource_streamer ||
+       (!brw->vs_ubo_gather && !brw->gs_ubo_gather && !brw->fs_ubo_gather))
+      return;
+
+   if (!brw->gather_pool.bo) {
+      brw->gather_pool.bo = drm_intel_bo_alloc(brw->bufmgr, "gather_pool",
+                                               brw->gather_pool.size, 4096);
+      brw->gather_pool.next_offset = 0;
+   }
+}
+
+void
+gen7_toggle_gather_constants(struct brw_context *brw, bool enable)
+{
+   if (!brw->use_resource_streamer ||
+       (enable && !(brw->vs_ubo_gather || brw->gs_ubo_gather ||
+                    brw->fs_ubo_gather)))
+      return;
+
+   uint32_t dw1 = enable ? BRW_GATHER_CONSTANTS_ENABLE : 0;
+   if (brw->is_haswell) {
+      dw1 |= HSW_GATHER_CONSTANTS_RESERVED | (enable ? GEN7_MOCS_L3 : 0);
+   } else if (brw->gen == 8) {
+      dw1 |= (enable ? BDW_MOCS_WB : 0);
+   }
+   int pkt_len = brw->gen >= 8 ? 4 : 3;
+
+   BEGIN_BATCH(pkt_len);
+   OUT_BATCH(_3DSTATE_GATHER_POOL_ALLOC << 16 | (pkt_len - 2));
+   if (brw->gen >=8 ) {
+      if (enable) {
+         OUT_RELOC64(brw->gather_pool.bo, I915_GEM_DOMAIN_SAMPLER, 0, dw1);
+         OUT_BATCH(brw->gather_pool.bo->size);
+      } else {
+         OUT_BATCH(dw1);
+         OUT_BATCH(0);
+         OUT_BATCH(0);
+      }
+   } else {
+      if (enable) {
+         OUT_RELOC(brw->gather_pool.bo, I915_GEM_DOMAIN_SAMPLER, 0, dw1);
+         OUT_RELOC(brw->gather_pool.bo, I915_GEM_DOMAIN_SAMPLER, 0,
+                   brw->gather_pool.bo->size);
+      } else {
+         OUT_BATCH(dw1);
+         OUT_BATCH(0);
+      }
+   }
+   ADVANCE_BATCH();
+}
+
 /**
  * Disable hardware binding table support, falling back to the
  * older software-generated binding table mechanism.
@@ -294,6 +348,7 @@ gen7_disable_hw_binding_tables(struct brw_context *brw)
    brw_emit_pipe_control_flush(brw, PIPE_CONTROL_STATE_CACHE_INVALIDATE);
 
    int pkt_len = brw->gen >= 8 ? 4 : 3;
+   gen7_toggle_gather_constants(brw, false);
 
    BEGIN_BATCH(pkt_len);
    OUT_BATCH(_3DSTATE_BINDING_TABLE_POOL_ALLOC << 16 | (pkt_len - 2));
@@ -360,12 +415,16 @@ gen7_enable_hw_binding_tables(struct brw_context *brw)
              brw->hw_bt_pool.bo->size);
    }
    ADVANCE_BATCH();
+
+   gen7_init_gather_pool(brw);
+   gen7_toggle_gather_constants(brw, true);
 }
 
 void
 gen7_reset_hw_bt_pool_offsets(struct brw_context *brw)
 {
    brw->hw_bt_pool.next_offset = 0;
+   brw->gather_pool.next_offset = 0;
 }
 
 const struct brw_tracked_state gen7_hw_binding_tables = {
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 7c1c133..8079465 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -68,6 +68,7 @@
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 #include "util/ralloc.h"
+#include "util/u_atomic.h"
 
 /***************************************
  * Mesa's Driver Functions
@@ -687,6 +688,26 @@ brw_process_driconf_options(struct brw_context *brw)
       driQueryOptionb(options, "allow_glsl_extension_directive_midshader");
 }
 
+static void
+brw_process_intel_gather_variable(struct brw_context *brw)
+{
+   uint64_t INTEL_UBO_GATHER = 0;
+
+   static const struct dri_debug_control gather_control[] = {
+      { "vs", 1 << MESA_SHADER_VERTEX },
+      { "gs", 1 << MESA_SHADER_GEOMETRY },
+      { "fs", 1 << MESA_SHADER_FRAGMENT },
+      { NULL, 0 }
+   };
+   uint64_t intel_ubo_gather = driParseDebugString(getenv("INTEL_UBO_GATHER"),
+                                                   gather_control);
+   (void) p_atomic_cmpxchg(&INTEL_UBO_GATHER, 0, intel_ubo_gather);
+
+   brw->vs_ubo_gather = INTEL_UBO_GATHER & (1 << MESA_SHADER_VERTEX);
+   brw->gs_ubo_gather = INTEL_UBO_GATHER & (1 << MESA_SHADER_GEOMETRY);
+   brw->fs_ubo_gather = INTEL_UBO_GATHER & (1 << MESA_SHADER_FRAGMENT);
+}
+
 GLboolean
 brwCreateContext(gl_api api,
 	         const struct gl_config *mesaVis,
@@ -750,6 +771,8 @@ brwCreateContext(gl_api api,
    brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil;
    brw->has_swizzling = screen->hw_has_swizzling;
 
+   brw_process_intel_gather_variable(brw);
+
    brw->vs.base.stage = MESA_SHADER_VERTEX;
    brw->gs.base.stage = MESA_SHADER_GEOMETRY;
    brw->wm.base.stage = MESA_SHADER_FRAGMENT;
@@ -894,7 +917,8 @@ brwCreateContext(gl_api api,
 
    brw->use_resource_streamer = screen->has_resource_streamer &&
       (brw_env_var_as_boolean("INTEL_USE_HW_BT", false) ||
-       brw_env_var_as_boolean("INTEL_USE_GATHER", false));
+       brw_env_var_as_boolean("INTEL_USE_GATHER", false) ||
+       brw->vs_ubo_gather || brw->gs_ubo_gather || brw->fs_ubo_gather);
 
    ctx->VertexProgram._MaintainTnlProgram = true;
    ctx->FragmentProgram._MaintainTexEnvProgram = true;
@@ -909,6 +933,16 @@ brwCreateContext(gl_api api,
    if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0)
       ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
 
+   /* The gather pool is required by the hardware to represent all combined
+    * constants gathered from various sources where it is then fed into the push
+    * constant state. There is no fixed amount how many constant
+    * states are uploaded per batch, so use the combined per-stage limits instead.
+    */
+   brw->gather_pool.size =
+      brw->ctx.Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents +
+      brw->ctx.Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents +
+      brw->ctx.Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents;
+
    if (INTEL_DEBUG & DEBUG_SHADER_TIME)
       brw_init_shader_time(brw);
 
@@ -963,7 +997,10 @@ intelDestroyContext(__DRIcontext * driContextPriv)
       drm_intel_bo_unreference(brw->wm.base.scratch_bo);
 
    gen7_reset_hw_bt_pool_offsets(brw);
+   drm_intel_bo_unreference(brw->gather_pool.bo);
    drm_intel_bo_unreference(brw->hw_bt_pool.bo);
+
+   brw->gather_pool.bo = NULL;
    brw->hw_bt_pool.bo = NULL;
 
    drm_intel_gem_context_destroy(brw->hw_ctx);
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 41ba769..33c49b7 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1192,6 +1192,9 @@ struct brw_context
    bool no_simd8;
    bool use_rep_send;
    bool use_resource_streamer;
+   bool vs_ubo_gather;
+   bool gs_ubo_gather;
+   bool fs_ubo_gather;
 
    /**
     * Some versions of Gen hardware don't do centroid interpolation correctly
@@ -1461,6 +1464,13 @@ struct brw_context
       uint32_t next_offset;
    } hw_bt_pool;
 
+   /* Internal storage used by the RS to flush and refer to constant data */
+   struct {
+      drm_intel_bo *bo;
+      uint32_t next_offset;
+      uint32_t size;
+   } gather_pool;
+
    struct {
       uint32_t state_offset;
       uint32_t blend_state_offset;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index afce8ad..c7c7e0b 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -375,6 +375,7 @@ void gen7_update_binding_table_from_array(struct brw_context *brw,
                                           int num_surfaces);
 void gen7_disable_hw_binding_tables(struct brw_context *brw);
 void gen7_reset_hw_bt_pool_offsets(struct brw_context *brw);
+void gen7_toggle_gather_constants(struct brw_context *brw, bool enable);
 
 #ifdef __cplusplus
 }
-- 
1.9.1



More information about the mesa-dev mailing list