summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-02-05 01:20:51 +0100
committerTimothy Arceri <[email protected]>2017-03-16 14:14:19 +1100
commitc83562ccaa5f4bd42f4f59c519b48faeb295e354 (patch)
treed997283ca998e8c737bcd667dde3acd3e03d0dfa /src/gallium
parent93bdad3253cfa353cadf4444711c70f39e9baf09 (diff)
gallium: implement the backend of threaded GL dispatch
Acked-by: Timothy Arceri <[email protected]> Tested-by: Dieter Nützel <[email protected]> Tested-by: Mike Lothian <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/include/state_tracker/st_api.h19
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c10
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c6
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c21
4 files changed, 56 insertions, 0 deletions
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)