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 <cgmeiner@igalia.com>
This commit is contained in:
Christian Gmeiner 2025-11-15 00:03:21 +01:00
parent c9ae59dec5
commit 7dd41c17b5
14 changed files with 23 additions and 32 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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