r300/compiler: add emulation of all mirrored-clamp wrap modes for NPOT textures
authorMarek Olšák <maraeo@gmail.com>
Sat, 17 Apr 2010 00:43:47 +0000 (02:43 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 17 Apr 2010 00:43:47 +0000 (02:43 +0200)
src/gallium/drivers/r300/r300_fs.c
src/mesa/drivers/dri/r300/compiler/radeon_code.h
src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c

index a37f23aaef2ecc661f4eff0128ad13e1c0f9702f..4d61f6385301d53b8793e548509a72f31c912a97 100644 (file)
@@ -169,10 +169,14 @@ static void get_external_state(
                         break;
 
                     case PIPE_TEX_WRAP_MIRROR_REPEAT:
+                        state->unit[i].wrap_mode = RC_WRAP_MIRRORED_REPEAT;
+                        state->unit[i].fake_npot = TRUE;
+                        break;
+
                     case PIPE_TEX_WRAP_MIRROR_CLAMP:
                     case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
                     case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
-                        state->unit[i].wrap_mode = RC_WRAP_MIRROR;
+                        state->unit[i].wrap_mode = RC_WRAP_MIRRORED_CLAMP;
                         state->unit[i].fake_npot = TRUE;
                         break;
 
index 28bcd1029bb2c89ca01e7ecc4e12a39fe2757c98..27274f07122d32b5985103d3ce387804e7ba4073 100644 (file)
@@ -115,7 +115,8 @@ typedef enum {
 typedef enum {
        RC_WRAP_NONE = 0,
        RC_WRAP_REPEAT,
-       RC_WRAP_MIRROR
+       RC_WRAP_MIRRORED_REPEAT,
+       RC_WRAP_MIRRORED_CLAMP
 } rc_wrap_mode;
 
 /**
index a8927acdffad18d804483f233cdd72e5d3d4f03d..0ca95d454b6d17f60a212f373e226c7450975458 100644 (file)
@@ -233,7 +233,7 @@ int radeonTransformTEX(
                                inst_frc->U.I.DstReg.Index = temp;
                                inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
                                inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
-                       } else if (wrapmode == RC_WRAP_MIRROR) {
+                       } else if (wrapmode == RC_WRAP_MIRRORED_REPEAT) {
                                /*
                                 * Function:
                                 *   f(v) = 1 - abs(frac(v * 0.5) * 2 - 1)
@@ -295,6 +295,22 @@ int radeonTransformTEX(
                                inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
                                inst_add->U.I.SrcReg[1].Abs = 1;
                                inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ;
+                       } else if (wrapmode == RC_WRAP_MIRRORED_CLAMP) {
+                               /*
+                                * Mirrored clamp modes are bloody simple, we just use abs
+                                * to mirror [0, 1] into [-1, 0]. This works for
+                                * all modes i.e. CLAMP, CLAMP_TO_EDGE, and CLAMP_TO_BORDER.
+                                */
+                               struct rc_instruction *inst_mov;
+
+                               inst_mov = rc_insert_new_instruction(c, inst->Prev);
+
+                               inst_mov->U.I.Opcode = RC_OPCODE_MOV;
+                               inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
+                               inst_mov->U.I.DstReg.Index = temp;
+                               inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+                               inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+                               inst_mov->U.I.SrcReg[0].Abs = 1;
                        }
 
                        /* Preserve W for TXP/TXB. */