Exemple #1
0
/**
 * Make the given fragment program into a "no-op" shader.
 * Actually, just copy the incoming fragment color (or texcoord)
 * to the output color.
 * This is for debug/test purposes.
 */
void
_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog)
{
    struct prog_instruction *inst;
    GLuint inputAttr;

    inst = _mesa_alloc_instructions(2);
    if (!inst) {
        _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program");
        return;
    }

    _mesa_init_instructions(inst, 2);

    inst[0].Opcode = OPCODE_MOV;
    inst[0].DstReg.File = PROGRAM_OUTPUT;
    inst[0].DstReg.Index = FRAG_RESULT_COLOR;
    inst[0].SrcReg[0].File = PROGRAM_INPUT;
    if (prog->Base.InputsRead & VARYING_BIT_COL0)
        inputAttr = VARYING_SLOT_COL0;
    else
        inputAttr = VARYING_SLOT_TEX0;
    inst[0].SrcReg[0].Index = inputAttr;

    inst[1].Opcode = OPCODE_END;

    _mesa_free_instructions(prog->Base.Instructions,
                            prog->Base.NumInstructions);

    prog->Base.Instructions = inst;
    prog->Base.NumInstructions = 2;
    prog->Base.InputsRead = BITFIELD64_BIT(inputAttr);
    prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
}
Exemple #2
0
bool
brw_color_buffer_write_enabled(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;
   /* BRW_NEW_FRAGMENT_PROGRAM */
   const struct gl_fragment_program *fp = brw->fragment_program;
   int i;

   /* _NEW_BUFFERS */
   for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];

      /* _NEW_COLOR */
      if (rb &&
	  (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR) ||
	   fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0 + i)) &&
	  (ctx->Color.ColorMask[i][0] ||
	   ctx->Color.ColorMask[i][1] ||
	   ctx->Color.ColorMask[i][2] ||
	   ctx->Color.ColorMask[i][3])) {
	 return true;
      }
   }

   return false;
}
static void
mark(struct gl_program *prog, ir_variable *var, int offset, int len,
     gl_shader_stage stage)
{
   /* As of GLSL 1.20, varyings can only be floats, floating-point
    * vectors or matrices, or arrays of them.  For Mesa programs using
    * InputsRead/OutputsWritten, everything but matrices uses one
    * slot, while matrices use a slot per column.  Presumably
    * something doing a more clever packing would use something other
    * than InputsRead/OutputsWritten.
    */

   for (int i = 0; i < len; i++) {
      int idx = var->data.location + var->data.index + offset + i;
      bool is_patch_generic = var->data.patch &&
                              idx != VARYING_SLOT_TESS_LEVEL_INNER &&
                              idx != VARYING_SLOT_TESS_LEVEL_OUTER;
      GLbitfield64 bitfield;

      if (is_patch_generic) {
         assert(idx >= VARYING_SLOT_PATCH0 && idx < VARYING_SLOT_TESS_MAX);
         bitfield = BITFIELD64_BIT(idx - VARYING_SLOT_PATCH0);
      }
      else {
         assert(idx < VARYING_SLOT_MAX);
         bitfield = BITFIELD64_BIT(idx);
      }

      if (var->data.mode == ir_var_shader_in) {
         if (is_patch_generic)
            prog->PatchInputsRead |= bitfield;
         else
            prog->InputsRead |= bitfield;

         /* double inputs read is only for vertex inputs */
         if (stage == MESA_SHADER_VERTEX &&
             var->type->without_array()->is_dual_slot_double())
            prog->DoubleInputsRead |= bitfield;

         if (stage == MESA_SHADER_FRAGMENT) {
            gl_fragment_program *fprog = (gl_fragment_program *) prog;
            fprog->InterpQualifier[idx] =
               (glsl_interp_qualifier) var->data.interpolation;
            if (var->data.centroid)
               fprog->IsCentroid |= bitfield;
            if (var->data.sample)
               fprog->IsSample |= bitfield;
         }
      } else if (var->data.mode == ir_var_system_value) {
         prog->SystemValuesRead |= bitfield;
      } else {
         assert(var->data.mode == ir_var_shader_out);
         if (is_patch_generic)
            prog->PatchOutputsWritten |= bitfield;
         else
            prog->OutputsWritten |= bitfield;
      }
   }
}
Exemple #4
0
/**
 * Return a bitfield where bit n is set if barycentric interpolation mode n
 * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
 */
static unsigned
brw_compute_barycentric_interp_modes(struct brw_context *brw,
                                     bool shade_model_flat,
                                     const struct gl_fragment_program *fprog)
{
   unsigned barycentric_interp_modes = 0;
   int attr;

   /* Loop through all fragment shader inputs to figure out what interpolation
    * modes are in use, and set the appropriate bits in
    * barycentric_interp_modes.
    */
   for (attr = 0; attr < VARYING_SLOT_MAX; ++attr) {
      enum glsl_interp_qualifier interp_qualifier =
         fprog->InterpQualifier[attr];
      bool is_centroid = fprog->IsCentroid & BITFIELD64_BIT(attr);
      bool is_gl_Color = attr == VARYING_SLOT_COL0 || attr == VARYING_SLOT_COL1;

      /* Ignore unused inputs. */
      if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
         continue;

      /* Ignore WPOS and FACE, because they don't require interpolation. */
      if (attr == VARYING_SLOT_POS || attr == VARYING_SLOT_FACE)
         continue;

      /* Determine the set (or sets) of barycentric coordinates needed to
       * interpolate this variable.  Note that when
       * brw->needs_unlit_centroid_workaround is set, centroid interpolation
       * uses PIXEL interpolation for unlit pixels and CENTROID interpolation
       * for lit pixels, so we need both sets of barycentric coordinates.
       */
      if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
         if (is_centroid) {
            barycentric_interp_modes |=
               1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
         }
         if (!is_centroid || brw->needs_unlit_centroid_workaround) {
            barycentric_interp_modes |=
               1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
         }
      } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
                 (!(shade_model_flat && is_gl_Color) &&
                  interp_qualifier == INTERP_QUALIFIER_NONE)) {
         if (is_centroid) {
            barycentric_interp_modes |=
               1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
         }
         if (!is_centroid || brw->needs_unlit_centroid_workaround) {
            barycentric_interp_modes |=
               1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
         }
      }
   }

   return barycentric_interp_modes;
}
Exemple #5
0
bool
brw_fs_precompile(struct gl_context *ctx,
                  struct gl_shader_program *shader_prog,
                  struct gl_program *prog)
{
   struct brw_context *brw = brw_context(ctx);
   struct brw_wm_prog_key key;

   struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
   struct brw_fragment_program *bfp = brw_fragment_program(fp);
   bool program_uses_dfdy = fp->UsesDFdy;

   memset(&key, 0, sizeof(key));

   if (brw->gen < 6) {
      if (fp->UsesKill)
         key.iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;

      if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
         key.iz_lookup |= IZ_PS_COMPUTES_DEPTH_BIT;

      /* Just assume depth testing. */
      key.iz_lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
      key.iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
   }

   if (brw->gen < 6 || _mesa_bitcount_64(fp->Base.InputsRead &
                                         BRW_FS_VARYING_INPUT_MASK) > 16)
      key.input_slots_valid = fp->Base.InputsRead | VARYING_BIT_POS;

   brw_setup_tex_for_precompile(brw, &key.tex, &fp->Base);

   if (fp->Base.InputsRead & VARYING_BIT_POS) {
      key.drawable_height = ctx->DrawBuffer->Height;
   }

   key.nr_color_regions = _mesa_bitcount_64(fp->Base.OutputsWritten &
         ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
         BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)));

   if ((fp->Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
      key.render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer) ||
                          key.nr_color_regions > 1;
   }

   key.program_string_id = bfp->id;

   uint32_t old_prog_offset = brw->wm.base.prog_offset;
   struct brw_wm_prog_data *old_prog_data = brw->wm.prog_data;

   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key);

   brw->wm.base.prog_offset = old_prog_offset;
   brw->wm.prog_data = old_prog_data;

   return success;
}
Exemple #6
0
/* Initialize all the register values.  Do the initial setup
 * calculations for interpolants.
 */
static void init_registers( struct brw_wm_compile *c )
{
   struct brw_context *brw = c->func.brw;
   struct intel_context *intel = &brw->intel;
   GLuint nr_interp_regs = 0;
   GLuint i = 0;
   GLuint j;

   for (j = 0; j < c->grf_limit; j++) 
      c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;

   for (j = 0; j < (c->nr_payload_regs + 1) / 2; j++)
      prealloc_reg(c, &c->payload.depth[j], i++);

   for (j = 0; j < c->nr_creg; j++) 
      prealloc_reg(c, &c->creg[j], i++);

   if (intel->gen >= 6) {
      for (unsigned int j = 0; j < FRAG_ATTRIB_MAX; j++) {
	 if (c->fp->program.Base.InputsRead & BITFIELD64_BIT(j)) {
	    nr_interp_regs++;
	    prealloc_reg(c, &c->payload.input_interp[j], i++);
	 }
      }
   } else {
      for (j = 0; j < VERT_RESULT_MAX; j++) {
         /* Point size is packed into the header, not as a general attribute */
         if (j == VERT_RESULT_PSIZ)
            continue;

	 if (c->key.vp_outputs_written & BITFIELD64_BIT(j)) {
	    int fp_index = _mesa_vert_result_to_frag_attrib(j);

	    nr_interp_regs++;

	    /* The back color slot is skipped when the front color is
	     * also written to.  In addition, some slots can be
	     * written in the vertex shader and not read in the
	     * fragment shader.  So the register number must always be
	     * incremented, mapped or not.
	     */
	    if (fp_index >= 0)
	       prealloc_reg(c, &c->payload.input_interp[fp_index], i);
            i++;
	 }
      }
      assert(nr_interp_regs >= 1);
   }


   c->prog_data.first_curbe_grf = ALIGN(c->nr_payload_regs, 2);
   c->prog_data.urb_read_length = nr_interp_regs * 2;
   c->prog_data.curb_read_length = c->nr_creg * 2;

   c->max_wm_grf = i * 2;
}
Exemple #7
0
static void
set_io_mask(nir_shader *shader, nir_variable *var, int offset, int len,
            bool is_output_read)
{
   for (int i = 0; i < len; i++) {
      assert(var->data.location != -1);

      int idx = var->data.location + offset + i;
      bool is_patch_generic = var->data.patch &&
                              idx != VARYING_SLOT_TESS_LEVEL_INNER &&
                              idx != VARYING_SLOT_TESS_LEVEL_OUTER &&
                              idx != VARYING_SLOT_BOUNDING_BOX0 &&
                              idx != VARYING_SLOT_BOUNDING_BOX1;
      uint64_t bitfield;

      if (is_patch_generic) {
         assert(idx >= VARYING_SLOT_PATCH0 && idx < VARYING_SLOT_TESS_MAX);
         bitfield = BITFIELD64_BIT(idx - VARYING_SLOT_PATCH0);
      }
      else {
         assert(idx < VARYING_SLOT_MAX);
         bitfield = BITFIELD64_BIT(idx);
      }

      if (var->data.mode == nir_var_shader_in) {
         if (is_patch_generic)
            shader->info.patch_inputs_read |= bitfield;
         else
            shader->info.inputs_read |= bitfield;

         if (shader->info.stage == MESA_SHADER_FRAGMENT) {
            shader->info.fs.uses_sample_qualifier |= var->data.sample;
         }
      } else {
         assert(var->data.mode == nir_var_shader_out);
         if (is_output_read) {
            if (is_patch_generic) {
               shader->info.patch_outputs_read |= bitfield;
            } else {
               shader->info.outputs_read |= bitfield;
            }
         } else {
	    if (is_patch_generic) {
	       shader->info.patch_outputs_written |= bitfield;
	    } else if (!var->data.read_only) {
	       shader->info.outputs_written |= bitfield;
	    }
	 }


         if (var->data.fb_fetch_output)
            shader->info.outputs_read |= bitfield;
      }
   }
}
Exemple #8
0
/**
 * Run fragment program on the pixels in span from 'start' to 'end' - 1.
 */
static void
run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
   const GLbitfield64 outputsWritten = program->Base.OutputsWritten;
   struct gl_program_machine *machine = &swrast->FragProgMachine;
   GLuint i;

   for (i = start; i < end; i++) {
      if (span->array->mask[i]) {
         init_machine(ctx, machine, program, span, i);

         if (_mesa_execute_program(ctx, &program->Base, machine)) {

            /* Store result color */
	    if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
               COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i],
                       machine->Outputs[FRAG_RESULT_COLOR]);
            }
            else {
               /* Multiple drawbuffers / render targets
                * Note that colors beyond 0 and 1 will overwrite other
                * attributes, such as FOGC, TEX0, TEX1, etc.  That's OK.
                */
               GLuint buf;
               for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
                  if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0 + buf)) {
                     COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i],
                             machine->Outputs[FRAG_RESULT_DATA0 + buf]);
                  }
               }
            }

            /* Store result depth/z */
            if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
               const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPTH][2];
               if (depth <= 0.0)
                  span->array->z[i] = 0;
               else if (depth >= 1.0)
                  span->array->z[i] = ctx->DrawBuffer->_DepthMax;
               else
                  span->array->z[i] =
                     (GLuint) (depth * ctx->DrawBuffer->_DepthMaxF + 0.5F);
            }
         }
         else {
            /* killed fragment */
            span->array->mask[i] = GL_FALSE;
            span->writeAll = GL_FALSE;
         }
      }
   }
}
Exemple #9
0
static bool
calculate_masks(struct brw_sf_compile *c,
	        GLuint reg,
		GLushort *pc,
		GLushort *pc_persp,
		GLushort *pc_linear)
{
   bool is_last_attr = (reg == c->nr_setup_regs - 1);
   GLbitfield64 persp_mask;
   GLbitfield64 linear_mask;

   if (c->key.do_flat_shading)
      persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_HPOS) |
                                    BITFIELD64_BIT(VERT_RESULT_COL0) |
                                    BITFIELD64_BIT(VERT_RESULT_COL1));
   else
      persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_HPOS));

   if (c->key.do_flat_shading)
      linear_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_COL0) |
                                     BITFIELD64_BIT(VERT_RESULT_COL1));
   else
      linear_mask = c->key.attrs;

   *pc_persp = 0;
   *pc_linear = 0;
   *pc = 0xf;
      
   if (persp_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 0)))
      *pc_persp = 0xf;

   if (linear_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 0)))
      *pc_linear = 0xf;

   /* Maybe only processs one attribute on the final round:
    */
   if (vert_reg_to_vert_result(c, reg, 1) != BRW_VERT_RESULT_MAX) {
      *pc |= 0xf0;

      if (persp_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 1)))
	 *pc_persp |= 0xf0;

      if (linear_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 1)))
	 *pc_linear |= 0xf0;
   }

   return is_last_attr;
}
static void
mark(struct gl_program *prog, ir_variable *var, int offset, int len,
     bool is_fragment_shader)
{
   /* As of GLSL 1.20, varyings can only be floats, floating-point
    * vectors or matrices, or arrays of them.  For Mesa programs using
    * InputsRead/OutputsWritten, everything but matrices uses one
    * slot, while matrices use a slot per column.  Presumably
    * something doing a more clever packing would use something other
    * than InputsRead/OutputsWritten.
    */

   for (int i = 0; i < len; i++) {
      GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i);
      if (var->mode == ir_var_in) {
	 prog->InputsRead |= bitfield;
         if (is_fragment_shader) {
            gl_fragment_program *fprog = (gl_fragment_program *) prog;
            fprog->InterpQualifier[var->location + var->index + offset + i] =
               (glsl_interp_qualifier) var->interpolation;
         }
      } else if (var->mode == ir_var_system_value) {
         prog->SystemValuesRead |= bitfield;
      } else {
	 prog->OutputsWritten |= bitfield;
      }
   }
}
Exemple #11
0
static void
init_array(struct gl_context *ctx,
           struct gl_vertex_array_object *obj, GLuint index, GLint size, GLint type)
{
   struct gl_vertex_attrib_array *array = &obj->VertexAttrib[index];
   struct gl_vertex_buffer_binding *binding = &obj->VertexBinding[index];

   array->Size = size;
   array->Type = type;
   array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
   array->Stride = 0;
   array->Ptr = NULL;
   array->RelativeOffset = 0;
   array->Enabled = GL_FALSE;
   array->Normalized = GL_FALSE;
   array->Integer = GL_FALSE;
   array->Doubles = GL_FALSE;
   array->_ElementSize = size * _mesa_sizeof_type(type);
   array->VertexBinding = index;

   binding->Offset = 0;
   binding->Stride = array->_ElementSize;
   binding->BufferObj = NULL;
   binding->_BoundArrays = BITFIELD64_BIT(index);

   /* Vertex array buffers */
   _mesa_reference_buffer_object(ctx, &binding->BufferObj,
                                 ctx->Shared->NullBufferObj);
}
void
_mesa_program_fragment_position_to_sysval(struct gl_program *prog)
{
   GLuint i;

   if (prog->Target != GL_FRAGMENT_PROGRAM_ARB ||
       !(prog->InputsRead & BITFIELD64_BIT(VARYING_SLOT_POS)))
      return;

   prog->InputsRead &= ~BITFIELD64_BIT(VARYING_SLOT_POS);
   prog->SystemValuesRead |= 1 << SYSTEM_VALUE_FRAG_COORD;

   for (i = 0; i < prog->NumInstructions; i++) {
      struct prog_instruction *inst = prog->Instructions + i;
      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
      GLuint j;

      for (j = 0; j < numSrc; j++) {
         if (inst->SrcReg[j].File == PROGRAM_INPUT &&
             inst->SrcReg[j].Index == VARYING_SLOT_POS) {
            inst->SrcReg[j].File = PROGRAM_SYSTEM_VALUE;
            inst->SrcReg[j].Index = SYSTEM_VALUE_FRAG_COORD;
         }
      }
   }
}
static uint32_t
get_attr_override(struct brw_context *brw, int fs_attr)
{
   int attr_index = 0, i, vs_attr;

   if (fs_attr <= FRAG_ATTRIB_TEX7)
      vs_attr = fs_attr;
   else if (fs_attr == FRAG_ATTRIB_FACE)
      vs_attr = 0; /* XXX */
   else if (fs_attr == FRAG_ATTRIB_PNTC)
      vs_attr = 0; /* XXX */
   else {
      assert(fs_attr >= FRAG_ATTRIB_VAR0);
      vs_attr = fs_attr - FRAG_ATTRIB_VAR0 + VERT_RESULT_VAR0;
   }

   /* Find the source index (0 = first attribute after the 4D position)
    * for this output attribute.  attr is currently a VERT_RESULT_* but should
    * be FRAG_ATTRIB_*.
    */
   for (i = 0; i < vs_attr; i++) {
      if (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(i))
	 attr_index++;
   }

   return attr_index;
}
Exemple #14
0
static GLboolean calculate_masks( struct brw_sf_compile *c,
                                  GLuint reg,
                                  GLushort *pc,
                                  GLushort *pc_persp,
                                  GLushort *pc_linear)
{
    GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
    GLbitfield64 persp_mask;
    GLbitfield64 linear_mask;

    if (c->key.do_flat_shading)
        persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
                                      FRAG_BIT_COL0 |
                                      FRAG_BIT_COL1);
    else
        persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS);

    if (c->key.do_flat_shading)
        linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1);
    else
        linear_mask = c->key.attrs;

    *pc_persp = 0;
    *pc_linear = 0;
    *pc = 0xf;

    if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
        *pc_persp = 0xf;

    if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
        *pc_linear = 0xf;

    /* Maybe only processs one attribute on the final round:
     */
    if (reg*2+1 < c->nr_setup_attrs) {
        *pc |= 0xf0;

        if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
            *pc_persp |= 0xf0;

        if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
            *pc_linear |= 0xf0;
    }

    return is_last_attr;
}
Exemple #15
0
static void
brw_merge_inputs(struct brw_context *brw,
                 const struct gl_client_array *arrays[])
{
   const struct gl_context *ctx = &brw->ctx;
   GLuint i;

   for (i = 0; i < brw->vb.nr_buffers; i++) {
      drm_intel_bo_unreference(brw->vb.buffers[i].bo);
      brw->vb.buffers[i].bo = NULL;
   }
   brw->vb.nr_buffers = 0;

   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
      brw->vb.inputs[i].buffer = -1;
      brw->vb.inputs[i].glarray = arrays[i];
   }

   if (brw->gen < 8 && !brw->is_haswell) {
      struct gl_program *vp = &ctx->VertexProgram._Current->Base;
      /* Prior to Haswell, the hardware can't natively support GL_FIXED or
       * 2_10_10_10_REV vertex formats.  Set appropriate workaround flags.
       */
      for (i = 0; i < VERT_ATTRIB_MAX; i++) {
         if (!(vp->InputsRead & BITFIELD64_BIT(i)))
            continue;

         uint8_t wa_flags = 0;

         switch (brw->vb.inputs[i].glarray->Type) {

         case GL_FIXED:
            wa_flags = brw->vb.inputs[i].glarray->Size;
            break;

         case GL_INT_2_10_10_10_REV:
            wa_flags |= BRW_ATTRIB_WA_SIGN;
            /* fallthough */

         case GL_UNSIGNED_INT_2_10_10_10_REV:
            if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
               wa_flags |= BRW_ATTRIB_WA_BGRA;

            if (brw->vb.inputs[i].glarray->Normalized)
               wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
            else if (!brw->vb.inputs[i].glarray->Integer)
               wa_flags |= BRW_ATTRIB_WA_SCALE;

            break;
         }

         if (brw->vb.attrib_wa_flags[i] != wa_flags) {
            brw->vb.attrib_wa_flags[i] = wa_flags;
            brw->ctx.NewDriverState |= BRW_NEW_VS_ATTRIB_WORKAROUNDS;
         }
      }
   }
}
Exemple #16
0
/**
 * Scan program instructions to update the program's InputsRead and
 * OutputsWritten fields.
 */
static void
_slang_update_inputs_outputs(struct gl_program *prog)
{
   GLuint i, j;
   GLuint maxAddrReg = 0;

   prog->InputsRead = 0x0;
   prog->OutputsWritten = 0x0;

   for (i = 0; i < prog->NumInstructions; i++) {
      const struct prog_instruction *inst = prog->Instructions + i;
      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
      for (j = 0; j < numSrc; j++) {
         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
            prog->InputsRead |= 1 << inst->SrcReg[j].Index;
         }
         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
            maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
         }
      }

      if (inst->DstReg.File == PROGRAM_OUTPUT) {
         prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
         if (inst->DstReg.RelAddr) {
            /* If the output attribute is indexed with relative addressing
             * we know that it must be a varying or texcoord such as
             * gl_TexCoord[i] = v;  In this case, mark all the texcoords
             * or varying outputs as being written.  It's not an error if
             * a vertex shader writes varying vars that aren't used by the
             * fragment shader.  But it is an error for a fragment shader
             * to use varyings that are not written by the vertex shader.
             */
            if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
               if (inst->DstReg.Index == VERT_RESULT_TEX0) {
                  /* mark all texcoord outputs as written */
                  const GLbitfield64 mask =
		     BITFIELD64_RANGE(VERT_RESULT_TEX0,
				      (VERT_RESULT_TEX0
				       + MAX_TEXTURE_COORD_UNITS - 1));
                  prog->OutputsWritten |= mask;
               }
               else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
                  /* mark all generic varying outputs as written */
                  const GLbitfield64 mask =
		     BITFIELD64_RANGE(VERT_RESULT_VAR0,
				      (VERT_RESULT_VAR0 + MAX_VARYING - 1));
                  prog->OutputsWritten |= mask;
               }
            }
         }
      }
      else if (inst->DstReg.File == PROGRAM_ADDRESS) {
         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
      }
   }
   prog->NumAddressRegs = maxAddrReg;
}
Exemple #17
0
/**
 * Tell the tnl module how to build SWvertex objects for swrast.
 * We'll build the map[] array with that info and pass it to
 * _tnl_install_attrs().
 */
static void
setup_vertex_format(struct gl_context *ctx)
{
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
    GLboolean intColors = ctx->RenderMode == GL_RENDER
                          && CHAN_TYPE != GL_FLOAT;

    if (intColors != swsetup->intColors ||
            tnl->render_inputs_bitset != swsetup->last_index_bitset) {
        GLbitfield64 index_bitset = tnl->render_inputs_bitset;
        struct tnl_attr_map map[_TNL_ATTRIB_MAX];
        unsigned e = 0;

        swsetup->intColors = intColors;

        EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] );

        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR)) {
            if (swsetup->intColors)
                EMIT_ATTR( _TNL_ATTRIB_COLOR, EMIT_4CHAN_4F_RGBA, color );
            else
                EMIT_ATTR( _TNL_ATTRIB_COLOR, EMIT_4F, attrib[FRAG_ATTRIB_COL]);
        }

        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
            EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F, attrib[FRAG_ATTRIB_FOGC]);
        }

        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX)) {
            EMIT_ATTR( _TNL_ATTRIB_TEX, EMIT_4F,
                       attrib[FRAG_ATTRIB_TEX] );
        }

        if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE))
            EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );

        _tnl_install_attrs( ctx, map, e,
                            ctx->Viewport._WindowMap.m,
                            sizeof(SWvertex) );

        swsetup->last_index_bitset = index_bitset;
    }
}
Exemple #18
0
/**
 * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
 * swrast->_ActiveAtttribMask.
 */
static void
_swrast_update_active_attribs(struct gl_context *ctx)
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLbitfield64 attribsMask;

   /*
    * Compute _ActiveAttribsMask = which fragment attributes are needed.
    */
   if (_swrast_use_fragment_program(ctx)) {
      /* fragment program/shader */
      attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
      attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */
   }
   else if (ctx->ATIFragmentShader._Enabled) {
      attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 |
                    VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY;
   }
   else {
      /* fixed function */
      attribsMask = 0x0;

#if CHAN_TYPE == GL_FLOAT
      attribsMask |= VARYING_BIT_COL0;
#endif

      if (ctx->Fog.ColorSumEnabled ||
          (ctx->Light.Enabled &&
           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
         attribsMask |= VARYING_BIT_COL1;
      }

      if (swrast->_FogEnabled)
         attribsMask |= VARYING_BIT_FOGC;

      attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0);
   }

   swrast->_ActiveAttribMask = attribsMask;

   /* Update _ActiveAttribs[] list */
   {
      GLuint i, num = 0;
      for (i = 0; i < VARYING_SLOT_MAX; i++) {
         if (attribsMask & BITFIELD64_BIT(i)) {
            swrast->_ActiveAttribs[num++] = i;
            /* how should this attribute be interpolated? */
            if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1)
               swrast->_InterpMode[i] = ctx->Light.ShadeModel;
            else
               swrast->_InterpMode[i] = GL_SMOOTH;
         }
      }
      swrast->_NumActiveAttribs = num;
   }
}
Exemple #19
0
/**
 * \sa _mesa_nop_fragment_program
 * Replace the given vertex program with a "no-op" program that just
 * transforms vertex position and emits color.
 */
void
_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog)
{
    struct prog_instruction *inst;
    GLuint inputAttr;

    /*
     * Start with a simple vertex program that emits color.
     */
    inst = _mesa_alloc_instructions(2);
    if (!inst) {
        _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program");
        return;
    }

    _mesa_init_instructions(inst, 2);

    inst[0].Opcode = OPCODE_MOV;
    inst[0].DstReg.File = PROGRAM_OUTPUT;
    inst[0].DstReg.Index = VARYING_SLOT_COL0;
    inst[0].SrcReg[0].File = PROGRAM_INPUT;
    if (prog->Base.InputsRead & VERT_BIT_COLOR0)
        inputAttr = VERT_ATTRIB_COLOR0;
    else
        inputAttr = VERT_ATTRIB_TEX0;
    inst[0].SrcReg[0].Index = inputAttr;

    inst[1].Opcode = OPCODE_END;

    _mesa_free_instructions(prog->Base.Instructions,
                            prog->Base.NumInstructions);

    prog->Base.Instructions = inst;
    prog->Base.NumInstructions = 2;
    prog->Base.InputsRead = BITFIELD64_BIT(inputAttr);
    prog->Base.OutputsWritten = BITFIELD64_BIT(VARYING_SLOT_COL0);

    /*
     * Now insert code to do standard modelview/projection transformation.
     */
    _mesa_insert_mvp_code(ctx, prog);
}
Exemple #20
0
/**
 * Interpolate the active attributes (and'd with attrMask) to
 * fill in span->array->attribs[].
 * Perspective correction will be done.  The point/line/triangle function
 * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]!
 */
static inline void
interpolate_active_attribs(struct gl_context *ctx, SWspan *span,
                           GLbitfield64 attrMask)
{
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);

   /*
    * Don't overwrite existing array values, such as colors that may have
    * been produced by glDraw/CopyPixels.
    */
   attrMask &= ~span->arrayAttribs;

   ATTRIB_LOOP_BEGIN
      if (attrMask & BITFIELD64_BIT(attr)) {
         const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
         GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
         const GLfloat dv0dx = span->attrStepX[attr][0];
         const GLfloat dv1dx = span->attrStepX[attr][1];
         const GLfloat dv2dx = span->attrStepX[attr][2];
         const GLfloat dv3dx = span->attrStepX[attr][3];
         GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx;
         GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx;
         GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx;
         GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx;
         GLuint k;
         for (k = 0; k < span->end; k++) {
            const GLfloat invW = 1.0f / w;
            span->array->attribs[attr][k][0] = v0 * invW;
            span->array->attribs[attr][k][1] = v1 * invW;
            span->array->attribs[attr][k][2] = v2 * invW;
            span->array->attribs[attr][k][3] = v3 * invW;
            v0 += dv0dx;
            v1 += dv1dx;
            v2 += dv2dx;
            v3 += dv3dx;
            w += dwdx;
         }
         ASSERT((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0);
         span->arrayAttribs |= BITFIELD64_BIT(attr);
      }
   ATTRIB_LOOP_END
}
Exemple #21
0
static void
swtnl_emit_attr(struct gl_context *ctx, struct tnl_attr_map *m, int attr, int emit)
{
	TNLcontext *tnl = TNL_CONTEXT(ctx);

	if (tnl->render_inputs_bitset & BITFIELD64_BIT(attr))
		*m = (struct tnl_attr_map) {
			.attrib = attr,
			.format = emit,
		};
	else
Exemple #22
0
/**
 * Execute the current fragment program for all the fragments
 * in the given span.
 */
void
_swrast_exec_fragment_program( struct gl_context *ctx, SWspan *span )
{
   const struct gl_fragment_program *program = ctx->FragmentProgram._Current;

   /* incoming colors should be floats */
   if (program->Base.InputsRead & FRAG_BIT_COL0) {
      ASSERT(span->array->ChanType == GL_FLOAT);
   }

   run_program(ctx, span, 0, span->end);

   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
      span->interpMask &= ~SPAN_RGBA;
      span->arrayMask |= SPAN_RGBA;
   }

   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
      span->interpMask &= ~SPAN_Z;
      span->arrayMask |= SPAN_Z;
   }
}
Exemple #23
0
void
brw_wm_populate_default_key(const struct gen_device_info *devinfo,
                            struct brw_wm_prog_key *key,
                            struct gl_program *prog)
{
   memset(key, 0, sizeof(*key));

   uint64_t outputs_written = prog->info.outputs_written;

   if (devinfo->gen < 6) {
      if (prog->info.fs.uses_discard)
         key->iz_lookup |= BRW_WM_IZ_PS_KILL_ALPHATEST_BIT;

      if (outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
         key->iz_lookup |= BRW_WM_IZ_PS_COMPUTES_DEPTH_BIT;

      /* Just assume depth testing. */
      key->iz_lookup |= BRW_WM_IZ_DEPTH_TEST_ENABLE_BIT;
      key->iz_lookup |= BRW_WM_IZ_DEPTH_WRITE_ENABLE_BIT;
   }

   if (devinfo->gen < 6 || util_bitcount64(prog->info.inputs_read &
                                             BRW_FS_VARYING_INPUT_MASK) > 16) {
      key->input_slots_valid = prog->info.inputs_read | VARYING_BIT_POS;
   }

   brw_setup_tex_for_precompile(devinfo, &key->tex, prog);

   key->nr_color_regions = util_bitcount64(outputs_written &
         ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
           BITFIELD64_BIT(FRAG_RESULT_STENCIL) |
           BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)));

   key->program_string_id = brw_program(prog)->id;

   /* Whether reads from the framebuffer should behave coherently. */
   key->coherent_fb_fetch = devinfo->gen >= 9;
}
Exemple #24
0
/**
 * Return binary representation of 64-bit value (as a string).
 * Insert a comma to separate each group of 8 bits.
 * Note we return a pointer to local static storage so this is not
 * re-entrant, etc.
 * XXX move to imports.[ch] if useful elsewhere.
 */
static const char *
binary(GLbitfield64 val)
{
    static char buf[80];
    GLint i, len = 0;
    for (i = 63; i >= 0; --i) {
        if (val & (BITFIELD64_BIT(i)))
            buf[len++] = '1';
        else if (len > 0 || i == 0)
            buf[len++] = '0';
        if (len > 0 && ((i-1) % 8) == 7)
            buf[len++] = ',';
    }
    buf[len] = '\0';
    return buf;
}
Exemple #25
0
/**
 * Set vertex state for SW TCL.  The primary purpose of this function is to
 * determine in advance whether or not the hardware can / should do the
 * projection divide or Mesa should do it.
 */
void radeonChooseVertexState( struct gl_context *ctx )
{
   r100ContextPtr rmesa = R100_CONTEXT( ctx );
   TNLcontext *tnl = TNL_CONTEXT(ctx);

   GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
   GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
                         ctx->Polygon.BackMode != GL_FILL);
   GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
   
   se_coord_fmt &= ~(RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
		     RADEON_VTX_Z_PRE_MULT_1_OVER_W0 |
		     RADEON_VTX_W0_IS_NOT_1_OVER_W0);

   /* We must ensure that we don't do _tnl_need_projected_coords while in a
    * rasterization fallback.  As this function will be called again when we
    * leave a rasterization fallback, we can just skip it for now.
    */
   if (rmesa->radeon.Fallback != 0)
      return;

   /* HW perspective divide is a win, but tiny vertex formats are a
    * bigger one.
    */

   if ((0 == (tnl->render_inputs_bitset & 
        (BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)
         | BITFIELD64_BIT(_TNL_ATTRIB_COLOR1))))
       || twosided
       || unfilled) {
      rmesa->swtcl.needproj = GL_TRUE;
      se_coord_fmt |= (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
		      RADEON_VTX_Z_PRE_MULT_1_OVER_W0);
   }
   else {
      rmesa->swtcl.needproj = GL_FALSE;
      se_coord_fmt |= (RADEON_VTX_W0_IS_NOT_1_OVER_W0);
   }

   _tnl_need_projected_coords( ctx, rmesa->swtcl.needproj );

   if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) {
      RADEON_STATECHANGE( rmesa, set );
      rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
   }
}
Exemple #26
0
static uint8_t
computed_depth_mode(struct gl_fragment_program *fp)
{
   if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
      switch (fp->FragDepthLayout) {
      case FRAG_DEPTH_LAYOUT_NONE:
      case FRAG_DEPTH_LAYOUT_ANY:
         return BRW_PSCDEPTH_ON;
      case FRAG_DEPTH_LAYOUT_GREATER:
         return BRW_PSCDEPTH_ON_GE;
      case FRAG_DEPTH_LAYOUT_LESS:
         return BRW_PSCDEPTH_ON_LE;
      case FRAG_DEPTH_LAYOUT_UNCHANGED:
         return BRW_PSCDEPTH_OFF;
      }
   }
   return BRW_PSCDEPTH_OFF;
}
Exemple #27
0
/**
 * Helper for _mesa_update_array_object_max_element().
 * \return  min(arrayObj->VertexAttrib[*]._MaxElement).
 */
static GLuint
compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled)
{
   GLuint min = ~((GLuint)0);
   
   while (enabled) {
      struct gl_client_array *client_array;
      GLint attrib = ffsll(enabled) - 1;
      enabled ^= BITFIELD64_BIT(attrib);
      
      client_array = &arrayObj->VertexAttrib[attrib];
      assert(client_array->Enabled);
      _mesa_update_array_max_element(client_array);
      min = MIN2(min, client_array->_MaxElement);
   }
   
   return min;
}
/**
 * Updates the derived gl_client_arrays when a gl_vertex_attrib_array
 * or a gl_vertex_buffer_binding has changed.
 */
void
_mesa_update_vao_client_arrays(struct gl_context *ctx,
                               struct gl_vertex_array_object *vao)
{
   GLbitfield64 arrays = vao->NewArrays;

   while (arrays) {
      struct gl_client_array *client_array;
      struct gl_vertex_attrib_array *attrib_array;
      struct gl_vertex_buffer_binding *buffer_binding;

      GLint attrib = ffsll(arrays) - 1;
      arrays ^= BITFIELD64_BIT(attrib);

      attrib_array = &vao->VertexAttrib[attrib];
      buffer_binding = &vao->VertexBinding[attrib_array->VertexBinding];
      client_array = &vao->_VertexAttrib[attrib];

      _mesa_update_client_array(ctx, client_array, attrib_array,
                                buffer_binding);
   }
}
Exemple #29
0
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;

   /* The inst->Aux field is used for FB write target and the EOT marker */

   if (c->key.nr_color_regions > 1) {
      for (i = 0 ; i < c->key.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 = INST_AUX_TARGET(i);
         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 = INST_AUX_TARGET(i);
         }
      }
      last_inst->Aux |= INST_AUX_EOT;
   }
   else {
      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
      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);

      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
                     0, outcolor, payload_r0_depth, outdepth);
      inst->Aux = INST_AUX_EOT | INST_AUX_TARGET(0);
   }
}
Exemple #30
0
/**
 * Return a bitfield where bit n is set if barycentric interpolation mode n
 * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
 */
static unsigned
brw_compute_barycentric_interp_modes(bool shade_model_flat,
                                     const struct gl_fragment_program *fprog)
{
   unsigned barycentric_interp_modes = 0;
   int attr;

   /* Loop through all fragment shader inputs to figure out what interpolation
    * modes are in use, and set the appropriate bits in
    * barycentric_interp_modes.
    */
   for (attr = 0; attr < FRAG_ATTRIB_MAX; ++attr) {
      enum glsl_interp_qualifier interp_qualifier =
         fprog->InterpQualifier[attr];
      bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;

      /* Ignore unused inputs. */
      if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
         continue;

      /* Ignore WPOS and FACE, because they don't require interpolation. */
      if (attr == FRAG_ATTRIB_WPOS || attr == FRAG_ATTRIB_FACE)
         continue;

      if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
         barycentric_interp_modes |=
            1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
      } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
                 (!(shade_model_flat && is_gl_Color) &&
                  interp_qualifier == INTERP_QUALIFIER_NONE)) {
         barycentric_interp_modes |=
            1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
      }
   }

   return barycentric_interp_modes;
}