diff options
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_context.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 08e576a214e..b8b29a3b5d7 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -42,6 +42,8 @@ nv50_flush(struct pipe_context *pipe, nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); PUSH_KICK(screen->pushbuf); + + nouveau_context_update_frame_stats(nouveau_context(pipe)); } static void @@ -115,6 +117,83 @@ nv50_destroy(struct pipe_context *pipe) nouveau_context_destroy(&nv50->base); } +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 s, i; + + if (res->bind & PIPE_BIND_RENDER_TARGET) { + for (i = 0; i < nv50->framebuffer.nr_cbufs; ++i) { + if (nv50->framebuffer.cbufs[i] && + nv50->framebuffer.cbufs[i]->texture == res) { + nv50->dirty |= NV50_NEW_FRAMEBUFFER; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); + if (!--ref) + return ref; + } + } + } + if (res->bind & PIPE_BIND_DEPTH_STENCIL) { + if (nv50->framebuffer.zsbuf && + nv50->framebuffer.zsbuf->texture == res) { + nv50->dirty |= NV50_NEW_FRAMEBUFFER; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); + if (!--ref) + return ref; + } + } + + if (res->bind & PIPE_BIND_VERTEX_BUFFER) { + for (i = 0; i < nv50->num_vtxbufs; ++i) { + if (nv50->vtxbuf[i].buffer == res) { + nv50->dirty |= NV50_NEW_ARRAYS; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX); + if (!--ref) + return ref; + } + } + } + if (res->bind & PIPE_BIND_INDEX_BUFFER) { + if (nv50->idxbuf.buffer == res) + if (!--ref) + return ref; + } + + if (res->bind & PIPE_BIND_SAMPLER_VIEW) { + for (s = 0; s < 5; ++s) { + for (i = 0; i < nv50->num_textures[s]; ++i) { + if (nv50->textures[s][i] && + nv50->textures[s][i]->texture == res) { + nv50->dirty |= NV50_NEW_TEXTURES; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); + if (!--ref) + return ref; + } + } + } + } + + if (res->bind & PIPE_BIND_CONSTANT_BUFFER) { + for (s = 0; s < 5; ++s) { + for (i = 0; i < nv50->num_vtxbufs; ++i) { + if (!nv50->constbuf[s][i].user && + nv50->constbuf[s][i].u.buf == res) { + nv50->dirty |= NV50_NEW_CONSTBUF; + nv50->constbuf_dirty[s] |= 1 << i; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i)); + if (!--ref) + return ref; + } + } + } + } + + return ref; +} + struct pipe_context * nv50_create(struct pipe_screen *pscreen, void *priv) { @@ -133,6 +212,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv) goto out_err; nv50->base.pushbuf = screen->base.pushbuf; + nv50->base.client = screen->base.client; ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT, &nv50->bufctx_3d); @@ -168,6 +248,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50_init_state_functions(nv50); nv50_init_resource_functions(pipe); + nv50->base.invalidate_resource_storage = nv50_invalidate_resource_storage; + #ifdef NV50_WITH_DRAW_MODULE /* no software fallbacks implemented */ nv50->draw = draw_create(pipe); |