mesa: fix draw mesh shader indirect buffer size check
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

We should not count the last draw command stride padding in
the indirect buffer.

Fixes: 176740c26f4 ("mesa: implement mesh shader draw calls")
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37392>
This commit is contained in:
Qiang Yu 2025-09-16 15:43:41 +08:00 committed by Marge Bot
parent 85ec0fffa2
commit faebbf9640

View file

@ -15,6 +15,12 @@
#include "pipe/p_context.h" #include "pipe/p_context.h"
#include "pipe/p_screen.h" #include "pipe/p_screen.h"
typedef struct {
GLuint x;
GLuint y;
GLuint z;
} DrawMeshTasksIndirectCommand;
static bool static bool
check_mesh_shader_present(struct gl_context *ctx, const char *function) check_mesh_shader_present(struct gl_context *ctx, const char *function)
{ {
@ -144,7 +150,7 @@ validate_draw_mesh_tasks_indirect(struct gl_context *ctx, GLintptr indirect,
return false; return false;
} }
if (stride < 3 * sizeof(GLuint)) { if (stride < sizeof(DrawMeshTasksIndirectCommand)) {
_mesa_error(ctx, GL_INVALID_VALUE, _mesa_error(ctx, GL_INVALID_VALUE,
"%s(stride is less then DrawMeshTasksIndirectCommandEXT)", name); "%s(stride is less then DrawMeshTasksIndirectCommandEXT)", name);
return false; return false;
@ -156,7 +162,7 @@ validate_draw_mesh_tasks_indirect(struct gl_context *ctx, GLintptr indirect,
return false; return false;
} }
GLsizei size = stride * drawcount; GLsizei size = stride * (drawcount - 1) + sizeof(DrawMeshTasksIndirectCommand);
const uint64_t end = (uint64_t) indirect + size; const uint64_t end = (uint64_t) indirect + size;
if (ctx->DrawIndirectBuffer->Size < end) { if (ctx->DrawIndirectBuffer->Size < end) {
@ -175,7 +181,8 @@ _mesa_DrawMeshTasksIndirectEXT(GLintptr indirect)
if (!_mesa_is_no_error_enabled(ctx) && if (!_mesa_is_no_error_enabled(ctx) &&
!validate_draw_mesh_tasks_indirect( !validate_draw_mesh_tasks_indirect(
ctx, indirect, 1, 3 * sizeof(GLuint), "glDrawMeshTasksIndirectEXT")) ctx, indirect, 1, sizeof(DrawMeshTasksIndirectCommand),
"glDrawMeshTasksIndirectEXT"))
return; return;
struct pipe_grid_info info = { struct pipe_grid_info info = {
@ -196,7 +203,7 @@ _mesa_MultiDrawMeshTasksIndirectEXT(GLintptr indirect,
/* If <stride> is zero, the array elements are treated as tightly packed. */ /* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0) if (stride == 0)
stride = 3 * sizeof(GLuint); stride = sizeof(DrawMeshTasksIndirectCommand);
if (!_mesa_is_no_error_enabled(ctx) && if (!_mesa_is_no_error_enabled(ctx) &&
!validate_draw_mesh_tasks_indirect( !validate_draw_mesh_tasks_indirect(
@ -270,7 +277,7 @@ _mesa_MultiDrawMeshTasksIndirectCountEXT(GLintptr indirect,
/* If <stride> is zero, the array elements are treated as tightly packed. */ /* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0) if (stride == 0)
stride = 3 * sizeof(GLuint); stride = sizeof(DrawMeshTasksIndirectCommand);
if (!_mesa_is_no_error_enabled(ctx) && if (!_mesa_is_no_error_enabled(ctx) &&
!validate_multi_draw_mesh_tasks_indirect_count(ctx, indirect, drawcount, !validate_multi_draw_mesh_tasks_indirect_count(ctx, indirect, drawcount,