Pack fragment program outputs to be consistant with vertex programs.
Previously, output[0] was always Z and output[1] was color. Now output[0] will be color if Z is not written. In shade_quad() use the semantic info to determine which quantity is in which output slot.
This commit is contained in:
@@ -152,7 +152,6 @@ struct pipe_shader_state {
|
||||
|
||||
ubyte num_inputs;
|
||||
ubyte num_outputs;
|
||||
uint outputs_written; /**< bitmask */
|
||||
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
|
||||
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
|
||||
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */
|
||||
|
@@ -78,6 +78,7 @@ shade_quad(
|
||||
const float fx = (float) quad->x0;
|
||||
const float fy = (float) quad->y0;
|
||||
struct tgsi_exec_machine *machine = &qss->machine;
|
||||
uint colorOut;
|
||||
|
||||
/* Consts does not require 16 byte alignment. */
|
||||
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||
@@ -109,28 +110,32 @@ shade_quad(
|
||||
quad->mask &= tgsi_exec_machine_run( machine );
|
||||
}
|
||||
|
||||
/* store result color (always in output[1]) */
|
||||
memcpy(
|
||||
quad->outputs.color,
|
||||
&machine->Outputs[1].xyzw[0].f[0],
|
||||
sizeof( quad->outputs.color ) );
|
||||
|
||||
/* Z */
|
||||
if (qss->stage.softpipe->fs->outputs_written & 0x1) {
|
||||
if (qss->stage.softpipe->fs->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
|
||||
/* output[0] is new Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
|
||||
}
|
||||
colorOut = 1;
|
||||
}
|
||||
else {
|
||||
/* pass input Z to output Z */
|
||||
/* pass input Z (which was interpolated by the executor) to output Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
|
||||
}
|
||||
colorOut = 0;
|
||||
}
|
||||
|
||||
/* store result color */
|
||||
/* XXX need to handle multiple color outputs someday */
|
||||
assert(qss->stage.softpipe->fs->output_semantic_name[colorOut]
|
||||
== TGSI_SEMANTIC_COLOR);
|
||||
memcpy(
|
||||
quad->outputs.color,
|
||||
&machine->Outputs[colorOut].xyzw[0].f[0],
|
||||
sizeof( quad->outputs.color ) );
|
||||
|
||||
/* shader may cull fragments */
|
||||
if( quad->mask ) {
|
||||
qs->next->run( qs->next, quad );
|
||||
|
@@ -46,47 +46,22 @@ map_register_file(
|
||||
*/
|
||||
static GLuint
|
||||
map_register_file_index(
|
||||
GLuint processor,
|
||||
GLuint file,
|
||||
GLuint index,
|
||||
const GLuint inputMapping[],
|
||||
const GLuint outputMapping[])
|
||||
{
|
||||
GLuint mapped_index;
|
||||
|
||||
assert(processor == TGSI_PROCESSOR_FRAGMENT
|
||||
|| processor == TGSI_PROCESSOR_VERTEX);
|
||||
|
||||
switch( file ) {
|
||||
case TGSI_FILE_INPUT:
|
||||
/* inputs are mapped according to the user-defined map */
|
||||
return inputMapping[index];
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
if( processor == TGSI_PROCESSOR_FRAGMENT ) {
|
||||
/* fragment program outputs are hard-coded:
|
||||
* depth result -> index 0
|
||||
* color results -> index 1, 2, ...
|
||||
*/
|
||||
if( index == FRAG_RESULT_DEPR ) {
|
||||
mapped_index = 0; /**TGSI_ATTRIB_POS;**/
|
||||
}
|
||||
else {
|
||||
assert( index == FRAG_RESULT_COLR );
|
||||
mapped_index = 1; /**TGSI_ATTRIB_COLOR0;**/
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* vertex outputs are mapped according to the user-defined map */
|
||||
mapped_index = outputMapping[index];
|
||||
}
|
||||
break;
|
||||
return outputMapping[index];
|
||||
|
||||
default:
|
||||
mapped_index = index;
|
||||
return index;
|
||||
}
|
||||
|
||||
return mapped_index;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,7 +141,6 @@ compile_instruction(
|
||||
fulldst = &fullinst->FullDstRegisters[0];
|
||||
fulldst->DstRegister.File = map_register_file( inst->DstReg.File );
|
||||
fulldst->DstRegister.Index = map_register_file_index(
|
||||
processor,
|
||||
fulldst->DstRegister.File,
|
||||
inst->DstReg.Index,
|
||||
inputMapping,
|
||||
@@ -180,7 +154,6 @@ compile_instruction(
|
||||
fullsrc = &fullinst->FullSrcRegisters[i];
|
||||
fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File );
|
||||
fullsrc->SrcRegister.Index = map_register_file_index(
|
||||
processor,
|
||||
fullsrc->SrcRegister.File,
|
||||
inst->SrcReg[i].Index,
|
||||
inputMapping,
|
||||
|
@@ -160,8 +160,6 @@ st_translate_vertex_program(struct st_context *st,
|
||||
defaultOutputMapping[attr] = slot;
|
||||
}
|
||||
|
||||
vs.outputs_written |= (1 << slot);
|
||||
|
||||
/*
|
||||
printf("Output %u -> slot %u\n", attr, slot);
|
||||
*/
|
||||
@@ -346,35 +344,33 @@ st_translate_fragment_program(struct st_context *st,
|
||||
}
|
||||
|
||||
/*
|
||||
* Semantics for outputs
|
||||
* Semantics and mapping for outputs
|
||||
*/
|
||||
{
|
||||
uint numColors = 0;
|
||||
GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
|
||||
|
||||
/* output[0] is always Z, but may not really be written */
|
||||
/* if z is written, emit that first */
|
||||
if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
|
||||
fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_POSITION;
|
||||
fs.output_semantic_index[fs.num_outputs] = 0;
|
||||
outputMapping[FRAG_RESULT_DEPR] = fs.num_outputs;
|
||||
fs.num_outputs++;
|
||||
|
||||
if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
|
||||
fs.outputs_written |= 0x1;
|
||||
outputsWritten &= ~(1 << FRAG_RESULT_DEPR);
|
||||
}
|
||||
|
||||
/* color outputs begin at output [1] */
|
||||
/* handle remaning outputs (color) */
|
||||
for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
|
||||
if (outputsWritten & (1 << attr)) {
|
||||
switch (attr) {
|
||||
case FRAG_RESULT_DEPR:
|
||||
/* handled above */
|
||||
assert(0);
|
||||
break;
|
||||
case FRAG_RESULT_COLR:
|
||||
fs.output_semantic_name[fs.num_outputs] = TGSI_SEMANTIC_COLOR;
|
||||
fs.output_semantic_index[fs.num_outputs] = numColors;
|
||||
outputMapping[attr] = fs.num_outputs;
|
||||
fs.outputs_written |= (0x2 << numColors);
|
||||
numColors++;
|
||||
break;
|
||||
default:
|
||||
|
Reference in New Issue
Block a user