static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *cb) { struct nv50_context *nv50 = nv50_context(pipe); struct pipe_resource *res = cb ? cb->buffer : NULL; const unsigned s = nv50_context_shader_stage(shader); const unsigned i = index; if (shader == PIPE_SHADER_COMPUTE) return; assert(i < NV50_MAX_PIPE_CONSTBUFS); if (nv50->constbuf[s][i].user) nv50->constbuf[s][i].u.buf = NULL; else if (nv50->constbuf[s][i].u.buf) { nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_CB(s, i)); nv04_resource(nv50->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i); } pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res); nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false; if (nv50->constbuf[s][i].user) { nv50->constbuf[s][i].u.data = cb->user_buffer; nv50->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000); nv50->constbuf_valid[s] |= 1 << i; nv50->constbuf_coherent[s] &= ~(1 << i); } else if (res) { nv50->constbuf[s][i].offset = cb->buffer_offset; nv50->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000); nv50->constbuf_valid[s] |= 1 << i; if (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT) nv50->constbuf_coherent[s] |= 1 << i; else nv50->constbuf_coherent[s] &= ~(1 << i); } else { nv50->constbuf_valid[s] &= ~(1 << i); nv50->constbuf_coherent[s] &= ~(1 << i); } nv50->constbuf_dirty[s] |= 1 << i; nv50->dirty_3d |= NV50_NEW_3D_CONSTBUF; }
static int nv50_invalidate_resource_storage(struct nouveau_context *ctx, struct pipe_resource *res, int ref) { struct nv50_context *nv50 = nv50_context(&ctx->pipe); unsigned bind = res->bind ? res->bind : PIPE_BIND_VERTEX_BUFFER; unsigned s, i; if (bind & PIPE_BIND_RENDER_TARGET) { assert(nv50->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS); for (i = 0; i < nv50->framebuffer.nr_cbufs; ++i) { if (nv50->framebuffer.cbufs[i] && nv50->framebuffer.cbufs[i]->texture == res) { nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB); if (!--ref) return ref; } } } if (bind & PIPE_BIND_DEPTH_STENCIL) { if (nv50->framebuffer.zsbuf && nv50->framebuffer.zsbuf->texture == res) { nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB); if (!--ref) return ref; } } if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER | PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_STREAM_OUTPUT | PIPE_BIND_SAMPLER_VIEW)) { assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS); for (i = 0; i < nv50->num_vtxbufs; ++i) { if (nv50->vtxbuf[i].buffer == res) { nv50->dirty_3d |= NV50_NEW_3D_ARRAYS; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_VERTEX); if (!--ref) return ref; } } if (nv50->idxbuf.buffer == res) { /* Just rebind to the bufctx as there is no separate dirty bit */ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_INDEX); BCTX_REFN(nv50->bufctx_3d, 3D_INDEX, nv04_resource(res), RD); if (!--ref) return ref; } for (s = 0; s < 3; ++s) { assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS); for (i = 0; i < nv50->num_textures[s]; ++i) { if (nv50->textures[s][i] && nv50->textures[s][i]->texture == res) { nv50->dirty_3d |= NV50_NEW_3D_TEXTURES; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES); if (!--ref) return ref; } } } for (s = 0; s < 3; ++s) { for (i = 0; i < NV50_MAX_PIPE_CONSTBUFS; ++i) { if (!(nv50->constbuf_valid[s] & (1 << i))) continue; if (!nv50->constbuf[s][i].user && nv50->constbuf[s][i].u.buf == res) { nv50->dirty_3d |= NV50_NEW_3D_CONSTBUF; nv50->constbuf_dirty[s] |= 1 << i; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_CB(s, i)); if (!--ref) return ref; } } } } return ref; }