From: Marek Olšák <marek.ol...@amd.com> --- 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 +++++++++++++++++++++ src/mesa/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 a2e37d2..19c38af 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -407,20 +407,33 @@ struct st_context_iface boolean (*share)(struct st_context_iface *stctxi, struct st_context_iface *stsrci); /** * Look up and return the info of a resource for EGLImage. * * This function is optional. */ 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); }; /** * Represent a state tracker manager. * * This interface is implemented by the state tracker manager. It corresponds * to a "display" in the window system. */ struct st_manager @@ -444,20 +457,26 @@ struct st_manager */ boolean (*get_egl_image)(struct st_manager *smapi, void *egl_image, struct st_egl_image *out); /** * Query an manager param. */ 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); }; /** * Represent a rendering API such as OpenGL or OpenVG. * * Implemented by the state tracker and used by the state tracker manager. */ struct st_api { /** diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 3d8af65..91d2d1f 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -149,20 +149,27 @@ dri_create_context(gl_api api, const struct gl_config * visual, goto fail; } ctx->st->st_manager_private = (void *) ctx; ctx->stapi = stapi; if (ctx->st->cso_context) { ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, ctx->st->cso_context); 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; fail: if (ctx && ctx->st) ctx->st->destroy(ctx->st); free(ctx); return GL_FALSE; } @@ -215,20 +222,23 @@ GLboolean dri_make_current(__DRIcontext * cPriv, __DRIdrawable * driDrawPriv, __DRIdrawable * driReadPriv) { /* dri_util.c ensures cPriv is not null */ struct dri_context *ctx = dri_context(cPriv); struct dri_drawable *draw = dri_drawable(driDrawPriv); 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); ++ctx->bind_count; if (!draw && !read) return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL); else if (!draw || !read) return GL_FALSE; diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index fd3b458..3c2e307 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -210,23 +210,27 @@ dri_drawable_validate_att(struct dri_context *ctx, } /** * These are used for GLX_EXT_texture_from_pixmap */ static void 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 */ pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; if (pt) { enum pipe_format internal_format = pt->format; if (format == __DRI_TEXTURE_FORMAT_RGB) { /* only need to cover the formats recognized by dri_fill_st_visual */ @@ -446,20 +450,22 @@ dri_flush(__DRIcontext *cPriv, struct st_context_iface *st; unsigned flush_flags; boolean swap_msaa_buffers = FALSE; if (!ctx) { assert(0); return; } st = ctx->st; + if (st->thread_finish) + st->thread_finish(st); if (drawable) { /* prevent recursion */ if (drawable->flushing) return; drawable->flushing = TRUE; } else { flags &= ~__DRI2_FLUSH_DRAWABLE; diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 9a8a0f9..308e12f 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -26,40 +26,45 @@ **************************************************************************/ /* * Author: Keith Whitwell <kei...@vmware.com> * Author: Jakob Bornecrantz <wallbra...@gmail.com> */ #include "utils.h" #include "xmlpool.h" #include "dri_screen.h" +#include "dri_context.h" #include "util/u_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_format.h" #include "pipe-loader/pipe_loader.h" #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ #include "state_tracker/drm_driver.h" #include "util/u_debug.h" #include "util/u_format_s3tc.h" #define MSAA_VISUAL_MAX_SAMPLES 32 #undef false const __DRIconfigOptionsExtension gallium_config_options = { .base = { __DRI_CONFIG_OPTIONS, 1 }, .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) DRI_CONF_PP_NORED(0) DRI_CONF_PP_NOGREEN(0) DRI_CONF_PP_NOBLUE(0) DRI_CONF_PP_JIMENEZMLAA(0, 0, 32) DRI_CONF_PP_JIMENEZMLAA_COLOR(0, 0, 32) DRI_CONF_SECTION_END @@ -420,28 +425,44 @@ static void dri_postprocessing_init(struct dri_screen *screen) { unsigned i; for (i = 0; i < PP_FILTERS; i++) { screen->pp_enabled[i] = driQueryOptioni(&screen->optionCache, pp_filters[i].name); } } +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, const char* driver_name) { 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) return NULL; if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) screen->target = PIPE_TEXTURE_2D; else screen->target = PIPE_TEXTURE_RECT; diff --git a/src/mesa/drivers/dri/common/xmlpool/t_options.h b/src/mesa/drivers/dri/common/xmlpool/t_options.h index a189bbe..fde9191 100644 --- a/src/mesa/drivers/dri/common/xmlpool/t_options.h +++ b/src/mesa/drivers/dri/common/xmlpool/t_options.h @@ -301,20 +301,24 @@ DRI_CONF_OPT_END #define DRI_CONF_TEXTURE_HEAPS_GART 2 #define DRI_CONF_TEXTURE_HEAPS(def) \ DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ DRI_CONF_DESC_BEGIN(en,gettext("Used types of texture memory")) \ DRI_CONF_ENUM(0,gettext("All available memory")) \ DRI_CONF_ENUM(1,gettext("Only card memory (if available)")) \ DRI_CONF_ENUM(2,gettext("Only GART (AGP/PCIE) memory (if available)")) \ 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 /** * \brief Software-fallback options. To allow using features (like * GL_ARB_vertex_program) on GPUs that don't otherwise support the feature. */ #define DRI_CONF_SECTION_SOFTWARE \ DRI_CONF_SECTION_BEGIN \ DRI_CONF_DESC(en,gettext("Features that are not hardware-accelerated")) diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 5523734..ab3db0e 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -22,20 +22,21 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ #include "main/imports.h" #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" #include "main/vtxfmt.h" #include "main/hash.h" #include "program/prog_cache.h" #include "vbo/vbo.h" #include "glapi/glapi.h" #include "st_context.h" #include "st_debug.h" @@ -617,20 +618,31 @@ void st_destroy_context( struct st_context *st ) free(ctx); } static void st_emit_string_marker(struct gl_context *ctx, const GLchar *string, GLsizei len) { struct st_context *st = ctx->st; 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) { _mesa_init_shader_object_functions(functions); _mesa_init_sampler_object_functions(functions); st_init_blit_functions(functions); st_init_bufferobject_functions(screen, functions); st_init_clear_functions(functions); st_init_bitmap_functions(functions); @@ -661,11 +673,12 @@ void st_init_driver_functions(struct pipe_screen *screen, st_init_syncobj_functions(functions); st_init_vdpau_functions(functions); if (screen->get_param(screen, PIPE_CAP_STRING_MARKER)) functions->EmitStringMarker = st_emit_string_marker; 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 c3d8286..f2bd53b 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -22,20 +22,21 @@ * DEALINGS IN THE SOFTWARE. * * Authors: * Chia-I Wu <o...@lunarg.com> */ #include "main/mtypes.h" #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" #include "main/errors.h" #include "main/framebuffer.h" #include "main/fbobject.h" #include "main/renderbuffer.h" #include "main/version.h" #include "st_texture.h" @@ -615,20 +616,36 @@ st_context_share(struct st_context_iface *stctxi, return _mesa_share_state(st->ctx, src->ctx); } static void st_context_destroy(struct st_context_iface *stctxi) { struct st_context *st = (struct st_context *) 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, enum st_context_error *error, struct st_context_iface *shared_stctxi) { struct st_context *shared_ctx = (struct st_context *) shared_stctxi; struct st_context *st; struct pipe_context *pipe; struct gl_config mode; @@ -709,20 +726,22 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, } st->invalidate_on_gl_viewport = smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE); st->iface.destroy = st_context_destroy; st->iface.flush = st_context_flush; 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; *error = ST_CONTEXT_SUCCESS; return &st->iface; } static struct st_context_iface * st_api_get_current(struct st_api *stapi) -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev