nvc0: sync textures with render targets ourselves
Fixes for example piglit/fbo-flushing and nexuiz' bloom effect.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) ||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user