summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-12-13 14:06:08 -0700
committerBrian Paul <brianp@vmware.com>2010-12-13 14:06:11 -0700
commit4f106f44a32eaddb6cf3fea6ba5ee9787bff609a (patch)
treebfa350f8cf23e6de70e1e08172477e6b95214177
parente12d6791c5e4bff60bb2e6c04414b1b4d1325f3e (diff)
downloadmesa-st-mesa-per-context-shaders.tar.gz
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.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 );