summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-08-18 16:10:01 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-08-18 16:10:01 -0600
commite3f3e22cf7e9af4c5416d37329b7b8ee50f0cfcb (patch)
tree72bb600a6411be0008bd3021a336dbc3ba8680c4 /src
parent90a1c6e4032571a1c3e43daeb357068ba14136fe (diff)
gallium: fix vertex program output translation/mapping bug
In some cases, the vertex program output's semantic info didn't match up with the fragment program's input semantic info. This info is now explicitly passed into the st_translate_fragment_program() function.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c60
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c2
-rw-r--r--src/mesa/state_tracker/st_program.c74
-rw-r--r--src/mesa/state_tracker/st_program.h8
4 files changed, 103 insertions, 41 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 4fa304ede0..6594e59e94 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -39,6 +39,7 @@
#include "main/imports.h"
#include "main/mtypes.h"
+#include "main/macros.h"
#include "shader/program.h"
#include "pipe/p_context.h"
@@ -71,6 +72,8 @@ struct translated_vertex_program
/** Maps VERT_RESULT_x to slot */
GLuint output_to_slot[VERT_RESULT_MAX];
+ ubyte output_to_semantic_name[VERT_RESULT_MAX];
+ ubyte output_to_semantic_index[VERT_RESULT_MAX];
/** Pointer to the translated vertex program */
struct st_vertex_program *vp;
@@ -176,17 +179,22 @@ find_translated_vp(struct st_context *st,
const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
GLuint numVpOuts = 0;
GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
+ GLint maxGeneric;
/* Compute mapping of vertex program outputs to slots, which depends
* on the fragment program's input->slot mapping.
*/
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
- /* set default: */
+ /* set defaults: */
xvp->output_to_slot[outAttr] = UNUSED;
+ xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
+ xvp->output_to_semantic_index[outAttr] = 99;
if (outAttr == VERT_RESULT_HPOS) {
/* always put xformed position into slot zero */
xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
+ xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
+ xvp->output_to_semantic_index[outAttr] = 0;
numVpOuts++;
}
else if (outputsWritten & (1 << outAttr)) {
@@ -195,8 +203,11 @@ find_translated_vp(struct st_context *st,
if (fpInAttrib >= 0) {
GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
if (fpInSlot != ~0) {
+ /* match this vp output to the fp input */
GLuint vpOutSlot = stfp->input_map[fpInSlot];
xvp->output_to_slot[outAttr] = vpOutSlot;
+ xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
+ xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
numVpOuts++;
}
}
@@ -208,19 +219,27 @@ find_translated_vp(struct st_context *st,
emitBFC1 = GL_TRUE;
}
#if 0 /*debug*/
- printf("assign output_to_slot[%d] = %d\n", outAttr,
+ printf("assign vp output_to_slot[%d] = %d\n", outAttr,
xvp->output_to_slot[outAttr]);
#endif
}
/* must do these last */
- if (emitPntSize)
+ if (emitPntSize) {
xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++;
- if (emitBFC0)
+ xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
+ xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
+ }
+ if (emitBFC0) {
xvp->output_to_slot[VERT_RESULT_BFC0] = numVpOuts++;
- if (emitBFC1)
+ xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
+ xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
+ }
+ if (emitBFC1) {
xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++;
-
+ xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
+ xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 1;
+ }
/* Unneeded vertex program outputs will go to this slot.
* We could use this info to do dead code elimination in the
@@ -228,14 +247,33 @@ find_translated_vp(struct st_context *st,
*/
dummySlot = numVpOuts;
- /* Map vert program outputs that aren't used to the dummy slot */
+ /* find max GENERIC slot index */
+ maxGeneric = -1;
+ for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
+ if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
+ maxGeneric = MAX2(maxGeneric,
+ xvp->output_to_semantic_index[outAttr]);
+ }
+ }
+
+ /* Map vert program outputs that aren't used to the dummy slot
+ * (and an unused generic attribute slot).
+ */
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
if (outputsWritten & (1 << outAttr)) {
- if (xvp->output_to_slot[outAttr] == UNUSED)
+ if (xvp->output_to_slot[outAttr] == UNUSED) {
xvp->output_to_slot[outAttr] = dummySlot;
+ xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
+ xvp->output_to_semantic_index[outAttr] = maxGeneric + 1;
+ }
+
+ assert(xvp->output_to_semantic_name[outAttr] != TGSI_SEMANTIC_COUNT);
+ assert(xvp->output_to_semantic_index[outAttr] != 99);
}
+
+
#if 0 /*debug*/
- printf("output_to_slot[%d] = %d\n", outAttr,
+ printf("vp output_to_slot[%d] = %d\n", outAttr,
xvp->output_to_slot[outAttr]);
#endif
@@ -243,7 +281,9 @@ find_translated_vp(struct st_context *st,
assert(stvp->Base.Base.NumInstructions > 1);
- st_translate_vertex_program(st, stvp, xvp->output_to_slot);
+ st_translate_vertex_program(st, stvp, xvp->output_to_slot,
+ xvp->output_to_semantic_name,
+ xvp->output_to_semantic_index);
xvp->vp = stvp;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index db0c9fbd09..0c5e21d4ff 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -294,7 +294,7 @@ st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
}
stvp = (struct st_vertex_program *) p;
- st_translate_vertex_program(st, stvp, NULL);
+ st_translate_vertex_program(st, stvp, NULL, NULL, NULL);
st->drawpix.vert_shaders[passColor] = stvp;
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 59314a3232..325d95e865 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -71,15 +71,17 @@ mem_dup(const void *src, uint size)
/**
* Translate a Mesa vertex shader into a TGSI shader.
- * \param outputMapping to map vertex program output registers to TGSI
- * output slots
+ * \param outputMapping to map vertex program output registers (VERT_RESULT_x)
+ * to TGSI output slots
* \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
void
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *stvp,
- const GLuint outputMapping[])
+ const GLuint outputMapping[],
+ const ubyte *outputSemanticName,
+ const ubyte *outputSemanticIndex)
{
struct pipe_context *pipe = st->pipe;
struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
@@ -172,6 +174,20 @@ st_translate_vertex_program(struct st_context *st,
}
}
+#if 0
+ if (outputMapping && outputSemanticName) {
+ printf("VERT_RESULT written out_slot semantic_name semantic_index\n");
+ for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
+ printf(" %-2d %c %3d %2d %2d\n",
+ attr,
+ ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
+ outputMapping[attr],
+ outputSemanticName[attr],
+ outputSemanticIndex[attr]);
+ }
+ }
+#endif
+
/* initialize output semantics to defaults */
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
@@ -203,10 +219,6 @@ st_translate_vertex_program(struct st_context *st,
defaultOutputMapping[attr] = slot;
}
- /*
- printf("Output %u -> slot %u\n", attr, slot);
- */
-
switch (attr) {
case VERT_RESULT_HPOS:
assert(slot == 0);
@@ -248,15 +260,21 @@ st_translate_vertex_program(struct st_context *st,
case VERT_RESULT_TEX5:
case VERT_RESULT_TEX6:
case VERT_RESULT_TEX7:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- vs_output_semantic_index[slot] = num_generic++;
- break;
+ /* fall-through */
case VERT_RESULT_VAR0:
/* fall-through */
default:
- assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- vs_output_semantic_index[slot] = num_generic++;
+ if (outputSemanticName) {
+ /* use provided semantic into */
+ assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
+ vs_output_semantic_name[slot] = outputSemanticName[attr];
+ vs_output_semantic_index[slot] = outputSemanticIndex[attr];
+ }
+ else {
+ /* use default semantic info */
+ vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ vs_output_semantic_index[slot] = num_generic++;
+ }
}
}
}
@@ -347,8 +365,6 @@ st_translate_fragment_program(struct st_context *st,
GLuint num_generic = 0;
GLuint num_tokens;
- ubyte fs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
- ubyte fs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
uint fs_num_inputs = 0;
ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
@@ -378,23 +394,23 @@ st_translate_fragment_program(struct st_context *st,
switch (attr) {
case FRAG_ATTRIB_WPOS:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
- fs_input_semantic_index[slot] = 0;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ stfp->input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_COL0:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- fs_input_semantic_index[slot] = 0;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stfp->input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_COL1:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- fs_input_semantic_index[slot] = 1;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stfp->input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_FOGC:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- fs_input_semantic_index[slot] = 0;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ stfp->input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_TEX0:
@@ -405,15 +421,15 @@ st_translate_fragment_program(struct st_context *st,
case FRAG_ATTRIB_TEX5:
case FRAG_ATTRIB_TEX6:
case FRAG_ATTRIB_TEX7:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- fs_input_semantic_index[slot] = num_generic++;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stfp->input_semantic_index[slot] = num_generic++;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_VAR0:
/* fall-through */
default:
- fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- fs_input_semantic_index[slot] = num_generic++;
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stfp->input_semantic_index[slot] = num_generic++;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
}
}
@@ -467,8 +483,8 @@ st_translate_fragment_program(struct st_context *st,
/* inputs */
fs_num_inputs,
inputMapping,
- fs_input_semantic_name,
- fs_input_semantic_index,
+ stfp->input_semantic_name,
+ stfp->input_semantic_index,
interpMode,
/* outputs */
fs_num_outputs,
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 086e9391aa..078e2c42a6 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -58,6 +58,9 @@ struct st_fragment_program
/** map FP input back to VP output */
GLuint input_map[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+
struct pipe_shader_state state;
void *driver_shader;
@@ -143,6 +146,9 @@ st_translate_fragment_program(struct st_context *st,
extern void
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *vp,
- const GLuint vert_output_to_slot[]);
+ const GLuint vert_output_to_slot[],
+ const ubyte *fs_input_semantic_name,
+ const ubyte *fs_input_semantic_index);
+
#endif