summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0/nvc0_context.c
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-01-08 16:13:11 +0100
committerChristoph Bumiller <[email protected]>2013-01-08 16:13:51 +0100
commit48a45ec24ae74c00d1487552e94d9f824a428f58 (patch)
treec2a160cb708b7a05f3340d889d6a0e676eb9d727 /src/gallium/drivers/nvc0/nvc0_context.c
parenta75ddfd55d24363046f11b2fd2de25563698fa39 (diff)
nouveau: improve buffer transfers
Save double memcpy on uploads to VRAM in most cases. Properly handle FLUSH_EXPLICIT. Reallocate on DISCARD_WHOLE_RESOURCE to avoid sync.
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_context.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index 6325ac859f4..23059a097b9 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -43,6 +43,8 @@ nvc0_flush(struct pipe_context *pipe,
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
+
+ nouveau_context_update_frame_stats(&nvc0->base);
}
static void
@@ -116,6 +118,87 @@ nvc0_default_kick_notify(struct nouveau_pushbuf *push)
}
}
+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) {
+ 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 (res->bind & PIPE_BIND_INDEX_BUFFER) {
+ if (nvc0->idxbuf.buffer == res) {
+ nvc0->dirty |= NVC0_NEW_IDXBUF;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX);
+ if (!--ref)
+ return ref;
+ }
+ }
+
+ if (res->bind & PIPE_BIND_SAMPLER_VIEW) {
+ 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;
+ }
+ }
+ }
+ }
+
+ if (res->bind & PIPE_BIND_CONSTANT_BUFFER) {
+ for (s = 0; s < 5; ++s) {
+ for (i = 0; i < nvc0->num_vtxbufs; ++i) {
+ 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;
+}
+
struct pipe_context *
nvc0_create(struct pipe_screen *pscreen, void *priv)
{
@@ -134,6 +217,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
goto out_err;
nvc0->base.pushbuf = screen->base.pushbuf;
+ nvc0->base.client = screen->base.client;
ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
&nvc0->bufctx_3d);
@@ -168,6 +252,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
nvc0_init_transfer_functions(nvc0);
nvc0_init_resource_functions(pipe);
+ nvc0->base.invalidate_resource_storage = nvc0_invalidate_resource_storage;
+
#ifdef NVC0_WITH_DRAW_MODULE
/* no software fallbacks implemented */
nvc0->draw = draw_create(pipe);