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 <anarsoul@gmail.com>
Signed-off-by: Andreas Baierl <ichgeh@imkreisrum.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12971>
This commit is contained in:
Andreas Baierl 2021-09-21 18:21:06 +02:00 committed by Marge Bot
parent 3e7bac80ce
commit ee41e1bbd2
4 changed files with 44 additions and 10 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;