case TGSI_OPCODE_NOP: return SVGA3DOP_NOP;
case TGSI_OPCODE_NRM4: return SVGA3DOP_NRM;
default:
- debug_printf("Unkown opcode %u\n", opcode);
- assert( 0 );
+ assert(!"svga: unexpected opcode in translate_opcode()");
return SVGA3DOP_LAST_INST;
}
}
case TGSI_FILE_SAMPLER: return SVGA3DREG_SAMPLER;
case TGSI_FILE_ADDRESS: return SVGA3DREG_ADDR;
default:
- assert( 0 );
+ assert(!"svga: unexpected register file in translate_file()");
return SVGA3DREG_TEMP;
}
}
+/**
+ * Translate a TGSI destination register to an SVGA3DShaderDestToken.
+ * \param insn the TGSI instruction
+ * \param idx which TGSI dest register to translate (usually (always?) zero)
+ */
static SVGA3dShaderDestToken
translate_dst_register( struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn,
}
+/**
+ * Translate a TGSI src register to a src_register.
+ */
static struct src_register
translate_src_register( const struct svga_shader_emitter *emit,
const struct tgsi_full_src_register *reg )
}
+/**
+ * Release all temps.
+ */
static void
reset_temp_regs(struct svga_shader_emitter *emit)
{
}
+/**
+ * Submit/emit an instruction with zero operands.
+ */
static boolean
submit_op0(struct svga_shader_emitter *emit,
SVGA3dShaderInstToken inst,
}
+/**
+ * Submit/emit an instruction with one operand.
+ */
static boolean
submit_op1(struct svga_shader_emitter *emit,
SVGA3dShaderInstToken inst,
/**
+ * Submit/emit an instruction with two operands.
+ *
* SVGA shaders may not refer to >1 constant register in a single
* instruction. This function checks for that usage and inserts a
* move to temporary if detected.
/**
+ * Submit/emit an instruction with three operands.
+ *
* SVGA shaders may not refer to >1 constant register in a single
* instruction. This function checks for that usage and inserts a
* move to temporary if detected.
/**
+ * Submit/emit an instruction with four operands.
+ *
* SVGA shaders may not refer to >1 constant register in a single
* instruction. This function checks for that usage and inserts a
* move to temporary if detected.
}
+/**
+ * Translate/emit a LRP (linear interpolation) instruction.
+ */
static boolean
submit_lrp(struct svga_shader_emitter *emit,
SVGA3dShaderDestToken dst,
}
+/**
+ * Helper for emitting SVGA immediate values using the SVGA3DOP_DEF[I]
+ * instructions.
+ */
static boolean
emit_def_const(struct svga_shader_emitter *emit,
SVGA3dShaderConstType type,
}
+/**
+ * Create/emit a constant with values {0, 0.5, -1, 1}.
+ * We can swizzle this to produce other useful constants such as
+ * {0, 0, 0, 0}, {1, 1, 1, 1}, etc.
+ */
static boolean
create_zero_immediate( struct svga_shader_emitter *emit )
{
/**
- * Return the register which holds the current dimenions of the
- * texture bound to the given sampler
+ * Return a register which holds the width and height of the texture
+ * currently bound to the given sampler.
*/
static struct src_register
get_tex_dimensions( struct svga_shader_emitter *emit, int sampler_num )
}
+/**
+ * Sine / Cosine helper function.
+ */
static boolean
do_emit_sincos(struct svga_shader_emitter *emit,
SVGA3dShaderDestToken dst,
}
+/**
+ * Translate/emit a TGSI SIN, COS or CSC instruction.
+ */
static boolean
emit_sincos(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
/**
+ * Translate TGSI SIN instruction into:
* SCS TMP SRC
* MOV DST TMP.yyyy
*/
return TRUE;
}
+
/*
+ * Translate TGSI COS instruction into:
* SCS TMP SRC
* MOV DST TMP.xxxx
*/
}
+/**
+ * Translate/emit TGSI SSG (Set Sign: -1, 0, +1) instruction.
+ */
static boolean
emit_ssg(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
/**
- * ADD DST SRC0, negate(SRC0)
+ * Translate/emit TGSI SUB instruction as:
+ * ADD DST, SRC0, negate(SRC1)
*/
static boolean
emit_sub(struct svga_shader_emitter *emit,
}
+/**
+ * Translate/emit KILL_IF instruction (kill if any of X,Y,Z,W are negative).
+ */
static boolean
emit_kill_if(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
/**
- * unconditional kill
+ * Translate/emit unconditional kill instruction (usually found inside
+ * an IF/ELSE/ENDIF block).
*/
static boolean
emit_kill(struct svga_shader_emitter *emit,
-/* Implement conditionals by initializing destination reg to 'fail',
+/**
+ * Implement conditionals by initializing destination reg to 'fail',
* then set predicate reg with UFOP_SETP, then move 'pass' to dest
* based on predicate reg.
*
}
+/**
+ * Helper for emiting 'selection' commands. Basically:
+ * if (src0 OP src1)
+ * dst = 1.0;
+ * else
+ * dst = 0.0;
+ */
static boolean
emit_select(struct svga_shader_emitter *emit,
unsigned compare_func,
one = scalar( zero, TGSI_SWIZZLE_W );
zero = scalar( zero, TGSI_SWIZZLE_X );
- return emit_conditional(
- emit,
- compare_func,
- dst,
- src0,
- src1,
- one, zero);
+ return emit_conditional(emit, compare_func, dst, src0, src1, one, zero);
}
}
+/**
+ * Translate/emit a TGSI SEQ, SNE, SLT, SGE, etc. instruction.
+ */
static boolean
emit_select_op(struct svga_shader_emitter *emit,
unsigned compare,
/**
- * Translate TGSI CMP instruction.
+ * Translate TGSI CMP instruction. Component-wise:
+ * dst = (src0 < 0.0) ? src1 : src2
*/
static boolean
emit_cmp(struct svga_shader_emitter *emit,
/**
- * Translate texture instructions to SVGA3D representation.
+ * Translate/emit 2-operand (coord, sampler) texture instructions.
*/
static boolean
emit_tex2(struct svga_shader_emitter *emit,
/**
- * Translate texture instructions to SVGA3D representation.
+ * Translate/emit 4-operand (coord, ddx, ddy, sampler) texture instructions.
*/
static boolean
emit_tex4(struct svga_shader_emitter *emit,
/**
- * Emit texture swizzle code.
+ * Emit texture swizzle code. We do this here since SVGA samplers don't
+ * directly support swizzles.
*/
static boolean
emit_tex_swizzle(struct svga_shader_emitter *emit,
}
+/**
+ * Translate/emit a TGSI texture sample instruction.
+ */
static boolean
emit_tex(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
static boolean
-emit_bgnloop2(struct svga_shader_emitter *emit,
- const struct tgsi_full_instruction *insn)
+emit_bgnloop(struct svga_shader_emitter *emit,
+ const struct tgsi_full_instruction *insn)
{
SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_LOOP );
struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
static boolean
-emit_endloop2(struct svga_shader_emitter *emit,
- const struct tgsi_full_instruction *insn)
+emit_endloop(struct svga_shader_emitter *emit,
+ const struct tgsi_full_instruction *insn)
{
SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
}
+/**
+ * Translate/emit TGSI BREAK (out of loop) instruction.
+ */
static boolean
emit_brk(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
+/**
+ * Emit simple instruction which operates on one scalar value (not
+ * a vector). Ex: LG2, RCP, RSQ.
+ */
static boolean
emit_scalar_op1(struct svga_shader_emitter *emit,
unsigned opcode,
}
+/**
+ * Translate/emit a simple instruction (one which has no special-case
+ * code) such as ADD, MUL, MIN, MAX.
+ */
static boolean
emit_simple_instruction(struct svga_shader_emitter *emit,
unsigned opcode,
}
+/**
+ * Translate/emit TGSI DDX, DDY instructions.
+ */
static boolean
emit_deriv(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn )
}
+/**
+ * Translate/emit ARL (Address Register Load) instruction. Used to
+ * move a value into the special 'address' register. Used to implement
+ * indirect/variable indexing into arrays.
+ */
static boolean
emit_arl(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
+/**
+ * Translate/emit TGSI XPD (vector cross product) instruction.
+ */
static boolean
emit_xpd(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
+/**
+ * Translate/emit LRP (Linear Interpolation) instruction.
+ */
static boolean
emit_lrp(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
return submit_lrp(emit, dst, src0, src1, src2);
}
-
+/**
+ * Translate/emit DST (Distance function) instruction.
+ */
static boolean
emit_dst_insn(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
+/**
+ * Translate/emit LIT (Lighting helper) instruction.
+ */
static boolean
emit_lit(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
+/**
+ * Translate/emit "begin subroutine" instruction/marker/label.
+ */
static boolean
emit_bgnsub(struct svga_shader_emitter *emit,
unsigned position,
}
+/**
+ * Translate/emit subroutine call instruction.
+ */
static boolean
emit_call(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
}
-
+/**
+ * Translate any TGSI instruction to SVGA.
+ */
static boolean
svga_emit_instruction(struct svga_shader_emitter *emit,
unsigned position,
return emit_endif( emit, insn );
case TGSI_OPCODE_BGNLOOP:
- return emit_bgnloop2( emit, insn );
+ return emit_bgnloop( emit, insn );
case TGSI_OPCODE_ENDLOOP:
- return emit_endloop2( emit, insn );
+ return emit_endloop( emit, insn );
case TGSI_OPCODE_BRK:
return emit_brk( emit, insn );
}
+/**
+ * Translate/emit a TGSI IMMEDIATE declaration.
+ * An immediate vector is a constant that's hard-coded into the shader.
+ */
static boolean
svga_emit_immediate(struct svga_shader_emitter *emit,
- struct tgsi_full_immediate *imm)
+ const struct tgsi_full_immediate *imm)
{
static const float id[4] = {0,0,0,1};
float value[4];
value[i] = util_is_inf_or_nan(f) ? 0.0f : f;
}
+ /* If the immediate has less than four values, fill in the remaining
+ * positions from id={0,0,0,1}.
+ */
for ( ; i < 4; i++ )
value[i] = id[i];
}
+/**
+ * Emit special VS instructions at top of shader.
+ */
static boolean
emit_vs_preamble(struct svga_shader_emitter *emit)
{
}
+/**
+ * Emit special PS instructions at top of shader.
+ */
static boolean
emit_ps_preamble(struct svga_shader_emitter *emit)
{
}
+/**
+ * Emit special PS instructions at end of shader.
+ */
static boolean
emit_ps_postamble(struct svga_shader_emitter *emit)
{
}
+/**
+ * Emit special VS instructions at end of shader.
+ */
static boolean
emit_vs_postamble(struct svga_shader_emitter *emit)
{
/**
* For the pixel shader: emit the code which chooses the front
* or back face color depending on triangle orientation.
+ * This happens at the top of the fragment shader.
*
* 0: IF VFACE :4
* 1: COLOR = FrontColor;
/**
+ * Emit special setup code for the front/back face register in the FS.
* 0: SETP_GT TEMP, VFACE, 0
* where TEMP is a fake frontface register
*/
}
+/**
+ * Determine if we need to emit an immediate value with zeros.
+ * We could just do this all the time except that we want to conserve
+ * registers whenever possible.
+ */
static boolean
-needs_to_create_zero( struct svga_shader_emitter *emit )
+needs_to_create_zero(const struct svga_shader_emitter *emit)
{
unsigned i;
}
+/**
+ * Do we need to create a looping constant?
+ */
static boolean
-needs_to_create_loop_const( struct svga_shader_emitter *emit )
+needs_to_create_loop_const(const struct svga_shader_emitter *emit)
{
return (emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1);
}
static boolean
-needs_to_create_arl_consts( struct svga_shader_emitter *emit )
+needs_to_create_arl_consts(const struct svga_shader_emitter *emit)
{
return (emit->num_arl_consts > 0);
}
}
+/**
+ * This is the main entrypoint into the TGSI instruction translater.
+ * Translate TGSI shader tokens into an SVGA shader.
+ */
boolean
svga_shader_emit_instructions(struct svga_shader_emitter *emit,
const struct tgsi_token *tokens)