mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
gallium/u_blitter: make the bilinear filter for MSAA resolving conformant
This implements the bilinear filter exactly like OpenGL. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17692>
This commit is contained in:
parent
5c7ad4757b
commit
2f4b9b7a95
3 changed files with 54 additions and 15 deletions
|
|
@ -1032,7 +1032,7 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
|
|||
assert(!ctx->cached_all_shaders);
|
||||
if (filter == PIPE_TEX_FILTER_LINEAR) {
|
||||
*shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
|
||||
src_nr_samples);
|
||||
src_nr_samples, ctx->has_txf_txq);
|
||||
}
|
||||
else {
|
||||
*shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
|
||||
|
|
|
|||
|
|
@ -877,12 +877,12 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
|
|||
void *
|
||||
util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
|
||||
enum tgsi_texture_type tgsi_tex,
|
||||
unsigned nr_samples)
|
||||
unsigned nr_samples, bool has_txq)
|
||||
{
|
||||
struct ureg_program *ureg;
|
||||
struct ureg_src sampler, coord;
|
||||
struct ureg_dst out, tmp, top, bottom;
|
||||
struct ureg_dst tmp_coord[4], tmp_sum[4];
|
||||
struct ureg_dst tmp_coord[4], tmp_sum[4], weights;
|
||||
unsigned i, c;
|
||||
|
||||
ureg = ureg_create(PIPE_SHADER_FRAGMENT);
|
||||
|
|
@ -903,21 +903,62 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
|
|||
tmp_coord[c] = ureg_DECL_temporary(ureg);
|
||||
tmp = ureg_DECL_temporary(ureg);
|
||||
top = ureg_DECL_temporary(ureg);
|
||||
weights = ureg_DECL_temporary(ureg);
|
||||
bottom = ureg_DECL_temporary(ureg);
|
||||
|
||||
/* Instructions. */
|
||||
for (c = 0; c < 4; c++)
|
||||
ureg_MOV(ureg, tmp_sum[c], ureg_imm1f(ureg, 0));
|
||||
|
||||
/* Get 4 texture coordinates for the bilinear filter. */
|
||||
ureg_F2U(ureg, tmp_coord[0], coord); /* top-left */
|
||||
ureg_UADD(ureg, tmp_coord[1], ureg_src(tmp_coord[0]),
|
||||
ureg_imm4u(ureg, 1, 0, 0, 0)); /* top-right */
|
||||
ureg_UADD(ureg, tmp_coord[2], ureg_src(tmp_coord[0]),
|
||||
ureg_imm4u(ureg, 0, 1, 0, 0)); /* bottom-left */
|
||||
/* Bilinear filtering starts with subtracting 0.5 from unnormalized
|
||||
* coordinates.
|
||||
*/
|
||||
ureg_MOV(ureg, ureg_writemask(tmp_coord[0], TGSI_WRITEMASK_ZW), coord);
|
||||
ureg_ADD(ureg, ureg_writemask(tmp_coord[0], TGSI_WRITEMASK_XY), coord,
|
||||
ureg_imm2f(ureg, -0.5, -0.5));
|
||||
|
||||
/* Get the filter weights. */
|
||||
ureg_FRC(ureg, ureg_writemask(weights, TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[0]));
|
||||
|
||||
/* Convert to integer by flooring to get the top-left coordinates. */
|
||||
ureg_FLR(ureg, ureg_writemask(tmp_coord[0], TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[0]));
|
||||
ureg_F2I(ureg, tmp_coord[0], ureg_src(tmp_coord[0]));
|
||||
|
||||
/* Get the bottom-right coordinates. */
|
||||
ureg_UADD(ureg, tmp_coord[3], ureg_src(tmp_coord[0]),
|
||||
ureg_imm4u(ureg, 1, 1, 0, 0)); /* bottom-right */
|
||||
|
||||
/* Clamp to edge. */
|
||||
if (has_txq) {
|
||||
ureg_TXQ(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XY), tgsi_tex,
|
||||
ureg_imm1u(ureg, 0), sampler);
|
||||
ureg_UADD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XY), ureg_src(tmp),
|
||||
ureg_imm2i(ureg, -1, -1)); /* width - 1, height - 1 */
|
||||
|
||||
ureg_IMIN(ureg, ureg_writemask(tmp_coord[0], TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[0]), ureg_src(tmp));
|
||||
ureg_IMIN(ureg, ureg_writemask(tmp_coord[3], TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[3]), ureg_src(tmp));
|
||||
}
|
||||
|
||||
ureg_IMAX(ureg, ureg_writemask(tmp_coord[0], TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[0]), ureg_imm2i(ureg, 0, 0));
|
||||
ureg_IMAX(ureg, ureg_writemask(tmp_coord[3], TGSI_WRITEMASK_XY),
|
||||
ureg_src(tmp_coord[3]), ureg_imm2i(ureg, 0, 0));
|
||||
|
||||
/* Get the remaining top-right and bottom-left coordinates. */
|
||||
ureg_MOV(ureg, ureg_writemask(tmp_coord[1], TGSI_WRITEMASK_X),
|
||||
ureg_src(tmp_coord[3]));
|
||||
ureg_MOV(ureg, ureg_writemask(tmp_coord[1], TGSI_WRITEMASK_YZW),
|
||||
ureg_src(tmp_coord[0])); /* top-right */
|
||||
|
||||
ureg_MOV(ureg, ureg_writemask(tmp_coord[2], TGSI_WRITEMASK_Y),
|
||||
ureg_src(tmp_coord[3]));
|
||||
ureg_MOV(ureg, ureg_writemask(tmp_coord[2], TGSI_WRITEMASK_XZW),
|
||||
ureg_src(tmp_coord[0])); /* bottom-left */
|
||||
|
||||
for (i = 0; i < nr_samples; i++) {
|
||||
for (c = 0; c < 4; c++) {
|
||||
/* Read one sample. */
|
||||
|
|
@ -936,20 +977,18 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
|
|||
ureg_imm1f(ureg, 1.0 / nr_samples));
|
||||
|
||||
/* Take the 4 average values and apply a standard bilinear filter. */
|
||||
ureg_FRC(ureg, tmp, coord);
|
||||
|
||||
ureg_LRP(ureg, top,
|
||||
ureg_scalar(ureg_src(tmp), 0),
|
||||
ureg_scalar(ureg_src(weights), 0),
|
||||
ureg_src(tmp_sum[1]),
|
||||
ureg_src(tmp_sum[0]));
|
||||
|
||||
ureg_LRP(ureg, bottom,
|
||||
ureg_scalar(ureg_src(tmp), 0),
|
||||
ureg_scalar(ureg_src(weights), 0),
|
||||
ureg_src(tmp_sum[3]),
|
||||
ureg_src(tmp_sum[2]));
|
||||
|
||||
ureg_LRP(ureg, out,
|
||||
ureg_scalar(ureg_src(tmp), 1),
|
||||
ureg_scalar(ureg_src(weights), 1),
|
||||
ureg_src(bottom),
|
||||
ureg_src(top));
|
||||
ureg_END(ureg);
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe,
|
|||
void *
|
||||
util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
|
||||
enum tgsi_texture_type tgsi_tex,
|
||||
unsigned nr_samples);
|
||||
unsigned nr_samples, bool has_txq);
|
||||
|
||||
extern void *
|
||||
util_make_geometry_passthrough_shader(struct pipe_context *pipe,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue