From 29603ae208fb0031a6746110d448a91ea4071dea Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 29 Nov 2016 01:06:50 -0800 Subject: [PATCH] i965: Separate uploading push constant data from the pointer packets. I hope to upload UBO via 3DSTATE_CONSTANT_XS packets, in addition to normal uniforms. In order to do that, I'll need to re-emit the packets when UBOs change. But I don't want to re-copy the regular uniform data to the batchbuffer every time. This patch separates out the data uploading from the packet submission. We're running low on dirty bits, so I made the new atom happen on every draw call, and added a flag to stage_state indicating that we want the packet for that stage emitted. I would have preferred to do this outside the atom system, but it has to happen between the uploading of push constant data and the binding table upload. Reviewed-by: Matt Turner --- src/mesa/drivers/dri/i965/brw_context.h | 3 + src/mesa/drivers/dri/i965/gen6_constant_state.c | 2 + src/mesa/drivers/dri/i965/genX_state_upload.c | 81 ++++++++++++++----------- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index c36797f8801..ffe4792b73e 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -565,6 +565,9 @@ struct brw_stage_state /** SAMPLER_STATE count and table offset */ uint32_t sampler_count; uint32_t sampler_offset; + + /** Need to re-emit 3DSTATE_CONSTANT_XS? */ + bool push_constants_dirty; }; enum brw_predicate_state { diff --git a/src/mesa/drivers/dri/i965/gen6_constant_state.c b/src/mesa/drivers/dri/i965/gen6_constant_state.c index 920f502ca37..dd4e224aada 100644 --- a/src/mesa/drivers/dri/i965/gen6_constant_state.c +++ b/src/mesa/drivers/dri/i965/gen6_constant_state.c @@ -119,4 +119,6 @@ gen6_upload_push_constants(struct brw_context *brw, */ assert(stage_state->push_const_size <= 32); } + + stage_state->push_constants_dirty = true; } diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index e0b87b762d2..267a0a8c200 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -2845,31 +2845,58 @@ UNUSED static const uint32_t push_constant_opcodes[] = { }; static void -upload_constant_state(struct brw_context *brw, - struct brw_stage_state *stage_state, - bool active, uint32_t stage) +genX(upload_push_constant_packets)(struct brw_context *brw) { UNUSED uint32_t mocs = GEN_GEN < 8 ? GEN7_MOCS_L3 : 0; - active = active && stage_state->push_const_size != 0; - brw_batch_emit(brw, GENX(3DSTATE_CONSTANT_VS), pkt) { - pkt._3DCommandSubOpcode = push_constant_opcodes[stage]; - if (active) { + struct brw_stage_state *stage_states[] = { + &brw->vs.base, + &brw->tcs.base, + &brw->tes.base, + &brw->gs.base, + &brw->wm.base, + }; + + if (GEN_GEN == 7 && !GEN_IS_HASWELL && !brw->is_baytrail && + stage_states[MESA_SHADER_VERTEX]->push_constants_dirty) + gen7_emit_vs_workaround_flush(brw); + + for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { + struct brw_stage_state *stage_state = stage_states[stage]; + bool active = stage_state->prog_data && stage_state->push_const_size > 0; + + if (!stage_state->push_constants_dirty) + continue; + + brw_batch_emit(brw, GENX(3DSTATE_CONSTANT_VS), pkt) { + pkt._3DCommandSubOpcode = push_constant_opcodes[stage]; + if (active) { #if GEN_GEN >= 8 || GEN_IS_HASWELL - pkt.ConstantBody.ReadLength[2] = stage_state->push_const_size; - pkt.ConstantBody.Buffer[2] = - render_ro_bo(stage_state->push_const_bo, - stage_state->push_const_offset); + pkt.ConstantBody.ReadLength[2] = stage_state->push_const_size; + pkt.ConstantBody.Buffer[2] = + render_ro_bo(stage_state->push_const_bo, + stage_state->push_const_offset); #else - pkt.ConstantBody.ReadLength[0] = stage_state->push_const_size; - pkt.ConstantBody.Buffer[0].offset = - stage_state->push_const_offset | mocs; + pkt.ConstantBody.ReadLength[0] = stage_state->push_const_size; + pkt.ConstantBody.Buffer[0].offset = + stage_state->push_const_offset | mocs; #endif + } } + + stage_state->push_constants_dirty = false; } brw->ctx.NewDriverState |= GEN_GEN >= 9 ? BRW_NEW_SURFACES : 0; } + +const struct brw_tracked_state genX(push_constant_packets) = { + .dirty = { + .mesa = 0, + .brw = BRW_NEW_DRAW_CALL, + }, + .emit = genX(upload_push_constant_packets), +}; #endif #if GEN_GEN >= 6 @@ -2885,14 +2912,6 @@ genX(upload_vs_push_constants)(struct brw_context *brw) _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_VERTEX); gen6_upload_push_constants(brw, &vp->program, prog_data, stage_state); - -#if GEN_GEN >= 7 - if (GEN_GEN == 7 && !GEN_IS_HASWELL && !brw->is_baytrail) - gen7_emit_vs_workaround_flush(brw); - - upload_constant_state(brw, stage_state, true /* active */, - MESA_SHADER_VERTEX); -#endif } static const struct brw_tracked_state genX(vs_push_constants) = { @@ -2923,10 +2942,6 @@ genX(upload_gs_push_constants)(struct brw_context *brw) _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_GEOMETRY); gen6_upload_push_constants(brw, &gp->program, prog_data, stage_state); } - -#if GEN_GEN >= 7 - upload_constant_state(brw, stage_state, gp, MESA_SHADER_GEOMETRY); -#endif } static const struct brw_tracked_state genX(gs_push_constants) = { @@ -2954,10 +2969,6 @@ genX(upload_wm_push_constants)(struct brw_context *brw) _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_FRAGMENT); gen6_upload_push_constants(brw, &fp->program, prog_data, stage_state); - -#if GEN_GEN >= 7 - upload_constant_state(brw, stage_state, true, MESA_SHADER_FRAGMENT); -#endif } static const struct brw_tracked_state genX(wm_push_constants) = { @@ -3803,8 +3814,6 @@ genX(upload_tes_push_constants)(struct brw_context *brw) _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_TESS_EVAL); gen6_upload_push_constants(brw, &tep->program, prog_data, stage_state); } - - upload_constant_state(brw, stage_state, tep, MESA_SHADER_TESS_EVAL); } static const struct brw_tracked_state genX(tes_push_constants) = { @@ -3834,8 +3843,6 @@ genX(upload_tcs_push_constants)(struct brw_context *brw) _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_TESS_CTRL); gen6_upload_push_constants(brw, &tcp->program, prog_data, stage_state); } - - upload_constant_state(brw, stage_state, active, MESA_SHADER_TESS_CTRL); } static const struct brw_tracked_state genX(tcs_push_constants) = { @@ -5204,6 +5211,9 @@ genX(init_atoms)(struct brw_context *brw) &gen6_renderbuffer_surfaces, &brw_renderbuffer_read_surfaces, &brw_texture_surfaces, + + &genX(push_constant_packets), + &brw_vs_binding_table, &brw_tcs_binding_table, &brw_tes_binding_table, @@ -5293,6 +5303,9 @@ genX(init_atoms)(struct brw_context *brw) &gen6_renderbuffer_surfaces, &brw_renderbuffer_read_surfaces, &brw_texture_surfaces, + + &genX(push_constant_packets), + &brw_vs_binding_table, &brw_tcs_binding_table, &brw_tes_binding_table, -- 2.11.0