return r;
}
+static pfs_reg_t get_temp_reg_tex(struct r300_fragment_program *rp)
+{
+ pfs_reg_t r = pfs_default_reg;
+ int hwreg;
+
+ hwreg = ffs(~(rp->hwreg_in_use | rp->used_in_node));
+ if (!hwreg) {
+ /* Try and grab an already used temp, will
+ * cause an indirection, but better than failing */
+ return get_temp_reg(rp);
+ }
+ if (hwreg > rp->max_temp_idx)
+ rp->max_temp_idx = hwreg;
+
+ r.index = ffs(~rp->temp_in_use);
+ if (!r.index) {
+ ERROR("Out of program temps\n");
+ return r;
+ }
+ rp->temp_in_use |= (1 << --r.index);
+ rp->temps[r.index] = --hwreg;
+
+ r.valid = GL_TRUE;
+ return r;
+}
+
static void free_temp(struct r300_fragment_program *rp, pfs_reg_t r)
{
if (!rp || !(rp->temp_in_use & (1<<r.index))) return;
static int swz_special_case(struct r300_fragment_program *rp,
pfs_reg_t src, pfs_reg_t *r, int mask, int mc)
{
- pfs_reg_t ssrc = pfs_default_reg;
-
switch(GET_SWZ(v_swiz[src.v_swz].hash, 0)) {
case SWIZZLE_ONE:
case SWIZZLE_ZERO:
int opcode)
{
pfs_reg_t coord = t_src(rp, fpi->SrcReg[0]);
- pfs_reg_t dest = t_dst(rp, fpi->DstReg);
+ pfs_reg_t dest = t_dst(rp, fpi->DstReg), rdest = pfs_default_reg;
int unit = fpi->TexSrcUnit;
int hwsrc, hwdest, flags = 0;
+ if (dest.type == REG_TYPE_OUTPUT) {
+ rdest = dest;
+ dest = get_temp_reg_tex(rp);
+ }
+
switch (coord.type) {
case REG_TYPE_TEMP:
hwsrc = rp->temps[coord.index];
ERROR("too many levels of texture indirection\n");
return;
}
+
/* Finish off current node */
sync_streams(rp);
rp->node[rp->cur_node].alu_end = rp->v_pos - 1;
| (unit << R300_FPITX_IMAGE_SHIFT)
| (opcode << R300_FPITX_OPCODE_SHIFT) /* not entirely sure about this */
| flags;
- rp->dest_in_node |= (1 << hwdest);
-
+ rp->dest_in_node |= (1 << hwdest);
+ if (coord.type != REG_TYPE_CONST)
+ rp->used_in_node |= (1 << hwsrc);
+
rp->node[rp->cur_node].tex_end++;
+
+ /* Copy from temp to output if needed */
+ if (rdest.valid) {
+ emit_arith(rp, PFS_OP_MAD, rdest, WRITEMASK_XYZW, dest, pfs_one, pfs_zero, 0);
+ free_temp(rp, dest);
+ }
}
#define ARG_NEG (1<<5)
void translate_fragment_shader(struct r300_fragment_program *rp)
{
int i;
-
+
if (!rp->translated) {
init_program(rp);
if (0) dump_program(rp);
}
+
update_params(rp);
}