summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2017-04-05 09:55:15 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2017-04-05 21:17:11 -0700
commitf195d40eca49800799d85d110939a125041f4028 (patch)
treef626e61bf1cad28fddb3a5257ff0d42d035c9b6d
parentd5157ddca4072856e0afce3d7af8929a7d387044 (diff)
anv/device: Add a helper for querying whether a BO is busy
This is a bit more efficient than using GEM_WAIT with a timeout of 0. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/intel/vulkan/anv_device.c34
-rw-r--r--src/intel/vulkan/anv_gem.c17
-rw-r--r--src/intel/vulkan/anv_private.h2
3 files changed, 47 insertions, 6 deletions
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 356b1b5f0d2..35ef4c486b2 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1328,6 +1328,31 @@ anv_device_query_status(struct anv_device *device)
}
VkResult
+anv_device_bo_busy(struct anv_device *device, struct anv_bo *bo)
+{
+ /* Note: This only returns whether or not the BO is in use by an i915 GPU.
+ * Other usages of the BO (such as on different hardware) will not be
+ * flagged as "busy" by this ioctl. Use with care.
+ */
+ int ret = anv_gem_busy(device, bo->gem_handle);
+ if (ret == 1) {
+ return VK_NOT_READY;
+ } else if (ret == -1) {
+ /* We don't know the real error. */
+ device->lost = true;
+ return vk_errorf(VK_ERROR_DEVICE_LOST, "gem wait failed: %m");
+ }
+
+ /* Query for device status after the busy call. If the BO we're checking
+ * got caught in a GPU hang we don't want to return VK_SUCCESS to the
+ * client because it clearly doesn't have valid data. Yes, this most
+ * likely means an ioctl, but we just did an ioctl to query the busy status
+ * so it's no great loss.
+ */
+ return anv_device_query_status(device);
+}
+
+VkResult
anv_device_wait(struct anv_device *device, struct anv_bo *bo,
int64_t timeout)
{
@@ -1906,14 +1931,11 @@ VkResult anv_GetFenceStatus(
return VK_SUCCESS;
case ANV_FENCE_STATE_SUBMITTED: {
- VkResult result = anv_device_wait(device, &fence->bo, 0);
- switch (result) {
- case VK_SUCCESS:
+ VkResult result = anv_device_bo_busy(device, &fence->bo);
+ if (result == VK_SUCCESS) {
fence->state = ANV_FENCE_STATE_SIGNALED;
return VK_SUCCESS;
- case VK_TIMEOUT:
- return VK_NOT_READY;
- default:
+ } else {
return result;
}
}
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index 2d07a3dbb0e..185086fefcc 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -147,6 +147,23 @@ anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle,
}
/**
+ * Returns 0, 1, or negative to indicate error
+ */
+int
+anv_gem_busy(struct anv_device *device, uint32_t gem_handle)
+{
+ struct drm_i915_gem_busy busy = {
+ .handle = gem_handle,
+ };
+
+ int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
+ if (ret < 0)
+ return ret;
+
+ return busy.busy != 0;
+}
+
+/**
* On error, \a timeout_ns holds the remaining time.
*/
int
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 95666d8f4b6..5e07808985a 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -644,6 +644,7 @@ VkResult anv_device_execbuf(struct anv_device *device,
struct drm_i915_gem_execbuffer2 *execbuf,
struct anv_bo **execbuf_bos);
VkResult anv_device_query_status(struct anv_device *device);
+VkResult anv_device_bo_busy(struct anv_device *device, struct anv_bo *bo);
VkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo,
int64_t timeout);
@@ -653,6 +654,7 @@ void anv_gem_munmap(void *p, uint64_t size);
uint32_t anv_gem_create(struct anv_device *device, size_t size);
void anv_gem_close(struct anv_device *device, uint32_t gem_handle);
uint32_t anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
+int anv_gem_busy(struct anv_device *device, uint32_t gem_handle);
int anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns);
int anv_gem_execbuffer(struct anv_device *device,
struct drm_i915_gem_execbuffer2 *execbuf);