xf86-video-intel: xvmc/i915_xvmc.c xvmc/i965_xvmc.c xvmc/intel_batchbuffer.c xvmc/intel_batchbuffer.h xvmc/intel_xvmc.c xvmc/xvmc_vld.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Nov 11 07:07:47 PST 2013


 xvmc/i915_xvmc.c         |    2 -
 xvmc/i965_xvmc.c         |    2 -
 xvmc/intel_batchbuffer.c |   60 +++++++++++++++++++++++------------------------
 xvmc/intel_batchbuffer.h |    4 ---
 xvmc/intel_xvmc.c        |   16 +++++++++++-
 xvmc/xvmc_vld.c          |    4 +--
 6 files changed, 50 insertions(+), 38 deletions(-)

New commits:
commit c489934ed732ed3d5a906939381c62a6bc1c38d5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 11 14:56:22 2013 +0000

    xvmc: Handle allocation failure around batch submission
    
    If we fail to allocate a new batch, just stall and reuse the old one
    rather than crashing.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/xvmc/i915_xvmc.c b/xvmc/i915_xvmc.c
index fbd4555..204d950 100644
--- a/xvmc/i915_xvmc.c
+++ b/xvmc/i915_xvmc.c
@@ -1207,7 +1207,7 @@ static int i915_xvmc_mc_render_surface(Display * display, XvMCContext * context,
 		}
 	}
 
-	intelFlushBatch(TRUE);
+	intelFlushBatch();
 
 	i915_xvmc_free_render_state_buffers(pI915XvMC);
 
diff --git a/xvmc/i965_xvmc.c b/xvmc/i965_xvmc.c
index 1850480..198027f 100644
--- a/xvmc/i965_xvmc.c
+++ b/xvmc/i965_xvmc.c
@@ -841,7 +841,7 @@ static Status render_surface(Display * display,
 				}
 			}
 		}
-		intelFlushBatch(TRUE);
+		intelFlushBatch();
 		UNLOCK_HARDWARE(intel_ctx->hw_context);
 	}
 	return Success;
diff --git a/xvmc/intel_batchbuffer.c b/xvmc/intel_batchbuffer.c
index 3fa16bb..b427d85 100644
--- a/xvmc/intel_batchbuffer.c
+++ b/xvmc/intel_batchbuffer.c
@@ -62,6 +62,15 @@ static void i965_end_batch(void)
 	xvmc_driver->batch.ptr += 4;
 }
 
+static void reset_batch(void)
+{
+	dri_bo *bo = xvmc_driver->batch.buf;
+
+	xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr = bo->virtual;
+	xvmc_driver->batch.size = bo->size;
+	xvmc_driver->batch.space = bo->size - 8;
+}
+
 Bool intelInitBatchBuffer(void)
 {
 	if ((xvmc_driver->batch.buf =
@@ -71,59 +80,50 @@ Bool intelInitBatchBuffer(void)
 		return False;
 	}
 
-	drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);
+	if (drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf)) {
+		drm_intel_bo_unreference(xvmc_driver->batch.buf);
+		return False;
+	}
 
-	xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual;
-	xvmc_driver->batch.size = BATCH_SIZE;
-	xvmc_driver->batch.space = BATCH_SIZE;
-	xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr;
+	reset_batch();
 	return True;
 }
 
 void intelFiniBatchBuffer(void)
 {
-	drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf);
+	if (xvmc_driver->batch.buf == NULL)
+		return;
 
 	drm_intel_bo_unreference(xvmc_driver->batch.buf);
 }
 
-void intelFlushBatch(Bool refill)
+void intelFlushBatch(void)
 {
-	i965_end_batch();
+	dri_bo *bo;
 
-	drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf);
+	i965_end_batch();
 
 	drm_intel_bo_exec(xvmc_driver->batch.buf,
 			  xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr,
 			  0, 0, 0);
 
-	drm_intel_bo_unreference(xvmc_driver->batch.buf);
-	if ((xvmc_driver->batch.buf =
-	     drm_intel_bo_alloc(xvmc_driver->bufmgr,
-				"batch buffer", BATCH_SIZE, 0x1000)) == NULL) {
-		fprintf(stderr, "unable to alloc batch buffer\n");
+	bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
+				"batch buffer", BATCH_SIZE, 0x1000);
+	if (bo != NULL && drm_intel_gem_bo_map_gtt(bo) == 0) {
+		drm_intel_bo_unreference(xvmc_driver->batch.buf);
+		xvmc_driver->batch.buf = bo;
+	} else {
+		if (bo != NULL)
+			drm_intel_bo_unreference(bo);
+		drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);
 	}
 
-	drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);
-
-	xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual;
-	xvmc_driver->batch.size = BATCH_SIZE;
-	xvmc_driver->batch.space = BATCH_SIZE;
-	xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr;
-}
-
-void intelBatchbufferRequireSpace(int size)
-{
-	assert(xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size <
-	       xvmc_driver->batch.size - 8);
-	if (xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size
-	    >= xvmc_driver->batch.size - 8)
-		intelFlushBatch(1);
+	reset_batch();
 }
 
 void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
 {
-	intelBatchbufferRequireSpace(bytes);
+	assert(bytes <= xvmc_driver->batch.space);
 	memcpy(xvmc_driver->batch.ptr, data, bytes);
 	xvmc_driver->batch.ptr += bytes;
 	xvmc_driver->batch.space -= bytes;
diff --git a/xvmc/intel_batchbuffer.h b/xvmc/intel_batchbuffer.h
index 7fae6f7..c63ee5e 100644
--- a/xvmc/intel_batchbuffer.h
+++ b/xvmc/intel_batchbuffer.h
@@ -11,8 +11,6 @@ extern int VERBOSE;
 #define BEGIN_BATCH(n)                                                  \
     do {                                                                \
 	assert(xvmc_driver->batch.space >= (n) *4);			\
-        if (xvmc_driver->batch.space < (n)*4)                           \
-            intelFlushBatch(TRUE);                            		\
         batch_ptr = xvmc_driver->batch.ptr;                             \
     } while (0)
 
@@ -46,7 +44,7 @@ extern int VERBOSE;
         xvmc_driver->batch.ptr = batch_ptr;                              \
     } while(0)
 
-extern void intelFlushBatch(Bool);
+extern void intelFlushBatch(void);
 extern void intelBatchbufferData(const void *, unsigned, unsigned);
 extern Bool intelInitBatchBuffer(void);
 extern void intelFiniBatchBuffer(void);
diff --git a/xvmc/intel_xvmc.c b/xvmc/intel_xvmc.c
index ff13d03..2a2c8b9 100644
--- a/xvmc/intel_xvmc.c
+++ b/xvmc/intel_xvmc.c
@@ -313,6 +313,16 @@ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port,
 	}
 	drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr);
 
+	if (!intelInitBatchBuffer()) {
+		XFree(priv_data);
+		context->privData = NULL;
+
+		dri_bufmgr_destroy(xvmc_driver->bufmgr);
+		xvmc_driver = NULL;
+
+		return BadAlloc;
+	}
+
 	/* call driver hook.
 	 * driver hook should free priv_data after return if success.*/
 	ret =
@@ -320,14 +330,18 @@ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port,
 					   priv_data);
 	if (ret) {
 		XVMC_ERR("driver create context failed\n");
+		intelFiniBatchBuffer();
+
 		XFree(priv_data);
 		context->privData = NULL;
+
+		dri_bufmgr_destroy(xvmc_driver->bufmgr);
 		xvmc_driver = NULL;
 		return ret;
 	}
 
+
 	pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
-	intelInitBatchBuffer();
 	intel_xvmc_dump_open();
 
 	return Success;
diff --git a/xvmc/xvmc_vld.c b/xvmc/xvmc_vld.c
index e576294..4c684ff 100644
--- a/xvmc/xvmc_vld.c
+++ b/xvmc/xvmc_vld.c
@@ -1010,7 +1010,7 @@ static Status put_slice2(Display * display, XvMCContext * context,
 	cs_buffer();
 	vld_send_media_object(media_state.slice_data.bo,
 			      nbytes, 0, mb_row, 6, 127, q_scale_code);
-	intelFlushBatch(TRUE);
+	intelFlushBatch();
 	UNLOCK_HARDWARE(intel_ctx->hw_context);
 
 	return Success;
@@ -1207,7 +1207,7 @@ static Status render_surface(Display * display,
 			}
 		}
 	}
-	intelFlushBatch(TRUE);
+	intelFlushBatch();
 	UNLOCK_HARDWARE(intel_ctx->hw_context);
 	return Success;
 }


More information about the xorg-commit mailing list