diff options
author | Marek Olšák <marek.olsak@amd.com> | 2021-08-24 12:59:14 -0400 |
---|---|---|
committer | Dylan Baker <dylan.c.baker@intel.com> | 2021-09-08 09:39:52 -0700 |
commit | 3b028036841bbcfe94f8a7b5cda22808b7870208 (patch) | |
tree | 38d60e7ca1129078769a4d6bf6af653e6898f61d | |
parent | b387d54238aae6ef489877d7bcac0d4e4f7cc01b (diff) |
mesa: skip draw calls with unaligned indices
GL doesn't say which error we should report. dEQP expects no error and
no crash and allows skipping the call. Some drivers can crash.
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5227
Cc: mesa-stable@lists.freedesktop.org
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12533>
(cherry picked from commit 6367d8036a261b7b5d0559d680c66697f488ad17)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/mesa/main/draw.c | 22 |
2 files changed, 22 insertions, 2 deletions
diff --git a/.pick_status.json b/.pick_status.json index 9c19dd0c1c8..b6eedb2a452 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2497,7 +2497,7 @@ "description": "mesa: skip draw calls with unaligned indices", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 12d306147bd..07e227d8268 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -202,6 +202,22 @@ valid_elements_type(struct gl_context *ctx, GLenum type) return GL_NO_ERROR; } +static inline bool +indices_aligned(unsigned index_size_shift, const GLvoid *indices) +{ + /* Require that indices are aligned to the element size. GL doesn't specify + * an error for this, but the ES 3.0 spec says: + * + * "Clients must align data elements consistently with the requirements + * of the client platform, with an additional base-level requirement + * that an offset within a buffer to a datum comprising N basic machine + * units be a multiple of N" + * + * This is only required by index buffers, not user indices. + */ + return ((uintptr_t)indices & ((1 << index_size_shift) - 1)) == 0; +} + static GLenum validate_DrawElements_common(struct gl_context *ctx, GLenum mode, GLsizei count, GLsizei numInstances, GLenum type) @@ -1723,6 +1739,9 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, unsigned index_size_shift = get_index_size_shift(type); struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; + if (index_bo && !indices_aligned(index_size_shift, indices)) + return; + info.mode = mode; info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 1 << index_size_shift; @@ -2155,7 +2174,8 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } else { for (int i = 0; i < primcount; i++) { draw[i].start = (uintptr_t)indices[i] >> index_size_shift; - draw[i].count = count[i]; + draw[i].count = + indices_aligned(index_size_shift, indices[i]) ? count[i] : 0; draw[i].index_bias = basevertex ? basevertex[i] : 0; } } |