Fix fencing when submitting empty batchbuffers.

Add a proper buffer waitidle method.
This commit is contained in:
Thomas Hellström 2006-09-18 14:11:00 +00:00
parent 0d646ea3a8
commit 8c58a32360
9 changed files with 76 additions and 30 deletions

View file

@ -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)
{

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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?