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>main
parent
52f05d3d89
commit
cd3681976c
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue