[Mesa-dev] [PATCH 15/24] i965: Implement ABO surface state emission.
Francisco Jerez
currojerez at riseup.net
Sun Sep 15 00:10:41 PDT 2013
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...
---
src/mesa/drivers/dri/i965/brw_context.h | 17 +++++++--
src/mesa/drivers/dri/i965/brw_gs_surface_state.c | 19 ++++++++++
src/mesa/drivers/dri/i965/brw_state.h | 3 ++
src/mesa/drivers/dri/i965/brw_state_upload.c | 4 +++
src/mesa/drivers/dri/i965/brw_vs_surface_state.c | 19 ++++++++++
src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 44 ++++++++++++++++++++++++
6 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 3003d15..3f2f297 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -157,6 +157,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,
@@ -195,6 +196,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)
@@ -570,6 +572,12 @@ struct brw_gs_prog_data
/** Max number of render targets in a shader */
#define BRW_MAX_DRAW_BUFFERS 8
+/** Max number of uniform buffer objects in a shader */
+#define BRW_MAX_UBO 12
+
+/** 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.
*
@@ -662,14 +670,16 @@ struct brw_gs_prog_data
#define SURF_INDEX_FRAG_CONST_BUFFER (BRW_MAX_DRAW_BUFFERS + 1)
#define SURF_INDEX_TEXTURE(t) (BRW_MAX_DRAW_BUFFERS + 2 + (t))
#define SURF_INDEX_WM_UBO(u) (SURF_INDEX_TEXTURE(BRW_MAX_TEX_UNIT) + u)
-#define SURF_INDEX_WM_SHADER_TIME (SURF_INDEX_WM_UBO(12))
+#define SURF_INDEX_WM_ABO(a) (SURF_INDEX_WM_UBO(BRW_MAX_UBO) + a)
+#define SURF_INDEX_WM_SHADER_TIME (SURF_INDEX_WM_ABO(BRW_MAX_ABO))
/** Maximum size of the binding table. */
#define BRW_MAX_WM_SURFACES (SURF_INDEX_WM_SHADER_TIME + 1)
#define SURF_INDEX_VEC4_CONST_BUFFER (0)
#define SURF_INDEX_VEC4_TEXTURE(t) (SURF_INDEX_VEC4_CONST_BUFFER + 1 + (t))
#define SURF_INDEX_VEC4_UBO(u) (SURF_INDEX_VEC4_TEXTURE(BRW_MAX_TEX_UNIT) + u)
-#define SURF_INDEX_VEC4_SHADER_TIME (SURF_INDEX_VEC4_UBO(12))
+#define SURF_INDEX_VEC4_ABO(a) (SURF_INDEX_VEC4_UBO(BRW_MAX_UBO) + a)
+#define SURF_INDEX_VEC4_SHADER_TIME (SURF_INDEX_VEC4_ABO(BRW_MAX_ABO))
#define BRW_MAX_VEC4_SURFACES (SURF_INDEX_VEC4_SHADER_TIME + 1)
#define SURF_INDEX_GEN6_SOL_BINDING(t) (t)
@@ -1456,6 +1466,9 @@ brw_update_sol_surface(struct brw_context *brw,
void brw_upload_ubo_surfaces(struct brw_context *brw,
struct gl_shader *shader,
uint32_t *surf_offsets);
+void brw_upload_abo_surfaces(struct brw_context *brw,
+ struct gl_shader_program *prog,
+ uint32_t *surf_offsets);
/* 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 bae6015..668bea5 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c
@@ -88,6 +88,25 @@ 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;
+ struct gl_shader_program *prog = ctx->Shader.CurrentGeometryProgram;
+
+ if (prog)
+ brw_upload_abo_surfaces(
+ brw, prog, &brw->gs.base.surf_offset[SURF_INDEX_VEC4_ABO(0)]);
+}
+
+const struct brw_tracked_state brw_gs_abo_surfaces = {
+ .dirty = {
+ .mesa = _NEW_PROGRAM,
+ .brw = BRW_NEW_BATCH | BRW_NEW_UNIFORM_BUFFER,
+ .cache = 0,
+ },
+ .emit = brw_upload_gs_abo_surfaces,
+};
/**
* Constructs the binding table for the WM surface state, which maps unit
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 04c1a97..1d01406 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 8f21f06..e48114c 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,
@@ -393,6 +396,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_TRANSFORM_FEEDBACK),
DEFINE_BIT(BRW_NEW_RASTERIZER_DISCARD),
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),
{0, 0, 0}
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 dbf26f4..9f8c0f5 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -149,6 +149,25 @@ 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;
+ struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram;
+
+ if (prog)
+ brw_upload_abo_surfaces(
+ brw, prog, &brw->vs.base.surf_offset[SURF_INDEX_VEC4_ABO(0)]);
+}
+
+const struct brw_tracked_state brw_vs_abo_surfaces = {
+ .dirty = {
+ .mesa = _NEW_PROGRAM,
+ .brw = BRW_NEW_BATCH | BRW_NEW_ATOMIC_BUFFER,
+ .cache = 0,
+ },
+ .emit = brw_upload_vs_abo_surfaces,
+};
void
brw_vec4_upload_binding_table(struct brw_context *brw,
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 bbe7803..48f351f 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -831,6 +831,50 @@ 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,
+ uint32_t *surf_offsets)
+{
+ struct gl_context *ctx = &brw->ctx;
+
+ 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,
+ INTEL_READ | INTEL_WRITE_PART);
+
+ brw->vtbl.create_raw_surface(brw, bo, binding->Offset,
+ bo->size - binding->Offset,
+ &surf_offsets[i], true);
+ }
+
+ if (prog->NumAtomicBuffers)
+ brw->state.dirty.brw |= BRW_NEW_SURFACES;
+}
+
+static void
+brw_upload_wm_abo_surfaces(struct brw_context *brw)
+{
+ struct gl_context *ctx = &brw->ctx;
+ struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram;
+
+ if (prog)
+ brw_upload_abo_surfaces(
+ brw, prog, &brw->wm.base.surf_offset[SURF_INDEX_WM_ABO(0)]);
+}
+
+const struct brw_tracked_state brw_wm_abo_surfaces = {
+ .dirty = {
+ .mesa = _NEW_PROGRAM,
+ .brw = BRW_NEW_BATCH | BRW_NEW_ATOMIC_BUFFER,
+ .cache = 0,
+ },
+ .emit = brw_upload_wm_abo_surfaces,
+};
+
/**
* Constructs the binding table for the WM surface state, which maps unit
* numbers to surface state objects.
--
1.8.3.4
More information about the mesa-dev
mailing list