summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2014-01-14 15:52:45 +0000
committerNeil Roberts <neil@linux.intel.com>2014-01-20 14:28:43 +0000
commit568677ab3bcb62ababad1623be0d6b9b117d0a26 (patch)
tree5feec3374d3409985d1f7b0db8a215db4431bb28
parent2f12c4329c519fa14b927b2dcd708dddcc903c32 (diff)
downloadcogl-568677ab3bcb62ababad1623be0d6b9b117d0a26.tar.gz
Add support for RG textures
This adds COGL_PIXEL_FORMAT_RG_88 and COGL_TEXTURE_COMPONENTS_RG in order to support two-component textures. The RG components for a texture is only supported if COGL_FEATURE_ID_TEXTURE_RG is advertised. This is only available on GL 3, GL 2 with the GL_ARB_texture_rg extension or GLES with the GL_EXT_texture_rg extension. The RG pixel format is always supported for images because Cogl can easily do the conversion if an application uses this format to upload to a texture with a different format. If an application tries to create an RG texture when the feature isn't supported then it will raise an error when the texture is allocated. https://bugzilla.gnome.org/show_bug.cgi?id=712830 Reviewed-by: Robert Bragg <robert@linux.intel.com>
-rw-r--r--cogl/cogl-bitmap-conversion.c40
-rw-r--r--cogl/cogl-bitmap-packing.h36
-rw-r--r--cogl/cogl-context.h4
-rw-r--r--cogl/cogl-texture.c15
-rw-r--r--cogl/cogl-texture.h13
-rw-r--r--cogl/cogl-types.h5
-rw-r--r--cogl/driver/gl/gl/cogl-driver-gl.c30
-rw-r--r--cogl/driver/gl/gles/cogl-driver-gles.c31
-rw-r--r--test-fixtures/test-utils.c6
-rw-r--r--test-fixtures/test-utils.h15
-rw-r--r--tests/conform/Makefile.am1
-rw-r--r--tests/conform/test-conform-main.c2
-rw-r--r--tests/conform/test-read-texture-formats.c22
-rw-r--r--tests/conform/test-texture-rg.c74
-rw-r--r--tests/conform/test-write-texture-formats.c5
15 files changed, 283 insertions, 16 deletions
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 6a2e8507..b6d9b149 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -325,6 +325,7 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
g_assert_not_reached ();
case COGL_PIXEL_FORMAT_A_8:
+ case COGL_PIXEL_FORMAT_RG_88:
case COGL_PIXEL_FORMAT_RGB_565:
case COGL_PIXEL_FORMAT_RGBA_4444:
case COGL_PIXEL_FORMAT_RGBA_5551:
@@ -512,6 +513,35 @@ _cogl_bitmap_convert (CoglBitmap *src_bmp,
return dst_bmp;
}
+static CoglBool
+driver_can_convert (CoglContext *ctx,
+ CoglPixelFormat src_format,
+ CoglPixelFormat internal_format)
+{
+ if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION))
+ return FALSE;
+
+ if (src_format == internal_format)
+ return TRUE;
+
+ /* If the driver doesn't natively support alpha textures then it
+ * won't work correctly to convert to/from component-alpha
+ * textures */
+ if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
+ (src_format == COGL_PIXEL_FORMAT_A_8 ||
+ internal_format == COGL_PIXEL_FORMAT_A_8))
+ return FALSE;
+
+ /* Same for red-green textures. If red-green textures aren't
+ * supported then the internal format should never be RG_88 but we
+ * should still be able to convert from an RG source image */
+ if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RG) &&
+ src_format == COGL_PIXEL_FORMAT_RG_88)
+ return FALSE;
+
+ return TRUE;
+}
+
CoglBitmap *
_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
CoglPixelFormat internal_format,
@@ -532,15 +562,7 @@ _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
limited number of formats so we must convert using the Cogl
bitmap code instead */
- /* If the driver doesn't natively support alpha textures then it
- * won't work correctly to convert to/from component-alpha
- * textures */
-
- if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&
- (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||
- (src_format != COGL_PIXEL_FORMAT_A_8 &&
- internal_format != COGL_PIXEL_FORMAT_A_8) ||
- src_format == internal_format))
+ if (driver_can_convert (ctx, src_format, internal_format))
{
/* If the source format does not have the same premult flag as the
internal_format then we need to copy and convert it */
diff --git a/cogl/cogl-bitmap-packing.h b/cogl/cogl-bitmap-packing.h
index 1ad05752..4251f231 100644
--- a/cogl/cogl-bitmap-packing.h
+++ b/cogl/cogl-bitmap-packing.h
@@ -65,6 +65,22 @@ G_PASTE (_cogl_unpack_a_8_, component_size) (const uint8_t *src,
}
inline static void
+G_PASTE (_cogl_unpack_rg_88_, component_size) (const uint8_t *src,
+ component_type *dst,
+ int width)
+{
+ while (width-- > 0)
+ {
+ dst[0] = UNPACK_BYTE (src[0]);
+ dst[1] = UNPACK_BYTE (src[1]);
+ dst[2] = 0;
+ dst[3] = UNPACK_BYTE (255);
+ dst += 4;
+ src += 2;
+ }
+}
+
+inline static void
G_PASTE (_cogl_unpack_rgb_888_, component_size) (const uint8_t *src,
component_type *dst,
int width)
@@ -304,6 +320,9 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_A_8:
G_PASTE (_cogl_unpack_a_8_, component_size) (src, dst, width);
break;
+ case COGL_PIXEL_FORMAT_RG_88:
+ G_PASTE (_cogl_unpack_rg_88_, component_size) (src, dst, width);
+ break;
case COGL_PIXEL_FORMAT_RGB_888:
G_PASTE (_cogl_unpack_rgb_888_, component_size) (src, dst, width);
break;
@@ -389,6 +408,20 @@ G_PASTE (_cogl_pack_a_8_, component_size) (const component_type *src,
}
inline static void
+G_PASTE (_cogl_pack_rg_88_, component_size) (const component_type *src,
+ uint8_t *dst,
+ int width)
+{
+ while (width-- > 0)
+ {
+ dst[0] = PACK_BYTE (src[0]);
+ dst[1] = PACK_BYTE (src[1]);
+ src += 4;
+ dst += 2;
+ }
+}
+
+inline static void
G_PASTE (_cogl_pack_rgb_888_, component_size) (const component_type *src,
uint8_t *dst,
int width)
@@ -626,6 +659,9 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_A_8:
G_PASTE (_cogl_pack_a_8_, component_size) (src, dst, width);
break;
+ case COGL_PIXEL_FORMAT_RG_88:
+ G_PASTE (_cogl_pack_rg_88_, component_size) (src, dst, width);
+ break;
case COGL_PIXEL_FORMAT_RGB_888:
G_PASTE (_cogl_pack_rgb_888_, component_size) (src, dst, width);
break;
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index 448ec3c0..8e1775c1 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -202,6 +202,9 @@ cogl_is_context (void *object);
* and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features combined.
* @COGL_FEATURE_ID_TEXTURE_RECTANGLE: Support for rectangular
* textures with non-normalized texture coordinates.
+ * @COGL_FEATURE_ID_TEXTURE_RG: Support for
+ * %COGL_TEXTURE_COMPONENTS_RG as the internal components of a
+ * texture.
* @COGL_FEATURE_ID_TEXTURE_3D: 3D texture support
* @COGL_FEATURE_ID_OFFSCREEN: Offscreen rendering support
* @COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE: Multisample support for
@@ -259,6 +262,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_PRESENTATION_TIME,
COGL_FEATURE_ID_FENCE,
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
+ COGL_FEATURE_ID_TEXTURE_RG,
/*< private >*/
_COGL_N_FEATURE_IDS /*< skip >*/
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 064d440f..8378ec69 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -1291,6 +1291,14 @@ cogl_texture_allocate (CoglTexture *texture,
if (texture->allocated)
return TRUE;
+ if (texture->components == COGL_TEXTURE_COMPONENTS_RG &&
+ !cogl_has_feature (texture->context, COGL_FEATURE_ID_TEXTURE_RG))
+ _cogl_set_error (error,
+ COGL_TEXTURE_ERROR,
+ COGL_TEXTURE_ERROR_FORMAT,
+ "A red-green texture was requested but the driver "
+ "does not support them");
+
texture->allocated = texture->vtable->allocate (texture, error);
return texture->allocated;
@@ -1310,6 +1318,11 @@ _cogl_texture_set_internal_format (CoglTexture *texture,
texture->components = COGL_TEXTURE_COMPONENTS_A;
return;
}
+ else if (internal_format == COGL_PIXEL_FORMAT_RG_88)
+ {
+ texture->components = COGL_TEXTURE_COMPONENTS_RG;
+ return;
+ }
else if (internal_format & COGL_DEPTH_BIT)
{
texture->components = COGL_TEXTURE_COMPONENTS_DEPTH;
@@ -1351,6 +1364,8 @@ _cogl_texture_determine_internal_format (CoglTexture *texture,
}
case COGL_TEXTURE_COMPONENTS_A:
return COGL_PIXEL_FORMAT_A_8;
+ case COGL_TEXTURE_COMPONENTS_RG:
+ return COGL_PIXEL_FORMAT_RG_88;
case COGL_TEXTURE_COMPONENTS_RGB:
if (src_format != COGL_PIXEL_FORMAT_ANY &&
!(src_format & COGL_A_BIT) && !(src_format & COGL_DEPTH_BIT))
diff --git a/cogl/cogl-texture.h b/cogl/cogl-texture.h
index 5c2613e7..b07da9bb 100644
--- a/cogl/cogl-texture.h
+++ b/cogl/cogl-texture.h
@@ -136,6 +136,9 @@ cogl_is_texture (void *object);
/**
* CoglTextureComponents:
* @COGL_TEXTURE_COMPONENTS_A: Only the alpha component
+ * @COGL_TEXTURE_COMPONENTS_RG: Red and green components. Note that
+ * this can only be used if the %COGL_FEATURE_ID_TEXTURE_RG feature
+ * is advertised.
* @COGL_TEXTURE_COMPONENTS_RGB: Red, green and blue components
* @COGL_TEXTURE_COMPONENTS_RGBA: Red, green, blue and alpha components
* @COGL_TEXTURE_COMPONENTS_DEPTH: Only a depth component
@@ -147,6 +150,7 @@ cogl_is_texture (void *object);
typedef enum _CoglTextureComponents
{
COGL_TEXTURE_COMPONENTS_A = 1,
+ COGL_TEXTURE_COMPONENTS_RG,
COGL_TEXTURE_COMPONENTS_RGB,
COGL_TEXTURE_COMPONENTS_RGBA,
COGL_TEXTURE_COMPONENTS_DEPTH
@@ -167,6 +171,15 @@ typedef enum _CoglTextureComponents
* a %CoglBitmap or a data pointer default to the same components as
* the pixel format of the data.
*
+ * Note that the %COGL_TEXTURE_COMPONENTS_RG format is not available
+ * on all drivers. The availability can be determined by checking for
+ * the %COGL_FEATURE_ID_TEXTURE_RG feature. If this format is used on
+ * a driver where it is not available then %COGL_TEXTURE_ERROR_FORMAT
+ * will be raised when the texture is allocated. Even if the feature
+ * is not available then %COGL_PIXEL_FORMAT_RG_88 can still be used as
+ * an image format as long as %COGL_TEXTURE_COMPONENTS_RG isn't used
+ * as the texture's components.
+ *
* Since: 1.18
*/
void
diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
index 31b3b4e5..007c801b 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -272,6 +272,9 @@ typedef struct _CoglColor CoglColor;
* CoglPixelFormat:
* @COGL_PIXEL_FORMAT_ANY: Any format
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
+ * @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
+ * are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
+ * See cogl_texture_set_components() for details.
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
@@ -320,6 +323,8 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_ANY = 0,
COGL_PIXEL_FORMAT_A_8 = (1 | COGL_A_BIT),
+ COGL_PIXEL_FORMAT_RG_88 = 2,
+
COGL_PIXEL_FORMAT_RGB_565 = (2 | COGL_BITWISE_BIT),
COGL_PIXEL_FORMAT_RGBA_4444 = (2 | COGL_BITWISE_BIT | COGL_A_BIT),
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (2 | COGL_PIXEL_FORMAT_RGBA_4444 | COGL_PREMULT_BIT),
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c
index caa8dd0e..32109c85 100644
--- a/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -69,6 +69,10 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
*out_format = COGL_PIXEL_FORMAT_A_8;
return TRUE;
+ case GL_RG:
+ *out_format = COGL_PIXEL_FORMAT_RG_88;
+ return TRUE;
+
case GL_RGB: case GL_RGB4: case GL_RGB5: case GL_RGB8:
case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_R3_G3_B2:
@@ -120,6 +124,26 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_BYTE;
break;
+ case COGL_PIXEL_FORMAT_RG_88:
+ if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG))
+ {
+ glintformat = GL_RG;
+ glformat = GL_RG;
+ }
+ else
+ {
+ /* If red-green textures aren't supported then we'll use RGB
+ * as an internal format. Note this should only end up
+ * mattering for downloading the data because Cogl will
+ * refuse to allocate a texture with RG components if RG
+ * textures aren't supported */
+ glintformat = GL_RGB;
+ glformat = GL_RGB;
+ required_format = COGL_PIXEL_FORMAT_RGB_888;
+ }
+ gltype = GL_UNSIGNED_BYTE;
+ break;
+
case COGL_PIXEL_FORMAT_RGB_888:
glintformat = GL_RGB;
glformat = GL_RGB;
@@ -601,6 +625,12 @@ _cogl_driver_update_features (CoglContext *ctx,
if (ctx->glFenceSync)
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE);
+ if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) ||
+ _cogl_check_extension ("GL_ARB_texture_rg", gl_extensions))
+ COGL_FLAGS_SET (ctx->features,
+ COGL_FEATURE_ID_TEXTURE_RG,
+ TRUE);
+
/* Cache features */
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
ctx->private_features[i] |= private_features[i];
diff --git a/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/driver/gl/gles/cogl-driver-gles.c
index c8367c1b..c8b53f99 100644
--- a/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -51,6 +51,12 @@
#ifndef GL_DEPTH_STENCIL
#define GL_DEPTH_STENCIL 0x84F9
#endif
+#ifndef GL_RG
+#define GL_RG 0x8227
+#endif
+#ifndef GL_RG8
+#define GL_RG8 0x822B
+#endif
static CoglBool
_cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
@@ -83,6 +89,26 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_BYTE;
break;
+ case COGL_PIXEL_FORMAT_RG_88:
+ if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG))
+ {
+ glintformat = GL_RG8;
+ glformat = GL_RG;
+ }
+ else
+ {
+ /* If red-green textures aren't supported then we'll use RGB
+ * as an internal format. Note this should only end up
+ * mattering for downloading the data because Cogl will
+ * refuse to allocate a texture with RG components if RG
+ * textures aren't supported */
+ glintformat = GL_RGB;
+ glformat = GL_RGB;
+ required_format = COGL_PIXEL_FORMAT_RGB_888;
+ }
+ gltype = GL_UNSIGNED_BYTE;
+ break;
+
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
/* There is an extension to support this format */
@@ -342,6 +368,11 @@ _cogl_driver_update_features (CoglContext *context,
_cogl_check_extension ("GL_OES_egl_sync", gl_extensions))
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE);
+ if (_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions))
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_TEXTURE_RG,
+ TRUE);
+
/* Cache features */
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
context->private_features[i] |= private_features[i];
diff --git a/test-fixtures/test-utils.c b/test-fixtures/test-utils.c
index a70d492a..8a0a3884 100644
--- a/test-fixtures/test-utils.c
+++ b/test-fixtures/test-utils.c
@@ -42,6 +42,12 @@ check_flags (TestFlags flags,
return FALSE;
}
+ if (flags & TEST_REQUIREMENT_TEXTURE_RG &&
+ !cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RG))
+ {
+ return FALSE;
+ }
+
if (flags & TEST_REQUIREMENT_POINT_SPRITE &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_POINT_SPRITE))
{
diff --git a/test-fixtures/test-utils.h b/test-fixtures/test-utils.h
index 5e40370d..9c3ced9b 100644
--- a/test-fixtures/test-utils.h
+++ b/test-fixtures/test-utils.h
@@ -35,13 +35,14 @@ typedef enum _TestFlags
TEST_REQUIREMENT_NPOT = 1<<2,
TEST_REQUIREMENT_TEXTURE_3D = 1<<3,
TEST_REQUIREMENT_TEXTURE_RECTANGLE = 1<<4,
- TEST_REQUIREMENT_POINT_SPRITE = 1<<5,
- TEST_REQUIREMENT_GLES2_CONTEXT = 1<<6,
- TEST_REQUIREMENT_MAP_WRITE = 1<<7,
- TEST_REQUIREMENT_GLSL = 1<<8,
- TEST_REQUIREMENT_OFFSCREEN = 1<<9,
- TEST_REQUIREMENT_FENCE = 1<<10,
- TEST_REQUIREMENT_PER_VERTEX_POINT_SIZE = 1<<11
+ TEST_REQUIREMENT_TEXTURE_RG = 1<<5,
+ TEST_REQUIREMENT_POINT_SPRITE = 1<<6,
+ TEST_REQUIREMENT_GLES2_CONTEXT = 1<<7,
+ TEST_REQUIREMENT_MAP_WRITE = 1<<8,
+ TEST_REQUIREMENT_GLSL = 1<<9,
+ TEST_REQUIREMENT_OFFSCREEN = 1<<10,
+ TEST_REQUIREMENT_FENCE = 1<<11,
+ TEST_REQUIREMENT_PER_VERTEX_POINT_SIZE = 1<<12
} TestFlags;
/**
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
index e3493a94..edfe940d 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -66,6 +66,7 @@ test_sources = \
test-pipeline-cache-unrefs-texture.c \
test-texture-no-allocate.c \
test-pipeline-shader-state.c \
+ test-texture-rg.c \
$(NULL)
if !USING_EMSCRIPTEN
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index 116d29d2..c119d79b 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -151,6 +151,8 @@ main (int argc, char **argv)
ADD_TEST (test_texture_no_allocate, 0, 0);
+ ADD_TEST (test_texture_rg, TEST_REQUIREMENT_TEXTURE_RG, 0);
+
g_printerr ("Unknown test name \"%s\"\n", argv[1]);
return 1;
diff --git a/tests/conform/test-read-texture-formats.c b/tests/conform/test-read-texture-formats.c
index 12b04ae9..4fa9eccc 100644
--- a/tests/conform/test-read-texture-formats.c
+++ b/tests/conform/test-read-texture-formats.c
@@ -80,6 +80,23 @@ test_read_888 (CoglTexture2D *tex_2d,
}
static void
+test_read_88 (CoglTexture2D *tex_2d,
+ CoglPixelFormat format,
+ uint32_t expected_pixel)
+{
+ uint8_t pixel[4];
+
+ pixel[2] = 0x00;
+
+ cogl_texture_get_data (tex_2d,
+ format,
+ 2, /* rowstride */
+ pixel);
+
+ test_utils_compare_pixel (pixel, expected_pixel);
+}
+
+static void
test_read_8888 (CoglTexture2D *tex_2d,
CoglPixelFormat format,
uint32_t expected_pixel)
@@ -155,6 +172,11 @@ test_read_texture_formats (void)
test_read_byte (tex_2d, COGL_PIXEL_FORMAT_A_8, 0x78);
+ /* We should always be able to read into an RG buffer regardless of
+ * whether RG textures are supported because Cogl will do the
+ * conversion for us */
+ test_read_88 (tex_2d, COGL_PIXEL_FORMAT_RG_88, 0x123400ff);
+
test_read_short (tex_2d, COGL_PIXEL_FORMAT_RGB_565,
5, 0x12, 6, 0x34, 5, 0x56,
-1);
diff --git a/tests/conform/test-texture-rg.c b/tests/conform/test-texture-rg.c
new file mode 100644
index 00000000..72a5ae93
--- /dev/null
+++ b/tests/conform/test-texture-rg.c
@@ -0,0 +1,74 @@
+#include <cogl/cogl.h>
+
+#include <string.h>
+
+#include "test-utils.h"
+
+#define TEX_WIDTH 8
+#define TEX_HEIGHT 8
+
+static CoglTexture2D *
+make_texture (void)
+{
+ uint8_t tex_data[TEX_WIDTH * TEX_HEIGHT * 2], *p = tex_data;
+ int x, y;
+
+ for (y = 0; y < TEX_HEIGHT; y++)
+ for (x = 0; x < TEX_WIDTH; x++)
+ {
+ *(p++) = x * 256 / TEX_WIDTH;
+ *(p++) = y * 256 / TEX_HEIGHT;
+ }
+
+ return cogl_texture_2d_new_from_data (test_ctx,
+ TEX_WIDTH, TEX_HEIGHT,
+ COGL_PIXEL_FORMAT_RG_88,
+ TEX_WIDTH * 2,
+ tex_data,
+ NULL);
+}
+
+void
+test_texture_rg (void)
+{
+ CoglPipeline *pipeline;
+ CoglTexture2D *tex;
+ int fb_width, fb_height;
+ int x, y;
+
+ fb_width = cogl_framebuffer_get_width (test_fb);
+ fb_height = cogl_framebuffer_get_height (test_fb);
+
+ tex = make_texture ();
+
+ g_assert (cogl_texture_get_components (tex) == COGL_TEXTURE_COMPONENTS_RG);
+
+ pipeline = cogl_pipeline_new (test_ctx);
+
+ cogl_pipeline_set_layer_texture (pipeline, 0, tex);
+ cogl_pipeline_set_layer_filters (pipeline,
+ 0,
+ COGL_PIPELINE_FILTER_NEAREST,
+ COGL_PIPELINE_FILTER_NEAREST);
+
+ cogl_framebuffer_draw_rectangle (test_fb,
+ pipeline,
+ -1.0f, 1.0f,
+ 1.0f, -1.0f);
+
+ for (y = 0; y < TEX_HEIGHT; y++)
+ for (x = 0; x < TEX_WIDTH; x++)
+ {
+ test_utils_check_pixel_rgb (test_fb,
+ x * fb_width / TEX_WIDTH +
+ fb_width / (TEX_WIDTH * 2),
+ y * fb_height / TEX_HEIGHT +
+ fb_height / (TEX_HEIGHT * 2),
+ x * 256 / TEX_WIDTH,
+ y * 256 / TEX_HEIGHT,
+ 0);
+ }
+
+ cogl_object_unref (pipeline);
+ cogl_object_unref (tex);
+}
diff --git a/tests/conform/test-write-texture-formats.c b/tests/conform/test-write-texture-formats.c
index b1c2111b..4e6c02a1 100644
--- a/tests/conform/test-write-texture-formats.c
+++ b/tests/conform/test-write-texture-formats.c
@@ -131,6 +131,11 @@ test_write_texture_formats (void)
{
test_write_byte (COGL_PIXEL_FORMAT_A_8, 0x34, 0x00000034);
+ /* We should always be able to read from an RG buffer regardless of
+ * whether RG textures are supported because Cogl will do the
+ * conversion for us */
+ test_write_bytes (COGL_PIXEL_FORMAT_RG_88, 0x123456ff, 0x123400ff);
+
test_write_short (COGL_PIXEL_FORMAT_RGB_565, 0x0843, 0x080819ff);
test_write_short (COGL_PIXEL_FORMAT_RGBA_4444_PRE, 0x1234, 0x11223344);
test_write_short (COGL_PIXEL_FORMAT_RGBA_5551_PRE, 0x0887, 0x081019ff);