Merge branch 'lp-offset-twoside'
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_fp.c
index 53fdd06f428667f7fa7b982245c085d797cc1349..2cae6988804efaf29b078afed4953d342d0ca69e 100644 (file)
@@ -37,9 +37,9 @@
 #include "brw_wm.h"
 #include "brw_util.h"
 
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
 
 
 /** An invalid texture target */
@@ -88,6 +88,9 @@ static struct prog_src_register src_reg(GLuint file, GLuint idx)
    reg.RelAddr = 0;
    reg.Negate = NEGATE_NONE;
    reg.Abs = 0;
+   reg.HasIndex2 = 0;
+   reg.RelAddr2 = 0;
+   reg.Index2 = 0;
    return reg;
 }
 
@@ -138,7 +141,6 @@ static struct prog_dst_register dst_reg(GLuint file, GLuint idx)
    reg.CondMask = COND_TR;
    reg.CondSwizzle = 0;
    reg.CondSrc = 0;
-   reg.pad = 0;
    return reg;
 }
 
@@ -160,7 +162,7 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c )
    int bit = _mesa_ffs( ~c->fp_temp );
 
    if (!bit) {
-      _mesa_printf("%s: out of temporaries\n", __FILE__);
+      printf("%s: out of temporaries\n", __FILE__);
       exit(1);
    }
 
@@ -181,6 +183,9 @@ static void release_temp( struct brw_wm_compile *c, struct prog_dst_register tem
 
 static struct prog_instruction *get_fp_inst(struct brw_wm_compile *c)
 {
+   assert(c->nr_fp_insns < BRW_WM_MAX_INSN);
+   memset(&c->prog_instructions[c->nr_fp_insns], 0,
+         sizeof(*c->prog_instructions));
    return &c->prog_instructions[c->nr_fp_insns++];
 }
 
@@ -333,6 +338,12 @@ static struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
 
 static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
 {
+   /* This is only called for producing 1/w in pre-gen6 interp.  for
+    * gen6, the interp opcodes don't use this argument.
+    */
+   if (c->func.brw->intel.gen >= 6)
+      return src_undef();
+
    if (src_is_undef(c->pixel_w)) {
       struct prog_dst_register pixel_w = get_temp(c);
       struct prog_src_register deltas = get_delta_xy(c);
@@ -360,7 +371,13 @@ static void emit_interp( struct brw_wm_compile *c,
 {
    struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
-   struct prog_src_register deltas = get_delta_xy(c);
+   struct prog_src_register deltas;
+
+   if (c->func.brw->intel.gen < 6) {
+      deltas = get_delta_xy(c);
+   } else {
+      deltas = src_undef();
+   }
 
    /* Need to use PINTERP on attributes which have been
     * multiplied by 1/W in the SF program, and LINTERP on those
@@ -447,7 +464,6 @@ static void emit_interp( struct brw_wm_compile *c,
       break;
 
    case FRAG_ATTRIB_FACE:
-      /* XXX review/test this case */
       emit_op(c,
               WM_FRONTFACING,
               dst_mask(dst, WRITEMASK_X),
@@ -518,12 +534,6 @@ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
    tokens[2] = s2;
    tokens[3] = s3;
    tokens[4] = s4;
-   
-   for (idx = 0; idx < paramList->NumParameters; idx++) {
-      if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
-         memcmp(paramList->Parameters[idx].StateIndexes, tokens, sizeof(tokens)) == 0)
-        return src_reg(PROGRAM_STATE_VAR, idx);
-   }
 
    idx = _mesa_add_state_reference( paramList, tokens );
 
@@ -541,28 +551,18 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
    GLfloat values[4];
    GLuint idx;
    GLuint swizzle;
+   struct prog_src_register reg;
 
    values[0] = s0;
    values[1] = s1;
    values[2] = s2;
    values[3] = s3;
 
-   /* Have to search, otherwise multiple compilations will each grow
-    * the parameter list.
-    */
-   for (idx = 0; idx < paramList->NumParameters; idx++) {
-      if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT &&
-         memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0)
-
-        /* XXX: this mimics the mesa bug which puts all constants and
-         * parameters into the "PROGRAM_STATE_VAR" category:
-         */
-        return src_reg(PROGRAM_STATE_VAR, idx);
-   }
-   
    idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
-   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */
-   return src_reg(PROGRAM_STATE_VAR, idx);
+   reg = src_reg(PROGRAM_STATE_VAR, idx);
+   reg.Swizzle = swizzle;
+
+   return reg;
 }
 
 
@@ -663,7 +663,7 @@ static void precalc_tex( struct brw_wm_compile *c,
                         const struct prog_instruction *inst )
 {
    struct prog_src_register coord;
-   struct prog_dst_register tmpcoord;
+   struct prog_dst_register tmpcoord = { 0 };
    const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
 
    assert(unit < BRW_MAX_TEX_UNIT);
@@ -956,14 +956,14 @@ static void precalc_txp( struct brw_wm_compile *c,
 
 
 
-static void emit_fb_write( struct brw_wm_compile *c )
+static void emit_render_target_writes( struct brw_wm_compile *c )
 {
    struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
    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 prog_instruction *inst, *last_inst = NULL;
 
    /* The inst->Aux field is used for FB write target and the EOT marker */
 
@@ -984,7 +984,7 @@ static void emit_fb_write( struct brw_wm_compile *c )
    }
    else {
       /* if gl_FragData[0] is written, use it, else use gl_FragColor */
-      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
+      if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0))
          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
       else 
          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
@@ -1033,18 +1033,17 @@ static void print_insns( const struct prog_instruction *insn,
 {
    GLuint i;
    for (i = 0; i < nr; i++, insn++) {
-      _mesa_printf("%3d: ", i);
+      printf("%3d: ", i);
       if (insn->Opcode < MAX_OPCODE)
-        _mesa_print_instruction(insn);
+        _mesa_fprint_instruction_opt(stdout, insn, 0, PROG_PRINT_DEBUG, NULL);
       else if (insn->Opcode < MAX_WM_OPCODE) {
         GLuint idx = insn->Opcode - MAX_OPCODE;
 
-        _mesa_print_alu_instruction(insn,
-                                    wm_opcode_strings[idx],
-                                    3);
+        _mesa_fprint_alu_instruction(stdout, insn, wm_opcode_strings[idx],
+                                     3, PROG_PRINT_DEBUG, NULL);
       }
       else 
-        _mesa_printf("965 Opcode %d\n", insn->Opcode);
+        printf("965 Opcode %d\n", insn->Opcode);
    }
 }
 
@@ -1055,17 +1054,26 @@ static void print_insns( const struct prog_instruction *insn,
  */
 void brw_wm_pass_fp( struct brw_wm_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
    struct brw_fragment_program *fp = c->fp;
    GLuint insn;
 
-   if (INTEL_DEBUG & DEBUG_WM) {
-      _mesa_printf("pre-fp:\n");
-      _mesa_print_program(&fp->program.Base); 
-      _mesa_printf("\n");
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+      printf("pre-fp:\n");
+      _mesa_fprint_program_opt(stdout, &fp->program.Base, PROG_PRINT_DEBUG,
+                              GL_TRUE);
+      printf("\n");
    }
 
    c->pixel_xy = src_undef();
-   c->delta_xy = src_undef();
+   if (intel->gen >= 6) {
+      /* The interpolation deltas come in as the perspective pixel
+       * location barycentric params.
+       */
+      c->delta_xy = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
+   } else {
+      c->delta_xy = src_undef();
+   }
    c->pixel_w = src_undef();
    c->nr_fp_insns = 0;
    c->fp->tex_units_used = 0x0;
@@ -1153,7 +1161,7 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
         out->DstReg.WriteMask = 0;
         break;
       case OPCODE_END:
-        emit_fb_write(c);
+        emit_render_target_writes(c);
         break;
       case OPCODE_PRINT:
         break;
@@ -1166,10 +1174,10 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
       }
    }
 
-   if (INTEL_DEBUG & DEBUG_WM) {
-      _mesa_printf("pass_fp:\n");
+   if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+      printf("pass_fp:\n");
       print_insns( c->prog_instructions, c->nr_fp_insns );
-      _mesa_printf("\n");
+      printf("\n");
    }
 }