[Mesa-dev] [PATCH 03/10] i965: Create a helper function for emitting PIPE_CONTROL flushes.
Kenneth Graunke
kenneth at whitecape.org
Fri Jan 10 12:03:24 PST 2014
On 01/09/2014 07:52 PM, Eric Anholt wrote:
> Kenneth Graunke <kenneth at whitecape.org> writes:
>
>> These days, we need to emit PIPE_CONTROL flushes all over the place.
>> Being able to do that via a single function call seems convenient.
>>
>> Broadwell will also increase the length of these packets by 1; with the
>> refactoring, we should have to do this in substantially fewer places.
>>
>> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
>
>> diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
>> index d9b6c15..d2f0e90 100644
>> --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
>> +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
>> @@ -475,6 +475,32 @@ emit:
>> }
>>
>> /**
>> + * Emit a PIPE_CONTROL with various flushing flags.
>> + *
>> + * The caller is responsible for deciding what flags are appropriate for the
>> + * given generation.
>> + */
>> +void
>> +brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags)
>> +{
>> + if (brw->gen >= 6) {
>> + BEGIN_BATCH(4);
>> + OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> + OUT_BATCH(flags);
>> + OUT_BATCH(0);
>> + OUT_BATCH(0);
>> + ADVANCE_BATCH();
>> + } else {
>> + BEGIN_BATCH(4);
>> + OUT_BATCH(_3DSTATE_PIPE_CONTROL | flags | (4 - 2));
>> + OUT_BATCH(0);
>> + OUT_BATCH(0);
>> + OUT_BATCH(0);
>> + ADVANCE_BATCH();
>> + }
>> +}
>> +
>> +/**
>> * Restriction [DevSNB, DevIVB]:
>> *
>> * Prior to changing Depth/Stencil Buffer state (i.e. any combination of
>> @@ -491,26 +517,9 @@ intel_emit_depth_stall_flushes(struct brw_context *brw)
>> {
>> assert(brw->gen >= 6 && brw->gen <= 7);
>>
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> - OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
>> - OUT_BATCH(0); /* address */
>> - OUT_BATCH(0); /* write data */
>> - ADVANCE_BATCH()
>> -
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> - OUT_BATCH(PIPE_CONTROL_DEPTH_CACHE_FLUSH);
>> - OUT_BATCH(0); /* address */
>> - OUT_BATCH(0); /* write data */
>> - ADVANCE_BATCH();
>> -
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> - OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
>> - OUT_BATCH(0); /* address */
>> - OUT_BATCH(0); /* write data */
>> - ADVANCE_BATCH();
>> + brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
>> + brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_CACHE_FLUSH);
>> + brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
>> }
>>
>> /**
>> @@ -608,13 +617,8 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
>> if (!brw->batch.need_workaround_flush)
>> return;
>>
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> - OUT_BATCH(PIPE_CONTROL_CS_STALL |
>> - PIPE_CONTROL_STALL_AT_SCOREBOARD);
>> - OUT_BATCH(0); /* address */
>> - OUT_BATCH(0); /* write data */
>> - ADVANCE_BATCH();
>> + brw_emit_pipe_control_flush(brw, PIPE_CONTROL_CS_STALL |
>> + PIPE_CONTROL_STALL_AT_SCOREBOARD);
>>
>> BEGIN_BATCH(4);
>> OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> @@ -636,46 +640,22 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
>> void
>> intel_batchbuffer_emit_mi_flush(struct brw_context *brw)
>> {
>> - if (brw->gen >= 6) {
>> - if (brw->batch.ring == BLT_RING) {
>> - BEGIN_BATCH_BLT(4);
>> - OUT_BATCH(MI_FLUSH_DW);
>> - OUT_BATCH(0);
>> - OUT_BATCH(0);
>> - OUT_BATCH(0);
>> - ADVANCE_BATCH();
>> - } else {
>> - if (brw->gen == 6) {
>> - /* Hardware workaround: SNB B-Spec says:
>> - *
>> - * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
>> - * Flush Enable =1, a PIPE_CONTROL with any non-zero
>> - * post-sync-op is required.
>> - */
>> - intel_emit_post_sync_nonzero_flush(brw);
>> - }
>> -
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
>> - OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
>> - PIPE_CONTROL_WRITE_FLUSH |
>> - PIPE_CONTROL_DEPTH_CACHE_FLUSH |
>> - PIPE_CONTROL_VF_CACHE_INVALIDATE |
>> - PIPE_CONTROL_TC_FLUSH |
>> - PIPE_CONTROL_NO_WRITE |
>> - PIPE_CONTROL_CS_STALL);
>> - OUT_BATCH(0); /* write address */
>> - OUT_BATCH(0); /* write data */
>> - ADVANCE_BATCH();
>> - }
>> - } else {
>> - BEGIN_BATCH(4);
>> - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2) |
>> - PIPE_CONTROL_WRITE_FLUSH |
>> - PIPE_CONTROL_NO_WRITE);
>> - OUT_BATCH(0); /* write address */
>> - OUT_BATCH(0); /* write data */
>> - OUT_BATCH(0); /* write data */
>> + if (unlikely(brw->batch.ring == BLT_RING) && brw->gen >= 6) {
>> + BEGIN_BATCH_BLT(4);
>> + OUT_BATCH(MI_FLUSH_DW);
>> + OUT_BATCH(0);
>> + OUT_BATCH(0);
>> + OUT_BATCH(0);
>> ADVANCE_BATCH();
>
> This shouldn't be marked unlikely. You should use unlikely for "this
> path should be never executed in a performance-sensitive way", not just
> "I bet this will be used a bit less frequently than the alternative."
> (the compiler does more than just try to hint branch prediction using
> this information)
Removed in v2.
>
>> + } else {
>> + int flags = PIPE_CONTROL_NO_WRITE | PIPE_CONTROL_WRITE_FLUSH;
>> + if (brw->gen >= 6) {
>> + flags |= PIPE_CONTROL_INSTRUCTION_FLUSH |
>> + PIPE_CONTROL_DEPTH_CACHE_FLUSH |
>> + PIPE_CONTROL_VF_CACHE_INVALIDATE |
>> + PIPE_CONTROL_TC_FLUSH |
>> + PIPE_CONTROL_CS_STALL;
>> + }
>
> Lost the emit_post_sync_nonzero_flush() from the previous code.
Yikes, thanks for catching that. Added back in v2.
>> + brw_emit_pipe_control_flush(brw, flags);
>> }
>> }
>
More information about the mesa-dev
mailing list