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>
This commit is contained in:
@@ -1327,6 +1327,31 @@ anv_device_query_status(struct anv_device *device)
|
|||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
VkResult
|
||||||
anv_device_wait(struct anv_device *device, struct anv_bo *bo,
|
anv_device_wait(struct anv_device *device, struct anv_bo *bo,
|
||||||
int64_t timeout)
|
int64_t timeout)
|
||||||
@@ -1906,14 +1931,11 @@ VkResult anv_GetFenceStatus(
|
|||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
case ANV_FENCE_STATE_SUBMITTED: {
|
case ANV_FENCE_STATE_SUBMITTED: {
|
||||||
VkResult result = anv_device_wait(device, &fence->bo, 0);
|
VkResult result = anv_device_bo_busy(device, &fence->bo);
|
||||||
switch (result) {
|
if (result == VK_SUCCESS) {
|
||||||
case VK_SUCCESS:
|
|
||||||
fence->state = ANV_FENCE_STATE_SIGNALED;
|
fence->state = ANV_FENCE_STATE_SIGNALED;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
case VK_TIMEOUT:
|
} else {
|
||||||
return VK_NOT_READY;
|
|
||||||
default:
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -146,6 +146,23 @@ anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle,
|
|||||||
return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &gem_set_domain);
|
return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &gem_set_domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* On error, \a timeout_ns holds the remaining time.
|
||||||
*/
|
*/
|
||||||
|
@@ -644,6 +644,7 @@ VkResult anv_device_execbuf(struct anv_device *device,
|
|||||||
struct drm_i915_gem_execbuffer2 *execbuf,
|
struct drm_i915_gem_execbuffer2 *execbuf,
|
||||||
struct anv_bo **execbuf_bos);
|
struct anv_bo **execbuf_bos);
|
||||||
VkResult anv_device_query_status(struct anv_device *device);
|
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,
|
VkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo,
|
||||||
int64_t timeout);
|
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);
|
uint32_t anv_gem_create(struct anv_device *device, size_t size);
|
||||||
void anv_gem_close(struct anv_device *device, uint32_t gem_handle);
|
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);
|
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_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns);
|
||||||
int anv_gem_execbuffer(struct anv_device *device,
|
int anv_gem_execbuffer(struct anv_device *device,
|
||||||
struct drm_i915_gem_execbuffer2 *execbuf);
|
struct drm_i915_gem_execbuffer2 *execbuf);
|
||||||
|
Reference in New Issue
Block a user