iris: Use coherent allocation for PIPE_RESOURCE_STAGING
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 22 Feb 2019 21:24:46 +0000 (21:24 +0000)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 13 Mar 2019 17:54:16 +0000 (10:54 -0700)
On !llc machines (Atoms), reading from a linear buffers is slow and so
copying from one resource into the linear staging buffer is still slow.
However, we can tell the GPU to snoop the CPU cache when reading from and
writing to the staging buffer eliminating the slow uncached reads.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/drivers/iris/iris_bufmgr.c
src/gallium/drivers/iris/iris_bufmgr.h
src/gallium/drivers/iris/iris_resource.c

index 92ede93405622051bcbb4e90d5a5e4e0489383dc..b20297fd94aab70a9d1d2de7c6b5decc7ad36902 100644 (file)
@@ -521,6 +521,12 @@ bo_alloc_internal(struct iris_bufmgr *bufmgr,
    if (flags & BO_ALLOC_ZEROED)
       zeroed = true;
 
+   if ((flags & BO_ALLOC_COHERENT) && !bufmgr->has_llc) {
+      bo_size = MAX2(ALIGN(size, page_size), page_size);
+      bucket = NULL;
+      goto skip_cache;
+   }
+
    /* Round the allocated size up to a power of two number of pages. */
    bucket = bucket_for_size(bufmgr, size);
 
@@ -579,6 +585,7 @@ retry:
          bo->gtt_offset = 0ull;
       }
    } else {
+skip_cache:
       bo = bo_calloc();
       if (!bo)
          goto err;
@@ -644,6 +651,17 @@ retry:
 
    mtx_unlock(&bufmgr->lock);
 
+   if ((flags & BO_ALLOC_COHERENT) && !bo->cache_coherent) {
+      struct drm_i915_gem_caching arg = {
+         .handle = bo->gem_handle,
+         .caching = 1,
+      };
+      if (drm_ioctl(bufmgr->fd, DRM_IOCTL_I915_GEM_SET_CACHING, &arg) == 0) {
+         bo->cache_coherent = true;
+         bo->reusable = false;
+      }
+   }
+
    DBG("bo_create: buf %d (%s) %llub\n", bo->gem_handle, bo->name,
        (unsigned long long) size);
 
index c8fd6af7216337261a5cd0d6f4f09e3415b3bc50..a8a650880369bc9a5ccc8716df257f87ea48c58d 100644 (file)
@@ -191,6 +191,7 @@ struct iris_bo {
 };
 
 #define BO_ALLOC_ZEROED     (1<<0)
+#define BO_ALLOC_COHERENT   (1<<1)
 
 /**
  * Allocate a buffer object.
index 5040637ee7719598974244ff3d0e50dbbbbcb9d6..155c8786d27dd87db5014ea5705839a485c08a27 100644 (file)
@@ -592,6 +592,10 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
    const char *name = "miptree";
    enum iris_memory_zone memzone = IRIS_MEMZONE_OTHER;
 
+   unsigned int flags = 0;
+   if (templ->usage == PIPE_USAGE_STAGING)
+      flags |= BO_ALLOC_COHERENT;
+
    /* These are for u_upload_mgr buffers only */
    assert(!(templ->flags & (IRIS_RESOURCE_FLAG_SHADER_MEMZONE |
                             IRIS_RESOURCE_FLAG_SURFACE_MEMZONE |
@@ -600,7 +604,7 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
    res->bo = iris_bo_alloc_tiled(screen->bufmgr, name, res->surf.size_B,
                                  memzone,
                                  isl_tiling_to_i915_tiling(res->surf.tiling),
-                                 res->surf.row_pitch_B, 0);
+                                 res->surf.row_pitch_B, flags);
 
    if (!res->bo)
       goto fail;