From fd42cdfc01f408ea625aed088ab99d109585704d Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Fri, 23 May 2025 11:43:23 +0200 Subject: [PATCH] mesa/main: support astc_hdr formats This gets a bit annoying because Vulkan has separate format enums for the LDR and HDR ASTC formats, whereas OpenGL uses the same format enums, but allows additional color-endpoint encodings when HDR is supported. Either of these behaviors makes sense on their own, but since we share pipe_format definitions between the APIs, we need to resolve this. This patch does that by checking if the HDR extension is supported, and always using the HDR formats. This works, because the HDR formats are supersets of the LDR formats in terms of features. Not all of the LDR formats have HDR variants, either because they're sRGB or 3D, which either is nonsensical or just not exposed by the ASTC HDR extensions. So we only need to map a subset of the ASTC formats with this HDR-aware mapping. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/mesa/main/formatquery.c | 2 +- src/mesa/main/formats.csv | 15 ++++++++ src/mesa/main/formats.h | 16 +++++++++ src/mesa/main/glformats.c | 2 +- src/mesa/main/texcompress.c | 49 ++++++++++++++++++-------- src/mesa/main/texcompress.h | 2 +- src/mesa/main/teximage.c | 16 ++++----- src/mesa/state_tracker/st_cb_texture.c | 15 ++++++++ src/mesa/state_tracker/st_format.c | 30 ++++++++-------- 9 files changed, 106 insertions(+), 41 deletions(-) diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c index 7d190bb8eda..44d7c3370f6 100644 --- a/src/mesa/main/formatquery.c +++ b/src/mesa/main/formatquery.c @@ -1574,7 +1574,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, mesa_format mesaformat; GLint block_size; - mesaformat = _mesa_glenum_to_compressed_format(internalformat); + mesaformat = _mesa_glenum_to_compressed_format(ctx, internalformat); if (mesaformat == MESA_FORMAT_NONE) goto end; diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv index 6252d830794..c5e09ee54c4 100644 --- a/src/mesa/main/formats.csv +++ b/src/mesa/main/formats.csv @@ -335,6 +335,21 @@ MESA_FORMAT_RGBA_ASTC_10x10 , astc ,10,10, 1, x128, , , MESA_FORMAT_RGBA_ASTC_12x10 , astc ,12,10, 1, x128, , , , xyzw, rgb MESA_FORMAT_RGBA_ASTC_12x12 , astc ,12,12, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_4x4_FLOAT , astc , 4, 4, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_5x4_FLOAT , astc , 5, 4, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_5x5_FLOAT , astc , 5, 5, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_6x5_FLOAT , astc , 6, 5, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_6x6_FLOAT , astc , 6, 6, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_8x5_FLOAT , astc , 8, 5, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_8x6_FLOAT , astc , 8, 6, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_8x8_FLOAT , astc , 8, 8, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_10x5_FLOAT , astc ,10, 5, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_10x6_FLOAT , astc ,10, 6, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_10x8_FLOAT , astc ,10, 8, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_10x10_FLOAT , astc ,10,10, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_12x10_FLOAT , astc ,12,10, 1, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_ASTC_12x12_FLOAT , astc ,12,12, 1, x128, , , , xyzw, rgb + MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4 , astc , 4, 4, 1, x128, , , , xyzw, srgb MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4 , astc , 5, 4, 1, x128, , , , xyzw, srgb MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5 , astc , 5, 5, 1, x128, , , , xyzw, srgb diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index d40b3b31191..50c65aca848 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -598,6 +598,22 @@ typedef enum pipe_format mesa_format; #define MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10 PIPE_FORMAT_ASTC_10x10_SRGB #define MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10 PIPE_FORMAT_ASTC_12x10_SRGB #define MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12 PIPE_FORMAT_ASTC_12x12_SRGB + +#define MESA_FORMAT_RGBA_ASTC_4x4_FLOAT PIPE_FORMAT_ASTC_4x4_FLOAT +#define MESA_FORMAT_RGBA_ASTC_5x4_FLOAT PIPE_FORMAT_ASTC_5x4_FLOAT +#define MESA_FORMAT_RGBA_ASTC_5x5_FLOAT PIPE_FORMAT_ASTC_5x5_FLOAT +#define MESA_FORMAT_RGBA_ASTC_6x5_FLOAT PIPE_FORMAT_ASTC_6x5_FLOAT +#define MESA_FORMAT_RGBA_ASTC_6x6_FLOAT PIPE_FORMAT_ASTC_6x6_FLOAT +#define MESA_FORMAT_RGBA_ASTC_8x5_FLOAT PIPE_FORMAT_ASTC_8x5_FLOAT +#define MESA_FORMAT_RGBA_ASTC_8x6_FLOAT PIPE_FORMAT_ASTC_8x6_FLOAT +#define MESA_FORMAT_RGBA_ASTC_8x8_FLOAT PIPE_FORMAT_ASTC_8x8_FLOAT +#define MESA_FORMAT_RGBA_ASTC_10x5_FLOAT PIPE_FORMAT_ASTC_10x5_FLOAT +#define MESA_FORMAT_RGBA_ASTC_10x6_FLOAT PIPE_FORMAT_ASTC_10x6_FLOAT +#define MESA_FORMAT_RGBA_ASTC_10x8_FLOAT PIPE_FORMAT_ASTC_10x8_FLOAT +#define MESA_FORMAT_RGBA_ASTC_10x10_FLOAT PIPE_FORMAT_ASTC_10x10_FLOAT +#define MESA_FORMAT_RGBA_ASTC_12x10_FLOAT PIPE_FORMAT_ASTC_12x10_FLOAT +#define MESA_FORMAT_RGBA_ASTC_12x12_FLOAT PIPE_FORMAT_ASTC_12x12_FLOAT + #define MESA_FORMAT_RGBA_ASTC_3x3x3 PIPE_FORMAT_ASTC_3x3x3 #define MESA_FORMAT_RGBA_ASTC_4x3x3 PIPE_FORMAT_ASTC_4x3x3 #define MESA_FORMAT_RGBA_ASTC_4x4x3 PIPE_FORMAT_ASTC_4x4x3 diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index 5efd55148f7..7c476bfd220 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -1333,7 +1333,7 @@ _mesa_is_generic_compressed_format(const struct gl_context *ctx, GLboolean _mesa_is_compressed_format(const struct gl_context *ctx, GLenum format) { - mesa_format m_format = _mesa_glenum_to_compressed_format(format); + mesa_format m_format = _mesa_glenum_to_compressed_format(ctx, format); /* Some formats in this switch have an equivalent mesa_format_layout * to the compressed formats in the layout switch below and thus diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index e4a0a590661..1a25a508a4a 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -477,12 +477,43 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) return n; } +static mesa_format +_mesa_astc_ldrhdr_glenum_to_format(const struct gl_context *ctx, GLenum format) +{ + bool has_hdr = _mesa_has_KHR_texture_compression_astc_hdr(ctx); + switch (format) { +#define CASE(x) \ + case GL_COMPRESSED_RGBA_ASTC_ ## x ## _KHR: \ + return has_hdr ? MESA_FORMAT_RGBA_ASTC_ ## x ## _FLOAT : \ + MESA_FORMAT_RGBA_ASTC_ ## x; + + CASE(4x4) + CASE(5x4) + CASE(5x5) + CASE(6x5) + CASE(6x6) + CASE(8x5) + CASE(8x6) + CASE(8x8) + CASE(10x5) + CASE(10x6) + CASE(10x8) + CASE(10x10) + CASE(12x10) + CASE(12x12) + +#undef CASE + + default: + unreachable("unexpected format"); + } +} /** * Convert GLenum to a compressed MESA_FORMAT_x. */ mesa_format -_mesa_glenum_to_compressed_format(GLenum format) +_mesa_glenum_to_compressed_format(const struct gl_context *ctx, GLenum format) { switch (format) { case GL_COMPRESSED_RGB_FXT1_3DFX: @@ -564,33 +595,21 @@ _mesa_glenum_to_compressed_format(GLenum format) return MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT; case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: - return MESA_FORMAT_RGBA_ASTC_4x4; case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: - return MESA_FORMAT_RGBA_ASTC_5x4; case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: - return MESA_FORMAT_RGBA_ASTC_5x5; case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: - return MESA_FORMAT_RGBA_ASTC_6x5; case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: - return MESA_FORMAT_RGBA_ASTC_6x6; case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: - return MESA_FORMAT_RGBA_ASTC_8x5; case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: - return MESA_FORMAT_RGBA_ASTC_8x6; case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: - return MESA_FORMAT_RGBA_ASTC_8x8; case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: - return MESA_FORMAT_RGBA_ASTC_10x5; case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: - return MESA_FORMAT_RGBA_ASTC_10x6; case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: - return MESA_FORMAT_RGBA_ASTC_10x8; case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: - return MESA_FORMAT_RGBA_ASTC_10x10; case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: - return MESA_FORMAT_RGBA_ASTC_12x10; case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: - return MESA_FORMAT_RGBA_ASTC_12x12; + return _mesa_astc_ldrhdr_glenum_to_format(ctx, format); + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4; case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h index 25e02981c1c..aa4bea0362a 100644 --- a/src/mesa/main/texcompress.h +++ b/src/mesa/main/texcompress.h @@ -37,7 +37,7 @@ extern GLuint _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats); extern mesa_format -_mesa_glenum_to_compressed_format(GLenum format); +_mesa_glenum_to_compressed_format(const struct gl_context *ctx, GLenum format); extern GLenum _mesa_compressed_format_to_glenum(struct gl_context *ctx, mesa_format mesaFormat); diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 419bdf8ec2b..ee452ebaa79 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1487,7 +1487,7 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, GLenum intFormat, GLenum *error) { GLboolean target_can_be_compresed = GL_FALSE; - mesa_format format = _mesa_glenum_to_compressed_format(intFormat); + mesa_format format = _mesa_glenum_to_compressed_format(ctx, intFormat); enum mesa_format_layout layout = _mesa_get_format_layout(format); switch (target) { @@ -1775,10 +1775,10 @@ mutable_tex_object(struct gl_texture_object *texObj) * Return expected size of a compressed texture. */ static GLuint -compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, - GLenum glformat) +compressed_tex_size(const struct gl_context *ctx, GLsizei width, GLsizei height, + GLsizei depth, GLenum glformat) { - mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); + mesa_format mesaFormat = _mesa_glenum_to_compressed_format(ctx, glformat); return _mesa_format_image_size(mesaFormat, width, height, depth); } @@ -2209,7 +2209,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, /* Figure out the expected texture size (in bytes). This will be * checked against the actual size later. */ - expectedSize = compressed_tex_size(width, height, depth, internalFormat); + expectedSize = compressed_tex_size(ctx, width, height, depth, internalFormat); break; } @@ -3245,7 +3245,7 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, * texture format since we'll never transcode the user's compressed * image data. The internalFormat was error checked earlier. */ - texFormat = _mesa_glenum_to_compressed_format(internalFormat); + texFormat = _mesa_glenum_to_compressed_format(ctx, internalFormat); } else { /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized @@ -5662,7 +5662,7 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, * * "Modify the "3D Tex." column to be checked for all ASTC formats." */ - format = _mesa_glenum_to_compressed_format(intFormat); + format = _mesa_glenum_to_compressed_format(ctx, intFormat); layout = _mesa_get_format_layout(format); switch (layout) { case MESA_FORMAT_LAYOUT_BPTC: @@ -5764,7 +5764,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, return GL_TRUE; } - expectedSize = compressed_tex_size(width, height, depth, format); + expectedSize = compressed_tex_size(ctx, width, height, depth, format); if (expectedSize != imageSize) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize); return GL_TRUE; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 728ddb9887a..8015ee7cb33 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -408,6 +408,21 @@ st_pbo_get_dst_format(struct gl_context *ctx, enum pipe_texture_target target, case PIPE_FORMAT_BPTC_RGB_UFLOAT: if (!ctx->Extensions.ARB_texture_float) return PIPE_FORMAT_NONE; + FALLTHROUGH; + case PIPE_FORMAT_ASTC_4x4_FLOAT: + case PIPE_FORMAT_ASTC_5x4_FLOAT: + case PIPE_FORMAT_ASTC_5x5_FLOAT: + case PIPE_FORMAT_ASTC_6x5_FLOAT: + case PIPE_FORMAT_ASTC_6x6_FLOAT: + case PIPE_FORMAT_ASTC_8x5_FLOAT: + case PIPE_FORMAT_ASTC_8x6_FLOAT: + case PIPE_FORMAT_ASTC_8x8_FLOAT: + case PIPE_FORMAT_ASTC_10x5_FLOAT: + case PIPE_FORMAT_ASTC_10x6_FLOAT: + case PIPE_FORMAT_ASTC_10x8_FLOAT: + case PIPE_FORMAT_ASTC_10x10_FLOAT: + case PIPE_FORMAT_ASTC_12x10_FLOAT: + case PIPE_FORMAT_ASTC_12x12_FLOAT: dst_glformat = GL_RGBA32F; break; case PIPE_FORMAT_ETC2_R11_UNORM: diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 4c6e1fa26ca..938c4d00480 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -717,59 +717,59 @@ static const struct format_mapping format_map[] = { /* ASTC */ { { GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 0 }, - { PIPE_FORMAT_ASTC_4x4, 0}, + { PIPE_FORMAT_ASTC_4x4_FLOAT, PIPE_FORMAT_ASTC_4x4, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 0 }, - { PIPE_FORMAT_ASTC_5x4, 0}, + { PIPE_FORMAT_ASTC_5x4_FLOAT, PIPE_FORMAT_ASTC_5x4, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 0 }, - { PIPE_FORMAT_ASTC_5x5, 0}, + { PIPE_FORMAT_ASTC_5x5_FLOAT, PIPE_FORMAT_ASTC_5x5, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 0 }, - { PIPE_FORMAT_ASTC_6x5, 0}, + { PIPE_FORMAT_ASTC_6x5_FLOAT, PIPE_FORMAT_ASTC_6x5, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 0 }, - { PIPE_FORMAT_ASTC_6x6, 0}, + { PIPE_FORMAT_ASTC_6x6_FLOAT, PIPE_FORMAT_ASTC_6x6, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 0 }, - { PIPE_FORMAT_ASTC_8x5, 0}, + { PIPE_FORMAT_ASTC_8x5_FLOAT, PIPE_FORMAT_ASTC_8x5, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 0 }, - { PIPE_FORMAT_ASTC_8x6, 0}, + { PIPE_FORMAT_ASTC_8x6_FLOAT, PIPE_FORMAT_ASTC_8x6, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 0 }, - { PIPE_FORMAT_ASTC_8x8, 0}, + { PIPE_FORMAT_ASTC_8x8_FLOAT, PIPE_FORMAT_ASTC_8x8, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 0 }, - { PIPE_FORMAT_ASTC_10x5, 0}, + { PIPE_FORMAT_ASTC_10x5_FLOAT, PIPE_FORMAT_ASTC_10x5, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 0 }, - { PIPE_FORMAT_ASTC_10x6, 0}, + { PIPE_FORMAT_ASTC_10x6_FLOAT, PIPE_FORMAT_ASTC_10x6, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 0 }, - { PIPE_FORMAT_ASTC_10x8, 0}, + { PIPE_FORMAT_ASTC_10x8_FLOAT, PIPE_FORMAT_ASTC_10x8, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 0 }, - { PIPE_FORMAT_ASTC_10x10, 0}, + { PIPE_FORMAT_ASTC_10x10_FLOAT, PIPE_FORMAT_ASTC_10x10, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 0 }, - { PIPE_FORMAT_ASTC_12x10, 0}, + { PIPE_FORMAT_ASTC_12x10_FLOAT, PIPE_FORMAT_ASTC_12x10, 0}, }, { { GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 0 }, - { PIPE_FORMAT_ASTC_12x12, 0}, + { PIPE_FORMAT_ASTC_12x12_FLOAT, PIPE_FORMAT_ASTC_12x12, 0}, }, { @@ -1453,7 +1453,7 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, } if (pFormat == PIPE_FORMAT_NONE) { - mFormat = _mesa_glenum_to_compressed_format(internalFormat); + mFormat = _mesa_glenum_to_compressed_format(ctx, internalFormat); if (st_compressed_format_fallback(st, mFormat)) return mFormat;