panfrost: fix GL_EXT_multisampled_render_to_texture regression

Signed-off-by: Italo Nicola <italonicola@collabora.com>
Fixes: ff3eada7eb ("panfrost: Use the generic preload and FB helpers in the gallium driver")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10962>
This commit is contained in:
Italo Nicola 2021-05-11 10:29:01 +00:00 committed by Marge Bot
parent 80f0726e4c
commit c746747cb8
4 changed files with 39 additions and 20 deletions

View file

@ -636,6 +636,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
rts[i].first_layer = surf->u.tex.first_layer; rts[i].first_layer = surf->u.tex.first_layer;
rts[i].last_layer = surf->u.tex.last_layer; rts[i].last_layer = surf->u.tex.last_layer;
rts[i].image = &prsrc->image; rts[i].image = &prsrc->image;
rts[i].nr_samples = surf->nr_samples ? : MAX2(surf->texture->nr_samples, 1);
memcpy(rts[i].swizzle, id_swz, sizeof(rts[i].swizzle)); memcpy(rts[i].swizzle, id_swz, sizeof(rts[i].swizzle));
fb->rts[i].state = &prsrc->state; fb->rts[i].state = &prsrc->state;
fb->rts[i].view = &rts[i]; fb->rts[i].view = &rts[i];
@ -663,6 +664,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
zs->first_layer = surf->u.tex.first_layer; zs->first_layer = surf->u.tex.first_layer;
zs->last_layer = surf->u.tex.last_layer; zs->last_layer = surf->u.tex.last_layer;
zs->image = &prsrc->image; zs->image = &prsrc->image;
zs->nr_samples = surf->nr_samples ? : MAX2(surf->texture->nr_samples, 1);
memcpy(zs->swizzle, id_swz, sizeof(zs->swizzle)); memcpy(zs->swizzle, id_swz, sizeof(zs->swizzle));
fb->zs.view.zs = zs; fb->zs.view.zs = zs;
fb->zs.state.zs = &prsrc->state; fb->zs.state.zs = &prsrc->state;
@ -680,6 +682,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
s->first_layer = surf->u.tex.first_layer; s->first_layer = surf->u.tex.first_layer;
s->last_layer = surf->u.tex.last_layer; s->last_layer = surf->u.tex.last_layer;
s->image = &prsrc->separate_stencil->image; s->image = &prsrc->separate_stencil->image;
s->nr_samples = surf->nr_samples ? : MAX2(surf->texture->nr_samples, 1);
memcpy(s->swizzle, id_swz, sizeof(s->swizzle)); memcpy(s->swizzle, id_swz, sizeof(s->swizzle));
fb->zs.view.s = s; fb->zs.view.s = s;
fb->zs.state.s = &prsrc->separate_stencil->state; fb->zs.state.s = &prsrc->separate_stencil->state;

View file

@ -281,7 +281,7 @@ pan_blitter_emit_rsd(const struct panfrost_device *dev,
for (unsigned i = 0; i < rt_count; i++) { for (unsigned i = 0; i < rt_count; i++) {
if (rts[i]) { if (rts[i]) {
tex_count++; tex_count++;
if (rts[i]->image->layout.nr_samples > 1) if (rts[i]->nr_samples > 1)
ms = true; ms = true;
} }
} }

View file

@ -124,6 +124,26 @@ translate_s_format(enum pipe_format in)
} }
} }
static enum mali_msaa
mali_sampling_mode(const struct pan_image_view *view)
{
if (view->image->layout.nr_samples > 1) {
assert(view->nr_samples == view->image->layout.nr_samples);
assert(view->image->layout.slices[0].surface_stride != 0);
return MALI_MSAA_LAYERED;
}
if (view->nr_samples > view->image->layout.nr_samples) {
assert(view->image->layout.nr_samples == 1);
return MALI_MSAA_AVERAGE;
}
assert(view->nr_samples == view->image->layout.nr_samples);
assert(view->nr_samples == 1);
return MALI_MSAA_SINGLE;
}
static void static void
pan_prepare_s(const struct panfrost_device *dev, pan_prepare_s(const struct panfrost_device *dev,
const struct pan_fb_info *fb, const struct pan_fb_info *fb,
@ -135,12 +155,11 @@ pan_prepare_s(const struct panfrost_device *dev,
return; return;
unsigned level = s->first_level; unsigned level = s->first_level;
unsigned nr_samples = s->image->layout.nr_samples;
if (dev->arch < 7) if (dev->arch < 7)
ext->s_msaa = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; ext->s_msaa = mali_sampling_mode(s);
else else
ext->s_msaa_v7 = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; ext->s_msaa_v7 = mali_sampling_mode(s);
struct pan_surface surf; struct pan_surface surf;
pan_iview_get_surface(s, 0, 0, 0, &surf); pan_iview_get_surface(s, 0, 0, 0, &surf);
@ -150,7 +169,7 @@ pan_prepare_s(const struct panfrost_device *dev,
ext->s_writeback_base = surf.data; ext->s_writeback_base = surf.data;
ext->s_writeback_row_stride = s->image->layout.slices[level].row_stride; ext->s_writeback_row_stride = s->image->layout.slices[level].row_stride;
ext->s_writeback_surface_stride = ext->s_writeback_surface_stride =
(nr_samples > 1) ? (s->image->layout.nr_samples > 1) ?
s->image->layout.slices[level].surface_stride : 0; s->image->layout.slices[level].surface_stride : 0;
if (dev->arch >= 7) if (dev->arch >= 7)
@ -172,12 +191,11 @@ pan_prepare_zs(const struct panfrost_device *dev,
return; return;
unsigned level = zs->first_level; unsigned level = zs->first_level;
unsigned nr_samples = zs->image->layout.nr_samples;
if (dev->arch < 7) if (dev->arch < 7)
ext->zs_msaa = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; ext->zs_msaa = mali_sampling_mode(zs);
else else
ext->zs_msaa_v7 = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; ext->zs_msaa_v7 = mali_sampling_mode(zs);
struct pan_surface surf; struct pan_surface surf;
pan_iview_get_surface(zs, 0, 0, 0, &surf); pan_iview_get_surface(zs, 0, 0, 0, &surf);
@ -207,7 +225,7 @@ pan_prepare_zs(const struct panfrost_device *dev,
ext->zs_writeback_row_stride = ext->zs_writeback_row_stride =
zs->image->layout.slices[level].row_stride; zs->image->layout.slices[level].row_stride;
ext->zs_writeback_surface_stride = ext->zs_writeback_surface_stride =
(nr_samples > 1) ? (zs->image->layout.nr_samples > 1) ?
zs->image->layout.slices[level].surface_stride : 0; zs->image->layout.slices[level].surface_stride : 0;
} }
@ -265,7 +283,7 @@ pan_internal_cbuf_size(const struct pan_fb_info *fb,
continue; continue;
total_size += pan_bytes_per_pixel_tib(rt->format) * total_size += pan_bytes_per_pixel_tib(rt->format) *
rt->image->layout.nr_samples * (*tile_size); rt->nr_samples * (*tile_size);
} }
/* We have a 4KB budget, let's reduce the tile size until it fits. */ /* We have a 4KB budget, let's reduce the tile size until it fits. */
@ -453,16 +471,11 @@ pan_prepare_rt(const struct panfrost_device *dev,
/* Only set layer_stride for layered MSAA rendering */ /* Only set layer_stride for layered MSAA rendering */
unsigned nr_samples = rt->image->layout.nr_samples;
unsigned layer_stride = unsigned layer_stride =
(nr_samples > 1) ? rt->image->layout.slices[level].surface_stride : 0; (rt->image->layout.nr_samples > 1) ?
rt->image->layout.slices[level].surface_stride : 0;
if (layer_stride) cfg->writeback_msaa = mali_sampling_mode(rt);
cfg->writeback_msaa = MALI_MSAA_LAYERED;
else if (rt->image->layout.nr_samples > 1)
cfg->writeback_msaa = MALI_MSAA_AVERAGE;
else
cfg->writeback_msaa = MALI_MSAA_SINGLE;
pan_rt_init_format(dev, rt, cfg); pan_rt_init_format(dev, rt, cfg);
@ -864,8 +877,7 @@ pan_emit_sfbd(const struct panfrost_device *dev,
cfg.sample_count = fb->nr_samples; cfg.sample_count = fb->nr_samples;
/* XXX: different behaviour from MFBD and probably wrong... */ /* XXX: different behaviour from MFBD and probably wrong... */
cfg.msaa = (fb->nr_samples > 1) ? cfg.msaa = mali_sampling_mode(fb->rts[0].view);
MALI_MSAA_MULTIPLE : MALI_MSAA_SINGLE;
} }
pan_emit_sfbd_tiler(dev, fb, tiler_ctx, fbd); pan_emit_sfbd_tiler(dev, fb, tiler_ctx, fbd);
pan_section_pack(fbd, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding); pan_section_pack(fbd, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding);

View file

@ -133,6 +133,10 @@ struct pan_image_view {
unsigned char swizzle[4]; unsigned char swizzle[4];
const struct pan_image *image; const struct pan_image *image;
/* If EXT_multisampled_render_to_texture is used, this may be
* greater than image->layout.nr_samples. */
unsigned nr_samples;
/* Only valid if dim == 1D, needed to implement buffer views */ /* Only valid if dim == 1D, needed to implement buffer views */
struct { struct {
unsigned offset; unsigned offset;