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:
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "main/imports.h"
|
#include "main/imports.h"
|
||||||
#include "main/mtypes.h"
|
#include "main/mtypes.h"
|
||||||
|
#include "main/macros.h"
|
||||||
#include "shader/program.h"
|
#include "shader/program.h"
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
@@ -71,6 +72,8 @@ struct translated_vertex_program
|
|||||||
|
|
||||||
/** Maps VERT_RESULT_x to slot */
|
/** Maps VERT_RESULT_x to slot */
|
||||||
GLuint output_to_slot[VERT_RESULT_MAX];
|
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 */
|
/** Pointer to the translated vertex program */
|
||||||
struct st_vertex_program *vp;
|
struct st_vertex_program *vp;
|
||||||
@@ -176,17 +179,22 @@ find_translated_vp(struct st_context *st,
|
|||||||
const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
|
const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
|
||||||
GLuint numVpOuts = 0;
|
GLuint numVpOuts = 0;
|
||||||
GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
|
GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
|
||||||
|
GLint maxGeneric;
|
||||||
|
|
||||||
/* Compute mapping of vertex program outputs to slots, which depends
|
/* Compute mapping of vertex program outputs to slots, which depends
|
||||||
* on the fragment program's input->slot mapping.
|
* on the fragment program's input->slot mapping.
|
||||||
*/
|
*/
|
||||||
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
||||||
/* set default: */
|
/* set defaults: */
|
||||||
xvp->output_to_slot[outAttr] = UNUSED;
|
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) {
|
if (outAttr == VERT_RESULT_HPOS) {
|
||||||
/* always put xformed position into slot zero */
|
/* always put xformed position into slot zero */
|
||||||
xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
|
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++;
|
numVpOuts++;
|
||||||
}
|
}
|
||||||
else if (outputsWritten & (1 << outAttr)) {
|
else if (outputsWritten & (1 << outAttr)) {
|
||||||
@@ -195,8 +203,11 @@ find_translated_vp(struct st_context *st,
|
|||||||
if (fpInAttrib >= 0) {
|
if (fpInAttrib >= 0) {
|
||||||
GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
|
GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
|
||||||
if (fpInSlot != ~0) {
|
if (fpInSlot != ~0) {
|
||||||
|
/* match this vp output to the fp input */
|
||||||
GLuint vpOutSlot = stfp->input_map[fpInSlot];
|
GLuint vpOutSlot = stfp->input_map[fpInSlot];
|
||||||
xvp->output_to_slot[outAttr] = vpOutSlot;
|
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++;
|
numVpOuts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,19 +219,27 @@ find_translated_vp(struct st_context *st,
|
|||||||
emitBFC1 = GL_TRUE;
|
emitBFC1 = GL_TRUE;
|
||||||
}
|
}
|
||||||
#if 0 /*debug*/
|
#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]);
|
xvp->output_to_slot[outAttr]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must do these last */
|
/* must do these last */
|
||||||
if (emitPntSize)
|
if (emitPntSize) {
|
||||||
xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++;
|
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++;
|
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_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.
|
/* Unneeded vertex program outputs will go to this slot.
|
||||||
* We could use this info to do dead code elimination in the
|
* 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;
|
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++) {
|
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
||||||
if (outputsWritten & (1 << 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_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*/
|
#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]);
|
xvp->output_to_slot[outAttr]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -243,7 +281,9 @@ find_translated_vp(struct st_context *st,
|
|||||||
|
|
||||||
assert(stvp->Base.Base.NumInstructions > 1);
|
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;
|
xvp->vp = stvp;
|
||||||
|
|
||||||
|
@@ -294,7 +294,7 @@ st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stvp = (struct st_vertex_program *) p;
|
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;
|
st->drawpix.vert_shaders[passColor] = stvp;
|
||||||
|
|
||||||
|
@@ -71,15 +71,17 @@ mem_dup(const void *src, uint size)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate a Mesa vertex shader into a TGSI shader.
|
* Translate a Mesa vertex shader into a TGSI shader.
|
||||||
* \param outputMapping to map vertex program output registers to TGSI
|
* \param outputMapping to map vertex program output registers (VERT_RESULT_x)
|
||||||
* output slots
|
* to TGSI output slots
|
||||||
* \param tokensOut destination for TGSI tokens
|
* \param tokensOut destination for TGSI tokens
|
||||||
* \return pointer to cached pipe_shader object.
|
* \return pointer to cached pipe_shader object.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
st_translate_vertex_program(struct st_context *st,
|
st_translate_vertex_program(struct st_context *st,
|
||||||
struct st_vertex_program *stvp,
|
struct st_vertex_program *stvp,
|
||||||
const GLuint outputMapping[])
|
const GLuint outputMapping[],
|
||||||
|
const ubyte *outputSemanticName,
|
||||||
|
const ubyte *outputSemanticIndex)
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = st->pipe;
|
struct pipe_context *pipe = st->pipe;
|
||||||
struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
|
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 */
|
/* initialize output semantics to defaults */
|
||||||
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
|
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
|
||||||
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
|
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
|
||||||
@@ -203,10 +219,6 @@ st_translate_vertex_program(struct st_context *st,
|
|||||||
defaultOutputMapping[attr] = slot;
|
defaultOutputMapping[attr] = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
printf("Output %u -> slot %u\n", attr, slot);
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case VERT_RESULT_HPOS:
|
case VERT_RESULT_HPOS:
|
||||||
assert(slot == 0);
|
assert(slot == 0);
|
||||||
@@ -248,15 +260,21 @@ st_translate_vertex_program(struct st_context *st,
|
|||||||
case VERT_RESULT_TEX5:
|
case VERT_RESULT_TEX5:
|
||||||
case VERT_RESULT_TEX6:
|
case VERT_RESULT_TEX6:
|
||||||
case VERT_RESULT_TEX7:
|
case VERT_RESULT_TEX7:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
/* fall-through */
|
||||||
vs_output_semantic_index[slot] = num_generic++;
|
|
||||||
break;
|
|
||||||
case VERT_RESULT_VAR0:
|
case VERT_RESULT_VAR0:
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
assert(attr - VERT_RESULT_VAR0 < MAX_VARYING);
|
if (outputSemanticName) {
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
/* use provided semantic into */
|
||||||
vs_output_semantic_index[slot] = num_generic++;
|
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_generic = 0;
|
||||||
GLuint num_tokens;
|
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;
|
uint fs_num_inputs = 0;
|
||||||
|
|
||||||
ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
||||||
@@ -378,23 +394,23 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
|
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case FRAG_ATTRIB_WPOS:
|
case FRAG_ATTRIB_WPOS:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||||
fs_input_semantic_index[slot] = 0;
|
stfp->input_semantic_index[slot] = 0;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_COL0:
|
case FRAG_ATTRIB_COL0:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||||
fs_input_semantic_index[slot] = 0;
|
stfp->input_semantic_index[slot] = 0;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_COL1:
|
case FRAG_ATTRIB_COL1:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||||
fs_input_semantic_index[slot] = 1;
|
stfp->input_semantic_index[slot] = 1;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_FOGC:
|
case FRAG_ATTRIB_FOGC:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||||
fs_input_semantic_index[slot] = 0;
|
stfp->input_semantic_index[slot] = 0;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_TEX0:
|
case FRAG_ATTRIB_TEX0:
|
||||||
@@ -405,15 +421,15 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
case FRAG_ATTRIB_TEX5:
|
case FRAG_ATTRIB_TEX5:
|
||||||
case FRAG_ATTRIB_TEX6:
|
case FRAG_ATTRIB_TEX6:
|
||||||
case FRAG_ATTRIB_TEX7:
|
case FRAG_ATTRIB_TEX7:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
fs_input_semantic_index[slot] = num_generic++;
|
stfp->input_semantic_index[slot] = num_generic++;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_VAR0:
|
case FRAG_ATTRIB_VAR0:
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
fs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
fs_input_semantic_index[slot] = num_generic++;
|
stfp->input_semantic_index[slot] = num_generic++;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -467,8 +483,8 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
/* inputs */
|
/* inputs */
|
||||||
fs_num_inputs,
|
fs_num_inputs,
|
||||||
inputMapping,
|
inputMapping,
|
||||||
fs_input_semantic_name,
|
stfp->input_semantic_name,
|
||||||
fs_input_semantic_index,
|
stfp->input_semantic_index,
|
||||||
interpMode,
|
interpMode,
|
||||||
/* outputs */
|
/* outputs */
|
||||||
fs_num_outputs,
|
fs_num_outputs,
|
||||||
|
@@ -58,6 +58,9 @@ struct st_fragment_program
|
|||||||
/** map FP input back to VP output */
|
/** map FP input back to VP output */
|
||||||
GLuint input_map[PIPE_MAX_SHADER_INPUTS];
|
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;
|
struct pipe_shader_state state;
|
||||||
void *driver_shader;
|
void *driver_shader;
|
||||||
|
|
||||||
@@ -143,6 +146,9 @@ st_translate_fragment_program(struct st_context *st,
|
|||||||
extern void
|
extern void
|
||||||
st_translate_vertex_program(struct st_context *st,
|
st_translate_vertex_program(struct st_context *st,
|
||||||
struct st_vertex_program *vp,
|
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
|
#endif
|
||||||
|
Reference in New Issue
Block a user