Exemplo n.º 1
0
static int
nv30_fp(int chipset, struct tgsi_token tokens[],
        unsigned *size, unsigned **code) {
   struct nv30_fragprog fp;
   memset(&fp, 0, sizeof(fp));
   fp.pipe.tokens = tokens;
   tgsi_scan_shader(fp.pipe.tokens, &fp.info);
   _nvfx_fragprog_translate(chipset >= 0x40 ? 0x4097 : 0x3097, &fp);
   *size = fp.insn_len * 4;
   *code = fp.insn;
   return !fp.translated;
}
Exemplo n.º 2
0
void
nv30_fragprog_validate(struct nv30_context *nv30)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nv30_fragprog *fp = nv30->fragprog.program;
   bool upload = false;
   int i;

   if (!fp->translated) {
      _nvfx_fragprog_translate(eng3d->oclass, fp);
      if (!fp->translated)
         return;

      upload = true;
   }

   /* update constants, also needs to be done on every fp switch as we
    * have no idea whether the constbuf changed in the meantime
    */
   if (nv30->fragprog.constbuf) {
      struct pipe_resource *constbuf = nv30->fragprog.constbuf;
      uint32_t *cbuf = (uint32_t *)nv04_resource(constbuf)->data;

      for (i = 0; i < fp->nr_consts; i++) {
         unsigned off = fp->consts[i].offset;
         unsigned idx = fp->consts[i].index * 4;

         if (!memcmp(&fp->insn[off], &cbuf[idx], 4 * 4))
            continue;
         memcpy(&fp->insn[off], &cbuf[idx], 4 * 4);
         upload = true;
      }
   }

   if (upload)
      nv30_fragprog_upload(nv30);

   /* FP_ACTIVE_PROGRAM needs to be done again even if only the consts
    * were updated.  TEX_CACHE_CTL magic is not enough to convince the
    * GPU that it should re-read the fragprog from VRAM... sigh.
    */
   if (nv30->state.fragprog != fp || upload) {
      struct nv04_resource *r = nv04_resource(fp->buffer);

      if (!PUSH_SPACE(push, 8))
         return;
      PUSH_RESET(push, BUFCTX_FRAGPROG);

      BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
      PUSH_RESRC(push, NV30_3D(FP_ACTIVE_PROGRAM), BUFCTX_FRAGPROG, r, 0,
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_OR,
                       NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
                       NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
      BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
      PUSH_DATA (push, fp->fp_control);
      if (eng3d->oclass < NV40_3D_CLASS) {
         BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1);
         PUSH_DATA (push, 0x00010004);
         BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1);
         PUSH_DATA (push, fp->texcoords);
      } else {
         BEGIN_NV04(push, SUBC_3D(0x0b40), 1);
         PUSH_DATA (push, 0x00000000);
      }

      nv30->state.fragprog = fp;
   }
}