[Cogl] [PATCH v2] Add support for RG textures

Robert Bragg robert at sixbynine.org
Mon Jan 20 06:18:08 PST 2014


Thanks for the update.

When I read this:

 Even if the feature is not
+ * available then %COGL_PIXEL_FORMAT_RG_88 can still be used for
+ * %CoglBitmap<!-- -->s and as the external image format for textures
+ * as long as a different internal texture format is used.

I'm wondering if instead of requiring the user to use a "different
internal format" if this could be written in terms of the
CoglTextureComponents enum to avoid introducing extra terminology, in
case someone wonders where they need to specify that "format" to
comply with this requirement.

Apart from that I think this looks good to land:

Reviewed-by: Robert Bragg <robert at linux.intel.com>

Thanks,
Robert


On Wed, Jan 15, 2014 at 5:20 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Ok, here is a second version of the patch with the suggested
> documentation changes. This is based on top of another documentation
> patch which I just posted to the list:
>
> http://lists.freedesktop.org/archives/cogl/2014-January/001561.html
>
> Thanks for the review.
>
> Regards,
> - Neil
>
> ------- >8 --------------- (use git am --scissors to automatically chop here)
>
> 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
> ---
>  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(-)
>  create mode 100644 tests/conform/test-texture-rg.c
>
> diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
> index 6a2e850..b6d9b14 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 1ad0575..4251f23 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 448ec3c..8e1775c 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 064d440..8378ec6 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 112af0d..9e73839 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
> @@ -149,6 +152,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
> @@ -169,6 +173,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 %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 for
> + * %CoglBitmap<!-- -->s and as the external image format for textures
> + * as long as a different internal texture format is used.
> + *
>   * Since: 1.18
>   */
>  void
> diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
> index 31b3b4e..007c801 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 caa8dd0..32109c8 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 c8367c1..c8b53f9 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 a70d492..8a0a388 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 e3493a9..edfe940 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 116d29d..c119d79 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 12b04ae..4fa9ecc 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 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 b1c2111..4e6c02a 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);
> --
> 1.8.4.2
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl


More information about the Cogl mailing list