From: Jason Ekstrand Date: Tue, 13 Jun 2017 16:59:18 +0000 (-0700) Subject: i965: Unify the two emit_pipe_control functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b771d9a136715fdf8ba0b478380e19b63f1e491b;p=mesa.git i965: Unify the two emit_pipe_control functions These two functions contain almost identical logic except for one SNB workaround required for render target cache flushes. They may as well call into the same code so we only have to handle the work-arounds in one place. Cc: "17.1" Reviewed-by: Kenneth Graunke --- diff --git a/src/mesa/drivers/dri/i965/brw_pipe_control.c b/src/mesa/drivers/dri/i965/brw_pipe_control.c index 0e206c683fc..39bb9c7365d 100644 --- a/src/mesa/drivers/dri/i965/brw_pipe_control.c +++ b/src/mesa/drivers/dri/i965/brw_pipe_control.c @@ -87,33 +87,10 @@ gen7_cs_stall_every_four_pipe_controls(struct brw_context *brw, uint32_t flags) return 0; } -/** - * 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) +static void +brw_emit_pipe_control(struct brw_context *brw, uint32_t flags, + struct brw_bo *bo, uint32_t offset, uint64_t imm) { - if (brw->gen >= 6 && - (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) && - (flags & PIPE_CONTROL_CACHE_INVALIDATE_BITS)) { - /* A pipe control command with flush and invalidate bits set - * simultaneously is an inherently racy operation on Gen6+ if the - * contents of the flushed caches were intended to become visible from - * any of the invalidated caches. Split it in two PIPE_CONTROLs, the - * first one should stall the pipeline to make sure that the flushed R/W - * caches are coherent with memory once the specified R/O caches are - * invalidated. On pre-Gen6 hardware the (implicit) R/O cache - * invalidation seems to happen at the bottom of the pipeline together - * with any write cache flush, so this shouldn't be a concern. - */ - brw_emit_pipe_control_flush(brw, (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) | - PIPE_CONTROL_CS_STALL); - flags &= ~(PIPE_CONTROL_CACHE_FLUSH_BITS | PIPE_CONTROL_CS_STALL); - } - if (brw->gen >= 8) { if (brw->gen == 8) gen8_add_cs_stall_workaround_bits(&flags); @@ -131,10 +108,15 @@ brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags) BEGIN_BATCH(6); OUT_BATCH(_3DSTATE_PIPE_CONTROL | (6 - 2)); OUT_BATCH(flags); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); + if (bo) { + OUT_RELOC64(bo, I915_GEM_DOMAIN_INSTRUCTION, + I915_GEM_DOMAIN_INSTRUCTION, offset); + } else { + OUT_BATCH(0); + OUT_BATCH(0); + } + OUT_BATCH(imm); + OUT_BATCH(imm >> 32); ADVANCE_BATCH(); } else if (brw->gen >= 6) { if (brw->gen == 6 && @@ -150,23 +132,68 @@ brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags) flags |= gen7_cs_stall_every_four_pipe_controls(brw, flags); + /* PPGTT/GGTT is selected by DW2 bit 2 on Sandybridge, but DW1 bit 24 + * on later platforms. We always use PPGTT on Gen7+. + */ + unsigned gen6_gtt = brw->gen == 6 ? PIPE_CONTROL_GLOBAL_GTT_WRITE : 0; + BEGIN_BATCH(5); OUT_BATCH(_3DSTATE_PIPE_CONTROL | (5 - 2)); OUT_BATCH(flags); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); + if (bo) { + OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, + gen6_gtt | offset); + } else { + OUT_BATCH(0); + } + OUT_BATCH(imm); + OUT_BATCH(imm >> 32); ADVANCE_BATCH(); } else { BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_PIPE_CONTROL | flags | (4 - 2)); - OUT_BATCH(0); - OUT_BATCH(0); - OUT_BATCH(0); + if (bo) { + OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, + PIPE_CONTROL_GLOBAL_GTT_WRITE | offset); + } else { + OUT_BATCH(0); + } + OUT_BATCH(imm); + OUT_BATCH(imm >> 32); ADVANCE_BATCH(); } } +/** + * 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 && + (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) && + (flags & PIPE_CONTROL_CACHE_INVALIDATE_BITS)) { + /* A pipe control command with flush and invalidate bits set + * simultaneously is an inherently racy operation on Gen6+ if the + * contents of the flushed caches were intended to become visible from + * any of the invalidated caches. Split it in two PIPE_CONTROLs, the + * first one should stall the pipeline to make sure that the flushed R/W + * caches are coherent with memory once the specified R/O caches are + * invalidated. On pre-Gen6 hardware the (implicit) R/O cache + * invalidation seems to happen at the bottom of the pipeline together + * with any write cache flush, so this shouldn't be a concern. + */ + brw_emit_pipe_control_flush(brw, (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) | + PIPE_CONTROL_CS_STALL); + flags &= ~(PIPE_CONTROL_CACHE_FLUSH_BITS | PIPE_CONTROL_CS_STALL); + } + + brw_emit_pipe_control(brw, flags, NULL, 0, 0); +} + /** * Emit a PIPE_CONTROL that writes to a buffer object. * @@ -180,43 +207,7 @@ brw_emit_pipe_control_write(struct brw_context *brw, uint32_t flags, struct brw_bo *bo, uint32_t offset, uint64_t imm) { - if (brw->gen >= 8) { - if (brw->gen == 8) - gen8_add_cs_stall_workaround_bits(&flags); - - BEGIN_BATCH(6); - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (6 - 2)); - OUT_BATCH(flags); - OUT_RELOC64(bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - offset); - OUT_BATCH(imm); - OUT_BATCH(imm >> 32); - ADVANCE_BATCH(); - } else if (brw->gen >= 6) { - flags |= gen7_cs_stall_every_four_pipe_controls(brw, flags); - - /* PPGTT/GGTT is selected by DW2 bit 2 on Sandybridge, but DW1 bit 24 - * on later platforms. We always use PPGTT on Gen7+. - */ - unsigned gen6_gtt = brw->gen == 6 ? PIPE_CONTROL_GLOBAL_GTT_WRITE : 0; - - BEGIN_BATCH(5); - OUT_BATCH(_3DSTATE_PIPE_CONTROL | (5 - 2)); - OUT_BATCH(flags); - OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - gen6_gtt | offset); - OUT_BATCH(imm); - OUT_BATCH(imm >> 32); - ADVANCE_BATCH(); - } else { - BEGIN_BATCH(4); - OUT_BATCH(_3DSTATE_PIPE_CONTROL | flags | (4 - 2)); - OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, - PIPE_CONTROL_GLOBAL_GTT_WRITE | offset); - OUT_BATCH(imm); - OUT_BATCH(imm >> 32); - ADVANCE_BATCH(); - } + brw_emit_pipe_control(brw, flags, bo, offset, imm); } /**