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 (views[i] && views[i]->texture) { struct pipe_resource *res = views[i]->texture; if (res->target == PIPE_BUFFER && (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)) nvc0->textures_coherent[s] |= 1 << i; else nvc0->textures_coherent[s] &= ~(1 << i); } else { nvc0->textures_coherent[s] &= ~(1 << i); } if (old) { if (s == 5) nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i)); else nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_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) { if (s == 5) nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i)); else nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i)); nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); } } nvc0->num_textures[s] = nr; }
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_3D_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 (views[p] && views[p]->texture) { struct pipe_resource *res = views[p]->texture; if (res->target == PIPE_BUFFER && (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)) nvc0->textures_coherent[s] |= 1 << i; else nvc0->textures_coherent[s] &= ~(1 << i); } else { nvc0->textures_coherent[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 void nvc0_compute_validate_textures(struct nvc0_context *nvc0) { bool need_flush = nvc0_validate_tic(nvc0, 5); if (need_flush) { BEGIN_NVC0(nvc0->base.pushbuf, NVC0_CP(TIC_FLUSH), 1); PUSH_DATA (nvc0->base.pushbuf, 0); } /* Invalidate all 3D textures because they are aliased. */ for (int s = 0; s < 5; s++) { for (int i = 0; i < nvc0->num_textures[s]; i++) nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i)); nvc0->textures_dirty[s] = ~0; } nvc0->dirty_3d |= NVC0_NEW_3D_TEXTURES; }
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_3d |= NVC0_NEW_3D_FRAMEBUFFER; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB); if (!--ref) return ref; } } } if (res->bind & PIPE_BIND_DEPTH_STENCIL) { if (nvc0->framebuffer.zsbuf && nvc0->framebuffer.zsbuf->texture == res) { nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB); if (!--ref) return ref; } } if (res->target == PIPE_BUFFER) { for (i = 0; i < nvc0->num_vtxbufs; ++i) { if (nvc0->vtxbuf[i].buffer == res) { nvc0->dirty_3d |= NVC0_NEW_3D_ARRAYS; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX); if (!--ref) return ref; } } if (nvc0->idxbuf.buffer == res) { nvc0->dirty_3d |= NVC0_NEW_3D_IDXBUF; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_IDX); if (!--ref) return ref; } for (s = 0; s < 6; ++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; if (unlikely(s == 5)) { nvc0->dirty_cp |= NVC0_NEW_CP_TEXTURES; nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i)); } else { nvc0->dirty_3d |= NVC0_NEW_3D_TEXTURES; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i)); } if (!--ref) return ref; } } } for (s = 0; s < 6; ++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->constbuf_dirty[s] |= 1 << i; if (unlikely(s == 5)) { nvc0->dirty_cp |= NVC0_NEW_CP_CONSTBUF; nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_CB(i)); } else { nvc0->dirty_3d |= NVC0_NEW_3D_CONSTBUF; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_CB(s, i)); } if (!--ref) return ref; } } } for (s = 0; s < 6; ++s) { for (i = 0; i < NVC0_MAX_BUFFERS; ++i) { if (nvc0->buffers[s][i].buffer == res) { nvc0->buffers_dirty[s] |= 1 << i; if (unlikely(s == 5)) { nvc0->dirty_cp |= NVC0_NEW_CP_BUFFERS; nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_BUF); } else { nvc0->dirty_3d |= NVC0_NEW_3D_BUFFERS; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_BUF); } if (!--ref) return ref; } } } for (s = 0; s < 6; ++s) { for (i = 0; i < NVC0_MAX_IMAGES; ++i) { if (nvc0->images[s][i].resource == res) { nvc0->images_dirty[s] |= 1 << i; if (unlikely(s == 5)) { nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES; nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF); } else { nvc0->dirty_3d |= NVC0_NEW_3D_SURFACES; nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF); } } if (!--ref) return ref; } } } return ref; }