Mesa (master): lima: fix vertex shader uniform buffer size

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Sep 19 10:01:09 UTC 2020


Module: Mesa
Branch: master
Commit: 95ee0ba41f0c53fe651b9fc12d57b1eb62eea539
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=95ee0ba41f0c53fe651b9fc12d57b1eb62eea539

Author: Erico Nunes <nunes.erico at gmail.com>
Date:   Thu Sep 10 00:02:38 2020 +0200

lima: fix vertex shader uniform buffer size

In some cases when switching shader programs, mesa does not switch the
currently set pipe_constant_buffer, which keeps pointing to the one
previously set.
If the two shader programs have a different number of uniforms, the size
of the constant buffer may be different and this needs to be considered
while generating the next draw command.
This patch fixes the uniform buffer creation in the lima vertex shader
command to avoid an out of bounds memcpy due to a previously set
pipe_constant_buffer.

Signed-off-by: Erico Nunes <nunes.erico at gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6701>

---

 src/gallium/drivers/lima/ir/gp/nir.c    |  2 +-
 src/gallium/drivers/lima/lima_context.h |  6 +-----
 src/gallium/drivers/lima/lima_draw.c    | 19 ++++++++++++-------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/lima/ir/gp/nir.c b/src/gallium/drivers/lima/ir/gp/nir.c
index 33fa35c600a..5143f2ba90b 100644
--- a/src/gallium/drivers/lima/ir/gp/nir.c
+++ b/src/gallium/drivers/lima/ir/gp/nir.c
@@ -456,7 +456,7 @@ bool gpir_compile_nir(struct lima_vs_shader_state *prog, struct nir_shader *nir,
       return false;
 
    comp->constant_base = nir->num_uniforms;
-   prog->uniform_pending_offset = nir->num_uniforms * 16;
+   prog->uniform_size = nir->num_uniforms * 16;
    prog->gl_pos_idx = 0;
    prog->point_size_idx = -1;
 
diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h
index f74554e812c..c8f4cf6f0e3 100644
--- a/src/gallium/drivers/lima/lima_context.h
+++ b/src/gallium/drivers/lima/lima_context.h
@@ -66,11 +66,7 @@ struct lima_vs_shader_state {
    int shader_size;
    int prefetch;
 
-   /* pipe_constant_buffer.size is aligned with some pad bytes,
-    * so record here for the real start place of gpir lowered
-    * uniforms */
-   int uniform_pending_offset;
-
+   int uniform_size;
    void *constant;
    int constant_size;
 
diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c
index 15474a08f9f..469f18eb6ae 100644
--- a/src/gallium/drivers/lima/lima_draw.c
+++ b/src/gallium/drivers/lima/lima_draw.c
@@ -255,6 +255,9 @@ lima_pipe_format_to_attrib_type(enum pipe_format format)
 static void
 lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
 {
+   struct lima_context_constant_buffer *ccb =
+      ctx->const_buffer + PIPE_SHADER_VERTEX;
+   struct lima_vs_shader_state *vs = ctx->vs;
    struct lima_job *job = lima_job_get(ctx);
 
    VS_CMD_BEGIN(&job->vs_cmd_array, 24);
@@ -263,11 +266,12 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
       VS_CMD_ARRAYS_SEMAPHORE_BEGIN_1();
       VS_CMD_ARRAYS_SEMAPHORE_BEGIN_2();
    }
+   int uniform_size = MIN2(vs->uniform_size, ccb->size);
 
-   int uniform_size = ctx->vs->uniform_pending_offset + ctx->vs->constant_size + 32;
+   int size = uniform_size + vs->constant_size + 32;
    VS_CMD_UNIFORMS_ADDRESS(
       lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform),
-      align(uniform_size, 16));
+      align(size, 16));
 
    VS_CMD_SHADER_ADDRESS(ctx->vs->bo->va, ctx->vs->shader_size);
    VS_CMD_SHADER_INFO(ctx->vs->prefetch, ctx->vs->shader_size);
@@ -824,23 +828,24 @@ lima_update_gp_uniform(struct lima_context *ctx)
    struct lima_context_constant_buffer *ccb =
       ctx->const_buffer + PIPE_SHADER_VERTEX;
    struct lima_vs_shader_state *vs = ctx->vs;
+   int uniform_size = MIN2(vs->uniform_size, ccb->size);
 
-   int size = vs->uniform_pending_offset + vs->constant_size + 32;
+   int size = uniform_size + vs->constant_size + 32;
    void *vs_const_buff =
       lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_uniform, size);
 
    if (ccb->buffer)
-      memcpy(vs_const_buff, ccb->buffer, ccb->size);
+      memcpy(vs_const_buff, ccb->buffer, uniform_size);
 
-   memcpy(vs_const_buff + vs->uniform_pending_offset,
+   memcpy(vs_const_buff + uniform_size,
           ctx->viewport.transform.scale,
           sizeof(ctx->viewport.transform.scale));
-   memcpy(vs_const_buff + vs->uniform_pending_offset + 16,
+   memcpy(vs_const_buff + uniform_size + 16,
           ctx->viewport.transform.translate,
           sizeof(ctx->viewport.transform.translate));
 
    if (vs->constant)
-      memcpy(vs_const_buff + vs->uniform_pending_offset + 32,
+      memcpy(vs_const_buff + uniform_size + 32,
              vs->constant, vs->constant_size);
 
    struct lima_job *job = lima_job_get(ctx);



More information about the mesa-commit mailing list