i965/vs: Add texture related data to brw_vs_prog_key.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs.cpp
index 20001807b1eda71facfc030898bb8328005ef4c6..8ca4a8735d045e1d039df7fdaf5e5b107ef7ccfe 100644 (file)
@@ -155,12 +155,12 @@ fs_visitor::implied_mrf_writes(fs_inst *inst)
    case SHADER_OPCODE_INT_QUOTIENT:
    case SHADER_OPCODE_INT_REMAINDER:
       return 2 * c->dispatch_width / 8;
-   case FS_OPCODE_TEX:
+   case SHADER_OPCODE_TEX:
    case FS_OPCODE_TXB:
-   case FS_OPCODE_TXD:
-   case FS_OPCODE_TXF:
-   case FS_OPCODE_TXL:
-   case FS_OPCODE_TXS:
+   case SHADER_OPCODE_TXD:
+   case SHADER_OPCODE_TXF:
+   case SHADER_OPCODE_TXL:
+   case SHADER_OPCODE_TXS:
       return 1;
    case FS_OPCODE_FB_WRITE:
       return 2;
@@ -407,8 +407,10 @@ fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
       emit(BRW_OPCODE_MOV, wpos,
           fs_reg(brw_vec8_grf(c->source_depth_reg, 0)));
    } else {
-      emit(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
-          interp_reg(FRAG_ATTRIB_WPOS, 2));
+      emit(FS_OPCODE_LINTERP, wpos,
+           this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
+           this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
+           interp_reg(FRAG_ATTRIB_WPOS, 2));
    }
    wpos.reg_offset++;
 
@@ -422,8 +424,7 @@ fs_reg *
 fs_visitor::emit_general_interpolation(ir_variable *ir)
 {
    fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
-   /* Interpolation is always in floating point regs. */
-   reg->type = BRW_REGISTER_TYPE_F;
+   reg->type = brw_type_for_base_type(ir->type->get_scalar_type());
    fs_reg attr = *reg;
 
    unsigned int array_elements;
@@ -440,6 +441,9 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
       type = ir->type;
    }
 
+   glsl_interp_qualifier interpolation_mode =
+      ir->determine_interpolation_mode(c->key.flat_shade);
+
    int location = ir->location;
    for (unsigned int i = 0; i < array_elements; i++) {
       for (unsigned int j = 0; j < type->matrix_columns; j++) {
@@ -452,10 +456,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
            continue;
         }
 
-        bool is_gl_Color =
-           location == FRAG_ATTRIB_COL0 || location == FRAG_ATTRIB_COL1;
-
-        if (c->key.flat_shade && is_gl_Color) {
+        if (interpolation_mode == INTERP_QUALIFIER_FLAT) {
            /* Constant interpolation (flat shading) case. The SF has
             * handed us defined values in only the constant offset
             * field of the setup reg.
@@ -463,11 +464,12 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
            for (unsigned int k = 0; k < type->vector_elements; k++) {
               struct brw_reg interp = interp_reg(location, k);
               interp = suboffset(interp, 3);
+               interp.type = reg->type;
               emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
               attr.reg_offset++;
            }
         } else {
-           /* Perspective interpolation case. */
+           /* Smooth/noperspective interpolation case. */
            for (unsigned int k = 0; k < type->vector_elements; k++) {
               /* FINISHME: At some point we probably want to push
                * this farther by giving similar treatment to the
@@ -481,8 +483,14 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
                  emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f));
               } else {
                  struct brw_reg interp = interp_reg(location, k);
-                 emit(FS_OPCODE_LINTERP, attr,
-                      this->delta_x, this->delta_y, fs_reg(interp));
+                  brw_wm_barycentric_interp_mode barycoord_mode;
+                  if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
+                     barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+                  else
+                     barycoord_mode = BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+                  emit(FS_OPCODE_LINTERP, attr,
+                       this->delta_x[barycoord_mode],
+                       this->delta_y[barycoord_mode], fs_reg(interp));
               }
               attr.reg_offset++;
            }
@@ -551,10 +559,10 @@ fs_visitor::emit_math(enum opcode opcode, fs_reg dst, fs_reg src)
     * expanding that result out, but we would need to be careful with
     * masking.
     *
-    * The hardware ignores source modifiers (negate and abs) on math
+    * Gen 6 hardware ignores source modifiers (negate and abs) on math
     * instructions, so we also move to a temp to set those up.
     */
-   if (intel->gen >= 6 && (src.file == UNIFORM ||
+   if (intel->gen == 6 && (src.file == UNIFORM ||
                           src.abs ||
                           src.negate)) {
       fs_reg expanded = fs_reg(this, glsl_type::float_type);
@@ -588,7 +596,9 @@ fs_visitor::emit_math(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1)
       return NULL;
    }
 
-   if (intel->gen >= 6) {
+   if (intel->gen >= 7) {
+      inst = emit(opcode, dst, src0, src1);
+   } else if (intel->gen == 6) {
       /* Can't do hstride == 0 args to gen6 math, so expand it out.
        *
        * The hardware ignores source modifiers (negate and abs) on math
@@ -768,9 +778,15 @@ fs_visitor::split_virtual_grfs()
         split_grf[i] = false;
    }
 
-   if (brw->has_pln) {
-      /* PLN opcodes rely on the delta_xy being contiguous. */
-      split_grf[this->delta_x.reg] = false;
+   if (brw->has_pln &&
+       this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].file == GRF) {
+      /* PLN opcodes rely on the delta_xy being contiguous.  We only have to
+       * check this for BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC, because prior to
+       * Gen6, that was the only supported interpolation mode, and since Gen6,
+       * delta_x and delta_y are in fixed hardware registers.
+       */
+      split_grf[this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg] =
+         false;
    }
 
    foreach_list(node, &this->instructions) {
@@ -1113,7 +1129,14 @@ fs_visitor::propagate_constants()
                  scan_inst->src[i] = inst->src[0];
                  progress = true;
               } else if (i == 0 && scan_inst->src[1].file != IMM) {
-                 /* Fit this constant in by commuting the operands */
+                 /* Fit this constant in by commuting the operands.
+                  * Exception: we can't do this for 32-bit integer MUL
+                  * because it's asymmetric.
+                  */
+                 if (scan_inst->opcode == BRW_OPCODE_MUL &&
+                     (scan_inst->src[1].type == BRW_REGISTER_TYPE_D ||
+                      scan_inst->src[1].type == BRW_REGISTER_TYPE_UD))
+                    break;
                  scan_inst->src[0] = scan_inst->src[1];
                  scan_inst->src[1] = inst->src[0];
                  progress = true;
@@ -1347,6 +1370,19 @@ fs_visitor::register_coalesce()
            interfered = true;
            break;
         }
+
+        /* The accumulator result appears to get used for the
+         * conditional modifier generation.  When negating a UD
+         * value, there is a 33rd bit generated for the sign in the
+         * accumulator value, so now you can't check, for example,
+         * equality with a 32-bit value.  See piglit fs-op-neg-uint.
+         */
+        if (scan_inst->conditional_mod &&
+            inst->src[0].negate &&
+            inst->src[0].type == BRW_REGISTER_TYPE_UD) {
+           interfered = true;
+           break;
+        }
       }
       if (interfered) {
         continue;
@@ -1363,8 +1399,11 @@ fs_visitor::register_coalesce()
                scan_inst->src[i].reg == inst->dst.reg &&
                scan_inst->src[i].reg_offset == inst->dst.reg_offset) {
               fs_reg new_src = inst->src[0];
+               if (scan_inst->src[i].abs) {
+                  new_src.negate = 0;
+                  new_src.abs = 1;
+               }
               new_src.negate ^= scan_inst->src[i].negate;
-              new_src.abs |= scan_inst->src[i].abs;
               scan_inst->src[i] = new_src;
            }
         }
@@ -1773,6 +1812,7 @@ fs_visitor::run()
 
       /* Make sure we didn't try to sneak in an extra uniform */
       assert(orig_nr_params == c->prog_data.nr_params);
+      (void) orig_nr_params;
    }
 
    return !failed;
@@ -1804,7 +1844,7 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c,
 
    fs_visitor v(c, prog, shader);
    if (!v.run()) {
-      prog->LinkStatus = GL_FALSE;
+      prog->LinkStatus = false;
       ralloc_strcat(&prog->InfoLog, v.fail_msg);
 
       return false;
@@ -1827,12 +1867,14 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
 {
    struct brw_context *brw = brw_context(ctx);
    struct brw_wm_prog_key key;
-   struct gl_fragment_program *fp = prog->FragmentProgram;
-   struct brw_fragment_program *bfp = brw_fragment_program(fp);
 
-   if (!fp)
+   if (!prog->_LinkedShaders[MESA_SHADER_FRAGMENT])
       return true;
 
+   struct gl_fragment_program *fp = (struct gl_fragment_program *)
+      prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
+   struct brw_fragment_program *bfp = brw_fragment_program(fp);
+
    memset(&key, 0, sizeof(key));
 
    if (fp->UsesKill)
@@ -1862,10 +1904,10 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
 
    for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       if (fp->Base.ShadowSamplers & (1 << i))
-        key.compare_funcs[i] = GL_LESS;
+        key.tex.compare_funcs[i] = GL_LESS;
 
       /* FINISHME: depth compares might use (0,0,0,W) for example */
-      key.tex_swizzles[i] = SWIZZLE_XYZW;
+      key.tex.swizzles[i] = SWIZZLE_XYZW;
    }
 
    if (fp->Base.InputsRead & FRAG_BIT_WPOS) {