#include "dri_screen.h"
#include "dri_drawable.h"
#include "dri_context.h"
+#include "state_tracker/drm_driver.h"
#include "pipe/p_context.h"
#include "state_tracker/st_context.h"
static void
-dri_init_extensions(struct dri_context *ctx)
+dri_fill_st_options(struct st_config_options *options,
+ const struct driOptionCache * optionCache)
{
- struct st_context *st = (struct st_context *) ctx->st;
-
- /* New extensions should be added in mesa/state_tracker/st_extensions.c
- * and not in this file. */
- driInitExtensions(st->ctx, NULL, GL_FALSE);
-}
-
-static void
-dri_pp_query(struct dri_context *ctx)
-{
- unsigned int i;
-
- for (i = 0; i < PP_FILTERS; i++) {
- ctx->pp_enabled[i] = driQueryOptioni(&ctx->optionCache, pp_filters[i].name);
- }
+ options->disable_blend_func_extended =
+ driQueryOptionb(optionCache, "disable_blend_func_extended");
+ options->disable_glsl_line_continuations =
+ driQueryOptionb(optionCache, "disable_glsl_line_continuations");
+ options->disable_shader_bit_encoding =
+ driQueryOptionb(optionCache, "disable_shader_bit_encoding");
+ options->force_glsl_extensions_warn =
+ driQueryOptionb(optionCache, "force_glsl_extensions_warn");
+ options->force_glsl_version =
+ driQueryOptioni(optionCache, "force_glsl_version");
+ options->force_s3tc_enable =
+ driQueryOptionb(optionCache, "force_s3tc_enable");
}
GLboolean
dri_create_context(gl_api api, const struct gl_config * visual,
- __DRIcontext * cPriv, void *sharedContextPrivate)
+ __DRIcontext * cPriv,
+ unsigned major_version,
+ unsigned minor_version,
+ uint32_t flags,
+ unsigned *error,
+ void *sharedContextPrivate)
{
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
struct st_context_attribs attribs;
+ enum st_context_error ctx_err = 0;
memset(&attribs, 0, sizeof(attribs));
switch (api) {
case API_OPENGLES2:
attribs.profile = ST_PROFILE_OPENGL_ES2;
break;
- default:
- attribs.profile = ST_PROFILE_DEFAULT;
+ case API_OPENGL_COMPAT:
+ case API_OPENGL_CORE:
+ attribs.profile = api == API_OPENGL_COMPAT ? ST_PROFILE_DEFAULT
+ : ST_PROFILE_OPENGL_CORE;
+ attribs.major = major_version;
+ attribs.minor = minor_version;
+
+ if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
+ attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
+
+ if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
+ attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
break;
+ default:
+ *error = __DRI_CTX_ERROR_BAD_API;
+ goto fail;
}
if (sharedContextPrivate) {
}
ctx = CALLOC_STRUCT(dri_context);
- if (ctx == NULL)
+ if (ctx == NULL) {
+ *error = __DRI_CTX_ERROR_NO_MEMORY;
goto fail;
+ }
cPriv->driverPrivate = ctx;
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
- ctx->lock = screen->drmLock;
-
- driParseConfigFiles(&ctx->optionCache,
- &screen->optionCache, sPriv->myNum, "dri");
+ dri_fill_st_options(&attribs.options, &screen->optionCache);
dri_fill_st_visual(&attribs.visual, screen, visual);
- ctx->st = stapi->create_context(stapi, &screen->base, &attribs, st_share);
- if (ctx->st == NULL)
+ ctx->st = stapi->create_context(stapi, &screen->base, &attribs, &ctx_err,
+ st_share);
+ if (ctx->st == NULL) {
+ switch (ctx_err) {
+ case ST_CONTEXT_SUCCESS:
+ *error = __DRI_CTX_ERROR_SUCCESS;
+ break;
+ case ST_CONTEXT_ERROR_NO_MEMORY:
+ *error = __DRI_CTX_ERROR_NO_MEMORY;
+ break;
+ case ST_CONTEXT_ERROR_BAD_API:
+ *error = __DRI_CTX_ERROR_BAD_API;
+ break;
+ case ST_CONTEXT_ERROR_BAD_VERSION:
+ *error = __DRI_CTX_ERROR_BAD_VERSION;
+ break;
+ case ST_CONTEXT_ERROR_BAD_FLAG:
+ *error = __DRI_CTX_ERROR_BAD_FLAG;
+ break;
+ case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
+ *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+ break;
+ case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
+ *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+ break;
+ }
goto fail;
+ }
ctx->st->st_manager_private = (void *) ctx;
ctx->stapi = stapi;
- /*
- * libmesagallium.a that this state tracker will be linked to expects
- * OpenGL's _glapi_table. That is, it expects libGL.so instead of
- * libGLESv1_CM.so or libGLESv2.so. As there is no clean way to know the
- * shared library the app links to, use the api as a simple check.
- * It might be as well to simply remove this function call though.
- */
- if (api == API_OPENGL)
- dri_init_extensions(ctx);
-
- // Context successfully created. See if post-processing is requested.
- dri_pp_query(ctx);
-
- ctx->pp = pp_init(screen->base.screen, ctx->pp_enabled);
+ 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);
+ }
+ *error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
fail:
if (ctx && ctx->st)
ctx->st->destroy(ctx->st);
- FREE(ctx);
+ free(ctx);
return GL_FALSE;
}
{
struct dri_context *ctx = dri_context(cPriv);
- /* note: we are freeing values and nothing more because
- * driParseConfigFiles allocated values only - the rest
- * is owned by screen optionCache.
- */
- FREE(ctx->optionCache.values);
+ if (ctx->hud) {
+ hud_destroy(ctx->hud);
+ }
/* No particular reason to wait for command completion before
- * destroying a context, but it is probably worthwhile flushing it
+ * destroying a context, but we flush the context here
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
ctx->st->flush(ctx->st, 0, NULL);
ctx->st->destroy(ctx->st);
- if (ctx->pp) pp_free(ctx->pp);
+ if (ctx->pp)
+ pp_free(ctx->pp);
- FREE(ctx);
+ free(ctx);
}
GLboolean
if (--ctx->bind_count == 0) {
if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
- ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
+ /* For conformance, unbind is supposed to flush the context.
+ * However, if we do it here we might end up flushing a partially
+ * destroyed context. Instead, we flush in dri_make_current and
+ * in dri_destroy_context which should cover all the cases.
+ */
stapi->make_current(stapi, NULL, NULL, NULL);
}
}
struct dri_drawable *read = dri_drawable(driReadPriv);
struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
+ /* 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);
if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
&& ctx->pp)
pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
- draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0,
- draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
+ draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
return GL_TRUE;
}
st = stapi->get_current(stapi);
- return (struct dri_context *) (st) ? st->st_manager_private : NULL;
+ return (struct dri_context *) st ? st->st_manager_private : NULL;
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */