summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-08-22 18:05:37 +0200
committerMarek Olšák <[email protected]>2015-08-29 23:03:06 +0200
commite321596e9f66207cc679b4ddbee13d4c8cdb896f (patch)
tree7559e8398f36bb8e05a00b3271543a83b14705cf
parenta5a96118ed728969c5a41e643cf6ffd0c42461f0 (diff)
winsys/radeon: handle non-zero finite timeout when waiting for buffers
Reviewed-by: Alex Deucher <[email protected]>
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c54
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_cs.c25
2 files changed, 41 insertions, 38 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 3a9ac445b24..600ced924ba 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -101,30 +101,54 @@ static struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf)
return bo;
}
+static bool radeon_bo_is_busy(struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_busy args = {0};
+
+ args.handle = bo->handle;
+ return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
+ &args, sizeof(args)) != 0;
+}
+
+static void radeon_bo_wait_idle(struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_wait_idle args = {0};
+
+ args.handle = bo->handle;
+ while (drmCommandWrite(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
+ &args, sizeof(args)) == -EBUSY);
+}
+
static bool radeon_bo_wait(struct pb_buffer *_buf, uint64_t timeout,
enum radeon_bo_usage usage)
{
- struct radeon_bo *bo = get_radeon_bo(_buf);
+ struct radeon_bo *bo = get_radeon_bo(_buf);
+ int64_t abs_timeout;
- /* Wait if any ioctl is being submitted with this buffer. */
- if (!os_wait_until_zero(&bo->num_active_ioctls, timeout))
- return false;
+ /* No timeout. Just query. */
+ if (timeout == 0)
+ return !bo->num_active_ioctls && !radeon_bo_is_busy(bo);
- /* TODO: handle arbitrary timeout */
- if (!timeout) {
- struct drm_radeon_gem_busy args = {0};
+ abs_timeout = os_time_get_absolute_timeout(timeout);
- args.handle = bo->handle;
- return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
- &args, sizeof(args)) == 0;
- } else {
- struct drm_radeon_gem_wait_idle args = {0};
+ /* Wait if any ioctl is being submitted with this buffer. */
+ if (!os_wait_until_zero_abs_timeout(&bo->num_active_ioctls, abs_timeout))
+ return false;
- args.handle = bo->handle;
- while (drmCommandWrite(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
- &args, sizeof(args)) == -EBUSY);
+ /* Infinite timeout. */
+ if (abs_timeout == PIPE_TIMEOUT_INFINITE) {
+ radeon_bo_wait_idle(bo);
return true;
}
+
+ /* Other timeouts need to be emulated with a loop. */
+ while (radeon_bo_is_busy(bo)) {
+ if (os_time_get_nano() >= abs_timeout)
+ return false;
+ os_time_sleep(10);
+ }
+
+ return true;
}
static enum radeon_bo_domain get_valid_domain(enum radeon_bo_domain domain)
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index f04a696988a..341af55df8b 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -645,29 +645,8 @@ static bool radeon_fence_wait(struct radeon_winsys *ws,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
- struct pb_buffer *rfence = (struct pb_buffer*)fence;
-
- if (timeout == 0)
- return ws->buffer_wait(rfence, 0, RADEON_USAGE_READWRITE);
-
- if (timeout != PIPE_TIMEOUT_INFINITE) {
- int64_t start_time = os_time_get();
-
- /* Convert to microseconds. */
- timeout /= 1000;
-
- /* Wait in a loop. */
- while (!ws->buffer_wait(rfence, 0, RADEON_USAGE_READWRITE)) {
- if (os_time_get() - start_time >= timeout) {
- return FALSE;
- }
- os_time_sleep(10);
- }
- return TRUE;
- }
-
- ws->buffer_wait(rfence, PIPE_TIMEOUT_INFINITE, RADEON_USAGE_READWRITE);
- return TRUE;
+ return ws->buffer_wait((struct pb_buffer*)fence, timeout,
+ RADEON_USAGE_READWRITE);
}
static void radeon_fence_reference(struct pipe_fence_handle **dst,