summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2017-06-13 09:59:18 -0700
committerAndres Gomez <agomez@igalia.com>2017-06-28 20:15:02 +0300
commit6e7d5532f3b94bcae3305aad3e22ec8a58e47313 (patch)
tree8a82f1b47f6da0f5737e6890dadca293ea279df8 /src/mesa/drivers/dri
parent3427a2e52ef514436c060dbb0a2815b0b07bce45 (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" <mesa-stable@lists.freedesktop.org> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> (cherry picked from commit b771d9a136715fdf8ba0b478380e19b63f1e491b)
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_pipe_control.c137
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);
}
/**