nouveau: downgrade hacked syncs to hacked flushes
Unfortunately we still need to keep the forced flushes as mesa's vbo path is still insane. But, at least this is a little less brutal. The bo code will detect when it needs to do a sync.
This commit is contained in:
@@ -205,6 +205,9 @@ nouveau_bo_del(struct nouveau_bo **userbo)
|
||||
if (--bo->refcount)
|
||||
return;
|
||||
|
||||
if (bo->fence)
|
||||
nouveau_fence_wait(&bo->fence);
|
||||
|
||||
nouveau_bo_realloc_gpu(bo, 0, 0);
|
||||
if (bo->sysmem && !bo->user)
|
||||
free(bo->sysmem);
|
||||
@@ -235,13 +238,15 @@ nouveau_bo_unmap(struct nouveau_bo *userbo)
|
||||
static int
|
||||
nouveau_bo_upload(struct nouveau_bo_priv *bo)
|
||||
{
|
||||
if (bo->fence)
|
||||
nouveau_fence_wait(&bo->fence);
|
||||
memcpy(bo->map, bo->sysmem, bo->drm.size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo,
|
||||
uint32_t flags)
|
||||
struct nouveau_fence *fence, uint32_t flags)
|
||||
{
|
||||
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
|
||||
|
||||
@@ -249,14 +254,23 @@ nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo,
|
||||
nouveau_bo_realloc_gpu(nvbo, flags, nvbo->base.size);
|
||||
nouveau_bo_upload(nvbo);
|
||||
} else
|
||||
if (nvbo->user || nvbo->base.map)
|
||||
if (nvbo->user) {
|
||||
nouveau_bo_upload(nvbo);
|
||||
} else
|
||||
if (nvbo->base.map) {
|
||||
nouveau_bo_upload(nvbo);
|
||||
nvbo->sync_hack = 1;
|
||||
}
|
||||
|
||||
if (!nvbo->user && !nvbo->base.map) {
|
||||
free(nvbo->sysmem);
|
||||
nvbo->sysmem = NULL;
|
||||
}
|
||||
|
||||
if (nvbo->fence)
|
||||
nouveau_fence_del(&nvbo->fence);
|
||||
nouveau_fence_ref(fence, &nvbo->fence);
|
||||
|
||||
nvbo->base.offset = nvbo->drm.offset;
|
||||
if (nvbo->drm.flags & NOUVEAU_MEM_AGP)
|
||||
nvbo->base.flags = NOUVEAU_BO_GART;
|
||||
|
||||
@@ -155,7 +155,6 @@ nouveau_dma_kickoff(struct nouveau_channel *userchan)
|
||||
if ((chan->pushbuf[i] & 0xf0000000) == 0x20000000) {
|
||||
int n = (((chan->pushbuf[i] & 0x0fffffff) -
|
||||
chan->dma.base) / 4);
|
||||
|
||||
do {
|
||||
NOUVEAU_MSG("\t0x%08x 0x%08x\n",
|
||||
(n<<2)+chan->dma.base,
|
||||
|
||||
@@ -243,6 +243,7 @@ struct nouveau_bo_priv {
|
||||
int user;
|
||||
|
||||
int refcount;
|
||||
int sync_hack;
|
||||
};
|
||||
#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n))
|
||||
|
||||
@@ -277,7 +278,7 @@ nouveau_bo_unmap(struct nouveau_bo *);
|
||||
|
||||
extern int
|
||||
nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *,
|
||||
uint32_t flags);
|
||||
struct nouveau_fence *fence, uint32_t flags);
|
||||
|
||||
extern int
|
||||
nouveau_resource_init(struct nouveau_resource **heap, int size);
|
||||
|
||||
@@ -55,6 +55,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
|
||||
struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
|
||||
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(nvchan->pb_tail);
|
||||
struct nouveau_pushbuf_bo *pbbo;
|
||||
struct nouveau_fence *fence = NULL;
|
||||
int sync_hack = 0;
|
||||
int ret;
|
||||
|
||||
if (!nvpb)
|
||||
@@ -63,7 +65,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
|
||||
if (nvpb->base.remaining == nvpb->res->size / 4)
|
||||
return 0;
|
||||
|
||||
ret = nouveau_fence_new(chan, &nvpb->fence);
|
||||
ret = nouveau_fence_new(chan, &fence);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -72,9 +74,12 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
|
||||
struct nouveau_pushbuf_reloc *r;
|
||||
struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base;
|
||||
|
||||
ret = nouveau_bo_validate(chan, bo, pbbo->flags);
|
||||
ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags);
|
||||
assert (ret == 0);
|
||||
|
||||
sync_hack |= nouveau_bo(bo)->sync_hack;
|
||||
nouveau_bo(bo)->sync_hack = 0;
|
||||
|
||||
while ((r = ptr_to_pbrel(pbbo->relocs))) {
|
||||
uint32_t push;
|
||||
|
||||
@@ -108,6 +113,9 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
|
||||
if (nvchan->dma.free < 1)
|
||||
WAIT_RING_CH(chan, 1);
|
||||
nvchan->dma.free -= 1;
|
||||
#ifdef NOUVEAU_DMA_DEBUG
|
||||
nvchan->dma.push_free = 1;
|
||||
#endif
|
||||
OUT_RING_CH(chan, 0x20000000 | (nvpb->res->start + 4096));
|
||||
|
||||
/* Add JMP back to master pushbuf from indirect pushbuf */
|
||||
@@ -115,6 +123,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
|
||||
0x20000000 | ((nvchan->dma.cur << 2) + nvchan->dma.base);
|
||||
|
||||
/* Fence */
|
||||
nvpb->fence = fence;
|
||||
nouveau_fence_emit(nvpb->fence);
|
||||
|
||||
/* Kickoff */
|
||||
@@ -173,12 +182,18 @@ out_realloc:
|
||||
nvpb->base.cur = &nvchan->pushbuf[(nvpb->res->start + 4096)/4];
|
||||
|
||||
if (nvchan->pb_tail) {
|
||||
nouveau_pushbuf(nvchan->pb_tail)->next = & nvpb->base;
|
||||
nouveau_pushbuf(nvchan->pb_tail)->next = &nvpb->base;
|
||||
} else {
|
||||
nvchan->pb_head = &nvpb->base;
|
||||
}
|
||||
nvchan->pb_tail = &nvpb->base;
|
||||
|
||||
if (sync_hack) {
|
||||
struct nouveau_fence *f = NULL;
|
||||
nouveau_fence_ref(nvpb->fence, &f);
|
||||
nouveau_fence_wait(&f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,13 +116,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
|
||||
static void
|
||||
nv04_surface_copy_done(struct nouveau_context *nv)
|
||||
{
|
||||
nouveau_notifier_reset(nv->sync_notifier, 0);
|
||||
BEGIN_RING(NvGdiRect, 0x104, 1);
|
||||
OUT_RING (0);
|
||||
BEGIN_RING(NvGdiRect, 0x100, 1);
|
||||
OUT_RING (0);
|
||||
FIRE_RING();
|
||||
nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -160,14 +154,7 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
|
||||
OUT_RING ((dx << 16) | dy);
|
||||
OUT_RING (( w << 16) | h);
|
||||
|
||||
nouveau_notifier_reset(nv->sync_notifier, 0);
|
||||
BEGIN_RING(NvGdiRect, 0x104, 1);
|
||||
OUT_RING (0);
|
||||
BEGIN_RING(NvGdiRect, 0x100, 1);
|
||||
OUT_RING (0);
|
||||
FIRE_RING();
|
||||
nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,13 +82,7 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
|
||||
static void
|
||||
nv50_surface_copy_done(struct nouveau_context *nv)
|
||||
{
|
||||
nouveau_notifier_reset(nv->sync_notifier, 0);
|
||||
BEGIN_RING(Nv2D, 0x104, 1);
|
||||
OUT_RING (0);
|
||||
BEGIN_RING(Nv2D, 0x100, 1);
|
||||
OUT_RING (0);
|
||||
FIRE_RING();
|
||||
nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -134,13 +128,7 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
|
||||
OUT_RING (dx + w);
|
||||
OUT_RING (dy + h);
|
||||
|
||||
nouveau_notifier_reset(nv->sync_notifier, 0);
|
||||
BEGIN_RING(Nv2D, 0x104, 1);
|
||||
OUT_RING (0);
|
||||
BEGIN_RING(Nv2D, 0x100, 1);
|
||||
OUT_RING (0);
|
||||
FIRE_RING();
|
||||
nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
|
||||
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
|
||||
OUT_RING (0);
|
||||
|
||||
pipe->flush(pipe, PIPE_FLUSH_WAIT);
|
||||
pipe->flush(pipe, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ nv40_draw_elements(struct pipe_context *pipe,
|
||||
OUT_RING (0);
|
||||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, ib);
|
||||
pipe->flush(pipe, PIPE_FLUSH_WAIT);
|
||||
pipe->flush(pipe, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user