From e6eed4f32c0e074c0a1279b736962ddb0f2dc6a3 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Mon, 4 Dec 2023 17:52:00 +0100 Subject: [PATCH] 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: --- cogl/cogl/cogl-pixel-format.c | 14 ++++++++++ cogl/cogl/cogl-pixel-format.h | 8 ++++-- cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 7 +++++ .../driver/gl/gl/cogl-texture-driver-gl.c | 2 ++ cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 26 +++++++++++++++++-- .../driver/gl/gles/cogl-texture-driver-gles.c | 2 ++ 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c index 53fafbd59..947277268 100644 --- a/cogl/cogl/cogl-pixel-format.c +++ b/cogl/cogl/cogl-pixel-format.c @@ -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", diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h index c89bba214..9417794e0 100644 --- a/cogl/cogl/cogl-pixel-format.h +++ b/cogl/cogl/cogl-pixel-format.h @@ -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) diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index c20bd3671..174f233af 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -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; diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c index efedeb1bd..ea0243017 100644 --- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c @@ -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: diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 11b271bbb..8174d72b8 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -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); diff --git a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c index bdfac90b3..4b6d87426 100644 --- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c @@ -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