Commit 8c277c5e authored by Juan A. Suárez's avatar Juan A. Suárez
Browse files

gallium/util: allow non average MS resolution in blit



When performing a MSAA resolve in the blitter, either a linear
(nearest filter) or a bilinear (linear filter) average sampling is done
for float-based color sources.

In the case of V3D, there's a path to do a stencil blit by
re-interpreting the stencil buffer as a color buffer, and using the
blitter to do the job. But the BlitFramebuffer spec requires that for
stencil values a single sample is used, not an average.

This can be observed in the piglit's test
`ext_framebuffer_multisample-unaligned-blit 2 stencil downsample -auto
-fbo`, specifically in the triangles borders.

Here we add an option to disable the averaging and use instead a single
sample.
Signed-off-by: Juan A. Suárez's avatarJuan A. Suarez Romero <jasuarez@igalia.com>
parent 24dcdc3f
Pipeline #250778 waiting for manual action with stages
in 8 seconds
......@@ -934,7 +934,8 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
unsigned src_nr_samples,
unsigned dst_nr_samples,
unsigned filter,
bool use_txf)
bool use_txf,
bool no_nearest_avg)
{
struct pipe_context *pipe = ctx->base.pipe;
enum tgsi_texture_type tgsi_tex =
......@@ -997,7 +998,7 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
}
else {
*shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
src_nr_samples,
no_nearest_avg ? 1 : src_nr_samples,
stype);
}
}
......@@ -1251,19 +1252,19 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
*/
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
PIPE_FORMAT_R32_FLOAT, target,
samples, samples, 0, use_txf);
samples, samples, 0, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
PIPE_FORMAT_R32_UINT, target,
samples, samples, 0, use_txf);
samples, samples, 0, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
PIPE_FORMAT_R32_SINT, target,
samples, samples, 0, use_txf);
samples, samples, 0, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
PIPE_FORMAT_R32_SINT, target,
samples, samples, 0, use_txf);
samples, samples, 0, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
PIPE_FORMAT_R32_UINT, target,
samples, samples, 0, use_txf);
samples, samples, 0, use_txf, false);
blitter_get_fs_texfetch_depth(ctx, target, samples, use_txf);
if (ctx->has_stencil_export) {
blitter_get_fs_texfetch_depthstencil(ctx, target, samples, use_txf);
......@@ -1287,13 +1288,13 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
PIPE_FORMAT_R32_FLOAT, target,
j, 1, f, use_txf);
j, 1, f, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
PIPE_FORMAT_R32_UINT, target,
j, 1, f, use_txf);
j, 1, f, use_txf, false);
blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
PIPE_FORMAT_R32_SINT, target,
j, 1, f, use_txf);
j, 1, f, use_txf, false);
}
}
}
......@@ -1726,7 +1727,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
util_blitter_blit_generic(blitter, dst_view, &dstbox,
src_view, srcbox, src->width0, src->height0,
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
false);
false, false);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
......@@ -1910,7 +1911,8 @@ void util_blitter_blit_generic(struct blitter_context *blitter,
unsigned src_width0, unsigned src_height0,
unsigned mask, unsigned filter,
const struct pipe_scissor_state *scissor,
bool alpha_blend)
bool alpha_blend,
bool no_nearest_avg)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
......@@ -2048,7 +2050,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter,
ctx->bind_fs_state(pipe,
blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
src_samples, dst_samples, filter,
use_txf));
use_txf, no_nearest_avg));
}
}
......@@ -2155,7 +2157,7 @@ util_blitter_blit(struct blitter_context *blitter,
src_view, &info->src.box, src->width0, src->height0,
info->mask, info->filter,
info->scissor_enable ? &info->scissor : NULL,
info->alpha_blend);
info->alpha_blend, false);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
......@@ -2208,7 +2210,7 @@ void util_blitter_generate_mipmap(struct blitter_context *blitter,
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
ctx->bind_fs_state(pipe,
blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
1, 1, PIPE_TEX_FILTER_LINEAR, false));
1, 1, PIPE_TEX_FILTER_LINEAR, false, false));
}
if (target == PIPE_TEXTURE_RECT) {
......
......@@ -261,6 +261,14 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
*
* The mask is a combination of the PIPE_MASK_* flags.
* Set to PIPE_MASK_RGBAZS if unsure.
*
* By default, when resolving a MS surface to a non-MS one, the result is an
* average of the samples. no_nearest_avg disables it (for nearest filter), so
* the output is a single sample from the input surface. This can be used when
* using this function to blit a stencil buffer by re-interpreting it as a
* color buffer. According to OpenGL's BlitFramebuffer spec, "if the source
* formats are integer types or stencil values, a single sample’s value is
* selected for each pixel".
*/
void util_blitter_blit_generic(struct blitter_context *blitter,
struct pipe_surface *dst,
......@@ -270,7 +278,8 @@ void util_blitter_blit_generic(struct blitter_context *blitter,
unsigned src_width0, unsigned src_height0,
unsigned mask, unsigned filter,
const struct pipe_scissor_state *scissor,
bool alpha_blend);
bool alpha_blend,
bool no_nearest_avg);
void util_blitter_blit(struct blitter_context *blitter,
const struct pipe_blit_info *info);
......
......@@ -158,7 +158,8 @@ fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
src_view, &info->src.box, src->width0, src->height0,
info->mask, info->filter,
info->scissor_enable ? &info->scissor : NULL,
info->alpha_blend);
info->alpha_blend,
false);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
......
......@@ -121,7 +121,7 @@ i915_surface_copy_render(struct pipe_context *pipe,
util_blitter_blit_generic(i915->blitter, dst_view, &dstbox,
src_view, src_box, src_width0, src_height0,
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
FALSE);
FALSE, FALSE);
return;
fallback:
......
......@@ -676,7 +676,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
util_blitter_blit_generic(r300->blitter, dst_view, &dstbox,
src_view, src_box, src_width0, src_height0,
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
FALSE);
FALSE, FALSE);
r300_blitter_end(r300);
pipe_surface_reference(&dst_view, NULL);
......
......@@ -813,7 +813,7 @@ void r600_resource_copy_region(struct pipe_context *ctx,
util_blitter_blit_generic(rctx->blitter, dst_view, &dstbox,
src_view, src_box, src_width0, src_height0,
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
FALSE);
FALSE, FALSE);
r600_blitter_end(ctx);
pipe_surface_reference(&dst_view, NULL);
......
......@@ -994,7 +994,7 @@ void si_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst
/* Copy. */
si_blitter_begin(sctx, SI_COPY);
util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox, src_view, src_box, src_width0,
src_height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, false);
src_height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, false, false);
si_blitter_end(sctx);
pipe_surface_reference(&dst_view, NULL);
......
......@@ -176,7 +176,7 @@ v3d_stencil_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
PIPE_MASK_R,
PIPE_TEX_FILTER_NEAREST,
info->scissor_enable ? &info->scissor : NULL,
info->alpha_blend);
info->alpha_blend, true);
pipe_surface_reference(&dst_surf, NULL);
pipe_sampler_view_reference(&src_view, NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment