diff options
Diffstat (limited to 'src/mesa/state_tracker/st_mesa_to_tgsi.c')
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 111 |
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); +} |