summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv30
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/nv30
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/nv30')
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c78
1 files changed, 77 insertions, 1 deletions
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index b0aee8d5755..66ffff350a1 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -59,7 +59,8 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
if (bref->flags & NOUVEAU_BO_WR) {
nouveau_fence_ref(screen->fence.current, &res->fence_wr);
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+ res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
+ NOUVEAU_BUFFER_STATUS_DIRTY;
}
}
}
@@ -78,6 +79,79 @@ nv30_context_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence,
(struct nouveau_fence **)fence);
PUSH_KICK(push);
+
+ nouveau_context_update_frame_stats(&nv30->base);
+}
+
+static int
+nv30_invalidate_resource_storage(struct nouveau_context *nv,
+ struct pipe_resource *res,
+ int ref)
+{
+ struct nv30_context *nv30 = nv30_context(&nv->pipe);
+ unsigned i;
+
+ if (res->bind & PIPE_BIND_RENDER_TARGET) {
+ for (i = 0; i < nv30->framebuffer.nr_cbufs; ++i) {
+ if (nv30->framebuffer.cbufs[i] &&
+ nv30->framebuffer.cbufs[i]->texture == res) {
+ nv30->dirty |= NV30_NEW_FRAMEBUFFER;
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);
+ if (!--ref)
+ return ref;
+ }
+ }
+ }
+ if (res->bind & PIPE_BIND_DEPTH_STENCIL) {
+ if (nv30->framebuffer.zsbuf &&
+ nv30->framebuffer.zsbuf->texture == res) {
+ nv30->dirty |= NV30_NEW_FRAMEBUFFER;
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);
+ if (!--ref)
+ return ref;
+ }
+ }
+
+ if (res->bind & PIPE_BIND_VERTEX_BUFFER) {
+ for (i = 0; i < nv30->num_vtxbufs; ++i) {
+ if (nv30->vtxbuf[i].buffer == res) {
+ nv30->dirty |= NV30_NEW_ARRAYS;
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
+ if (!--ref)
+ return ref;
+ }
+ }
+ }
+ if (res->bind & PIPE_BIND_INDEX_BUFFER) {
+ if (nv30->idxbuf.buffer == res) {
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_IDXBUF);
+ if (!--ref)
+ return ref;
+ }
+ }
+
+ if (res->bind & PIPE_BIND_SAMPLER_VIEW) {
+ for (i = 0; i < nv30->fragprog.num_textures; ++i) {
+ if (nv30->fragprog.textures[i] &&
+ nv30->fragprog.textures[i]->texture == res) {
+ nv30->dirty |= NV30_NEW_FRAGTEX;
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FRAGTEX(i));
+ if (!--ref)
+ return ref;
+ }
+ }
+ for (i = 0; i < nv30->vertprog.num_textures; ++i) {
+ if (nv30->vertprog.textures[i] &&
+ nv30->vertprog.textures[i]->texture == res) {
+ nv30->dirty |= NV30_NEW_VERTTEX;
+ nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VERTTEX(i));
+ if (!--ref)
+ return ref;
+ }
+ }
+ }
+
+ return ref;
}
static void
@@ -138,6 +212,8 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv)
nv30->base.pushbuf->rsvd_kick = 16; /* hack in screen before first space */
nv30->base.pushbuf->kick_notify = nv30_context_kick_notify;
+ nv30->base.invalidate_resource_storage = nv30_invalidate_resource_storage;
+
ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);
if (ret) {
nv30_context_destroy(pipe);