void i915_gem_object_flush_if_display_locked(struct drm_i915_gem_object *obj)
{ if (i915_gem_object_is_framebuffer(obj))
__i915_gem_object_flush_for_display(obj);
}
/** *i915_gem_object_set_to_wc_domain-MovesasingleobjecttotheWCread,and *possiblywritedomain. *@obj:objecttoacton *@write:askforwriteaccessorreadonly * *Thisfunctionreturnswhenthemoveiscomplete,includingwaitingon *flushestooccur.
*/ int
i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write)
{ int ret;
assert_object_held(obj);
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE |
(write ? I915_WAIT_ALL : 0),
MAX_SCHEDULE_TIMEOUT); if (ret) return ret;
if (obj->write_domain == I915_GEM_DOMAIN_WC) return0;
/* Flush and acquire obj->pages so that we are coherent through *directaccessinmemorywithpreviouscachedwritesthrough *shmemfsandthatourcachedomaintrackingremainsvalid. *Forexample,iftheobj->filpwasmovedtoswapwithoutus *beingnotifiedandreleasingthepages,wewouldmistakenly *continuetoassumethattheobjremainedoutoftheCPUcached *domain.
*/
ret = i915_gem_object_pin_pages(obj); if (ret) return ret;
flush_write_domain(obj, ~I915_GEM_DOMAIN_WC);
/* Serialise direct access to this object with the barriers for *coherentwritesfromtheGPU,byeffectivelyinvalidatingthe *WCdomainuponfirstaccess.
*/ if ((obj->read_domains & I915_GEM_DOMAIN_WC) == 0)
mb();
/* It should now be out of any other write domains, and we can update *thedomainvaluesforourchanges.
*/
GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_WC) != 0);
obj->read_domains |= I915_GEM_DOMAIN_WC; if (write) {
obj->read_domains = I915_GEM_DOMAIN_WC;
obj->write_domain = I915_GEM_DOMAIN_WC;
obj->mm.dirty = true;
}
i915_gem_object_unpin_pages(obj); return0;
}
/** *i915_gem_object_set_to_gtt_domain-MovesasingleobjecttotheGTTread, *andpossiblywritedomain. *@obj:objecttoacton *@write:askforwriteaccessorreadonly * *Thisfunctionreturnswhenthemoveiscomplete,includingwaitingon *flushestooccur.
*/ int
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
{ int ret;
assert_object_held(obj);
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE |
(write ? I915_WAIT_ALL : 0),
MAX_SCHEDULE_TIMEOUT); if (ret) return ret;
if (obj->write_domain == I915_GEM_DOMAIN_GTT) return0;
/* Flush and acquire obj->pages so that we are coherent through *directaccessinmemorywithpreviouscachedwritesthrough *shmemfsandthatourcachedomaintrackingremainsvalid. *Forexample,iftheobj->filpwasmovedtoswapwithoutus *beingnotifiedandreleasingthepages,wewouldmistakenly *continuetoassumethattheobjremainedoutoftheCPUcached *domain.
*/
ret = i915_gem_object_pin_pages(obj); if (ret) return ret;
flush_write_domain(obj, ~I915_GEM_DOMAIN_GTT);
/* Serialise direct access to this object with the barriers for *coherentwritesfromtheGPU,byeffectivelyinvalidatingthe *GTTdomainuponfirstaccess.
*/ if ((obj->read_domains & I915_GEM_DOMAIN_GTT) == 0)
mb();
/* It should now be out of any other write domains, and we can update *thedomainvaluesforourchanges.
*/
GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
obj->read_domains |= I915_GEM_DOMAIN_GTT; if (write) { struct i915_vma *vma;
/* The cache-level will be applied when each vma is rebound. */ return i915_gem_object_unbind(obj,
I915_GEM_OBJECT_UNBIND_ACTIVE |
I915_GEM_OBJECT_UNBIND_BARRIER);
}
/** *i915_gem_object_set_to_cpu_domain-MovesasingleobjecttotheCPUread, *andpossiblywritedomain. *@obj:objecttoacton *@write:requestingwriteorread-onlyaccess * *Thisfunctionreturnswhenthemoveiscomplete,includingwaitingon *flushestooccur.
*/ int
i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
{ int ret;
assert_object_held(obj);
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE |
(write ? I915_WAIT_ALL : 0),
MAX_SCHEDULE_TIMEOUT); if (ret) return ret;
flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
/* Flush the CPU cache if it's still invalid. */ if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) {
i915_gem_clflush_object(obj, I915_CLFLUSH_SYNC);
obj->read_domains |= I915_GEM_DOMAIN_CPU;
}
/* It should now be out of any other write domains, and we can update *thedomainvaluesforourchanges.
*/
GEM_BUG_ON(obj->write_domain & ~I915_GEM_DOMAIN_CPU);
/* If we're writing through the CPU, then the GPU read domains will *needtobeinvalidatedatnextuse.
*/ if (write)
__start_cpu_write(obj);
if (!err && write_domain)
i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
out:
i915_gem_object_put(obj); return err;
}
/* *Pinsthespecifiedobject'spagesandsynchronizestheobjectwith *GPUaccesses.Setsneeds_clflushtonon-zeroifthecallershould *flushtheobjectfromtheCPUcache.
*/ int i915_gem_object_prepare_read(struct drm_i915_gem_object *obj, unsignedint *needs_clflush)
{ int ret;
*needs_clflush = 0; if (!i915_gem_object_has_struct_page(obj)) return -ENODEV;
assert_object_held(obj);
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE,
MAX_SCHEDULE_TIMEOUT); if (ret) return ret;
ret = i915_gem_object_pin_pages(obj); if (ret) return ret;
if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ ||
!static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, false); if (ret) goto err_unpin; else goto out;
}
flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
/* If we're not in the cpu read domain, set ourself into the gtt *readdomainandmanuallyflushcachelines(ifrequired).This *optimizesforthecasewhenthegpuwilldirtythedata *anywayagainbeforethenextpreadhappens.
*/ if (!obj->cache_dirty &&
!(obj->read_domains & I915_GEM_DOMAIN_CPU))
*needs_clflush = CLFLUSH_BEFORE;
int i915_gem_object_prepare_write(struct drm_i915_gem_object *obj, unsignedint *needs_clflush)
{ int ret;
*needs_clflush = 0; if (!i915_gem_object_has_struct_page(obj)) return -ENODEV;
assert_object_held(obj);
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE |
I915_WAIT_ALL,
MAX_SCHEDULE_TIMEOUT); if (ret) return ret;
ret = i915_gem_object_pin_pages(obj); if (ret) return ret;
if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE ||
!static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, true); if (ret) goto err_unpin; else goto out;
}
flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
/* If we're not in the cpu write domain, set ourself into the *gttwritedomainandmanuallyflushcachelines(asrequired). *Thisoptimizesforthecasewhenthegpuwillusethedata *rightawayandwethereforehavetoclflushanyway.
*/ if (!obj->cache_dirty) {
*needs_clflush |= CLFLUSH_AFTER;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.