From e8dc3c0c36e830f4b134151ac1e18d979e70f0c6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 11 Jul 2018 14:53:57 -0700 Subject: [PATCH] u_blitter: Add an option to draw the triangles using an index buffer. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For V3D, the HW will interpolate slightly differently along the shared edge of the trifan. The conformance tests manage to catch this in the nearest_consistency_* group. To get interpolation to match, we need the last vertex of the triangle to be shared. I first tried implementing draw_rectangle to do triangles instead, but that was quite a bit (147 lines) of code duplication from u_blitter, and this seems much simpler and less likely to break as u_blitter changes. Fixes dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* on V3D. Reviewed-by: Marek Olšák --- src/gallium/auxiliary/util/u_blitter.c | 16 ++++++++++++++-- src/gallium/auxiliary/util/u_blitter.h | 2 ++ src/gallium/drivers/v3d/v3d_context.c | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 4748627fc52..eadb76a109f 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -1258,8 +1258,20 @@ static void blitter_draw(struct blitter_context_priv *ctx, pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); pipe->bind_vertex_elements_state(pipe, vertex_elements_cso); pipe->bind_vs_state(pipe, get_vs(&ctx->base)); - util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, - 0, num_instances); + + if (ctx->base.use_index_buffer) { + /* Note that for V3D, + * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require + * that the last vert of the two tris be the same. + */ + static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 }; + util_draw_elements_instanced(pipe, indices, 1, 0, + PIPE_PRIM_TRIANGLES, 0, 6, + 0, num_instances); + } else { + util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, + 0, num_instances); + } pipe_resource_reference(&vb.buffer.resource, NULL); } diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 9e945983baa..9ea1dc9b6b2 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -100,6 +100,8 @@ struct blitter_context /* Whether the blitter is running. */ bool running; + bool use_index_buffer; + /* Private members, really. */ struct pipe_context *pipe; /**< pipe context */ diff --git a/src/gallium/drivers/v3d/v3d_context.c b/src/gallium/drivers/v3d/v3d_context.c index cef32ceb069..6fb807b1aa8 100644 --- a/src/gallium/drivers/v3d/v3d_context.c +++ b/src/gallium/drivers/v3d/v3d_context.c @@ -164,6 +164,7 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) v3d->blitter = util_blitter_create(pctx); if (!v3d->blitter) goto fail; + v3d->blitter->use_index_buffer = true; v3d->primconvert = util_primconvert_create(pctx, (1 << PIPE_PRIM_QUADS) - 1); -- 2.30.2