cogl: Add a fp32 format for pixel read-back

We will also require GL_OES_texture_half_float and GLES 3.0 to enable
COGL_FEATURE_ID_TEXTURE_HALF_FLOAT. This gives us float types and makes
it possible to read pixels from framebuffers with internal floating
point formats (into float, half is never supported).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3441>
This commit is contained in:
Sebastian Wick 2023-12-04 17:52:00 +01:00
parent 568506ecbe
commit e6eed4f32c
6 changed files with 55 additions and 4 deletions

View File

@ -385,6 +385,20 @@ static const CoglPixelFormatInfo format_info_table[] = {
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232,
.format_str = "RGBA_FP_32323232",
.n_planes = 1,
.bpp = { 16 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE,
.format_str = "RGBA_FP_32323232_PRE",
.n_planes = 1,
.bpp = { 16 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
.format_str = "DEPTH_16",

View File

@ -101,9 +101,8 @@ G_BEGIN_DECLS
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = YUV: undefined bpp, undefined alignment
* 9 = 2 bpp, aligned
* 10 = depth, aligned (8, 16, 24, 32, 32f)
* 11 = 8 bpp fp16
* 12 = 3 bpp, not aligned
* 12 = 16 bpp fp32
* 13 = 4 bpp, not aligned (e.g. 2101010)
* 14 = 2 bpp, aligned (e.g. G_16)
* 15 = 4 bpp, aligned (e.g. RG_1616)
@ -186,6 +185,8 @@ G_BEGIN_DECLS
* @COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: Premultiplied BGRA half floating point, 64 bit
* @COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: Premultiplied ARGB half floating point, 64 bit
* @COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: Premultiplied ABGR half floating point, 64 bit
* @COGL_PIXEL_FORMAT_RGBA_FP_32323232: RGBA floating point, 128 bit
* @COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE: Premultiplied RGBA floating point, 128 bit
*
* Pixel formats used by Cogl. For the formats with a byte per
* component, the order of the components specify the order in
@ -266,6 +267,9 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
COGL_PIXEL_FORMAT_RGBA_FP_32323232 = (12 | COGL_A_BIT),
COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE = (12 | COGL_A_BIT | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)

View File

@ -302,6 +302,13 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
&gltype);
break;
case COGL_PIXEL_FORMAT_RGBA_FP_32323232:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE:
glintformat = GL_RGBA32F;
glformat = GL_RGBA;
gltype = GL_FLOAT;
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
glintformat = GL_DEPTH_COMPONENT16;
glformat = GL_DEPTH_COMPONENT;

View File

@ -438,6 +438,8 @@ _cogl_texture_driver_upload_supported (CoglContext *ctx,
case COGL_PIXEL_FORMAT_RGBX_FP_16161616:
case COGL_PIXEL_FORMAT_RGBA_FP_16161616:
case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE:
return TRUE;
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:

View File

@ -68,6 +68,9 @@
#ifndef GL_RGBA16F
#define GL_RGBA16F 0x881A
#endif
#ifndef GL_RGBA32F
#define GL_RGBA32F 0x8814
#endif
#ifndef GL_HALF_FLOAT
#define GL_HALF_FLOAT 0x140B
#endif
@ -322,6 +325,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
&gltype);
break;
case COGL_PIXEL_FORMAT_RGBA_FP_32323232:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE:
if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT))
{
glintformat = GL_RGBA32F;
glformat = GL_RGBA;
gltype = GL_FLOAT;
}
else
{
g_assert_not_reached ();
}
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
glintformat = GL_DEPTH_COMPONENT;
glformat = GL_DEPTH_COMPONENT;
@ -429,7 +446,11 @@ _cogl_driver_get_read_pixels_format (CoglContext *context,
case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE:
case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE:
case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE:
g_assert_not_reached ();
case COGL_PIXEL_FORMAT_RGBA_FP_32323232:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE:
required_gl_format = GL_RGBA;
required_gl_type = GL_FLOAT;
required_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232;
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
@ -617,7 +638,8 @@ _cogl_driver_update_features (CoglContext *context,
#endif
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 2) ||
(_cogl_check_extension ("GL_OES_texture_half_float", gl_extensions) &&
(COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) &&
_cogl_check_extension ("GL_OES_texture_half_float", gl_extensions) &&
_cogl_check_extension ("GL_EXT_color_buffer_half_float", gl_extensions)))
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_HALF_FLOAT, TRUE);

View File

@ -499,6 +499,8 @@ _cogl_texture_driver_upload_supported (CoglContext *ctx,
case COGL_PIXEL_FORMAT_RGBX_FP_16161616:
case COGL_PIXEL_FORMAT_RGBA_FP_16161616:
case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232:
case COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE:
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT))
return TRUE;
else