From 5809512b17d3216045b612d359f97759644945f1 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 20 Oct 2013 13:09:57 -0700 Subject: [PATCH] i965: Implement ABO surface state emission. The maximum number of atomic buffer objects is somewhat arbitrary, we can change it in the future easily if it turns out it's not enough... v2: Add comments with the relevant mesa dirty bits. Fix usage of BRW_NEW_UNIFORM_BUFFER in the GS ABO state atom. v3: Update binding table layout diagrams. v4: Resolve conflicts with the recent dynamic surface index assignment changes. Reviewed-by: Paul Berry --- src/mesa/drivers/dri/i965/brw_context.h | 11 ++++ .../drivers/dri/i965/brw_gs_surface_state.c | 23 +++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 7 +++ src/mesa/drivers/dri/i965/brw_state.h | 3 ++ src/mesa/drivers/dri/i965/brw_state_upload.c | 5 ++ .../drivers/dri/i965/brw_vs_surface_state.c | 23 +++++++++ .../drivers/dri/i965/brw_wm_surface_state.c | 50 +++++++++++++++++++ 7 files changed, 122 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index d13a88c9877..7aacf4f160b 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -181,6 +181,7 @@ enum brw_state_id { BRW_STATE_RASTERIZER_DISCARD, BRW_STATE_STATS_WM, BRW_STATE_UNIFORM_BUFFER, + BRW_STATE_ATOMIC_BUFFER, BRW_STATE_META_IN_PROGRESS, BRW_STATE_INTERPOLATION_MAP, BRW_STATE_PUSH_CONSTANT_ALLOCATION, @@ -219,6 +220,7 @@ enum brw_state_id { #define BRW_NEW_RASTERIZER_DISCARD (1 << BRW_STATE_RASTERIZER_DISCARD) #define BRW_NEW_STATS_WM (1 << BRW_STATE_STATS_WM) #define BRW_NEW_UNIFORM_BUFFER (1 << BRW_STATE_UNIFORM_BUFFER) +#define BRW_NEW_ATOMIC_BUFFER (1 << BRW_STATE_ATOMIC_BUFFER) #define BRW_NEW_META_IN_PROGRESS (1 << BRW_STATE_META_IN_PROGRESS) #define BRW_NEW_INTERPOLATION_MAP (1 << BRW_STATE_INTERPOLATION_MAP) #define BRW_NEW_PUSH_CONSTANT_ALLOCATION (1 << BRW_STATE_PUSH_CONSTANT_ALLOCATION) @@ -344,6 +346,7 @@ struct brw_stage_prog_data { uint32_t texture_start; uint32_t gather_texture_start; uint32_t ubo_start; + uint32_t abo_start; uint32_t shader_time_start; /** @} */ } binding_table; @@ -655,6 +658,9 @@ struct brw_gs_prog_data /** Max number of render targets in a shader */ #define BRW_MAX_DRAW_BUFFERS 8 +/** Max number of atomic counter buffer objects in a shader */ +#define BRW_MAX_ABO 4 + /** * Max number of binding table entries used for stream output. * @@ -686,6 +692,7 @@ struct brw_gs_prog_data #define BRW_MAX_SURFACES (BRW_MAX_DRAW_BUFFERS + \ BRW_MAX_TEX_UNIT * 2 + /* normal, gather */ \ 12 + /* ubo */ \ + BRW_MAX_ABO + \ 2 /* shader time, pull constants */) #define SURF_INDEX_GEN6_SOL_BINDING(t) (t) @@ -1541,6 +1548,10 @@ void brw_upload_ubo_surfaces(struct brw_context *brw, struct gl_shader *shader, struct brw_stage_state *stage_state, struct brw_stage_prog_data *prog_data); +void brw_upload_abo_surfaces(struct brw_context *brw, + struct gl_shader_program *prog, + 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_gs_surface_state.c b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c index 55152c27a02..5661941fabd 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c @@ -87,3 +87,26 @@ const struct brw_tracked_state brw_gs_ubo_surfaces = { }, .emit = brw_upload_gs_ubo_surfaces, }; + +static void +brw_upload_gs_abo_surfaces(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + /* _NEW_PROGRAM */ + struct gl_shader_program *prog = ctx->Shader.CurrentGeometryProgram; + + if (prog) { + /* CACHE_NEW_GS_PROG */ + brw_upload_abo_surfaces(brw, prog, &brw->gs.base, + &brw->gs.prog_data->base.base); + } +} + +const struct brw_tracked_state brw_gs_abo_surfaces = { + .dirty = { + .mesa = _NEW_PROGRAM, + .brw = BRW_NEW_BATCH | BRW_NEW_ATOMIC_BUFFER, + .cache = CACHE_NEW_GS_PROG, + }, + .emit = brw_upload_gs_abo_surfaces, +}; diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 3efc201d5a2..2c0248aeb21 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -653,6 +653,13 @@ backend_visitor::assign_common_binding_table_offsets(uint32_t next_binding_table stage_prog_data->binding_table.gather_texture_start = 0xd0d0d0d0; } + if (shader_prog && shader_prog->NumAtomicBuffers) { + stage_prog_data->binding_table.abo_start = next_binding_table_offset; + next_binding_table_offset += shader_prog->NumAtomicBuffers; + } else { + stage_prog_data->binding_table.abo_start = 0xd0d0d0d0; + } + /* This may or may not be used depending on how the compile goes. */ stage_prog_data->binding_table.pull_constants_start = next_binding_table_offset; next_binding_table_offset++; diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 0d8503a5101..0e8387c2c5d 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -71,7 +71,9 @@ extern const struct brw_tracked_state brw_vs_prog; extern const struct brw_tracked_state brw_vs_samplers; extern const struct brw_tracked_state brw_gs_samplers; extern const struct brw_tracked_state brw_vs_ubo_surfaces; +extern const struct brw_tracked_state brw_vs_abo_surfaces; extern const struct brw_tracked_state brw_gs_ubo_surfaces; +extern const struct brw_tracked_state brw_gs_abo_surfaces; extern const struct brw_tracked_state brw_vs_unit; extern const struct brw_tracked_state brw_gs_prog; extern const struct brw_tracked_state brw_wm_prog; @@ -81,6 +83,7 @@ extern const struct brw_tracked_state brw_wm_binding_table; extern const struct brw_tracked_state brw_gs_binding_table; extern const struct brw_tracked_state brw_vs_binding_table; extern const struct brw_tracked_state brw_wm_ubo_surfaces; +extern const struct brw_tracked_state brw_wm_abo_surfaces; extern const struct brw_tracked_state brw_wm_unit; extern const struct brw_tracked_state brw_interpolation_map; diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index ec9bfb06175..666af34ee50 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -204,10 +204,13 @@ static const struct brw_tracked_state *gen7_atoms[] = */ &brw_vs_pull_constants, &brw_vs_ubo_surfaces, + &brw_vs_abo_surfaces, &brw_gs_pull_constants, &brw_gs_ubo_surfaces, + &brw_gs_abo_surfaces, &brw_wm_pull_constants, &brw_wm_ubo_surfaces, + &brw_wm_abo_surfaces, &gen6_renderbuffer_surfaces, &brw_texture_surfaces, &brw_vs_binding_table, @@ -304,6 +307,7 @@ void brw_init_state( struct brw_context *brw ) ctx->DriverFlags.NewTransformFeedback = BRW_NEW_TRANSFORM_FEEDBACK; ctx->DriverFlags.NewRasterizerDiscard = BRW_NEW_RASTERIZER_DISCARD; ctx->DriverFlags.NewUniformBuffer = BRW_NEW_UNIFORM_BUFFER; + ctx->DriverFlags.NewAtomicBuffer = BRW_NEW_ATOMIC_BUFFER; } @@ -411,6 +415,7 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_RASTERIZER_DISCARD), DEFINE_BIT(BRW_NEW_STATS_WM), DEFINE_BIT(BRW_NEW_UNIFORM_BUFFER), + DEFINE_BIT(BRW_NEW_ATOMIC_BUFFER), DEFINE_BIT(BRW_NEW_META_IN_PROGRESS), DEFINE_BIT(BRW_NEW_INTERPOLATION_MAP), DEFINE_BIT(BRW_NEW_PUSH_CONSTANT_ALLOCATION), 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 7e4bcc08f68..ca8577a9eba 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -148,3 +148,26 @@ const struct brw_tracked_state brw_vs_ubo_surfaces = { }, .emit = brw_upload_vs_ubo_surfaces, }; + +static void +brw_upload_vs_abo_surfaces(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + /* _NEW_PROGRAM */ + struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram; + + if (prog) { + /* CACHE_NEW_VS_PROG */ + brw_upload_abo_surfaces(brw, prog, &brw->vs.base, + &brw->vs.prog_data->base.base); + } +} + +const struct brw_tracked_state brw_vs_abo_surfaces = { + .dirty = { + .mesa = _NEW_PROGRAM, + .brw = BRW_NEW_BATCH | BRW_NEW_ATOMIC_BUFFER, + .cache = CACHE_NEW_VS_PROG, + }, + .emit = brw_upload_vs_abo_surfaces, +}; 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 744821b846a..46871c7cf55 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -869,6 +869,56 @@ const struct brw_tracked_state brw_wm_ubo_surfaces = { .emit = brw_upload_wm_ubo_surfaces, }; +void +brw_upload_abo_surfaces(struct brw_context *brw, + struct gl_shader_program *prog, + struct brw_stage_state *stage_state, + struct brw_stage_prog_data *prog_data) +{ + struct gl_context *ctx = &brw->ctx; + uint32_t *surf_offsets = + &stage_state->surf_offset[prog_data->binding_table.abo_start]; + + for (int i = 0; i < prog->NumAtomicBuffers; i++) { + struct gl_atomic_buffer_binding *binding = + &ctx->AtomicBufferBindings[prog->AtomicBuffers[i].Binding]; + struct intel_buffer_object *intel_bo = + intel_buffer_object(binding->BufferObject); + drm_intel_bo *bo = intel_bufferobj_buffer( + brw, intel_bo, binding->Offset, bo->size - binding->Offset); + + brw->vtbl.create_raw_surface(brw, bo, binding->Offset, + bo->size - binding->Offset, + &surf_offsets[i], true); + } + + if (prog->NumUniformBlocks) + brw->state.dirty.brw |= BRW_NEW_SURFACES; +} + +static void +brw_upload_wm_abo_surfaces(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + /* _NEW_PROGRAM */ + struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram; + + if (prog) { + /* CACHE_NEW_WM_PROG */ + brw_upload_abo_surfaces(brw, prog, &brw->wm.base, + &brw->wm.prog_data->base); + } +} + +const struct brw_tracked_state brw_wm_abo_surfaces = { + .dirty = { + .mesa = _NEW_PROGRAM, + .brw = BRW_NEW_BATCH | BRW_NEW_ATOMIC_BUFFER, + .cache = CACHE_NEW_WM_PROG, + }, + .emit = brw_upload_wm_abo_surfaces, +}; + void gen4_init_vtable_surface_functions(struct brw_context *brw) { -- 2.30.2