This commit results in garbage output for r600g when building with OpenGL (not ES) as enabled by my patches: https://github.com/Zoxc/weston/commits/gl-rebase. (--enable-opengl on configure)
It works on i965 so I was wondering how well tested this is on Gallium drivers? On Fri, Mar 7, 2014 at 7:05 PM, Neil Roberts <n...@linux.intel.com> wrote: > This extension provides a way for an application to render to multiple > surfaces with different buffer formats without having to use multiple > contexts. An EGLContext can be created without an EGLConfig by passing > EGL_NO_CONFIG_MESA. In that case there are no restrictions on the surfaces > that can be used with the context apart from that they must be using the same > EGLDisplay. > > _mesa_initialze_context can now take a NULL gl_config which will mark the > context as ‘configless’. It will memset the visual to zero in that case. > Previously the i965 and i915 drivers were explicitly creating a zeroed visual > whenever 0 is passed for the EGLConfig. Mesa needs to be aware that the > context is configless because it affects the initial value to use for > glDrawBuffer. The first time the context is bound it will set the initial > value for configless contexts depending on whether the framebuffer used is > double-buffered. > --- > docs/specs/MESA_configless_context.spec | 120 > ++++++++++++++++++++++++++++++ > include/EGL/eglext.h | 5 ++ > src/egl/drivers/dri2/egl_dri2.c | 1 + > src/egl/main/eglapi.c | 2 +- > src/egl/main/eglcontext.c | 20 ++++- > src/egl/main/egldisplay.h | 1 + > src/egl/main/eglmisc.c | 1 + > src/mesa/drivers/dri/i915/intel_context.c | 6 -- > src/mesa/drivers/dri/i965/brw_context.c | 6 -- > src/mesa/main/context.c | 82 +++++++++++++++----- > src/mesa/main/mtypes.h | 6 ++ > 11 files changed, 213 insertions(+), 37 deletions(-) > create mode 100644 docs/specs/MESA_configless_context.spec > > diff --git a/docs/specs/MESA_configless_context.spec > b/docs/specs/MESA_configless_context.spec > new file mode 100644 > index 0000000..8bed90d > --- /dev/null > +++ b/docs/specs/MESA_configless_context.spec > @@ -0,0 +1,120 @@ > +Name > + > + MESA_configless_context > + > +Name Strings > + > + EGL_MESA_configless_context > + > +Contact > + > + Neil Roberts <neil.s.robe...@intel.com> > + > +Status > + > + Proposal > + > +Version > + > + Version 1, February 28, 2014 > + > +Number > + > + EGL Extension #not assigned > + > +Dependencies > + > + Requires EGL 1.4 or later. This extension is written against the > + wording of the EGL 1.4 specification. > + > +Overview > + > + This extension provides a means to use a single context to render to > + multiple surfaces which have different EGLConfigs. Without this extension > + the EGLConfig for every surface used by the context must be compatible > + with the one used by the context. The only way to render to surfaces with > + different formats would be to create multiple contexts but this is > + inefficient with modern GPUs where this restriction is unnecessary. > + > +IP Status > + > + Open-source; freely implementable. > + > +New Procedures and Functions > + > + None. > + > +New Tokens > + > + Accepted as <config> in eglCreateContext > + > + EGL_NO_CONFIG_MESA ((EGLConfig)0) > + > +Additions to the EGL Specification section "2.2 Rendering Contexts and > Drawing > +Surfaces" > + > + Add the following to the 3rd paragraph: > + > + "EGLContexts can also optionally be created with respect to an EGLConfig > + depending on the parameters used at creation time. If a config is > provided > + then additional restrictions apply on what surfaces can be used with the > + context." > + > + Replace the last sentence of the 6th paragraph with: > + > + "In order for a context to be compatible with a surface they both must > have > + been created with respect to the same EGLDisplay. If the context was > + created without respect to an EGLConfig then there are no further > + constraints. Otherwise they are only compatible if:" > + > + Remove the last bullet point in the list of constraints. > + > +Additions to the EGL Specification section "3.7.1 Creating Rendering > Contexts" > + > + Replace the paragraph starting "If config is not a valid EGLConfig..." > + with > + > + "The config argument can either be a valid EGLConfig or > EGL_NO_CONFIG_MESA. > + If it is neither of these then an EGL_BAD_CONFIG error is generated. If a > + valid config is passed then the error will also be generated if the > config > + does not support the requested client API (this includes requesting > + creation of an OpenGL ES 1.x context when the EGL_RENDERABLE_TYPE > + attribute of config does not contain EGL_OPENGL_ES_BIT, or creation of an > + OpenGL ES 2.x context when the attribute does not contain > + EGL_OPENGL_ES2_BIT). > + > + Passing EGL_NO_CONFIG_MESA will create a configless context. When a > + configless context is used with the OpenGL API it can be assumed that the > + initial values of the context's state will be decided when the context is > + first made current. In particular this means that the decision of whether > + to use GL_BACK or GL_FRONT for the initial value of the first output in > + glDrawBuffers will be decided based on the config of the draw surface > when > + it is first bound. If the context is later bound to another surface with > a > + different config it will not alter the context's state. This means that > is > + possible to have the draw buffer set to GL_BACK with a single-buffered > + surface. The results of drawing in this case are undefined. The OpenGL ES > + 3.0 API does not have this problem and instead the default is always > + GL_BACK which has a special interpretation depending on how many buffers > + the surface has." > + > +Additions to the EGL Specification section "3.7.3 Binding Contexts and > +Drawables" > + > + Replace the first bullet point with the following: > + > + "* If draw or read are not compatible with ctx as described in section > 2.2, > + then an EGL_BAD_MATCH error is generated." > + > + Add a second bullet point after that: > + > + "* If draw and read are not compatible with each other as described in > + section 2.2, then an EGL_BAD_MATCH error is generated." > + > +Issues > + > + None. > + > +Revision History > + > + Version 1, February 28, 2014 > + Initial draft (Neil Roberts) > diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h > index 1d68178..fc53914 100644 > --- a/include/EGL/eglext.h > +++ b/include/EGL/eglext.h > @@ -571,6 +571,11 @@ EGLAPI EGLBoolean EGLAPIENTRY > eglSwapBuffersWithDamageEXT( EGLDisplay dpy, EGLSu > typedef EGLBoolean (EGLAPIENTRYP > PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)(EGLDisplay dpy, EGLSurface surface, > EGLint *rects, EGLint n_rects); > #endif > > +#ifndef EGL_MESA_configless_context > +#define EGL_MESA_configless_context 1 > +#define EGL_NO_CONFIG_MESA ((EGLConfig)0) > +#endif > + > #include <EGL/eglmesaext.h> > > #ifdef __cplusplus > diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c > index 892f1f4..f304075 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 42bcb72..950c447 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 79a92c7..70277ab 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 66aaff5..0952bc9 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 341a723..65669d8 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 0cb1fea..a6057d3 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 1441b46..ad5e729 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 5b77ce1..cd009c1 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 d05649c..d18082f 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -4220,6 +4220,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; > > -- > 1.8.5.3 > > _______________________________________________ > wayland-devel mailing list > wayland-de...@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev