aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2011-02-24 17:04:49 +0100
committerChristoph Bumiller <[email protected]>2011-02-24 17:35:35 +0100
commit67c7aefea33a7935e42ede30463eb7ca5009b068 (patch)
treea1f83b80dcdf33a0b6c3cc04dce01110856c4b34 /src/gallium/drivers/nvc0
parenta6ea37da4bd02241ce3bf522b93dd7ff0757f959 (diff)
nvc0: sync textures with render targets ourselves
Fixes for example piglit/fbo-flushing and nexuiz' bloom effect.
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_buffer.c6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.h5
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h5
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c16
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_winsys.h2
6 files changed, 35 insertions, 6 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c
index f16671ac7ff..aa949bdfa36 100644
--- a/src/gallium/drivers/nvc0/nvc0_buffer.c
+++ b/src/gallium/drivers/nvc0/nvc0_buffer.c
@@ -117,7 +117,7 @@ nvc0_buffer_download(struct nvc0_context *nvc0, struct nvc0_resource *buf,
memcpy(buf->data + start, bounce->map, size);
nouveau_bo_unmap(bounce);
- buf->status &= ~NVC0_BUFFER_STATUS_DIRTY;
+ buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
nouveau_bo_ref(NULL, &bounce);
if (mm)
@@ -156,7 +156,7 @@ nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf,
release_allocation(&mm, nvc0->screen->fence.current);
if (start == 0 && size == buf->base.width0)
- buf->status &= ~NVC0_BUFFER_STATUS_DIRTY;
+ buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
return TRUE;
}
@@ -179,7 +179,7 @@ nvc0_buffer_transfer_get(struct pipe_context *pipe,
if (buf->domain == NOUVEAU_BO_VRAM) {
if (usage & PIPE_TRANSFER_READ) {
- if (buf->status & NVC0_BUFFER_STATUS_DIRTY)
+ if (buf->status & NVC0_BUFFER_STATUS_GPU_WRITING)
nvc0_buffer_download(nvc0_context(pipe), buf, 0, buf->base.width0);
}
}
diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h
index 709e6157f55..599823c0dc9 100644
--- a/src/gallium/drivers/nvc0/nvc0_resource.h
+++ b/src/gallium/drivers/nvc0/nvc0_resource.h
@@ -24,7 +24,8 @@ struct nvc0_context;
* USER_MEMORY: resource->data is a pointer to client memory and may change
* between GL calls
*/
-#define NVC0_BUFFER_STATUS_DIRTY (1 << 0)
+#define NVC0_BUFFER_STATUS_GPU_READING (1 << 0)
+#define NVC0_BUFFER_STATUS_GPU_WRITING (1 << 1)
#define NVC0_BUFFER_STATUS_USER_MEMORY (1 << 7)
/* Resources, if mapped into the GPU's address space, are guaranteed to
@@ -90,7 +91,7 @@ nvc0_resource_map_offset(struct nvc0_context *nvc0,
nvc0_buffer_adjust_score(nvc0, res, -250);
if ((res->domain == NOUVEAU_BO_VRAM) &&
- (res->status & NVC0_BUFFER_STATUS_DIRTY))
+ (res->status & NVC0_BUFFER_STATUS_GPU_WRITING))
nvc0_buffer_download(nvc0, res, 0, res->base.width0);
if ((res->domain != NOUVEAU_BO_GART) ||
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 5af96cbacea..d952ff1f9b1 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -131,6 +131,11 @@ nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags)
if (likely(res->bo)) {
nouveau_bo_validate(screen->base.channel, res->bo, flags);
+ if (flags & NOUVEAU_BO_WR)
+ res->status |= NVC0_BUFFER_STATUS_GPU_WRITING;
+ if (flags & NOUVEAU_BO_RD)
+ res->status |= NVC0_BUFFER_STATUS_GPU_READING;
+
nvc0_resource_fence(res, flags);
}
}
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 96c1198d4cb..0cc0a0c6236 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -58,6 +58,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
struct nouveau_channel *chan = nvc0->screen->base.channel;
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
unsigned i;
+ boolean serialize = FALSE;
nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME);
@@ -86,6 +87,11 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
OUT_RING (chan, sf->depth);
OUT_RING (chan, mt->layer_stride >> 2);
+ if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING)
+ serialize = TRUE;
+ mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING;
+ mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING;
+
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
}
@@ -111,12 +117,22 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
OUT_RING (chan, sf->height);
OUT_RING (chan, (unk << 16) | sf->depth);
+ if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING)
+ serialize = TRUE;
+ mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING;
+ mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING;
+
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
} else {
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
OUT_RING (chan, 0);
}
+
+ if (serialize) {
+ BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
+ OUT_RING (chan, 0);
+ }
}
static void
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index b219f82c903..968558a5869 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -196,9 +196,16 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
OUT_RINGp (chan, &tic->tic[3], 5);
need_flush = TRUE;
+ } else
+ if (res->status & NVC0_BUFFER_STATUS_GPU_WRITING) {
+ BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
+ OUT_RING (chan, (tic->id << 4) | 1);
}
nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
+ res->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
+ res->status |= NVC0_BUFFER_STATUS_GPU_READING;
+
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res,
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h
index 1544fb7a1de..45f71967eff 100644
--- a/src/gallium/drivers/nvc0/nvc0_winsys.h
+++ b/src/gallium/drivers/nvc0/nvc0_winsys.h
@@ -95,7 +95,7 @@ OUT_RESRCl(struct nouveau_channel *chan, struct nvc0_resource *res,
unsigned delta, unsigned flags)
{
if (flags & NOUVEAU_BO_WR)
- res->status |= NVC0_BUFFER_STATUS_DIRTY;
+ res->status |= NVC0_BUFFER_STATUS_GPU_WRITING;
return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
}