summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-16 19:29:27 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-16 19:29:27 +0200
commit8b4bf31190f7774cd54acac7c998b28a9e1ac7c3 (patch)
tree6285993b8298a2f65db9cd346a5e815d21bebb3d
parent33f17b996dd0fcbb8e07875770e11571380d6509 (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.c45
-rw-r--r--src/sna/kgem.h2
-rw-r--r--src/sna/sna_reg.h3
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)