summaryrefslogtreecommitdiff
path: root/intel
diff options
context:
space:
mode:
authorAshutosh Dixit <ashutosh.dixit@intel.com>2020-09-21 17:34:16 -0700
committerAshutosh Dixit <ashutosh.dixit@intel.com>2021-03-22 15:22:31 -0700
commitcd3681976c3bbefa08236be86551c11bd4599c88 (patch)
tree5fe9be01a413fcdec467c046ac02698d50a6d580 /intel
parent52f05d3d896480ee5431dcd444f53bb2a8e41cce (diff)
downloaddrm-cd3681976c3bbefa08236be86551c11bd4599c88.tar.gz
intel: Keep libdrm working without pread/pwrite ioctls
The general direction at this time is to phase out pread/write ioctls and not support them in future products. The ioctls have already been disabled in i915 for future products. This means libdrm must handle the absence of these ioctls. This patch does this by modifying drm_intel_gem_bo_subdata() and drm_intel_gem_bo_get_subdata() to do the read/write using the pread/pwrite ioctls first but when these ioctls are unavailable fall back to doing the read/write using a combination of mmap and memcpy. A similar solution was added to igt-gpu-tools in commit ad5eb02eb3 ("lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls"). Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Diffstat (limited to 'intel')
-rw-r--r--intel/intel_bufmgr_gem.c96
1 files changed, 92 insertions, 4 deletions
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 023af61f..3c522eab 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -1732,6 +1732,82 @@ drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
return drm_intel_gem_bo_unmap(bo);
}
+static bool is_cache_coherent(drm_intel_bo *bo)
+{
+ drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+ drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+ struct drm_i915_gem_caching arg = {};
+
+ arg.handle = bo_gem->gem_handle;
+ if (drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_GET_CACHING, &arg))
+ assert(false);
+ return arg.caching != I915_CACHING_NONE;
+}
+
+static void set_domain(drm_intel_bo *bo, uint32_t read, uint32_t write)
+{
+ drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+ drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+ struct drm_i915_gem_set_domain arg = {};
+
+ arg.handle = bo_gem->gem_handle;
+ arg.read_domains = read;
+ arg.write_domain = write;
+ if (drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &arg))
+ assert(false);
+}
+
+static int mmap_write(drm_intel_bo *bo, unsigned long offset,
+ unsigned long length, const void *buf)
+{
+ void *map = NULL;
+
+ if (!length)
+ return 0;
+
+ if (is_cache_coherent(bo)) {
+ map = drm_intel_gem_bo_map__cpu(bo);
+ if (map)
+ set_domain(bo, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+ }
+ if (!map) {
+ map = drm_intel_gem_bo_map__wc(bo);
+ if (map)
+ set_domain(bo, I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+ }
+
+ assert(map);
+ memcpy((char *)map + offset, buf, length);
+ drm_intel_gem_bo_unmap(bo);
+ return 0;
+}
+
+static int mmap_read(drm_intel_bo *bo, unsigned long offset,
+ unsigned long length, void *buf)
+{
+ drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
+ void *map = NULL;
+
+ if (!length)
+ return 0;
+
+ if (bufmgr_gem->has_llc || is_cache_coherent(bo)) {
+ map = drm_intel_gem_bo_map__cpu(bo);
+ if (map)
+ set_domain(bo, I915_GEM_DOMAIN_CPU, 0);
+ }
+ if (!map) {
+ map = drm_intel_gem_bo_map__wc(bo);
+ if (map)
+ set_domain(bo, I915_GEM_DOMAIN_WC, 0);
+ }
+
+ assert(map);
+ memcpy(buf, (char *)map + offset, length);
+ drm_intel_gem_bo_unmap(bo);
+ return 0;
+}
+
static int
drm_intel_gem_bo_subdata(drm_intel_bo *bo, unsigned long offset,
unsigned long size, const void *data)
@@ -1752,14 +1828,20 @@ drm_intel_gem_bo_subdata(drm_intel_bo *bo, unsigned long offset,
ret = drmIoctl(bufmgr_gem->fd,
DRM_IOCTL_I915_GEM_PWRITE,
&pwrite);
- if (ret != 0) {
+ if (ret)
ret = -errno;
+
+ if (ret != 0 && ret != -EOPNOTSUPP) {
DBG("%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
__FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
(int)size, strerror(errno));
+ return ret;
}
- return ret;
+ if (ret == -EOPNOTSUPP)
+ mmap_write(bo, offset, size, data);
+
+ return 0;
}
static int
@@ -1807,14 +1889,20 @@ drm_intel_gem_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
ret = drmIoctl(bufmgr_gem->fd,
DRM_IOCTL_I915_GEM_PREAD,
&pread);
- if (ret != 0) {
+ if (ret)
ret = -errno;
+
+ if (ret != 0 && ret != -EOPNOTSUPP) {
DBG("%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
__FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
(int)size, strerror(errno));
+ return ret;
}
- return ret;
+ if (ret == -EOPNOTSUPP)
+ mmap_read(bo, offset, size, data);
+
+ return 0;
}
/** Waits for all GPU rendering with the object to have completed. */