diff options
author | Brian Paul <brianp@vmware.com> | 2010-12-13 14:06:08 -0700 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-12-13 14:06:11 -0700 |
commit | 4f106f44a32eaddb6cf3fea6ba5ee9787bff609a (patch) | |
tree | bfa350f8cf23e6de70e1e08172477e6b95214177 | |
parent | e12d6791c5e4bff60bb2e6c04414b1b4d1325f3e (diff) |
st/mesa: reorganize vertex program translation codest-mesa-per-context-shaders
Now it looks like the fragment and geometry program code.
Also remove the serial number fields from programs. It was used to
determine when new translations were needed. Now the variant key is
used for that. And the st_program_string_notify() callback removes all
variants when the program's code is changed.
-rw-r--r-- | src/mesa/state_tracker/st_atom_shader.c | 83 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_program.c | 10 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 39 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 21 |
4 files changed, 59 insertions, 94 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index a0e8565bdb..f416293a7e 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -51,71 +51,6 @@ /** - * Find a translated vertex program that corresponds to stvp and - * has outputs matched to stfp's inputs. - * This performs vertex and fragment translation (to TGSI) when needed. - */ -static struct st_vp_varient * -find_translated_vp(struct st_context *st, - struct st_vertex_program *stvp ) -{ - struct st_vp_varient *vpv; - struct st_vp_varient_key key; - - /* Nothing in our key yet. This will change: - */ - memset(&key, 0, sizeof key); - - /* When this is true, we will add an extra input to the vertex - * shader translation (for edgeflags), an extra output with - * edgeflag semantics, and extend the vertex shader to pass through - * the input to the output. We'll need to use similar logic to set - * up the extra vertex_element input for edgeflags. - * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA - */ - key.passthrough_edgeflags = (st->vertdata_edgeflags && ( - st->ctx->Polygon.FrontMode != GL_FILL || - st->ctx->Polygon.BackMode != GL_FILL)); - - key.st = st; /* variants are per-context */ - - /* Do we need to throw away old translations after a change in the - * GL program string? - */ - if (stvp->serialNo != stvp->lastSerialNo) { - /* These may have changed if the program string changed. - */ - st_prepare_vertex_program( st, stvp ); - - /* We are now up-to-date: - */ - stvp->lastSerialNo = stvp->serialNo; - } - - /* See if we've got a translated vertex program whose outputs match - * the fragment program's inputs. - */ - for (vpv = stvp->varients; vpv; vpv = vpv->next) { - if (memcmp(&vpv->key, &key, sizeof key) == 0) { - break; - } - } - - /* No? Perform new translation here. */ - if (!vpv) { - vpv = st_translate_vertex_program(st, stvp, &key); - if (!vpv) - return NULL; - - vpv->next = stvp->varients; - stvp->varients = vpv; - } - - return vpv; -} - - -/** * Return pointer to a pass-through fragment shader. * This shader is used when a texture is missing/incomplete. */ @@ -145,7 +80,6 @@ update_fp( struct st_context *st ) stfp = st_fragment_program(st->ctx->FragmentProgram._Current); assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); - memset(&key, 0, sizeof(key)); key.st = st; @@ -184,6 +118,7 @@ static void update_vp( struct st_context *st ) { struct st_vertex_program *stvp; + struct st_vp_varient_key key; /* find active shader and params -- Should be covered by * ST_NEW_VERTEX_PROGRAM @@ -192,7 +127,21 @@ update_vp( struct st_context *st ) stvp = st_vertex_program(st->ctx->VertexProgram._Current); assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); - st->vp_varient = find_translated_vp(st, stvp); + memset(&key, 0, sizeof key); + key.st = st; /* variants are per-context */ + + /* When this is true, we will add an extra input to the vertex + * shader translation (for edgeflags), an extra output with + * edgeflag semantics, and extend the vertex shader to pass through + * the input to the output. We'll need to use similar logic to set + * up the extra vertex_element input for edgeflags. + * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA + */ + key.passthrough_edgeflags = (st->vertdata_edgeflags && ( + st->ctx->Polygon.FrontMode != GL_FILL || + st->ctx->Polygon.BackMode != GL_FILL)); + + st->vp_varient = st_get_vp_varient(st, stvp, &key); st_reference_vertprog(st, &st->vp, stvp); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 08d29ae11b..3e1b709d25 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -46,8 +46,6 @@ #include "st_cb_program.h" -static GLuint SerialNo = 1; - /** * Called via ctx->Driver.BindProgram() to bind an ARB vertex or @@ -100,8 +98,6 @@ static struct gl_program *st_new_program( struct gl_context *ctx, case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program); - prog->serialNo = SerialNo++; - return _mesa_init_vertex_program( ctx, &prog->Base, target, @@ -121,8 +117,6 @@ static struct gl_program *st_new_program( struct gl_context *ctx, case MESA_GEOMETRY_PROGRAM: { struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program); - prog->serialNo = SerialNo++; - return _mesa_init_geometry_program( ctx, &prog->Base, target, @@ -213,8 +207,6 @@ static GLboolean st_program_string_notify( struct gl_context *ctx, else if (target == MESA_GEOMETRY_PROGRAM) { struct st_geometry_program *stgp = (struct st_geometry_program *) prog; - stgp->serialNo++; - st_gp_release_varients(st, stgp); if (stgp->tgsi.tokens) { @@ -228,8 +220,6 @@ static GLboolean st_program_string_notify( struct gl_context *ctx, else if (target == GL_VERTEX_PROGRAM_ARB) { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - stvp->serialNo++; - st_vp_release_varients( st, stvp ); if (st->vp == stvp) diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 18c90b7fa4..202f7cb711 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -171,7 +171,7 @@ st_gp_release_varients(struct st_context *st, struct st_geometry_program *stgp) * \param tokensOut destination for TGSI tokens * \return pointer to cached pipe_shader object. */ -void +static void st_prepare_vertex_program(struct st_context *st, struct st_vertex_program *stvp) { @@ -275,7 +275,10 @@ st_prepare_vertex_program(struct st_context *st, } -struct st_vp_varient * +/** + * Translate a vertex program to create a new varient. + */ +static struct st_vp_varient * st_translate_vertex_program(struct st_context *st, struct st_vertex_program *stvp, const struct st_vp_varient_key *key) @@ -286,6 +289,8 @@ st_translate_vertex_program(struct st_context *st, enum pipe_error error; unsigned num_outputs; + st_prepare_vertex_program( st, stvp ); + _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT); _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING); @@ -356,6 +361,36 @@ fail: } +/** + * Find/create a vertex program varient. + */ +struct st_vp_varient * +st_get_vp_varient(struct st_context *st, + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key) +{ + struct st_vp_varient *vpv; + + /* Search for existing varient */ + for (vpv = stvp->varients; vpv; vpv = vpv->next) { + if (memcmp(&vpv->key, key, sizeof(*key)) == 0) { + break; + } + } + + if (!vpv) { + /* create now */ + vpv = st_translate_vertex_program(st, stvp, key); + if (vpv) { + /* insert into list */ + vpv->next = stvp->varients; + stvp->varients = vpv; + } + } + + return vpv; +} + /** * Translate a Mesa fragment shader into a TGSI shader using extra info in diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 245866bf65..519ee8c0d1 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -135,7 +135,6 @@ struct st_vp_varient struct st_vertex_program { struct gl_vertex_program Base; /**< The Mesa vertex program */ - GLuint serialNo, lastSerialNo; /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */ GLuint input_to_index[VERT_ATTRIB_MAX]; @@ -183,7 +182,6 @@ struct st_gp_varient struct st_geometry_program { struct gl_geometry_program Base; /**< The Mesa geometry program */ - GLuint serialNo; /** map GP input back to VP output */ GLuint input_map[PIPE_MAX_SHADER_INPUTS]; @@ -258,6 +256,12 @@ st_reference_fragprog(struct st_context *st, } +extern struct st_vp_varient * +st_get_vp_varient(struct st_context *st, + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key); + + extern struct st_fp_varient * st_get_fp_varient(struct st_context *st, struct st_fragment_program *stfp, @@ -271,19 +275,6 @@ st_get_gp_varient(struct st_context *st, -/* Called after program string change, discard all previous - * compilation results. - */ -extern void -st_prepare_vertex_program(struct st_context *st, - struct st_vertex_program *stvp); - -extern struct st_vp_varient * -st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *stvp, - const struct st_vp_varient_key *key); - - extern void st_vp_release_varients( struct st_context *st, struct st_vertex_program *stvp ); |