summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c83
-rw-r--r--src/mesa/state_tracker/st_cb_program.c10
-rw-r--r--src/mesa/state_tracker/st_program.c39
-rw-r--r--src/mesa/state_tracker/st_program.h21
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 a0e8565bdbf..f416293a7e4 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 08d29ae11b7..3e1b709d25b 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 18c90b7fa46..202f7cb711e 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 245866bf656..519ee8c0d17 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 );