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.c457
1 files changed, 304 insertions, 153 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index ff97d87dc4..7e88ef0053 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -30,9 +30,9 @@
*/
-#include "glheader.h"
-#include "macros.h"
-#include "enums.h"
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
#include "brw_context.h"
#include "brw_wm.h"
#include "brw_util.h"
@@ -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
@@ -122,10 +128,11 @@ static struct prog_dst_register dst_reg(GLuint file, GLuint idx)
reg.File = file;
reg.Index = idx;
reg.WriteMask = WRITEMASK_XYZW;
+ reg.RelAddr = 0;
reg.CondMask = 0;
reg.CondSwizzle = 0;
- reg.pad = 0;
reg.CondSrc = 0;
+ reg.pad = 0;
return reg;
}
@@ -144,7 +151,7 @@ static struct prog_dst_register dst_undef( void )
static struct prog_dst_register get_temp( struct brw_wm_compile *c )
{
- int bit = ffs( ~c->fp_temp );
+ int bit = _mesa_ffs( ~c->fp_temp );
if (!bit) {
_mesa_printf("%s: out of temporaries\n", __FILE__);
@@ -158,7 +165,7 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c )
static void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
{
- c->fp_temp &= ~1<<(temp.Index + 1 - FIRST_INTERNAL_TEMP);
+ c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
}
@@ -179,12 +186,13 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
return inst;
}
-static struct prog_instruction * emit_op(struct brw_wm_compile *c,
+static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
GLuint op,
struct prog_dst_register dest,
GLuint saturate,
GLuint tex_src_unit,
GLuint tex_src_target,
+ GLuint tex_shadow,
struct prog_src_register src0,
struct prog_src_register src1,
struct prog_src_register src2 )
@@ -198,14 +206,28 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
inst->SaturateMode = saturate;
inst->TexSrcUnit = tex_src_unit;
inst->TexSrcTarget = tex_src_target;
+ inst->TexShadow = tex_shadow;
inst->SrcReg[0] = src0;
inst->SrcReg[1] = src1;
inst->SrcReg[2] = src2;
-
return inst;
}
+static struct prog_instruction * emit_op(struct brw_wm_compile *c,
+ GLuint op,
+ struct prog_dst_register dest,
+ GLuint saturate,
+ struct prog_src_register src0,
+ struct prog_src_register src1,
+ struct prog_src_register src2 )
+{
+ return emit_tex_op(c, op, dest, saturate,
+ 0, 0, 0, /* tex unit, target, shadow */
+ src0, src1, src2);
+}
+
+
/***********************************************************************
@@ -227,7 +249,7 @@ static struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
emit_op(c,
WM_PIXELXY,
dst_mask(pixel_xy, WRITEMASK_XY),
- 0, 0, 0,
+ 0,
payload_r0_depth,
src_undef(),
src_undef());
@@ -250,7 +272,7 @@ static struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
emit_op(c,
WM_DELTAXY,
dst_mask(delta_xy, WRITEMASK_XY),
- 0, 0, 0,
+ 0,
pixel_xy,
payload_r0_depth,
src_undef());
@@ -267,14 +289,13 @@ static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
struct prog_dst_register pixel_w = get_temp(c);
struct prog_src_register deltas = get_delta_xy(c);
struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
-
-
+
/* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
*/
emit_op(c,
WM_PIXELW,
dst_mask(pixel_w, WRITEMASK_W),
- 0, 0, 0,
+ 0,
interp_wpos,
deltas,
src_undef());
@@ -309,7 +330,7 @@ static void emit_interp( struct brw_wm_compile *c,
emit_op(c,
WM_WPOSXY,
dst_mask(dst, WRITEMASK_XY),
- 0, 0, 0,
+ 0,
get_pixel_xy(c),
src_undef(),
src_undef());
@@ -321,7 +342,7 @@ static void emit_interp( struct brw_wm_compile *c,
emit_op(c,
WM_LINTERP,
dst,
- 0, 0, 0,
+ 0,
interp,
deltas,
arg2);
@@ -332,7 +353,7 @@ static void emit_interp( struct brw_wm_compile *c,
emit_op(c,
WM_CINTERP,
dst,
- 0, 0, 0,
+ 0,
interp,
src_undef(),
src_undef());
@@ -341,7 +362,7 @@ static void emit_interp( struct brw_wm_compile *c,
emit_op(c,
WM_LINTERP,
dst,
- 0, 0, 0,
+ 0,
interp,
deltas,
src_undef());
@@ -351,7 +372,7 @@ static void emit_interp( struct brw_wm_compile *c,
emit_op(c,
WM_PINTERP,
dst,
- 0, 0, 0,
+ 0,
interp,
deltas,
get_pixel_w(c));
@@ -361,6 +382,37 @@ static void emit_interp( struct brw_wm_compile *c,
c->fp_interp_emitted |= 1<<idx;
}
+static void emit_ddx( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDX,
+ inst->DstReg,
+ 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
+
+static void emit_ddy( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ GLuint idx = inst->SrcReg[0].Index;
+ struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+ c->fp_deriv_emitted |= 1<<idx;
+ emit_op(c,
+ OPCODE_DDY,
+ inst->DstReg,
+ 0,
+ interp,
+ get_pixel_w(c),
+ src_undef());
+}
/***********************************************************************
* Hacks to extend the program parameter and constant lists.
@@ -395,10 +447,6 @@ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
idx = _mesa_add_state_reference( paramList, tokens );
- /* Recalculate state dependency:
- */
- c->fp->param_state = paramList->StateFlags;
-
return src_reg(PROGRAM_STATE_VAR, idx);
}
@@ -433,7 +481,7 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
}
idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
- /* XXX what about swizzle? */
+ assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
return src_reg(PROGRAM_STATE_VAR, idx);
}
@@ -455,25 +503,27 @@ static void precalc_dst( struct brw_wm_compile *c,
emit_op(c,
OPCODE_MUL,
dst_mask(dst, WRITEMASK_Y),
- inst->SaturateMode, 0, 0,
+ inst->SaturateMode,
src0,
src1,
src_undef());
}
-
if (dst.WriteMask & WRITEMASK_XZ) {
+ struct prog_instruction *swz;
GLuint z = GET_SWZ(src0.Swizzle, Z);
/* dst.xz = swz src0.1zzz
*/
- emit_op(c,
- OPCODE_SWZ,
- dst_mask(dst, WRITEMASK_XZ),
- inst->SaturateMode, 0, 0,
- src_swizzle(src0, SWIZZLE_ONE, z, z, z),
- src_undef(),
- src_undef());
+ swz = emit_op(c,
+ OPCODE_SWZ,
+ dst_mask(dst, WRITEMASK_XZ),
+ inst->SaturateMode,
+ src_swizzle(src0, SWIZZLE_ONE, z, z, z),
+ src_undef(),
+ src_undef());
+ /* Avoid letting negation flag of src0 affect our 1 constant. */
+ swz->SrcReg[0].NegateBase &= ~NEGATE_X;
}
if (dst.WriteMask & WRITEMASK_W) {
/* dst.w = mov src1.w
@@ -481,7 +531,7 @@ static void precalc_dst( struct brw_wm_compile *c,
emit_op(c,
OPCODE_MOV,
dst_mask(dst, WRITEMASK_W),
- inst->SaturateMode, 0, 0,
+ inst->SaturateMode,
src1,
src_undef(),
src_undef());
@@ -496,41 +546,109 @@ static void precalc_lit( struct brw_wm_compile *c,
struct prog_dst_register dst = inst->DstReg;
if (dst.WriteMask & WRITEMASK_XW) {
+ struct prog_instruction *swz;
+
/* dst.xw = swz src0.1111
*/
- emit_op(c,
- OPCODE_SWZ,
- dst_mask(dst, WRITEMASK_XW),
- 0, 0, 0,
- src_swizzle1(src0, SWIZZLE_ONE),
- src_undef(),
- src_undef());
+ swz = emit_op(c,
+ OPCODE_SWZ,
+ dst_mask(dst, WRITEMASK_XW),
+ 0,
+ src_swizzle1(src0, SWIZZLE_ONE),
+ src_undef(),
+ src_undef());
+ /* Avoid letting the negation flag of src0 affect our 1 constant. */
+ swz->SrcReg[0].NegateBase = 0;
}
-
if (dst.WriteMask & WRITEMASK_YZ) {
emit_op(c,
OPCODE_LIT,
dst_mask(dst, WRITEMASK_YZ),
- inst->SaturateMode, 0, 0,
+ inst->SaturateMode,
src0,
src_undef(),
src_undef());
}
}
+
+/**
+ * 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;
-
- if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
+ const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+
+ if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
+ struct prog_instruction *out;
+ struct prog_dst_register tmp0 = get_temp(c);
+ struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
+ struct prog_dst_register tmp1 = get_temp(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,
+ src0,
+ src_undef(),
+ src_undef());
+ out->SrcReg[0].NegateBase = 0;
+ out->SrcReg[0].Abs = 1;
+
+ /* tmp0 = MAX(coord.X, coord.Y) */
+ emit_op(c, OPCODE_MAX,
+ tmp0,
+ 0,
+ src_swizzle1(coord, X),
+ src_swizzle1(coord, Y),
+ src_undef());
+
+ /* tmp1 = MAX(tmp0, coord.Z) */
+ emit_op(c, OPCODE_MAX,
+ tmp1,
+ 0,
+ tmp0src,
+ src_swizzle1(coord, Z),
+ src_undef());
+
+ /* tmp0 = 1 / tmp1 */
+ emit_op(c, OPCODE_RCP,
+ tmp0,
+ 0,
+ tmp1src,
+ src_undef(),
+ src_undef());
+
+ /* tmpCoord = src0 * tmp0 */
+ emit_op(c, OPCODE_MUL,
+ tmpcoord,
+ 0,
+ src0,
+ tmp0src,
+ src_undef());
+
+ release_temp(c, tmp0);
+ release_temp(c, tmp1);
+ }
+ else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
struct prog_src_register scale =
search_or_add_param5( c,
STATE_INTERNAL,
STATE_TEXRECT_SCALE,
- inst->TexSrcUnit,
+ unit,
0,0 );
tmpcoord = get_temp(c);
@@ -540,7 +658,7 @@ static void precalc_tex( struct brw_wm_compile *c,
emit_op(c,
OPCODE_MUL,
tmpcoord,
- 0, 0, 0,
+ 0,
inst->SrcReg[0],
scale,
src_undef());
@@ -556,29 +674,23 @@ 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<<inst->TexSrcUnit))) {
- emit_op(c,
- OPCODE_TEX,
- inst->DstReg,
- inst->SaturateMode,
- inst->TexSrcUnit,
- inst->TexSrcTarget,
- coord,
- src_undef(),
- src_undef());
- }
- else {
+ 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 }
CONST C1 = { 1.596, -0.813, 2.018, -.391 }
UYV = TEX ...
UYV.xyz = ADD UYV, C0
UYV.y = MUL UYV.y, C0.w
- RGB.xyz = MAD UYV.xxz, C1, UYV.y
+ if (UV swaped)
+ RGB.xyz = MAD UYV.zzx, C1, UYV.y
+ else
+ RGB.xyz = MAD UYV.xxz, C1, UYV.y
RGB.y = MAD UYV.z, C1.w, RGB.y
*/
struct prog_dst_register dst = inst->DstReg;
- struct prog_src_register src0 = inst->SrcReg[0];
struct prog_dst_register tmp = get_temp(c);
struct prog_src_register tmpsrc = src_reg_from_dst(tmp);
struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 );
@@ -586,43 +698,50 @@ static void precalc_tex( struct brw_wm_compile *c,
/* tmp = TEX ...
*/
- emit_op(c,
- OPCODE_TEX,
- tmp,
- inst->SaturateMode,
- inst->TexSrcUnit,
- inst->TexSrcTarget,
- src0,
- src_undef(),
- src_undef());
+ emit_tex_op(c,
+ OPCODE_TEX,
+ tmp,
+ inst->SaturateMode,
+ unit,
+ inst->TexSrcTarget,
+ inst->TexShadow,
+ coord,
+ src_undef(),
+ src_undef());
/* tmp.xyz = ADD TMP, C0
*/
emit_op(c,
OPCODE_ADD,
dst_mask(tmp, WRITEMASK_XYZ),
- 0, 0, 0,
+ 0,
tmpsrc,
C0,
src_undef());
/* YUV.y = MUL YUV.y, C0.w
*/
+
emit_op(c,
OPCODE_MUL,
dst_mask(tmp, WRITEMASK_Y),
- 0, 0, 0,
+ 0,
tmpsrc,
src_swizzle1(C0, W),
src_undef());
- /* RGB.xyz = MAD YUV.xxz, C1, YUV.y
+ /*
+ * if (UV swaped)
+ * RGB.xyz = MAD YUV.zzx, C1, YUV.y
+ * else
+ * RGB.xyz = MAD YUV.xxz, C1, YUV.y
*/
+
emit_op(c,
OPCODE_MAD,
dst_mask(dst, WRITEMASK_XYZ),
- 0, 0, 0,
- src_swizzle(tmpsrc, X,X,Z,Z),
+ 0,
+ swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
C1,
src_swizzle1(tmpsrc, Y));
@@ -631,15 +750,41 @@ static void precalc_tex( struct brw_wm_compile *c,
emit_op(c,
OPCODE_MAD,
dst_mask(dst, WRITEMASK_Y),
- 0, 0, 0,
+ 0,
src_swizzle1(tmpsrc, Z),
src_swizzle1(C1, W),
src_swizzle1(src_reg_from_dst(dst), Y));
release_temp(c, tmp);
}
+ else {
+ /* ordinary RGBA tex instruction */
+ emit_tex_op(c,
+ OPCODE_TEX,
+ inst->DstReg,
+ inst->SaturateMode,
+ unit,
+ inst->TexSrcTarget,
+ inst->TexShadow,
+ coord,
+ src_undef(),
+ src_undef());
+ }
- if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV)
+ /* 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 */
+ src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
+ src_undef(),
+ src_undef());
+ }
+
+ if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
+ (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
release_temp(c, tmpcoord);
}
@@ -660,7 +805,7 @@ static GLboolean projtex( struct brw_wm_compile *c,
return 0; /* ut2004 gun rendering !?! */
else if (src.File == PROGRAM_INPUT &&
GET_SWZ(src.Swizzle, W) == W &&
- (c->key.projtex_mask & (1<<src.Index)) == 0)
+ (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0)
return 0;
else
return 1;
@@ -681,7 +826,7 @@ static void precalc_txp( struct brw_wm_compile *c,
emit_op(c,
OPCODE_RCP,
dst_mask(tmp, WRITEMASK_W),
- 0, 0, 0,
+ 0,
src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
src_undef(),
src_undef());
@@ -691,7 +836,7 @@ static void precalc_txp( struct brw_wm_compile *c,
emit_op(c,
OPCODE_MUL,
dst_mask(tmp, WRITEMASK_XYZ),
- 0, 0, 0,
+ 0,
src0,
src_swizzle1(src_reg_from_dst(tmp), W),
src_undef());
@@ -714,70 +859,45 @@ static void precalc_txp( struct brw_wm_compile *c,
-
-
-/***********************************************************************
- * Add instructions to perform fog blending
- */
-
-static void fog_blend( struct brw_wm_compile *c,
- struct prog_src_register fog_factor )
-{
- struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
- struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
-
- /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
-
- emit_op(c,
- OPCODE_LRP,
- dst_mask(outcolor, WRITEMASK_XYZ),
- 0, 0, 0,
- fog_factor,
- src_reg_from_dst(outcolor),
- fogcolor);
-}
-
-
-
-/* This one is simple - just take the interpolated fog coordinate and
- * use it as the fog blend factor.
- */
-static void fog_interpolated( struct brw_wm_compile *c )
-{
- struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC);
-
- if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC)))
- emit_interp(c, FRAG_ATTRIB_FOGC);
-
- fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X)));
-}
-
-static void emit_fog( struct brw_wm_compile *c )
-{
- if (!c->fp->program.FogOption)
- return;
-
- if (1)
- fog_interpolated( c );
- else {
- /* TODO: per-pixel fog */
- assert(0);
- }
-}
-
static void emit_fb_write( struct brw_wm_compile *c )
{
- struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
- struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);
+ struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
+ struct prog_src_register outcolor;
+ GLuint i;
+
+ struct prog_instruction *inst, *last_inst;
+ struct brw_context *brw = c->func.brw;
+
+ /* The inst->Aux field is used for FB write target and the EOT marker */
+
+ if (brw->state.nr_color_regions > 1) {
+ for (i = 0 ; i < brw->state.nr_color_regions; i++) {
+ outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
+ last_inst = inst = emit_op(c,
+ WM_FB_WRITE, dst_mask(dst_undef(),0), 0,
+ outcolor, payload_r0_depth, outdepth);
+ inst->Aux = (i<<1);
+ if (c->fp_fragcolor_emitted) {
+ outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
+ last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
+ 0, outcolor, payload_r0_depth, outdepth);
+ inst->Aux = (i<<1);
+ }
+ }
+ last_inst->Aux |= 1; //eot
+ }
+ else {
+ /* if gl_FragData[0] is written, use it, else use gl_FragColor */
+ if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
+ outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
+ else
+ outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
- emit_op(c,
- WM_FB_WRITE,
- dst_mask(dst_undef(),0),
- 0, 0, 0,
- outcolor,
- payload_r0_depth,
- outdepth);
+ inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
+ 0, outcolor, payload_r0_depth, outdepth);
+ inst->Aux = 1|(0<<1);
+ }
}
@@ -803,7 +923,15 @@ static void validate_src_regs( struct brw_wm_compile *c,
}
}
-
+static void validate_dst_regs( struct brw_wm_compile *c,
+ const struct prog_instruction *inst )
+{
+ if (inst->DstReg.File == PROGRAM_OUTPUT) {
+ GLuint idx = inst->DstReg.Index;
+ if (idx == FRAG_RESULT_COLOR)
+ c->fp_fragcolor_emitted = 1;
+ }
+}
static void print_insns( const struct prog_instruction *insn,
GLuint nr )
@@ -822,17 +950,21 @@ static void print_insns( const struct prog_instruction *insn,
}
else
_mesa_printf("UNKNOWN\n");
-
}
}
+
+/**
+ * Initial pass for fragment program code generation.
+ * This function is used by both the GLSL and non-GLSL paths.
+ */
void brw_wm_pass_fp( struct brw_wm_compile *c )
{
struct brw_fragment_program *fp = c->fp;
GLuint insn;
if (INTEL_DEBUG & DEBUG_WM) {
- _mesa_printf("\n\n\npre-fp:\n");
+ _mesa_printf("pre-fp:\n");
_mesa_print_program(&fp->program.Base);
_mesa_printf("\n");
}
@@ -842,10 +974,19 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
c->pixel_w = src_undef();
c->nr_fp_insns = 0;
- /* Emit preamble instructions:
+ /* Emit preamble instructions. This is where special instructions such as
+ * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
+ * compute shader inputs from varying vars.
*/
+ for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
+ const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
+ validate_src_regs(c, inst);
+ validate_dst_regs(c, inst);
+ }
-
+ /* Loop over all instructions doing assorted simplifications and
+ * transformations.
+ */
for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
struct prog_instruction *out;
@@ -853,8 +994,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
/* Check for INPUT values, emit INTERP instructions where
* necessary:
*/
- validate_src_regs(c, inst);
-
switch (inst->Opcode) {
case OPCODE_SWZ:
@@ -889,11 +1028,20 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
case OPCODE_LIT:
precalc_lit(c, inst);
break;
-
+
+ case OPCODE_TEX:
+ precalc_tex(c, inst);
+ break;
+
case OPCODE_TXP:
precalc_txp(c, inst);
break;
+ case OPCODE_TXB:
+ out = emit_insn(c, inst);
+ out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ break;
+
case OPCODE_XPD:
out = emit_insn(c, inst);
/* This should probably be done in the parser.
@@ -907,8 +1055,15 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
*/
out->DstReg.WriteMask = 0;
break;
-
+ case OPCODE_DDX:
+ emit_ddx(c, inst);
+ break;
+ case OPCODE_DDY:
+ emit_ddy(c, inst);
+ break;
case OPCODE_END:
+ emit_fb_write(c);
+ break;
case OPCODE_PRINT:
break;
@@ -917,13 +1072,9 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
break;
}
}
-
- emit_fog(c);
- emit_fb_write(c);
-
if (INTEL_DEBUG & DEBUG_WM) {
- _mesa_printf("\n\n\npass_fp:\n");
+ _mesa_printf("pass_fp:\n");
print_insns( c->prog_instructions, c->nr_fp_insns );
_mesa_printf("\n");
}