case TGSI_OPCODE_ABS: return SVGA3DOP_ABS;
case TGSI_OPCODE_ADD: return SVGA3DOP_ADD;
case TGSI_OPCODE_BREAKC: return SVGA3DOP_BREAKC;
- case TGSI_OPCODE_DDX: return SVGA3DOP_DSX;
- case TGSI_OPCODE_DDY: return SVGA3DOP_DSY;
case TGSI_OPCODE_DP2A: return SVGA3DOP_DP2ADD;
case TGSI_OPCODE_DP3: return SVGA3DOP_DP3;
case TGSI_OPCODE_DP4: return SVGA3DOP_DP4;
const struct tgsi_full_instruction *insn,
unsigned idx )
{
- const struct tgsi_full_dst_register *reg = &insn->FullDstRegisters[idx];
+ const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
SVGA3dShaderDestToken dest;
- switch (reg->DstRegister.File) {
+ switch (reg->Register.File) {
case TGSI_FILE_OUTPUT:
/* Output registers encode semantic information in their name.
* Need to lookup a table built at decl time:
*/
- dest = emit->output_map[reg->DstRegister.Index];
+ dest = emit->output_map[reg->Register.Index];
break;
default:
- dest = dst_register( translate_file( reg->DstRegister.File ),
- reg->DstRegister.Index );
+ dest = dst_register( translate_file( reg->Register.File ),
+ reg->Register.Index );
break;
}
- dest.mask = reg->DstRegister.WriteMask;
+ dest.mask = reg->Register.WriteMask;
+ assert(dest.mask);
if (insn->Instruction.Saturate)
dest.dstMod = SVGA3DDSTMOD_SATURATE;
{
struct src_register src;
- switch (reg->SrcRegister.File) {
+ switch (reg->Register.File) {
case TGSI_FILE_INPUT:
/* Input registers are referred to by their semantic name rather
* than by index. Use the mapping build up from the decls:
*/
- src = emit->input_map[reg->SrcRegister.Index];
+ src = emit->input_map[reg->Register.Index];
break;
case TGSI_FILE_IMMEDIATE:
/* Immediates are appended after TGSI constants in the D3D
* constant buffer.
*/
- src = src_register( translate_file( reg->SrcRegister.File ),
- reg->SrcRegister.Index +
+ src = src_register( translate_file( reg->Register.File ),
+ reg->Register.Index +
emit->imm_start );
break;
default:
- src = src_register( translate_file( reg->SrcRegister.File ),
- reg->SrcRegister.Index );
+ src = src_register( translate_file( reg->Register.File ),
+ reg->Register.Index );
break;
}
/* Indirect addressing (for coninstant buffer lookups only)
*/
- if (reg->SrcRegister.Indirect)
+ if (reg->Register.Indirect)
{
/* we shift the offset towards the minimum */
if (svga_arl_needs_adjustment( emit )) {
/* Not really sure what should go in the second token:
*/
src.indirect = src_token( SVGA3DREG_ADDR,
- reg->SrcRegisterInd.Index );
+ reg->Indirect.Index );
src.indirect.swizzle = SWIZZLE_XXXX;
}
src = swizzle( src,
- reg->SrcRegister.SwizzleX,
- reg->SrcRegister.SwizzleY,
- reg->SrcRegister.SwizzleZ,
- reg->SrcRegister.SwizzleW );
+ reg->Register.SwizzleX,
+ reg->Register.SwizzleY,
+ reg->Register.SwizzleZ,
+ reg->Register.SwizzleW );
/* src.mod isn't a bitfield, unfortunately:
* See tgsi_util_get_full_src_register_sign_mode for implementation details.
*/
- if (reg->SrcRegisterExtMod.Absolute) {
- if (reg->SrcRegisterExtMod.Negate)
+ if (reg->Register.Absolute) {
+ if (reg->Register.Negate)
src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
else
src.base.srcMod = SVGA3DSRCMOD_ABS;
}
else {
- if (reg->SrcRegister.Negate != reg->SrcRegisterExtMod.Negate)
+ if (reg->Register.Negate)
src.base.srcMod = SVGA3DSRCMOD_NEG;
else
src.base.srcMod = SVGA3DSRCMOD_NONE;
}
+
+
+/* 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.
+ */
+static boolean submit_op4( struct svga_shader_emitter *emit,
+ SVGA3dShaderInstToken inst,
+ SVGA3dShaderDestToken dest,
+ struct src_register src0,
+ struct src_register src1,
+ struct src_register src2,
+ struct src_register src3)
+{
+ SVGA3dShaderDestToken temp0;
+ SVGA3dShaderDestToken temp3;
+ boolean need_temp0 = FALSE;
+ boolean need_temp3 = FALSE;
+ SVGA3dShaderRegType type0, type1, type2, type3;
+
+ temp0.value = 0;
+ temp3.value = 0;
+ type0 = SVGA3dShaderGetRegType( src0.base.value );
+ type1 = SVGA3dShaderGetRegType( src1.base.value );
+ type2 = SVGA3dShaderGetRegType( src2.base.value );
+ type3 = SVGA3dShaderGetRegType( src2.base.value );
+
+ /* Make life a little easier - this is only used by the TXD
+ * instruction which is guaranteed not to have a constant/input reg
+ * in one slot at least:
+ */
+ assert(type1 == SVGA3DREG_SAMPLER);
+
+ if (type0 == SVGA3DREG_CONST &&
+ ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
+ (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
+ need_temp0 = TRUE;
+
+ if (type3 == SVGA3DREG_CONST &&
+ (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
+ need_temp3 = TRUE;
+
+ if (type0 == SVGA3DREG_INPUT &&
+ ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
+ (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
+ need_temp0 = TRUE;
+
+ if (type3 == SVGA3DREG_INPUT &&
+ (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
+ need_temp3 = TRUE;
+
+ if (need_temp0)
+ {
+ temp0 = get_temp( emit );
+
+ if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 ))
+ return FALSE;
+
+ src0 = src( temp0 );
+ }
+
+ if (need_temp3)
+ {
+ temp3 = get_temp( emit );
+
+ if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp3, src3 ))
+ return FALSE;
+
+ src3 = src( temp3 );
+ }
+
+ if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
+ return FALSE;
+
+ if (need_temp3)
+ release_temp( emit, temp3 );
+ if (need_temp0)
+ release_temp( emit, temp0 );
+ return TRUE;
+}
+
+
static boolean emit_def_const( struct svga_shader_emitter *emit,
SVGA3dShaderConstType type,
unsigned idx,
break;
default:
assert(0);
+ opcode = inst_token( SVGA3DOP_NOP );
break;
}
const struct tgsi_full_instruction *insn)
{
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register src1 = get_fake_arl_const( emit );
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
SVGA3dShaderDestToken tmp = get_temp( emit );
const struct tgsi_full_instruction *insn)
{
const struct src_register src = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register zero = get_zero_immediate( emit );
SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
if_token.control = SVGA3DOPCOMPC_NE;
zero = scalar(zero, TGSI_SWIZZLE_X);
+ emit->dynamic_branching_level++;
+
return (emit_instruction( emit, if_token ) &&
emit_src( emit, src ) &&
emit_src( emit, zero ) );
static boolean emit_endif(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
{
+ emit->dynamic_branching_level--;
+
return (emit_instruction( emit,
inst_token( SVGA3DOP_ENDIF )));
}
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* FRC TMP, SRC */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
const struct src_register src2 = translate_src_register(
- emit, &insn->FullSrcRegisters[2] );
+ emit, &insn->Src[2] );
/* CMP DST, SRC0, SRC2, SRC1 */
return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst, src0, src2, src1);
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
SVGA3dShaderDestToken temp = get_temp( emit );
int i;
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
SVGA3dShaderDestToken temp = get_temp( emit );
struct src_register temp_src0, temp_src1;
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* DP3 TMP, SRC1, SRC2 */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* DP3 TMP, SRC, SRC */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* SCS TMP SRC */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* SCS TMP SRC */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
SVGA3dShaderDestToken temp = get_temp( emit );
/* SCS TMP SRC */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
src1 = negate(src1);
const struct tgsi_full_instruction *insn )
{
SVGA3dShaderInstToken inst;
- const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[0];
+ const struct tgsi_full_src_register *reg = &insn->Src[0];
struct src_register src0;
inst = inst_token( SVGA3DOP_TEXKILL );
src0 = translate_src_register( emit, reg );
- if (reg->SrcRegisterExtMod.Absolute ||
- reg->SrcRegister.Negate != reg->SrcRegisterExtMod.Negate ||
- reg->SrcRegister.Indirect ||
- reg->SrcRegister.SwizzleX != 0 ||
- reg->SrcRegister.SwizzleY != 1 ||
- reg->SrcRegister.SwizzleZ != 2 ||
- reg->SrcRegister.File != TGSI_FILE_TEMPORARY)
+ if (reg->Register.Absolute ||
+ reg->Register.Negate ||
+ reg->Register.Indirect ||
+ reg->Register.SwizzleX != 0 ||
+ reg->Register.SwizzleY != 1 ||
+ reg->Register.SwizzleZ != 2 ||
+ reg->Register.File != TGSI_FILE_TEMPORARY)
{
SVGA3dShaderDestToken temp = get_temp( emit );
{
SVGA3dShaderInstToken inst;
SVGA3dShaderDestToken temp;
- struct src_register one = get_zero_immediate( emit );
+ struct src_register one = scalar( get_zero_immediate( emit ),
+ TGSI_SWIZZLE_W );
inst = inst_token( SVGA3DOP_TEXKILL );
- one = scalar( one, TGSI_SWIZZLE_W );
/* texkill doesn't allow negation on the operand so lets move
* negation of {1} to a temp register */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
return emit_select( emit, compare, dst, src0, src1 );
}
SVGA3dShaderDestToken dst )
{
SVGA3dShaderInstToken inst;
- struct src_register src0;
- struct src_register src1;
-
+ struct src_register texcoord;
+ struct src_register sampler;
+ SVGA3dShaderDestToken tmp;
+
inst.value = 0;
- inst.op = SVGA3DOP_TEX;
switch (insn->Instruction.Opcode) {
case TGSI_OPCODE_TEX:
+ inst.op = SVGA3DOP_TEX;
break;
case TGSI_OPCODE_TXP:
+ inst.op = SVGA3DOP_TEX;
inst.control = SVGA3DOPCONT_PROJECT;
break;
case TGSI_OPCODE_TXB:
+ inst.op = SVGA3DOP_TEX;
inst.control = SVGA3DOPCONT_BIAS;
break;
+ case TGSI_OPCODE_TXL:
+ inst.op = SVGA3DOP_TEXLDL;
+ break;
default:
assert(0);
return FALSE;
}
- src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
- src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
+ texcoord = translate_src_register( emit, &insn->Src[0] );
+ sampler = translate_src_register( emit, &insn->Src[1] );
- if (emit->key.fkey.tex[src1.base.num].unnormalized) {
- struct src_register wh = get_tex_dimensions( emit, src1.base.num );
- SVGA3dShaderDestToken tmp = get_temp( emit );
+ if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
+ emit->dynamic_branching_level > 0)
+ tmp = get_temp( emit );
+
+ /* Can't do mipmapping inside dynamic branch constructs. Force LOD
+ * zero in that case.
+ */
+ if (emit->dynamic_branching_level > 0 &&
+ inst.op == SVGA3DOP_TEX &&
+ SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
+ struct src_register zero = get_zero_immediate( emit );
+
+ /* MOV tmp, texcoord */
+ if (!submit_op1( emit,
+ inst_token( SVGA3DOP_MOV ),
+ tmp,
+ texcoord ))
+ return FALSE;
+
+ /* MOV tmp.w, zero */
+ if (!submit_op1( emit,
+ inst_token( SVGA3DOP_MOV ),
+ writemask( tmp, TGSI_WRITEMASK_W ),
+ scalar( zero, TGSI_SWIZZLE_X )))
+ return FALSE;
+
+ texcoord = src( tmp );
+ inst.op = SVGA3DOP_TEXLDL;
+ }
+
+ /* Explicit normalization of texcoords:
+ */
+ if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
+ struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
/* MUL tmp, SRC0, WH */
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
- tmp, src0, wh ))
+ tmp, texcoord, wh ))
return FALSE;
- src0 = src( tmp );
+
+ texcoord = src( tmp );
}
- return submit_op2( emit, inst, dst, src0, src1 );
+ return submit_op2( emit, inst, dst, texcoord, sampler );
}
/* Translate texture instructions to SVGA3D representation.
*/
-static boolean emit_tex3(struct svga_shader_emitter *emit,
+static boolean emit_tex4(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn,
SVGA3dShaderDestToken dst )
{
SVGA3dShaderInstToken inst;
- struct src_register src0;
- struct src_register src1;
- struct src_register src2;
+ struct src_register texcoord;
+ struct src_register ddx;
+ struct src_register ddy;
+ struct src_register sampler;
+
+ texcoord = translate_src_register( emit, &insn->Src[0] );
+ ddx = translate_src_register( emit, &insn->Src[1] );
+ ddy = translate_src_register( emit, &insn->Src[2] );
+ sampler = translate_src_register( emit, &insn->Src[3] );
inst.value = 0;
switch (insn->Instruction.Opcode) {
case TGSI_OPCODE_TXD:
- inst.op = SVGA3DOP_TEXLDD;
- break;
- case TGSI_OPCODE_TXL:
- inst.op = SVGA3DOP_TEXLDL;
+ inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
break;
+ default:
+ assert(0);
+ return FALSE;
}
- src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
- src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
- src2 = translate_src_register( emit, &insn->FullSrcRegisters[2] );
-
- return submit_op3( emit, inst, dst, src0, src1, src2 );
+ return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
}
SVGA3dShaderDestToken dst =
translate_dst_register( emit, insn, 0 );
struct src_register src0 =
- translate_src_register( emit, &insn->FullSrcRegisters[0] );
+ translate_src_register( emit, &insn->Src[0] );
struct src_register src1 =
- translate_src_register( emit, &insn->FullSrcRegisters[1] );
+ translate_src_register( emit, &insn->Src[1] );
SVGA3dShaderDestToken tex_result;
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXP:
+ case TGSI_OPCODE_TXL:
if (!emit_tex2( emit, insn, tex_result ))
return FALSE;
break;
- case TGSI_OPCODE_TXL:
case TGSI_OPCODE_TXD:
- if (!emit_tex3( emit, insn, tex_result ))
+ if (!emit_tex4( emit, insn, tex_result ))
return FALSE;
break;
default:
if (compare) {
- SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
- struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
- struct src_register one =
- scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
-
- /* Divide texcoord R by Q */
- if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
- src0_zdivw,
- scalar(src0, TGSI_SWIZZLE_W) ))
- return FALSE;
+ if (dst.mask & TGSI_WRITEMASK_XYZ) {
+ SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
+ struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
+
+ /* Divide texcoord R by Q */
+ if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
+ writemask(src0_zdivw, TGSI_WRITEMASK_X),
+ scalar(src0, TGSI_SWIZZLE_W) ))
+ return FALSE;
- if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
- src0_zdivw,
- scalar(src0, TGSI_SWIZZLE_Z),
- src(src0_zdivw) ))
- return FALSE;
+ if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
+ writemask(src0_zdivw, TGSI_WRITEMASK_X),
+ scalar(src0, TGSI_SWIZZLE_Z),
+ scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
+ return FALSE;
- if (!emit_select(
- emit,
- emit->key.fkey.tex[src1.base.num].compare_func,
- dst,
- src(src0_zdivw),
- tex_src_x))
- return FALSE;
+ if (!emit_select(
+ emit,
+ emit->key.fkey.tex[src1.base.num].compare_func,
+ writemask( dst, TGSI_WRITEMASK_XYZ ),
+ scalar(src(src0_zdivw), TGSI_SWIZZLE_X),
+ tex_src_x))
+ return FALSE;
+ }
- return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
- writemask( dst, TGSI_WRITEMASK_W),
- one );
+ if (dst.mask & TGSI_WRITEMASK_W) {
+ struct src_register one =
+ scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
+
+ if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+ writemask( dst, TGSI_WRITEMASK_W ),
+ one ))
+ return FALSE;
+ }
+
+ return TRUE;
}
else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW)
{
struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
struct src_register const_int = get_loop_const( emit );
+ emit->dynamic_branching_level++;
+
return (emit_instruction( emit, inst ) &&
emit_src( emit, loop_reg ) &&
emit_src( emit, const_int ) );
const struct tgsi_full_instruction *insn )
{
SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
+
+ emit->dynamic_branching_level--;
+
return emit_instruction( emit, inst );
}
inst = inst_token( opcode );
dst = translate_dst_register( emit, insn, 0 );
- src = translate_src_register( emit, &insn->FullSrcRegisters[0] );
+ src = translate_src_register( emit, &insn->Src[0] );
src = scalar( src, TGSI_SWIZZLE_X );
return submit_op1( emit, inst, dst, src );
unsigned opcode,
const struct tgsi_full_instruction *insn )
{
- const struct tgsi_full_src_register *src = insn->FullSrcRegisters;
+ const struct tgsi_full_src_register *src = insn->Src;
SVGA3dShaderInstToken inst;
SVGA3dShaderDestToken dst;
}
}
+
+static boolean emit_deriv(struct svga_shader_emitter *emit,
+ const struct tgsi_full_instruction *insn )
+{
+ if (emit->dynamic_branching_level > 0 &&
+ insn->Src[0].Register.File == TGSI_FILE_TEMPORARY)
+ {
+ struct src_register zero = get_zero_immediate( emit );
+ SVGA3dShaderDestToken dst =
+ translate_dst_register( emit, insn, 0 );
+
+ /* Deriv opcodes not valid inside dynamic branching, workaround
+ * by zeroing out the destination.
+ */
+ if (!submit_op1(emit,
+ inst_token( SVGA3DOP_MOV ),
+ dst,
+ scalar(zero, TGSI_SWIZZLE_X)))
+ return FALSE;
+
+ return TRUE;
+ }
+ else {
+ unsigned opcode;
+
+ switch (insn->Instruction.Opcode) {
+ case TGSI_OPCODE_DDX:
+ opcode = SVGA3DOP_DSX;
+ break;
+ case TGSI_OPCODE_DDY:
+ opcode = SVGA3DOP_DSY;
+ break;
+ default:
+ return FALSE;
+ }
+
+ return emit_simple_instruction( emit, opcode, insn );
+ }
+}
+
static boolean emit_arl(struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn)
{
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
boolean need_tmp = FALSE;
/* POW can only output to a temporary */
- if (insn->FullDstRegisters[0].DstRegister.File != TGSI_FILE_TEMPORARY)
+ if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
need_tmp = TRUE;
/* POW src1 must not be the same register as dst */
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
boolean need_dst_tmp = FALSE;
/* XPD can only output to a temporary */
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
SVGA3dShaderDestToken tmp;
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
const struct src_register src2 = translate_src_register(
- emit, &insn->FullSrcRegisters[2] );
+ emit, &insn->Src[2] );
boolean need_dst_tmp = FALSE;
/* The dst reg must not be the same as src0 or src2 */
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
SVGA3dShaderDestToken tmp;
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
const struct src_register src1 = translate_src_register(
- emit, &insn->FullSrcRegisters[1] );
+ emit, &insn->Src[1] );
struct src_register zero = get_zero_immediate( emit );
boolean need_tmp = FALSE;
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 =
- translate_src_register( emit, &insn->FullSrcRegisters[0] );
+ translate_src_register( emit, &insn->Src[0] );
struct src_register zero = get_zero_immediate( emit );
SVGA3dShaderDestToken fraction;
fraction = dst;
else if (dst.mask & TGSI_WRITEMASK_X)
fraction = get_temp( emit );
+ else
+ fraction.value = 0;
/* If y is being written, fill it with src0 - floor(src0).
*/
*/
if (dst.mask & TGSI_WRITEMASK_X) {
if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
- writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
+ writemask( dst, TGSI_WRITEMASK_X ),
src0,
scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
return FALSE;
if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
- writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
+ writemask( dst, TGSI_WRITEMASK_X ),
scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
return FALSE;
*/
if (dst.mask & TGSI_WRITEMASK_Z) {
if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
- writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
+ writemask( dst, TGSI_WRITEMASK_Z ),
src0 ) )
return FALSE;
}
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
SVGA3dShaderDestToken tmp = get_temp( emit );
const struct src_register src0 = translate_src_register(
- emit, &insn->FullSrcRegisters[0] );
+ emit, &insn->Src[0] );
struct src_register zero = get_zero_immediate( emit );
/* tmp = pow(src.y, src.w)
inst = inst_token( SVGA3DOP_EXP );
dst = translate_dst_register( emit, insn, 0 );
- src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
+ src0 = translate_src_register( emit, &insn->Src[0] );
src0 = scalar( src0, TGSI_SWIZZLE_X );
if (dst.mask != TGSI_WRITEMASK_XYZW) {
{
SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
struct src_register src0 =
- translate_src_register( emit, &insn->FullSrcRegisters[0] );
+ translate_src_register( emit, &insn->Src[0] );
struct src_register zero = get_zero_immediate( emit );
SVGA3dShaderDestToken abs_tmp;
struct src_register abs_src0;
SVGA3dShaderDestToken log2_abs;
+ abs_tmp.value = 0;
+
if (dst.mask & TGSI_WRITEMASK_Z)
log2_abs = dst;
else if (dst.mask & TGSI_WRITEMASK_XY)
log2_abs = get_temp( emit );
+ else
+ log2_abs.value = 0;
/* If z is being written, fill it with log2( abs( src0 ) ).
*/
static boolean emit_call( struct svga_shader_emitter *emit,
const struct tgsi_full_instruction *insn )
{
- unsigned position = insn->InstructionExtLabel.Label;
+ unsigned position = insn->Label.Label;
unsigned i;
for (i = 0; i < emit->nr_labels; i++) {
case TGSI_OPCODE_TXD:
return emit_tex( emit, insn );
+ case TGSI_OPCODE_DDX:
+ case TGSI_OPCODE_DDY:
+ return emit_deriv( emit, insn );
+
case TGSI_OPCODE_BGNSUB:
return emit_bgnsub( emit, position, insn );
case TGSI_OPCODE_I2F:
case TGSI_OPCODE_NOT:
case TGSI_OPCODE_SHL:
- case TGSI_OPCODE_SHR:
+ case TGSI_OPCODE_ISHR:
case TGSI_OPCODE_XOR:
return FALSE;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
- if (!submit_op1( emit,
- inst_token(SVGA3DOP_MOV),
- emit->true_col[i],
- src(emit->temp_col[i]) ))
- return FALSE;
+ /* Potentially override output colors with white for XOR
+ * logicop workaround.
+ */
+ if (emit->unit == PIPE_SHADER_FRAGMENT &&
+ emit->key.fkey.white_fragments) {
+
+ struct src_register one = scalar( get_zero_immediate( emit ),
+ TGSI_SWIZZLE_W );
+
+ if (!submit_op1( emit,
+ inst_token(SVGA3DOP_MOV),
+ emit->true_col[i],
+ one ))
+ return FALSE;
+ }
+ else {
+ if (!submit_op1( emit,
+ inst_token(SVGA3DOP_MOV),
+ emit->true_col[i],
+ src(emit->temp_col[i]) ))
+ return FALSE;
+ }
}
}
if (emit->key.fkey.light_twoside)
return TRUE;
+ if (emit->key.fkey.white_fragments)
+ return TRUE;
+
if (emit->emit_frontface)
return TRUE;
}
if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
+ emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
+ emit->info.opcode_count[TGSI_OPCODE_BGNFOR] >= 1 ||
+ emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
+ emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
const struct tgsi_full_instruction *insn,
int current_arl)
{
- if (insn->FullSrcRegisters[0].SrcRegister.Indirect &&
- insn->FullSrcRegisters[0].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
- const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[0];
- if (reg->SrcRegister.Index < 0) {
- pre_parse_add_indirect(emit, reg->SrcRegister.Index, current_arl);
+ if (insn->Src[0].Register.Indirect &&
+ insn->Src[0].Indirect.File == TGSI_FILE_ADDRESS) {
+ const struct tgsi_full_src_register *reg = &insn->Src[0];
+ if (reg->Register.Index < 0) {
+ pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
}
}
- if (insn->FullSrcRegisters[1].SrcRegister.Indirect &&
- insn->FullSrcRegisters[1].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
- const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[1];
- if (reg->SrcRegister.Index < 0) {
- pre_parse_add_indirect(emit, reg->SrcRegister.Index, current_arl);
+ if (insn->Src[1].Register.Indirect &&
+ insn->Src[1].Indirect.File == TGSI_FILE_ADDRESS) {
+ const struct tgsi_full_src_register *reg = &insn->Src[1];
+ if (reg->Register.Index < 0) {
+ pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
}
}
- if (insn->FullSrcRegisters[2].SrcRegister.Indirect &&
- insn->FullSrcRegisters[2].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
- const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[2];
- if (reg->SrcRegister.Index < 0) {
- pre_parse_add_indirect(emit, reg->SrcRegister.Index, current_arl);
+ if (insn->Src[2].Register.Indirect &&
+ insn->Src[2].Indirect.File == TGSI_FILE_ADDRESS) {
+ const struct tgsi_full_src_register *reg = &insn->Src[2];
+ if (reg->Register.Index < 0) {
+ pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
}
}
goto done;
}
+ assert(emit->dynamic_branching_level == 0);
+
/* Need to terminate the whole shader:
*/
ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );