static inline void nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s, unsigned nr, struct pipe_sampler_view **views) { unsigned i; for (i = 0; i < nr; ++i) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); if (views[i] == nvc0->textures[s][i]) continue; nvc0->textures_dirty[s] |= 1 << i; if (old) { nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); nvc0_screen_tic_unlock(nvc0->screen, old); } pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]); } for (i = nr; i < nvc0->num_textures[s]; ++i) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); if (old) { nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); } } nvc0->num_textures[s] = nr; nvc0->dirty |= NVC0_NEW_TEXTURES; }
static void nvc0_stage_set_sampler_views_range(struct nvc0_context *nvc0, const unsigned s, unsigned start, unsigned nr, struct pipe_sampler_view **views) { struct nouveau_bufctx *bctx = (s == 5) ? nvc0->bufctx_cp : nvc0->bufctx_3d; const unsigned end = start + nr; const unsigned bin = (s == 5) ? NVC0_BIND_CP_TEX(0) : NVC0_BIND_TEX(s, 0); int last_valid = -1; unsigned i; if (views) { for (i = start; i < end; ++i) { const unsigned p = i - start; if (views[p]) last_valid = i; if (views[p] == nvc0->textures[s][i]) continue; nvc0->textures_dirty[s] |= 1 << i; if (nvc0->textures[s][i]) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); nouveau_bufctx_reset(bctx, bin + i); nvc0_screen_tic_unlock(nvc0->screen, old); } pipe_sampler_view_reference(&nvc0->textures[s][i], views[p]); } } else { for (i = start; i < end; ++i) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); if (!old) continue; nvc0->textures_dirty[s] |= 1 << i; nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); nouveau_bufctx_reset(bctx, bin + i); } } if (nvc0->num_textures[s] <= end) { if (last_valid < 0) { for (i = start; i && !nvc0->textures[s][i - 1]; --i); nvc0->num_textures[s] = i; } else { nvc0->num_textures[s] = last_valid + 1; } } }
static int nvc0_invalidate_resource_storage(struct nouveau_context *ctx, struct pipe_resource *res, int ref) { struct nvc0_context *nvc0 = nvc0_context(&ctx->pipe); unsigned s, i; if (res->bind & PIPE_BIND_RENDER_TARGET) { for (i = 0; i < nvc0->framebuffer.nr_cbufs; ++i) { if (nvc0->framebuffer.cbufs[i] && nvc0->framebuffer.cbufs[i]->texture == res) { nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB); if (!--ref) return ref; } } } if (res->bind & PIPE_BIND_DEPTH_STENCIL) { if (nvc0->framebuffer.zsbuf && nvc0->framebuffer.zsbuf->texture == res) { nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB); if (!--ref) return ref; } } if (res->bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER | PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_STREAM_OUTPUT | PIPE_BIND_COMMAND_ARGS_BUFFER | PIPE_BIND_SAMPLER_VIEW)) { for (i = 0; i < nvc0->num_vtxbufs; ++i) { if (nvc0->vtxbuf[i].buffer == res) { nvc0->dirty |= NVC0_NEW_ARRAYS; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX); if (!--ref) return ref; } } if (nvc0->idxbuf.buffer == res) { nvc0->dirty |= NVC0_NEW_IDXBUF; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX); if (!--ref) return ref; } for (s = 0; s < 5; ++s) { for (i = 0; i < nvc0->num_textures[s]; ++i) { if (nvc0->textures[s][i] && nvc0->textures[s][i]->texture == res) { nvc0->textures_dirty[s] |= 1 << i; nvc0->dirty |= NVC0_NEW_TEXTURES; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); if (!--ref) return ref; } } } for (s = 0; s < 5; ++s) { for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; ++i) { if (!(nvc0->constbuf_valid[s] & (1 << i))) continue; if (!nvc0->constbuf[s][i].user && nvc0->constbuf[s][i].u.buf == res) { nvc0->dirty |= NVC0_NEW_CONSTBUF; nvc0->constbuf_dirty[s] |= 1 << i; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i)); if (!--ref) return ref; } } } } return ref; }