summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c427
1 files changed, 255 insertions, 172 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index 313d0b28cf..da2c6dbcd5 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -416,49 +416,68 @@ static GLboolean valid_dst(struct r300_vertex_program *vp,
return GL_TRUE;
}
-static void t_opcode_pow(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- struct r300_vertprog_instruction *o_inst,
- struct prog_src_register src[3])
-{
- o_inst->opcode =
- MAKE_VSF_OP(R300_VPI_OUT_OP_POW, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src_scalar(vp, &src[0]);
- o_inst->src[1] = ZERO_SRC_0;
- o_inst->src[2] = t_src_scalar(vp, &src[1]);
-}
+/*
+ * Instruction Inputs Output Description
+ * ----------- ------ ------ --------------------------------
+ * ABS v v absolute value
+ * ADD v,v v add
+ * ARL s a address register load
+ * DP3 v,v ssss 3-component dot product
+ * DP4 v,v ssss 4-component dot product
+ * DPH v,v ssss homogeneous dot product
+ * DST v,v v distance vector
+ * EX2 s ssss exponential base 2
+ * EXP s v exponential base 2 (approximate)
+ * FLR v v floor
+ * FRC v v fraction
+ * LG2 s ssss logarithm base 2
+ * LIT v v compute light coefficients
+ * LOG s v logarithm base 2 (approximate)
+ * MAD v,v,v v multiply and add
+ * MAX v,v v maximum
+ * MIN v,v v minimum
+ * MOV v v move
+ * MUL v,v v multiply
+ * POW s,s ssss exponentiate
+ * RCP s ssss reciprocal
+ * RSQ s ssss reciprocal square root
+ * SGE v,v v set on greater than or equal
+ * SLT v,v v set on less than
+ * SUB v,v v subtract
+ * SWZ v v extended swizzle
+ * XPD v,v v cross product
+ *
+ * Table X.5: Summary of vertex program instructions. "v" indicates a
+ * floating-point vector input or output, "s" indicates a floating-point
+ * scalar input, "ssss" indicates a scalar output replicated across a
+ * 4-component result vector, and "a" indicates a single address register
+ * component.
+ */
-static void t_opcode_mov(struct r300_vertex_program *vp,
+static void t_opcode_abs(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
struct prog_src_register src[3])
{
- //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+ //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-#if 1
o_inst->opcode =
- MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+ MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg),
t_dst_mask(vpi->DstReg.WriteMask),
t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] = ZERO_SRC_0;
- o_inst->src[2] = ZERO_SRC_0;
-#else
- hw_op =
- (src[0].File ==
- PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
- R300_VPI_OUT_OP_MAD;
- o_inst->opcode =
- MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] = ONE_SRC_0;
- o_inst->src[2] = ZERO_SRC_0;
-#endif
+ o_inst->src[1] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
+ t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)),
+ t_src_class(src[0].File),
+ (!src[0].
+ NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+ o_inst->src[2] = 0;
}
static void t_opcode_add(struct r300_vertex_program *vp,
@@ -493,51 +512,7 @@ static void t_opcode_add(struct r300_vertex_program *vp,
#endif
}
-static void t_opcode_mad(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- struct r300_vertprog_instruction *o_inst,
- struct prog_src_register src[3])
-{
- unsigned long hw_op;
-
- hw_op = (src[0].File == PROGRAM_TEMPORARY
- && src[1].File == PROGRAM_TEMPORARY
- && src[2].File ==
- PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
- R300_VPI_OUT_OP_MAD;
-
- o_inst->opcode =
- MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] = t_src(vp, &src[1]);
- o_inst->src[2] = t_src(vp, &src[2]);
-}
-
-static void t_opcode_mul(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- struct r300_vertprog_instruction *o_inst,
- struct prog_src_register src[3])
-{
- unsigned long hw_op;
-
- // HW mul can take third arg but appears to have some other limitations.
-
- hw_op = (src[0].File == PROGRAM_TEMPORARY
- && src[1].File ==
- PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
- R300_VPI_OUT_OP_MAD;
-
- o_inst->opcode =
- MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] = t_src(vp, &src[1]);
-
- o_inst->src[2] = ZERO_SRC_1;
-}
+/* TODO: ARL */
static void t_opcode_dp3(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
@@ -574,84 +549,38 @@ static void t_opcode_dp3(struct r300_vertex_program *vp,
o_inst->src[2] = ZERO_SRC_1;
}
-static void t_opcode_sub(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- struct r300_vertprog_instruction *o_inst,
- struct prog_src_register src[3])
-{
- unsigned long hw_op;
-
- //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-
-#if 1
- hw_op = (src[0].File == PROGRAM_TEMPORARY
- && src[1].File ==
- PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
- R300_VPI_OUT_OP_MAD;
-
- o_inst->opcode =
- MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] = ONE_SRC_0;
- o_inst->src[2] =
- MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
- t_src_class(src[1].File),
- (!src[1].
- NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
-#else
- o_inst->opcode =
- MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
+/* TODO: DP4 */
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] =
- MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
- t_src_class(src[1].File),
- (!src[1].
- NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
- o_inst->src[2] = 0;
-#endif
-}
-
-static void t_opcode_abs(struct r300_vertex_program *vp,
+static void t_opcode_dph(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
struct prog_src_register src[3])
{
- //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-
+ //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
o_inst->opcode =
- MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg),
+ MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg),
t_dst_mask(vpi->DstReg.WriteMask),
t_dst_class(vpi->DstReg.File));
- o_inst->src[0] = t_src(vp, &src[0]);
- o_inst->src[1] =
+ o_inst->src[0] =
MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)),
- t_src_class(src[0].File),
- (!src[0].
- NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+ VSF_IN_COMPONENT_ONE, t_src_class(src[0].File),
+ src[0].
+ NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
(src[0].RelAddr << 4);
- o_inst->src[2] = 0;
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = ZERO_SRC_1;
}
+/* TODO: DST */
+
+/* TODO: EX2 */
+
+/* TODO: EXP */
+
static void t_opcode_flr(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
@@ -689,6 +618,8 @@ static void t_opcode_flr(struct r300_vertex_program *vp,
(*u_temp_i)--;
}
+/* TODO: FRC */
+
static void t_opcode_lg2(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
@@ -756,30 +687,165 @@ static void t_opcode_lit(struct r300_vertex_program *vp,
RelAddr << 4);
}
-static void t_opcode_dph(struct r300_vertex_program *vp,
+/* TODO: LOG */
+
+static void t_opcode_mad(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
struct prog_src_register src[3])
{
- //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
+ unsigned long hw_op;
+
+ hw_op = (src[0].File == PROGRAM_TEMPORARY
+ && src[1].File == PROGRAM_TEMPORARY
+ && src[2].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
o_inst->opcode =
- MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg),
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
t_dst_mask(vpi->DstReg.WriteMask),
t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = t_src(vp, &src[2]);
+}
- o_inst->src[0] =
- MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
- VSF_IN_COMPONENT_ONE, t_src_class(src[0].File),
- src[0].
- NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
+/* TODO: MAX */
+
+/* TODO: MIN */
+
+static void t_opcode_mov(struct r300_vertex_program *vp,
+ struct prog_instruction *vpi,
+ struct r300_vertprog_instruction *o_inst,
+ struct prog_src_register src[3])
+{
+ //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+
+#if 1
+ o_inst->opcode =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+#else
+ hw_op =
+ (src[0].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->opcode =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ONE_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+#endif
+}
+
+static void t_opcode_mul(struct r300_vertex_program *vp,
+ struct prog_instruction *vpi,
+ struct r300_vertprog_instruction *o_inst,
+ struct prog_src_register src[3])
+{
+ unsigned long hw_op;
+
+ // HW mul can take third arg but appears to have some other limitations.
+
+ hw_op = (src[0].File == PROGRAM_TEMPORARY
+ && src[1].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->opcode =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
o_inst->src[1] = t_src(vp, &src[1]);
+
o_inst->src[2] = ZERO_SRC_1;
}
+static void t_opcode_pow(struct r300_vertex_program *vp,
+ struct prog_instruction *vpi,
+ struct r300_vertprog_instruction *o_inst,
+ struct prog_src_register src[3])
+{
+ o_inst->opcode =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_POW, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src_scalar(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = t_src_scalar(vp, &src[1]);
+}
+
+/* TODO: RCP */
+
+/* TODO: RSQ */
+
+/* TODO: SGE */
+
+/* TODO: SLT */
+
+static void t_opcode_sub(struct r300_vertex_program *vp,
+ struct prog_instruction *vpi,
+ struct r300_vertprog_instruction *o_inst,
+ struct prog_src_register src[3])
+{
+ unsigned long hw_op;
+
+ //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
+
+#if 1
+ hw_op = (src[0].File == PROGRAM_TEMPORARY
+ && src[1].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->opcode =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ONE_SRC_0;
+ o_inst->src[2] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
+ t_src_class(src[1].File),
+ (!src[1].
+ NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+ (src[1].RelAddr << 4);
+#else
+ o_inst->opcode =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
+ t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
+ t_src_class(src[1].File),
+ (!src[1].
+ NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+ (src[1].RelAddr << 4);
+ o_inst->src[2] = 0;
+#endif
+}
+
+/* TODO: SWZ */
+
static void t_opcode_xpd(struct r300_vertex_program *vp,
struct prog_instruction *vpi,
struct r300_vertprog_instruction *o_inst,
@@ -1064,56 +1130,73 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
}
switch (vpi->Opcode) {
- case OPCODE_POW:
- t_opcode_pow(vp, vpi, o_inst, src);
- break;
- case OPCODE_MOV:
- t_opcode_mov(vp, vpi, o_inst, src);
- break;
- case OPCODE_SWZ:
- t_opcode_mov(vp, vpi, o_inst, src);
+ case OPCODE_ABS:
+ t_opcode_abs(vp, vpi, o_inst, src);
break;
case OPCODE_ADD:
t_opcode_add(vp, vpi, o_inst, src);
break;
- case OPCODE_MAD:
- t_opcode_mad(vp, vpi, o_inst, src);
- break;
- case OPCODE_MUL:
- t_opcode_mul(vp, vpi, o_inst, src);
- break;
+ /* TODO: ARL */
case OPCODE_DP3:
t_opcode_dp3(vp, vpi, o_inst, src);
break;
- case OPCODE_SUB:
- t_opcode_sub(vp, vpi, o_inst, src);
- break;
- case OPCODE_ABS:
- t_opcode_abs(vp, vpi, o_inst, src);
+ /* TODO: DP4 */
+ case OPCODE_DPH:
+ t_opcode_dph(vp, vpi, o_inst, src);
break;
+ /* TODO: DST */
+ /* TODO: EX2 */
+ /* TODO: EXP */
case OPCODE_FLR:
/* FIXME */
t_opcode_flr(vp, vpi, o_inst, src, &u_temp_i);
break;
+ /* TODO: FRC */
case OPCODE_LG2:
t_opcode_lg2(vp, vpi, o_inst, src);
break;
case OPCODE_LIT:
t_opcode_lit(vp, vpi, o_inst, src);
break;
- case OPCODE_DPH:
- t_opcode_dph(vp, vpi, o_inst, src);
+ /* TODO: LOG */
+ case OPCODE_MAD:
+ t_opcode_mad(vp, vpi, o_inst, src);
+ break;
+ /* TODO: MAX */
+ /* TODO: MIN */
+ case OPCODE_MOV:
+ t_opcode_mov(vp, vpi, o_inst, src);
+ break;
+ case OPCODE_MUL:
+ t_opcode_mul(vp, vpi, o_inst, src);
+ break;
+ case OPCODE_POW:
+ t_opcode_pow(vp, vpi, o_inst, src);
+ break;
+ /* TODO: RCP */
+ /* TODO: RSQ */
+ /* TODO: SGE */
+ /* TODO: SLT */
+ case OPCODE_SUB:
+ t_opcode_sub(vp, vpi, o_inst, src);
break;
+ case OPCODE_SWZ:
+ t_opcode_mov(vp, vpi, o_inst, src);
+ break;
+ /* TODO: SWZ */
case OPCODE_XPD:
/* FIXME */
t_opcode_xpd(vp, vpi, o_inst, src, &u_temp_i);
break;
+
case OPCODE_RCC:
t_opcode_rcc(vp, vpi, o_inst, src);
break;
+
case OPCODE_END:
/* empty */
break;
+
default:
t_opcode_default(vp, vpi, o_inst, src,
num_operands, are_srcs_scalar);