diff options
-rw-r--r-- | src/gallium/auxiliary/hud/hud_context.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/hud/hud_context.h | 5 | ||||
-rw-r--r-- | src/gallium/auxiliary/hud/hud_private.h | 2 | ||||
-rw-r--r-- | src/gallium/include/state_tracker/st_api.h | 4 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_screen.c | 6 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 4 | ||||
-rw-r--r-- | src/mesa/main/glthread.c | 21 | ||||
-rw-r--r-- | src/mesa/main/glthread.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 5 | ||||
-rw-r--r-- | src/util/u_queue.h | 14 |
10 files changed, 65 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c index f32831b55f9..551cea97a79 100644 --- a/src/gallium/auxiliary/hud/hud_context.c +++ b/src/gallium/auxiliary/hud/hud_context.c @@ -1694,3 +1694,11 @@ hud_destroy(struct hud_context *hud) pipe_resource_reference(&hud->font.texture, NULL); FREE(hud); } + +void +hud_add_queue_for_monitoring(struct hud_context *hud, + struct util_queue_monitoring *queue_info) +{ + assert(!hud->monitored_queue); + hud->monitored_queue = queue_info; +} diff --git a/src/gallium/auxiliary/hud/hud_context.h b/src/gallium/auxiliary/hud/hud_context.h index abf2ad58642..5a7e13b2732 100644 --- a/src/gallium/auxiliary/hud/hud_context.h +++ b/src/gallium/auxiliary/hud/hud_context.h @@ -32,6 +32,7 @@ struct hud_context; struct cso_context; struct pipe_context; struct pipe_resource; +struct util_queue_monitoring; struct hud_context * hud_create(struct pipe_context *pipe, struct cso_context *cso); @@ -42,4 +43,8 @@ hud_destroy(struct hud_context *hud); void hud_draw(struct hud_context *hud, struct pipe_resource *tex); +void +hud_add_queue_for_monitoring(struct hud_context *hud, + struct util_queue_monitoring *queue_info); + #endif diff --git a/src/gallium/auxiliary/hud/hud_private.h b/src/gallium/auxiliary/hud/hud_private.h index f765bd9649c..fba919e5410 100644 --- a/src/gallium/auxiliary/hud/hud_private.h +++ b/src/gallium/auxiliary/hud/hud_private.h @@ -40,6 +40,8 @@ struct hud_context { struct hud_batch_query_context *batch_query; struct list_head pane_list; + struct util_queue_monitoring *monitored_queue; + /* states */ struct pipe_blend_state no_blend, alpha_blend; struct pipe_depth_stencil_alpha_state dsa; diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index 47d06c869c6..d641092aa23 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -179,6 +179,7 @@ enum st_manager_param { struct pipe_context; struct pipe_resource; struct pipe_fence_handle; +struct util_queue_monitoring; /** * Used in st_context_iface->get_resource_for_egl_image. @@ -474,7 +475,8 @@ struct st_manager * Call the loader function setBackgroundContext. Called from the worker * thread. */ - void (*set_background_context)(struct st_context_iface *stctxi); + void (*set_background_context)(struct st_context_iface *stctxi, + struct util_queue_monitoring *queue_info); }; /** diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index aa215b09a2d..6b58830e0b4 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -447,7 +447,8 @@ dri_postprocessing_init(struct dri_screen *screen) } static void -dri_set_background_context(struct st_context_iface *st) +dri_set_background_context(struct st_context_iface *st, + struct util_queue_monitoring *queue_info) { struct dri_context *ctx = (struct dri_context *)st->st_manager_private; const __DRIbackgroundCallableExtension *backgroundCallable = @@ -459,6 +460,9 @@ dri_set_background_context(struct st_context_iface *st) */ assert(backgroundCallable); backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate); + + if (ctx->hud) + hud_add_queue_for_monitoring(ctx->hud, queue_info); } unsigned diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 84ed57f2df0..8e382e1e9a4 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -50,6 +50,7 @@ struct gl_shader_program; struct gl_texture_image; struct gl_texture_object; struct gl_memory_info; +struct util_queue_monitoring; /* GL_ARB_vertex_buffer_object */ /* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return @@ -1039,7 +1040,8 @@ struct dd_function_table { * * Mesa will only call this function if GL multithreading is enabled. */ - void (*SetBackgroundContext)(struct gl_context *ctx); + void (*SetBackgroundContext)(struct gl_context *ctx, + struct util_queue_monitoring *queue_info); /** * \name GL_ARB_sparse_buffer interface diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c index d467298b639..c71c03778aa 100644 --- a/src/mesa/main/glthread.c +++ b/src/mesa/main/glthread.c @@ -36,6 +36,7 @@ #include "main/glthread.h" #include "main/marshal.h" #include "main/marshal_generated.h" +#include "util/u_atomic.h" #include "util/u_thread.h" @@ -60,7 +61,7 @@ glthread_thread_initialization(void *job, int thread_index) { struct gl_context *ctx = (struct gl_context*)job; - ctx->Driver.SetBackgroundContext(ctx); + ctx->Driver.SetBackgroundContext(ctx, &ctx->GLThread->stats); _glapi_set_context(ctx); } @@ -90,6 +91,7 @@ _mesa_glthread_init(struct gl_context *ctx) util_queue_fence_init(&glthread->batches[i].fence); } + glthread->stats.queue = &glthread->queue; ctx->CurrentClientDispatch = ctx->MarshalExec; ctx->GLThread = glthread; @@ -159,6 +161,8 @@ _mesa_glthread_flush_batch(struct gl_context *ctx) return; } + p_atomic_add(&glthread->stats.num_offloaded_items, next->used); + util_queue_add_job(&glthread->queue, next, &next->fence, glthread_unmarshal_batch, NULL); glthread->last = glthread->next; @@ -188,16 +192,29 @@ _mesa_glthread_finish(struct gl_context *ctx) struct glthread_batch *last = &glthread->batches[glthread->last]; struct glthread_batch *next = &glthread->batches[glthread->next]; + bool synced = false; - if (!util_queue_fence_is_signalled(&last->fence)) + if (!util_queue_fence_is_signalled(&last->fence)) { util_queue_fence_wait(&last->fence); + synced = true; + } if (next->used) { + p_atomic_add(&glthread->stats.num_direct_items, next->used); + /* Since glthread_unmarshal_batch changes the dispatch to direct, * restore it after it's done. */ struct _glapi_table *dispatch = _glapi_get_dispatch(); glthread_unmarshal_batch(next, 0); _glapi_set_dispatch(dispatch); + + /* It's not a sync because we don't enqueue partial batches, but + * it would be a sync if we did. So count it anyway. + */ + synced = true; } + + if (synced) + p_atomic_inc(&glthread->stats.num_syncs); } diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h index 5b938fdeef9..36692fe5704 100644 --- a/src/mesa/main/glthread.h +++ b/src/mesa/main/glthread.h @@ -65,6 +65,9 @@ struct glthread_state /** Multithreaded queue. */ struct util_queue queue; + /** This is sent to the driver for framebuffer overlay / HUD. */ + struct util_queue_monitoring stats; + /** The ring of batches in memory. */ struct glthread_batch batches[MARSHAL_MAX_BATCHES]; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index f57cd6a4256..f5351398474 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -629,14 +629,15 @@ st_emit_string_marker(struct gl_context *ctx, const GLchar *string, GLsizei len) } static void -st_set_background_context(struct gl_context *ctx) +st_set_background_context(struct gl_context *ctx, + struct util_queue_monitoring *queue_info) { struct st_context *st = ctx->st; struct st_manager *smapi = (struct st_manager*)st->iface.st_context_private; assert(smapi->set_background_context); - smapi->set_background_context(&st->iface); + smapi->set_background_context(&st->iface, queue_info); } void st_init_driver_functions(struct pipe_screen *screen, diff --git a/src/util/u_queue.h b/src/util/u_queue.h index 8ec959814b0..edd6babb5c7 100644 --- a/src/util/u_queue.h +++ b/src/util/u_queue.h @@ -115,6 +115,20 @@ util_queue_fence_is_signalled(struct util_queue_fence *fence) return fence->signalled != 0; } +/* Convenient structure for monitoring the queue externally and passing + * the structure between Mesa components. The queue doesn't use it directly. + */ +struct util_queue_monitoring +{ + /* For querying the thread busyness. */ + struct util_queue *queue; + + /* Counters updated by the user of the queue. */ + unsigned num_offloaded_items; + unsigned num_direct_items; + unsigned num_syncs; +}; + #ifdef __cplusplus } #endif |