panvk: Setup attachments for ms to ss rendering

Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38825>
This commit is contained in:
Christoph Pillmayer
2025-12-05 09:28:58 +00:00
committed by Marge Bot
parent cb3f648175
commit 5d2e297556
+119 -4
View File
@@ -48,6 +48,42 @@ att_set_clear_preload(const VkRenderingAttachmentInfo *att, bool *clear, bool *p
}
}
static struct panvk_image_view *
get_ms2ss_image_view(struct panvk_image_view *iview, uint32_t nr_samples)
{
assert(nr_samples >= 2 && nr_samples <= 16);
assert(iview->pview.nr_samples == 1);
assert(iview->vk.image->create_flags &
VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT);
/* sample count 2 is at index 0, 4 at 1, .. */
uint32_t vidx = 0;
switch (nr_samples) {
case VK_SAMPLE_COUNT_2_BIT:
vidx = 0;
break;
case VK_SAMPLE_COUNT_4_BIT:
vidx = 1;
break;
case VK_SAMPLE_COUNT_8_BIT:
vidx = 2;
break;
case VK_SAMPLE_COUNT_16_BIT:
vidx = 3;
break;
default:
UNREACHABLE("unhandled sample count");
}
assert(iview->ms_views[vidx] != VK_NULL_HANDLE);
struct panvk_image_view *res =
panvk_image_view_from_handle(iview->ms_views[vidx]);
assert(res->pview.nr_samples == nr_samples);
return res;
}
static void
render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf,
const VkRenderingAttachmentInfo *att,
@@ -58,11 +94,24 @@ render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf,
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
struct pan_fb_info *fbinfo = &state->render.fb.info;
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
struct panvk_image_view *iview_ss = NULL;
const bool ms2ss = cmdbuf->state.gfx.render.fb.nr_samples > 1 &&
iview->pview.nr_samples == 1;
if (ms2ss) {
iview_ss = iview;
iview =
get_ms2ss_image_view(iview, cmdbuf->state.gfx.render.fb.nr_samples);
}
struct panvk_image *img =
container_of(iview->vk.image, struct panvk_image, vk);
state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(index);
state->render.color_attachments.iviews[index] = iview;
state->render.color_attachments.preload_iviews[index] =
ms2ss ? iview_ss : NULL;
state->render.color_attachments.fmts[index] = iview->vk.format;
state->render.color_attachments.samples[index] = img->vk.samples;
@@ -103,8 +152,20 @@ render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf,
&state->render.color_attachments.resolve[index];
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
/* VUID-VkRenderingAttachmentInfo-imageView-06862 and
* VUID-VkRenderingAttachmentInfo-imageView-06863:
* If resolveMode != NONE, then
* resolveView == NULL iff. multisampledRenderToSingleSampledEnable */
assert(ms2ss == (resolve_iview == NULL));
resolve_info->mode = att->resolveMode;
resolve_info->dst_iview = resolve_iview;
if (!ms2ss) {
resolve_info->dst_iview = resolve_iview;
} else {
assert(iview_ss);
resolve_info->dst_iview = iview_ss;
assert(resolve_info->dst_iview->pview.nr_samples == 1);
}
}
}
@@ -115,6 +176,17 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf,
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
struct pan_fb_info *fbinfo = &state->render.fb.info;
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
struct panvk_image_view *iview_ss = NULL;
const bool ms2ss = cmdbuf->state.gfx.render.fb.nr_samples > 1 &&
iview->pview.nr_samples == 1;
if (ms2ss) {
iview_ss = iview;
iview =
get_ms2ss_image_view(iview, cmdbuf->state.gfx.render.fb.nr_samples);
}
struct panvk_image *img =
container_of(iview->vk.image, struct panvk_image, vk);
@@ -142,6 +214,7 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf,
MAX2(state->render.fb.nr_samples,
pan_image_view_get_nr_samples(&iview->pview));
state->render.z_attachment.iview = iview;
state->render.z_attachment.preload_iview = ms2ss ? iview_ss : NULL;
/* D24S8 is a single plane format where the depth/stencil are interleaved.
* If we touch the depth component, we need to make sure the stencil
@@ -166,7 +239,13 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf,
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
resolve_info->mode = att->resolveMode;
resolve_info->dst_iview = resolve_iview;
if (!ms2ss) {
resolve_info->dst_iview = resolve_iview;
} else {
assert(iview_ss);
resolve_info->dst_iview = iview_ss;
assert(resolve_info->dst_iview->pview.nr_samples == 1);
}
}
}
@@ -177,6 +256,17 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf,
struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
struct pan_fb_info *fbinfo = &state->render.fb.info;
VK_FROM_HANDLE(panvk_image_view, iview, att->imageView);
struct panvk_image_view *iview_ss = NULL;
const bool ms2ss = cmdbuf->state.gfx.render.fb.nr_samples > 1 &&
iview->pview.nr_samples == 1;
if (ms2ss) {
iview_ss = iview;
iview =
get_ms2ss_image_view(iview, cmdbuf->state.gfx.render.fb.nr_samples);
}
struct panvk_image *img =
container_of(iview->vk.image, struct panvk_image, vk);
@@ -212,6 +302,7 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf,
MAX2(state->render.fb.nr_samples,
pan_image_view_get_nr_samples(&iview->pview));
state->render.s_attachment.iview = iview;
state->render.s_attachment.preload_iview = ms2ss ? iview_ss : NULL;
/* If the depth and stencil attachments point to the same image,
* and the format is D24S8, we can combine them in a single view
@@ -248,7 +339,13 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf,
VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView);
resolve_info->mode = att->resolveMode;
resolve_info->dst_iview = resolve_iview;
if (!ms2ss) {
resolve_info->dst_iview = resolve_iview;
} else {
assert(iview_ss);
resolve_info->dst_iview = iview_ss;
assert(resolve_info->dst_iview->pview.nr_samples == 1);
}
}
}
@@ -283,6 +380,13 @@ panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf,
memset(&state->render.s_attachment, 0, sizeof(state->render.s_attachment));
state->render.bound_attachments = 0;
const VkMultisampledRenderToSingleSampledInfoEXT *ms2ss_info =
vk_find_struct_const(pRenderingInfo,
MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT);
const bool ms2ss = ms2ss_info
? ms2ss_info->multisampledRenderToSingleSampledEnable
: VK_FALSE;
cmdbuf->state.gfx.render.layer_count = pRenderingInfo->viewMask ?
util_last_bit(pRenderingInfo->viewMask) :
pRenderingInfo->layerCount;
@@ -293,7 +397,12 @@ panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf,
.nr_samples = 0,
.rt_count = pRenderingInfo->colorAttachmentCount,
};
cmdbuf->state.gfx.render.fb.nr_samples = 1;
/* In case ms2ss is enabled, use the provided sample count.
* All attachments need to have sample count == 1 or the provided value.
* But, if all attachments have 1, we would end up choosing the wrong value
* if we don't set it here already. */
cmdbuf->state.gfx.render.fb.nr_samples =
ms2ss ? ms2ss_info->rasterizationSamples : 1;
assert(pRenderingInfo->colorAttachmentCount <= ARRAY_SIZE(fbinfo->rts));
@@ -391,6 +500,7 @@ panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf)
util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS);
VkRenderingAttachmentInfo color_atts[MAX_RTS];
for (uint32_t i = 0; i < color_att_count; i++) {
const struct panvk_resolve_attachment *resolve_info =
&cmdbuf->state.gfx.render.color_attachments.resolve[i];
struct panvk_image_view *src_iview =
@@ -408,6 +518,11 @@ panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf)
if (resolve_info->mode != VK_RESOLVE_MODE_NONE)
needs_resolve = true;
if (resolve_info->mode != VK_RESOLVE_MODE_NONE) {
assert(src_iview->pview.nr_samples > 1);
assert(resolve_info->dst_iview->pview.nr_samples == 1);
}
}
const struct panvk_resolve_attachment *resolve_info =