summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Hellström <thomas@tungstengraphics.com>2006-09-18 14:11:00 +0000
committerThomas Hellström <thomas@tungstengraphics.com>2006-09-18 14:11:00 +0000
commit8c58a32360b1e8591dbf2f28aa5b804892187f6a (patch)
tree7efa361cf38e810d8966abbe9a5617ce7d7d491b /src
parent0d646ea3a860bf3b456e3270b368a1b76729a380 (diff)
Fix fencing when submitting empty batchbuffers.
Add a proper buffer waitidle method.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.c26
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.h3
-rw-r--r--src/mesa/drivers/dri/common/dri_bufpool.h2
-rw-r--r--src/mesa/drivers/dri/common/dri_drmpool.c12
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.c38
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchpool.c8
-rw-r--r--src/mesa/drivers/dri/i915/intel_buffers.c5
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c9
-rw-r--r--src/mesa/drivers/dri/i915/intel_regions.c3
9 files changed, 76 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c
index db607a74cd..0387c7a927 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.c
@@ -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)
{
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h
index c742029135..0ee5867d2d 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.h
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.h
@@ -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
diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h
index 98b0d031b5..c6fb2c3ce0 100644
--- a/src/mesa/drivers/dri/common/dri_bufpool.h
+++ b/src/mesa/drivers/dri/common/dri_bufpool.h
@@ -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;
diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c
index 845b604784..e69a738b1c 100644
--- a/src/mesa/drivers/dri/common/dri_drmpool.c
+++ b/src/mesa/drivers/dri/common/dri_drmpool.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
index ee96fd8579..87969900b3 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i915/intel_batchpool.c b/src/mesa/drivers/dri/i915/intel_batchpool.c
index 1011e2f5ed..8f9a54470e 100644
--- a/src/mesa/drivers/dri/i915/intel_batchpool.c
+++ b/src/mesa/drivers/dri/i915/intel_batchpool.c
@@ -278,6 +278,13 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
}
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)
{
BBuf *buf = (BBuf *) 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;
diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c
index 8022f17b71..c84f141c8c 100644
--- a/src/mesa/drivers/dri/i915/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915/intel_buffers.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index a9e7c8db78..ed2580948c 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -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 */
diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c
index 12421c59e7..a86e70d053 100644
--- a/src/mesa/drivers/dri/i915/intel_regions.c
+++ b/src/mesa/drivers/dri/i915/intel_regions.c
@@ -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?