summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2019-11-25 17:58:45 -0500
committerMarek Olšák <[email protected]>2019-11-26 15:14:10 -0500
commited1ff99da7026de3bb10ab4219f75424116124b1 (patch)
treef29626d0454ce27af0452a94e0545d46dfd5ded0 /src/mesa
parentb8772a559a223be0817ba3abb4392d559fee9891 (diff)
st/mesa: add st_variant base class to simplify code for shader variants
Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c18
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c2
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c4
-rw-r--r--src/mesa/state_tracker/st_cb_program.c31
-rw-r--r--src/mesa/state_tracker/st_glsl_to_nir.cpp8
-rw-r--r--src/mesa/state_tracker/st_program.c310
-rw-r--r--src/mesa/state_tracker/st_program.h75
-rw-r--r--src/mesa/state_tracker/st_shader_cache.c8
8 files changed, 149 insertions, 307 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index b18b33e5000..10d21905780 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -109,10 +109,10 @@ st_update_fp( struct st_context *st )
if (st->shader_has_one_variant[MESA_SHADER_FRAGMENT] &&
!stfp->ati_fs && /* ATI_fragment_shader always has multiple variants */
!stfp->Base.ExternalSamplersUsed && /* external samplers need variants */
- stfp->fp_variants &&
- !stfp->fp_variants->key.drawpixels &&
- !stfp->fp_variants->key.bitmap) {
- shader = stfp->fp_variants->driver_shader;
+ stfp->variants &&
+ !st_fp_variant(stfp->variants)->key.drawpixels &&
+ !st_fp_variant(stfp->variants)->key.bitmap) {
+ shader = stfp->variants->driver_shader;
} else {
struct st_fp_variant_key key;
@@ -160,7 +160,7 @@ st_update_fp( struct st_context *st )
key.external = st_get_external_sampler_key(st, &stfp->Base);
- shader = st_get_fp_variant(st, stfp, &key)->driver_shader;
+ shader = st_get_fp_variant(st, stfp, &key)->base.driver_shader;
}
st_reference_prog(st, &st->fp, stfp);
@@ -186,9 +186,9 @@ st_update_vp( struct st_context *st )
assert(stvp->Base.Target == GL_VERTEX_PROGRAM_ARB);
if (st->shader_has_one_variant[MESA_SHADER_VERTEX] &&
- stvp->vp_variants &&
- stvp->vp_variants->key.passthrough_edgeflags == st->vertdata_edgeflags) {
- st->vp_variant = stvp->vp_variants;
+ stvp->variants &&
+ st_vp_variant(stvp->variants)->key.passthrough_edgeflags == st->vertdata_edgeflags) {
+ st->vp_variant = st_vp_variant(stvp->variants);
} else {
struct st_common_variant_key key;
@@ -236,7 +236,7 @@ st_update_vp( struct st_context *st )
st_reference_prog(st, &st->vp, stvp);
cso_set_vertex_shader_handle(st->cso_context,
- st->vp_variant->driver_shader);
+ st->vp_variant->base.driver_shader);
}
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 676fb12be55..112af82815a 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -212,7 +212,7 @@ setup_render_state(struct gl_context *ctx,
cso_set_rasterizer(cso, &st->bitmap.rasterizer);
/* fragment shader state: TEX lookup program */
- cso_set_fragment_shader_handle(cso, fpv->driver_shader);
+ cso_set_fragment_shader_handle(cso, fpv->base.driver_shader);
/* vertex shader state: position + texcoord pass-through */
cso_set_vertex_shader_handle(cso, st->passthrough_vs);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 6b47548d33b..fc11bc3ae47 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1363,7 +1363,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
fpv = (format != GL_COLOR_INDEX) ? get_color_fp_variant(st) :
get_color_index_fp_variant(st);
- driver_fp = fpv->driver_shader;
+ driver_fp = fpv->base.driver_shader;
if (ctx->Pixel.MapColorFlag && format != GL_COLOR_INDEX) {
pipe_sampler_view_reference(&sv[1],
@@ -1741,7 +1741,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
rbRead = st_get_color_read_renderbuffer(ctx);
- driver_fp = fpv->driver_shader;
+ driver_fp = fpv->base.driver_shader;
if (ctx->Pixel.MapColorFlag) {
pipe_sampler_view_reference(&sv[1],
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 0bc6e90ee07..bf0b5e6a05f 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -87,12 +87,7 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
struct st_context *st = st_context(ctx);
struct st_program *stp = st_program(prog);
- if (prog->Target == GL_VERTEX_PROGRAM_ARB)
- st_release_vp_variants(st, stp);
- if (prog->Target == GL_FRAGMENT_PROGRAM_ARB)
- st_release_fp_variants(st, stp);
- else
- st_release_common_variants(st, stp);
+ st_release_variants(st, stp);
if (stp->glsl_to_tgsi)
free_glsl_to_tgsi_visitor(stp->glsl_to_tgsi);
@@ -117,6 +112,8 @@ st_program_string_notify( struct gl_context *ctx,
/* GLSL-to-NIR should not end up here. */
assert(!stp->shader_program);
+ st_release_variants(st, stp);
+
if (target == GL_FRAGMENT_PROGRAM_ARB ||
target == GL_FRAGMENT_SHADER_ATI) {
if (target == GL_FRAGMENT_SHADER_ATI) {
@@ -126,15 +123,12 @@ st_program_string_notify( struct gl_context *ctx,
st_init_atifs_prog(ctx, prog);
}
- st_release_fp_variants(st, stp);
if (!st_translate_fragment_program(st, stp))
return false;
} else if (target == GL_VERTEX_PROGRAM_ARB) {
- st_release_vp_variants(st, stp);
if (!st_translate_vertex_program(st, stp))
return false;
} else {
- st_release_common_variants(st, stp);
if (!st_translate_common_program(st, stp))
return false;
}
@@ -182,23 +176,8 @@ st_get_shader_program_completion_status(struct gl_context *ctx,
if (!linked || !linked->Program)
continue;
- switch (i) {
- case MESA_SHADER_VERTEX:
- if (st_program(linked->Program)->vp_variants)
- sh = st_program(linked->Program)->vp_variants->driver_shader;
- break;
- case MESA_SHADER_FRAGMENT:
- if (st_program(linked->Program)->fp_variants)
- sh = st_program(linked->Program)->fp_variants->driver_shader;
- break;
- case MESA_SHADER_TESS_CTRL:
- case MESA_SHADER_TESS_EVAL:
- case MESA_SHADER_GEOMETRY:
- case MESA_SHADER_COMPUTE:
- if (st_program(linked->Program)->variants)
- sh = st_program(linked->Program)->variants->driver_shader;
- break;
- }
+ if (st_program(linked->Program)->variants)
+ sh = st_program(linked->Program)->variants->driver_shader;
unsigned type = pipe_shader_type_from_mesa(i);
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
index c7a1e12530d..7a417d98f14 100644
--- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
@@ -785,13 +785,7 @@ st_link_nir(struct gl_context *ctx,
st_store_ir_in_disk_cache(st, prog, true);
- if (prog->info.stage == MESA_SHADER_VERTEX)
- st_release_vp_variants(st, stp);
- else if (prog->info.stage == MESA_SHADER_FRAGMENT)
- st_release_fp_variants(st, stp);
- else
- st_release_common_variants(st, stp);
-
+ st_release_variants(st, stp);
st_finalize_program(st, prog);
/* The GLSL IR won't be needed anymore. */
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 53781e6c01e..2dd9227ddd7 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -208,127 +208,23 @@ st_set_prog_affected_state_flags(struct gl_program *prog)
}
}
-static void
-delete_ir(struct pipe_shader_state *ir)
-{
- if (ir->tokens) {
- ureg_free_tokens(ir->tokens);
- ir->tokens = NULL;
- }
-
- /* Note: Any setup of ->ir.nir that has had pipe->create_*_state called on
- * it has resulted in the driver taking ownership of the NIR. Those
- * callers should be NULLing out the nir field in any pipe_shader_state
- * that might have this called in order to indicate that.
- *
- * GLSL IR and ARB programs will have set gl_program->nir to the same
- * shader as ir->ir.nir, so it will be freed by _mesa_delete_program().
- */
-}
/**
- * Delete a vertex program variant. Note the caller must unlink
- * the variant from the linked list.
+ * Delete a shader variant. Note the caller must unlink the variant from
+ * the linked list.
*/
static void
-delete_vp_variant(struct st_context *st, struct st_vp_variant *vpv)
-{
- if (vpv->driver_shader) {
- if (st->has_shareable_shaders || vpv->key.st == st) {
- cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
- } else {
- st_save_zombie_shader(vpv->key.st, PIPE_SHADER_VERTEX,
- vpv->driver_shader);
- }
- }
-
- if (vpv->draw_shader)
- draw_delete_vertex_shader( st->draw, vpv->draw_shader );
-
- if (vpv->tokens)
- ureg_free_tokens(vpv->tokens);
-
- free( vpv );
-}
-
-
-
-/**
- * Clean out any old compilations:
- */
-void
-st_release_vp_variants( struct st_context *st,
- struct st_program *stvp )
-{
- struct st_vp_variant *vpv;
-
- for (vpv = stvp->vp_variants; vpv; ) {
- struct st_vp_variant *next = vpv->next;
- delete_vp_variant(st, vpv);
- vpv = next;
- }
-
- stvp->vp_variants = NULL;
-
- delete_ir(&stvp->state);
-}
-
-
-
-/**
- * Delete a fragment program variant. Note the caller must unlink
- * the variant from the linked list.
- */
-static void
-delete_fp_variant(struct st_context *st, struct st_fp_variant *fpv)
-{
- if (fpv->driver_shader) {
- if (st->has_shareable_shaders || fpv->key.st == st) {
- cso_delete_fragment_shader(st->cso_context, fpv->driver_shader);
- } else {
- st_save_zombie_shader(fpv->key.st, PIPE_SHADER_FRAGMENT,
- fpv->driver_shader);
- }
- }
-
- free(fpv);
-}
-
-
-/**
- * Free all variants of a fragment program.
- */
-void
-st_release_fp_variants(struct st_context *st, struct st_program *stfp)
-{
- struct st_fp_variant *fpv;
-
- for (fpv = stfp->fp_variants; fpv; ) {
- struct st_fp_variant *next = fpv->next;
- delete_fp_variant(st, fpv);
- fpv = next;
- }
-
- stfp->fp_variants = NULL;
-
- delete_ir(&stfp->state);
-}
-
-
-/**
- * Delete a basic program variant. Note the caller must unlink
- * the variant from the linked list.
- */
-static void
-delete_common_variant(struct st_context *st, struct st_common_variant *v,
- GLenum target)
+delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
{
if (v->driver_shader) {
- if (st->has_shareable_shaders || v->key.st == st) {
+ if (st->has_shareable_shaders || v->st == st) {
/* The shader's context matches the calling context, or we
* don't care.
*/
switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ cso_delete_vertex_shader(st->cso_context, v->driver_shader);
+ break;
case GL_TESS_CONTROL_PROGRAM_NV:
cso_delete_tessctrl_shader(st->cso_context, v->driver_shader);
break;
@@ -338,6 +234,9 @@ delete_common_variant(struct st_context *st, struct st_common_variant *v,
case GL_GEOMETRY_PROGRAM_NV:
cso_delete_geometry_shader(st->cso_context, v->driver_shader);
break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ cso_delete_fragment_shader(st->cso_context, v->driver_shader);
+ break;
case GL_COMPUTE_PROGRAM_NV:
cso_delete_compute_shader(st->cso_context, v->driver_shader);
break;
@@ -348,24 +247,23 @@ delete_common_variant(struct st_context *st, struct st_common_variant *v,
/* We can't delete a shader with a context different from the one
* that created it. Add it to the creating context's zombie list.
*/
- enum pipe_shader_type type;
- switch (target) {
- case GL_TESS_CONTROL_PROGRAM_NV:
- type = PIPE_SHADER_TESS_CTRL;
- break;
- case GL_TESS_EVALUATION_PROGRAM_NV:
- type = PIPE_SHADER_TESS_EVAL;
- break;
- case GL_GEOMETRY_PROGRAM_NV:
- type = PIPE_SHADER_GEOMETRY;
- break;
- default:
- unreachable("");
- }
- st_save_zombie_shader(v->key.st, type, v->driver_shader);
+ enum pipe_shader_type type =
+ pipe_shader_type_from_mesa(_mesa_program_enum_to_shader_stage(target));
+
+ st_save_zombie_shader(v->st, type, v->driver_shader);
}
}
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ struct st_vp_variant *vpv = (struct st_vp_variant *)v;
+
+ if (vpv->draw_shader)
+ draw_delete_vertex_shader( st->draw, vpv->draw_shader );
+
+ if (vpv->tokens)
+ ureg_free_tokens(vpv->tokens);
+ }
+
free(v);
}
@@ -374,18 +272,31 @@ delete_common_variant(struct st_context *st, struct st_common_variant *v,
* Free all basic program variants.
*/
void
-st_release_common_variants(struct st_context *st, struct st_program *p)
+st_release_variants(struct st_context *st, struct st_program *p)
{
- struct st_common_variant *v;
+ struct st_variant *v;
for (v = p->variants; v; ) {
- struct st_common_variant *next = v->next;
- delete_common_variant(st, v, p->Base.Target);
+ struct st_variant *next = v->next;
+ delete_variant(st, v, p->Base.Target);
v = next;
}
p->variants = NULL;
- delete_ir(&p->state);
+
+ if (p->state.tokens) {
+ ureg_free_tokens(p->state.tokens);
+ p->state.tokens = NULL;
+ }
+
+ /* Note: Any setup of ->ir.nir that has had pipe->create_*_state called on
+ * it has resulted in the driver taking ownership of the NIR. Those
+ * callers should be NULLing out the nir field in any pipe_shader_state
+ * that might have this called in order to indicate that.
+ *
+ * GLSL IR and ARB programs will have set gl_program->nir to the same
+ * shader as ir->ir.nir, so it will be freed by _mesa_delete_program().
+ */
}
void
@@ -745,7 +656,7 @@ st_create_vp_variant(struct st_context *st,
if (ST_DEBUG & DEBUG_PRINT_IR)
nir_print_shader(state.ir.nir, stderr);
- vpv->driver_shader = pipe->create_vs_state(pipe, &state);
+ vpv->base.driver_shader = pipe->create_vs_state(pipe, &state);
/* When generating a NIR program, we usually don't have TGSI tokens.
* However, we do create them for ARB_vertex_program / fixed-function VS
@@ -798,7 +709,7 @@ st_create_vp_variant(struct st_context *st,
if (ST_DEBUG & DEBUG_PRINT_IR)
tgsi_dump(state.tokens, 0);
- vpv->driver_shader = pipe->create_vs_state(pipe, &state);
+ vpv->base.driver_shader = pipe->create_vs_state(pipe, &state);
/* Save this for selection/feedback/rasterpos. */
vpv->tokens = state.tokens;
return vpv;
@@ -817,7 +728,8 @@ st_get_vp_variant(struct st_context *st,
struct st_vp_variant *vpv;
/* Search for existing variant */
- for (vpv = stp->vp_variants; vpv; vpv = vpv->next) {
+ for (vpv = st_vp_variant(stp->variants); vpv;
+ vpv = st_vp_variant(vpv->base.next)) {
if (memcmp(&vpv->key, key, sizeof(*key)) == 0) {
break;
}
@@ -827,16 +739,18 @@ st_get_vp_variant(struct st_context *st,
/* create now */
vpv = st_create_vp_variant(st, stp, key);
if (vpv) {
- for (unsigned index = 0; index < vpv->num_inputs; ++index) {
- unsigned attr = stvp->index_to_input[index];
- if (attr == ST_DOUBLE_ATTRIB_PLACEHOLDER)
- continue;
- vpv->vert_attrib_mask |= 1u << attr;
- }
+ vpv->base.st = key->st;
+
+ for (unsigned index = 0; index < vpv->num_inputs; ++index) {
+ unsigned attr = stvp->index_to_input[index];
+ if (attr == ST_DOUBLE_ATTRIB_PLACEHOLDER)
+ continue;
+ vpv->vert_attrib_mask |= 1u << attr;
+ }
/* insert into list */
- vpv->next = stp->vp_variants;
- stp->vp_variants = vpv;
+ vpv->base.next = stp->variants;
+ stp->variants = &vpv->base;
}
}
@@ -1366,7 +1280,7 @@ st_create_fp_variant(struct st_context *st,
if (ST_DEBUG & DEBUG_PRINT_IR)
nir_print_shader(state.ir.nir, stderr);
- variant->driver_shader = pipe->create_fs_state(pipe, &state);
+ variant->base.driver_shader = pipe->create_fs_state(pipe, &state);
variant->key = *key;
return variant;
@@ -1498,7 +1412,7 @@ st_create_fp_variant(struct st_context *st,
tgsi_dump(state.tokens, 0);
/* fill in variant */
- variant->driver_shader = pipe->create_fs_state(pipe, &state);
+ variant->base.driver_shader = pipe->create_fs_state(pipe, &state);
variant->key = *key;
if (state.tokens != stfp->state.tokens)
@@ -1517,7 +1431,8 @@ st_get_fp_variant(struct st_context *st,
struct st_fp_variant *fpv;
/* Search for existing variant */
- for (fpv = stfp->fp_variants; fpv; fpv = fpv->next) {
+ for (fpv = st_fp_variant(stfp->variants); fpv;
+ fpv = st_fp_variant(fpv->base.next)) {
if (memcmp(&fpv->key, key, sizeof(*key)) == 0) {
break;
}
@@ -1527,6 +1442,8 @@ st_get_fp_variant(struct st_context *st,
/* create new */
fpv = st_create_fp_variant(st, stfp, key);
if (fpv) {
+ fpv->base.st = key->st;
+
if (key->bitmap || key->drawpixels) {
/* Regular variants should always come before the
* bitmap & drawpixels variants, (unless there
@@ -1534,17 +1451,17 @@ st_get_fp_variant(struct st_context *st,
* st_update_fp can take a fast path when
* shader_has_one_variant is set.
*/
- if (!stfp->fp_variants) {
- stfp->fp_variants = fpv;
+ if (!stfp->variants) {
+ stfp->variants = &fpv->base;
} else {
/* insert into list after the first one */
- fpv->next = stfp->fp_variants->next;
- stfp->fp_variants->next = fpv;
+ fpv->base.next = stfp->variants->next;
+ stfp->variants->next = &fpv->base;
}
} else {
/* insert into list */
- fpv->next = stfp->fp_variants;
- stfp->fp_variants = fpv;
+ fpv->base.next = stfp->variants;
+ stfp->variants = &fpv->base;
}
}
}
@@ -1744,25 +1661,24 @@ st_translate_common_program(struct st_context *st,
/**
* Get/create a basic program variant.
*/
-struct st_common_variant *
+struct st_variant *
st_get_common_variant(struct st_context *st,
struct st_program *prog,
const struct st_common_variant_key *key)
{
struct pipe_context *pipe = st->pipe;
- struct st_common_variant *v;
+ struct st_variant *v;
struct pipe_shader_state state = {0};
/* Search for existing variant */
for (v = prog->variants; v; v = v->next) {
- if (memcmp(&v->key, key, sizeof(*key)) == 0) {
+ if (memcmp(&st_common_variant(v)->key, key, sizeof(*key)) == 0)
break;
- }
}
if (!v) {
/* create new */
- v = CALLOC_STRUCT(st_common_variant);
+ v = (struct st_variant*)CALLOC_STRUCT(st_common_variant);
if (v) {
if (prog->state.type == PIPE_SHADER_IR_NIR) {
bool finalize = false;
@@ -1837,7 +1753,8 @@ st_get_common_variant(struct st_context *st,
return NULL;
}
- v->key = *key;
+ st_common_variant(v)->key = *key;
+ v->st = key->st;
/* insert into list */
v->next = prog->variants;
@@ -1859,74 +1776,21 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
if (!target || target == &_mesa_DummyProgram)
return;
- switch (target->Target) {
- case GL_VERTEX_PROGRAM_ARB:
- {
- struct st_program *stvp = (struct st_program *) target;
- struct st_vp_variant *vpv, **prevPtr = &stvp->vp_variants;
-
- for (vpv = stvp->vp_variants; vpv; ) {
- struct st_vp_variant *next = vpv->next;
- if (vpv->key.st == st) {
- /* unlink from list */
- *prevPtr = next;
- /* destroy this variant */
- delete_vp_variant(st, vpv);
- }
- else {
- prevPtr = &vpv->next;
- }
- vpv = next;
- }
- }
- break;
- case GL_FRAGMENT_PROGRAM_ARB:
- {
- struct st_program *stfp =
- (struct st_program *) target;
- struct st_fp_variant *fpv, **prevPtr = &stfp->fp_variants;
-
- for (fpv = stfp->fp_variants; fpv; ) {
- struct st_fp_variant *next = fpv->next;
- if (fpv->key.st == st) {
- /* unlink from list */
- *prevPtr = next;
- /* destroy this variant */
- delete_fp_variant(st, fpv);
- }
- else {
- prevPtr = &fpv->next;
- }
- fpv = next;
- }
+ struct st_program *p = st_program(target);
+ struct st_variant *v, **prevPtr = &p->variants;
+
+ for (v = p->variants; v; ) {
+ struct st_variant *next = v->next;
+ if (v->st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_variant(st, v, target->Target);
}
- break;
- case GL_GEOMETRY_PROGRAM_NV:
- case GL_TESS_CONTROL_PROGRAM_NV:
- case GL_TESS_EVALUATION_PROGRAM_NV:
- case GL_COMPUTE_PROGRAM_NV:
- {
- struct st_program *p = st_program(target);
- struct st_common_variant *v, **prevPtr = &p->variants;
-
- for (v = p->variants; v; ) {
- struct st_common_variant *next = v->next;
- if (v->key.st == st) {
- /* unlink from list */
- *prevPtr = next;
- /* destroy this variant */
- delete_common_variant(st, v, target->Target);
- }
- else {
- prevPtr = &v->next;
- }
- v = next;
- }
+ else {
+ prevPtr = &v->next;
}
- break;
- default:
- _mesa_problem(NULL, "Unexpected program target 0x%x in "
- "destroy_program_variants_cb()", target->Target);
+ v = next;
}
}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 9ad23235bcb..62d82c2bf84 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -139,27 +139,36 @@ struct st_fp_variant_key
struct st_external_sampler_key external;
};
+/**
+ * Base class for shader variants.
+ */
+struct st_variant
+{
+ /** next in linked list */
+ struct st_variant *next;
+
+ /** st_context from the shader key */
+ struct st_context *st;
+
+ void *driver_shader;
+};
/**
* Variant of a fragment program.
*/
struct st_fp_variant
{
+ struct st_variant base;
+
/** Parameters which generated this version of fragment program */
struct st_fp_variant_key key;
- /** Driver's compiled shader */
- void *driver_shader;
-
/** For glBitmap variants */
uint bitmap_sampler;
/** For glDrawPixels variants */
unsigned drawpix_sampler;
unsigned pixelmap_sampler;
-
- /** next in linked list */
- struct st_fp_variant *next;
};
@@ -190,6 +199,8 @@ struct st_common_variant_key
*/
struct st_vp_variant
{
+ struct st_variant base;
+
/* Parameters which generated this translated version of a vertex
* shader:
*/
@@ -201,15 +212,9 @@ struct st_vp_variant
*/
const struct tgsi_token *tokens;
- /** Driver's compiled shader */
- void *driver_shader;
-
/** For using our private draw module (glRasterPos) */
struct draw_vertex_shader *draw_shader;
- /** Next in linked list */
- struct st_vp_variant *next;
-
/** similar to that in st_vertex_program, but with edgeflags info too */
GLuint num_inputs;
@@ -219,16 +224,14 @@ struct st_vp_variant
/**
- * Geometry program variant.
+ * Common shader variant.
*/
struct st_common_variant
{
+ struct st_variant base;
+
/* Parameters which generated this variant. */
struct st_common_variant_key key;
-
- void *driver_shader;
-
- struct st_common_variant *next;
};
@@ -243,14 +246,10 @@ struct st_program
struct ati_fragment_shader *ati_fs;
uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
- /* used when bypassing glsl_to_tgsi: */
+ /* used when bypassing glsl_to_tgsi: */
struct gl_shader_program *shader_program;
- union {
- struct st_common_variant *variants;
- struct st_vp_variant *vp_variants;
- struct st_fp_variant *fp_variants;
- };
+ struct st_variant *variants;
};
@@ -285,6 +284,24 @@ st_reference_prog(struct st_context *st,
(struct gl_program *) prog);
}
+static inline struct st_common_variant *
+st_common_variant(struct st_variant *v)
+{
+ return (struct st_common_variant*)v;
+}
+
+static inline struct st_vp_variant *
+st_vp_variant(struct st_variant *v)
+{
+ return (struct st_vp_variant*)v;
+}
+
+static inline struct st_fp_variant *
+st_fp_variant(struct st_variant *v)
+{
+ return (struct st_fp_variant*)v;
+}
+
/**
* This defines mapping from Mesa VARYING_SLOTs to TGSI GENERIC slots.
*/
@@ -309,21 +326,13 @@ st_get_fp_variant(struct st_context *st,
struct st_program *stfp,
const struct st_fp_variant_key *key);
-extern struct st_common_variant *
+extern struct st_variant *
st_get_common_variant(struct st_context *st,
struct st_program *p,
const struct st_common_variant_key *key);
extern void
-st_release_vp_variants( struct st_context *st,
- struct st_program *stvp );
-
-extern void
-st_release_fp_variants( struct st_context *st,
- struct st_program *stfp );
-
-extern void
-st_release_common_variants(struct st_context *st, struct st_program *p);
+st_release_variants(struct st_context *st, struct st_program *p);
extern void
st_destroy_program_variants(struct st_context *st);
diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c
index 6145281573f..17cd8b0b835 100644
--- a/src/mesa/state_tracker/st_shader_cache.c
+++ b/src/mesa/state_tracker/st_shader_cache.c
@@ -184,9 +184,9 @@ st_deserialise_ir_program(struct gl_context *ctx,
struct blob_reader blob_reader;
blob_reader_init(&blob_reader, buffer, size);
- if (prog->info.stage == MESA_SHADER_VERTEX) {
- st_release_vp_variants(st, stp);
+ st_release_variants(st, stp);
+ if (prog->info.stage == MESA_SHADER_VERTEX) {
struct st_vertex_program *stvp = (struct st_vertex_program *)stp;
stvp->num_inputs = blob_read_uint32(&blob_reader);
blob_copy_bytes(&blob_reader, (uint8_t *) stvp->index_to_input,
@@ -195,10 +195,6 @@ st_deserialise_ir_program(struct gl_context *ctx,
sizeof(stvp->input_to_index));
blob_copy_bytes(&blob_reader, (uint8_t *) stvp->result_to_output,
sizeof(stvp->result_to_output));
- } else if (prog->info.stage == MESA_SHADER_FRAGMENT) {
- st_release_fp_variants(st, stp);
- } else {
- st_release_common_variants(st, stp);
}
if (prog->info.stage == MESA_SHADER_VERTEX ||