The maximum number of "commands" that can be queued at once is fixed at
compile time at MAX_RELOCS. However, during the creation of an image
object in qxl_image_create(), the image is split into commands of
maximum size 512*512. For a large dual-head system, it is easy to create
an image for which the number of chunks will result in an overflow of
MAX_RELOCS number of "commands".
Identify this scenario and dynamically increase the chunk size to avoid
the overflow, and the resulting assert() which crashes Xorg.
Note: the debugging statement is currently enabled in this patch.
diff -r -u xf86-video-qxl-0.1.1.orig/src/qxl_image.c xf86-video-qxl-0.1.1/src/qxl_image.c
--- xf86-video-qxl-0.1.1.orig/src/qxl_image.c 2013-10-20 10:53:29.000000000 -0400
+++ xf86-video-qxl-0.1.1/src/qxl_image.c 2014-05-14 09:10:43.435444196 -0400
@@ -140,6 +140,7 @@
struct qxl_bo *image_bo;
int dest_stride = (width * Bpp + 3) & (~3);
int h;
+ int chunk_size;
data += y * stride + x * Bpp;
@@ -155,9 +156,23 @@
hash = 0;
h = height;
+
+ chunk_size = MAX (512 * 512, dest_stride);
+
+ /* ensure we will not create too many pieces and overflow
+ * the command buffer (MAX_RELOCS). if so, increase the chunk_size.
+ * each loop creates at least 2 cmd buffer entries, and
+ * we have to leave room when we're done.
+ */
+ if (height / (chunk_size / dest_stride) > (MAX_RELOCS / 4)) {
+ chunk_size = height / (MAX_RELOCS/4) * dest_stride;
+#if 1
+ ErrorF ("adjusted chunk_size to %d\n", chunk_size);
+#endif
+ }
+
while (h)
{
- int chunk_size = MAX (512 * 512, dest_stride);
int n_lines = MIN ((chunk_size / dest_stride), h);
struct qxl_bo *bo = qxl->bo_funcs->bo_alloc (qxl, sizeof (QXLDataChunk) + n_lines * dest_stride, "image data");
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel