cogl/pixel-format: Support 16 bpc UNORM formats

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3371>
This commit is contained in:
Sebastian Wick 2023-10-31 16:34:48 +01:00 committed by Marge Bot
parent 19472c75be
commit e40a256584
9 changed files with 265 additions and 16 deletions

View File

@ -70,6 +70,8 @@ unpack_flt (uint32_t b)
0x1f) / 0x3f)
#define UNPACK_10(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \
0x1ff) / 0x3ff)
#define UNPACK_16(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \
0x7fff) / 0xffff)
#define UNPACK_SHORT(b) (CLAMP_NORM (cogl_half_to_float (b)) * \
((1 << (sizeof (component_type) * 8)) - 1))
#define UNPACK_FLOAT(b) (CLAMP_NORM (unpack_flt (b)) * \
@ -86,6 +88,7 @@ unpack_flt (uint32_t b)
#define PACK_5(b) PACK_SIZE (b, 0x1f)
#define PACK_6(b) PACK_SIZE (b, 0x3f)
#define PACK_10(b) PACK_SIZE (b, 0x3ff)
#define PACK_16(b) PACK_SIZE (b, 0xffff)
#define PACK_SHORT(b) cogl_float_to_half ( \
(b) / ((1 << (sizeof (component_type) * 8)) - 1))
#define PACK_FLOAT(b) pack_flt ((b) / ((1 << (sizeof (component_type) * 8)) - 1))
@ -121,6 +124,7 @@ unpack_flt (uint32_t b)
#undef UNPACK_5
#undef UNPACK_6
#undef UNPACK_10
#undef UNPACK_16
#undef UNPACK_SHORT
#undef UNPACK_FLOAT
#undef PACK_SIZE
@ -130,6 +134,7 @@ unpack_flt (uint32_t b)
#undef PACK_5
#undef PACK_6
#undef PACK_10
#undef PACK_16
#undef PACK_SHORT
#undef PACK_FLOAT
@ -140,6 +145,7 @@ unpack_flt (uint32_t b)
#define UNPACK_6(b) ((b) / 63.0f)
#define UNPACK_BYTE(b) ((b) / 255.0f)
#define UNPACK_10(b) ((b) / 1023.0f)
#define UNPACK_16(b) ((b) / 65535.0f)
#define UNPACK_SHORT(b) cogl_half_to_float (b)
#define UNPACK_FLOAT(b) unpack_flt (b)
#define PACK_1(b) ((uint32_t) (b))
@ -149,6 +155,7 @@ unpack_flt (uint32_t b)
#define PACK_6(b) ((uint32_t) ((b) * 63.5f))
#define PACK_BYTE(b) ((uint32_t) ((b) * 255.5f))
#define PACK_10(b) ((uint32_t) ((b) * 1023.5f))
#define PACK_16(b) ((uint32_t) ((b) * 65535.0f))
#define PACK_SHORT(b) cogl_float_to_half (b)
#define PACK_FLOAT(b) pack_flt((b) / 1.0)
@ -166,6 +173,7 @@ unpack_flt (uint32_t b)
#undef UNPACK_5
#undef UNPACK_6
#undef UNPACK_10
#undef UNPACK_16
#undef UNPACK_SHORT
#undef UNPACK_FLOAT
#undef PACK_1
@ -174,6 +182,7 @@ unpack_flt (uint32_t b)
#undef PACK_5
#undef PACK_6
#undef PACK_10
#undef PACK_16
#undef PACK_SHORT
#undef PACK_FLOAT
@ -459,8 +468,6 @@ determine_medium_size (CoglPixelFormat format)
{
switch (format)
{
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
@ -501,6 +508,10 @@ determine_medium_size (CoglPixelFormat format)
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
return MEDIUM_TYPE_16;
case COGL_PIXEL_FORMAT_RGBX_FP_16161616:

View File

@ -573,6 +573,60 @@ G_PASTE (_cogl_unpack_rgba_fp_32323232_, component_size) (const uint8_t *src,
}
}
inline static void
G_PASTE (_cogl_unpack_r_16_, component_size) (const uint8_t *src,
component_type *dst,
int width)
{
while (width-- > 0)
{
const uint16_t *v = (const uint16_t *) src;
dst[0] = UNPACK_16 (v[0]);
dst[1] = 0;
dst[2] = 0;
dst[3] = UNPACK_BYTE (255);
dst += 4;
src += 2;
}
}
inline static void
G_PASTE (_cogl_unpack_rg_1616_, component_size) (const uint8_t *src,
component_type *dst,
int width)
{
while (width-- > 0)
{
const uint16_t *v = (const uint16_t *) src;
dst[0] = UNPACK_16 (v[0]);
dst[1] = UNPACK_16 (v[1]);
dst[2] = 0;
dst[3] = UNPACK_BYTE (255);
dst += 4;
src += 4;
}
}
inline static void
G_PASTE (_cogl_unpack_rgba_16161616_, component_size) (const uint8_t *src,
component_type *dst,
int width)
{
while (width-- > 0)
{
const uint16_t *v = (const uint16_t *) src;
dst[0] = UNPACK_16 (v[0]);
dst[1] = UNPACK_16 (v[1]);
dst[2] = UNPACK_16 (v[2]);
dst[3] = UNPACK_16 (v[3]);
dst += 4;
src += 8;
}
}
inline static void
G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
const uint8_t *src,
@ -690,7 +744,15 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format,
G_PASTE (_cogl_unpack_rgba_fp_32323232_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_R_16:
G_PASTE (_cogl_unpack_r_16_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_RG_1616:
G_PASTE (_cogl_unpack_rg_1616_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
G_PASTE (_cogl_unpack_rgba_16161616_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
@ -1227,6 +1289,58 @@ G_PASTE (_cogl_pack_rgba_fp_32323232_, component_size) (const component_type *sr
}
}
inline static void
G_PASTE (_cogl_pack_r_16_, component_size) (const component_type *src,
uint8_t *dst,
int width)
{
while (width-- > 0)
{
uint16_t *v = (uint16_t *) dst;
v[0] = PACK_16 (src[0]);
src += 4;
dst += 2;
}
}
inline static void
G_PASTE (_cogl_pack_rg_1616_, component_size) (const component_type *src,
uint8_t *dst,
int width)
{
while (width-- > 0)
{
uint16_t *v = (uint16_t *) dst;
v[0] = PACK_16 (src[0]);
v[1] = PACK_16 (src[1]);
src += 4;
dst += 4;
}
}
inline static void
G_PASTE (_cogl_pack_rgba_16161616_, component_size) (const component_type *src,
uint8_t *dst,
int width)
{
while (width-- > 0)
{
uint16_t *v = (uint16_t *) dst;
v[0] = PACK_16 (src[0]);
v[1] = PACK_16 (src[1]);
v[2] = PACK_16 (src[2]);
v[3] = PACK_16 (src[3]);
src += 4;
dst += 8;
}
}
inline static void
G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
const component_type *src,
@ -1344,7 +1458,15 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format,
G_PASTE (_cogl_pack_rgba_fp_32323232_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_R_16:
G_PASTE (_cogl_pack_r_16_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_RG_1616:
G_PASTE (_cogl_pack_rg_1616_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
G_PASTE (_cogl_pack_rgba_16161616_, component_size) (src, dst, width);
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:

View File

@ -160,6 +160,7 @@ cogl_context_get_renderer (CoglContext *context);
* texture.
* @COGL_FEATURE_ID_TEXTURE_RGBA1010102: Support for 10bpc RGBA formats
* @COGL_FEATURE_ID_TEXTURE_HALF_FLOAT: Support for half float formats
* @COGL_FEATURE_ID_TEXTURE_NORM16: Support for 16bpc formats
* @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if
* %COGL_INDICES_TYPE_UNSIGNED_INT is supported in
* cogl_indices_new().
@ -186,6 +187,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_TEXTURE_RG,
COGL_FEATURE_ID_TEXTURE_RGBA1010102,
COGL_FEATURE_ID_TEXTURE_HALF_FLOAT,
COGL_FEATURE_ID_TEXTURE_NORM16,
COGL_FEATURE_ID_BUFFER_AGE,
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
COGL_FEATURE_ID_BLIT_FRAMEBUFFER,

View File

@ -119,6 +119,20 @@ static const CoglPixelFormatInfo format_info_table[] = {
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616,
.format_str = "RGBA_16161616",
.n_planes = 1,
.aligned = 1,
.bpp = { 8 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616_PRE,
.format_str = "RGBA_16161616_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 8 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
.format_str = "RGB_888",
@ -133,7 +147,7 @@ static const CoglPixelFormatInfo format_info_table[] = {
.aligned = 1,
.bpp = { 3 },
},
{
{
.cogl_format = COGL_PIXEL_FORMAT_RGBX_8888,
.format_str = "RGBX_8888",
.n_planes = 1,

View File

@ -101,6 +101,7 @@ 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 = 8 bpp, RGBA_161616
* 11 = 8 bpp fp16
* 12 = 16 bpp fp32
* 13 = 4 bpp, not aligned (e.g. 2101010)
@ -142,13 +143,11 @@ G_BEGIN_DECLS
* @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_RG_1616: RG, 32 bits
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
* @COGL_PIXEL_FORMAT_R_8: Single luminance component
* @COGL_PIXEL_FORMAT_R_16: Single luminance component, 16 bits
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
* @COGL_PIXEL_FORMAT_RGBX_8888: RGBX, 32 bits
@ -187,6 +186,9 @@ G_BEGIN_DECLS
* @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
* @COGL_PIXEL_FORMAT_R_16: Single luminance component, 16 bits
* @COGL_PIXEL_FORMAT_RG_1616: RG, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_16161616: RGBA, 64 bits, 16bpc
*
* Pixel formats used by Cogl. For the formats with a byte per
* component, the order of the components specify the order in
@ -217,10 +219,7 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
COGL_PIXEL_FORMAT_YUV = 7,
COGL_PIXEL_FORMAT_R_8 = 8,
COGL_PIXEL_FORMAT_R_16 = 14,
COGL_PIXEL_FORMAT_RG_88 = 9,
COGL_PIXEL_FORMAT_RG_1616 = 15,
COGL_PIXEL_FORMAT_RGB_888 = 2,
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
@ -270,6 +269,11 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
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_R_16 = 14,
COGL_PIXEL_FORMAT_RG_1616 = 15,
COGL_PIXEL_FORMAT_RGBA_16161616 = (10 | COGL_A_BIT),
COGL_PIXEL_FORMAT_RGBA_16161616_PRE = (10 | 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

@ -309,6 +309,23 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_FLOAT;
break;
case COGL_PIXEL_FORMAT_R_16:
glintformat = GL_R16;
glformat = GL_RED;
gltype = GL_UNSIGNED_SHORT;
break;
case COGL_PIXEL_FORMAT_RG_1616:
glintformat = GL_RG16;
glformat = GL_RG;
gltype = GL_UNSIGNED_SHORT;
break;
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
glintformat = GL_RGBA16;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT;
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
glintformat = GL_DEPTH_COMPONENT16;
glformat = GL_DEPTH_COMPONENT;
@ -321,8 +338,6 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_INT_24_8;
break;
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@ -522,6 +537,8 @@ _cogl_driver_update_features (CoglContext *ctx,
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_HALF_FLOAT, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NORM16, TRUE);
if (ctx->glGenQueries && ctx->glQueryCounter && ctx->glGetInteger64v)
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE);

View File

@ -440,9 +440,11 @@ _cogl_texture_driver_upload_supported (CoglContext *ctx,
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:
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
return TRUE;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:

View File

@ -77,6 +77,18 @@
#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
#ifndef GL_R16
#define GL_R16 0x822A
#endif
#ifndef GL_RG16
#define GL_RG16 0x822C
#endif
#ifndef GL_RED
#define GL_RED 0x1903
#endif
#ifndef GL_RGBA16
#define GL_RGBA16 0x805B
#endif
static CoglPixelFormat
_cogl_driver_pixel_format_to_gl (CoglContext *context,
@ -183,6 +195,51 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
&gltype);
break;
case COGL_PIXEL_FORMAT_R_16:
if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16))
{
glintformat = GL_R16;
glformat = GL_RED;
gltype = GL_UNSIGNED_SHORT;
break;
}
else
{
g_assert_not_reached ();
}
break;
case COGL_PIXEL_FORMAT_RG_1616:
if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16))
{
/* NORM16 implies RG for GLES */
g_assert (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG));
glintformat = GL_RG16;
glformat = GL_RG;
gltype = GL_UNSIGNED_SHORT;
break;
}
else
{
g_assert_not_reached ();
}
break;
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NORM16))
{
glintformat = GL_RGBA16;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT;
break;
}
else
{
g_assert_not_reached ();
}
break;
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
if (_cogl_has_private_feature
@ -351,8 +408,6 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_INT_24_8;
break;
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@ -453,10 +508,18 @@ _cogl_driver_get_read_pixels_format (CoglContext *context,
required_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232;
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
/* fixed point normalized 16bpc */
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
required_gl_format = GL_RGBA;
required_gl_type = GL_UNSIGNED_SHORT;
required_format = COGL_PIXEL_FORMAT_RGBA_16161616;
break;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@ -659,7 +722,8 @@ _cogl_driver_update_features (CoglContext *context,
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
#endif
if (_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions))
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) ||
_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions))
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_RG,
TRUE);
@ -680,6 +744,12 @@ _cogl_driver_update_features (CoglContext *context,
TRUE);
}
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 1) &&
_cogl_check_extension ("GL_EXT_texture_norm16", gl_extensions))
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NORM16,
TRUE);
/* Cache features */
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
context->private_features[i] |= private_features[i];

View File

@ -447,6 +447,7 @@ _cogl_texture_driver_upload_supported (CoglContext *ctx,
case COGL_PIXEL_FORMAT_A_8:
case COGL_PIXEL_FORMAT_R_8:
case COGL_PIXEL_FORMAT_RG_88:
return TRUE;
case COGL_PIXEL_FORMAT_BGRX_8888:
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
@ -507,6 +508,12 @@ _cogl_texture_driver_upload_supported (CoglContext *ctx,
return FALSE;
case COGL_PIXEL_FORMAT_R_16:
case COGL_PIXEL_FORMAT_RG_1616:
case COGL_PIXEL_FORMAT_RGBA_16161616:
case COGL_PIXEL_FORMAT_RGBA_16161616_PRE:
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NORM16))
return TRUE;
else
return FALSE;
case COGL_PIXEL_FORMAT_DEPTH_16:
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY: