14c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller/*
24c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Copyright 2010 Christoph Bumiller
34c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
44c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Permission is hereby granted, free of charge, to any person obtaining a
54c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * copy of this software and associated documentation files (the "Software"),
64c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * to deal in the Software without restriction, including without limitation
74c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * and/or sell copies of the Software, and to permit persons to whom the
94c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Software is furnished to do so, subject to the following conditions:
104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * The above copyright notice and this permission notice shall be included in
124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * all copies or substantial portions of the Software.
134c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
144c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
184c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
194c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * SOFTWARE.
214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller */
224c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
234c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "pipe/p_context.h"
244c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "pipe/p_defines.h"
254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "pipe/p_state.h"
264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "util/u_inlines.h"
274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "nvc0_context.h"
294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
301a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumillerstatic INLINE void
311a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumillernvc0_program_update_context_state(struct nvc0_context *nvc0,
321a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller                                  struct nvc0_program *prog, int stage)
331a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller{
346d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
353afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller
366d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (prog && prog->need_tls) {
376d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
386d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (!nvc0->state.tls_required)
396d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls);
401a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller      nvc0->state.tls_required |= 1 << stage;
416d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   } else {
426d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (nvc0->state.tls_required == (1 << stage))
436d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS);
441a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller      nvc0->state.tls_required &= ~(1 << stage);
456d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   }
463afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller
476d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (prog && prog->immd_size) {
486d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
493afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller      /* NOTE: may overlap code of a different shader */
506d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, align(prog->immd_size, 0x100));
516d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base);
526d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base);
536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
546d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, (14 << 4) | 1);
553afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller
563afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller      nvc0->state.c14_bound |= 1 << stage;
573afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller   } else
583afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller   if (nvc0->state.c14_bound & (1 << stage)) {
596d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
606d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, (14 << 4) | 0);
613afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller
623afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller      nvc0->state.c14_bound &= ~(1 << stage);
633afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumiller   }
641a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller}
651a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller
663afabfb929cf24a783c10c99bf0d86245e70a94aChristoph Bumillerstatic INLINE boolean
674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
684c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
696d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (prog->mem)
704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return TRUE;
714c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
727744e867b7f45f3f9d763b61d7219dc28ca39c45Christoph Bumiller   if (!prog->translated) {
73e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      prog->translated = nvc0_program_translate(
74e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller         prog, nvc0->screen->base.device->chipset);
757744e867b7f45f3f9d763b61d7219dc28ca39c45Christoph Bumiller      if (!prog->translated)
767744e867b7f45f3f9d763b61d7219dc28ca39c45Christoph Bumiller         return FALSE;
777744e867b7f45f3f9d763b61d7219dc28ca39c45Christoph Bumiller   }
784c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
7914bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (likely(prog->code_size))
8014bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      return nvc0_program_upload_code(nvc0, prog);
8114bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   return TRUE; /* stream output info only */
824c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
854c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_vertprog_validate(struct nvc0_context *nvc0)
864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
876d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
884c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_program *vp = nvc0->vertprog;
894c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
904c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (!nvc0_program_validate(nvc0, vp))
914c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         return;
921a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller   nvc0_program_update_context_state(nvc0, vp, 0);
934c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
946d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2);
956d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, 0x11);
966d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, vp->code_base);
976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1);
986d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, vp->max_gpr);
994c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1006d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   // BEGIN_NVC0(push, NVC0_3D_(0x163c), 1);
1016d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   // PUSH_DATA (push, 0);
1024c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1034c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1044c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
1054c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_fragprog_validate(struct nvc0_context *nvc0)
1064c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
1084c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_program *fp = nvc0->fragprog;
1094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (!nvc0_program_validate(nvc0, fp))
1114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         return;
1121a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller   nvc0_program_update_context_state(nvc0, fp, 4);
1134c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
11436158c199448ce038d9fe913d972f29a655aecabChristoph Bumiller   if (fp->fp.early_z != nvc0->state.early_z_forced) {
11536158c199448ce038d9fe913d972f29a655aecabChristoph Bumiller      nvc0->state.early_z_forced = fp->fp.early_z;
11636158c199448ce038d9fe913d972f29a655aecabChristoph Bumiller      IMMED_NVC0(push, NVC0_3D(FORCE_EARLY_FRAGMENT_TESTS), fp->fp.early_z);
11736158c199448ce038d9fe913d972f29a655aecabChristoph Bumiller   }
11836158c199448ce038d9fe913d972f29a655aecabChristoph Bumiller
1196d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2);
1206d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, 0x51);
1216d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, fp->code_base);
1226d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1);
1236d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, fp->max_gpr);
1246d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
1256d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, SUBC_3D(0x0360), 2);
1266d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, 0x20164010);
1276d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, 0x20);
1286d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1);
1296d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, fp->flags[0]);
1304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
1334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_tctlprog_validate(struct nvc0_context *nvc0)
1344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1356d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
1364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_program *tp = nvc0->tctlprog;
1374c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1386d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (tp && nvc0_program_validate(nvc0, tp)) {
1396d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (tp->tp.tess_mode != ~0) {
1406d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
1416d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, tp->tp.tess_mode);
1426d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      }
1436d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
1446d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x21);
1456d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, tp->code_base);
1466d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
1476d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, tp->max_gpr);
1486d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
1496d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (tp->tp.input_patch_size <= 32)
1506d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), tp->tp.input_patch_size);
1516d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   } else {
1526d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
1536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x20);
1544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
1551a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller   nvc0_program_update_context_state(nvc0, tp, 1);
1564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1584c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
1594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_tevlprog_validate(struct nvc0_context *nvc0)
1604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1616d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
1624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_program *tp = nvc0->tevlprog;
1634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1646d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (tp && nvc0_program_validate(nvc0, tp)) {
1656d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (tp->tp.tess_mode != ~0) {
1666d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
1676d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, tp->tp.tess_mode);
1686d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      }
1697a40ae4a31f3ab526706fdfda7631d54f094512aChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
1706d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x31);
1716d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1);
1726d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, tp->code_base);
1736d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1);
1746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, tp->max_gpr);
1756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   } else {
1767a40ae4a31f3ab526706fdfda7631d54f094512aChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
1776d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x30);
1784c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
1791a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller   nvc0_program_update_context_state(nvc0, tp, 2);
1804c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1814c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1824c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
1834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_gmtyprog_validate(struct nvc0_context *nvc0)
1844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1856d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
1864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_program *gp = nvc0->gmtyprog;
1874c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
18814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (gp)
18914bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      nvc0_program_validate(nvc0, gp);
1906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
19114bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   /* we allow GPs with no code for specifying stream output state only */
1926d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (gp && gp->code_size) {
1936d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      const boolean gp_selects_layer = gp->hdr[13] & (1 << 9);
1946d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
1957a40ae4a31f3ab526706fdfda7631d54f094512aChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
1966d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x41);
1976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1);
1986d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, gp->code_base);
1996d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1);
2006d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, gp->max_gpr);
2016d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
2026d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0);
2036d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   } else {
2046d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      IMMED_NVC0(push, NVC0_3D(LAYER), 0);
2057a40ae4a31f3ab526706fdfda7631d54f094512aChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
2066d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x40);
2074c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
2081a8297139396ec2a6415ef803a3901e1ecef485cChristoph Bumiller   nvc0_program_update_context_state(nvc0, gp, 3);
2094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
210f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
211f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumillervoid
212f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumillernvc0_tfb_validate(struct nvc0_context *nvc0)
213f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller{
2146d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
21514bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   struct nvc0_transform_feedback_state *tfb;
2160d27be3d7982d38d3c26e693be959a9e6b776e5fChristoph Bumiller   unsigned b;
217f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
21814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (nvc0->gmtyprog) tfb = nvc0->gmtyprog->tfb;
21914bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   else
22014bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (nvc0->tevlprog) tfb = nvc0->tevlprog->tfb;
22114bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   else
22214bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      tfb = nvc0->vertprog->tfb;
22314bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller
2246d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
22514bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller
22614bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (tfb && tfb != nvc0->state.tfb) {
2270d27be3d7982d38d3c26e693be959a9e6b776e5fChristoph Bumiller      for (b = 0; b < 4; ++b) {
22814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller         if (tfb->varying_count[b]) {
2290d27be3d7982d38d3c26e693be959a9e6b776e5fChristoph Bumiller            unsigned n = (tfb->varying_count[b] + 3) / 4;
2300d27be3d7982d38d3c26e693be959a9e6b776e5fChristoph Bumiller
2316d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3);
2326d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, 0);
2336d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, tfb->varying_count[b]);
2346d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, tfb->stride[b]);
2356d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n);
2366d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATAp(push, tfb->varying_index[b], n);
23714bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller
23814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller            if (nvc0->tfbbuf[b])
23914bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller               nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b];
24014bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller         } else {
2416d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0);
24214bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller         }
24314bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      }
244f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller   }
24514bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   nvc0->state.tfb = tfb;
246f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
24714bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller   if (!(nvc0->dirty & NVC0_NEW_TFB_TARGETS))
24814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      return;
2496d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TFB);
250f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
251f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller   for (b = 0; b < nvc0->num_tfbbufs; ++b) {
25214bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]);
25314bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      struct nv04_resource *buf = nv04_resource(targ->pipe.buffer);
254f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
25514bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      if (tfb)
25614bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller         targ->stride = tfb->stride[b];
257f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
25814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      if (!(nvc0->tfbbuf_dirty & (1 << b)))
259f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller         continue;
260f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller
26114bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      if (!targ->clean)
2626d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         nvc0_query_fifo_wait(push, targ->pq);
2636d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
2646d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 1);
2656d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
2666d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, buf->address + targ->pipe.buffer_offset);
2676d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, targ->pipe.buffer_size);
26814bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      if (!targ->clean) {
2696d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         nvc0_query_pushbuf_submit(push, targ->pq, 0x4);
27014bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller      } else {
2716d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
27214bd9d764802b5fedb652c791faafe4d13b65262Christoph Bumiller         targ->clean = FALSE;
273f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller      }
2746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
275f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller   }
276f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller   for (; b < 4; ++b)
2776d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
278f8a7a0b6f30ff38b2743860cbc4caeab102c2c29Christoph Bumiller}
279