From ee41e1bbd2a57f58b616d560451759a4fcd940db Mon Sep 17 00:00:00 2001 From: Andreas Baierl Date: Tue, 21 Sep 2021 18:21:06 +0200 Subject: [PATCH] lima: Fix drawing wide lines GLES2.0 spec allows parts of wide lines and points to be drawn even if their center is outside the viewport. Therefore 0x2000 in PLBU_CMD_PRIMITIVE_SETUP has to be set for points. This is already our default setting as it seems to have no negative effect when this bit is always set. Points work as expected but lines don't. It's hard to RE it, because the affected deqp tests also fail with the blob. To respect this behaviour for lines and solve another 2 tests, we need to do a workaround and temporarily extend the viewport by half of the line width. The scissor rectangle is still equal with the initial viewport. Reviewed-by: Vasily Khoruzhick Signed-off-by: Andreas Baierl Part-of: --- src/gallium/drivers/lima/ci/lima-fails.txt | 2 -- src/gallium/drivers/lima/lima_context.h | 2 ++ src/gallium/drivers/lima/lima_draw.c | 38 +++++++++++++++++++--- src/gallium/drivers/lima/lima_state.c | 12 ++++--- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/lima/ci/lima-fails.txt b/src/gallium/drivers/lima/ci/lima-fails.txt index 4232bffe760..ec9b634fc1e 100644 --- a/src/gallium/drivers/lima/ci/lima-fails.txt +++ b/src/gallium/drivers/lima/ci/lima-fails.txt @@ -1,5 +1,3 @@ -dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_center,Fail -dEQP-GLES2.functional.clipping.line.wide_line_clip_viewport_corner,Fail dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_neg_y_pos_z_and_pos_x_pos_y_neg_z,Fail dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_pos_y_pos_z_and_pos_x_neg_y_neg_z,Fail dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_neg_y_pos_z_and_neg_x_pos_y_neg_z,Fail diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h index 86a668cb4dc..e871d0b952d 100644 --- a/src/gallium/drivers/lima/lima_context.h +++ b/src/gallium/drivers/lima/lima_context.h @@ -209,6 +209,8 @@ struct lima_context { struct lima_context_framebuffer framebuffer; struct lima_context_viewport_state viewport; + /* input for PLBU_CMD_VIEWPORT_* */ + struct lima_context_viewport_state ext_viewport; struct pipe_scissor_state scissor; struct pipe_scissor_state clipped_scissor; struct lima_vs_compiled_shader *vs; diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index c60956629bd..5c9f03b1d1c 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -85,6 +85,32 @@ lima_clip_scissor_to_viewport(struct lima_context *ctx) cscissor->miny = cscissor->maxy; } +static void +lima_extend_viewport(struct lima_context *ctx, const struct pipe_draw_info *info) +{ + /* restore the original values */ + ctx->ext_viewport.left = ctx->viewport.left; + ctx->ext_viewport.right = ctx->viewport.right; + ctx->ext_viewport.bottom = ctx->viewport.bottom; + ctx->ext_viewport.top = ctx->viewport.top; + + if (info->mode != PIPE_PRIM_LINES) + return; + + if (!ctx->rasterizer) + return; + + float line_width = ctx->rasterizer->base.line_width; + + if (line_width == 1.0f) + return; + + ctx->ext_viewport.left = ctx->viewport.left - line_width / 2; + ctx->ext_viewport.right = ctx->viewport.right + line_width / 2; + ctx->ext_viewport.bottom = ctx->viewport.bottom - line_width / 2; + ctx->ext_viewport.top = ctx->viewport.top + line_width / 2; +} + static bool lima_is_scissor_zero(struct lima_context *ctx) { @@ -327,10 +353,10 @@ lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info, struct lima_job *job = lima_job_get(ctx); PLBU_CMD_BEGIN(&job->plbu_cmd_array, 32); - PLBU_CMD_VIEWPORT_LEFT(fui(ctx->viewport.left)); - PLBU_CMD_VIEWPORT_RIGHT(fui(ctx->viewport.right)); - PLBU_CMD_VIEWPORT_BOTTOM(fui(ctx->viewport.bottom)); - PLBU_CMD_VIEWPORT_TOP(fui(ctx->viewport.top)); + PLBU_CMD_VIEWPORT_LEFT(fui(ctx->ext_viewport.left)); + PLBU_CMD_VIEWPORT_RIGHT(fui(ctx->ext_viewport.right)); + PLBU_CMD_VIEWPORT_BOTTOM(fui(ctx->ext_viewport.bottom)); + PLBU_CMD_VIEWPORT_TOP(fui(ctx->ext_viewport.top)); if (!info->index_size) PLBU_CMD_ARRAYS_SEMAPHORE_BEGIN(); @@ -1171,6 +1197,10 @@ lima_draw_vbo(struct pipe_context *pctx, if (lima_is_scissor_zero(ctx)) return; + /* extend the viewport in case of line draws with a line_width > 1.0f, + * otherwise use the original values */ + lima_extend_viewport(ctx, info); + if (!lima_update_fs_state(ctx) || !lima_update_vs_state(ctx)) return; diff --git a/src/gallium/drivers/lima/lima_state.c b/src/gallium/drivers/lima/lima_state.c index 778c793fece..515e8f185c8 100644 --- a/src/gallium/drivers/lima/lima_state.c +++ b/src/gallium/drivers/lima/lima_state.c @@ -212,10 +212,14 @@ lima_set_viewport_states(struct pipe_context *pctx, struct lima_context *ctx = lima_context(pctx); /* reverse calculate the parameter of glViewport */ - ctx->viewport.left = viewport->translate[0] - fabsf(viewport->scale[0]); - ctx->viewport.right = viewport->translate[0] + fabsf(viewport->scale[0]); - ctx->viewport.bottom = viewport->translate[1] - fabsf(viewport->scale[1]); - ctx->viewport.top = viewport->translate[1] + fabsf(viewport->scale[1]); + ctx->viewport.left = ctx->ext_viewport.left = + viewport->translate[0] - fabsf(viewport->scale[0]); + ctx->viewport.right = ctx->ext_viewport.right = + viewport->translate[0] + fabsf(viewport->scale[0]); + ctx->viewport.bottom = ctx->ext_viewport.bottom = + viewport->translate[1] - fabsf(viewport->scale[1]); + ctx->viewport.top = ctx->ext_viewport.top = + viewport->translate[1] + fabsf(viewport->scale[1]); /* reverse calculate the parameter of glDepthRange */ float near, far;