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]],
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); }