diff options
author | Eric Anholt <eric@anholt.net> | 2012-02-15 14:15:14 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2012-02-21 11:54:14 -0800 |
commit | f9c3ea32cd9b243050ee16f10d6eb9d9c8b3a8ea (patch) | |
tree | bc8d85b12d70377ce22fa3444e22e2cffec64120 /src/mesa/drivers/dri/i965/gen6_sol.c | |
parent | 07e00b3040d6da381595c65db5afe597f20d99fc (diff) |
i965: Split the gen6 GS binding table to a separate table.
Improves VS state change microbenchmark performance by 7.08729% +/-
1.22289% (n=10) on gen7, because we don't upload the 64 dwords of
unused binding table any more.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/mesa/drivers/dri/i965/gen6_sol.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_sol.c | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c index 41923b7f527..fbd8e71631f 100644 --- a/src/mesa/drivers/dri/i965/gen6_sol.c +++ b/src/mesa/drivers/dri/i965/gen6_sol.c @@ -30,6 +30,7 @@ #include "brw_context.h" #include "intel_batchbuffer.h" #include "brw_defines.h" +#include "brw_state.h" static void gen6_update_sol_surfaces(struct brw_context *brw) @@ -54,11 +55,11 @@ gen6_update_sol_surfaces(struct brw_context *brw) xfb_obj->Offset[buffer] / 4 + linked_xfb_info->Outputs[i].DstOffset; brw_update_sol_surface( - brw, xfb_obj->Buffers[buffer], &brw->bind.surf_offset[surf_index], + brw, xfb_obj->Buffers[buffer], &brw->gs.surf_offset[surf_index], linked_xfb_info->Outputs[i].NumComponents, linked_xfb_info->BufferStride[buffer], buffer_offset); } else { - brw->bind.surf_offset[surf_index] = 0; + brw->gs.surf_offset[surf_index] = 0; } } @@ -75,6 +76,59 @@ const struct brw_tracked_state gen6_sol_surface = { .emit = gen6_update_sol_surfaces, }; +/** + * Constructs the binding table for the WM surface state, which maps unit + * numbers to surface state objects. + */ +static void +brw_gs_upload_binding_table(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->intel.ctx; + /* BRW_NEW_VERTEX_PROGRAM */ + const struct gl_shader_program *shaderprog = + ctx->Shader.CurrentVertexProgram; + const struct gl_transform_feedback_info *linked_xfb_info = + &shaderprog->LinkedTransformFeedback; + /* Currently we only ever upload surfaces for SOL. */ + bool has_surfaces = linked_xfb_info->NumOutputs != 0; + + uint32_t *bind; + + /* CACHE_NEW_GS_PROG: Skip making a binding table if we don't use textures or + * pull constants. + */ + if (!has_surfaces) { + if (brw->gs.bind_bo_offset != 0) { + brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE; + brw->gs.bind_bo_offset = 0; + } + return; + } + + /* Might want to calculate nr_surfaces first, to avoid taking up so much + * space for the binding table. + */ + bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, + sizeof(uint32_t) * BRW_MAX_SURFACES, + 32, &brw->gs.bind_bo_offset); + + /* BRW_NEW_SURFACES */ + memcpy(bind, brw->gs.surf_offset, BRW_MAX_GS_SURFACES * sizeof(uint32_t)); + + brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE; +} + +const struct brw_tracked_state gen6_gs_binding_table = { + .dirty = { + .mesa = 0, + .brw = (BRW_NEW_BATCH | + BRW_NEW_VERTEX_PROGRAM | + BRW_NEW_SURFACES), + .cache = 0 + }, + .emit = brw_gs_upload_binding_table, +}; + static void gen6_update_sol_indices(struct brw_context *brw) { |