mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
winsys/radeon: hook up the new DRM_RADEON_GEM_WAIT ioctl
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
296b899095
commit
1e3c81a068
4 changed files with 65 additions and 24 deletions
|
|
@ -454,7 +454,7 @@ static boolean r300_fence_signalled(struct pipe_screen *screen,
|
|||
struct radeon_winsys *rws = r300_screen(screen)->rws;
|
||||
struct pb_buffer *rfence = (struct pb_buffer*)fence;
|
||||
|
||||
return !rws->buffer_is_busy(rfence);
|
||||
return !rws->buffer_is_busy(rfence, RADEON_USAGE_READWRITE);
|
||||
}
|
||||
|
||||
static boolean r300_fence_finish(struct pipe_screen *screen,
|
||||
|
|
@ -471,7 +471,7 @@ static boolean r300_fence_finish(struct pipe_screen *screen,
|
|||
timeout /= 1000;
|
||||
|
||||
/* Wait in a loop. */
|
||||
while (rws->buffer_is_busy(rfence)) {
|
||||
while (rws->buffer_is_busy(rfence, RADEON_USAGE_READWRITE)) {
|
||||
if (os_time_get() - start_time >= timeout) {
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -480,7 +480,7 @@ static boolean r300_fence_finish(struct pipe_screen *screen,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
rws->buffer_wait(rfence);
|
||||
rws->buffer_wait(rfence, RADEON_USAGE_READWRITE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
|
|||
referenced_hw = TRUE;
|
||||
} else {
|
||||
referenced_hw =
|
||||
r300->rws->buffer_is_busy(tex->buf);
|
||||
r300->rws->buffer_is_busy(tex->buf, RADEON_USAGE_READWRITE);
|
||||
}
|
||||
|
||||
blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,21 @@
|
|||
#define RADEON_BO_FLAGS_MICRO_TILE 2
|
||||
#define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20
|
||||
|
||||
#ifndef DRM_RADEON_GEM_WAIT
|
||||
#define DRM_RADEON_GEM_WAIT 0x2b
|
||||
|
||||
#define RADEON_GEM_NO_WAIT 0x1
|
||||
#define RADEON_GEM_USAGE_READ 0x2
|
||||
#define RADEON_GEM_USAGE_WRITE 0x4
|
||||
|
||||
struct drm_radeon_gem_wait {
|
||||
uint32_t handle;
|
||||
uint32_t flags; /* one of RADEON_GEM_* */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
extern const struct pb_vtbl radeon_bo_vtbl;
|
||||
|
||||
|
||||
|
|
@ -87,35 +102,49 @@ static struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf)
|
|||
return bo;
|
||||
}
|
||||
|
||||
static void radeon_bo_wait(struct pb_buffer *_buf)
|
||||
static void radeon_bo_wait(struct pb_buffer *_buf, enum radeon_bo_usage usage)
|
||||
{
|
||||
struct radeon_bo *bo = get_radeon_bo(_buf);
|
||||
struct drm_radeon_gem_wait_idle args = {};
|
||||
|
||||
while (p_atomic_read(&bo->num_active_ioctls)) {
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
args.handle = bo->handle;
|
||||
while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
|
||||
&args, sizeof(args)) == -EBUSY);
|
||||
if (bo->rws->info.drm_minor >= 12) {
|
||||
struct drm_radeon_gem_wait args = {};
|
||||
args.handle = bo->handle;
|
||||
args.flags = usage;
|
||||
while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
|
||||
&args, sizeof(args)) == -EBUSY);
|
||||
} else {
|
||||
struct drm_radeon_gem_wait_idle args = {};
|
||||
args.handle = bo->handle;
|
||||
while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
|
||||
&args, sizeof(args)) == -EBUSY);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean radeon_bo_is_busy(struct pb_buffer *_buf)
|
||||
static boolean radeon_bo_is_busy(struct pb_buffer *_buf,
|
||||
enum radeon_bo_usage usage)
|
||||
{
|
||||
struct radeon_bo *bo = get_radeon_bo(_buf);
|
||||
struct drm_radeon_gem_busy args = {};
|
||||
boolean busy;
|
||||
|
||||
if (p_atomic_read(&bo->num_active_ioctls)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
args.handle = bo->handle;
|
||||
busy = drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
|
||||
&args, sizeof(args)) != 0;
|
||||
|
||||
return busy;
|
||||
if (bo->rws->info.drm_minor >= 12) {
|
||||
struct drm_radeon_gem_wait args = {};
|
||||
args.handle = bo->handle;
|
||||
args.flags = usage | RADEON_GEM_NO_WAIT;
|
||||
return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
|
||||
&args, sizeof(args)) != 0;
|
||||
} else {
|
||||
struct drm_radeon_gem_busy args = {};
|
||||
args.handle = bo->handle;
|
||||
return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
|
||||
&args, sizeof(args)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void radeon_bo_destroy(struct pb_buffer *_buf)
|
||||
|
|
@ -173,7 +202,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (radeon_bo_is_busy((struct pb_buffer*)bo)) {
|
||||
if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -187,10 +216,12 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
|
|||
* Only check whether the buffer is being used for write. */
|
||||
if (radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
|
||||
cs->flush_cs(cs->flush_data, 0);
|
||||
radeon_bo_wait((struct pb_buffer*)bo);
|
||||
radeon_bo_wait((struct pb_buffer*)bo,
|
||||
RADEON_USAGE_READWRITE);
|
||||
} else {
|
||||
/* XXX We could check whether the buffer is busy for write here. */
|
||||
radeon_bo_wait((struct pb_buffer*)bo);
|
||||
radeon_bo_wait((struct pb_buffer*)bo,
|
||||
RADEON_USAGE_READWRITE);
|
||||
}
|
||||
} else {
|
||||
/* Mapping for write. */
|
||||
|
|
@ -202,7 +233,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
|
|||
radeon_drm_cs_sync_flush(cs);
|
||||
}
|
||||
|
||||
radeon_bo_wait((struct pb_buffer*)bo);
|
||||
radeon_bo_wait((struct pb_buffer*)bo, RADEON_USAGE_READWRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +369,7 @@ static boolean radeon_bomgr_is_buffer_busy(struct pb_manager *_mgr,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (radeon_bo_is_busy((struct pb_buffer*)bo)) {
|
||||
if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,12 @@ enum radeon_bo_domain { /* bitfield */
|
|||
RADEON_DOMAIN_VRAM = 4
|
||||
};
|
||||
|
||||
enum radeon_bo_usage { /* bitfield */
|
||||
RADEON_USAGE_READ = 2,
|
||||
RADEON_USAGE_WRITE = 4,
|
||||
RADEON_USAGE_READWRITE = RADEON_USAGE_READ | RADEON_USAGE_WRITE
|
||||
};
|
||||
|
||||
struct winsys_handle;
|
||||
struct radeon_winsys_cs_handle; /* for write_reloc etc. */
|
||||
|
||||
|
|
@ -162,8 +168,10 @@ struct radeon_winsys {
|
|||
* Return TRUE if a buffer object is being used by the GPU.
|
||||
*
|
||||
* \param buf A winsys buffer object.
|
||||
* \param usage Only check whether the buffer is busy for the given usage.
|
||||
*/
|
||||
boolean (*buffer_is_busy)(struct pb_buffer *buf);
|
||||
boolean (*buffer_is_busy)(struct pb_buffer *buf,
|
||||
enum radeon_bo_usage usage);
|
||||
|
||||
/**
|
||||
* Wait for a buffer object until it is not used by a GPU. This is
|
||||
|
|
@ -171,8 +179,10 @@ struct radeon_winsys {
|
|||
* and synchronizing to the fence.
|
||||
*
|
||||
* \param buf A winsys buffer object to wait for.
|
||||
* \param usage Only wait until the buffer is idle for the given usage,
|
||||
* but may still be busy for some other usage.
|
||||
*/
|
||||
void (*buffer_wait)(struct pb_buffer *buf);
|
||||
void (*buffer_wait)(struct pb_buffer *buf, enum radeon_bo_usage usage);
|
||||
|
||||
/**
|
||||
* Return tiling flags describing a memory layout of a buffer object.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue