summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-05-07 12:46:06 -0700
committerEric Anholt <eric@anholt.net>2008-05-07 12:46:06 -0700
commit5f5f01ed91f5ad50f2b38e11740a30441ac845a4 (patch)
tree40d56359c9a6a97d8fb94ce5597050f72a315c49
parent6a6c37af9ecaabfe1399a1300cadaff730767013 (diff)
GEM: Extend cache domain stuff for 965.
One of our MI_FLUSH bits is reserved on 965, being always implied, and there's a vertex cache that was forgotten.
-rw-r--r--linux-core/i915_gem.c40
-rw-r--r--shared-core/i915_drm.h1
2 files changed, 38 insertions, 3 deletions
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 220d6179..f3adf39b 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -84,14 +84,41 @@ i915_gem_flush(struct drm_device *dev, uint32_t domains)
#if WATCH_EXEC
DRM_INFO ("%s: flush %08x\n", __FUNCTION__, domains);
#endif
+
+ /* read/write caches:
+ * DRM_GEM_DOMAIN_I915_RENDER is always invalidated, but is
+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is also
+ * flushed at 2d versus 3d pipeline switches.
+ *
+ * read-only caches:
+ * DRM_GEM_DOMAIN_I915_SAMPLER is flushed on pre-965 if MI_READ_FLUSH
+ * is set, and is always flushed on 965.
+ * DRM_GEM_DOMAIN_I915_COMMAND may not exist?
+ * DRM_GEM_DOMAIN_I915_INSTRUCTION, which exists on 965, is invalidated
+ * when MI_EXE_FLUSH is set.
+ * DRM_GEM_DOMAIN_I915_VERTEX, which exists on 965, is invalidated with
+ * every MI_FLUSH.
+ *
+ * TLBs:
+ * On 965, TLBs associated with DRM_GEM_DOMAIN_I915_COMMAND and
+ * DRM_GEM_DOMAIN_CPU in are invalidated at PTE write and
+ * DRM_GEM_DOMAIN_I915_RENDER and DRM_GEM_DOMAIN_I915_SAMPLER are
+ * flushed at any MI_FLUSH.
+ */
+
cmd = CMD_MI_FLUSH | MI_NO_WRITE_FLUSH;
if (domains & DRM_GEM_DOMAIN_I915_RENDER)
cmd &= ~MI_NO_WRITE_FLUSH;
- if (domains & DRM_GEM_DOMAIN_I915_SAMPLER)
- cmd |= MI_READ_FLUSH;
+ if (!IS_I965G(dev)) {
+ /* On the 965, the sampler cache always gets flushed and this
+ * bit is reserved.
+ */
+ if (domains & DRM_GEM_DOMAIN_I915_SAMPLER)
+ cmd |= MI_READ_FLUSH;
+ }
if (domains & DRM_GEM_DOMAIN_I915_INSTRUCTION)
cmd |= MI_EXE_FLUSH;
-
+
BEGIN_LP_RING(2);
OUT_RING(cmd);
OUT_RING(0); /* noop */
@@ -363,6 +390,13 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
return -ENOMEM;
}
+ /* When we have just bound an object, we have no valid read
+ * caches on it, regardless of where it was before. We also need
+ * an MI_FLUSH to occur so that the render and sampler TLBs
+ * get flushed and pick up our binding change above.
+ */
+ obj->read_domains = 0;
+
return 0;
}
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index 302fc646..8c3cd646 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -466,6 +466,7 @@ struct drm_i915_gem_relocation_entry {
#define DRM_GEM_DOMAIN_I915_COMMAND 0x00000008 /* Command queue, used to load batch buffers */
#define DRM_GEM_DOMAIN_I915_INSTRUCTION 0x00000010 /* Instruction cache, used by shader programs */
#define DRM_GEM_DOMAIN_I915_STOLEN 0x00000020 /* Stolen memory, needed by some objects */
+#define DRM_GEM_DOMAIN_I915_VERTEX 0x00000040 /* Vertex address cache */
struct drm_i915_gem_validate_entry {
/**