Mesa (master): i965: Implement ABO surface state emission.

Francisco Jerez currojerez at kemper.freedesktop.org
Tue Oct 29 19:45:41 UTC 2013


Module: Mesa
Branch: master
Commit: 5809512b17d3216045b612d359f97759644945f1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5809512b17d3216045b612d359f97759644945f1

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Sun Oct 20 13:09:57 2013 -0700

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 <stereotype441 at gmail.com>

---

 src/mesa/drivers/dri/i965/brw_context.h          |   11 +++++
 src/mesa/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 ++
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c |   23 ++++++++++
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   50 ++++++++++++++++++++++
 7 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index d13a88c..7aacf4f 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 55152c2..5661941 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 3efc201..2c0248a 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 0d8503a..0e8387c 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 ec9bfb0..666af34 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 7e4bcc0..ca8577a 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 744821b..46871c7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -870,6 +870,56 @@ const struct brw_tracked_state brw_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)
 {
    brw->vtbl.update_texture_surface = brw_update_texture_surface;




More information about the mesa-commit mailing list