Module: Mesa
Branch: staging/23.3
Commit: f544bd05caf9ff6295028791f52df1d8b5e12c5a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=f544bd05caf9ff6295028791f52df1d8b5e12c5a

Author: Mike Blumenkrantz <michael.blumenkra...@gmail.com>
Date:   Wed Jan  3 10:08:12 2024 -0500

zink: enforce maxTexelBufferElements for texel buffer sizing

according to spec, creating larger texel buffers is legal for apps
but the resulting texel buffer must be clamped to device limits

fixes #10068

backport-to: 23.3

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26873>
(cherry picked from commit 49378bc3cda770493c656e0de1b2e2a1e35d79f4)

---

 .pick_status.json                       |  2 +-
 src/gallium/drivers/zink/zink_context.c | 20 +++++++++++++++-----
 src/gallium/drivers/zink/zink_types.h   |  1 +
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 8ebb6d962cc..dfb633f13ef 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -24,7 +24,7 @@
         "description": "zink: enforce maxTexelBufferElements for texel buffer 
sizing",
         "nominated": true,
         "nomination_type": 4,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null,
         "notes": null
diff --git a/src/gallium/drivers/zink/zink_context.c 
b/src/gallium/drivers/zink/zink_context.c
index c7c0e8ab5c2..db60dd5e1d1 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -709,7 +709,7 @@ update_descriptor_state_sampler(struct zink_context *ctx, 
gl_shader_stage shader
       if (res->obj->is_buffer) {
          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
             ctx->di.db.tbos[shader][slot].address = res->obj->bda + 
ctx->sampler_views[shader][slot]->u.buf.offset;
-            ctx->di.db.tbos[shader][slot].range = 
ctx->sampler_views[shader][slot]->u.buf.size;
+            ctx->di.db.tbos[shader][slot].range = 
zink_sampler_view(ctx->sampler_views[shader][slot])->tbo_size;
             ctx->di.db.tbos[shader][slot].format = zink_get_format(screen, 
ctx->sampler_views[shader][slot]->format);
          } else {
             struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, 
shader, type, slot);
@@ -1199,8 +1199,12 @@ zink_create_sampler_view(struct pipe_context *pctx, 
struct pipe_resource *pres,
       }
       err = !sampler_view->image_view;
    } else {
-      if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
+      if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
+         /* always enforce limit clamping */
+         unsigned blocksize = util_format_get_blocksize(state->format);
+         sampler_view->tbo_size = MIN2(state->u.buf.size / blocksize, 
screen->info.props.limits.maxTexelBufferElements) * blocksize;
          return &sampler_view->base;
+      }
       VkBufferViewCreateInfo bvci = create_bvci(ctx, res, state->format, 
state->u.buf.offset, state->u.buf.size);
       sampler_view->buffer_view = get_buffer_view(ctx, res, &bvci);
       err = !sampler_view->buffer_view;
@@ -1238,9 +1242,10 @@ zink_sampler_view_destroy(struct pipe_context *pctx,
                           struct pipe_sampler_view *pview)
 {
    struct zink_sampler_view *view = zink_sampler_view(pview);
-   if (pview->texture->target == PIPE_BUFFER)
-      zink_buffer_view_reference(zink_screen(pctx->screen), 
&view->buffer_view, NULL);
-   else {
+   if (pview->texture->target == PIPE_BUFFER) {
+      if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
+         zink_buffer_view_reference(zink_screen(pctx->screen), 
&view->buffer_view, NULL);
+   } else {
       zink_surface_reference(zink_screen(pctx->screen), &view->image_view, 
NULL);
       zink_surface_reference(zink_screen(pctx->screen), &view->cube_array, 
NULL);
       zink_surface_reference(zink_screen(pctx->screen), &view->zs_view, NULL);
@@ -1921,6 +1926,11 @@ zink_set_shader_images(struct pipe_context *pctx,
                                           
zink_resource_access_is_write(access), false);
          }
          memcpy(&a->base, images + i, sizeof(struct pipe_image_view));
+         if (b->resource->target == PIPE_BUFFER) {
+            /* always enforce limit clamping */
+            unsigned blocksize = util_format_get_blocksize(a->base.format);
+            a->base.u.buf.size = MIN2(a->base.u.buf.size / blocksize, 
screen->info.props.limits.maxTexelBufferElements) * blocksize;
+         }
          update = true;
          res->image_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
       } else if (a->base.resource) {
diff --git a/src/gallium/drivers/zink/zink_types.h 
b/src/gallium/drivers/zink/zink_types.h
index 6aa00b86c2b..b1aff033b76 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -1664,6 +1664,7 @@ struct zink_sampler_view {
    union {
       struct zink_surface *image_view;
       struct zink_buffer_view *buffer_view;
+      unsigned tbo_size;
    };
    struct zink_surface *cube_array;
    /* Optional sampler view returning red (depth) in all channels, for shader 
rewrites. */

Reply via email to