mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
Fix fencing when submitting empty batchbuffers.
Add a proper buffer waitidle method.
This commit is contained in:
parent
0d646ea3a8
commit
8c58a32360
9 changed files with 76 additions and 30 deletions
|
|
@ -79,7 +79,7 @@ bmError(int val, const char *file, const char *function, int line)
|
|||
"Detected in file %s, line %d, function %s.\n",
|
||||
strerror(-val), file, line, function);
|
||||
#ifndef NDEBUG
|
||||
exit(-1);
|
||||
abort();
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
|
|
@ -109,6 +109,19 @@ driFenceBuffers(int fd, char *name, unsigned flags)
|
|||
}
|
||||
|
||||
|
||||
unsigned
|
||||
driFenceType(DriFenceObject * fence)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
_glthread_LOCK_MUTEX(bmMutex);
|
||||
ret = fence->fence.flags;
|
||||
_glthread_UNLOCK_MUTEX(bmMutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
driFenceReference(DriFenceObject * fence)
|
||||
{
|
||||
|
|
@ -159,6 +172,7 @@ driFenceSignaled(DriFenceObject * fence, unsigned type)
|
|||
return signaled;
|
||||
}
|
||||
|
||||
|
||||
extern drmBO *
|
||||
driBOKernel(struct _DriBufferObject *buf)
|
||||
{
|
||||
|
|
@ -172,6 +186,16 @@ driBOKernel(struct _DriBufferObject *buf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
driBOWaitIdle(struct _DriBufferObject *buf, int lazy)
|
||||
{
|
||||
assert(buf->private != NULL);
|
||||
|
||||
_glthread_LOCK_MUTEX(buf->mutex);
|
||||
BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy));
|
||||
_glthread_UNLOCK_MUTEX(buf->mutex);
|
||||
}
|
||||
|
||||
void *
|
||||
driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ extern void
|
|||
driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy);
|
||||
|
||||
extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type);
|
||||
extern unsigned driFenceType(struct _DriFenceObject *fence);
|
||||
|
||||
/*
|
||||
* Return a pointer to the libdrm buffer object this DriBufferObject
|
||||
|
|
@ -92,5 +93,7 @@ extern void driPoolTakeDown(struct _DriBufferPool *pool);
|
|||
extern void driBOSetStatic(struct _DriBufferObject *buf,
|
||||
unsigned long offset,
|
||||
unsigned long size, void *virtual, unsigned flags);
|
||||
extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ typedef struct _DriBufferPool
|
|||
int (*validate) (struct _DriBufferPool * pool, void *private);
|
||||
void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset,
|
||||
unsigned long size, void *virtual, unsigned flags);
|
||||
int (*waitIdle) (struct _DriBufferPool *pool, void *private,
|
||||
int lazy);
|
||||
void (*takeDown) (struct _DriBufferPool * pool);
|
||||
void *data;
|
||||
} DriBufferPool;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,15 @@ pool_kernel(struct _DriBufferPool *pool, void *private)
|
|||
return (drmBO *) private;
|
||||
}
|
||||
|
||||
void
|
||||
static int
|
||||
pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy)
|
||||
{
|
||||
drmBO *buf = (drmBO *) private;
|
||||
return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pool_takedown(struct _DriBufferPool *pool)
|
||||
{
|
||||
free(pool);
|
||||
|
|
@ -153,6 +161,7 @@ driDRMPoolInit(int fd)
|
|||
pool->kernel = &pool_kernel;
|
||||
pool->validate = NULL;
|
||||
pool->setstatic = NULL;
|
||||
pool->waitIdle = &pool_waitIdle;
|
||||
pool->takeDown = &pool_takedown;
|
||||
pool->data = NULL;
|
||||
return pool;
|
||||
|
|
@ -205,6 +214,7 @@ driDRMStaticPoolInit(int fd)
|
|||
pool->kernel = &pool_kernel;
|
||||
pool->validate = NULL;
|
||||
pool->setstatic = &pool_setstatic;
|
||||
pool->waitIdle = &pool_waitIdle;
|
||||
pool->takeDown = &pool_takedown;
|
||||
pool->data = NULL;
|
||||
return pool;
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ do_flush_locked(struct intel_batchbuffer *batch,
|
|||
GLuint i;
|
||||
struct intel_context *intel = batch->intel;
|
||||
unsigned fenceFlags;
|
||||
struct _DriFenceObject *fo;
|
||||
|
||||
driBOValidateList(batch->intel->driFd, &batch->list);
|
||||
|
||||
|
|
@ -189,23 +190,6 @@ do_flush_locked(struct intel_batchbuffer *batch,
|
|||
driBOUnmap(batch->buffer);
|
||||
batch->map = NULL;
|
||||
|
||||
/* Fire the batch buffer, which was uploaded above:
|
||||
*/
|
||||
|
||||
#if 0
|
||||
{
|
||||
void *iterator = drmBOListIterator(&batch->list);
|
||||
|
||||
_mesa_printf("\n");
|
||||
while (iterator != NULL) {
|
||||
_mesa_printf("0x%08x\n", drmBOListBuf(iterator)->offset);
|
||||
iterator = drmBOListNext(&batch->list, iterator);
|
||||
}
|
||||
_mesa_printf("Submitting 0x%08x\n", driBOOffset(batch->buffer));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Throw away non-effective packets. Won't work once we have
|
||||
* hardware contexts which would preserve statechanges beyond a
|
||||
* single buffer.
|
||||
|
|
@ -217,7 +201,6 @@ do_flush_locked(struct intel_batchbuffer *batch,
|
|||
used, ignore_cliprects, allow_unlock);
|
||||
}
|
||||
|
||||
driFenceUnReference(batch->last_fence);
|
||||
|
||||
/*
|
||||
* Kernel fencing. The flags tells the kernel that we've
|
||||
|
|
@ -225,19 +208,32 @@ do_flush_locked(struct intel_batchbuffer *batch,
|
|||
*/
|
||||
|
||||
fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED;
|
||||
batch->last_fence = driFenceBuffers(batch->intel->driFd,
|
||||
"Batch fence", fenceFlags);
|
||||
fo = driFenceBuffers(batch->intel->driFd,
|
||||
"Batch fence", fenceFlags);
|
||||
|
||||
/*
|
||||
* User space fencing.
|
||||
*/
|
||||
|
||||
driBOFence(batch->buffer, batch->last_fence);
|
||||
driBOFence(batch->buffer, fo);
|
||||
for (i = 0; i < batch->nr_relocs; i++) {
|
||||
struct buffer_reloc *r = &batch->reloc[i];
|
||||
driBOFence(r->buf, batch->last_fence);
|
||||
}
|
||||
|
||||
if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) {
|
||||
|
||||
/*
|
||||
* Oops. We only validated a batch buffer. This means we
|
||||
* didn't do any proper rendering. Discard this fence object.
|
||||
*/
|
||||
|
||||
driFenceUnReference(fo);
|
||||
} else {
|
||||
driFenceUnReference(batch->last_fence);
|
||||
batch->last_fence = fo;
|
||||
}
|
||||
|
||||
if (intel->numClipRects == 0 && !ignore_cliprects) {
|
||||
if (allow_unlock) {
|
||||
UNLOCK_HARDWARE(intel);
|
||||
|
|
|
|||
|
|
@ -277,6 +277,13 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy)
|
||||
{
|
||||
BBuf *buf = (BBuf *) private;
|
||||
driFenceFinish(buf->fence, 0, lazy);
|
||||
}
|
||||
|
||||
static int
|
||||
pool_unmap(struct _DriBufferPool *pool, void *private)
|
||||
{
|
||||
|
|
@ -400,6 +407,7 @@ driBatchPoolInit(int fd, unsigned flags,
|
|||
pool->fence = &pool_fence;
|
||||
pool->kernel = &pool_kernel;
|
||||
pool->validate = &pool_validate;
|
||||
pool->waitIdle = &pool_waitIdle;
|
||||
pool->setstatic = NULL;
|
||||
pool->takeDown = &pool_takedown;
|
||||
return pool;
|
||||
|
|
|
|||
|
|
@ -696,9 +696,8 @@ void
|
|||
intelSwapBuffers(__DRIdrawablePrivate * dPriv)
|
||||
{
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
struct intel_context *intel =
|
||||
(struct intel_context *) dPriv->driContextPriv->driverPrivate;
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
intelScreenPrivate *screen = intel->intelScreen;
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ intelFinish(GLcontext * ctx)
|
|||
intelFlush(ctx);
|
||||
if (intel->batch->last_fence) {
|
||||
driFenceFinish(intel->batch->last_fence,
|
||||
DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE);
|
||||
0, GL_FALSE);
|
||||
driFenceUnReference(intel->batch->last_fence);
|
||||
intel->batch->last_fence = NULL;
|
||||
}
|
||||
|
|
@ -575,6 +575,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
|
|||
intel->Fallback = 0; /* don't call _swrast_Flush later */
|
||||
|
||||
intel_batchbuffer_free(intel->batch);
|
||||
|
||||
if (intel->last_swap_fence) {
|
||||
driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
|
||||
driFenceUnReference(intel->last_swap_fence);
|
||||
|
|
@ -713,7 +714,11 @@ intelGetLock(struct intel_context *intel, GLuint flags)
|
|||
sarea->rotation != intelScreen->current_rotation) {
|
||||
intelUpdateScreenRotation(intel, sPriv, sarea);
|
||||
|
||||
/* This will drop the outstanding batchbuffer on the floor */
|
||||
/*
|
||||
* This will drop the outstanding batchbuffer on the floor
|
||||
* FIXME: This should be done for all contexts?
|
||||
*/
|
||||
|
||||
intel_batchbuffer_reset(intel->batch);
|
||||
|
||||
/* lose all primitives */
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ void
|
|||
intel_region_idle(struct intel_context *intel, struct intel_region *region)
|
||||
{
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
if (driBOMap(region->buffer, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0))
|
||||
driBOUnmap(region->buffer);
|
||||
driBOWaitIdle(region->buffer, GL_FALSE);
|
||||
}
|
||||
|
||||
/* XXX: Thread safety?
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue