From 47c9c1869c253bf0de4e9f8bd2ee122c809f546f Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 29 Jul 2025 10:00:33 +0200 Subject: [PATCH] llvmpipe: Fix attribute interpolation setup when rendering lines with msaa If multisampling is enabled, we effectively always use pixel offset 0 for the purposes of setup, overriding half pixel center. However, line setup (and by the looks of it rectangle as well), while honoring this for the purposes of setting up the rasterization planes, it forgot to do this adjustment when setting up attribute interpolation, hence attribute interpolation for lines ended up wrong. Rather than fixing this up in line setup, just override pixel_offset in setup context when using msaa, since this is what we actually do, which simplifies the logic (do the same for the key for the setup jit function as well). Reviewed-by: Brian Paul Reviewed-by: Lucas Fryzek Part-of: --- src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- src/gallium/drivers/llvmpipe/lp_setup_line.c | 2 +- src/gallium/drivers/llvmpipe/lp_setup_point.c | 4 +-- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 2 +- src/gallium/drivers/llvmpipe/lp_state_setup.c | 28 +++++++++---------- src/gallium/drivers/llvmpipe/lp_state_setup.h | 1 - 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 4a68aeb03db..20432ee269b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -585,7 +585,7 @@ lp_setup_bind_rasterizer(struct lp_setup_context *setup, setup->triangle = first_triangle; setup->rect = first_rectangle; setup->multisample = rast->multisample; - setup->pixel_offset = rast->half_pixel_center ? 0.5f : 0.0f; + setup->pixel_offset = !rast->multisample && rast->half_pixel_center ? 0.5f : 0.0f; setup->bottom_edge_rule = rast->bottom_edge_rule; if (setup->scissor_test != rast->scissor) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index bd1deaea23e..51727168193 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -336,7 +336,7 @@ try_setup_line(struct lp_setup_context *setup, info.v1 = v1; info.v2 = v2; - const float pixel_offset = setup->multisample ? 0.0 : setup->pixel_offset; + const float pixel_offset = setup->pixel_offset; int x[4], y[4]; if (setup->rectangular_lines) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index 5d1786ed4da..f9769adde35 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -115,7 +115,7 @@ texcoord_coef(struct lp_setup_context *setup, assert(i < 4); - const float pixel_offset = setup->multisample ? 0.0 : setup->pixel_offset; + const float pixel_offset = setup->pixel_offset; if (i == 0) { float dadx = FIXED_ONE / (float)info->dx12; float dady = 0.0f; @@ -343,7 +343,7 @@ try_setup_point(struct lp_setup_context *setup, * slightly different rounding. */ const int adj = (setup->bottom_edge_rule != 0) ? 1 : 0; - const float pixel_offset = setup->multisample ? 0.0 : setup->pixel_offset; + const float pixel_offset = setup->pixel_offset; struct lp_scene *scene = setup->scene; int x[2], y[2]; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 02e8e04f588..8a14e87480c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -1040,7 +1040,7 @@ calc_fixed_position(struct lp_setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { - float pixel_offset = setup->multisample ? 0.0 : setup->pixel_offset; + float pixel_offset = setup->pixel_offset; /* * The rounding may not be quite the same with DETECT_ARCH_SSE * (util_iround right now only does nearest/even on x87, diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 1de79960c9a..f72a450e717 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -566,7 +566,7 @@ init_args(struct gallivm_state *gallivm, load_attribute(gallivm, args, key, 0, attr_pos); pixel_center = lp_build_const_vec(gallivm, typef4, - (!key->multisample && key->pixel_center_half) ? 0.5 : 0.0); + key->pixel_center_half ? 0.5 : 0.0); /* * xy are first two elems in v0a/v1a/v2a but just use vec4 arit @@ -774,15 +774,15 @@ lp_make_setup_variant_key(const struct llvmpipe_context *lp, struct lp_setup_variant_key *key) { const struct lp_fragment_shader *fs = lp->fs; + const struct pipe_rasterizer_state *rast = lp->rasterizer; struct nir_shader *nir = fs->base.ir.nir; assert(sizeof key->inputs[0] == sizeof(uint)); key->num_inputs = nir->num_inputs; - key->flatshade_first = lp->rasterizer->flatshade_first; - key->pixel_center_half = lp->rasterizer->half_pixel_center; - key->multisample = lp->rasterizer->multisample; - key->twoside = lp->rasterizer->light_twoside; + key->flatshade_first = rast->flatshade_first; + key->pixel_center_half = rast->half_pixel_center && !rast->multisample; + key->twoside = rast->light_twoside; key->size = offsetof(struct lp_setup_variant_key, inputs[key->num_inputs]); key->color_slot = lp->color_slot[0]; @@ -795,23 +795,23 @@ lp_make_setup_variant_key(const struct llvmpipe_context *lp, * to the primitive's maximum Z value. Retain the original depth bias * value until that stage. */ - key->floating_point_depth = lp->floating_point_depth && !lp->rasterizer->offset_units_unscaled; + key->floating_point_depth = lp->floating_point_depth && !rast->offset_units_unscaled; - key->pgon_offset_units = (float) lp->rasterizer->offset_units; - if (lp->rasterizer->offset_units != 0 && !lp->floating_point_depth && - !lp->rasterizer->offset_units_unscaled) { + key->pgon_offset_units = (float) rast->offset_units; + if (rast->offset_units != 0 && !lp->floating_point_depth && + !rast->offset_units_unscaled) { /* Ensure correct rounding if a unorm format is used. */ float adjustment = lp->floating_point_depth ? 0 - : (lp->rasterizer->offset_units > 0 ? 0.5 : -0.5); + : (rast->offset_units > 0.0f ? 0.5f : -0.5f); key->pgon_offset_units = - (float) ((lp->rasterizer->offset_units + adjustment) * lp->mrd); + (float) ((rast->offset_units + adjustment) * lp->mrd); } - key->pgon_offset_scale = lp->rasterizer->offset_scale; - key->pgon_offset_clamp = lp->rasterizer->offset_clamp; + key->pgon_offset_scale = rast->offset_scale; + key->pgon_offset_clamp = rast->offset_clamp; key->uses_constant_interp = 0; key->pad = 0; @@ -819,7 +819,7 @@ lp_make_setup_variant_key(const struct llvmpipe_context *lp, for (unsigned i = 0; i < key->num_inputs; i++) { if (key->inputs[i].interp == LP_INTERP_COLOR) { - if (lp->rasterizer->flatshade) + if (rast->flatshade) key->inputs[i].interp = LP_INTERP_CONSTANT; else key->inputs[i].interp = LP_INTERP_PERSPECTIVE; diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h index 5882ce187ec..de7dc017523 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h @@ -26,7 +26,6 @@ struct lp_setup_variant_key { unsigned twoside:1; unsigned floating_point_depth:1; unsigned uses_constant_interp:1; - unsigned multisample:1; unsigned pad:3; /* TODO: get those floats out of the key and use a jit_context for setup */