summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2021-08-24 12:59:14 -0400
committerDylan Baker <dylan.c.baker@intel.com>2021-09-08 09:39:52 -0700
commit3b028036841bbcfe94f8a7b5cda22808b7870208 (patch)
tree38d60e7ca1129078769a4d6bf6af653e6898f61d
parentb387d54238aae6ef489877d7bcac0d4e4f7cc01b (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.json2
-rw-r--r--src/mesa/main/draw.c22
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;
}
}