From 110a5f4f02f5552e6fcbb84e7c9284339b2af9cd Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 21 Oct 2022 09:45:24 -0700 Subject: [PATCH] freedreno/a6xx: Fix buffer size clamping Fixes spec@arb_texture_buffer_object@texture-buffer-size-clamp@* which we start hitting after exposing glsl420 Signed-off-by: Rob Clark Part-of: --- src/gallium/drivers/freedreno/a6xx/fd6_image.c | 11 ++++++++--- src/gallium/drivers/freedreno/a6xx/fd6_texture.c | 7 +++++-- src/gallium/drivers/freedreno/freedreno_screen.c | 5 +++-- src/gallium/drivers/freedreno/freedreno_util.h | 25 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c index 9ffbd83..04e68ab 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c @@ -34,6 +34,7 @@ #include "fd6_image.h" #include "fd6_resource.h" +#include "fd6_screen.h" #include "fd6_texture.h" static const uint8_t swiz_identity[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, @@ -88,11 +89,15 @@ fd6_emit_image_descriptor(struct fd_context *ctx, struct fd_ringbuffer *ring, co } if (buf->resource->target == PIPE_BUFFER) { - uint32_t descriptor[FDL6_TEX_CONST_DWORDS]; + uint32_t descriptor[FDL6_TEX_CONST_DWORDS]; + + uint32_t size = fd_clamp_buffer_size(buf->format, buf->u.buf.size, + A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT); + fdl6_buffer_view_init(descriptor, buf->format, swiz_identity, buf->u.buf.offset, /* Using relocs for addresses */ - buf->u.buf.size); - fd6_emit_single_plane_descriptor(ring, buf->resource, descriptor); + size); + fd6_emit_single_plane_descriptor(ring, buf->resource, descriptor); } else { struct fdl_view_args args = { /* Using relocs for addresses */ diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index c33c09e..ed07afc 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -37,6 +37,7 @@ #include "freedreno_dev_info.h" #include "fd6_emit.h" #include "fd6_resource.h" +#include "fd6_screen.h" #include "fd6_texture.h" static void @@ -233,8 +234,10 @@ fd6_sampler_view_update(struct fd_context *ctx, /* Using relocs for addresses still */ uint64_t iova = cso->u.buf.offset; - fdl6_buffer_view_init(so->descriptor, cso->format, swiz, iova, - cso->u.buf.size); + uint32_t size = fd_clamp_buffer_size(cso->format, cso->u.buf.size, + A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT); + + fdl6_buffer_view_init(so->descriptor, cso->format, swiz, iova, size); } else { struct fdl_view_args args = { /* Using relocs for addresses still */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index ae34bf7..59372c0 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -292,14 +292,15 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) * splitting high bits of index into 2nd dimension.. */ if (is_a3xx(screen)) - return 8192; + return A3XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT; /* Note that the Vulkan blob on a540 and 640 report a * maxTexelBufferElements of just 65536 (the GLES3.2 and Vulkan * minimum). */ if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) - return 1 << 27; + return A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT; + return 0; case PIPE_CAP_TEXTURE_FLOAT_LINEAR: diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index f910337..a75f61f 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -442,6 +442,31 @@ fd_msaa_samples(unsigned samples) } } +#define A3XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT (1 << 13) + +/* Note that the Vulkan blob on a540 and 640 report a + * maxTexelBufferElements of just 65536 (the GLES3.2 and Vulkan + * minimum). + */ +#define A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT (1 << 27) + +static inline uint32_t +fd_clamp_buffer_size(enum pipe_format format, uint32_t size, + unsigned max_texel_buffer_elements) +{ + /* The spec says: + * The number of texels in the texel array is then clamped to the value of + * the implementation-dependent limit GL_MAX_TEXTURE_BUFFER_SIZE. + * + * So compute the number of texels, compare to GL_MAX_TEXTURE_BUFFER_SIZE and update it. + */ + unsigned blocksize = util_format_get_blocksize(format); + unsigned elements = MIN2(max_texel_buffer_elements, size / blocksize); + + return elements * blocksize; +} + + /* * a4xx+ helpers: */ -- 2.7.4