summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker/st_mesa_to_tgsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker/st_mesa_to_tgsi.c')
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 04be57f8ff..1611d53e2f 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -151,7 +151,7 @@ dst_register( struct st_translate *t,
return t->address[index];
default:
- assert( 0 );
+ debug_assert( 0 );
return ureg_dst_undef();
}
}
@@ -173,8 +173,9 @@ src_register( struct st_translate *t,
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
+ case PROGRAM_ENV_PARAM:
case PROGRAM_UNIFORM:
- case PROGRAM_CONSTANT:
+ case PROGRAM_CONSTANT: /* ie, immediate */
return t->constants[index];
case PROGRAM_INPUT:
@@ -187,7 +188,7 @@ src_register( struct st_translate *t,
return ureg_src(t->address[index]);
default:
- assert( 0 );
+ debug_assert( 0 );
return ureg_src_undef();
}
}
@@ -216,7 +217,7 @@ translate_texture_target( GLuint textarget,
case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE;
case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT;
default:
- assert( 0 );
+ debug_assert( 0 );
return TGSI_TEXTURE_1D;
}
}
@@ -277,7 +278,7 @@ static struct ureg_src swizzle_4v( struct ureg_src src,
/**
- * Translate SWZ instructions into a single MAD. EG:
+ * Translate a SWZ instruction into a MOV, MUL or MAD instruction. EG:
*
* SWZ dst, src.x-y10
*
@@ -386,7 +387,7 @@ static void emit_swz( struct st_translate *t,
swizzle_4v( imm, add_swizzle ) );
}
else {
- assert(0);
+ debug_assert(0);
}
#undef IMM_ZERO
@@ -395,6 +396,23 @@ static void emit_swz( struct st_translate *t,
}
+/**
+ * Negate the value of DDY to match GL semantics where (0,0) is the
+ * lower-left corner of the window.
+ * Note that the GL_ARB_fragment_coord_conventions extension will
+ * effect this someday.
+ */
+static void emit_ddy( struct st_translate *t,
+ struct ureg_dst dst,
+ const struct prog_src_register *SrcReg )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_src src = translate_src( t, SrcReg );
+ src = ureg_negate( src );
+ ureg_DDY( ureg, dst, src );
+}
+
+
static unsigned
translate_opcode( unsigned op )
@@ -480,14 +498,6 @@ translate_opcode( unsigned op )
return TGSI_OPCODE_MOV;
case OPCODE_MUL:
return TGSI_OPCODE_MUL;
- case OPCODE_NOISE1:
- return TGSI_OPCODE_NOISE1;
- case OPCODE_NOISE2:
- return TGSI_OPCODE_NOISE2;
- case OPCODE_NOISE3:
- return TGSI_OPCODE_NOISE3;
- case OPCODE_NOISE4:
- return TGSI_OPCODE_NOISE4;
case OPCODE_NOP:
return TGSI_OPCODE_NOP;
case OPCODE_NRM3:
@@ -522,8 +532,6 @@ translate_opcode( unsigned op )
return TGSI_OPCODE_SSG;
case OPCODE_SUB:
return TGSI_OPCODE_SUB;
- case OPCODE_SWZ:
- return TGSI_OPCODE_SWZ;
case OPCODE_TEX:
return TGSI_OPCODE_TEX;
case OPCODE_TXB:
@@ -539,7 +547,7 @@ translate_opcode( unsigned op )
case OPCODE_END:
return TGSI_OPCODE_END;
default:
- assert( 0 );
+ debug_assert( 0 );
return TGSI_OPCODE_NOP;
}
}
@@ -578,7 +586,7 @@ compile_instruction(
case OPCODE_ELSE:
case OPCODE_ENDLOOP:
case OPCODE_IF:
- assert(num_dst == 0);
+ debug_assert(num_dst == 0);
ureg_label_insn( ureg,
translate_opcode( inst->Opcode ),
src, num_src,
@@ -615,6 +623,23 @@ compile_instruction(
src, num_src );
break;
+ case OPCODE_NOISE1:
+ case OPCODE_NOISE2:
+ case OPCODE_NOISE3:
+ case OPCODE_NOISE4:
+ /* At some point, a motivated person could add a better
+ * implementation of noise. Currently not even the nvidia
+ * binary drivers do anything more than this. In any case, the
+ * place to do this is in the GL state tracker, not the poor
+ * driver.
+ */
+ ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) );
+ break;
+
+ case OPCODE_DDY:
+ emit_ddy( t, dst[0], &inst->SrcReg[0] );
+ break;
+
default:
ureg_insn( ureg,
translate_opcode( inst->Opcode ),
@@ -670,6 +695,31 @@ emit_inverted_wpos( struct st_translate *t,
/**
+ * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
+ * TGSI uses +1 for front, -1 for back.
+ * This function converts the TGSI value to the GL value. Simply clamping/
+ * saturating the value to [0,1] does the job.
+ */
+static void
+emit_face_var( struct st_translate *t,
+ const struct gl_program *program )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_dst face_temp = ureg_DECL_temporary( ureg );
+ struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]];
+
+ /* MOV_SAT face_temp, input[face]
+ */
+ face_temp = ureg_saturate( face_temp );
+ ureg_MOV( ureg, face_temp, face_input );
+
+ /* Use face_temp as face input from here on:
+ */
+ t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp);
+}
+
+
+/**
* Translate Mesa program to TGSI format.
* \param program the program to translate
* \param numInputs number of input registers used
@@ -698,12 +748,10 @@ st_translate_mesa_program(
const ubyte inputSemanticName[],
const ubyte inputSemanticIndex[],
const GLuint interpMode[],
- const GLbitfield inputFlags[],
GLuint numOutputs,
const GLuint outputMapping[],
const ubyte outputSemanticName[],
- const ubyte outputSemanticIndex[],
- const GLbitfield outputFlags[] )
+ const ubyte outputSemanticIndex[] )
{
struct st_translate translate, *t;
struct ureg_program *ureg;
@@ -742,6 +790,10 @@ st_translate_mesa_program(
emit_inverted_wpos( t, program );
}
+ if (program->InputsRead & FRAG_BIT_FACE) {
+ emit_face_var( t, program );
+ }
+
/*
* Declare output attributes.
*/
@@ -761,7 +813,7 @@ st_translate_mesa_program(
outputSemanticIndex[i] );
break;
default:
- assert(0);
+ debug_assert(0);
return 0;
}
}
@@ -781,7 +833,7 @@ st_translate_mesa_program(
/* Declare address register.
*/
if (program->NumAddressRegs > 0) {
- assert( program->NumAddressRegs == 1 );
+ debug_assert( program->NumAddressRegs == 1 );
t->address[0] = ureg_DECL_address( ureg );
}
@@ -864,8 +916,19 @@ out:
if (!tokens) {
debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
_mesa_print_program(program);
- assert(0);
+ debug_assert(0);
}
return tokens;
}
+
+
+/**
+ * Tokens cannot be free with _mesa_free otherwise the builtin gallium
+ * malloc debugging will get confused.
+ */
+void
+st_free_tokens(const struct tgsi_token *tokens)
+{
+ FREE((void *)tokens);
+}