glthread: Check out of bounds for MultiDrawElementsBaseVertex cmd

Make sure draw count is not high so the MultiDrawElementsBaseVertex cmd
can fit the queue buffer.

v2: add the same check for _mesa_marshal_MultiDrawArrays and add additional
    assert to _mesa_glthread_allocate_command (Pierre-Eric)

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5719
Signed-off-by: Vadym Shovkoplias <vadym.shovkoplias@globallogic.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14490>
This commit is contained in:
Vadym Shovkoplias 2022-01-11 10:21:05 +02:00 committed by Marge Bot
parent 70a4e64685
commit fd2fbc558b
2 changed files with 23 additions and 7 deletions

View file

@ -459,7 +459,7 @@ _mesa_unmarshal_MultiDrawArrays(struct gl_context *ctx,
return cmd->cmd_base.cmd_size;
}
static ALWAYS_INLINE void
static ALWAYS_INLINE bool
multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
const GLint *first, const GLsizei *count,
GLsizei draw_count, unsigned user_buffer_mask,
@ -472,6 +472,11 @@ multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
first_size + count_size + buffers_size;
struct marshal_cmd_MultiDrawArrays *cmd;
/* Make sure cmd can fit the queue buffer */
if (cmd_size > MARSHAL_MAX_CMD_SIZE) {
return false;
}
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArrays,
cmd_size);
cmd->mode = mode;
@ -487,6 +492,8 @@ multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
variable_data += count_size;
memcpy(variable_data, buffers, buffers_size);
}
return true;
}
void GLAPIENTRY
@ -502,8 +509,8 @@ _mesa_marshal_MultiDrawArrays(GLenum mode, const GLint *first,
goto sync;
if (draw_count >= 0 &&
(ctx->API == API_OPENGL_CORE || !user_buffer_mask)) {
multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL);
(ctx->API == API_OPENGL_CORE || !user_buffer_mask) &&
multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL)) {
return;
}
@ -938,7 +945,7 @@ _mesa_unmarshal_MultiDrawElementsBaseVertex(struct gl_context *ctx,
return cmd->cmd_base.cmd_size;
}
static ALWAYS_INLINE void
static ALWAYS_INLINE bool
multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
const GLsizei *count, GLenum type,
const GLvoid *const *indices, GLsizei draw_count,
@ -955,6 +962,11 @@ multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
count_size + indices_size + basevertex_size + buffers_size;
struct marshal_cmd_MultiDrawElementsBaseVertex *cmd;
/* Make sure cmd can fit the queue buffer */
if (cmd_size > MARSHAL_MAX_CMD_SIZE) {
return false;
}
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsBaseVertex, cmd_size);
cmd->mode = mode;
cmd->type = type;
@ -976,6 +988,8 @@ multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
if (user_buffer_mask)
memcpy(variable_data, buffers, buffers_size);
return true;
}
void GLAPIENTRY
@ -999,9 +1013,9 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
(ctx->API == API_OPENGL_CORE ||
!is_index_type_valid(type) ||
(!user_buffer_mask && !has_user_indices))) {
multi_draw_elements_async(ctx, mode, count, type, indices, draw_count,
basevertex, NULL, 0, NULL);
return;
if (multi_draw_elements_async(ctx, mode, count, type, indices,
draw_count, basevertex, NULL, 0, NULL))
return;
}
bool need_index_bounds = user_buffer_mask & ~vao->NonZeroDivisorMask;

View file

@ -59,6 +59,8 @@ _mesa_glthread_allocate_command(struct gl_context *ctx,
struct glthread_state *glthread = &ctx->GLThread;
const unsigned num_elements = align(size, 8) / 8;
assert (num_elements <= MARSHAL_MAX_CMD_SIZE / 8);
if (unlikely(glthread->used + num_elements > MARSHAL_MAX_CMD_SIZE / 8))
_mesa_glthread_flush_batch(ctx);