[cogl/cogl-1.18] Add support for RG textures



commit eb7ef457cb281d5ed75863a269da2a94c427bd7b
Author: Neil Roberts <neil linux intel com>
Date:   Tue Jan 14 15:52:45 2014 +0000

    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>
    
    (cherry picked from commit 568677ab3bcb62ababad1623be0d6b9b117d0a26)
    
    Conflicts:
        cogl/cogl-bitmap-packing.h
        cogl/cogl-types.h
        cogl/driver/gl/gl/cogl-driver-gl.c
        tests/conform/test-read-texture-formats.c
        tests/conform/test-write-texture-formats.c

 cogl/cogl-bitmap-conversion.c              |   40 ++++++++++++---
 cogl/cogl-bitmap-packing.h                 |   36 +++++++++++++
 cogl/cogl-context.h                        |    4 ++
 cogl/cogl-texture.c                        |   15 ++++++
 cogl/cogl-texture.h                        |   13 +++++
 cogl/cogl-types.h                          |    5 ++
 cogl/driver/gl/gl/cogl-driver-gl.c         |   30 +++++++++++
 cogl/driver/gl/gles/cogl-driver-gles.c     |   31 ++++++++++++
 test-fixtures/test-utils.c                 |    6 ++
 test-fixtures/test-utils.h                 |   15 +++---
 tests/conform/Makefile.am                  |    1 +
 tests/conform/test-conform-main.c          |    2 +
 tests/conform/test-read-texture-formats.c  |   22 ++++++++
 tests/conform/test-texture-rg.c            |   74 ++++++++++++++++++++++++++++
 tests/conform/test-write-texture-formats.c |    5 ++
 15 files changed, 283 insertions(+), 16 deletions(-)
---
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index e8a86c5..47769b6 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -319,6 +319,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:
@@ -507,6 +508,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,
@@ -527,15 +557,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 e631c17..e2bc8a1 100644
--- a/cogl/cogl-bitmap-packing.h
+++ b/cogl/cogl-bitmap-packing.h
@@ -79,6 +79,22 @@ G_PASTE (_cogl_unpack_g_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)
@@ -321,6 +337,9 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
     case COGL_PIXEL_FORMAT_G_8:
       G_PASTE (_cogl_unpack_g_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;
@@ -425,6 +444,20 @@ G_PASTE (_cogl_pack_g_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)
@@ -665,6 +698,9 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
     case COGL_PIXEL_FORMAT_G_8:
       G_PASTE (_cogl_pack_g_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 8c99bce..c38b863 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -200,6 +200,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
@@ -263,6 +266,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 0e124ba..e2abde6 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -1377,6 +1377,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;
@@ -1396,6 +1404,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;
@@ -1437,6 +1450,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 08fa085..d4e40c5 100644
--- a/cogl/cogl-texture.h
+++ b/cogl/cogl-texture.h
@@ -127,6 +127,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
@@ -138,6 +141,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
@@ -158,6 +162,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 57e0e29..3f9c23b 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -298,6 +298,9 @@ typedef struct _CoglTextureVertex       CoglTextureVertex;
  * 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
@@ -355,6 +358,8 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
   COGL_PIXEL_FORMAT_YUV           = 7,
   COGL_PIXEL_FORMAT_G_8           = 8,
 
+  COGL_PIXEL_FORMAT_RG_88         = 9,
+
   COGL_PIXEL_FORMAT_RGB_888       = 2,
   COGL_PIXEL_FORMAT_BGR_888       = (2 | COGL_BGR_BIT),
 
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c
index 905956a..4134a7e 100644
--- a/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -68,6 +68,10 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
       *out_format = COGL_PIXEL_FORMAT_G_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:
 
@@ -124,6 +128,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;
@@ -637,6 +661,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 82c33ed..4c4961d 100644
--- a/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -44,6 +44,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,
@@ -81,6 +87,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 */
@@ -367,6 +393,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 6029dde..59e3fd8 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 5e40370..9c3ced9 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 68f922a..b6aa552 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -67,6 +67,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 83317d1..63210d0 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -149,6 +149,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 ab2184b..3fa4d8e 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)
@@ -162,6 +179,11 @@ test_read_texture_formats (void)
   test_read_byte (tex_2d, COGL_PIXEL_FORMAT_G_8, 0x9c);
 #endif
 
+  /* 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 0000000..72a5ae9
--- /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 859f4b4..d415df0 100644
--- a/tests/conform/test-write-texture-formats.c
+++ b/tests/conform/test-write-texture-formats.c
@@ -141,6 +141,11 @@ test_write_texture_formats (void)
   test_write_byte (test_ctx, COGL_PIXEL_FORMAT_G_8, 0x34, 0x340000ff);
 #endif
 
+  /* 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 (test_ctx, COGL_PIXEL_FORMAT_RG_88, 0x123456ff, 0x123400ff);
+
   test_write_short (test_ctx, COGL_PIXEL_FORMAT_RGB_565, 0x0843, 0x080819ff);
   test_write_short (test_ctx, COGL_PIXEL_FORMAT_RGBA_4444_PRE, 0x1234, 0x11223344);
   test_write_short (test_ctx, COGL_PIXEL_FORMAT_RGBA_5551_PRE, 0x0887, 0x081019ff);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]