diff options
author | Jason Ekstrand <[email protected]> | 2017-06-13 09:59:18 -0700 |
---|---|---|
committer | Andres Gomez <[email protected]> | 2017-06-28 20:15:02 +0300 |
commit | 6e7d5532f3b94bcae3305aad3e22ec8a58e47313 (patch) | |
tree | 8a82f1b47f6da0f5737e6890dadca293ea279df8 /src/mesa | |
parent | 3427a2e52ef514436c060dbb0a2815b0b07bce45 (diff) |
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" <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
(cherry picked from commit b771d9a136715fdf8ba0b478380e19b63f1e491b)
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_pipe_control.c | 137 |
1 files changed, 64 insertions, 73 deletions
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,24 +132,69 @@ 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. * * \p flags should contain one of the following items: @@ -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); } /** |