> > Andrew, do you have anything hacked together for this yet?
> 
> Nope.  I gave up because I couldn't even get the mode to set. :)

Ok well you should be able to now. :)  Using the patchset I posted
earlier along with the two attached patches, the testdisplay program in
intel-gpu-tools will set a 30bpp mode and draw some nice gradients
(though without a 10bpc gamma ramp loaded).

> One issue was that the RandR apis aren't really designed for cards
> that can accept more than one gamma ramp size.  Someone (I forget who)
> suggested adding a display property to control it.  It might be
> possible to kill two birds with one stone by adding a property with
> two settings:
> 
>  - Low depth: the logic you implemented: the bit depth is set to match
> the framebuffer when possible and the gamma ramp size is set according
> to the framebuffer depth.
>  - High depth: the bit depth is set to the maximum that the encoder,
> connector, and monitor support at the requested resolution and the
> gamma ramp size is set to whatever gives the highest precision in each
> entry.

Well, I haven't implemented anything, gamma-wise.  If you select say
30bpp when you start X *and* you have a kernel with my patches applied,
you'll get 10bpc all the way out to the display if it supports it.  If
the display does *not* support 10bpc, the pipe will dither it to 8bpc
before sending it to the encoder.  Current DDX on an old kernel will
fail to create an FB with 10bpc because the kernel will reject it.

So I guess I don't understand your low vs high distinction; the bit
depth is ultimately tied to the framebuffer and its allocation.
Correction happens after the fact in hw when the plane feeds bits to the
pipe.

Of course that's all separate from the color correction that happens
before the bits get to the pipe.  For that we have to wait until the
DDX starts up and decides what to do.  In a 30bpp mode, I'd hope it
would default to using the 10 bit gamma ramp (1024 entries of 30 bits
each), which I think is what you had in mind?  For that, we'd just need
to check whether we can hand the kernel a 1024 entry table, then do it
if possible, otherwise fall back to the existing 256 entry code.

-- 
Jesse Barnes, Intel Open Source Technology Center
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index b8bdfd1..1aa5779 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -118,6 +118,7 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
 	width = image->width*2;
 	break;
     case CAIRO_FORMAT_RGB24:
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	width = image->width*4;
 	break;
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 7097fa4..15af007 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -101,6 +101,8 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
     switch (pixman_format) {
     case PIXMAN_a8r8g8b8:
 	return CAIRO_FORMAT_ARGB32;
+    case PIXMAN_x2b10g10r10:
+	return CAIRO_FORMAT_RGB30;
     case PIXMAN_x8r8g8b8:
 	return CAIRO_FORMAT_RGB24;
     case PIXMAN_a8:
@@ -122,7 +124,6 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
     case PIXMAN_yuy2:     case PIXMAN_yv12:
     case PIXMAN_b8g8r8x8:
     case PIXMAN_b8g8r8a8:
-    case PIXMAN_x2b10g10r10:
     case PIXMAN_a2b10g10r10:
     case PIXMAN_x2r10g10b10:
     case PIXMAN_a2r10g10b10:
@@ -300,6 +301,9 @@ _cairo_format_to_pixman_format_code (cairo_format_t format)
     case CAIRO_FORMAT_RGB24:
 	ret = PIXMAN_x8r8g8b8;
 	break;
+    case CAIRO_FORMAT_RGB30:
+	ret = PIXMAN_x2r10g10b10;
+	break;
     case CAIRO_FORMAT_RGB16_565:
 	ret = PIXMAN_r5g6b5;
 	break;
@@ -668,6 +672,8 @@ _cairo_content_from_format (cairo_format_t format)
     switch (format) {
     case CAIRO_FORMAT_ARGB32:
 	return CAIRO_CONTENT_COLOR_ALPHA;
+    case CAIRO_FORMAT_RGB30:
+	return CAIRO_CONTENT_COLOR;
     case CAIRO_FORMAT_RGB24:
 	return CAIRO_CONTENT_COLOR;
     case CAIRO_FORMAT_RGB16_565:
@@ -689,6 +695,8 @@ _cairo_format_bits_per_pixel (cairo_format_t format)
     switch (format) {
     case CAIRO_FORMAT_ARGB32:
 	return 32;
+    case CAIRO_FORMAT_RGB30:
+	return 32;
     case CAIRO_FORMAT_RGB24:
 	return 32;
     case CAIRO_FORMAT_RGB16_565:
@@ -1272,6 +1280,19 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
 	color.blue = expand_channel ((pixel & 0x1f) << 11, 5);
 	return pixman_image_create_solid_fill (&color);
 
+    case CAIRO_FORMAT_RGB30:
+	pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
+	if (pixel == 0)
+	    return _pixman_black_image ();
+	if (pixel == 0x3fffffff)
+	    return _pixman_white_image ();
+
+	color.alpha = 0xc0;
+	color.red = (pixel >> 20) & 0x3fff;
+	color.green = (pixel >> 10) & 0x3fff;
+	color.blue = pixel & 0x3fff;
+	return pixman_image_create_solid_fill (&color);
+
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_FORMAT_RGB24:
 	pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
diff --git a/src/cairo-png.c b/src/cairo-png.c
index f5c7cb5..e176043 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -241,6 +241,10 @@ write_png (cairo_surface_t	*surface,
 	else
 	    png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 	break;
+    case CAIRO_FORMAT_RGB30:
+	depth = 30;
+	png_color_type = PNG_COLOR_TYPE_RGB;
+	break;
     case CAIRO_FORMAT_RGB24:
 	depth = 8;
 	png_color_type = PNG_COLOR_TYPE_RGB;
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index dd60484..bef9c83 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -584,6 +584,7 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	    xrender_format = XRenderFindVisualFormat(display->display, visual);
 	    break;
 	}
+	case CAIRO_FORMAT_RGB30:
 	case CAIRO_FORMAT_INVALID:
 	default:
 	    ASSERT_NOT_REACHED;
diff --git a/src/cairo.h b/src/cairo.h
index 3495146..9632592 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -2251,6 +2251,7 @@ cairo_surface_has_show_text_glyphs (cairo_surface_t *surface);
  * @CAIRO_FORMAT_RGB16_565: each pixel is a 16-bit quantity
  *   with red in the upper 5 bits, then green in the middle
  *   6 bits, and blue in the lower 5 bits.
+ * @CAIRO_FORMAT_RGB30: like RGB24 but with 10bpc
  *
  * #cairo_format_t is used to identify the memory format of
  * image data.
@@ -2263,7 +2264,8 @@ typedef enum _cairo_format {
     CAIRO_FORMAT_RGB24     = 1,
     CAIRO_FORMAT_A8        = 2,
     CAIRO_FORMAT_A1        = 3,
-    CAIRO_FORMAT_RGB16_565 = 4
+    CAIRO_FORMAT_RGB16_565 = 4,
+    CAIRO_FORMAT_RGB30     = 5,
 } cairo_format_t;
 
 cairo_public cairo_surface_t *
diff --git a/src/cairoint.h b/src/cairoint.h
index 8d9bd44..efe9424 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1862,7 +1862,7 @@ _cairo_surface_release_device_reference (cairo_surface_t *surface);
  * in cairo-xlib-surface.c--again see -Wswitch-enum).
  */
 #define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 &&		\
-                                    (format) <= CAIRO_FORMAT_RGB16_565)
+                                    (format) <= CAIRO_FORMAT_RGB30)
 
 /* pixman-required stride alignment in bytes. */
 #define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index 647975f..34b534e 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -2854,6 +2854,7 @@ _image_read_raw (csi_file_t *src,
 	rowlen = 3 * width;
 	break;
     default:
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_INVALID:
     case CAIRO_FORMAT_ARGB32:
 	rowlen = 4 * width;
@@ -2915,6 +2916,7 @@ _image_read_raw (csi_file_t *src,
 #endif
 		}
 		break;
+	    case CAIRO_FORMAT_RGB30:
 	    case CAIRO_FORMAT_INVALID:
 	    case CAIRO_FORMAT_ARGB32:
 		/* stride == width */
@@ -3003,6 +3005,7 @@ _image_read_raw (csi_file_t *src,
 #endif
 	    }
 	    break;
+	case CAIRO_FORMAT_RGB30:
 	case CAIRO_FORMAT_INVALID:
 	case CAIRO_FORMAT_ARGB32:
 	    /* stride == width */
@@ -3038,6 +3041,7 @@ _image_read_raw (csi_file_t *src,
 	case CAIRO_FORMAT_A8:
 	    break;
 
+	case CAIRO_FORMAT_RGB30:
 	case CAIRO_FORMAT_RGB24:
 	case CAIRO_FORMAT_INVALID:
 	default:
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 9bdeb01..44dc137 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -1451,6 +1451,7 @@ _format_to_string (cairo_format_t format)
     switch (format) {
 	f(INVALID);
 	f(ARGB32);
+	f(RGB30);
 	f(RGB24);
 	f(RGB16_565);
 	f(A8);
@@ -1584,6 +1585,7 @@ _emit_image (cairo_surface_t *image,
     case CAIRO_FORMAT_RGB16_565: len = 2*width; break;
     case CAIRO_FORMAT_RGB24:     len = 3*width; break;
     default:
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_INVALID:
     case CAIRO_FORMAT_ARGB32: len = 4*width; break;
     }
@@ -1622,6 +1624,7 @@ _emit_image (cairo_surface_t *image,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	for (row = height; row--; ) {
 	    _write_data (&stream, data, 4*width);
@@ -1681,6 +1684,7 @@ _emit_image (cairo_surface_t *image,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	for (row = height; row--; ) {
 	    uint32_t *src = (uint32_t *) data;
diff --git a/tests/testdisplay.c b/tests/testdisplay.c
index 5bf5183..eeff97e 100644
--- a/tests/testdisplay.c
+++ b/tests/testdisplay.c
@@ -369,6 +369,8 @@ allocate_surface(int fd, int width, int height, uint32_t depth, uint32_t bpp,
 		format = CAIRO_FORMAT_RGB24;
 		break;
 	case 30:
+		format = CAIRO_FORMAT_RGB30;
+		break;
 	case 32:
 		format = CAIRO_FORMAT_ARGB32;
 		break;
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to