static INLINE void nvc0_program_update_context_state(struct nvc0_context *nvc0, struct nvc0_program *prog, int stage) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; if (prog && prog->need_tls) { const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; if (!nvc0->state.tls_required) BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls); nvc0->state.tls_required |= 1 << stage; } else { if (nvc0->state.tls_required == (1 << stage)) nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS); nvc0->state.tls_required &= ~(1 << stage); } if (prog && prog->immd_size) { BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); /* NOTE: may overlap code of a different shader */ PUSH_DATA (push, align(prog->immd_size, 0x100)); PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base); PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base); BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1); PUSH_DATA (push, (14 << 4) | 1); nvc0->state.c14_bound |= 1 << stage; } else if (nvc0->state.c14_bound & (1 << stage)) { BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1); PUSH_DATA (push, (14 << 4) | 0); nvc0->state.c14_bound &= ~(1 << stage); } }
static INLINE void nvc0_program_update_context_state(struct nvc0_context *nvc0, struct nvc0_program *prog, int stage) { struct nouveau_channel *chan = nvc0->screen->base.channel; if (prog->hdr[1]) nvc0->state.tls_required |= 1 << stage; else nvc0->state.tls_required &= ~(1 << stage); if (prog->immd_size) { const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; BEGIN_RING(chan, RING_3D(CB_SIZE), 3); /* NOTE: may overlap code of a different shader */ OUT_RING (chan, align(prog->immd_size, 0x100)); OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl); OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl); BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1); OUT_RING (chan, (14 << 4) | 1); nvc0->state.c14_bound |= 1 << stage; } else if (nvc0->state.c14_bound & (1 << stage)) { BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1); OUT_RING (chan, (14 << 4) | 0); nvc0->state.c14_bound &= ~(1 << stage); } }