summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c1
-rw-r--r--src/egl/main/eglapi.c2
-rw-r--r--src/egl/main/eglcontext.c20
-rw-r--r--src/egl/main/egldisplay.h1
-rw-r--r--src/egl/main/eglmisc.c1
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c6
-rw-r--r--src/mesa/main/context.c82
-rw-r--r--src/mesa/main/mtypes.h6
9 files changed, 88 insertions, 37 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 892f1f4def7..f304075b520 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -508,6 +508,7 @@ dri2_setup_screen(_EGLDisplay *disp)
assert(dri2_dpy->dri2 || dri2_dpy->swrast);
disp->Extensions.KHR_surfaceless_context = EGL_TRUE;
+ disp->Extensions.MESA_configless_context = EGL_TRUE;
if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) {
disp->Extensions.KHR_create_context = EGL_TRUE;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 42bcb720f41..950c447de9d 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -431,7 +431,7 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
- if (!config)
+ if (!config && !disp->Extensions.MESA_configless_context)
RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
if (!share && share_list != EGL_NO_CONTEXT)
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 79a92c7c4a6..70277ab9db6 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -523,10 +523,22 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
}
- /* simply require the configs to be equal */
- if ((draw && draw->Config != ctx->Config) ||
- (read && read->Config != ctx->Config))
- return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ /* If the context has a config then it must match that of the two
+ * surfaces */
+ if (ctx->Config) {
+ if ((draw && draw->Config != ctx->Config) ||
+ (read && read->Config != ctx->Config))
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ } else {
+ /* Otherwise we must be using the EGL_MESA_configless_context
+ * extension */
+ assert(dpy->Extensions.MESA_configless_context);
+
+ /* The extension doesn't permit binding draw and read buffers with
+ * differing contexts */
+ if (draw && read && draw->Config != read->Config)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ }
switch (ctx->ClientAPI) {
/* OpenGL and OpenGL ES are conflicting */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 66aaff52ac1..0952bc960cf 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -89,6 +89,7 @@ struct _egl_extensions
EGLBoolean MESA_copy_context;
EGLBoolean MESA_drm_display;
EGLBoolean MESA_drm_image;
+ EGLBoolean MESA_configless_context;
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 341a723be5d..65669d8830f 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -90,6 +90,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(MESA_copy_context);
_EGL_CHECK_EXTENSION(MESA_drm_display);
_EGL_CHECK_EXTENSION(MESA_drm_image);
+ _EGL_CHECK_EXTENSION(MESA_configless_context);
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 0cb1fea523b..a6057d3334e 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -410,7 +410,6 @@ intelInitContext(struct intel_context *intel,
__DRIscreen *sPriv = driContextPriv->driScreenPriv;
struct intel_screen *intelScreen = sPriv->driverPrivate;
int bo_reuse_mode;
- struct gl_config visual;
/* Can't rely on invalidate events, fall back to glViewport hack */
if (!driContextPriv->driScreenPriv->dri2.useInvalidate)
@@ -418,11 +417,6 @@ intelInitContext(struct intel_context *intel,
else
functions->Viewport = intel_viewport;
- if (mesaVis == NULL) {
- memset(&visual, 0, sizeof visual);
- mesaVis = &visual;
- }
-
intel->intelScreen = intelScreen;
if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index c9719f5bde6..de58d515ddb 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -584,7 +584,6 @@ brwCreateContext(gl_api api,
struct intel_screen *screen = sPriv->driverPrivate;
const struct brw_device_info *devinfo = screen->devinfo;
struct dd_function_table functions;
- struct gl_config visual;
/* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel
* provides us with context reset notifications.
@@ -651,11 +650,6 @@ brwCreateContext(gl_api api,
struct gl_context *ctx = &brw->ctx;
- if (mesaVis == NULL) {
- memset(&visual, 0, sizeof visual);
- mesaVis = &visual;
- }
-
if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) {
*dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
fprintf(stderr, "%s: failed to init mesa context\n", __FUNCTION__);
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 5b77ce103d2..cd009c11597 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1013,7 +1013,8 @@ _mesa_initialize_dispatch_tables(struct gl_context *ctx)
*
* \param ctx the context to initialize
* \param api the GL API type to create the context for
- * \param visual describes the visual attributes for this context
+ * \param visual describes the visual attributes for this context or NULL to
+ * create a configless context
* \param share_list points to context to share textures, display lists,
* etc with, or NULL
* \param driverFunctions table of device driver functions for this context
@@ -1033,12 +1034,20 @@ _mesa_initialize_context(struct gl_context *ctx,
assert(driverFunctions->FreeTextureImageBuffer);
ctx->API = api;
- ctx->Visual = *visual;
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
ctx->WinSysDrawBuffer = NULL;
ctx->WinSysReadBuffer = NULL;
+ if (visual) {
+ ctx->Visual = *visual;
+ ctx->HasConfig = GL_TRUE;
+ }
+ else {
+ memset(&ctx->Visual, 0, sizeof ctx->Visual);
+ ctx->HasConfig = GL_FALSE;
+ }
+
if (_mesa_is_desktop_gl(ctx)) {
_mesa_override_gl_version(ctx);
}
@@ -1145,7 +1154,8 @@ fail:
* the rendering context.
*
* \param api the GL API type to create the context for
- * \param visual a struct gl_config pointer (we copy the struct contents)
+ * \param visual a struct gl_config pointer (we copy the struct contents) or
+ * NULL to create a configless context
* \param share_list another context to share display lists with or NULL
* \param driverFunctions points to the dd_function_table into which the
* driver has plugged in all its special functions.
@@ -1160,8 +1170,6 @@ _mesa_create_context(gl_api api,
{
struct gl_context *ctx;
- ASSERT(visual);
-
ctx = calloc(1, sizeof(struct gl_context));
if (!ctx)
return NULL;
@@ -1475,6 +1483,54 @@ _mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
}
}
+static void
+handle_first_current(struct gl_context *ctx)
+{
+ GLenum buffer;
+ GLint bufferIndex;
+
+ assert(ctx->Version > 0);
+
+ ctx->Extensions.String = _mesa_make_extension_string(ctx);
+
+ check_context_limits(ctx);
+
+ /* According to GL_MESA_configless_context the default value of
+ * glDrawBuffers depends on the config of the first surface it is bound to.
+ * For GLES it is always GL_BACK which has a magic interpretation */
+ if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
+ if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
+ if (ctx->DrawBuffer->Visual.doubleBufferMode)
+ buffer = GL_BACK;
+ else
+ buffer = GL_FRONT;
+
+ _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
+ }
+
+ if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
+ if (ctx->ReadBuffer->Visual.doubleBufferMode) {
+ buffer = GL_BACK;
+ bufferIndex = BUFFER_BACK_LEFT;
+ }
+ else {
+ buffer = GL_FRONT;
+ bufferIndex = BUFFER_FRONT_LEFT;
+ }
+
+ _mesa_readbuffer(ctx, buffer, bufferIndex);
+ }
+ }
+
+ /* We can use this to help debug user's problems. Tell them to set
+ * the MESA_INFO env variable before running their app. Then the
+ * first time each context is made current we'll print some useful
+ * information.
+ */
+ if (_mesa_getenv("MESA_INFO")) {
+ _mesa_print_info(ctx);
+ }
+}
/**
* Bind the given context to the given drawBuffer and readBuffer and
@@ -1567,21 +1623,7 @@ _mesa_make_current( struct gl_context *newCtx,
}
if (newCtx->FirstTimeCurrent) {
- assert(newCtx->Version > 0);
-
- newCtx->Extensions.String = _mesa_make_extension_string(newCtx);
-
- check_context_limits(newCtx);
-
- /* We can use this to help debug user's problems. Tell them to set
- * the MESA_INFO env variable before running their app. Then the
- * first time each context is made current we'll print some useful
- * information.
- */
- if (_mesa_getenv("MESA_INFO")) {
- _mesa_print_info(newCtx);
- }
-
+ handle_first_current(newCtx);
newCtx->FirstTimeCurrent = GL_FALSE;
}
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7c83d664f60..c6d90c57978 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4212,6 +4212,12 @@ struct gl_context
GLboolean FirstTimeCurrent;
/*@}*/
+ /**
+ * False if this context was created without a config. This is needed
+ * because the initial state of glDrawBuffers depends on this
+ */
+ GLboolean HasConfig;
+
/** software compression/decompression supported or not */
GLboolean Mesa_DXTn;