freedreno/a5xx: fix crash in dEQP-GLES31.stress.vertex_attribute_binding.buffer_bound...
authorRob Clark <robdclark@gmail.com>
Thu, 14 Jun 2018 13:34:11 +0000 (09:34 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 19 Jun 2018 17:02:28 +0000 (13:02 -0400)
This is kind of a hack, but really the only problem is the
debug_assert() in OUT_RELOC().  But the debug_assert() is
useful to catch real issues.  So just add some #ifdef DEBUG
code to filter things out before we hit the assert.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.c

index 3419ba8..bab3d3d 100644 (file)
@@ -409,8 +409,17 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
                                        (instance_regid != regid(63, 0)) ||
                                        (vtxcnt_regid != regid(63, 0));
                        bool isint = util_format_is_pure_integer(pfmt);
+                       uint32_t off = vb->buffer_offset + elem->src_offset;
                        uint32_t fs = util_format_get_blocksize(pfmt);
 
+#ifdef DEBUG
+                       /* see dEQP-GLES31.stress.vertex_attribute_binding.buffer_bounds.bind_vertex_buffer_offset_near_wrap_10
+                        * should mesa/st be protecting us from this?
+                        */
+                       if (off > fd_bo_size(rsc->bo))
+                               continue;
+#endif
+
                        debug_assert(fmt != ~0);
 
                        OUT_PKT0(ring, REG_A3XX_VFD_FETCH(j), 2);
@@ -420,7 +429,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
                                        A3XX_VFD_FETCH_INSTR_0_INDEXCODE(j) |
                                        COND(elem->instance_divisor, A3XX_VFD_FETCH_INSTR_0_INSTANCED) |
                                        A3XX_VFD_FETCH_INSTR_0_STEPRATE(MAX2(1, elem->instance_divisor)));
-                       OUT_RELOC(ring, rsc->bo, vb->buffer_offset + elem->src_offset, 0, 0);
+                       OUT_RELOC(ring, rsc->bo, off, 0, 0);
 
                        OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(j), 1);
                        OUT_RING(ring, A3XX_VFD_DECODE_INSTR_CONSTFILL |
index 42268ce..8470fa9 100644 (file)
@@ -418,6 +418,13 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
                        uint32_t size = fd_bo_size(rsc->bo) - off;
                        debug_assert(fmt != ~0);
 
+#ifdef DEBUG
+                       /* see dEQP-GLES31.stress.vertex_attribute_binding.buffer_bounds.bind_vertex_buffer_offset_near_wrap_10
+                        */
+                       if (off > fd_bo_size(rsc->bo))
+                               continue;
+#endif
+
                        OUT_PKT0(ring, REG_A4XX_VFD_FETCH(j), 4);
                        OUT_RING(ring, A4XX_VFD_FETCH_INSTR_0_FETCHSIZE(fs - 1) |
                                        A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vb->stride) |
index 6ce9954..944c62e 100644 (file)
@@ -478,6 +478,13 @@ fd5_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd5_emit *emit)
                        uint32_t size = fd_bo_size(rsc->bo) - off;
                        debug_assert(fmt != ~0);
 
+#ifdef DEBUG
+                       /* see dEQP-GLES31.stress.vertex_attribute_binding.buffer_bounds.bind_vertex_buffer_offset_near_wrap_10
+                        */
+                       if (off > fd_bo_size(rsc->bo))
+                               continue;
+#endif
+
                        OUT_PKT4(ring, REG_A5XX_VFD_FETCH(j), 4);
                        OUT_RELOC(ring, rsc->bo, off, 0, 0);
                        OUT_RING(ring, size);           /* VFD_FETCH[j].SIZE */