st/mesa: handle failed context creation for core profile
authorBrian Paul <brianp@vmware.com>
Tue, 9 Sep 2014 15:56:47 +0000 (09:56 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 11 Sep 2014 14:22:55 +0000 (08:22 -0600)
If the glx/wgl state tracker requested a core profile but the gallium
driver did not support some feature of GL 3.1 or later, we were setting
ctx->Version=0 and then failing the assertion in
_mesa_initialize_exec_table().

With this change we check for ctx->Version=0 and tear down the context
and return NULL from st_create_context().

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/mesa/main/context.c
src/mesa/state_tracker/st_context.c

index 8208a50b3e6c39e58f2b254d9bb361a72a205189..4c2c32e7b7a3fe0ea711ea525b3b9fced60b6d4c 100644 (file)
@@ -1507,7 +1507,10 @@ handle_first_current(struct gl_context *ctx)
    GLenum buffer;
    GLint bufferIndex;
 
-   assert(ctx->Version > 0);
+   if (ctx->Version == 0) {
+      /* probably in the process of tearing down the context */
+      return;
+   }
 
    ctx->Extensions.String = _mesa_make_extension_string(ctx);
 
index 09b61546582835e47b648fc92db0ccb1fa5a0db9..768a667901e19bda1775932386fe07ab67b82377 100644 (file)
@@ -104,6 +104,42 @@ void st_invalidate_state(struct gl_context * ctx, GLuint new_state)
    _vbo_InvalidateState(ctx, new_state);
 }
 
+
+static void
+st_destroy_context_priv(struct st_context *st)
+{
+   uint shader, i;
+
+   st_destroy_atoms( st );
+   st_destroy_draw( st );
+   st_destroy_clear(st);
+   st_destroy_bitmap(st);
+   st_destroy_drawpix(st);
+   st_destroy_drawtex(st);
+
+   for (shader = 0; shader < Elements(st->state.sampler_views); shader++) {
+      for (i = 0; i < Elements(st->state.sampler_views[0]); i++) {
+         pipe_sampler_view_release(st->pipe,
+                                   &st->state.sampler_views[shader][i]);
+      }
+   }
+
+   if (st->default_texture) {
+      st->ctx->Driver.DeleteTexture(st->ctx, st->default_texture);
+      st->default_texture = NULL;
+   }
+
+   u_upload_destroy(st->uploader);
+   if (st->indexbuf_uploader) {
+      u_upload_destroy(st->indexbuf_uploader);
+   }
+   if (st->constbuf_uploader) {
+      u_upload_destroy(st->constbuf_uploader);
+   }
+   free( st );
+}
+
+
 static struct st_context *
 st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
                const struct st_config_options *options)
@@ -238,6 +274,14 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
 
    _mesa_compute_version(ctx);
 
+   if (ctx->Version == 0) {
+      /* This can happen when a core profile was requested, but the driver
+       * does not support some features of GL 3.1 or later.
+       */
+      st_destroy_context_priv(st);
+      return NULL;
+   }
+
    _mesa_initialize_dispatch_tables(ctx);
    _mesa_initialize_vbo_vtxfmt(ctx);
 
@@ -259,6 +303,7 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
    struct gl_context *ctx;
    struct gl_context *shareCtx = share ? share->ctx : NULL;
    struct dd_function_table funcs;
+   struct st_context *st;
 
    memset(&funcs, 0, sizeof(funcs));
    st_init_driver_functions(&funcs);
@@ -276,41 +321,12 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
    if (debug_get_option_mesa_mvp_dp4())
       ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE;
 
-   return st_create_context_priv(ctx, pipe, options);
-}
-
-
-static void st_destroy_context_priv( struct st_context *st )
-{
-   uint shader, i;
-
-   st_destroy_atoms( st );
-   st_destroy_draw( st );
-   st_destroy_clear(st);
-   st_destroy_bitmap(st);
-   st_destroy_drawpix(st);
-   st_destroy_drawtex(st);
-
-   for (shader = 0; shader < Elements(st->state.sampler_views); shader++) {
-      for (i = 0; i < Elements(st->state.sampler_views[0]); i++) {
-         pipe_sampler_view_release(st->pipe,
-                                   &st->state.sampler_views[shader][i]);
-      }
+   st = st_create_context_priv(ctx, pipe, options);
+   if (!st) {
+      _mesa_destroy_context(ctx);
    }
 
-   if (st->default_texture) {
-      st->ctx->Driver.DeleteTexture(st->ctx, st->default_texture);
-      st->default_texture = NULL;
-   }
-
-   u_upload_destroy(st->uploader);
-   if (st->indexbuf_uploader) {
-      u_upload_destroy(st->indexbuf_uploader);
-   }
-   if (st->constbuf_uploader) {
-      u_upload_destroy(st->constbuf_uploader);
-   }
-   free( st );
+   return st;
 }