st/mesa: decouple shaders from contexts if they are shareable
authorMarek Olšák <marek.olsak@amd.com>
Sun, 27 Sep 2015 21:36:59 +0000 (23:36 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 20 Oct 2015 10:51:51 +0000 (12:51 +0200)
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_program.c

index 1e880a107c0c14a5a499484d1573e45312a962ec..394145409b3cb6342ffeb9835acfbf8c884ecacd 100644 (file)
@@ -64,7 +64,7 @@ update_fp( struct st_context *st )
    assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
 
    memset(&key, 0, sizeof(key));
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
 
    /* _NEW_FRAG_CLAMP */
    key.clamp_color = st->clamp_frag_color_in_shader &&
@@ -119,7 +119,7 @@ update_vp( struct st_context *st )
    assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
 
    memset(&key, 0, sizeof key);
-   key.st = st;  /* variants are per-context */
+   key.st = st->has_shareable_shaders ? NULL : st;
 
    /* When this is true, we will add an extra input to the vertex
     * shader translation (for edgeflags), an extra output with
@@ -174,7 +174,7 @@ update_gp( struct st_context *st )
    assert(stgp->Base.Base.Target == GL_GEOMETRY_PROGRAM_NV);
 
    memset(&key, 0, sizeof(key));
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
 
    st->gp_variant = st_get_gp_variant(st, stgp, &key);
 
@@ -210,7 +210,7 @@ update_tcp( struct st_context *st )
    assert(sttcp->Base.Base.Target == GL_TESS_CONTROL_PROGRAM_NV);
 
    memset(&key, 0, sizeof(key));
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
 
    st->tcp_variant = st_get_tcp_variant(st, sttcp, &key);
 
@@ -246,7 +246,7 @@ update_tep( struct st_context *st )
    assert(sttep->Base.Base.Target == GL_TESS_EVALUATION_PROGRAM_NV);
 
    memset(&key, 0, sizeof(key));
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
 
    st->tep_variant = st_get_tep_variant(st, sttep, &key);
 
index bb6dfe8564431e2c8d61504a2f25949e71aa1546..cbc6845d771e971d86313eb4ff6de35fe21d8092 100644 (file)
@@ -269,7 +269,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    struct pipe_resource *vbuf = NULL;
 
    memset(&key, 0, sizeof(key));
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
    key.bitmap = GL_TRUE;
    key.clamp_color = st->clamp_frag_color_in_shader &&
                      st->ctx->Color._ClampFragmentColor;
index 7e8633edc1a9074b923e5f378bbefdc0669b724c..20cbfdefd23e8da44f794598397e176feb45e6ac 100644 (file)
@@ -914,7 +914,7 @@ get_color_fp_variant(struct st_context *st)
 
    memset(&key, 0, sizeof(key));
 
-   key.st = st;
+   key.st = st->has_shareable_shaders ? NULL : st;
    key.drawpixels = 1;
    key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
                        ctx->Pixel.RedScale != 1.0 ||
index bef7307bb27d94a773176d7293c038b8a21d63b9..6256c0b0d8235173784cf4033dc0b57f0abdada8 100644 (file)
@@ -237,7 +237,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
                               PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);
    st->can_force_persample_interp = screen->get_param(screen,
                                           PIPE_CAP_FORCE_PERSAMPLE_INTERP);
-
+   st->has_shareable_shaders = screen->get_param(screen,
+                                                 PIPE_CAP_SHAREABLE_SHADERS);
    st->needs_texcoord_semantic =
       screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
    st->apply_texture_swizzle_to_border_color =
index f187d82449b49eb0b0f9ad1a760648bfab10c32e..446fe5de889a8104bac7e3191f393b87cd9eb8ad 100644 (file)
@@ -99,6 +99,7 @@ struct st_context
    boolean has_etc2;
    boolean prefer_blit_based_texture_transfer;
    boolean can_force_persample_interp;
+   boolean has_shareable_shaders;
 
    boolean needs_texcoord_semantic;
    boolean apply_texture_swizzle_to_border_color;
index 6a69ba7aa2685f9c76416d3c6f58bfd4c733d792..87571a88e78f70c6e61ee6c6d4f41fb33eeb0427 100644 (file)
@@ -1728,6 +1728,12 @@ destroy_program_variants_cb(GLuint key, void *data, void *userData)
 void
 st_destroy_program_variants(struct st_context *st)
 {
+   /* If shaders can be shared with other contexts, the last context will
+    * call DeleteProgram on all shaders, releasing everything.
+    */
+   if (st->has_shareable_shaders)
+      return;
+
    /* ARB vert/frag program */
    _mesa_HashWalk(st->ctx->Shared->Programs,
                   destroy_program_variants_cb, st);
@@ -1774,7 +1780,7 @@ st_precompile_shader_variant(struct st_context *st,
       struct st_vp_variant_key key;
 
       memset(&key, 0, sizeof(key));
-      key.st = st;
+      key.st = st->has_shareable_shaders ? NULL : st;
       st_get_vp_variant(st, p, &key);
       break;
    }
@@ -1784,7 +1790,7 @@ st_precompile_shader_variant(struct st_context *st,
       struct st_tcp_variant_key key;
 
       memset(&key, 0, sizeof(key));
-      key.st = st;
+      key.st = st->has_shareable_shaders ? NULL : st;
       st_get_tcp_variant(st, p, &key);
       break;
    }
@@ -1794,7 +1800,7 @@ st_precompile_shader_variant(struct st_context *st,
       struct st_tep_variant_key key;
 
       memset(&key, 0, sizeof(key));
-      key.st = st;
+      key.st = st->has_shareable_shaders ? NULL : st;
       st_get_tep_variant(st, p, &key);
       break;
    }
@@ -1804,7 +1810,7 @@ st_precompile_shader_variant(struct st_context *st,
       struct st_gp_variant_key key;
 
       memset(&key, 0, sizeof(key));
-      key.st = st;
+      key.st = st->has_shareable_shaders ? NULL : st;
       st_get_gp_variant(st, p, &key);
       break;
    }
@@ -1814,7 +1820,7 @@ st_precompile_shader_variant(struct st_context *st,
       struct st_fp_variant_key key;
 
       memset(&key, 0, sizeof(key));
-      key.st = st;
+      key.st = st->has_shareable_shaders ? NULL : st;
       st_get_fp_variant(st, p, &key);
       break;
    }