[Mesa-dev] [PATCH 01/12] panfrost: Fix vertex/index buffer corruption

Alyssa Rosenzweig alyssa at rosenzweig.io
Mon Mar 25 02:01:35 UTC 2019


Fixes a bunch of crashes in dEQP-GLES2.functional.buffer.*

Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
---
 src/gallium/drivers/panfrost/pan_context.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index 2e8a0f03b1a..8c09fa81738 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -744,7 +744,8 @@ panfrost_emit_vertex_data(struct panfrost_context *ctx)
 
         for (int i = 0; i < ctx->vertex_buffer_count; ++i) {
                 struct pipe_vertex_buffer *buf = &ctx->vertex_buffers[i];
-                struct panfrost_resource *rsrc = (struct panfrost_resource *) (buf->buffer.resource);
+                struct panfrost_resource *rsrc = !buf->is_user_buffer ?
+                        (struct panfrost_resource *) (buf->buffer.resource) : NULL;
 
                 /* Let's figure out the layout of the attributes in memory so
                  * we can be smart about size computation. The idea is to
@@ -772,12 +773,17 @@ panfrost_emit_vertex_data(struct panfrost_context *ctx)
                  * rsrc->gpu. However, attribute buffers must be 64 aligned. If
                  * it is not, for now we have to duplicate the buffer. */
 
-                mali_ptr effective_address = (rsrc->bo->gpu[0] + buf->buffer_offset);
+                mali_ptr effective_address = rsrc ? (rsrc->bo->gpu[0] + buf->buffer_offset) : 0;
 
-                if (effective_address & 0x3F) {
+                if (buf->is_user_buffer && buf->buffer.user) {
+                        /* User buffers always have to be uploaded manually (slow) */
+                        attrs[i].elements = panfrost_upload_transient(ctx, (uint8_t *) buf->buffer.user + buf->buffer_offset, attrs[i].size) | 1;
+                } else if (effective_address & 0x3F) {
                         attrs[i].elements = panfrost_upload_transient(ctx, rsrc->bo->cpu[0] + buf->buffer_offset, attrs[i].size) | 1;
-                } else {
+                } else if (effective_address) {
                         attrs[i].elements = effective_address | 1;
+                } else {
+                        /* Something seriously corrupted */
                 }
         }
 
@@ -1383,7 +1389,7 @@ panfrost_get_index_bounds(
         uint64_t key = ((uint64_t) info->start << 32) | ((uint32_t) info->count);
 
         /* Reuse bounds from cache if possible */
-        if (rsrc) {
+        if (rsrc && rsrc->indices) {
                 struct panfrost_indices *cached = (struct panfrost_indices *)
                         _mesa_hash_table_u64_search(rsrc->indices, key);
 
@@ -1421,7 +1427,7 @@ panfrost_get_index_bounds(
         *o_max_index = max_index;
 
         /* Write bounds to cache */
-        if (rsrc) {
+        if (rsrc && rsrc->indices) {
                 struct panfrost_indices *ind = CALLOC_STRUCT(panfrost_indices);
                 ind->min = min_index;
                 ind->max = max_index;
-- 
2.20.1



More information about the mesa-dev mailing list