示例#1
0
/**
 * Compute the setup->coef[] array dadx, dady, a0 values.
 * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
 */
static void setup_tri_coefficients( struct setup_context *setup )
{
   struct softpipe_context *softpipe = setup->softpipe;
   const struct sp_fragment_shader *spfs = softpipe->fs;
   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
   uint fragSlot;

   /* z and w are done by linear interpolation:
    */
   tri_linear_coeff(setup, &setup->posCoef, 0, 2);
   tri_linear_coeff(setup, &setup->posCoef, 0, 3);

   /* setup interpolation for all the remaining attributes:
    */
   for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) {
      const uint vertSlot = vinfo->attrib[fragSlot].src_index;
      uint j;

      switch (vinfo->attrib[fragSlot].interp_mode) {
      case INTERP_CONSTANT:
         for (j = 0; j < NUM_CHANNELS; j++)
            const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_LINEAR:
         for (j = 0; j < NUM_CHANNELS; j++)
            tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_PERSPECTIVE:
         for (j = 0; j < NUM_CHANNELS; j++)
            tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
         /* FOG.y = front/back facing  XXX fix this */
         setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.input.facing;
         setup->coef[fragSlot].dadx[1] = 0.0;
         setup->coef[fragSlot].dady[1] = 0.0;
      }
   }
}
示例#2
0
/**
 * Compute the setup->coef[] array dadx, dady, a0 values.
 * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
 */
static void setup_tri_coefficients( struct setup_context *setup )
{
   struct llvmpipe_context *llvmpipe = setup->llvmpipe;
   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
   const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe);
   uint fragSlot;

   /* z and w are done by linear interpolation:
    */
   tri_pos_coeff(setup, 0, 2);
   tri_pos_coeff(setup, 0, 3);

   /* setup interpolation for all the remaining attributes:
    */
   for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) {
      const uint vertSlot = vinfo->attrib[fragSlot].src_index;

      switch (vinfo->attrib[fragSlot].interp_mode) {
      case INTERP_CONSTANT:
         const_coeff(setup, fragSlot, vertSlot);
         break;
      case INTERP_LINEAR:
         tri_linear_coeff(setup, fragSlot, vertSlot);
         break;
      case INTERP_PERSPECTIVE:
         tri_persp_coeff(setup, fragSlot, vertSlot);
         break;
      case INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
         setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing;
         setup->coef.dadx[1 + fragSlot][0] = 0.0;
         setup->coef.dady[1 + fragSlot][0] = 0.0;
      }
   }
}
示例#3
0
/**
 * Compute the setup->coef[] array dadx, dady, a0 values.
 * Must be called after setup->vmin,vmax are initialized.
 */
static boolean
setup_line_coefficients(struct setup_context *setup,
                        const float (*v0)[4],
                        const float (*v1)[4])
{
   struct softpipe_context *softpipe = setup->softpipe;
   const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
   const struct sp_setup_info *sinfo = &softpipe->setup_info;
   uint fragSlot;
   float area;
   float v[2];

   assert(sinfo->valid);

   /* use setup->vmin, vmax to point to vertices */
   if (softpipe->rasterizer->flatshade_first)
      setup->vprovoke = v0;
   else
      setup->vprovoke = v1;
   setup->vmin = v0;
   setup->vmax = v1;

   setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0];
   setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1];

   /* NOTE: this is not really area but something proportional to it */
   area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy;
   if (area == 0.0f || util_is_inf_or_nan(area))
      return FALSE;
   setup->oneoverarea = 1.0f / area;

   /* z and w are done by linear interpolation:
    */
   v[0] = setup->vmin[0][2];
   v[1] = setup->vmax[0][2];
   line_linear_coeff(setup, &setup->posCoef, 2, v);

   v[0] = setup->vmin[0][3];
   v[1] = setup->vmax[0][3];
   line_linear_coeff(setup, &setup->posCoef, 3, v);

   /* setup interpolation for all the remaining attributes:
    */
   for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
      uint j;

      switch (sinfo->attrib[fragSlot].interp) {
      case SP_INTERP_CONSTANT:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
            const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case SP_INTERP_LINEAR:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            line_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                        setup->vmax[vertSlot][j],
                                        fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
                                        v);
            line_linear_coeff(setup, &setup->coef[fragSlot], j, v);
         }
         break;
      case SP_INTERP_PERSPECTIVE:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            line_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                        setup->vmax[vertSlot][j],
                                        fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
                                        v);
            line_persp_coeff(setup, &setup->coef[fragSlot], j, v);
         }
         break;
      case SP_INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
         /* convert 0 to 1.0 and 1 to -1.0 */
         setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
         setup->coef[fragSlot].dadx[0] = 0.0;
         setup->coef[fragSlot].dady[0] = 0.0;
      }
   }
   return TRUE;
}
示例#4
0
/**
 * Compute the setup->coef[] array dadx, dady, a0 values.
 * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
 */
static void
setup_tri_coefficients(struct setup_context *setup)
{
   struct softpipe_context *softpipe = setup->softpipe;
   const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
   const struct sp_setup_info *sinfo = &softpipe->setup_info;
   uint fragSlot;
   float v[3];

   assert(sinfo->valid);

   /* z and w are done by linear interpolation:
    */
   v[0] = setup->vmin[0][2];
   v[1] = setup->vmid[0][2];
   v[2] = setup->vmax[0][2];
   tri_linear_coeff(setup, &setup->posCoef, 2, v);

   v[0] = setup->vmin[0][3];
   v[1] = setup->vmid[0][3];
   v[2] = setup->vmax[0][3];
   tri_linear_coeff(setup, &setup->posCoef, 3, v);

   /* setup interpolation for all the remaining attributes:
    */
   for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
      uint j;

      switch (sinfo->attrib[fragSlot].interp) {
      case SP_INTERP_CONSTANT:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         }
         break;
      case SP_INTERP_LINEAR:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                       setup->vmid[vertSlot][j],
                                       setup->vmax[vertSlot][j],
                                       fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
                                       v);
            tri_linear_coeff(setup, &setup->coef[fragSlot], j, v);
         }
         break;
      case SP_INTERP_PERSPECTIVE:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j],
                                       setup->vmid[vertSlot][j],
                                       setup->vmax[vertSlot][j],
                                       fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j),
                                       v);
            tri_persp_coeff(setup, &setup->coef[fragSlot], j, v);
         }
         break;
      case SP_INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
         /* convert 0 to 1.0 and 1 to -1.0 */
         setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
         setup->coef[fragSlot].dadx[0] = 0.0;
         setup->coef[fragSlot].dady[0] = 0.0;
      }

      if (0) {
         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
            debug_printf("attr[%d].%c: a0:%f dx:%f dy:%f\n",
                         fragSlot, "xyzw"[j],
                         setup->coef[fragSlot].a0[j],
                         setup->coef[fragSlot].dadx[j],
                         setup->coef[fragSlot].dady[j]);
         }
      }
   }
}
示例#5
0
/**
 * Do setup for point rasterization, then render the point.
 * Round or square points...
 * XXX could optimize a lot for 1-pixel points.
 */
void
sp_setup_point(struct setup_context *setup,
               const float (*v0)[4])
{
   struct softpipe_context *softpipe = setup->softpipe;
   const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
   const int sizeAttr = setup->softpipe->psize_slot;
   const float size
      = sizeAttr > 0 ? v0[sizeAttr][0]
      : setup->softpipe->rasterizer->point_size;
   const float halfSize = 0.5F * size;
   const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
   const float x = v0[0][0];  /* Note: data[0] is always position */
   const float y = v0[0][1];
   const struct sp_setup_info *sinfo = &softpipe->setup_info;
   uint fragSlot;
   uint layer = 0;
   unsigned viewport_index = 0;
#if DEBUG_VERTS
   debug_printf("Setup point:\n");
   print_vertex(setup, v0);
#endif

   assert(sinfo->valid);

   if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
      return;

   assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS);

   if (setup->softpipe->layer_slot > 0) {
      layer = *(unsigned *)v0[setup->softpipe->layer_slot];
      layer = MIN2(layer, setup->max_layer);
   }
   setup->quad[0].input.layer = layer;

   if (setup->softpipe->viewport_index_slot > 0) {
      unsigned *udata = (unsigned*)v0[setup->softpipe->viewport_index_slot];
      viewport_index = sp_clamp_viewport_idx(*udata);
   }
   setup->quad[0].input.viewport_index = viewport_index;

   /* For points, all interpolants are constant-valued.
    * However, for point sprites, we'll need to setup texcoords appropriately.
    * XXX: which coefficients are the texcoords???
    * We may do point sprites as textured quads...
    *
    * KW: We don't know which coefficients are texcoords - ultimately
    * the choice of what interpolation mode to use for each attribute
    * should be determined by the fragment program, using
    * per-attribute declaration statements that include interpolation
    * mode as a parameter.  So either the fragment program will have
    * to be adjusted for pointsprite vs normal point behaviour, or
    * otherwise a special interpolation mode will have to be defined
    * which matches the required behaviour for point sprites.  But -
    * the latter is not a feature of normal hardware, and as such
    * probably should be ruled out on that basis.
    */
   setup->vprovoke = v0;

   /* setup Z, W */
   const_coeff(setup, &setup->posCoef, 0, 2);
   const_coeff(setup, &setup->posCoef, 0, 3);

   for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
      uint j;

      switch (sinfo->attrib[fragSlot].interp) {
      case SP_INTERP_CONSTANT:
         /* fall-through */
      case SP_INTERP_LINEAR:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
            const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case SP_INTERP_PERSPECTIVE:
         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
            point_persp_coeff(setup, setup->vprovoke,
                              &setup->coef[fragSlot], vertSlot, j);
         break;
      case SP_INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
         /* convert 0 to 1.0 and 1 to -1.0 */
         setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
         setup->coef[fragSlot].dadx[0] = 0.0;
         setup->coef[fragSlot].dady[0] = 0.0;
      }
   }


   if (halfSize <= 0.5 && !round) {
      /* special case for 1-pixel points */
      const int ix = ((int) x) & 1;
      const int iy = ((int) y) & 1;
      setup->quad[0].input.x0 = (int) x - ix;
      setup->quad[0].input.y0 = (int) y - iy;
      setup->quad[0].inout.mask = (1 << ix) << (2 * iy);
      clip_emit_quad(setup, &setup->quad[0]);
   }
   else {
      if (round) {
         /* rounded points */
         const int ixmin = block((int) (x - halfSize));
         const int ixmax = block((int) (x + halfSize));
         const int iymin = block((int) (y - halfSize));
         const int iymax = block((int) (y + halfSize));
         const float rmin = halfSize - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
         const float rmax = halfSize + 0.7071F;
         const float rmin2 = MAX2(0.0F, rmin * rmin);
         const float rmax2 = rmax * rmax;
         const float cscale = 1.0F / (rmax2 - rmin2);
         int ix, iy;

         for (iy = iymin; iy <= iymax; iy += 2) {
            for (ix = ixmin; ix <= ixmax; ix += 2) {
               float dx, dy, dist2, cover;

               setup->quad[0].inout.mask = 0x0;

               dx = (ix + 0.5f) - x;
               dy = (iy + 0.5f) - y;
               dist2 = dx * dx + dy * dy;
               if (dist2 <= rmax2) {
                  cover = 1.0F - (dist2 - rmin2) * cscale;
                  setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f);
                  setup->quad[0].inout.mask |= MASK_TOP_LEFT;
               }

               dx = (ix + 1.5f) - x;
               dy = (iy + 0.5f) - y;
               dist2 = dx * dx + dy * dy;
               if (dist2 <= rmax2) {
                  cover = 1.0F - (dist2 - rmin2) * cscale;
                  setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f);
                  setup->quad[0].inout.mask |= MASK_TOP_RIGHT;
               }

               dx = (ix + 0.5f) - x;
               dy = (iy + 1.5f) - y;
               dist2 = dx * dx + dy * dy;
               if (dist2 <= rmax2) {
                  cover = 1.0F - (dist2 - rmin2) * cscale;
                  setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f);
                  setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT;
               }

               dx = (ix + 1.5f) - x;
               dy = (iy + 1.5f) - y;
               dist2 = dx * dx + dy * dy;
               if (dist2 <= rmax2) {
                  cover = 1.0F - (dist2 - rmin2) * cscale;
                  setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f);
                  setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT;
               }

               if (setup->quad[0].inout.mask) {
                  setup->quad[0].input.x0 = ix;
                  setup->quad[0].input.y0 = iy;
                  clip_emit_quad(setup, &setup->quad[0]);
               }
            }
         }
      }
      else {
         /* square points */
         const int xmin = (int) (x + 0.75 - halfSize);
         const int ymin = (int) (y + 0.25 - halfSize);
         const int xmax = xmin + (int) size;
         const int ymax = ymin + (int) size;
         /* XXX could apply scissor to xmin,ymin,xmax,ymax now */
         const int ixmin = block(xmin);
         const int ixmax = block(xmax - 1);
         const int iymin = block(ymin);
         const int iymax = block(ymax - 1);
         int ix, iy;

         /*
         debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax);
         */
         for (iy = iymin; iy <= iymax; iy += 2) {
            uint rowMask = 0xf;
            if (iy < ymin) {
               /* above the top edge */
               rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
            }
            if (iy + 1 >= ymax) {
               /* below the bottom edge */
               rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
            }

            for (ix = ixmin; ix <= ixmax; ix += 2) {
               uint mask = rowMask;

               if (ix < xmin) {
                  /* fragment is past left edge of point, turn off left bits */
                  mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
               }
               if (ix + 1 >= xmax) {
                  /* past the right edge */
                  mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
               }

               setup->quad[0].inout.mask = mask;
               setup->quad[0].input.x0 = ix;
               setup->quad[0].input.y0 = iy;
               clip_emit_quad(setup, &setup->quad[0]);
            }
         }
      }
   }
}
示例#6
0
/**
 * Compute the setup->coef[] array dadx, dady, a0 values.
 * Must be called after setup->vmin,vmax are initialized.
 */
static INLINE boolean
setup_line_coefficients(struct setup_context *setup,
                        const float (*v0)[4],
                        const float (*v1)[4])
{
   struct softpipe_context *softpipe = setup->softpipe;
   const struct sp_fragment_shader *spfs = softpipe->fs;
   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
   uint fragSlot;
   float area;

   /* use setup->vmin, vmax to point to vertices */
   if (softpipe->rasterizer->flatshade_first)
      setup->vprovoke = v0;
   else
      setup->vprovoke = v1;
   setup->vmin = v0;
   setup->vmax = v1;

   setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0];
   setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1];

   /* NOTE: this is not really area but something proportional to it */
   area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy;
   if (area == 0.0f || util_is_inf_or_nan(area))
      return FALSE;
   setup->oneoverarea = 1.0f / area;

   /* z and w are done by linear interpolation:
    */
   line_linear_coeff(setup, &setup->posCoef, 0, 2);
   line_linear_coeff(setup, &setup->posCoef, 0, 3);

   /* setup interpolation for all the remaining attributes:
    */
   for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) {
      const uint vertSlot = vinfo->attrib[fragSlot].src_index;
      uint j;

      switch (vinfo->attrib[fragSlot].interp_mode) {
      case INTERP_CONSTANT:
         for (j = 0; j < NUM_CHANNELS; j++)
            const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_LINEAR:
         for (j = 0; j < NUM_CHANNELS; j++)
            line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_PERSPECTIVE:
         for (j = 0; j < NUM_CHANNELS; j++)
            line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
         break;
      case INTERP_POS:
         setup_fragcoord_coeff(setup, fragSlot);
         break;
      default:
         assert(0);
      }

      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
         setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
         setup->coef[fragSlot].dadx[0] = 0.0;
         setup->coef[fragSlot].dady[0] = 0.0;
      }
   }
   return TRUE;
}