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.
This commit is contained in:
Brian Paul
2008-08-18 16:10:01 -06:00
parent 90a1c6e403
commit e3f3e22cf7
4 changed files with 103 additions and 41 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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