summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/r300_fragprog.c
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2007-03-24 19:08:26 +0100
committerNicolai Haehnle <nhaehnle@gmail.com>2007-03-24 19:09:44 +0100
commitf27991c9165450872c652e2fd27811409957b2a0 (patch)
treee9e5e8d3023498c04c2b04fe5dce9a554d10f2e0 /src/mesa/drivers/dri/r300/r300_fragprog.c
parent0c3ae2ea7fbb9c1087bdbc1048c380ca760b80d2 (diff)
r300: Fix texture coordinate calculation for rectangle textures
R300 hardware takes texcoords in the range 0..1 even for rectangle textures. Previously, the necessary texcoord conversion was applied to the texture coordinate during vertex processing in a render stage. This is obviously wrong when fragment programs are used, which can calculate arbitrary coordinates for TEX instructions. Therefore, we now inject an appropriate MUL instruction before a TEX that reference a rectangle texture.
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_fragprog.c')
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 0d7d1f1af2..68a75ec7f0 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -929,13 +929,40 @@ static void emit_tex(struct r300_fragment_program *rp,
COMPILE_STATE;
GLuint coord = t_src(rp, fpi->SrcReg[0]);
GLuint dest = undef, rdest = undef;
- GLuint din = cs->dest_in_node, uin = cs->used_in_node;
+ GLuint din, uin;
int unit = fpi->TexSrcUnit;
int hwsrc, hwdest;
+ GLuint tempreg = 0;
/* Resolve source/dest to hardware registers */
- hwsrc = t_hw_src(rp, coord, GL_TRUE);
if (opcode != R300_FPITX_OP_KIL) {
+ if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) {
+ /**
+ * Hardware uses [0..1]x[0..1] range for rectangle textures
+ * instead of [0..Width]x[0..Height].
+ * Add a scaling instruction.
+ *
+ * \todo Refactor this once we have proper rewriting/optimization
+ * support for programs.
+ */
+ GLint tokens[6] = { STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, 0, 0 };
+ int factor_index;
+ GLuint factorreg;
+
+ tokens[2] = unit;
+ factor_index = _mesa_add_state_reference(rp->mesa_program.Base.Parameters, tokens);
+ factorreg = emit_const4fv(rp,
+ rp->mesa_program.Base.Parameters->ParameterValues[factor_index]);
+ tempreg = keep(get_temp_reg(rp));
+
+ emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW,
+ coord, factorreg, pfs_zero, 0);
+
+ hwsrc = t_hw_src(rp, tempreg, GL_TRUE);
+ } else {
+ hwsrc = t_hw_src(rp, coord, GL_TRUE);
+ }
+
dest = t_dst(rp, fpi->DstReg);
/* r300 doesn't seem to be able to do TEX->output reg */
@@ -956,8 +983,12 @@ static void emit_tex(struct r300_fragment_program *rp,
} else {
hwdest = 0;
unit = 0;
+ hwsrc = t_hw_src(rp, coord, GL_TRUE);
}
+ din = cs->dest_in_node;
+ uin = cs->used_in_node;
+
/* Indirection if source has been written in this node, or if the
* dest has been read/written in this node
*/
@@ -1009,6 +1040,10 @@ static void emit_tex(struct r300_fragment_program *rp,
pfs_one, pfs_zero, 0);
free_temp(rp, dest);
}
+
+ /* Free temp register */
+ if (tempreg != 0)
+ free_temp(rp, tempreg);
}