[Cogl] [PATCH 3/3] Support retrieving depth textures from framebuffers

Robert Bragg robert at sixbynine.org
Wed May 23 12:48:20 PDT 2012


Thanks Damien, I've put some (mostly minor) comments inline...

On Wed, May 23, 2012 at 6:23 PM, Damien Lespiau
<damien.lespiau at gmail.com> wrote:
> From: Damien Lespiau <damien.lespiau at intel.com>
>
> This commit introduces two new funtions on framebuffers to be able to
> retrieve the depth buffer as a texture for further usage, say, to
> implement shadow mapping.
>
> The proposed API works as follow:
>  * Before the framebuffer is allocated, you can request that a depth
>    texture is created with cogl_framebuffer_enable_depth_texture()
>  * cogl_framebuffer_get_depth_texture() can then be used to grab a
>    CoglTexture
> ---
>  cogl/cogl-bitmap-conversion.c               |    5 +
>  cogl/cogl-bitmap-packing.h                  |   10 ++
>  cogl/cogl-context.h                         |    3 +
>  cogl/cogl-framebuffer-private.h             |    3 +
>  cogl/cogl-framebuffer.c                     |  170 +++++++++++++++++++++------
>  cogl/cogl-framebuffer.h                     |   42 +++++++
>  cogl/cogl-types.h                           |   28 ++++-
>  cogl/driver/gl/cogl-gl.c                    |    7 +
>  cogl/driver/gl/cogl-texture-driver-gl.c     |   27 +++++
>  cogl/driver/gles/cogl-gles.c                |    6 +
>  cogl/driver/gles/cogl-texture-driver-gles.c |   27 +++++
>  examples/cogl-info.c                        |    6 +
>  12 files changed, 289 insertions(+), 45 deletions(-)
>
> diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
> index 6a57dbf..6e918da 100644
> --- a/cogl/cogl-bitmap-conversion.c
> +++ b/cogl/cogl-bitmap-conversion.c
> @@ -306,6 +306,11 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
>      floats */
>   switch (format)
>     {
> +    case COGL_PIXEL_FORMAT_DEPTH_ANY:
> +    case COGL_PIXEL_FORMAT_DEPTH_16:
> +    case COGL_PIXEL_FORMAT_DEPTH_24:
> +    case COGL_PIXEL_FORMAT_DEPTH_32:
> +    case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
>     case COGL_PIXEL_FORMAT_ANY:
>     case COGL_PIXEL_FORMAT_YUV:
>       g_assert_not_reached ();
> diff --git a/cogl/cogl-bitmap-packing.h b/cogl/cogl-bitmap-packing.h
> index 6c0a985..b12986f 100644
> --- a/cogl/cogl-bitmap-packing.h
> +++ b/cogl/cogl-bitmap-packing.h
> @@ -370,6 +370,11 @@ G_PASTE (_cogl_unpack_, component_type) (CoglPixelFormat format,
>     case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
>       G_PASTE (_cogl_unpack_abgr_2101010_, component_type) (src, dst, width);
>       break;
> +    case COGL_PIXEL_FORMAT_DEPTH_ANY:
> +    case COGL_PIXEL_FORMAT_DEPTH_16:
> +    case COGL_PIXEL_FORMAT_DEPTH_24:
> +    case COGL_PIXEL_FORMAT_DEPTH_32:
> +    case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
>     case COGL_PIXEL_FORMAT_ANY:
>     case COGL_PIXEL_FORMAT_YUV:
>       g_assert_not_reached ();
> @@ -711,6 +716,11 @@ G_PASTE (_cogl_pack_, component_type) (CoglPixelFormat format,
>     case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
>       G_PASTE (_cogl_pack_abgr_2101010_, component_type) (src, dst, width);
>       break;
> +    case COGL_PIXEL_FORMAT_DEPTH_ANY:
> +    case COGL_PIXEL_FORMAT_DEPTH_16:
> +    case COGL_PIXEL_FORMAT_DEPTH_24:
> +    case COGL_PIXEL_FORMAT_DEPTH_32:
> +    case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
>     case COGL_PIXEL_FORMAT_ANY:
>     case COGL_PIXEL_FORMAT_YUV:
>       g_assert_not_reached ();
> diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
> index e2120d7..f4b1950 100644
> --- a/cogl/cogl-context.h
> +++ b/cogl/cogl-context.h
> @@ -203,6 +203,8 @@ cogl_is_context (void *object);
>  * @COGL_FEATURE_ID_SWAP_BUFFERS_EVENT:
>  *     Available if the window system supports reporting an event
>  *     for swap buffer completions.
> + * @COGL_FEATURE_ID_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering
> + *     the depth buffer to a texture.
>  *
>  * All the capabilities that can vary between different GPUs supported
>  * by Cogl. Applications that depend on any of these features should explicitly
> @@ -230,6 +232,7 @@ typedef enum _CoglFeatureID
>   COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
>   COGL_FEATURE_ID_MIRRORED_REPEAT,
>   COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
> +  COGL_FEATURE_ID_DEPTH_TEXTURE,
>
>   /*< private > */
>   _COGL_N_FEATURE_IDS
> diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
> index 0081a2f..f2643f5 100644
> --- a/cogl/cogl-framebuffer-private.h
> +++ b/cogl/cogl-framebuffer-private.h
> @@ -49,6 +49,7 @@ typedef enum _CoglFramebufferType {
>  typedef struct
>  {
>   CoglSwapChain *swap_chain;
> +  gboolean need_depth_texture;

As a minor style note; we recently switched all use of gboolean to
CoglBool in master. I suppose this patch is based against the 1.10
branch currently, since it looks like there are other uses of gboolean
here too?

>   gboolean need_stencil;
>   int samples_per_pixel;
>   gboolean swap_throttled;
> @@ -166,6 +167,8 @@ struct _CoglOffscreen
>   int             texture_level_width;
>   int             texture_level_height;
>
> +  CoglTexture    *depth_texture;
> +
>   /* FIXME: _cogl_offscreen_new_to_texture_full should be made to use
>    * fb->config to configure if we want a depth or stencil buffer so
>    * we can get rid of these flags */
> diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
> index 30613f7..c219ab4 100644
> --- a/cogl/cogl-framebuffer.c
> +++ b/cogl/cogl-framebuffer.c
> @@ -881,52 +881,125 @@ try_creating_fbo (CoglOffscreen *offscreen,
>
>   if (flags & _TRY_DEPTH24_STENCIL8)
>     {
> -      /* Create a renderbuffer for depth and stenciling */
> -      GE (ctx, glGenRenderbuffers (1, &gl_depth_stencil_handle));
> -      GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle));
> -      if (n_samples)
> -        GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER,
> -                                                      n_samples,
> -                                                      GL_DEPTH24_STENCIL8,
> -                                                      width, height));
> +      if (fb->config.need_depth_texture)
> +        {
> +          /* We need a depth texture, so let's attatch a newly created
> +           * GL_DEPTH24_STENCIL8 texture to the GL_DEPTH_ATTACHMENT and
> +           * GL_STENCIL_ATTACHMENT attachement points */
> +          CoglTexture2D *depth_texture;
> +          int width, height;
> +
> +          width = cogl_texture_get_width (offscreen->texture);
> +          height = cogl_texture_get_height (offscreen->texture);
> +
> +          depth_texture =
> +            cogl_texture_2d_new_with_size (ctx,
> +                                           width, height,
> +                                           COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
> +                                           NULL);

It looks like we should check for an error here so we can gracefully
return from try_creating_fbo if creating the depth texture fails.

> +
> +          cogl_texture_get_gl_texture (COGL_TEXTURE (depth_texture),
> +                                       &tex_gl_handle, &tex_gl_target);
> +
> +          GE (ctx, glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER,
> +                                           GL_DEPTH_ATTACHMENT,
> +                                           tex_gl_target, tex_gl_handle,
> +                                           0));
> +          GE (ctx, glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER,
> +                                           GL_STENCIL_ATTACHMENT,
> +                                           tex_gl_target, tex_gl_handle,
> +                                           0));
> +
> +          offscreen->depth_texture = COGL_TEXTURE (depth_texture);
> +          _cogl_texture_associate_framebuffer (offscreen->depth_texture, fb);
> +        }
>       else
> -        GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
> -                                        width, height));
> -      GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0));
> -      GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> -                                          GL_STENCIL_ATTACHMENT,
> -                                          GL_RENDERBUFFER,
> -                                          gl_depth_stencil_handle));
> -      GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> -                                          GL_DEPTH_ATTACHMENT,
> -                                          GL_RENDERBUFFER,
> -                                          gl_depth_stencil_handle));
> -      offscreen->renderbuffers =
> -        g_slist_prepend (offscreen->renderbuffers,
> -                         GUINT_TO_POINTER (gl_depth_stencil_handle));
> +        {
> +          /* renderbuffer for depth and stenciling */
> +          GE (ctx, glGenRenderbuffers (1, &gl_depth_stencil_handle));
> +          GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle));
> +
> +          if (n_samples)
> +            GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER,
> +                                                          n_samples,
> +                                                          GL_DEPTH24_STENCIL8,
> +                                                          width, height));
> +          else
> +            GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER,
> +                                            GL_DEPTH24_STENCIL8,
> +                                            width, height));
> +
> +          GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0));
> +          GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> +                                              GL_STENCIL_ATTACHMENT,
> +                                              GL_RENDERBUFFER,
> +                                              gl_depth_stencil_handle));
> +
> +          GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> +                                              GL_DEPTH_ATTACHMENT,
> +                                              GL_RENDERBUFFER,
> +                                              gl_depth_stencil_handle));
> +          offscreen->renderbuffers =
> +            g_slist_prepend (offscreen->renderbuffers,
> +                             GUINT_TO_POINTER (gl_depth_stencil_handle));
> +        }
>     }
>
>   if (flags & _TRY_DEPTH)
>     {
> -      GE (ctx, glGenRenderbuffers (1, &gl_depth_handle));
> -      GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle));
>       /* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's
>        * available under GLES */
> -      if (n_samples)
> -        GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER,
> -                                                      n_samples,
> -                                                      GL_DEPTH_COMPONENT16,
> -                                                      width, height));
> +
> +      if (fb->config.need_depth_texture)
> +        {
> +          /* We need a depth texture, so let's attatch a newly created
> +           * GL_DEPTH_COMPONENT16 texture to the GL_DEPTH_ATTACHMENT
> +           * attachement point */
> +          CoglTexture2D *depth_texture;
> +          int width, height;
> +
> +          width = cogl_texture_get_width (offscreen->texture);
> +          height = cogl_texture_get_height (offscreen->texture);
> +
> +          depth_texture =
> +            cogl_texture_2d_new_with_size (ctx,
> +                                           width, height,
> +                                           COGL_PIXEL_FORMAT_DEPTH_16,
> +                                           NULL);
> +
> +          cogl_texture_get_gl_texture (COGL_TEXTURE (depth_texture),
> +                                       &tex_gl_handle, &tex_gl_target);
> +
> +          GE (ctx, glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER,
> +                                           GL_DEPTH_ATTACHMENT,
> +                                           tex_gl_target, tex_gl_handle,
> +                                           0));
> +
> +          offscreen->depth_texture = COGL_TEXTURE (depth_texture);
> +          _cogl_texture_associate_framebuffer (offscreen->depth_texture, fb);
> +        }
>       else
> -        GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
> -                                        width, height));
> -      GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0));
> -      GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> -                                          GL_DEPTH_ATTACHMENT,
> -                                          GL_RENDERBUFFER, gl_depth_handle));
> -      offscreen->renderbuffers =
> -        g_slist_prepend (offscreen->renderbuffers,
> -                         GUINT_TO_POINTER (gl_depth_handle));
> +        {
> +          /* renderbuffer for depth and stenciling */
> +          GE (ctx, glGenRenderbuffers (1, &gl_depth_handle));
> +          GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle));
> +          if (n_samples)
> +            GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER,
> +                                                          n_samples,
> +                                                          GL_DEPTH_COMPONENT16,
> +                                                          width, height));
> +          else
> +            GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER,
> +                                            GL_DEPTH_COMPONENT16,
> +                                            width, height));
> +          GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0));
> +          GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER,
> +                                              GL_DEPTH_ATTACHMENT,
> +                                              GL_RENDERBUFFER, gl_depth_handle));
> +          offscreen->renderbuffers =
> +            g_slist_prepend (offscreen->renderbuffers,
> +                             GUINT_TO_POINTER (gl_depth_handle));
> +        }
>     }
>
>   if (flags & _TRY_STENCIL)
> @@ -1792,6 +1865,27 @@ cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer)
>   return framebuffer->format;
>  }
>
> +void
> +cogl_framebuffer_enable_depth_texture (CoglFramebuffer *framebuffer,
> +                                       gboolean         enabled)

s/gboolean/CoglBool/

> +{
> +  _COGL_RETURN_IF_FAIL (!framebuffer->allocated);
> +
> +  framebuffer->config.need_depth_texture = enabled;
> +}
> +
> +CoglTexture *
> +cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer)
> +{
> +  _COGL_RETURN_VAL_IF_FAIL (cogl_is_offscreen (framebuffer),
> +                            COGL_INVALID_HANDLE);

We're well on our way to removing COGL_INVALID_HANDLE from Cogl and
using NULL instead; actually I think we may have even removed it in
master so I guess this is just due to you being based on 1.10
currently.

> +
> +  if (!cogl_framebuffer_allocate (framebuffer, NULL))
> +    return COGL_INVALID_HANDLE;
> +
> +  return COGL_OFFSCREEN(framebuffer)->depth_texture;
> +}
> +
>  int
>  cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer)
>  {
> diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
> index 07886db..7a568f1 100644
> --- a/cogl/cogl-framebuffer.h
> +++ b/cogl/cogl-framebuffer.h
> @@ -43,6 +43,7 @@
>  #include <cogl/cogl-pipeline.h>
>  #include <cogl/cogl-indices.h>
>  #include <cogl/cogl-bitmap.h>
> +#include <cogl/cogl-texture.h>
>
>  G_BEGIN_DECLS
>
> @@ -774,6 +775,47 @@ CoglPixelFormat
>  cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer);
>
>  /**
> + * cogl_framebuffer_enable_depth_texture:
> + * @framebuffer: A #CoglFramebuffer
> + * @enabled: TRUE or FALSE
> + *
> + * If @enabled is #TRUE, the depth buffer used when rendering to @framebuffer
> + * is available as a texture. You can retrieve the texture with
> + * cogl_framebuffer_get_depth_texture().
> + *
> + * <note>It's possible that your GPU does not support depth textures. You
> + * should check the COGL_FEATURE_ID_DEPTH_TEXTURE feature before using this
> + * function.</note>
> + * <note>It's not valid to call this function after the framebuffer has been
> + * allocated as the creation of the depth texture is done at allocation time.
> + * </note>
> + *

Can we perhaps also say that framebuffer allocation will gracefully
fail if this has been enabled but isn't supported?

> + * Since: 2.0
> + */
> +void
> +cogl_framebuffer_enable_depth_texture (CoglFramebuffer *framebuffer,
> +                                       gboolean         enabled);
> +
> +/**
> + * cogl_framebuffer_get_depth_texture:
> + * @framebuffer: A #CoglFramebuffer
> + *
> + * Retrieves the depth buffer of @framebuffer as a #CoglTexture. You need to
> + * call cogl_framebuffer_get_depth_texture(fb, TRUE); before using this
> + * function.
> + *
> + * <note>Calling this function implicitely allocates the framebuffer.</note>
> + * <note>The texture returned stays valid as long as the framebuffer stays
> + * valid.</note>
> + *
> + * Returns: (transfer none): the depth texture

I'm wondering if the semantics should be to actually transfer a
reference to the caller so actually the depth texture can be kept
alive beyond the lifetime of the framebuffer.

Although the color buffer is arguably different, it is possible to
destroy the framebuffer and continue accessing the color buffer
texture. My initial instinct is that I'd like to be able to use a
framebuffer to render to a depth texture and then I want to be able to
get a reference to the texture and potentially free the framebuffer
before using the texture. I might want to re-use the depth texture
multiple times while the geometry of the scene is static and may not
want all the ancillary buffers of a framebuffer lying around in the
mean time. Would it be that tricky to change these semantics?

> + *
> + * Since: 2.0
> + */
> +CoglTexture *
> +cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer);
> +
> +/**
>  * cogl_framebuffer_set_samples_per_pixel:
>  * @framebuffer: A #CoglFramebuffer framebuffer
>  * @samples_per_pixel: The minimum number of samples per pixel
> diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
> index 92c5e9a..73dd9bb 100644
> --- a/cogl/cogl-types.h
> +++ b/cogl/cogl-types.h
> @@ -167,18 +167,22 @@ typedef struct _CoglTextureVertex       CoglTextureVertex;
>  #define COGL_BGR_BIT            (1 << 5)
>  #define COGL_AFIRST_BIT         (1 << 6)
>  #define COGL_PREMULT_BIT        (1 << 7)
> +#define COGL_DEPTH_BIT          (1 << 8)
> +#define COGL_STENCIL_BIT        (1 << 9)
>
>  /* XXX: Notes to those adding new formats here...
>  *
>  * First this diagram outlines how we allocate the 32bits of a
>  * CoglPixelFormat currently...
>  *
> - *                             4 bits for flags
> - *                             |--|
> + *                            6 bits for flags
> + *                          |-----|
>  *  enum        unused             4 bits for the bytes-per-pixel
>  *                                 and component alignment info
> - *  |------| |---------------|     |--|
> - *  00000000 xxxxxxxx xxxxxxxx PFBA0000
> + *  |------| |-------------|       |--|
> + *  00000000 xxxxxxxx xxxxxxSD PFBA0000
> + *                          ^ stencil
> + *                           ^ depth
>  *                             ^ premult
>  *                              ^ alpha first
>  *                               ^ bgr order
> @@ -200,7 +204,7 @@ typedef struct _CoglTextureVertex       CoglTextureVertex;
>  * 4-6   = 2 bpp, not aligned (e.g. 565, 4444, 5551)
>  * 7     = YUV: undefined bpp, undefined alignment
>  * 9     = 2 bpp, aligned
> - * 10    = undefined
> + * 10    = depth, aligned (8, 16, 24, 32, 32f)
>  * 11    = undefined
>  * 12    = 3 bpp, not aligned
>  * 13    = 4 bpp, not aligned (e.g. 2101010)
> @@ -318,7 +322,14 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
>   COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
>   COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
>   COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
> -  COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT)
> +  COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
> +
> +  COGL_PIXEL_FORMAT_DEPTH_ANY = (0 | COGL_DEPTH_BIT),
> +  COGL_PIXEL_FORMAT_DEPTH_16  = (9 | COGL_DEPTH_BIT),
> +  COGL_PIXEL_FORMAT_DEPTH_24  = (2 | COGL_DEPTH_BIT),
> +  COGL_PIXEL_FORMAT_DEPTH_32  = (3 | COGL_DEPTH_BIT),
> +
> +  COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
>  } CoglPixelFormat;
>

My guess is that before 2.0 we will hopefully introduce a separate
enum for the internal format of a texture and so probably these
formats will be taken out again, but for now this looks ok to me

>  /**
> @@ -361,6 +372,8 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
>  *     supported with CoglBufferAccess including read support.
>  * @COGL_FEATURE_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
>  *     supported with CoglBufferAccess including write support.
> + * @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the
> + *     depth buffer to a texture.
>  *
>  * Flags for the supported features.
>  *
> @@ -390,7 +403,8 @@ typedef enum
>   COGL_FEATURE_SHADERS_ARBFP          = (1 << 20),
>   COGL_FEATURE_MAP_BUFFER_FOR_READ    = (1 << 21),
>   COGL_FEATURE_MAP_BUFFER_FOR_WRITE   = (1 << 22),
> -  COGL_FEATURE_ONSCREEN_MULTIPLE      = (1 << 23)
> +  COGL_FEATURE_ONSCREEN_MULTIPLE      = (1 << 23),
> +  COGL_FEATURE_DEPTH_TEXTURE          = (1 << 24)
>  } CoglFeatureFlags;
>
>  /**
> diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c
> index b35ddbe..7bcee59 100644
> --- a/cogl/driver/gl/cogl-gl.c
> +++ b/cogl/driver/gl/cogl-gl.c
> @@ -216,6 +216,13 @@ _cogl_gl_update_features (CoglContext *context,
>                       COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE);
>     }
>
> +  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) ||
> +      _cogl_check_extension ("GL_ARB_depth_texture", gl_extensions))
> +    {
> +      flags |= COGL_FEATURE_DEPTH_TEXTURE;
> +      COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
> +    }
> +
>   if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
>       _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
>     private_flags |= COGL_PRIVATE_FEATURE_PBOS;
> diff --git a/cogl/driver/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/cogl-texture-driver-gl.c
> index 3d46ccb..66b247d 100644
> --- a/cogl/driver/gl/cogl-texture-driver-gl.c
> +++ b/cogl/driver/gl/cogl-texture-driver-gl.c
> @@ -517,6 +517,33 @@ _cogl_texture_driver_pixel_format_to_gl (CoglPixelFormat  format,
>       gltype = GL_UNSIGNED_SHORT_5_5_5_1;
>       break;
>
> +    case COGL_PIXEL_FORMAT_DEPTH_ANY:
> +      glintformat = GL_DEPTH_COMPONENT;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_BYTE;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_16:
> +      glintformat = GL_DEPTH_COMPONENT16;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_SHORT;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_24:
> +      glintformat = GL_DEPTH_COMPONENT24;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_INT;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_32:
> +      glintformat = GL_DEPTH_COMPONENT32;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_INT;
> +      break;
> +
> +    case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
> +      glintformat = GL_DEPTH24_STENCIL8;
> +      glformat = GL_DEPTH_STENCIL;
> +      gltype = GL_UNSIGNED_INT_24_8;
> +      break;
> +
>     case COGL_PIXEL_FORMAT_ANY:
>     case COGL_PIXEL_FORMAT_YUV:
>       g_assert_not_reached ();
> diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c
> index 8087ae0..8ba0cc6 100644
> --- a/cogl/driver/gles/cogl-gles.c
> +++ b/cogl/driver/gles/cogl-gles.c
> @@ -120,6 +120,12 @@ _cogl_gles_update_features (CoglContext *context,
>                       COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
>     }
>
> +  if (_cogl_check_extension ("GL_OES_depth_texture"))
> +    {
> +      flags |= COGL_FEATURE_DEPTH_TEXTURE;
> +      COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
> +    }
> +
>   if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
>     {
>       flags |= (COGL_FEATURE_TEXTURE_NPOT |
> diff --git a/cogl/driver/gles/cogl-texture-driver-gles.c b/cogl/driver/gles/cogl-texture-driver-gles.c
> index 21cfb61..5bee0e6 100644
> --- a/cogl/driver/gles/cogl-texture-driver-gles.c
> +++ b/cogl/driver/gles/cogl-texture-driver-gles.c
> @@ -478,6 +478,33 @@ _cogl_texture_driver_pixel_format_to_gl (CoglPixelFormat  format,
>       gltype = GL_UNSIGNED_SHORT_5_5_5_1;
>       break;
>
> +    case COGL_PIXEL_FORMAT_DEPTH_ANY:
> +      glintformat = GL_DEPTH_COMPONENT;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_BYTE;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_16:
> +      glintformat = GL_DEPTH_COMPONENT16;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_SHORT;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_24:
> +      glintformat = GL_DEPTH_COMPONENT24;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_INT;
> +      break;
> +    case COGL_PIXEL_FORMAT_DEPTH_32:
> +      glintformat = GL_DEPTH_COMPONENT32;
> +      glformat = GL_DEPTH_COMPONENT;
> +      gltype = GL_UNSIGNED_INT;
> +      break;
> +
> +    case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
> +      glintformat = GL_DEPTH24_STENCIL8;
> +      glformat = GL_DEPTH_STENCIL;
> +      gltype = GL_UNSIGNED_INT_24_8;
> +      break;
> +
>     case COGL_PIXEL_FORMAT_ANY:
>     case COGL_PIXEL_FORMAT_YUV:
>       g_assert_not_reached ();
> diff --git a/examples/cogl-info.c b/examples/cogl-info.c
> index 988e991..808f3ed 100644
> --- a/examples/cogl-info.c
> +++ b/examples/cogl-info.c
> @@ -103,6 +103,12 @@ struct {
>     COGL_FEATURE_ID_MIRRORED_REPEAT,
>     "Mirrored repeat wrap modes",
>     "Mirrored repeat wrap modes"
> +  },
> +  {
> +    COGL_FEATURE_ID_DEPTH_TEXTURE,
> +    "Depth Textures",
> +    "CoglFramebuffers can be configured to render their depth buffer into "
> +    "a texture"
>   }
>  };
>
> --
> 1.7.7.5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl


Cool, on the whole this looks good to me.

It would be good to see this rebased onto master.

kind regards,
- Robert


More information about the Cogl mailing list