예제 #1
0
      bfc = (nv50->state.semantic_color & NV50_3D_SEMANTIC_COLOR_BFC0_ID__MASK)
         >> 8;
      if (nv50->rast->pipe.light_twoside == ((ffc == bfc) ? 0 : 1))
         return;
   }

   memset(lin, 0x00, sizeof(lin));

   /* XXX: in buggy-endian mode, is the first element of map (u32)0x000000xx
    *  or is it the first byte ?
    */
   memset(map, nv50->gmtyprog ? 0x80 : 0x40, sizeof(map));

   dummy.mask = 0xf; /* map all components of HPOS */
   dummy.linear = 0;
   m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);

   for (c = 0; c < vp->vp.clpd_nr; ++c)
      map[m++] = vp->vp.clpd[c / 4] + (c % 4);

   colors |= m << 8; /* adjust BFC0 id */

   dummy.mask = 0x0;

   /* if light_twoside is active, FFC0_ID == BFC0_ID is invalid */
   if (nv50->rast->pipe.light_twoside) {
      for (i = 0; i < 2; ++i) {
         n = vp->vp.bfc[i];
         if (fp->vp.bfc[i] >= fp->in_nr)
            continue;
         m = nv50_vec4_map(map, m, lin, &fp->in[fp->vp.bfc[i]],
예제 #2
0
void
nv50_fp_linkage_validate(struct nv50_context *nv50)
{
   struct nouveau_channel *chan = nv50->screen->base.channel;
   struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog;
   struct nv50_program *fp = nv50->fragprog;
   struct nv50_varying dummy;
   int i, n, c, m;
   uint32_t primid = 0;
   uint32_t psiz = 0x000;
   uint32_t interp = fp->fp.interp;
   uint32_t colors = fp->fp.colors;
   uint32_t lin[4];
   uint8_t map[64];

   memset(lin, 0x00, sizeof(lin));

   /* XXX: in buggy-endian mode, is the first element of map (u32)0x000000xx
    *  or is it the first byte ?
    */
   memset(map, nv50->gmtyprog ? 0x80 : 0x40, sizeof(map));

   dummy.mask = 0xf; /* map all components of HPOS */
   dummy.linear = 0;
   m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);

   for (c = 0; c < vp->vp.clpd_nr; ++c)
      map[m++] = vp->vp.clpd + c;

   colors |= m << 8; /* adjust BFC0 id */

   /* if light_twoside is active, FFC0_ID == BFC0_ID is invalid */
   if (nv50->rast->pipe.light_twoside) {
      for (i = 0; i < 2; ++i)
         m = nv50_vec4_map(map, m, lin,
                           &fp->in[fp->vp.bfc[i]], &vp->out[vp->vp.bfc[i]]);
   }
   colors += m - 4; /* adjust FFC0 id */
   interp |= m << 8; /* set map id where 'normal' FP inputs start */

   dummy.mask = 0x0;
   for (i = 0; i < fp->in_nr; ++i) {
      for (n = 0; n < vp->out_nr; ++n)
         if (vp->out[n].sn == fp->in[i].sn &&
             vp->out[n].si == fp->in[i].si)
            break;
      m = nv50_vec4_map(map, m, lin,
                        &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy);
   }

   /* PrimitiveID either is replaced by the system value, or
    * written by the geometry shader into an output register
    */
   if (fp->gp.primid < 0x40) {
      primid = m;
      map[m++] = vp->gp.primid;
   }

   if (nv50->rast->pipe.point_size_per_vertex) {
      psiz = (m << 4) | 1;
      map[m++] = vp->vp.psiz;
   }

   if (nv50->rast->pipe.clamp_vertex_color)
      colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;

   n = (m + 3) / 4;
   assert(m <= 64);

   if (unlikely(nv50->gmtyprog)) {
      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1);
      OUT_RING  (chan, m);
      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n);
      OUT_RINGp (chan, map, n);
   } else {
      BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
      OUT_RING  (chan, vp->vp.attrs[2]);

      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1);
      OUT_RING  (chan, primid);

      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
      OUT_RING  (chan, m);
      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
      OUT_RINGp (chan, map, n);
   }

   BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4);
   OUT_RING  (chan, colors);
   OUT_RING  (chan, (vp->vp.clpd_nr << 8) | 4);
   OUT_RING  (chan, 0);
   OUT_RING  (chan, psiz);

   BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
   OUT_RING  (chan, interp);

   nv50->state.interpolant_ctrl = interp;

   nv50->state.semantic_color = colors;
   nv50->state.semantic_psize = psiz;

   BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
   OUT_RINGp (chan, lin, 4);

   BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
   OUT_RING  (chan, nv50->gmtyprog ? 1 : 0);
}