summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/pipe/draw/draw_feedback.c7
-rw-r--r--src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c4
-rw-r--r--src/mesa/sources4
-rw-r--r--src/mesa/state_tracker/st_atom.c3
-rw-r--r--src/mesa/state_tracker/st_atom.h3
-rw-r--r--src/mesa/state_tracker/st_atom_fs.c96
-rw-r--r--src/mesa/state_tracker/st_atom_vs.c156
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c6
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.c4
-rw-r--r--src/mesa/state_tracker/st_cb_program.c88
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c61
-rw-r--r--src/mesa/state_tracker/st_context.h6
-rw-r--r--src/mesa/state_tracker/st_program.h27
14 files changed, 287 insertions, 184 deletions
diff --git a/src/mesa/pipe/draw/draw_feedback.c b/src/mesa/pipe/draw/draw_feedback.c
index 3b8400233ed..ee54db0ad5c 100644
--- a/src/mesa/pipe/draw/draw_feedback.c
+++ b/src/mesa/pipe/draw/draw_feedback.c
@@ -78,11 +78,9 @@ feedback_vertex(struct draw_stage *stage, const struct vertex_header *vertex)
* we can either address output buffer 0 (for interleaving) or
* output buffer i (for non-interleaved).
*/
-#if 0
for (i = 0; i < feedback->num_attribs; i++) {
- const uint attr = feedback->attrib[i];
- const uint slot = stage->draw->vertex_info.attrib_to_slot[attr];
- const float *src = attr ? vertex->data[slot] : vertex->clip;
+ const uint slot = feedback->attrib[i];
+ const float *src = slot ? vertex->data[slot] : vertex->clip;
const uint size = feedback->size[i];
float *dest = fs->dest[i * select];
@@ -104,7 +102,6 @@ feedback_vertex(struct draw_stage *stage, const struct vertex_header *vertex)
}
fs->dest[i * select] += size;
}
-#endif
fs->num_vert_emitted++;
}
diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
index d0d97ab0f87..fa27fd3cd07 100644
--- a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
+++ b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
@@ -476,6 +476,8 @@ make_input_decl(
{
struct tgsi_full_declaration decl;
+ assert(semantic_name < TGSI_SEMANTIC_COUNT);
+
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Declare = TGSI_DECLARE_RANGE;
@@ -500,6 +502,8 @@ make_output_decl(
{
struct tgsi_full_declaration decl;
+ assert(semantic_name < TGSI_SEMANTIC_COUNT);
+
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
decl.Declaration.Declare = TGSI_DECLARE_RANGE;
diff --git a/src/mesa/sources b/src/mesa/sources
index 0d4fdc15f49..985bd2dce6f 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -200,14 +200,13 @@ STATETRACKER_SOURCES = \
state_tracker/st_atom_depth.c \
state_tracker/st_atom_fixedfunction.c \
state_tracker/st_atom_framebuffer.c \
- state_tracker/st_atom_fs.c \
state_tracker/st_atom_sampler.c \
state_tracker/st_atom_scissor.c \
+ state_tracker/st_atom_shader.c \
state_tracker/st_atom_rasterizer.c \
state_tracker/st_atom_stipple.c \
state_tracker/st_atom_texture.c \
state_tracker/st_atom_viewport.c \
- state_tracker/st_atom_vs.c \
state_tracker/st_cb_bufferobjects.c \
state_tracker/st_cb_clear.c \
state_tracker/st_cb_flush.c \
@@ -224,6 +223,7 @@ STATETRACKER_SOURCES = \
state_tracker/st_context.c \
state_tracker/st_draw.c \
state_tracker/st_format.c \
+ state_tracker/st_program.c \
state_tracker/st_mipmap_tree.c
SHADER_SOURCES = \
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index fc339b91ed7..326042cb34c 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -50,8 +50,7 @@ static const struct st_tracked_state *atoms[] =
&st_update_clip,
&st_update_tnl,
- &st_update_vs,
- &st_update_fs,
+ &st_update_shader,
&st_update_rasterizer,
&st_update_polygon_stipple,
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 6710c1a2695..94cb7bee7a7 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -49,8 +49,7 @@ const struct st_tracked_state st_update_clip;
const struct st_tracked_state st_update_clear_color;
const struct st_tracked_state st_update_depth_stencil;
const struct st_tracked_state st_update_tnl;
-const struct st_tracked_state st_update_fs;
-const struct st_tracked_state st_update_vs;
+const struct st_tracked_state st_update_shader;
const struct st_tracked_state st_update_rasterizer;
const struct st_tracked_state st_update_polygon_stipple;
const struct st_tracked_state st_update_viewport;
diff --git a/src/mesa/state_tracker/st_atom_fs.c b/src/mesa/state_tracker/st_atom_fs.c
index dd4cdf0855e..28019858f79 100644
--- a/src/mesa/state_tracker/st_atom_fs.c
+++ b/src/mesa/state_tracker/st_atom_fs.c
@@ -24,11 +24,12 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <[email protected]>
- * Brian Paul
- */
+
+/*
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ * Brian Paul
+ */
#include "shader/prog_parameter.h"
@@ -50,14 +51,20 @@
/**
* Translate a Mesa fragment shader into a TGSI shader.
+ * \param inputMapping to map fragment program input registers to TGSI
+ * input slots
+ * \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
const struct cso_fragment_shader *
-st_translate_fragment_shader(struct st_context *st,
- struct st_fragment_program *stfp)
+st_translate_fragment_shader(const struct st_context *st,
+ struct st_fragment_program *stfp,
+ const GLuint inputMapping[],
+ struct tgsi_token *tokensOut,
+ GLuint maxTokens)
{
GLuint outputMapping[FRAG_RESULT_MAX];
- GLuint inputMapping[PIPE_MAX_SHADER_INPUTS];
+ GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
struct pipe_shader_state fs;
const struct cso_fragment_shader *cso;
GLuint interpMode[16]; /* XXX size? */
@@ -67,6 +74,7 @@ st_translate_fragment_shader(struct st_context *st,
/* Check if all fragment programs need the fragment position (in order
* to do perspective-corrected interpolation).
*/
+ /* XXX temporary! */
if (st->pipe->get_param(st->pipe, PIPE_PARAM_FS_NEEDS_POS))
inputsRead |= FRAG_BIT_WPOS;
@@ -77,28 +85,32 @@ st_translate_fragment_shader(struct st_context *st,
*/
for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
if (inputsRead & (1 << attr)) {
- inputMapping[attr] = fs.num_inputs;
+ const GLuint slot = fs.num_inputs;
+
+ fs.num_inputs++;
+
+ defaultInputMapping[attr] = slot;
switch (attr) {
case FRAG_ATTRIB_WPOS:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_POSITION;
- fs.input_semantic_index[fs.num_inputs] = 0;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_CONSTANT;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ fs.input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
break;
case FRAG_ATTRIB_COL0:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_COLOR;
- fs.input_semantic_index[fs.num_inputs] = 0;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_LINEAR;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ fs.input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_COL1:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_COLOR;
- fs.input_semantic_index[fs.num_inputs] = 1;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_LINEAR;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ fs.input_semantic_index[slot] = 1;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_FOGC:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_FOG;
- fs.input_semantic_index[fs.num_inputs] = 0;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_PERSPECTIVE;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ fs.input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1:
@@ -108,19 +120,17 @@ st_translate_fragment_shader(struct st_context *st,
case FRAG_ATTRIB_TEX5:
case FRAG_ATTRIB_TEX6:
case FRAG_ATTRIB_TEX7:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- fs.input_semantic_index[fs.num_inputs] = attr - FRAG_ATTRIB_TEX0;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_PERSPECTIVE;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ fs.input_semantic_index[slot] = attr - FRAG_ATTRIB_TEX0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_VAR0:
/* fall-through */
default:
- fs.input_semantic_name[fs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- fs.input_semantic_index[fs.num_inputs] = attr - FRAG_ATTRIB_VAR0;
- interpMode[fs.num_inputs] = TGSI_INTERPOLATE_PERSPECTIVE;
+ fs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ fs.input_semantic_index[slot] = attr - FRAG_ATTRIB_VAR0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
}
-
- fs.num_inputs++;
}
}
@@ -145,35 +155,40 @@ st_translate_fragment_shader(struct st_context *st,
}
}
+ if (!inputMapping)
+ inputMapping = defaultInputMapping;
+
/* XXX: fix static allocation of tokens:
*/
tgsi_mesa_compile_fp_program( &stfp->Base,
+ /* inputs */
fs.num_inputs,
inputMapping,
fs.input_semantic_name,
fs.input_semantic_index,
interpMode,
+ /* outputs */
outputMapping,
- stfp->tokens, ST_FP_MAX_TOKENS );
+ /* tokenized result */
+ tokensOut, maxTokens);
+
- fs.tokens = &stfp->tokens[0];
+ fs.tokens = tokensOut;
cso = st_cached_fs_state(st, &fs);
stfp->fs = cso;
if (TGSI_DEBUG)
- tgsi_dump( stfp->tokens, 0/*TGSI_DUMP_VERBOSE*/ );
+ tgsi_dump( tokensOut, 0/*TGSI_DUMP_VERBOSE*/ );
#if defined(USE_X86_ASM) || defined(SLANG_X86)
if (stfp->sse2_program.csr == stfp->sse2_program.store)
- tgsi_emit_sse2_fs( stfp->tokens, &stfp->sse2_program );
+ tgsi_emit_sse2_fs( tokensOut, &stfp->sse2_program );
if (!cso->state.executable)
((struct cso_fragment_shader*)cso)->state.executable = (void *) x86_get_func( &stfp->sse2_program );
#endif
- stfp->dirty = 0;
-
return cso;
}
@@ -200,8 +215,9 @@ static void update_fs( struct st_context *st )
}
/* if new binding, or shader has changed */
- if (st->fp != stfp || stfp->dirty) {
+ if (st->fp != stfp /**|| stfp->dirty**/) {
+#if 0
if (stfp->dirty)
(void) st_translate_fragment_shader( st, stfp );
@@ -210,10 +226,17 @@ static void update_fs( struct st_context *st )
st->state.fs = stfp->fs;
st->pipe->bind_fs_state(st->pipe, st->state.fs->data);
+#else
+
+ /* NEW */
+ st->dirty.st |= ST_NEW_LINKAGE;
+
+#endif
}
}
+#if 0
const struct st_tracked_state st_update_fs = {
.name = "st_update_fs",
.dirty = {
@@ -222,3 +245,4 @@ const struct st_tracked_state st_update_fs = {
},
.update = update_fs
};
+#endif
diff --git a/src/mesa/state_tracker/st_atom_vs.c b/src/mesa/state_tracker/st_atom_vs.c
index a6c0d159d44..0f07906a968 100644
--- a/src/mesa/state_tracker/st_atom_vs.c
+++ b/src/mesa/state_tracker/st_atom_vs.c
@@ -51,15 +51,22 @@
/**
* Translate a Mesa vertex shader into a TGSI shader.
+ * \param outputMapping to map vertex program output registers to TGSI
+ * output slots
+ * \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
const struct cso_vertex_shader *
-st_translate_vertex_shader(struct st_context *st,
- struct st_vertex_program *stvp)
+st_translate_vertex_shader(const struct st_context *st,
+ struct st_vertex_program *stvp,
+ const GLuint outputMapping[],
+ struct tgsi_token *tokensOut,
+ GLuint maxTokens)
{
+ GLuint defaultOutputMapping[VERT_RESULT_MAX];
struct pipe_shader_state vs;
const struct cso_vertex_shader *cso;
- GLuint attr;
+ GLuint attr, i;
memset(&vs, 0, sizeof(vs));
@@ -69,31 +76,36 @@ st_translate_vertex_shader(struct st_context *st,
*/
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
if (stvp->Base.Base.InputsRead & (1 << attr)) {
- stvp->input_to_index[attr] = vs.num_inputs;
- stvp->index_to_input[vs.num_inputs] = attr;
+ const GLuint slot = vs.num_inputs;
+
+ vs.num_inputs++;
+
+ stvp->input_to_index[attr] = slot;
+ stvp->index_to_input[slot] = attr;
+
switch (attr) {
case VERT_ATTRIB_POS:
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_POSITION;
- vs.input_semantic_index[vs.num_inputs] = 0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ vs.input_semantic_index[slot] = 0;
break;
case VERT_ATTRIB_WEIGHT:
/* fall-through */
case VERT_ATTRIB_NORMAL:
/* just label as a generic */
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- vs.input_semantic_index[vs.num_inputs] = 0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs.input_semantic_index[slot] = 0;
break;
case VERT_ATTRIB_COLOR0:
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_COLOR;
- vs.input_semantic_index[vs.num_inputs] = 0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ vs.input_semantic_index[slot] = 0;
break;
case VERT_ATTRIB_COLOR1:
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_COLOR;
- vs.input_semantic_index[vs.num_inputs] = 1;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ vs.input_semantic_index[slot] = 1;
break;
case VERT_ATTRIB_FOG:
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_FOG;
- vs.input_semantic_index[vs.num_inputs] = 0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ vs.input_semantic_index[slot] = 0;
break;
case VERT_ATTRIB_TEX0:
case VERT_ATTRIB_TEX1:
@@ -103,8 +115,8 @@ st_translate_vertex_shader(struct st_context *st,
case VERT_ATTRIB_TEX5:
case VERT_ATTRIB_TEX6:
case VERT_ATTRIB_TEX7:
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- vs.input_semantic_index[vs.num_inputs] = attr - VERT_ATTRIB_TEX0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs.input_semantic_index[slot] = attr - VERT_ATTRIB_TEX0;
break;
case VERT_ATTRIB_GENERIC0:
case VERT_ATTRIB_GENERIC1:
@@ -115,53 +127,71 @@ st_translate_vertex_shader(struct st_context *st,
case VERT_ATTRIB_GENERIC6:
case VERT_ATTRIB_GENERIC7:
assert(attr < VERT_ATTRIB_MAX);
- vs.input_semantic_name[vs.num_inputs] = TGSI_SEMANTIC_GENERIC;
- vs.input_semantic_index[vs.num_inputs] = attr - VERT_ATTRIB_GENERIC0;
+ vs.input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs.input_semantic_index[slot] = attr - VERT_ATTRIB_GENERIC0;
break;
default:
assert(0);
}
- vs.num_inputs++;
}
}
+ /* initialize output semantics to defaults */
+ for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
+ vs.output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
+ vs.output_semantic_index[i] = 0;
+ }
+
/*
- * Determine number of outputs, the register mapping and
- * the semantic information for each vertex output/result.
+ * Determine number of outputs, the (default) output register
+ * mapping and the semantic information for each output.
*/
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
- /* put this attrib in the next available slot */
- st->vertex_attrib_to_slot[attr] = vs.num_outputs;
+ GLuint slot;
+
+ if (outputMapping) {
+ slot = outputMapping[attr];
+ assert(slot != ~0);
+ }
+ else {
+ slot = vs.num_outputs;
+ vs.num_outputs++;
+ defaultOutputMapping[attr] = slot;
+ }
+
+ /*
+ printf("Output %u -> slot %u\n", attr, slot);
+ */
switch (attr) {
case VERT_RESULT_HPOS:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_POSITION;
- vs.output_semantic_index[vs.num_outputs] = 0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ vs.output_semantic_index[slot] = 0;
break;
case VERT_RESULT_COL0:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_COLOR;
- vs.output_semantic_index[vs.num_outputs] = 0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ vs.output_semantic_index[slot] = 0;
break;
case VERT_RESULT_COL1:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_COLOR;
- vs.output_semantic_index[vs.num_outputs] = 1;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ vs.output_semantic_index[slot] = 1;
break;
case VERT_RESULT_BFC0:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_BCOLOR;
- vs.output_semantic_index[vs.num_outputs] = 0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ vs.output_semantic_index[slot] = 0;
break;
case VERT_RESULT_BFC1:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_BCOLOR;
- vs.output_semantic_index[vs.num_outputs] = 1;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ vs.output_semantic_index[slot] = 1;
break;
case VERT_RESULT_FOGC:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_FOG;
- vs.output_semantic_index[vs.num_outputs] = 0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ vs.output_semantic_index[slot] = 0;
break;
case VERT_RESULT_PSIZ:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_PSIZE;
- vs.output_semantic_index[vs.num_outputs] = 0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+ vs.output_semantic_index[slot] = 0;
break;
case VERT_RESULT_EDGE:
assert(0);
@@ -174,46 +204,59 @@ st_translate_vertex_shader(struct st_context *st,
case VERT_RESULT_TEX5:
case VERT_RESULT_TEX6:
case VERT_RESULT_TEX7:
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_GENERIC;
- vs.output_semantic_index[vs.num_outputs] = attr - VERT_RESULT_TEX0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs.output_semantic_index[slot] = attr - VERT_RESULT_TEX0;
break;
case VERT_RESULT_VAR0:
/* fall-through */
default:
assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
- vs.output_semantic_name[vs.num_outputs] = TGSI_SEMANTIC_GENERIC;
- vs.output_semantic_index[vs.num_outputs] = attr - VERT_RESULT_VAR0;
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs.output_semantic_index[slot] = attr - VERT_RESULT_VAR0;
}
-
- vs.num_outputs++;
}
}
+ if (outputMapping) {
+ /* find max output slot referenced to compute vs.num_outputs */
+ GLuint maxSlot = 0;
+ for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
+ if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
+ maxSlot = outputMapping[attr];
+ }
+ vs.num_outputs = maxSlot + 1;
+ }
+ else {
+ outputMapping = defaultOutputMapping;
+ }
+
/* XXX: fix static allocation of tokens:
*/
tgsi_mesa_compile_vp_program( &stvp->Base,
+ /* inputs */
vs.num_inputs,
stvp->input_to_index,
vs.input_semantic_name,
vs.input_semantic_index,
+ /* outputs */
vs.num_outputs,
- st->vertex_attrib_to_slot,
+ outputMapping,
vs.output_semantic_name,
vs.output_semantic_index,
- stvp->tokens, ST_FP_MAX_TOKENS );
-
- vs.tokens = &stvp->tokens[0];
+ /* tokenized result */
+ tokensOut, maxTokens);
+ vs.tokens = tokensOut;
cso = st_cached_vs_state(st, &vs);
stvp->vs = cso;
if (TGSI_DEBUG)
- tgsi_dump( stvp->tokens, 0 );
+ tgsi_dump( tokensOut, 0 );
#if defined(USE_X86_ASM) || defined(SLANG_X86)
if (stvp->sse2_program.csr == stvp->sse2_program.store)
- tgsi_emit_sse2( stvp->tokens, &stvp->sse2_program );
+ tgsi_emit_sse2( tokensOut, &stvp->sse2_program );
if (!cso->state.executable)
((struct cso_vertex_shader*)cso)->state.executable = (void *) x86_get_func( &stvp->sse2_program );
@@ -246,6 +289,7 @@ static void update_vs( struct st_context *st )
}
if (st->vp != stvp || stvp->dirty) {
+#if 0
if (stvp->dirty)
(void) st_translate_vertex_shader( st, stvp );
@@ -260,10 +304,15 @@ static void update_vs( struct st_context *st )
tgsi_dump( stvp->tokens, 0 );
#endif
st->pipe->bind_vs_state(st->pipe, st->state.vs->data);
+#else
+ /* NEW */
+ st->dirty.st |= ST_NEW_LINKAGE;
+
+#endif
}
}
-
+#if 0
const struct st_tracked_state st_update_vs = {
.name = "st_update_vs",
.dirty = {
@@ -272,7 +321,4 @@ const struct st_tracked_state st_update_vs = {
},
.update = update_vs
};
-
-
-
-
+#endif
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 639e0ceb40a..367ae06cf39 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -155,7 +155,8 @@ make_frag_shader(struct st_context *st)
p->OutputsWritten = (1 << FRAG_RESULT_COLR);
stfp = (struct st_fragment_program *) p;
- st_translate_fragment_shader(st, stfp);
+ st_translate_fragment_program(st, stfp, NULL,
+ stfp->tokens, ST_FP_MAX_TOKENS);
return stfp;
}
@@ -203,7 +204,8 @@ make_vertex_shader(struct st_context *st)
(1 << VERT_RESULT_HPOS));
stvp = (struct st_vertex_program *) p;
- st_translate_vertex_shader(st, stvp);
+ st_translate_vertex_program(st, stvp, NULL,
+ stvp->tokens, ST_FP_MAX_TOKENS);
assert(stvp->vs);
return stvp;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 65c54655464..619c5d8ab7c 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -92,7 +92,8 @@ make_fragment_shader(struct st_context *st)
p->OutputsWritten = (1 << FRAG_RESULT_COLR);
stfp = (struct st_fragment_program *) p;
- st_translate_fragment_shader(st, stfp);
+ st_translate_fragment_program(st, stfp, NULL,
+ stfp->tokens, ST_FP_MAX_TOKENS);
return stfp;
}
@@ -141,7 +142,8 @@ make_vertex_shader(struct st_context *st)
(1 << VERT_RESULT_HPOS));
stvp = (struct st_vertex_program *) p;
- st_translate_vertex_shader(st, stvp);
+ st_translate_vertex_program(st, stvp, NULL,
+ stvp->tokens, ST_FP_MAX_TOKENS);
return stvp;
}
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
index 78cf4c2b4d3..537a58f39dc 100644
--- a/src/mesa/state_tracker/st_cb_feedback.c
+++ b/src/mesa/state_tracker/st_cb_feedback.c
@@ -102,13 +102,13 @@ feedback_vertex(GLcontext *ctx, const struct draw_context *draw,
* color and texcoord attribs to use here.
*/
- slot = st->vertex_attrib_to_slot[VERT_RESULT_COL0];
+ slot = st->vertex_result_to_slot[VERT_RESULT_COL0];
if (slot)
color = v->data[slot];
else
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- slot = st->vertex_attrib_to_slot[VERT_RESULT_TEX0];
+ slot = st->vertex_result_to_slot[VERT_RESULT_TEX0];
if (slot)
texcoord = v->data[slot];
else
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 9f46f9e93f4..aee316df6fc 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -30,24 +30,26 @@
* Keith Whitwell <[email protected]>
*/
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/program.h"
+#include "shader/programopt.h"
+
#include "st_context.h"
-#include "st_program.h"
-#include "glheader.h"
-#include "macros.h"
-#include "enums.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "program.h"
-#include "programopt.h"
+#include "st_program.h"
+#include "st_atom_shader.h"
+
#include "tnl/tnl.h"
#include "pipe/tgsi/mesa/tgsi_mesa.h"
-/* Counter to track program string changes:
+/**
+ * Called via ctx->Driver.BindProgram() to bind an ARB vertex or
+ * fragment program.
*/
-static GLuint program_id = 0;
-
-
static void st_bind_program( GLcontext *ctx,
GLenum target,
struct gl_program *prog )
@@ -62,8 +64,14 @@ static void st_bind_program( GLcontext *ctx,
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
break;
}
+ st->dirty.st |= ST_NEW_LINKAGE;
}
+
+/**
+ * Called via ctx->Driver.UseProgram() to bind a linked GLSL program
+ * (vertex shader + fragment shader).
+ */
static void st_use_program( GLcontext *ctx,
GLuint program )
{
@@ -71,6 +79,7 @@ static void st_use_program( GLcontext *ctx,
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+ st->dirty.st |= ST_NEW_LINKAGE;
}
@@ -79,14 +88,13 @@ static struct gl_program *st_new_program( GLcontext *ctx,
GLenum target,
GLuint id )
{
-// struct st_context *st = st_context(ctx);
+ struct st_context *st = st_context(ctx);
switch (target) {
case GL_VERTEX_PROGRAM_ARB: {
struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program);
- prog->id = program_id++;
- prog->dirty = 1;
+ prog->serialNo = 1;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
x86_init_func( &prog->sse2_program );
@@ -102,8 +110,7 @@ static struct gl_program *st_new_program( GLcontext *ctx,
case GL_FRAGMENT_PROGRAM_NV: {
struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program);
- prog->id = program_id++;
- prog->dirty = 1;
+ prog->serialNo = 1;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
x86_init_func( &prog->sse2_program );
@@ -118,29 +125,40 @@ static struct gl_program *st_new_program( GLcontext *ctx,
default:
return _mesa_new_program(ctx, target, id);
}
+
+ st->dirty.st |= ST_NEW_LINKAGE;
}
+
static void st_delete_program( GLcontext *ctx,
struct gl_program *prog )
{
+ struct st_context *st = st_context(ctx);
+
switch( prog->Target ) {
- case GL_VERTEX_PROGRAM_ARB: {
+ case GL_VERTEX_PROGRAM_ARB:
+ {
+ struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- struct st_vertex_program *p = (struct st_vertex_program *) prog;
-
- x86_release_func( &p->sse2_program );
+ x86_release_func( &stvp->sse2_program );
#endif
+ st_remove_vertex_program(st, stvp);
+ }
break;
- }
- case GL_FRAGMENT_PROGRAM_ARB: {
+ case GL_FRAGMENT_PROGRAM_ARB:
+ {
+ struct st_fragment_program *stfp
+ = (struct st_fragment_program *) prog;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
- struct st_fragment_program *p = (struct st_fragment_program *) prog;
-
- x86_release_func( &p->sse2_program );
+ x86_release_func( &stfp->sse2_program );
#endif
+ st_remove_fragment_program(st, stfp);
+ }
break;
+ default:
+ assert(0); /* problem */
}
- }
+
_mesa_delete_program( ctx, prog );
}
@@ -160,27 +178,31 @@ static void st_program_string_notify( GLcontext *ctx,
struct st_context *st = st_context(ctx);
if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct st_fragment_program *p = (struct st_fragment_program *)prog;
+ struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
if (prog == &ctx->FragmentProgram._Current->Base)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
- p->id = program_id++;
- p->param_state = p->Base.Base.Parameters->StateFlags;
+ stfp->serialNo++;
+
+ stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
}
else if (target == GL_VERTEX_PROGRAM_ARB) {
- struct st_vertex_program *p = (struct st_vertex_program *)prog;
+ struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
if (prog == &ctx->VertexProgram._Current->Base)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
- p->id = program_id++;
- p->param_state = p->Base.Base.Parameters->StateFlags;
+ stvp->serialNo++;
+
+ stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
/* Also tell tnl about it:
*/
_tnl_program_string(ctx, target, prog);
}
+
+ st->dirty.st |= ST_NEW_LINKAGE;
}
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 2311bddc655..661d155e6da 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -53,9 +53,9 @@ static void
setup_vertex_attribs(GLcontext *ctx)
{
struct pipe_context *pipe = ctx->st->pipe;
-#if 0
- const uint inputAttrs = ctx->st->state.vs->inputs_read;
- uint attr;
+ const struct cso_vertex_shader *vs = ctx->st->state.vs;
+ const struct st_vertex_program *stvp = ctx->st->vp;
+ uint slot;
/* all attributes come from the default attribute buffer */
{
@@ -67,20 +67,16 @@ setup_vertex_attribs(GLcontext *ctx)
pipe->set_vertex_buffer(pipe, 0, &vbuffer);
}
- for (attr = 0; attr < 16; attr++) {
+ for (slot = 0; slot < vs->state.num_inputs; slot++) {
struct pipe_vertex_element velement;
+ const GLuint attr = stvp->index_to_input[slot];
- if (inputAttrs & (1 << attr)) {
- velement.src_offset = attr * 4 * sizeof(GLfloat);
- velement.vertex_buffer_index = 0;
- velement.dst_offset = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- pipe->set_vertex_element(pipe, attr, &velement);
- }
+ velement.src_offset = attr * 4 * sizeof(GLfloat);
+ velement.vertex_buffer_index = 0;
+ velement.dst_offset = 0;
+ velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ pipe->set_vertex_element(pipe, slot, &velement);
}
-#else
- assert(0);
-#endif
}
@@ -98,12 +94,11 @@ setup_feedback(GLcontext *ctx)
feedback.discard = 1;
feedback.num_attribs = 0;
+ /* feedback all results from vertex shader */
for (i = 0; i < vs->num_outputs; i++) {
- if (1/***(1 << i) & outputAttrs***/) {
- feedback.attrib[feedback.num_attribs] = i;
- feedback.size[feedback.num_attribs] = 4;
- feedback.num_attribs++;
- }
+ feedback.attrib[feedback.num_attribs] = i;
+ feedback.size[feedback.num_attribs] = 4;
+ feedback.num_attribs++;
}
pipe->set_feedback_state(pipe, &feedback);
@@ -261,13 +256,11 @@ update_rasterpos(GLcontext *ctx,
static void
st_RasterPos(GLcontext *ctx, const GLfloat v[4])
{
- struct pipe_context *pipe = ctx->st->pipe;
+ const struct st_context *st = ctx->st;
+ struct pipe_context *pipe = st->pipe;
float *buf_map;
struct pipe_feedback_buffer fb_buf;
- /** XXX TEMPORARILY DISABLE */
- return;
-
st_validate_state(ctx->st);
/* setup vertex buffers */
@@ -277,7 +270,7 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
* Load the default attribute buffer with current attribs.
*/
{
- struct pipe_buffer_handle *buf = ctx->st->default_attrib_buffer;
+ struct pipe_buffer_handle *buf = st->default_attrib_buffer;
const unsigned size = sizeof(ctx->Current.Attrib);
const void *data = ctx->Current.Attrib;
/* colors, texcoords, etc */
@@ -313,17 +306,16 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
PIPE_BUFFER_FLAG_READ);
/* extract values and update rasterpos state */
-#if 0 /* XXX update */
{
- const uint outputAttrs = ctx->st->state.vs->outputs_written;
+ const GLuint *outputMapping = st->vertex_result_to_slot;
const float *pos, *color0, *color1, *tex0;
float *buf = buf_map;
- assert(outputAttrs & (1 << TGSI_ATTRIB_POS));
+ assert(outputMapping[VERT_RESULT_HPOS] != ~0);
pos = buf;
buf += 4;
- if (outputAttrs & (1 << TGSI_ATTRIB_COLOR0)) {
+ if (outputMapping[VERT_RESULT_COL0] != ~0) {
color0 = buf;
buf += 4;
}
@@ -331,7 +323,7 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
color0 = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
}
- if (outputAttrs & (1 << TGSI_ATTRIB_COLOR1)) {
+ if (outputMapping[VERT_RESULT_COL1] != ~0) {
color1 = buf;
buf += 4;
}
@@ -339,16 +331,23 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
color1 = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
}
+ if (outputMapping[VERT_RESULT_TEX0] != ~0) {
+ tex0 = buf;
+ buf += 4;
+ }
+ else {
+ tex0 = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
+ }
+
update_rasterpos(ctx, pos, color0, color1, tex0);
}
-#endif
/* free vertex feedback buffer */
pipe->winsys->buffer_unmap(pipe->winsys, fb_buf.buffer);
pipe->winsys->buffer_reference(pipe->winsys, &fb_buf.buffer, NULL);
/* restore pipe state */
- pipe->set_feedback_state(pipe, &ctx->st->state.feedback);
+ pipe->set_feedback_state(pipe, &st->state.feedback);
}
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 3713328eb14..24f0ff9aaf3 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -45,6 +45,8 @@ struct cso_blend;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
#define ST_NEW_FRAGMENT_PROGRAM 0x2
#define ST_NEW_VERTEX_PROGRAM 0x4
+#define ST_NEW_LINKAGE 0x8
+
struct st_state_flags {
GLuint mesa;
@@ -119,8 +121,8 @@ struct st_context
GLfloat polygon_offset_scale; /* ?? */
- /** Mapping from VERT_ATTRIB_x to post-transformed vertex slot */
- GLuint vertex_attrib_to_slot[VERT_RESULT_MAX];
+ /** Mapping from VERT_RESULT_x to post-transformed vertex slot */
+ const GLuint *vertex_result_to_slot;
struct st_vertex_program *vp; /**< Currently bound vertex program */
struct st_fragment_program *fp; /**< Currently bound fragment program */
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 419afa4e786..355dee574bd 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -47,11 +47,11 @@ struct st_fragment_program
{
struct gl_fragment_program Base;
GLboolean error; /* If program is malformed for any reason. */
- GLuint id; /**< String id, for tracking ProgramStringNotify changes. */
+
+ GLuint serialNo;
/** The program in TGSI format */
struct tgsi_token tokens[ST_FP_MAX_TOKENS];
- GLboolean dirty;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
struct x86_function sse2_program;
@@ -68,7 +68,8 @@ struct st_vertex_program
{
struct gl_vertex_program Base; /**< The Mesa vertex program */
GLboolean error; /**< Set if program is malformed for any reason. */
- GLuint id; /**< String id, for tracking ProgramStringNotify changes. */
+
+ GLuint serialNo;
/** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
GLuint input_to_index[MAX_VERTEX_PROGRAM_ATTRIBS];
@@ -77,7 +78,6 @@ struct st_vertex_program
/** The program in TGSI format */
struct tgsi_token tokens[ST_FP_MAX_TOKENS];
- GLboolean dirty;
#if defined(USE_X86_ASM) || defined(SLANG_X86)
struct x86_function sse2_program;
@@ -90,7 +90,8 @@ struct st_vertex_program
};
-extern void st_init_program_functions(struct dd_function_table *functions);
+extern void
+st_init_program_functions(struct dd_function_table *functions);
static inline struct st_fragment_program *
@@ -99,6 +100,7 @@ st_fragment_program( struct gl_fragment_program *fp )
return (struct st_fragment_program *)fp;
}
+
static inline struct st_vertex_program *
st_vertex_program( struct gl_vertex_program *vp )
{
@@ -107,13 +109,18 @@ st_vertex_program( struct gl_vertex_program *vp )
extern const struct cso_fragment_shader *
-st_translate_fragment_shader(struct st_context *st,
- struct st_fragment_program *fp);
+st_translate_fragment_program(struct st_context *st,
+ struct st_fragment_program *fp,
+ const GLuint inputMapping[],
+ struct tgsi_token *tokens,
+ GLuint maxTokens);
extern const struct cso_vertex_shader *
-st_translate_vertex_shader(struct st_context *st,
- struct st_vertex_program *vp);
-
+st_translate_vertex_program(struct st_context *st,
+ struct st_vertex_program *vp,
+ const GLuint vert_output_to_slot[],
+ struct tgsi_token *tokens,
+ GLuint maxTokens);
#endif