[Mesa-dev] [PATCH 2/2] winsys/radeon: use the common job queue for multithreaded command submission v2
Marek Olšák
maraeo at gmail.com
Tue Jun 14 17:06:07 UTC 2016
From: Marek Olšák <marek.olsak at amd.com>
v2: fixup after renaming to util_queue_fence
---
src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 22 ++++----
src/gallium/winsys/radeon/drm/radeon_drm_cs.h | 4 +-
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 63 ++---------------------
src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 12 ++---
4 files changed, 19 insertions(+), 82 deletions(-)
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index e9ab53d..9552bd5 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -177,7 +177,7 @@ radeon_drm_cs_create(struct radeon_winsys_ctx *ctx,
if (!cs) {
return NULL;
}
- pipe_semaphore_init(&cs->flush_completed, 1);
+ util_queue_fence_init(&cs->flush_completed);
cs->ws = ws;
cs->flush_cs = flush;
@@ -427,8 +427,9 @@ static unsigned radeon_drm_cs_get_buffer_list(struct radeon_winsys_cs *rcs,
return cs->csc->crelocs;
}
-void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_drm_cs *cs, struct radeon_cs_context *csc)
+void radeon_drm_cs_emit_ioctl_oneshot(void *job)
{
+ struct radeon_cs_context *csc = ((struct radeon_drm_cs*)job)->cst;
unsigned i;
int r;
@@ -463,11 +464,9 @@ void radeon_drm_cs_sync_flush(struct radeon_winsys_cs *rcs)
{
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
- /* Wait for any pending ioctl to complete. */
- if (cs->ws->thread) {
- pipe_semaphore_wait(&cs->flush_completed);
- pipe_semaphore_signal(&cs->flush_completed);
- }
+ /* Wait for any pending ioctl of this CS to complete. */
+ if (util_queue_is_initialized(&cs->ws->cs_queue))
+ util_queue_job_wait(&cs->flush_completed);
}
DEBUG_GET_ONCE_BOOL_OPTION(noop, "RADEON_NOOP", FALSE)
@@ -586,13 +585,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
break;
}
- if (cs->ws->thread) {
- pipe_semaphore_wait(&cs->flush_completed);
- radeon_drm_ws_queue_cs(cs->ws, cs);
+ if (util_queue_is_initialized(&cs->ws->cs_queue)) {
+ util_queue_add_job(&cs->ws->cs_queue, cs, &cs->flush_completed);
if (!(flags & RADEON_FLUSH_ASYNC))
radeon_drm_cs_sync_flush(rcs);
} else {
- radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
+ radeon_drm_cs_emit_ioctl_oneshot(cs);
}
} else {
radeon_cs_context_cleanup(cs->cst);
@@ -610,7 +608,7 @@ static void radeon_drm_cs_destroy(struct radeon_winsys_cs *rcs)
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
radeon_drm_cs_sync_flush(rcs);
- pipe_semaphore_destroy(&cs->flush_completed);
+ util_queue_fence_destroy(&cs->flush_completed);
radeon_cs_context_cleanup(&cs->csc1);
radeon_cs_context_cleanup(&cs->csc2);
p_atomic_dec(&cs->ws->num_cs);
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index 8056e72..a5f243d 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -78,7 +78,7 @@ struct radeon_drm_cs {
void (*flush_cs)(void *ctx, unsigned flags, struct pipe_fence_handle **fence);
void *flush_data;
- pipe_semaphore flush_completed;
+ struct util_queue_fence flush_completed;
};
int radeon_lookup_buffer(struct radeon_cs_context *csc, struct radeon_bo *bo);
@@ -122,6 +122,6 @@ radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo)
void radeon_drm_cs_sync_flush(struct radeon_winsys_cs *rcs);
void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws);
-void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_drm_cs *cs, struct radeon_cs_context *csc);
+void radeon_drm_cs_emit_ioctl_oneshot(void *job);
#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 5c85c8f..1f296f4 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -534,16 +534,11 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
{
struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
- if (ws->thread) {
- ws->kill_thread = 1;
- pipe_semaphore_signal(&ws->cs_queued);
- pipe_thread_wait(ws->thread);
- }
- pipe_semaphore_destroy(&ws->cs_queued);
+ if (util_queue_is_initialized(&ws->cs_queue))
+ util_queue_destroy(&ws->cs_queue);
pipe_mutex_destroy(ws->hyperz_owner_mutex);
pipe_mutex_destroy(ws->cmask_owner_mutex);
- pipe_mutex_destroy(ws->cs_stack_lock);
pb_cache_deinit(&ws->bo_cache);
@@ -686,55 +681,7 @@ static int compare_fd(void *key1, void *key2)
stat1.st_rdev != stat2.st_rdev;
}
-void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs)
-{
-retry:
- pipe_mutex_lock(ws->cs_stack_lock);
- if (ws->ncs >= RING_LAST) {
- /* no room left for a flush */
- pipe_mutex_unlock(ws->cs_stack_lock);
- goto retry;
- }
- ws->cs_stack[ws->ncs++] = cs;
- pipe_mutex_unlock(ws->cs_stack_lock);
- pipe_semaphore_signal(&ws->cs_queued);
-}
-
-static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
-{
- struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)param;
- struct radeon_drm_cs *cs;
- unsigned i;
-
- while (1) {
- pipe_semaphore_wait(&ws->cs_queued);
- if (ws->kill_thread)
- break;
-
- pipe_mutex_lock(ws->cs_stack_lock);
- cs = ws->cs_stack[0];
- for (i = 1; i < ws->ncs; i++)
- ws->cs_stack[i - 1] = ws->cs_stack[i];
- ws->cs_stack[--ws->ncs] = NULL;
- pipe_mutex_unlock(ws->cs_stack_lock);
-
- if (cs) {
- radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
- pipe_semaphore_signal(&cs->flush_completed);
- }
- }
- pipe_mutex_lock(ws->cs_stack_lock);
- for (i = 0; i < ws->ncs; i++) {
- pipe_semaphore_signal(&ws->cs_stack[i]->flush_completed);
- ws->cs_stack[i] = NULL;
- }
- ws->ncs = 0;
- pipe_mutex_unlock(ws->cs_stack_lock);
- return 0;
-}
-
DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE)
-static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param);
static bool radeon_winsys_unref(struct radeon_winsys *ws)
{
@@ -823,7 +770,6 @@ radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
pipe_mutex_init(ws->hyperz_owner_mutex);
pipe_mutex_init(ws->cmask_owner_mutex);
- pipe_mutex_init(ws->cs_stack_lock);
ws->bo_names = util_hash_table_create(handle_hash, handle_compare);
ws->bo_handles = util_hash_table_create(handle_hash, handle_compare);
@@ -836,10 +782,9 @@ radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create)
/* TTM aligns the BO size to the CPU page size */
ws->info.gart_page_size = sysconf(_SC_PAGESIZE);
- ws->ncs = 0;
- pipe_semaphore_init(&ws->cs_queued, 0);
if (ws->num_cpus > 1 && debug_get_option_thread())
- ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);
+ util_queue_init(&ws->cs_queue,
+ radeon_drm_cs_emit_ioctl_oneshot);
/* Create the screen at the end. The winsys must be initialized
* completely.
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 80de561..c429aba 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -32,7 +32,7 @@
#include "gallium/drivers/radeon/radeon_winsys.h"
#include "pipebuffer/pb_cache.h"
-#include "os/os_thread.h"
+#include "util/u_queue.h"
#include "util/list.h"
#include <radeon_drm.h>
@@ -101,13 +101,8 @@ struct radeon_drm_winsys {
struct radeon_drm_cs *cmask_owner;
pipe_mutex cmask_owner_mutex;
- /* rings submission thread */
- pipe_mutex cs_stack_lock;
- pipe_semaphore cs_queued;
- pipe_thread thread;
- int kill_thread;
- int ncs;
- struct radeon_drm_cs *cs_stack[RING_LAST];
+ /* multithreaded command submission */
+ struct util_queue cs_queue;
};
static inline struct radeon_drm_winsys *
@@ -116,7 +111,6 @@ radeon_drm_winsys(struct radeon_winsys *base)
return (struct radeon_drm_winsys*)base;
}
-void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs);
void radeon_surface_init_functions(struct radeon_drm_winsys *ws);
#endif
--
2.7.4
More information about the mesa-dev
mailing list