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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev