tu: Implement VK_EXT_custom_resolve

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38451>
This commit is contained in:
Connor Abbott 2025-06-09 19:08:04 -04:00 committed by Marge Bot
parent ad84ae2719
commit 520e3f3a47
4 changed files with 152 additions and 50 deletions

View file

@ -4400,7 +4400,7 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
if (rendering_info) {
tu_setup_dynamic_inheritance(cmd_buffer, rendering_info);
cmd_buffer->state.pass = &cmd_buffer->dynamic_pass;
cmd_buffer->state.subpass = &cmd_buffer->dynamic_subpass;
cmd_buffer->state.subpass = &cmd_buffer->dynamic_subpasses[0];
const VkRenderingAttachmentLocationInfoKHR *location_info =
vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext,
@ -6864,7 +6864,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
tu_setup_dynamic_framebuffer(cmd, pRenderingInfo);
cmd->state.pass = &cmd->dynamic_pass;
cmd->state.subpass = &cmd->dynamic_subpass;
cmd->state.subpass = &cmd->dynamic_subpasses[0];
cmd->state.framebuffer = &cmd->dynamic_framebuffer;
cmd->state.render_area = pRenderingInfo->renderArea;
cmd->state.fdm_per_layer =
@ -6877,7 +6877,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
for (unsigned i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
if (!pRenderingInfo->pColorAttachments[i].imageView)
continue;
uint32_t a = cmd->dynamic_subpass.color_attachments[i].attachment;
uint32_t a = cmd->dynamic_subpasses[0].color_attachments[i].attachment;
cmd->state.clear_values[a] =
pRenderingInfo->pColorAttachments[i].clearValue;
@ -6897,7 +6897,12 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
pRenderingInfo->pColorAttachments[i].imageView);
cmd->state.attachments[a] = view;
a = cmd->dynamic_subpass.resolve_attachments[i].attachment;
if (cmd->dynamic_pass.subpass_count > 1) {
a = cmd->dynamic_subpasses[1].color_attachments[i].attachment;
} else {
a = cmd->dynamic_subpasses[0].resolve_attachments[i].attachment;
}
if (!msrtss && a != VK_ATTACHMENT_UNUSED) {
VK_FROM_HANDLE(tu_image_view, resolve_view,
pRenderingInfo->pColorAttachments[i].resolveImageView);
@ -6905,7 +6910,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
}
}
uint32_t a = cmd->dynamic_subpass.depth_stencil_attachment.attachment;
uint32_t a = cmd->dynamic_subpasses[0].depth_stencil_attachment.attachment;
if (pRenderingInfo->pDepthAttachment || pRenderingInfo->pStencilAttachment) {
const struct VkRenderingAttachmentInfo *common_info =
(pRenderingInfo->pDepthAttachment &&
@ -6932,13 +6937,22 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
cmd->state.attachments[a] = view;
if (!msrtss && cmd->dynamic_subpass.resolve_count >
cmd->dynamic_subpass.color_count) {
if (!msrtss && cmd->dynamic_subpasses[0].resolve_count >
cmd->dynamic_subpasses[0].color_count) {
VK_FROM_HANDLE(tu_image_view, resolve_view,
common_info->resolveImageView);
a = cmd->dynamic_subpass.resolve_attachments[cmd->dynamic_subpass.color_count].attachment;
a = cmd->dynamic_subpasses[0].resolve_attachments[cmd->dynamic_subpasses[0].color_count].attachment;
cmd->state.attachments[a] = resolve_view;
}
if (cmd->dynamic_pass.subpass_count > 1) {
a = cmd->dynamic_subpasses[1].depth_stencil_attachment.attachment;
if (a != VK_ATTACHMENT_UNUSED) {
VK_FROM_HANDLE(tu_image_view, resolve_view,
common_info->resolveImageView);
cmd->state.attachments[a] = resolve_view;
}
}
}
}
@ -6959,7 +6973,7 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
cmd->patchpoints_ctx = ralloc_context(NULL);
a = cmd->dynamic_subpass.fsr_attachment;
a = cmd->dynamic_subpasses[0].fsr_attachment;
if (a != VK_ATTACHMENT_UNUSED) {
const VkRenderingFragmentShadingRateAttachmentInfoKHR *fsr_info =
vk_find_struct_const(pRenderingInfo->pNext,
@ -7087,7 +7101,7 @@ tu_CmdSetRenderingInputAttachmentIndicesKHR(
const struct vk_input_attachment_location_state *ial =
&cmd->vk.dynamic_graphics_state.ial;
struct tu_subpass *subpass = &cmd->dynamic_subpass;
struct tu_subpass *subpass = &cmd->dynamic_subpasses[0];
for (unsigned i = 0; i < ARRAY_SIZE(cmd->dynamic_input_attachments); i++) {
subpass->input_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
@ -7128,7 +7142,23 @@ tu_CmdSetRenderingInputAttachmentIndicesKHR(
subpass->input_count = input_count;
tu_set_input_attachments(cmd, cmd->state.subpass);
tu_set_input_attachments(cmd, subpass);
}
static void
tu_next_subpass_lrz(struct tu_cmd_buffer *cmd,
const struct tu_subpass *subpass,
const struct tu_subpass *new_subpass)
{
/* Track LRZ valid state
*
* TODO: Improve this tracking for keeping the state of the past depth/stencil images,
* so if they become active again, we reuse its old state.
*/
if (new_subpass->depth_stencil_attachment.attachment != subpass->depth_stencil_attachment.attachment) {
cmd->state.lrz.valid = false;
cmd->state.dirty |= TU_CMD_DIRTY_LRZ;
}
}
template <chip CHIP>
@ -7150,15 +7180,7 @@ tu_CmdNextSubpass2(VkCommandBuffer commandBuffer,
const struct tu_subpass *subpass = cmd->state.subpass++;
const struct tu_subpass *new_subpass = cmd->state.subpass;
/* Track LRZ valid state
*
* TODO: Improve this tracking for keeping the state of the past depth/stencil images,
* so if they become active again, we reuse its old state.
*/
if (new_subpass->depth_stencil_attachment.attachment != subpass->depth_stencil_attachment.attachment) {
cmd->state.lrz.valid = false;
cmd->state.dirty |= TU_CMD_DIRTY_LRZ;
}
tu_next_subpass_lrz(cmd, subpass, new_subpass);
if (cmd->state.tiling->possible) {
if (cmd->state.pass->has_fdm)
@ -7198,6 +7220,24 @@ tu_CmdNextSubpass2(VkCommandBuffer commandBuffer,
}
TU_GENX(tu_CmdNextSubpass2);
template <chip CHIP>
VKAPI_ATTR void VKAPI_CALL
tu_CmdBeginCustomResolveEXT(VkCommandBuffer commandBuffer,
const VkBeginCustomResolveInfoEXT *pBeginShaderResolveInfo)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
const struct tu_subpass *subpass = &cmd->dynamic_subpasses[0];
const struct tu_subpass *new_subpass = &cmd->dynamic_subpasses[1];
cmd->state.subpass = new_subpass;
tu_next_subpass_lrz(cmd, subpass, new_subpass);
tu_emit_subpass_begin<CHIP>(cmd);
}
TU_GENX(tu_CmdBeginCustomResolveEXT);
static uint32_t
tu6_user_consts_size(const struct tu_const_state *const_state,
bool ldgk,

View file

@ -684,7 +684,7 @@ struct tu_cmd_buffer
struct tu_image dynamic_msrtss_images[MAX_RTS + 1];
struct tu_render_pass dynamic_pass;
struct tu_subpass dynamic_subpass;
struct tu_subpass dynamic_subpasses[2];
struct tu_framebuffer dynamic_framebuffer;
struct tu_cs cs;

View file

@ -270,6 +270,7 @@ get_device_extensions(const struct tu_physical_device *device,
.EXT_conditional_rendering = true,
.EXT_conservative_rasterization = device->info->chip >= 7,
.EXT_custom_border_color = true,
.EXT_custom_resolve = true,
.EXT_depth_clamp_zero_one = true,
.EXT_depth_clip_control = true,
.EXT_depth_clip_enable = true,
@ -821,6 +822,9 @@ tu_get_features(struct tu_physical_device *pdevice,
/* VK_EXT_multisampled_render_to_single_sampled */
features->multisampledRenderToSingleSampled = true;
/* VK_EXT_custom_resolve */
features->customResolve = true;
}
static void
@ -955,8 +959,12 @@ tu_get_physical_device_properties_1_2(struct tu_physical_device *pdevice,
p->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
p->maxDescriptorSetUpdateAfterBindInputAttachments = MAX_RTS;
p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
p->supportedDepthResolveModes =
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
VK_RESOLVE_MODE_CUSTOM_BIT_EXT;
p->supportedStencilResolveModes =
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
VK_RESOLVE_MODE_CUSTOM_BIT_EXT;
p->independentResolveNone = false;
p->independentResolve = false;

View file

@ -1184,7 +1184,7 @@ tu_CreateRenderPass2(VkDevice _device,
subpass->legacy_dithering_enabled = desc->flags &
VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT;
subpass->custom_resolve = desc->flags &
VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM;
VK_SUBPASS_DESCRIPTION_CUSTOM_RESOLVE_BIT_EXT;
const BITMASK_ENUM(VkSubpassDescriptionFlagBits) raster_order_access_bits =
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT |
@ -1399,7 +1399,8 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
{
struct tu_device *device = cmd_buffer->device;
struct tu_render_pass *pass = &cmd_buffer->dynamic_pass;
struct tu_subpass *subpass = &cmd_buffer->dynamic_subpass;
struct tu_subpass *subpass = &cmd_buffer->dynamic_subpasses[0];
struct tu_subpass *resolve_subpass = &cmd_buffer->dynamic_subpasses[1];
const VkMultisampledRenderToSingleSampledInfoEXT *msrtss =
vk_find_struct_const(info->pNext,
MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT);
@ -1407,16 +1408,40 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
*pass = {};
*subpass = {};
pass->subpass_count = 1;
if (info->flags & VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT) {
*resolve_subpass = {};
resolve_subpass->custom_resolve = true;
resolve_subpass->samples = VK_SAMPLE_COUNT_1_BIT;
resolve_subpass->color_count = info->colorAttachmentCount;
resolve_subpass->input_count = info->colorAttachmentCount + 1;
resolve_subpass->color_attachments = cmd_buffer->dynamic_resolve_attachments;
resolve_subpass->input_attachments = cmd_buffer->dynamic_input_attachments;
resolve_subpass->multiview_mask = info->viewMask;
resolve_subpass->legacy_dithering_enabled = info->flags &
VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT;
/* These will be filled in below. */
for (unsigned i = 0; i < info->colorAttachmentCount; i++) {
resolve_subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
}
resolve_subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
pass->subpass_count = 2;
subpass->resolve_count = 0;
} else {
subpass->resolve_attachments = cmd_buffer->dynamic_resolve_attachments;
subpass->resolve_count = info->colorAttachmentCount;
pass->subpass_count = 1;
}
pass->attachments = cmd_buffer->dynamic_rp_attachments;
subpass->color_count = subpass->resolve_count = info->colorAttachmentCount;
subpass->color_count = info->colorAttachmentCount;
if (msrtss)
subpass->unresolve_count = info->colorAttachmentCount;
subpass->input_count = info->colorAttachmentCount + 1;
subpass->color_attachments = cmd_buffer->dynamic_color_attachments;
subpass->input_attachments = cmd_buffer->dynamic_input_attachments;
subpass->resolve_attachments = cmd_buffer->dynamic_resolve_attachments;
subpass->unresolve_attachments = cmd_buffer->dynamic_unresolve_attachments;
subpass->multiview_mask = info->viewMask;
subpass->legacy_dithering_enabled = info->flags &
@ -1442,7 +1467,8 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
if (att_info->imageView == VK_NULL_HANDLE) {
subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
subpass->input_attachments[i + 1].attachment = VK_ATTACHMENT_UNUSED;
subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
if (subpass->resolve_attachments)
subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
subpass->unresolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
continue;
}
@ -1500,10 +1526,16 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
device, resolve_att, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_STORE_OP_DONT_CARE);
subpass->resolve_attachments[i].attachment = a++;
att->will_be_resolved = true;
if (att_info->resolveMode == VK_RESOLVE_MODE_CUSTOM_BIT_EXT) {
att->will_be_resolved = false;
resolve_subpass->color_attachments[i].attachment = a++;
} else {
subpass->resolve_attachments[i].attachment = a++;
att->will_be_resolved = true;
}
} else {
subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
if (subpass->resolve_count)
subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
att->will_be_resolved = false;
}
}
@ -1584,7 +1616,6 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
if (!att_is_msrtss) {
if (common_info->resolveMode != VK_RESOLVE_MODE_NONE) {
unsigned i = subpass->resolve_count++;
struct tu_render_pass_attachment *resolve_att = &pass->attachments[a];
VK_FROM_HANDLE(tu_image_view, resolve_view,
common_info->resolveImageView);
@ -1596,9 +1627,15 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_STORE_OP_STORE);
subpass->resolve_attachments[i].attachment = a++;
att->will_be_resolved = true;
subpass->resolve_depth_stencil = true;
if (common_info->resolveMode == VK_RESOLVE_MODE_CUSTOM_BIT_EXT) {
resolve_subpass->depth_stencil_attachment.attachment = a++;
att->will_be_resolved = false;
} else {
unsigned i = subpass->resolve_count++;
subpass->resolve_attachments[i].attachment = a++;
att->will_be_resolved = true;
subpass->resolve_depth_stencil = true;
}
} else {
att->will_be_resolved = false;
}
@ -1659,6 +1696,12 @@ tu_setup_dynamic_render_pass(struct tu_cmd_buffer *cmd_buffer,
subpass->fsr_attachment = VK_ATTACHMENT_UNUSED;
}
if (info->flags & VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT) {
resolve_subpass->fsr_attachment_texel_size =
subpass->fsr_attachment_texel_size;
resolve_subpass->fsr_attachment = subpass->fsr_attachment;
}
if (TU_DEBUG(FDM) && !tu_render_pass_disable_fdm(device, pass))
pass->has_fdm = true;
@ -1746,7 +1789,11 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
const VkCommandBufferInheritanceRenderingInfo *info)
{
struct tu_render_pass *pass = &cmd_buffer->dynamic_pass;
struct tu_subpass *subpass = &cmd_buffer->dynamic_subpass;
struct tu_subpass *subpass = &cmd_buffer->dynamic_subpasses[0];
const VkCustomResolveCreateInfoEXT *crc_info =
vk_find_struct_const(info->pNext, CUSTOM_RESOLVE_CREATE_INFO_EXT);
bool custom_resolve = crc_info && crc_info->customResolve;
pass->subpass_count = 1;
pass->attachments = cmd_buffer->dynamic_rp_attachments;
@ -1764,12 +1811,16 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
subpass->srgb_cntl = 0;
subpass->raster_order_attachment_access = false;
subpass->multiview_mask = info->viewMask;
subpass->samples = info->rasterizationSamples;
subpass->samples =
custom_resolve ? VK_SAMPLE_COUNT_1_BIT : info->rasterizationSamples;
subpass->custom_resolve = crc_info && crc_info->customResolve;
unsigned a = 0;
for (unsigned i = 0; i < info->colorAttachmentCount; i++) {
struct tu_render_pass_attachment *att = &pass->attachments[a];
VkFormat format = info->pColorAttachmentFormats[i];
VkFormat format =
custom_resolve ? crc_info->pColorAttachmentFormats[i] :
info->pColorAttachmentFormats[i];
if (format == VK_FORMAT_UNDEFINED) {
subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
@ -1777,8 +1828,7 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
}
att->format = format;
att->samples = info->rasterizationSamples;
subpass->samples = info->rasterizationSamples;
att->samples = subpass->samples;
subpass->color_attachments[i].attachment = a++;
/* conservatively assume that the attachment may be conditionally
@ -1787,17 +1837,21 @@ tu_setup_dynamic_inheritance(struct tu_cmd_buffer *cmd_buffer,
att->cond_load_allowed = att->cond_store_allowed = true;
}
if (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ||
info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) {
VkFormat depth_format =
custom_resolve ? crc_info->depthAttachmentFormat :
info->depthAttachmentFormat;
VkFormat stencil_format =
custom_resolve ? crc_info->stencilAttachmentFormat :
info->stencilAttachmentFormat;
if (depth_format != VK_FORMAT_UNDEFINED ||
stencil_format != VK_FORMAT_UNDEFINED) {
struct tu_render_pass_attachment *att = &pass->attachments[a];
att->format = info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ?
info->depthAttachmentFormat : info->stencilAttachmentFormat;
att->samples = info->rasterizationSamples;
att->format = depth_format != VK_FORMAT_UNDEFINED ?
depth_format : stencil_format;
att->samples = subpass->samples;
subpass->depth_stencil_attachment.attachment = a++;
subpass->depth_used =
info->depthAttachmentFormat != VK_FORMAT_UNDEFINED;
subpass->stencil_used =
info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED;
subpass->depth_used = depth_format != VK_FORMAT_UNDEFINED;
subpass->stencil_used = stencil_format != VK_FORMAT_UNDEFINED;
att->cond_load_allowed = att->cond_store_allowed = true;
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;