v3d: Add support for 16bit normalised formats

This is done using unsigned integer formats combined with in shader
conversion. This is incompatible with hardware blending.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35820>
This commit is contained in:
Ella Stanforth 2025-06-29 15:26:21 +01:00 committed by Marge Bot
parent aaa858f958
commit b597e838c2
9 changed files with 69 additions and 36 deletions

View file

@ -14,7 +14,6 @@ spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail
spec@!opengl 1.0@gl-1.0-no-op-paths,Fail
spec@!opengl 1.0@gl-1.0-user-clip-all-planes,Fail
spec@!opengl 1.1@point-line-no-cull,Fail
spec@!opengl 1.1@teximage-colors gl_alpha16@Exact upload-download of GL_ALPHA16,Fail
spec@!opengl 1.1@texwrap formats bordercolor,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled@GL_INTENSITY12- swizzled- border color only,Fail
@ -42,8 +41,6 @@ spec@!opengl 1.1@texwrap formats bordercolor@GL_RGBA16- border color only,Fail
spec@!opengl 1.4@gl-1.4-polygon-offset,Fail
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@arb_copy_image@arb_copy_image-formats,Fail
spec@arb_copy_image@arb_copy_image-formats@Source: GL_ALPHA16/Destination: GL_ALPHA16,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT32F NPOT,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT32F,Fail
@ -190,8 +187,6 @@ spec@ext_framebuffer_multisample@interpolation 2 centroid-edges,Fail
spec@ext_framebuffer_multisample@interpolation 4 centroid-edges,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-clear-and-render,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-rendering,Fail
spec@ext_image_dma_buf_import@ext_image_dma_buf_import-modifiers,Fail
spec@ext_image_dma_buf_import@ext_image_dma_buf_import-modifiers@autogen-R16-DRM_FORMAT_MOD_LINEAR-clear_reimport,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor-swizzled,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor-swizzled@GL_DEPTH24_STENCIL8- swizzled- border color only,Fail
@ -259,8 +254,6 @@ spec@khr_texture_compression_astc@miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@nv_copy_image@nv_copy_image-formats,Fail
spec@nv_copy_image@nv_copy_image-formats@Source: GL_ALPHA16/Destination: GL_ALPHA16,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d-array.frag,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d-array.vert,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d.frag,Fail
@ -348,10 +341,8 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected blue pixel in center,Fai
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on right edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge,Fail
# V3D does not support PIPE_FORMAT_{R16,R16G16,R16G16B16A16}_UNORM for
# V3D does not support PIPE_FORMAT_{R8,R8G8,R8G8B8A8}_UNORM for
# rendering
spec@!opengl 3.0@required-texture-attachment-formats,Fail
spec@!opengl 3.1@required-texture-attachment-formats,Fail
spec@arb_texture_view@rendering-formats,Crash
# V3D does not support blending for GL_R{GBA}32F
@ -394,10 +385,6 @@ spec@oes_texture_view@rendering-formats@clear GL_RGB10_A2 as GL_RG16F,Fail
spec@oes_texture_view@rendering-formats@clear GL_RGB10_A2 as GL_RG16I,Fail
spec@oes_texture_view@rendering-formats@clear GL_RGB10_A2 as GL_RGBA8I,Fail
# This fails the subtest for GL_ALPHA16 because we don't support a 16-bit unorm format for rendering
# so gallium falls back to using an 8-bit unorm format and we lose some precision in the result.
spec@arb_clear_texture@arb_clear_texture-sized-formats,Fail
# These fail because the shaders use indirect indexing on samplers which we
# don't support (the GLSL linker fails to link the shaders because of this).
# If loop unrolling kicks-in for these tests it removes the indirect indexing

View file

@ -16,7 +16,6 @@ spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail
spec@!opengl 1.0@gl-1.0-no-op-paths,Fail
spec@!opengl 1.0@gl-1.0-user-clip-all-planes,Fail
spec@!opengl 1.1@point-line-no-cull,Fail
spec@!opengl 1.1@teximage-colors gl_alpha16@Exact upload-download of GL_ALPHA16,Fail
spec@!opengl 1.1@texwrap formats bordercolor,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled,Fail
spec@!opengl 1.1@texwrap formats bordercolor-swizzled@GL_LUMINANCE12_ALPHA12- swizzled- border color only,Fail
@ -28,8 +27,6 @@ spec@!opengl 1.1@texwrap formats bordercolor@GL_LUMINANCE16_ALPHA16- border colo
spec@!opengl 1.4@gl-1.4-polygon-offset,Fail
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@arb_copy_image@arb_copy_image-formats,Fail
spec@arb_copy_image@arb_copy_image-formats@Source: GL_ALPHA16/Destination: GL_ALPHA16,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT32F NPOT,Fail
spec@arb_depth_buffer_float@fbo-generatemipmap-formats@GL_DEPTH_COMPONENT32F,Fail
@ -173,8 +170,6 @@ spec@ext_framebuffer_multisample@interpolation 2 centroid-edges,Fail
spec@ext_framebuffer_multisample@interpolation 4 centroid-edges,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-clear-and-render,Fail
spec@ext_framebuffer_object@getteximage-formats init-by-rendering,Fail
spec@ext_image_dma_buf_import@ext_image_dma_buf_import-modifiers,Fail
spec@ext_image_dma_buf_import@ext_image_dma_buf_import-modifiers@autogen-R16-DRM_FORMAT_MOD_LINEAR-clear_reimport,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor-swizzled,Fail
spec@ext_packed_depth_stencil@texwrap formats bordercolor-swizzled@GL_DEPTH24_STENCIL8- swizzled- border color only,Fail
@ -229,8 +224,6 @@ spec@khr_texture_compression_astc@miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@nv_copy_image@nv_copy_image-formats,Fail
spec@nv_copy_image@nv_copy_image-formats@Source: GL_ALPHA16/Destination: GL_ALPHA16,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d-array.frag,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d-array.vert,Fail
spec@nv_image_formats@compiler@declaration-disallow-r16-snorm-2d.frag,Fail
@ -320,10 +313,8 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected blue pixel in center,Fai
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on right edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge,Fail
# V3D does not support PIPE_FORMAT_{R16,R16G16,R16G16B16A16}_UNORM for
# V3D does not support PIPE_FORMAT_{R8,R8G8,R8G8B8A8}_SNORM for
# rendering
spec@!opengl 3.0@required-texture-attachment-formats,Fail
spec@!opengl 3.1@required-texture-attachment-formats,Fail
spec@arb_texture_view@rendering-formats,Crash
# V3D does not support blending for GL_R{GBA}32F
@ -334,10 +325,6 @@ spec@!opengl 1.1@getteximage-formats,Fail
spec@!opengl 3.0@sampler-cube-shadow,Fail
spec@arb_texture_cube_map_array@arb_texture_cube_map_array-sampler-cube-array-shadow,Fail
# This fails the subtest for GL_ALPHA16 because we don't support a 16-bit unorm format for rendering
# so gallium falls back to using an 8-bit unorm format and we lose some precision in the result.
spec@arb_clear_texture@arb_clear_texture-sized-formats,Fail
# These fail because the shaders use indirect indexing on samplers which we
# don't support (the GLSL linker fails to link the shaders because of this).
# If loop unrolling kicks-in for these tests it removes the indirect indexing

View file

@ -350,6 +350,15 @@ check_tlb_blit_ok(struct v3d_device_info *devinfo, struct pipe_blit_info *info)
v3d_get_rt_format(devinfo, info->dst.format))
return false;
/* We can not support tlb copies between different formats with
* the same internal format if either format is emulated in shaders.
*/
if ((info->src.format != info->dst.format) &&
(v3d_rt_format_is_emulated(info->src.format) ||
v3d_rt_format_is_emulated(info->dst.format))) {
return false;
}
bool is_msaa_resolve = (info->src.resource->nr_samples > 1 &&
info->dst.resource->nr_samples < 2);

View file

@ -838,6 +838,7 @@ void v3d_flush_jobs_reading_resource(struct v3d_context *v3d,
void v3d_update_compiled_shaders(struct v3d_context *v3d, uint8_t prim_mode);
void v3d_update_compiled_cs(struct v3d_context *v3d);
bool v3d_rt_format_is_emulated(enum pipe_format f);
bool v3d_rt_format_supported(const struct v3d_device_info *devinfo,
enum pipe_format f);
bool v3d_tex_format_supported(const struct v3d_device_info *devinfo,

View file

@ -39,6 +39,22 @@
#define V3D_VERSION 42
#include "v3d_format_table.h"
bool
v3d_rt_format_is_emulated(enum pipe_format f)
{
switch (f) {
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16_UNORM:
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
case PIPE_FORMAT_R16G16_SNORM:
case PIPE_FORMAT_R16_SNORM:
return true;
default:
return false;
}
}
bool
v3d_rt_format_supported(const struct v3d_device_info *devinfo,
enum pipe_format f)

View file

@ -685,6 +685,19 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
key->f32_color_rb |= 1 << i;
}
if (desc->is_unorm && desc->channel[0].size == 16) {
/* We write as integer */
key->f32_color_rb |= 1 << i;
key->norm_16 |= 1 << i;
}
if (desc->is_snorm) {
if (desc->channel[0].size == 16)
key->norm_16 |= 1 << i;
key->snorm |= 1 << i;
key->f32_color_rb |= 1 << i;
}
if (util_format_is_pure_uint(cbuf->format))
key->f32_color_rb |= 1 << i;
else if (util_format_is_pure_sint(cbuf->format))

View file

@ -1748,8 +1748,20 @@ v3d_tlb_clear(struct v3d_job *job, unsigned buffers,
&uc);
memcpy(job->clear_color[i], uc.ui, internal_size);
break;
case V3D_INTERNAL_TYPE_16I:
case V3D_INTERNAL_TYPE_16UI:
case V3D_INTERNAL_TYPE_16I:
if (util_format_is_unorm(psurf->format)) {
util_pack_color(clamped_color.f, PIPE_FORMAT_R16G16B16A16_UNORM,
&uc);
memcpy(job->clear_color[i], uc.ui, internal_size);
break;
}
if (util_format_is_snorm(psurf->format)) {
util_pack_color(clamped_color.f, PIPE_FORMAT_R16G16B16A16_SNORM,
&uc);
memcpy(job->clear_color[i], uc.ui, internal_size);
break;
}
job->clear_color[i][0] = ((clamped_color.ui[0] & 0xffff) |
clamped_color.ui[1] << 16);
job->clear_color[i][1] = ((clamped_color.ui[2] & 0xffff) |

View file

@ -85,18 +85,18 @@ static const struct v3d_format format_table[] = {
FORMAT(R8G8_UNORM, RG8, RG8, SWIZ_XY01, 16, 0),
FORMAT(R8G8_SNORM, NO, RG8_SNORM, SWIZ_XY01, 16, 0),
FORMAT(R16_UNORM, NO, R16, SWIZ_X001, 32, 1),
FORMAT(R16_SNORM, NO, R16_SNORM, SWIZ_X001, 32, 1),
FORMAT(R16_UNORM, R16UI, R16, SWIZ_X001, 32, 1),
FORMAT(R16_SNORM, R16I, R16_SNORM, SWIZ_X001, 32, 1),
FORMAT(R16_FLOAT, R16F, R16F, SWIZ_X001, 16, 0),
FORMAT(R32_FLOAT, R32F, R32F, SWIZ_X001, 32, 1),
FORMAT(R16G16_UNORM, NO, RG16, SWIZ_XY01, 32, 2),
FORMAT(R16G16_SNORM, NO, RG16_SNORM, SWIZ_XY01, 32, 2),
FORMAT(R16G16_UNORM, RG16UI, RG16, SWIZ_XY01, 32, 2),
FORMAT(R16G16_SNORM, RG16I, RG16_SNORM, SWIZ_XY01, 32, 2),
FORMAT(R16G16_FLOAT, RG16F, RG16F, SWIZ_XY01, 16, 0),
FORMAT(R32G32_FLOAT, RG32F, RG32F, SWIZ_XY01, 32, 2),
FORMAT(R16G16B16A16_UNORM, NO, RGBA16, SWIZ_XYZW, 32, 4),
FORMAT(R16G16B16A16_SNORM, NO, RGBA16_SNORM, SWIZ_XYZW, 32, 4),
FORMAT(R16G16B16A16_UNORM, RGBA16UI, RGBA16, SWIZ_XYZW, 32, 4),
FORMAT(R16G16B16A16_SNORM, RGBA16I, RGBA16_SNORM, SWIZ_XYZW, 32, 4),
FORMAT(R16G16B16A16_FLOAT, RGBA16F, RGBA16F, SWIZ_XYZW, 16, 0),
FORMAT(R32G32B32A32_FLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32, 4),

View file

@ -421,7 +421,15 @@ v3dX(clamp_for_format_and_type)(enum V3DX(Internal_Type) rt_type,
case V3D_INTERNAL_TYPE_8:
return V3D_RENDER_TARGET_TYPE_CLAMP_8;
case V3D_INTERNAL_TYPE_16I:
return V3D_RENDER_TARGET_TYPE_CLAMP_16I_CLAMPED;
/* For the 16-bit snorm case we need to take care of sign
* extension. Consider F2SNORM16 for -1.0f. We get
* 0x00008000. This is greater than 2**15 therefore gets
* clamped to 00007fff. If we didn't disable clamping here, we
* would need to sign extend after F2SNORM16 in the shader.
*/
return util_format_is_snorm(format) ?
V3D_RENDER_TARGET_TYPE_CLAMP_16I :
V3D_RENDER_TARGET_TYPE_CLAMP_16I_CLAMPED;
case V3D_INTERNAL_TYPE_16UI:
return V3D_RENDER_TARGET_TYPE_CLAMP_16UI_CLAMPED;
case V3D_INTERNAL_TYPE_16F: