summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_wm_fp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_fp.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 6df2c95d80..ea3f3fc678 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -111,6 +111,12 @@ static struct prog_src_register src_swizzle1( struct prog_src_register reg, int
return src_swizzle(reg, x, x, x, x);
}
+static struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
+{
+ reg.Swizzle = swizzle;
+ return reg;
+}
+
/***********************************************************************
* Dest regs
@@ -554,12 +560,19 @@ static void precalc_lit( struct brw_wm_compile *c,
}
}
+
+/**
+ * Some TEX instructions require extra code, cube map coordinate
+ * normalization, or coordinate scaling for RECT textures, etc.
+ * This function emits those extra instructions and the TEX
+ * instruction itself.
+ */
static void precalc_tex( struct brw_wm_compile *c,
const struct prog_instruction *inst )
{
struct prog_src_register coord;
struct prog_dst_register tmpcoord;
- GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
struct prog_instruction *out;
@@ -569,9 +582,11 @@ static void precalc_tex( struct brw_wm_compile *c,
struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
struct prog_src_register src0 = inst->SrcReg[0];
+ /* find longest component of coord vector and normalize it */
tmpcoord = get_temp(c);
coord = src_reg_from_dst(tmpcoord);
+ /* tmpcoord = src0 (i.e.: coord = src0) */
out = emit_op(c, OPCODE_MOV,
tmpcoord,
0, 0, 0,
@@ -581,6 +596,7 @@ static void precalc_tex( struct brw_wm_compile *c,
out->SrcReg[0].NegateBase = 0;
out->SrcReg[0].Abs = 1;
+ /* tmp0 = MAX(coord.X, coord.Y) */
emit_op(c, OPCODE_MAX,
tmp0,
0, 0, 0,
@@ -588,6 +604,7 @@ static void precalc_tex( struct brw_wm_compile *c,
src_swizzle1(coord, Y),
src_undef());
+ /* tmp1 = MAX(tmp0, coord.Z) */
emit_op(c, OPCODE_MAX,
tmp1,
0, 0, 0,
@@ -595,6 +612,7 @@ static void precalc_tex( struct brw_wm_compile *c,
src_swizzle1(coord, Z),
src_undef());
+ /* tmp0 = 1 / tmp1 */
emit_op(c, OPCODE_RCP,
tmp0,
0, 0, 0,
@@ -602,6 +620,7 @@ static void precalc_tex( struct brw_wm_compile *c,
src_undef(),
src_undef());
+ /* tmpCoord = src0 * tmp0 */
emit_op(c, OPCODE_MUL,
tmpcoord,
0, 0, 0,
@@ -611,7 +630,8 @@ static void precalc_tex( struct brw_wm_compile *c,
release_temp(c, tmp0);
release_temp(c, tmp1);
- } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
+ }
+ else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
struct prog_src_register scale =
search_or_add_param5( c,
STATE_INTERNAL,
@@ -642,19 +662,9 @@ static void precalc_tex( struct brw_wm_compile *c,
* conversion requires allocating a temporary variable which we
* don't have the facility to do that late in the compilation.
*/
- if (!(c->key.yuvtex_mask & (1<<unit))) {
- emit_op(c,
- OPCODE_TEX,
- inst->DstReg,
- inst->SaturateMode,
- unit,
- inst->TexSrcTarget,
- coord,
- src_undef(),
- src_undef());
- }
- else {
- GLboolean swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
+ if (c->key.yuvtex_mask & (1 << unit)) {
+ /* convert ycbcr to RGBA */
+ GLboolean swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
/*
CONST C0 = { -.5, -.0625, -.5, 1.164 }
@@ -734,6 +744,31 @@ static void precalc_tex( struct brw_wm_compile *c,
release_temp(c, tmp);
}
+ else {
+ /* ordinary RGBA tex instruction */
+ emit_op(c,
+ OPCODE_TEX,
+ inst->DstReg,
+ inst->SaturateMode,
+ unit,
+ inst->TexSrcTarget,
+ coord,
+ src_undef(),
+ src_undef());
+ }
+
+ /* For GL_EXT_texture_swizzle: */
+ if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
+ /* swizzle the result of the TEX instruction */
+ struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
+ emit_op(c, OPCODE_SWZ,
+ inst->DstReg,
+ SATURATE_OFF, /* saturate already done above */
+ 0, 0, /* tex unit, target N/A */
+ src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
+ src_undef(),
+ src_undef());
+ }
if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
(inst->TexSrcTarget == TEXTURE_CUBE_INDEX))