[Mesa-dev] [RFC PATCH 05/12] i965: Switch on hardware-generated binding tables.

Abdiel Janulgue abdiel.janulgue at linux.intel.com
Mon Jul 8 06:16:56 PDT 2013


On Haswell hardware with resource streamer enabled, enable the on-chip hardware
binding tables. The hw-bt can be updated directly using EDIT commands.
Skip manual generation of binding tables when this is activated.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.c          |    2 +
 src/mesa/drivers/dri/i965/brw_context.h          |    1 +
 src/mesa/drivers/dri/i965/brw_defines.h          |    4 ++
 src/mesa/drivers/dri/i965/brw_state.h            |    4 ++
 src/mesa/drivers/dri/i965/brw_state_upload.c     |    3 +
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c |    4 ++
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |    4 ++
 src/mesa/drivers/dri/i965/gen7_misc_state.c      |   68 ++++++++++++++++++++++
 8 files changed, 90 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 56c42ba..ed13bc4 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -438,6 +438,8 @@ brwCreateContext(int api,
 
    brw_fs_alloc_reg_sets(brw);
 
+   brw->hw_bt_pool = 0;
+
    if (INTEL_DEBUG & DEBUG_SHADER_TIME)
       brw_init_shader_time(brw);
 
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index e250f51..26cc228 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1052,6 +1052,7 @@ struct brw_context
       } reg_sets[2];
    } wm;
 
+   drm_intel_bo *hw_bt_pool;
 
    struct {
       uint32_t state_offset;
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 04422fe..c990958 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1162,6 +1162,10 @@ enum brw_message_target {
 #define _3DSTATE_BINDING_TABLE_POINTERS_GS	0x7829 /* GEN7+ */
 #define _3DSTATE_BINDING_TABLE_POINTERS_PS	0x782A /* GEN7+ */
 
+/* Haswell hardware-generated binding tables */
+#define _3DSTATE_BINDING_TABLE_POOL_ALLOC       0x7919 /* GEN7.5+ */
+# define HSW_BINDING_TABLE_ALLOC_OFFSET         0x860  /* GEN7.5+ */
+
 #define _3DSTATE_SAMPLER_STATE_POINTERS		0x7802 /* GEN6+ */
 # define PS_SAMPLER_STATE_CHANGE				(1 << 12)
 # define GS_SAMPLER_STATE_CHANGE				(1 << 9)
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 43e5b0c..eecc1f2 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -118,6 +118,8 @@ extern const struct brw_tracked_state gen7_sol_state;
 extern const struct brw_tracked_state gen7_urb;
 extern const struct brw_tracked_state gen7_vs_state;
 extern const struct brw_tracked_state gen7_wm_state;
+extern const struct brw_tracked_state gen7_hw_binding_tables;
+extern const struct brw_tracked_state gen7_hw_bt_update;
 extern const struct brw_tracked_state haswell_cut_index;
 
 /* brw_misc_state.c */
@@ -212,6 +214,8 @@ get_attr_override(const struct brw_vue_map *vue_map, int urb_entry_read_offset,
 
 /* Haswell Resource streamer controls */
 void gen7_rs_control(struct brw_context *brw, int enable);
+void gen7_enable_hw_binding_tables(struct brw_context *brw);
+void gen7_update_hw_bt(struct brw_context *brw);
 
 /* gen7_urb.c */
 void gen7_allocate_push_constants(struct brw_context *brw);
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index b04f9af..1916979 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -191,6 +191,9 @@ static const struct brw_tracked_state *gen7_atoms[] =
    &gen6_vs_push_constants, /* Before vs_state */
    &gen6_wm_push_constants, /* Before wm_surfaces and constant_buffer */
 
+   &gen7_hw_bt_update,
+   &gen7_hw_binding_tables, /* Enable hw-generated binding tables for Haswell */
+
    /* Surface state setup.  Must come before the VS/WM unit.  The binding
     * table upload must be last.
     */
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index cbad071..605d394 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -138,6 +138,10 @@ brw_vs_upload_binding_table(struct brw_context *brw)
 {
    uint32_t *bind;
    int i;
+   struct intel_context *intel = &brw->intel;
+
+   if (intel->is_haswell)
+      return;
 
    if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
       gen7_create_shader_time_surface(brw, &brw->vs.surf_offset[SURF_INDEX_VS_SHADER_TIME]);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 27a2651..f1fb889 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -879,6 +879,10 @@ brw_upload_wm_binding_table(struct brw_context *brw)
 {
    uint32_t *bind;
    int i;
+   struct intel_context *intel = &brw->intel;
+
+   if (intel->is_haswell)
+      return;
 
    if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
       gen7_create_shader_time_surface(brw, &brw->wm.surf_offset[SURF_INDEX_WM_SHADER_TIME]);
diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
index 0c96681..11464a2 100644
--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
@@ -148,3 +148,71 @@ gen7_rs_control(struct brw_context *brw, int enable)
    OUT_BATCH(MI_RS_CONTROL | enable);
    ADVANCE_BATCH();
 }
+
+void
+gen7_enable_hw_binding_tables(struct brw_context *brw)
+{
+   struct intel_context *intel = &brw->intel;
+
+   if (!intel->is_haswell)
+      return;
+
+   if (brw->hw_bt_pool) {
+      BEGIN_BATCH(3);
+      OUT_BATCH(_3DSTATE_BINDING_TABLE_POOL_ALLOC << 16 | (3 - 2));
+      OUT_RELOC(brw->hw_bt_pool, I915_GEM_DOMAIN_SAMPLER, 0,
+                HSW_BINDING_TABLE_ALLOC_OFFSET);
+      OUT_RELOC(brw->hw_bt_pool, I915_GEM_DOMAIN_SAMPLER, 0,
+                brw->hw_bt_pool->size);
+      ADVANCE_BATCH();
+      /* Pipe control workaround */
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+      OUT_BATCH(PIPE_CONTROL_STATE_CACHE_INVALIDATE);
+      OUT_BATCH(0); /* address */
+      OUT_BATCH(0); /* write data */
+      ADVANCE_BATCH();
+   }
+}
+
+void
+gen7_update_hw_bt(struct brw_context *brw)
+{
+   struct intel_context *intel = &brw->intel;
+
+   if (!intel->is_haswell)
+      return;
+
+   brw->vs.bind_bo_offset = brw->wm.bind_bo_offset + 64;
+   brw->wm.bind_bo_offset = brw->vs.bind_bo_offset + 64;
+
+   if (!brw->hw_bt_pool ||
+       (brw->hw_bt_pool &&
+        (brw->vs.bind_bo_offset > brw->hw_bt_pool->size - 4))) {
+
+      brw->vs.bind_bo_offset = 0;
+      brw->wm.bind_bo_offset = 64;
+
+      drm_intel_bo_unreference(brw->hw_bt_pool);
+      brw->hw_bt_pool = drm_intel_bo_alloc(intel->bufmgr, "hw_bt",
+                                              131072, 4096);
+   }
+}
+
+const struct brw_tracked_state gen7_hw_binding_tables = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_BATCH,
+      .cache = 0
+   },
+   .emit = gen7_enable_hw_binding_tables
+};
+
+const struct brw_tracked_state gen7_hw_bt_update = {
+   .dirty = {
+      .mesa = _NEW_TEXTURE,
+      .brw = 0,
+      .cache = 0
+   },
+   .emit = gen7_update_hw_bt
+};
-- 
1.7.9.5



More information about the mesa-dev mailing list