diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-16 19:29:27 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-16 19:29:27 +0200 |
commit | 8b4bf31190f7774cd54acac7c998b28a9e1ac7c3 (patch) | |
tree | 6285993b8298a2f65db9cd346a5e815d21bebb3d | |
parent | 33f17b996dd0fcbb8e07875770e11571380d6509 (diff) |
sna: implement PIPE_CONTROL with work-around for gen6+sna-pc
Copied over from the uxa driver.
Also kill the commented-out PIPE_CONTROL for gen5 because PIPE_CONTROL
only greq an additional dword for flags on gen6 and later.
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | src/sna/kgem.c | 45 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_reg.h | 3 |
3 files changed, 41 insertions, 9 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 15ddd7a8..8ea4607a 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -398,6 +398,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) (void)drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); kgem->fence_max = v - 2; + if (gen >= 60) { + kgem->wa_scratch_bo = kgem_create_linear(kgem, 4096); + } + DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max)); } @@ -1840,10 +1844,17 @@ void kgem_clear_dirty(struct kgem *kgem) /* Flush the contents of the RenderCache and invalidate the TextureCache */ void kgem_emit_flush(struct kgem *kgem) { + int space; + if (kgem->nbatch == 0) return; - if (!kgem_check_batch(kgem, 4)) { + if (kgem->gen >= 60 && kgem->ring == KGEM_RENDER) + space = 4*3; + else + space = 4; + + if (!kgem_check_batch(kgem, space)) { _kgem_submit(kgem); return; } @@ -1855,14 +1866,30 @@ void kgem_emit_flush(struct kgem *kgem) kgem->batch[kgem->nbatch++] = 0; kgem->batch[kgem->nbatch++] = 0; kgem->batch[kgem->nbatch++] = 0; - } else if (kgem->gen >= 50 && 0) { - kgem->batch[kgem->nbatch++] = PIPE_CONTROL | 2; - kgem->batch[kgem->nbatch++] = - PIPE_CONTROL_WC_FLUSH | - PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOWRITE; - kgem->batch[kgem->nbatch++] = 0; - kgem->batch[kgem->nbatch++] = 0; + } else if (kgem->gen >= 60) { + kgem->batch[kgem->nbatch++] = PIPE_CONTROL | (4 - 2); + kgem->batch[kgem->nbatch++] = PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_STALL_AT_SCOREBOARD; + kgem->batch[kgem->nbatch++] = 0; /* address */ + kgem->batch[kgem->nbatch++] = 0; /* write data */ + + kgem->batch[kgem->nbatch++] = PIPE_CONTROL | (4 - 2); + kgem->batch[kgem->nbatch++] = PIPE_CONTROL_WRITE_QWORD; + kgem->batch[kgem->nbatch] = kgem_add_reloc(kgem, kgem->nbatch, + kgem->wa_scratch_bo, + I915_GEM_DOMAIN_INSTRUCTION << 16 | + I915_GEM_DOMAIN_INSTRUCTION, + 0); + kgem->nbatch++; + kgem->batch[kgem->nbatch++] = 0; /* write data */ + + /* now finally the _real flush */ + kgem->batch[kgem->nbatch++] = PIPE_CONTROL | (4 - 2); + kgem->batch[kgem->nbatch++] = PIPE_CONTROL_WC_FLUSH | + PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOWRITE; + kgem->batch[kgem->nbatch++] = 0; /* write address */ + kgem->batch[kgem->nbatch++] = 0; /* write data */ } else { if ((kgem->batch[kgem->nbatch-1] & (0xff<<23)) == MI_FLUSH) kgem->nbatch--; diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 49ca3d70..2a93deb4 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -118,6 +118,8 @@ struct kgem { uint32_t batch[4*1024]; struct drm_i915_gem_exec_object2 exec[256]; struct drm_i915_gem_relocation_entry reloc[384]; + + struct kgem_bo *wa_scratch_bo; }; #define KGEM_BATCH_RESERVED 4 /* need a bit of extra room for workarounds */ diff --git a/src/sna/sna_reg.h b/src/sna/sna_reg.h index 8ca90895..fb877302 100644 --- a/src/sna/sna_reg.h +++ b/src/sna/sna_reg.h @@ -96,6 +96,9 @@ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define PIPE_CONTROL BRW_3D(3, 2, 0) +#define PIPE_CONTROL_CS_STALL (1 << 20) +#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) +#define PIPE_CONTROL_NOWRITE (0 << 14) #define PIPE_CONTROL_NOWRITE (0 << 14) #define PIPE_CONTROL_WRITE_QWORD (1 << 14) #define PIPE_CONTROL_WRITE_DEPTH (2 << 14) |