diff options
author | Nicolai Haehnle <nhaehnle@gmail.com> | 2007-03-24 19:08:26 +0100 |
---|---|---|
committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2007-03-24 19:09:44 +0100 |
commit | f27991c9165450872c652e2fd27811409957b2a0 (patch) | |
tree | e9e5e8d3023498c04c2b04fe5dce9a554d10f2e0 /src/mesa/drivers/dri/r300/r300_fragprog.c | |
parent | 0c3ae2ea7fbb9c1087bdbc1048c380ca760b80d2 (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.c | 39 |
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); } |