i965: Implement ABO surface state emission.
authorFrancisco Jerez <currojerez@riseup.net>
Sun, 20 Oct 2013 20:09:57 +0000 (13:09 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 29 Oct 2013 19:40:56 +0000 (12:40 -0700)
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 <stereotype441@gmail.com>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_gs_surface_state.c
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_vs_surface_state.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index d13a88c98774e07af939a3a28cceb808414fe24b..7aacf4f160b0b93609185de5ad612591e9d1a444 100644 (file)
@@ -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);
index 55152c27a0285cd07442fbd59f91cc96fe92375f..5661941fabd853070695ef324200e042b544a1e2 100644 (file)
@@ -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,
+};
index 3efc201d5a21d40a2dbfeebd23d89d1e105c4f56..2c0248aeb214d40cfd697c8533ed815685e61153 100644 (file)
@@ -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++;
index 0d8503a5101aef9eb8b2abdbbdfe18b8ba2c0820..0e8387c2c5d6ee701e1ddcebd6010e6f5e250b7b 100644 (file)
@@ -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;
 
index ec9bfb06175ecdf707e6fa78279a946cd691877b..666af34ee50492d5d85b58d8aa9034d53819e659 100644 (file)
@@ -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),
index 7e4bcc08f68942368417c506e46202efed9700c9..ca8577a9ebaf8246bd6cc1e929d57b339d9f73b6 100644 (file)
@@ -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,
+};
index 744821b846a5f30ce29761058ecc01eef47b0dd8..46871c7cf5555ddb5285342c43ed41e3800dde79 100644 (file)
@@ -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)
 {