diff options
| -rw-r--r-- | linux-core/i915_gem.c | 40 | ||||
| -rw-r--r-- | shared-core/i915_drm.h | 1 | 
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 {  	/** | 
