[Mesa-dev] [PATCH 4/7] i965: Make a brw_stage_prog_data for storing the SURF_INDEX information.

Eric Anholt eric at anholt.net
Fri Oct 4 15:44:55 PDT 2013


It would be nice to be able to pack our binding table so that programs
that use 1 render target don't upload an extra BRW_MAX_DRAW_BUFFERS - 1
binding table entries.  To do that, we need the compiled program to have
information on where its surfaces go.
---

I consistently named the structure members "*_start" even if there's
only one of them.  I could go either way on naming these.

 src/mesa/drivers/dri/i965/brw_binding_tables.c    | 47 +++++-----------
 src/mesa/drivers/dri/i965/brw_context.h           | 42 +++++++++++++--
 src/mesa/drivers/dri/i965/brw_fs.cpp              | 19 ++++++-
 src/mesa/drivers/dri/i965/brw_fs.h                |  1 +
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp    | 21 ++++----
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp      |  3 +-
 src/mesa/drivers/dri/i965/brw_gs_surface_state.c  |  6 +--
 src/mesa/drivers/dri/i965/brw_state.h             |  6 ---
 src/mesa/drivers/dri/i965/brw_vec4.cpp            | 16 +++++-
 src/mesa/drivers/dri/i965/brw_vec4.h              |  1 +
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp  | 15 +++---
 src/mesa/drivers/dri/i965/brw_vec4_gs.c           |  2 +
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp    |  4 +-
 src/mesa/drivers/dri/i965/brw_vec4_vp.cpp         |  2 +-
 src/mesa/drivers/dri/i965/brw_vs.c                |  2 +
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c  | 14 ++---
 src/mesa/drivers/dri/i965/brw_wm.c                |  3 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c  | 65 +++++++++++------------
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |  7 ++-
 19 files changed, 161 insertions(+), 115 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_binding_tables.c b/src/mesa/drivers/dri/i965/brw_binding_tables.c
index 9d15bac..878e20d 100644
--- a/src/mesa/drivers/dri/i965/brw_binding_tables.c
+++ b/src/mesa/drivers/dri/i965/brw_binding_tables.c
@@ -50,19 +50,16 @@
  * This copies brw_stage_state::surf_offset[] into the indirect state section
  * of the batchbuffer (allocated by brw_state_batch()).
  */
-void
+static void
 brw_upload_binding_table(struct brw_context *brw,
                          GLbitfield brw_new_binding_table,
-                         struct brw_stage_state *stage_state,
-                         unsigned binding_table_entries,
-                         int shader_time_surf_index)
+                         struct brw_stage_state *stage_state)
 {
-   if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
-      gen7_create_shader_time_surface(brw, &stage_state->surf_offset[shader_time_surf_index]);
-   }
+   /* CACHE_NEW_*_PROG */
+   struct brw_stage_prog_data *prog_data = stage_state->prog_data;
 
    /* If there are no surfaces, skip making the binding table altogether. */
-   if (binding_table_entries == 0) {
+   if (prog_data->binding_table.size == 0) {
       if (stage_state->bind_bo_offset != 0) {
          brw->state.dirty.brw |= brw_new_binding_table;
          stage_state->bind_bo_offset = 0;
@@ -70,14 +67,16 @@ brw_upload_binding_table(struct brw_context *brw,
       return;
    }
 
-   size_t table_size_in_bytes = binding_table_entries * sizeof(uint32_t);
+   if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
+      gen7_create_shader_time_surface(brw, &stage_state->surf_offset[prog_data->binding_table.shader_time_start]);
+   }
 
    uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
-                                    table_size_in_bytes, 32,
+                                    prog_data->binding_table.size, 32,
                                     &stage_state->bind_bo_offset);
 
    /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */
-   memcpy(bind, stage_state->surf_offset, table_size_in_bytes);
+   memcpy(bind, stage_state->surf_offset, prog_data->binding_table.size);
 
    brw->state.dirty.brw |= brw_new_binding_table;
 }
@@ -91,14 +90,7 @@ brw_upload_binding_table(struct brw_context *brw,
 static void
 brw_vs_upload_binding_table(struct brw_context *brw)
 {
-   struct brw_stage_state *stage_state = &brw->vs.base;
-   /* CACHE_NEW_VS_PROG */
-   const struct brw_vec4_prog_data *prog_data = &brw->vs.prog_data->base;
-
-   /* BRW_NEW_SURFACES and BRW_NEW_VS_CONSTBUF */
-   brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, stage_state,
-                            prog_data->binding_table_size,
-                            SURF_INDEX_VEC4_SHADER_TIME);
+   brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, &brw->vs.base);
 }
 
 const struct brw_tracked_state brw_vs_binding_table = {
@@ -117,12 +109,7 @@ const struct brw_tracked_state brw_vs_binding_table = {
 static void
 brw_upload_wm_binding_table(struct brw_context *brw)
 {
-   struct brw_stage_state *stage_state = &brw->wm.base;
-
-   /* BRW_NEW_SURFACES and CACHE_NEW_WM_PROG */
-   brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, stage_state,
-                            brw->wm.prog_data->binding_table_size,
-                            SURF_INDEX_WM_SHADER_TIME);
+   brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, &brw->wm.base);
 }
 
 const struct brw_tracked_state brw_wm_binding_table = {
@@ -138,19 +125,11 @@ const struct brw_tracked_state brw_wm_binding_table = {
 static void
 brw_gs_upload_binding_table(struct brw_context *brw)
 {
-   struct brw_stage_state *stage_state = &brw->gs.base;
-
    /* If there's no GS, skip changing anything. */
    if (!brw->gs.prog_data)
       return;
 
-   /* CACHE_NEW_GS_PROG */
-   const struct brw_vec4_prog_data *prog_data = &brw->gs.prog_data->base;
-
-   /* BRW_NEW_SURFACES and BRW_NEW_GS_CONSTBUF */
-   brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, stage_state,
-                            prog_data->binding_table_size,
-                            SURF_INDEX_VEC4_SHADER_TIME);
+   brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, &brw->gs.base);
 }
 
 const struct brw_tracked_state brw_gs_binding_table = {
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index eb9d93c..8c991a9 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -305,6 +305,27 @@ struct brw_shader {
    struct exec_list *ir;
 };
 
+/* Note: If adding fields that need anything besides a normal memcmp() for
+ * comparing them, be sure to go fix the the stage-specific
+ * prog_data_compare().
+ */
+struct brw_stage_prog_data {
+   struct {
+      /** size in bytes of our binding table. */
+      uint32_t size;
+
+      /** @{
+       * surface indices for the various groups of surfaces
+       */
+      uint32_t pull_constants_start;
+      uint32_t texture_start;
+      uint32_t gather_texture_start;
+      uint32_t ubo_start;
+      uint32_t shader_time_start;
+      /** @} */
+   } binding_table;
+};
+
 /* Data about a particular attempt to compile a program.  Note that
  * there can be many of these, each in a different GL state
  * corresponding to a different brw_wm_prog_key struct, with different
@@ -314,6 +335,8 @@ struct brw_shader {
  * struct!
  */
 struct brw_wm_prog_data {
+   struct brw_stage_prog_data base;
+
    GLuint curb_read_length;
    GLuint num_varying_inputs;
 
@@ -323,7 +346,13 @@ struct brw_wm_prog_data {
    GLuint reg_blocks_16;
    GLuint total_scratch;
 
-   unsigned binding_table_size;
+   struct {
+      /** @{
+       * surface indices the WM-specific surfaces
+       */
+      uint32_t render_target_start;
+      /** @} */
+   } binding_table;
 
    GLuint nr_params;       /**< number of float params/constants */
    GLuint nr_pull_params;
@@ -521,6 +550,7 @@ struct brw_ff_gs_prog_data {
  * this struct!
  */
 struct brw_vec4_prog_data {
+   struct brw_stage_prog_data base;
    struct brw_vue_map vue_map;
 
    /**
@@ -542,8 +572,6 @@ struct brw_vec4_prog_data {
     */
    GLuint urb_entry_size;
 
-   unsigned binding_table_size;
-
    /* These pointers must appear last.  See brw_vec4_prog_data_compare(). */
    const float **param;
    const float **pull_param;
@@ -874,10 +902,13 @@ struct brw_query_object {
 
 
 /**
- * Data shared between brw_context::vs and brw_context::gs
+ * Data shared between each programmable stage in the pipeline (vs, gs, and
+ * wm).
  */
 struct brw_stage_state
 {
+   struct brw_stage_prog_data *prog_data;
+
    /**
     * Optional scratch buffer used to store spilled register values and
     * variably-indexed GRF arrays.
@@ -1503,7 +1534,8 @@ brw_update_sol_surface(struct brw_context *brw,
                        unsigned stride_dwords, unsigned offset_dwords);
 void brw_upload_ubo_surfaces(struct brw_context *brw,
 			     struct gl_shader *shader,
-			     uint32_t *surf_offsets);
+                             struct brw_stage_state *stage_state,
+                             struct brw_stage_prog_data *prog_data);
 
 /* brw_surface_formats.c */
 bool brw_is_hiz_depth_format(struct brw_context *ctx, gl_format format);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 89eb33e..b00ebc0 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1673,7 +1673,7 @@ fs_visitor::move_uniform_array_access_to_pull_constants()
          base_ir = inst->ir;
          current_annotation = inst->annotation;
 
-         fs_reg surf_index = fs_reg((unsigned)SURF_INDEX_FRAG_CONST_BUFFER);
+         fs_reg surf_index = fs_reg(c->prog_data.base.binding_table.pull_constants_start);
          fs_reg temp = fs_reg(this, glsl_type::float_type);
          exec_list list = VARYING_PULL_CONSTANT_LOAD(temp,
                                                      surf_index,
@@ -1757,7 +1757,7 @@ fs_visitor::setup_pull_constants()
          assert(!inst->src[i].reladdr);
 
 	 fs_reg dst = fs_reg(this, glsl_type::float_type);
-	 fs_reg index = fs_reg((unsigned)SURF_INDEX_FRAG_CONST_BUFFER);
+	 fs_reg index = fs_reg(c->prog_data.base.binding_table.pull_constants_start);
 	 fs_reg offset = fs_reg((unsigned)(pull_index * 4) & ~15);
 	 fs_inst *pull =
             new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
@@ -2940,12 +2940,27 @@ fs_visitor::setup_payload_gen6()
    }
 }
 
+void
+fs_visitor::assign_binding_table_offsets()
+{
+   c->prog_data.binding_table.render_target_start = SURF_INDEX_DRAW(0);
+   c->prog_data.base.binding_table.texture_start = SURF_INDEX_TEXTURE(0);
+   c->prog_data.base.binding_table.ubo_start = SURF_INDEX_WM_UBO(0);
+   c->prog_data.base.binding_table.shader_time_start = SURF_INDEX_WM_SHADER_TIME;
+   c->prog_data.base.binding_table.gather_texture_start = SURF_INDEX_GATHER_TEXTURE(0);
+   c->prog_data.base.binding_table.pull_constants_start = SURF_INDEX_FRAG_CONST_BUFFER;
+
+   /* c->prog_data.base.binding_table.size will be set by mark_surface_used. */
+}
+
 bool
 fs_visitor::run()
 {
    sanity_param_count = fp->Base.Parameters->NumParameters;
    uint32_t orig_nr_params = c->prog_data.nr_params;
 
+   assign_binding_table_offsets();
+
    if (brw->gen >= 6)
       setup_payload_gen6();
    else
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index cf6379c..88e885c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -270,6 +270,7 @@ public:
                                         uint32_t const_offset);
 
    bool run();
+   void assign_binding_table_offsets();
    void setup_payload_gen4();
    void setup_payload_gen6();
    void assign_curb_setup();
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 1e27152..36513ba 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -63,8 +63,8 @@ fs_generator::mark_surface_used(unsigned surf_index)
 {
    assert(surf_index < BRW_MAX_WM_SURFACES);
 
-   c->prog_data.binding_table_size =
-      MAX2(c->prog_data.binding_table_size, surf_index + 1);
+   c->prog_data.base.binding_table.size =
+      MAX2(c->prog_data.base.binding_table.size, (surf_index + 1) * 4);
 }
 
 void
@@ -174,18 +174,20 @@ fs_generator::generate_fb_write(fs_inst *inst)
 
    brw_pop_insn_state(p);
 
+   uint32_t surf_index =
+      c->prog_data.binding_table.render_target_start + inst->target;
    brw_fb_WRITE(p,
 		dispatch_width,
 		inst->base_mrf,
 		implied_header,
 		msg_control,
-		SURF_INDEX_DRAW(inst->target),
+		surf_index,
 		inst->mlen,
 		0,
 		eot,
 		inst->header_present);
 
-   mark_surface_used(SURF_INDEX_DRAW(inst->target));
+   mark_surface_used(surf_index);
 }
 
 /* Computes the integer pixel x,y values from the origin.
@@ -522,9 +524,9 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src
       src = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
    }
 
-   uint32_t surface_index = inst->opcode == SHADER_OPCODE_TG4
-      ? SURF_INDEX_GATHER_TEXTURE(inst->sampler)
-      : SURF_INDEX_TEXTURE(inst->sampler);
+   uint32_t surface_index = (inst->opcode == SHADER_OPCODE_TG4
+      ? c->prog_data.base.binding_table.gather_texture_start
+      : c->prog_data.base.binding_table.texture_start) + inst->sampler;
 
    brw_SAMPLE(p,
 	      retype(dst, BRW_REGISTER_TYPE_UW),
@@ -1125,10 +1127,11 @@ fs_generator::generate_shader_time_add(fs_inst *inst,
     */
    brw_MOV(p, payload_offset, offset);
    brw_MOV(p, payload_value, value);
-   brw_shader_time_add(p, payload, SURF_INDEX_WM_SHADER_TIME);
+   brw_shader_time_add(p, payload,
+                       c->prog_data.base.binding_table.shader_time_start);
    brw_pop_insn_state(p);
 
-   mark_surface_used(SURF_INDEX_WM_SHADER_TIME);
+   mark_surface_used(c->prog_data.base.binding_table.shader_time_start);
 }
 
 void
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index cf97f5e..8fa7f9d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -674,7 +674,8 @@ fs_visitor::visit(ir_expression *ir)
        */
       ir_constant *uniform_block = ir->operands[0]->as_constant();
       ir_constant *const_offset = ir->operands[1]->as_constant();
-      fs_reg surf_index = fs_reg((unsigned)SURF_INDEX_WM_UBO(uniform_block->value.u[0]));
+      fs_reg surf_index = fs_reg(c->prog_data.base.binding_table.ubo_start +
+                                 uniform_block->value.u[0]);
       if (const_offset) {
          fs_reg packed_consts = fs_reg(this, glsl_type::float_type);
          packed_consts.type = result.type;
diff --git a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
index d0ce412..55152c2 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
@@ -67,7 +67,6 @@ static void
 brw_upload_gs_ubo_surfaces(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
-   struct brw_stage_state *stage_state = &brw->gs.base;
 
    /* _NEW_PROGRAM */
    struct gl_shader_program *prog = ctx->Shader.CurrentGeometryProgram;
@@ -75,15 +74,16 @@ brw_upload_gs_ubo_surfaces(struct brw_context *brw)
    if (!prog)
       return;
 
+   /* CACHE_NEW_GS_PROG */
    brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
-			   &stage_state->surf_offset[SURF_INDEX_VEC4_UBO(0)]);
+			   &brw->gs.base, &brw->gs.prog_data->base.base);
 }
 
 const struct brw_tracked_state brw_gs_ubo_surfaces = {
    .dirty = {
       .mesa = _NEW_PROGRAM,
       .brw = BRW_NEW_BATCH | BRW_NEW_UNIFORM_BUFFER,
-      .cache = 0,
+      .cache = CACHE_NEW_GS_PROG,
    },
    .emit = brw_upload_gs_ubo_surfaces,
 };
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index ec64328..0d8503a 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -239,12 +239,6 @@ brw_upload_vec4_pull_constants(struct brw_context *brw,
                                const struct gl_program *prog,
                                struct brw_stage_state *stage_state,
                                const struct brw_vec4_prog_data *prog_data);
-void
-brw_upload_binding_table(struct brw_context *brw,
-                         GLbitfield brw_new_binding_table,
-                         struct brw_stage_state *stage_state,
-                         unsigned binding_table_entries,
-                         int shader_time_surf_index);
 
 /* gen7_vs_state.c */
 void
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 75c3d34..1f34cf4 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1405,6 +1405,18 @@ vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type,
    emit(SHADER_OPCODE_SHADER_TIME_ADD, dst_reg(), src_reg(dst));
 }
 
+void
+vec4_visitor::assign_binding_table_offsets()
+{
+   prog_data->base.binding_table.texture_start = SURF_INDEX_VEC4_TEXTURE(0);
+   prog_data->base.binding_table.ubo_start = SURF_INDEX_VEC4_UBO(0);
+   prog_data->base.binding_table.shader_time_start = SURF_INDEX_VEC4_SHADER_TIME;
+   prog_data->base.binding_table.gather_texture_start = SURF_INDEX_VEC4_GATHER_TEXTURE(0);
+   prog_data->base.binding_table.pull_constants_start = SURF_INDEX_VEC4_CONST_BUFFER;
+
+   /* prog_data->base.binding_table.size will be set by mark_surface_used. */
+}
+
 bool
 vec4_visitor::run()
 {
@@ -1413,6 +1425,8 @@ vec4_visitor::run()
    if (INTEL_DEBUG & DEBUG_SHADER_TIME)
       emit_shader_time_begin();
 
+   assign_binding_table_offsets();
+
    emit_prolog();
 
    /* Generate VS IR for main().  (the visitor only descends into
@@ -1578,7 +1592,7 @@ bool
 brw_vec4_prog_data_compare(const struct brw_vec4_prog_data *a,
                            const struct brw_vec4_prog_data *b)
 {
-   /* Compare all the struct up to the pointers. */
+   /* Compare all the struct (including the base) up to the pointers. */
    if (memcmp(a, b, offsetof(struct brw_vec4_prog_data, param)))
       return false;
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index cebf573..d75c46a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -332,6 +332,7 @@ public:
    bool run(void);
    void fail(const char *msg, ...);
 
+   void assign_binding_table_offsets();
    int virtual_grf_alloc(int size);
    void setup_uniform_clipplane_values();
    void setup_uniform_values(ir_variable *ir);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index 00efb10..4cac292 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -157,8 +157,8 @@ vec4_generator::mark_surface_used(unsigned surf_index)
 {
    assert(surf_index < BRW_MAX_VEC4_SURFACES);
 
-   prog_data->binding_table_size = MAX2(prog_data->binding_table_size,
-                                        surf_index + 1);
+   prog_data->base.binding_table.size = MAX2(prog_data->base.binding_table.size,
+                                             (surf_index + 1) * 4);
 }
 
 void
@@ -385,9 +385,9 @@ vec4_generator::generate_tex(vec4_instruction *inst,
       break;
    }
 
-   uint32_t surface_index = inst->opcode == SHADER_OPCODE_TG4
-      ? SURF_INDEX_VEC4_GATHER_TEXTURE(inst->sampler)
-      : SURF_INDEX_VEC4_TEXTURE(inst->sampler);
+   uint32_t surface_index = (inst->opcode == SHADER_OPCODE_TG4
+      ? prog_data->base.binding_table.gather_texture_start
+      : prog_data->base.binding_table.texture_start) + inst->sampler;
 
    brw_SAMPLE(p,
 	      dst,
@@ -1100,8 +1100,9 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
       break;
 
    case SHADER_OPCODE_SHADER_TIME_ADD:
-      brw_shader_time_add(p, src[0], SURF_INDEX_VEC4_SHADER_TIME);
-      mark_surface_used(SURF_INDEX_VEC4_SHADER_TIME);
+      brw_shader_time_add(p, src[0],
+                          prog_data->base.binding_table.shader_time_start);
+      mark_surface_used(prog_data->base.binding_table.shader_time_start);
       break;
 
    case VS_OPCODE_UNPACK_FLAGS_SIMD4X2:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs.c b/src/mesa/drivers/dri/i965/brw_vec4_gs.c
index 967e384..b48422c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs.c
@@ -286,6 +286,8 @@ brw_upload_gs_prog(struct brw_context *brw)
                                 gp, &key);
       assert(success);
    }
+   brw->gs.base.prog_data = &brw->gs.prog_data->base.base;
+
    if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out,
               sizeof(brw->vue_map_geom_out)) != 0) {
       brw->vue_map_geom_out = brw->gs.prog_data->base.vue_map;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 9e6cc78..150bc31 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1552,7 +1552,7 @@ vec4_visitor::visit(ir_expression *ir)
       src_reg packed_consts = src_reg(this, glsl_type::vec4_type);
       packed_consts.type = result.type;
       src_reg surf_index =
-         src_reg(SURF_INDEX_VEC4_UBO(uniform_block->value.u[0]));
+         src_reg(prog_data->base.binding_table.ubo_start + uniform_block->value.u[0]);
       if (const_offset_ir) {
          offset = src_reg(const_offset / 16);
       } else {
@@ -2987,7 +2987,7 @@ vec4_visitor::emit_pull_constant_load(vec4_instruction *inst,
 				      int base_offset)
 {
    int reg_offset = base_offset + orig_src.reg_offset;
-   src_reg index = src_reg((unsigned)SURF_INDEX_VEC4_CONST_BUFFER);
+   src_reg index = src_reg(prog_data->base.binding_table.pull_constants_start);
    src_reg offset = get_pull_constant_offset(inst, orig_src.reladdr, reg_offset);
    vec4_instruction *load;
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_vp.cpp b/src/mesa/drivers/dri/i965/brw_vec4_vp.cpp
index d2dc253..1f3d75c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_vp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_vp.cpp
@@ -560,7 +560,7 @@ vec4_vs_visitor::get_vp_src_reg(const prog_src_register &src)
       #endif
 
          result = src_reg(this, glsl_type::vec4_type);
-         src_reg surf_index = src_reg(unsigned(SURF_INDEX_VEC4_CONST_BUFFER));
+         src_reg surf_index = src_reg(unsigned(prog_data->base.binding_table.pull_constants_start));
          vec4_instruction *load =
             new(mem_ctx) vec4_instruction(this, VS_OPCODE_PULL_CONSTANT_LOAD,
                                           dst_reg(result), surf_index, reladdr);
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 5d4423f..c0ae3ed 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -488,6 +488,8 @@ static void brw_upload_vs_prog(struct brw_context *brw)
       (void) success;
       assert(success);
    }
+   brw->vs.base.prog_data = &brw->vs.prog_data->base.base;
+
    if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out,
               sizeof(brw->vue_map_geom_out)) != 0) {
       brw->vue_map_vs = brw->vs.prog_data->base.vue_map;
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 2c5d06f..7e4bcc0 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -44,6 +44,7 @@ brw_upload_vec4_pull_constants(struct brw_context *brw,
                                const struct brw_vec4_prog_data *prog_data)
 {
    int i;
+   uint32_t surf_index = prog_data->base.binding_table.pull_constants_start;
 
    /* Updates the ParamaterValues[i] pointers for all parameters of the
     * basic type of PROGRAM_STATE_VAR.
@@ -54,7 +55,7 @@ brw_upload_vec4_pull_constants(struct brw_context *brw,
       if (stage_state->const_bo) {
 	 drm_intel_bo_unreference(stage_state->const_bo);
 	 stage_state->const_bo = NULL;
-	 stage_state->surf_offset[SURF_INDEX_VEC4_CONST_BUFFER] = 0;
+	 stage_state->surf_offset[surf_index] = 0;
 	 brw->state.dirty.brw |= brw_new_constbuf;
       }
       return;
@@ -84,9 +85,9 @@ brw_upload_vec4_pull_constants(struct brw_context *brw,
 
    drm_intel_gem_bo_unmap_gtt(stage_state->const_bo);
 
-   const int surf = SURF_INDEX_VEC4_CONST_BUFFER;
    brw->vtbl.create_constant_surface(brw, stage_state->const_bo, 0, size,
-                                     &stage_state->surf_offset[surf], false);
+                                     &stage_state->surf_offset[surf_index],
+                                     false);
 
    brw->state.dirty.brw |= brw_new_constbuf;
 }
@@ -127,8 +128,6 @@ const struct brw_tracked_state brw_vs_pull_constants = {
 static void
 brw_upload_vs_ubo_surfaces(struct brw_context *brw)
 {
-   struct brw_stage_state *stage_state = &brw->vs.base;
-
    struct gl_context *ctx = &brw->ctx;
    /* _NEW_PROGRAM */
    struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram;
@@ -136,15 +135,16 @@ brw_upload_vs_ubo_surfaces(struct brw_context *brw)
    if (!prog)
       return;
 
+   /* CACHE_NEW_VS_PROG */
    brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_VERTEX],
-			   &stage_state->surf_offset[SURF_INDEX_VEC4_UBO(0)]);
+			   &brw->vs.base, &brw->vs.prog_data->base.base);
 }
 
 const struct brw_tracked_state brw_vs_ubo_surfaces = {
    .dirty = {
       .mesa = _NEW_PROGRAM,
       .brw = BRW_NEW_BATCH | BRW_NEW_UNIFORM_BUFFER,
-      .cache = 0,
+      .cache = CACHE_NEW_VS_PROG,
    },
    .emit = brw_upload_vs_ubo_surfaces,
 };
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index e0969dd..ee6573c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -108,7 +108,7 @@ brw_wm_prog_data_compare(const void *in_a, const void *in_b)
    const struct brw_wm_prog_data *a = in_a;
    const struct brw_wm_prog_data *b = in_b;
 
-   /* Compare all the struct up to the pointers. */
+   /* Compare all the struct (including the base) up to the pointers. */
    if (memcmp(a, b, offsetof(struct brw_wm_prog_data, param)))
       return false;
 
@@ -511,6 +511,7 @@ brw_upload_wm_prog(struct brw_context *brw)
       (void) success;
       assert(success);
    }
+   brw->wm.base.prog_data = &brw->wm.prog_data->base;
 }
 
 
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 6e91857..e1b5cfc 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -424,7 +424,8 @@ brw_upload_wm_pull_constants(struct brw_context *brw)
       (struct brw_fragment_program *) brw->fragment_program;
    struct gl_program_parameter_list *params = fp->program.Base.Parameters;
    const int size = brw->wm.prog_data->nr_pull_params * sizeof(float);
-   const int surf_index = SURF_INDEX_FRAG_CONST_BUFFER;
+   const int surf_index =
+      brw->wm.prog_data->base.binding_table.pull_constants_start;
    float *constants;
    unsigned int i;
 
@@ -496,12 +497,14 @@ brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
    drm_intel_bo *bo = NULL;
    unsigned pitch_minus_1 = 0;
    uint32_t multisampling_state = 0;
+   uint32_t surf_index =
+      brw->wm.prog_data->binding_table.render_target_start + unit;
 
    /* _NEW_BUFFERS */
    const struct gl_framebuffer *fb = ctx->DrawBuffer;
 
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
-                          &brw->wm.base.surf_offset[SURF_INDEX_DRAW(unit)]);
+                          &brw->wm.base.surf_offset[surf_index]);
 
    if (fb->Visual.samples > 1) {
       /* On Gen6, null render targets seem to cause GPU hangs when
@@ -554,7 +557,7 @@ brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
 
    if (bo) {
       drm_intel_bo_emit_reloc(brw->batch.bo,
-                              brw->wm.base.surf_offset[SURF_INDEX_DRAW(unit)] + 4,
+                              brw->wm.base.surf_offset[surf_index] + 4,
                               bo, 0,
                               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
    }
@@ -580,6 +583,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
    uint32_t format = 0;
    /* _NEW_BUFFERS */
    gl_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));
+   uint32_t surf_index =
+      brw->wm.prog_data->binding_table.render_target_start + unit;
 
    assert(!layered);
 
@@ -603,7 +608,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
    region = irb->mt->region;
 
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
-                          &brw->wm.base.surf_offset[SURF_INDEX_DRAW(unit)]);
+                          &brw->wm.base.surf_offset[surf_index]);
 
    format = brw->render_target_format[rb_format];
    if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
@@ -659,7 +664,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
    }
 
    drm_intel_bo_emit_reloc(brw->batch.bo,
-			   brw->wm.base.surf_offset[SURF_INDEX_DRAW(unit)] + 4,
+			   brw->wm.base.surf_offset[surf_index] + 4,
 			   region->bo,
 			   surf[1] - region->bo->offset,
 			   I915_GEM_DOMAIN_RENDER,
@@ -715,7 +720,7 @@ const struct brw_tracked_state gen6_renderbuffer_surfaces = {
 static void
 update_stage_texture_surfaces(struct brw_context *brw,
                               const struct gl_program *prog,
-                              uint32_t *surf_offset,
+                              struct brw_stage_state *stage_state,
                               bool for_gather)
 {
    if (!prog)
@@ -723,8 +728,13 @@ update_stage_texture_surfaces(struct brw_context *brw,
 
    struct gl_context *ctx = &brw->ctx;
 
-   unsigned num_samplers = _mesa_fls(prog->SamplersUsed);
+   uint32_t *surf_offset = stage_state->surf_offset;
+   if (for_gather)
+      surf_offset += stage_state->prog_data->binding_table.gather_texture_start;
+   else
+      surf_offset += stage_state->prog_data->binding_table.texture_start;
 
+   unsigned num_samplers = _mesa_fls(prog->SamplersUsed);
    for (unsigned s = 0; s < num_samplers; s++) {
       surf_offset[s] = 0;
 
@@ -756,37 +766,19 @@ brw_update_texture_surfaces(struct brw_context *brw)
    struct gl_program *fs = (struct gl_program *) brw->fragment_program;
 
    /* _NEW_TEXTURE */
-   update_stage_texture_surfaces(brw, vs,
-                                 brw->vs.base.surf_offset +
-                                 SURF_INDEX_VEC4_TEXTURE(0),
-                                 false);
-   update_stage_texture_surfaces(brw, gs,
-                                 brw->gs.base.surf_offset +
-                                 SURF_INDEX_VEC4_TEXTURE(0),
-                                 false);
-   update_stage_texture_surfaces(brw, fs,
-                                 brw->wm.base.surf_offset +
-                                 SURF_INDEX_TEXTURE(0),
-                                 false);
+   update_stage_texture_surfaces(brw, vs, &brw->vs.base, false);
+   update_stage_texture_surfaces(brw, gs, &brw->gs.base, false);
+   update_stage_texture_surfaces(brw, fs, &brw->wm.base, false);
 
    /* emit alternate set of surface state for gather. this
     * allows the surface format to be overriden for only the
     * gather4 messages. */
    if (vs && vs->UsesGather)
-      update_stage_texture_surfaces(brw, vs,
-                                    brw->vs.base.surf_offset +
-                                    SURF_INDEX_VEC4_GATHER_TEXTURE(0),
-                                    true);
+      update_stage_texture_surfaces(brw, vs, &brw->vs.base, true);
    if (gs && gs->UsesGather)
-      update_stage_texture_surfaces(brw, gs,
-                                    brw->gs.base.surf_offset +
-                                    SURF_INDEX_VEC4_GATHER_TEXTURE(0),
-                                    true);
+      update_stage_texture_surfaces(brw, gs, &brw->gs.base, true);
    if (fs && fs->UsesGather)
-      update_stage_texture_surfaces(brw, fs,
-                                    brw->wm.base.surf_offset +
-                                    SURF_INDEX_GATHER_TEXTURE(0),
-                                    true);
+      update_stage_texture_surfaces(brw, fs, &brw->wm.base, true);
 
    brw->state.dirty.brw |= BRW_NEW_SURFACES;
 }
@@ -806,13 +798,17 @@ const struct brw_tracked_state brw_texture_surfaces = {
 void
 brw_upload_ubo_surfaces(struct brw_context *brw,
 			struct gl_shader *shader,
-			uint32_t *surf_offsets)
+                        struct brw_stage_state *stage_state,
+                        struct brw_stage_prog_data *prog_data)
 {
    struct gl_context *ctx = &brw->ctx;
 
    if (!shader)
       return;
 
+   uint32_t *surf_offsets =
+      &stage_state->surf_offset[prog_data->binding_table.ubo_start];
+
    for (int i = 0; i < shader->NumUniformBlocks; i++) {
       struct gl_uniform_buffer_binding *binding;
       struct intel_buffer_object *intel_bo;
@@ -845,15 +841,16 @@ brw_upload_wm_ubo_surfaces(struct brw_context *brw)
    if (!prog)
       return;
 
+   /* CACHE_NEW_WM_PROG */
    brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
-			   &brw->wm.base.surf_offset[SURF_INDEX_WM_UBO(0)]);
+                           &brw->wm.base, &brw->wm.prog_data->base);
 }
 
 const struct brw_tracked_state brw_wm_ubo_surfaces = {
    .dirty = {
       .mesa = _NEW_PROGRAM,
       .brw = BRW_NEW_BATCH | BRW_NEW_UNIFORM_BUFFER,
-      .cache = 0,
+      .cache = CACHE_NEW_WM_PROG,
    },
    .emit = brw_upload_wm_ubo_surfaces,
 };
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 564ac76..4488d48 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -451,9 +451,11 @@ gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
 
    /* _NEW_BUFFERS */
    const struct gl_framebuffer *fb = ctx->DrawBuffer;
+   uint32_t surf_index =
+      brw->wm.prog_data->binding_table.render_target_start + unit;
 
    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32,
-                                    &brw->wm.base.surf_offset[SURF_INDEX_DRAW(unit)]);
+                                    &brw->wm.base.surf_offset[surf_index]);
    memset(surf, 0, 8 * 4);
 
    /* From the Ivybridge PRM, Volume 4, Part 1, page 65,
@@ -495,7 +497,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
    GLenum gl_target = rb->TexImage ?
                          rb->TexImage->TexObject->Target : GL_TEXTURE_2D;
 
-   uint32_t surf_index = SURF_INDEX_DRAW(unit);
+   uint32_t surf_index =
+      brw->wm.prog_data->binding_table.render_target_start + unit;
 
    uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32,
                                     &brw->wm.base.surf_offset[surf_index]);
-- 
1.8.4.rc3



More information about the mesa-dev mailing list