From 7dd41c17b528058bc881234e0f697209eb7ae2a2 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sat, 15 Nov 2025 00:03:21 +0100 Subject: [PATCH] mesa/main: Reject unsized RGB half-float textures as framebuffer attachments in GLES2 GL_EXT_color_buffer_half_float specifies that for unsized texture formats, only "internalformat = RGBA, format = RGBA, type = HALF_FLOAT_OES" textures are renderable (see "Dependencies on OES_texture_half_float" section of the spec). RGB half-float textures are not included. This is distinct from sized renderbuffer formats where both RGB16F_EXT and RGBA16F_EXT are color-renderable. While fixing this, also refactor the float type tracking in gl_texture_object: replace the separate _IsFloat and _IsHalfFloat booleans with a single _FloatType enum that stores the actual type (GL_FLOAT, GL_HALF_FLOAT, GL_HALF_FLOAT_OES, or 0). This allows us to correctly distinguish between GL_HALF_FLOAT_OES (covered by EXT_color_buffer_half_float) and GL_HALF_FLOAT (ES3+, not covered by any extension for unsized formats). The renderability rules are now: - Unsized GL_RGB with any float type: never color-renderable - Unsized GL_RGBA with GL_FLOAT: never color-renderable - Unsized GL_RGBA with GL_HALF_FLOAT: never color-renderable - Unsized GL_RGBA with GL_HALF_FLOAT_OES: requires EXT_color_buffer_half_float Fixes dEQP-GLES2 test expecting RGB half-float attachments to be incomplete: dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes Signed-off-by: Christian Gmeiner --- src/etnaviv/ci/etnaviv-gc3000-r5450-fails.txt | 1 - src/etnaviv/ci/etnaviv-gc7000-r6204-fails.txt | 1 - src/etnaviv/ci/etnaviv-gc7000-r6214-fails.txt | 1 - .../drivers/crocus/ci/crocus-g41-fails.txt | 3 --- .../drivers/r300/ci/r300-rs740-fails.txt | 2 -- .../drivers/r300/ci/r300-rv380-fails.txt | 1 - .../drivers/r300/ci/r300-rv410-fails.txt | 1 - .../r300/ci/r300-rv530-nohiz-fails.txt | 4 ---- src/mesa/main/fbobject.c | 20 ++++++++++++++----- src/mesa/main/mtypes.h | 3 +-- src/mesa/main/teximage.c | 7 ++----- src/mesa/main/texobj.c | 8 ++++---- src/mesa/state_tracker/st_atom_sampler.c | 2 +- src/panfrost/ci/panfrost-t720-fails.txt | 1 - 14 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/etnaviv/ci/etnaviv-gc3000-r5450-fails.txt b/src/etnaviv/ci/etnaviv-gc3000-r5450-fails.txt index 10ea19724d3..d78a13e8c79 100644 --- a/src/etnaviv/ci/etnaviv-gc3000-r5450-fails.txt +++ b/src/etnaviv/ci/etnaviv-gc3000-r5450-fails.txt @@ -4,7 +4,6 @@ dEQP-GLES2.functional.fbo.completeness.renderable.renderbuffer.depth.r16f,Fail dEQP-GLES2.functional.fbo.completeness.renderable.renderbuffer.depth.rg16f,Fail dEQP-GLES2.functional.fbo.completeness.renderable.renderbuffer.stencil.r16f,Fail dEQP-GLES2.functional.fbo.completeness.renderable.renderbuffer.stencil.rg16f,Fail -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.shaders.invariance.highp.loop_2,Fail dEQP-GLES2.functional.shaders.invariance.highp.subexpression_precision_lowp,Fail dEQP-GLES2.functional.shaders.invariance.lowp.loop_2,Fail diff --git a/src/etnaviv/ci/etnaviv-gc7000-r6204-fails.txt b/src/etnaviv/ci/etnaviv-gc7000-r6204-fails.txt index 18669ccd96f..f8965445f8e 100644 --- a/src/etnaviv/ci/etnaviv-gc7000-r6204-fails.txt +++ b/src/etnaviv/ci/etnaviv-gc7000-r6204-fails.txt @@ -1,4 +1,3 @@ -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.shaders.operator.selection.highp_float_fragment,Fail dEQP-GLES2.functional.shaders.operator.selection.highp_int_fragment,Fail dEQP-GLES2.functional.shaders.operator.selection.highp_ivec2_fragment,Fail diff --git a/src/etnaviv/ci/etnaviv-gc7000-r6214-fails.txt b/src/etnaviv/ci/etnaviv-gc7000-r6214-fails.txt index eb195f2e5ae..da4b198a55a 100644 --- a/src/etnaviv/ci/etnaviv-gc7000-r6214-fails.txt +++ b/src/etnaviv/ci/etnaviv-gc7000-r6214-fails.txt @@ -1,4 +1,3 @@ -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.rasterization.primitives.lines_wide,Fail dEQP-GLES2.functional.shaders.operator.selection.highp_float_fragment,Fail dEQP-GLES2.functional.shaders.operator.selection.highp_int_fragment,Fail diff --git a/src/gallium/drivers/crocus/ci/crocus-g41-fails.txt b/src/gallium/drivers/crocus/ci/crocus-g41-fails.txt index 9f2416fbb48..65705c54a5c 100644 --- a/src/gallium/drivers/crocus/ci/crocus-g41-fails.txt +++ b/src/gallium/drivers/crocus/ci/crocus-g41-fails.txt @@ -20,9 +20,6 @@ dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner,Fail dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_pos_z_and_neg_x_neg_y_neg_z,Fail dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_y_neg_z_and_neg_x_neg_y_pos_z,Fail -# RGB/RGBA half float should be incomplete, tested as complete. -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail - dEQP-GLES2.functional.shaders.texture_functions.vertex.texturecubelod,Fail # Subpixel precision errors diff --git a/src/gallium/drivers/r300/ci/r300-rs740-fails.txt b/src/gallium/drivers/r300/ci/r300-rs740-fails.txt index 29ad009a7d1..c6ba9f08d99 100644 --- a/src/gallium/drivers/r300/ci/r300-rs740-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rs740-fails.txt @@ -32,8 +32,6 @@ dEQP-GLES2.functional.draw.random.70,Fail dEQP-GLES2.functional.draw.random.71,Fail dEQP-GLES2.functional.draw.random.8,Fail -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail - dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgb,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgba,Fail diff --git a/src/gallium/drivers/r300/ci/r300-rv380-fails.txt b/src/gallium/drivers/r300/ci/r300-rv380-fails.txt index b71fac13773..0cba7865e9b 100644 --- a/src/gallium/drivers/r300/ci/r300-rv380-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv380-fails.txt @@ -3,7 +3,6 @@ dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_center,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner,Fail -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgb,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgba,Fail diff --git a/src/gallium/drivers/r300/ci/r300-rv410-fails.txt b/src/gallium/drivers/r300/ci/r300-rv410-fails.txt index 44d7e3dc8d5..378d50f15cb 100644 --- a/src/gallium/drivers/r300/ci/r300-rv410-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv410-fails.txt @@ -3,7 +3,6 @@ dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_center,Fail dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner,Fail -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgb,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgba,Fail diff --git a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt index 61f35fd6e7d..634dc39250e 100644 --- a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt @@ -5,10 +5,6 @@ dEQP-GLES2.functional.clipping.point.wide_point_clip_viewport_corner,Fail dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_center,Fail dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail - -# "Framebuffer checked as complete, expected incomplete" -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail - dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgb,Fail dEQP-GLES2.functional.fbo.render.repeated_clear.tex2d_rgba,Fail diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index e89567eb132..77071347173 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -915,14 +915,24 @@ gles_check_float_renderable(const struct gl_context *ctx, if (!att->Texture || !is_float_format(att->Renderbuffer->InternalFormat)) return true; - /* GL_RGBA with unsized GL_FLOAT type, no extension can make this - * color renderable. + /* We don't support any extension that makes unsized GL_RGB with float + * or half-float color-renderable. */ - if (att->Texture->_IsFloat && att->Renderbuffer->_BaseFormat == GL_RGBA) + if (att->Texture->_FloatType && att->Renderbuffer->_BaseFormat == GL_RGB) return false; - /* Unsized GL_HALF_FLOAT supported only with EXT_color_buffer_half_float. */ - if (att->Texture->_IsHalfFloat && !_mesa_has_EXT_color_buffer_half_float(ctx)) + /* Unsized GL_FLOAT is never color-renderable (EXT_color_buffer_float + * only covers sized formats). + */ + if (att->Texture->_FloatType == GL_FLOAT) + return false; + + /* Unsized GL_HALF_FLOAT (non-OES) is never color-renderable. */ + if (att->Texture->_FloatType == GL_HALF_FLOAT) + return false; + + /* Unsized GL_HALF_FLOAT_OES supported only with EXT_color_buffer_half_float. */ + if (att->Texture->_FloatType == GL_HALF_FLOAT_OES && !_mesa_has_EXT_color_buffer_half_float(ctx)) return false; const struct gl_texture_object *texObj = att->Texture; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 66d890cb89d..5a7183db9e9 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -932,8 +932,7 @@ struct gl_texture_object GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */ GLboolean _RenderToTexture; /**< Any rendering to this texture? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ - GLboolean _IsFloat; /**< GL_OES_float_texture */ - GLboolean _IsHalfFloat; /**< GL_OES_half_float_texture */ + GLenum16 _FloatType; /**< GL_FLOAT, GL_HALF_FLOAT, GL_HALF_FLOAT_OES, or 0 */ bool HandleAllocated; /**< GL_ARB_bindless_texture */ bool DeletePending; /**< true if texture object is removed from the hash */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index d8c5ca50452..748c70789d0 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3197,11 +3197,8 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, * internal floating point format for the given base format. */ if (_mesa_is_gles(ctx) && format == internalFormat) { - if (type == GL_FLOAT) { - texObj->_IsFloat = GL_TRUE; - } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { - texObj->_IsHalfFloat = GL_TRUE; - } + if (type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES) + texObj->_FloatType = type; internalFormat = adjust_for_oes_float_texture(ctx, format, type); } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 72c56967657..2cd99317b8b 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -76,9 +76,9 @@ valid_filter_for_float(const struct gl_context *ctx, { switch (obj->Sampler.Attrib.MagFilter) { case GL_LINEAR: - if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + if (obj->_FloatType == GL_HALF_FLOAT_OES && !ctx->Extensions.OES_texture_half_float_linear) { return false; - } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + } else if (obj->_FloatType == GL_FLOAT && !ctx->Extensions.OES_texture_float_linear) { return false; } FALLTHROUGH; @@ -94,9 +94,9 @@ valid_filter_for_float(const struct gl_context *ctx, case GL_NEAREST_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_LINEAR: - if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + if (obj->_FloatType == GL_HALF_FLOAT_OES && !ctx->Extensions.OES_texture_half_float_linear) { return false; - } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + } else if (obj->_FloatType == GL_FLOAT && !ctx->Extensions.OES_texture_float_linear) { return false; } FALLTHROUGH; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index a123be3703f..74165fb4f03 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -71,7 +71,7 @@ st_convert_sampler(const struct st_context *st, sampler->seamless_cube_map |= seamless_cube_map; if (texobj->_IsIntegerFormat || - (texobj->_IsFloat && st->ctx->Const.ForceFloat32TexNearest)) { + (texobj->_FloatType == GL_FLOAT && st->ctx->Const.ForceFloat32TexNearest)) { sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST; sampler->min_mip_filter = PIPE_TEX_FILTER_NEAREST; sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST; diff --git a/src/panfrost/ci/panfrost-t720-fails.txt b/src/panfrost/ci/panfrost-t720-fails.txt index d5b56da96f3..1ffb246d29f 100644 --- a/src/panfrost/ci/panfrost-t720-fails.txt +++ b/src/panfrost/ci/panfrost-t720-fails.txt @@ -18,7 +18,6 @@ dEQP-GLES2.functional.fragment_ops.interaction.basic_shader.62,Fail dEQP-GLES2.functional.fragment_ops.interaction.basic_shader.73,Fail dEQP-GLES2.functional.fragment_ops.interaction.basic_shader.81,Fail dEQP-GLES2.functional.fragment_ops.random.43,Fail -dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.rgb_half_float_oes,Fail dEQP-GLES2.functional.texture.vertex.cube.filtering.nearest_mipmap_linear_linear_clamp,Fail dEQP-GLES2.functional.texture.vertex.cube.filtering.nearest_mipmap_linear_linear_mirror,Fail dEQP-GLES2.functional.texture.vertex.cube.filtering.nearest_mipmap_linear_linear_repeat,Fail