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