From c83562ccaa5f4bd42f4f59c519b48faeb295e354 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 5 Feb 2017 01:20:51 +0100 Subject: [PATCH] gallium: implement the backend of threaded GL dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Acked-by: Timothy Arceri Tested-by: Dieter Nützel Tested-by: Mike Lothian --- src/gallium/include/state_tracker/st_api.h | 19 +++++++++++++++++ src/gallium/state_trackers/dri/dri_context.c | 10 +++++++++ src/gallium/state_trackers/dri/dri_drawable.c | 6 ++++++ src/gallium/state_trackers/dri/dri_screen.c | 21 +++++++++++++++++++ .../drivers/dri/common/xmlpool/t_options.h | 4 ++++ src/mesa/state_tracker/st_context.c | 13 ++++++++++++ src/mesa/state_tracker/st_manager.c | 19 +++++++++++++++++ 7 files changed, 92 insertions(+) diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index a9997744cde..bf9a7e95d7c 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -417,6 +417,19 @@ struct st_context_iface */ boolean (*get_resource_for_egl_image)(struct st_context_iface *stctxi, struct st_context_resource *stres); + + /** + * Start the thread if the API has a worker thread. + * Called after the context has been created and fully initialized on both + * sides (e.g. st/mesa and st/dri). + */ + void (*start_thread)(struct st_context_iface *stctxi); + + /** + * If the API is multithreaded, wait for all queued commands to complete. + * Called from the main thread. + */ + void (*thread_finish)(struct st_context_iface *stctxi); }; @@ -454,6 +467,12 @@ struct st_manager */ int (*get_param)(struct st_manager *smapi, enum st_manager_param param); + + /** + * Call the loader function setBackgroundContext. Called from the worker + * thread. + */ + void (*set_background_context)(struct st_context_iface *stctxi); }; /** diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 3d8af65ca61..91d2d1fbbe8 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -156,6 +156,13 @@ dri_create_context(gl_api api, const struct gl_config * visual, ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context); } + /* Do this last. */ + if (ctx->st->start_thread && + /* the driver loader must implement this */ + screen->sPriv->dri2.backgroundCallable && + driQueryOptionb(&screen->optionCache, "mesa_glthread")) + ctx->st->start_thread(ctx->st); + *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; @@ -222,6 +229,9 @@ dri_make_current(__DRIcontext * cPriv, struct dri_drawable *read = dri_drawable(driReadPriv); struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi); + if (old_st && old_st->thread_finish) + old_st->thread_finish(old_st); + /* Flush the old context here so we don't have to flush on unbind() */ if (old_st && old_st != ctx->st) old_st->flush(old_st, ST_FLUSH_FRONT, NULL); diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index fd3b458de6c..3c2e3075249 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -217,9 +217,13 @@ dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, GLint format, __DRIdrawable *dPriv) { struct dri_context *ctx = dri_context(pDRICtx); + struct st_context_iface *st = ctx->st; struct dri_drawable *drawable = dri_drawable(dPriv); struct pipe_resource *pt; + if (st->thread_finish) + st->thread_finish(st); + dri_drawable_validate_att(ctx, drawable, ST_ATTACHMENT_FRONT_LEFT); /* Use the pipe resource associated with the X drawable */ @@ -453,6 +457,8 @@ dri_flush(__DRIcontext *cPriv, } st = ctx->st; + if (st->thread_finish) + st->thread_finish(st); if (drawable) { /* prevent recursion */ diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 9b37dff6778..799a2649b04 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -33,6 +33,7 @@ #include "xmlpool.h" #include "dri_screen.h" +#include "dri_context.h" #include "util/u_inlines.h" #include "pipe/p_screen.h" @@ -53,6 +54,10 @@ const __DRIconfigOptionsExtension gallium_config_options = { .xml = DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_MESA_GLTHREAD("false") + DRI_CONF_SECTION_END + DRI_CONF_SECTION_QUALITY DRI_CONF_FORCE_S3TC_ENABLE("false") DRI_CONF_PP_CELSHADE(0) @@ -432,6 +437,21 @@ dri_postprocessing_init(struct dri_screen *screen) } } +static void +dri_set_background_context(struct st_context_iface *st) +{ + struct dri_context *ctx = (struct dri_context *)st->st_manager_private; + const __DRIbackgroundCallableExtension *backgroundCallable = + ctx->sPriv->dri2.backgroundCallable; + + /* Note: Mesa will only call this function if GL multithreading is enabled + * We only do that if the loader exposed the __DRI_BACKGROUND_CALLABLE + * extension. So we know that backgroundCallable is not NULL. + */ + assert(backgroundCallable); + backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate); +} + const __DRIconfig ** dri_init_screen_helper(struct dri_screen *screen, struct pipe_screen *pscreen, @@ -440,6 +460,7 @@ dri_init_screen_helper(struct dri_screen *screen, screen->base.screen = pscreen; screen->base.get_egl_image = dri_get_egl_image; screen->base.get_param = dri_get_param; + screen->base.set_background_context = dri_set_background_context; screen->st_api = st_gl_api_create(); if (!screen->st_api) diff --git a/src/mesa/drivers/dri/common/xmlpool/t_options.h b/src/mesa/drivers/dri/common/xmlpool/t_options.h index f200093177d..c7c658d0aac 100644 --- a/src/mesa/drivers/dri/common/xmlpool/t_options.h +++ b/src/mesa/drivers/dri/common/xmlpool/t_options.h @@ -313,6 +313,10 @@ DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ DRI_CONF_DESC_END \ DRI_CONF_OPT_END +#define DRI_CONF_MESA_GLTHREAD(def) \ +DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \ + DRI_CONF_DESC(en,gettext("Enable offloading GL driver work to a separate thread")) \ +DRI_CONF_OPT_END /** diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index a528f343700..869e6e9f87b 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -29,6 +29,7 @@ #include "main/accum.h" #include "main/api_exec.h" #include "main/context.h" +#include "main/glthread.h" #include "main/samplerobj.h" #include "main/shaderobj.h" #include "main/version.h" @@ -612,6 +613,17 @@ st_emit_string_marker(struct gl_context *ctx, const GLchar *string, GLsizei len) st->pipe->emit_string_marker(st->pipe, string, len); } +static void +st_set_background_context(struct gl_context *ctx) +{ + 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); +} + void st_init_driver_functions(struct pipe_screen *screen, struct dd_function_table *functions) { @@ -656,4 +668,5 @@ void st_init_driver_functions(struct pipe_screen *screen, functions->Enable = st_Enable; functions->UpdateState = st_invalidate_state; functions->QueryMemoryInfo = st_query_memory_info; + functions->SetBackgroundContext = st_set_background_context; } diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index e663b017174..dad408a451e 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -29,6 +29,7 @@ #include "main/extensions.h" #include "main/context.h" #include "main/debug_output.h" +#include "main/glthread.h" #include "main/texobj.h" #include "main/teximage.h" #include "main/texstate.h" @@ -629,6 +630,22 @@ st_context_destroy(struct st_context_iface *stctxi) st_destroy_context(st); } +static void +st_start_thread(struct st_context_iface *stctxi) +{ + struct st_context *st = (struct st_context *) stctxi; + + _mesa_glthread_init(st->ctx); +} + +static void +st_thread_finish(struct st_context_iface *stctxi) +{ + struct st_context *st = (struct st_context *) stctxi; + + _mesa_glthread_finish(st->ctx); +} + static struct st_context_iface * st_api_create_context(struct st_api *stapi, struct st_manager *smapi, const struct st_context_attribs *attribs, @@ -723,6 +740,8 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, st->iface.teximage = st_context_teximage; st->iface.copy = st_context_copy; st->iface.share = st_context_share; + st->iface.start_thread = st_start_thread; + st->iface.thread_finish = st_thread_finish; st->iface.st_context_private = (void *) smapi; st->iface.cso_context = st->cso_context; st->iface.pipe = st->pipe; -- 2.30.2