From d5af1dce8fc23dc3763773e3c0b7e0be128d2aa0 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Sun, 11 Apr 2010 16:13:45 -0700 Subject: r300/compiler: Implement texcoord repeat and mirror for NPOT. --- src/mesa/drivers/dri/r300/compiler/r500_fragprog.c | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/mesa/drivers/dri/r300/compiler/r500_fragprog.c') diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c index b78d7d5715..c20ee90fcd 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c @@ -138,6 +138,63 @@ int r500_transform_TEX( } } + /* Texture wrap modes don't work on NPOT textures or texrects. */ + if (inst->U.I.Opcode != RC_OPCODE_KIL && + (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT || + compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot || + compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) { + rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode; + struct rc_instruction *inst_rect = NULL; + unsigned temp = rc_find_free_temporary(c); + + if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot && + wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) { + + if ((inst->U.I.TexSrcTarget == RC_TEXTURE_RECT || + compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) { + inst_rect = rc_insert_new_instruction(c, inst->Prev); + + inst_rect->U.I.Opcode = RC_OPCODE_MUL; + inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_rect->U.I.DstReg.Index = temp; + inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; + inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT; + inst_rect->U.I.SrcReg[1].Index = + rc_constants_add_state(&c->Program.Constants, + RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit); + + reset_srcreg(&inst->U.I.SrcReg[0]); + inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; + inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index; + + inst->U.I.TexSrcTarget = RC_TEXTURE_2D; + } + + /* Repeat, with optional mirror */ + inst_rect = rc_insert_new_instruction(c, inst->Prev); + + inst_rect->U.I.Opcode = RC_OPCODE_FRC; + inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_rect->U.I.DstReg.Index = temp; + inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; + + if (wrapmode == RC_WRAP_MIRROR) { + inst_rect = rc_insert_new_instruction(c, inst->Prev); + + inst_rect->U.I.Opcode = RC_OPCODE_SUB; + inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_rect->U.I.DstReg.Index = temp; + inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111; + inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; + inst_rect->U.I.SrcReg[1].Index = temp; + } + + reset_srcreg(&inst->U.I.SrcReg[0]); + inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; + inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index; + } + } + /* Cannot write texture to output registers */ if (inst->U.I.Opcode != RC_OPCODE_KIL && inst->U.I.DstReg.File != RC_FILE_TEMPORARY) { struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst); -- cgit v1.2.3