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 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 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 (old) 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) continue; nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); } nvc0->num_textures[s] = nr; nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES); nvc0->dirty |= NVC0_NEW_TEXTURES; }
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 bool nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s, unsigned start, unsigned nr, const struct pipe_image_view *pimages) { const unsigned end = start + nr; unsigned mask = 0; unsigned i; assert(s < 6); if (pimages) { for (i = start; i < end; ++i) { struct pipe_image_view *img = &nvc0->images[s][i]; const unsigned p = i - start; if (img->resource == pimages[p].resource && img->format == pimages[p].format && img->access == pimages[p].access) { if (img->resource == NULL) continue; if (img->resource->target == PIPE_BUFFER && img->u.buf.offset == pimages[p].u.buf.offset && img->u.buf.size == pimages[p].u.buf.size) continue; if (img->resource->target != PIPE_BUFFER && img->u.tex.first_layer == pimages[p].u.tex.first_layer && img->u.tex.last_layer == pimages[p].u.tex.last_layer && img->u.tex.level == pimages[p].u.tex.level) continue; } mask |= (1 << i); if (pimages[p].resource) nvc0->images_valid[s] |= (1 << i); else nvc0->images_valid[s] &= ~(1 << i); img->format = pimages[p].format; img->access = pimages[p].access; if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER) img->u.buf = pimages[p].u.buf; else img->u.tex = pimages[p].u.tex; pipe_resource_reference( &img->resource, pimages[p].resource); if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) { if (nvc0->images_tic[s][i]) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->images_tic[s][i]); nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL); } nvc0->images_tic[s][i] = gm107_create_texture_view_from_image(&nvc0->base.pipe, &pimages[p]); } } if (!mask) return false; } else { mask = ((1 << nr) - 1) << start; if (!(nvc0->images_valid[s] & mask)) return false; for (i = start; i < end; ++i) { pipe_resource_reference(&nvc0->images[s][i].resource, NULL); if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->images_tic[s][i]); if (old) { nvc0_screen_tic_unlock(nvc0->screen, old); pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL); } } } nvc0->images_valid[s] &= ~mask; } nvc0->images_dirty[s] |= mask; if (s == 5) nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF); else nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF); return true; }