winsys/radeon: handle non-zero finite timeout when waiting for buffers
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a5a96118ed
commit
e321596e9f
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue