vk: Set I915_CACHING_NONE for userptr BOs when !llc
authorKristian Høgsberg <krh@sweater.jf.intel.com>
Thu, 3 Dec 2015 20:09:33 +0000 (12:09 -0800)
committerKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Fri, 4 Dec 2015 17:51:47 +0000 (09:51 -0800)
Regular objects are created I915_CACHING_CACHED on LLC platforms and
I915_CACHING_NONE on non-LLC platforms. However, userptr objects are
always created as I915_CACHING_CACHED, which on non-LLC means
snooped. That can be useful but comes with a bit of overheard.  Since
we're eplicitly clflushing and don't want the overhead we need to turn
it off.

src/vulkan/anv_allocator.c
src/vulkan/anv_gem.c
src/vulkan/anv_private.h

index db04a2c236c67fe1ac985d2a7a147dd182f78af5..970d809e8a3cc6140d31db5512c9acf022f29b12 100644 (file)
@@ -441,6 +441,18 @@ anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state)
       goto fail;
    cleanup->gem_handle = gem_handle;
 
+   /* Regular objects are created I915_CACHING_CACHED on LLC platforms and
+    * I915_CACHING_NONE on non-LLC platforms. However, userptr objects are
+    * always created as I915_CACHING_CACHED, which on non-LLC means
+    * snooped. That can be useful but comes with a bit of overheard.  Since
+    * we're eplicitly clflushing and don't want the overhead we need to turn
+    * it off. */
+   if (!pool->device->info.has_llc) {
+      anv_gem_set_caching(pool->device, gem_handle, I915_CACHING_NONE);
+      anv_gem_set_domain(pool->device, gem_handle,
+                         I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+   }
+
    /* Now that we successfull allocated everything, we can write the new
     * values back into pool. */
    pool->map = map + center_bo_offset;
index 01671d2ea50cccc5d75da0b0b32eb4947c592153..57b8505e156c48faf4552c909e1810aa57de6ec0 100644 (file)
@@ -137,6 +137,32 @@ anv_gem_userptr(struct anv_device *device, void *mem, size_t size)
    return userptr.handle;
 }
 
+int
+anv_gem_set_caching(struct anv_device *device, int gem_handle, uint32_t caching)
+{
+   struct drm_i915_gem_caching gem_caching;
+
+   VG_CLEAR(gem_caching);
+   gem_caching.handle = gem_handle;
+   gem_caching.caching = caching;
+
+   return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_SET_CACHING, &gem_caching);
+}
+
+int
+anv_gem_set_domain(struct anv_device *device, int gem_handle,
+                   uint32_t read_domains, uint32_t write_domain)
+{
+   struct drm_i915_gem_set_domain gem_set_domain;
+
+   VG_CLEAR(gem_set_domain);
+   gem_set_domain.handle = gem_handle;
+   gem_set_domain.read_domains = read_domains;
+   gem_set_domain.write_domain = write_domain;
+
+   return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &gem_set_domain);
+}
+
 /**
  * On error, \a timeout_ns holds the remaining time.
  */
index c21d9d7c8567a24ed5a75d6d188e6302f1b9ea1c..8be64d8887dd6f971710b53163720ccfbd521a9f 100644 (file)
@@ -598,6 +598,9 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
 int anv_gem_handle_to_fd(struct anv_device *device, int gem_handle);
 int anv_gem_fd_to_handle(struct anv_device *device, int fd);
 int anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
+int anv_gem_set_caching(struct anv_device *device, int gem_handle, uint32_t caching);
+int anv_gem_set_domain(struct anv_device *device, int gem_handle,
+                       uint32_t read_domains, uint32_t write_domain);
 
 VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);