Fix subpass MSAA resolves with multiple layers not working on D3D12.

This commit is contained in:
Skyth committed 2026-05-04 15:29:59 +03:00
1 parent 16bb065ac3
commit 5aecc0da58
1 file changed
+35 -26
+35 -26
View File
@@ -4508,8 +4508,9 @@ void RenderingDeviceDriverD3D12::_end_render_pass(CommandBufferID p_cmd_buffer)
uint32_t dst_subres = 0;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
};
Resolve *resolves = ALLOCA_ARRAY(Resolve, subpass.resolve_references.size());
uint32_t num_resolves = 0;
thread_local LocalVector<Resolve> resolves;
resolves.clear();
for (uint32_t i = 0; i < subpass.resolve_references.size(); i++) {
uint32_t color_index = subpass.color_references[i].attachment;
@@ -4520,41 +4521,49 @@ void RenderingDeviceDriverD3D12::_end_render_pass(CommandBufferID p_cmd_buffer)
}
TextureInfo *src_tex_info = (TextureInfo *)fb_info->attachments[color_index].id;
uint32_t src_subresource = D3D12CalcSubresource(src_tex_info->base_mip, src_tex_info->base_layer, 0, src_tex_info->desc.MipLevels, src_tex_info->desc.ArraySize());
if (barrier_capabilities.enhanced_barriers_supported) {
cmd_buf_info->render_pass_state.attachment_layouts[color_index].aspect_layouts[TEXTURE_ASPECT_COLOR].expected_layout = TEXTURE_LAYOUT_RESOLVE_SRC_OPTIMAL;
} else {
_resource_transition_batch(cmd_buf_info, src_tex_info, src_subresource, 1, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
}
TextureInfo *dst_tex_info = (TextureInfo *)fb_info->attachments[resolve_index].id;
uint32_t dst_subresource = D3D12CalcSubresource(dst_tex_info->base_mip, dst_tex_info->base_layer, 0, dst_tex_info->desc.MipLevels, dst_tex_info->desc.ArraySize());
if (barrier_capabilities.enhanced_barriers_supported) {
// This should have already been done when beginning the subpass.
DEV_ASSERT(cmd_buf_info->render_pass_state.attachment_layouts[resolve_index].aspect_layouts[TEXTURE_ASPECT_COLOR].expected_layout == TEXTURE_LAYOUT_RESOLVE_DST_OPTIMAL);
} else {
_resource_transition_batch(cmd_buf_info, dst_tex_info, dst_subresource, 1, D3D12_RESOURCE_STATE_RESOLVE_DEST);
DEV_ASSERT(src_tex_info->mipmaps == dst_tex_info->mipmaps && src_tex_info->layers == dst_tex_info->layers);
for (uint32_t mip = 0; mip < src_tex_info->mipmaps; mip++) {
for (uint32_t layer = 0; layer < src_tex_info->layers; layer++) {
uint32_t src_subresource = D3D12CalcSubresource(src_tex_info->base_mip + mip, src_tex_info->base_layer + layer, 0, src_tex_info->desc.MipLevels, src_tex_info->desc.ArraySize());
if (barrier_capabilities.enhanced_barriers_supported) {
cmd_buf_info->render_pass_state.attachment_layouts[color_index].aspect_layouts[TEXTURE_ASPECT_COLOR].expected_layout = TEXTURE_LAYOUT_RESOLVE_SRC_OPTIMAL;
} else {
_resource_transition_batch(cmd_buf_info, src_tex_info, src_subresource, 1, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
}
uint32_t dst_subresource = D3D12CalcSubresource(dst_tex_info->base_mip + mip, dst_tex_info->base_layer + layer, 0, dst_tex_info->desc.MipLevels, dst_tex_info->desc.ArraySize());
if (barrier_capabilities.enhanced_barriers_supported) {
// This should have already been done when beginning the subpass.
DEV_ASSERT(cmd_buf_info->render_pass_state.attachment_layouts[resolve_index].aspect_layouts[TEXTURE_ASPECT_COLOR].expected_layout == TEXTURE_LAYOUT_RESOLVE_DST_OPTIMAL);
} else {
_resource_transition_batch(cmd_buf_info, dst_tex_info, dst_subresource, 1, D3D12_RESOURCE_STATE_RESOLVE_DEST);
}
Resolve resolve = {};
resolve.src_res = src_tex_info->resource;
resolve.src_subres = src_subresource;
resolve.dst_res = dst_tex_info->resource;
resolve.dst_subres = dst_subresource;
resolve.format = RD_TO_D3D12_FORMAT[src_tex_info->format].general_format;
resolves.push_back(resolve);
}
}
resolves[num_resolves].src_res = src_tex_info->resource;
resolves[num_resolves].src_subres = src_subresource;
resolves[num_resolves].dst_res = dst_tex_info->resource;
resolves[num_resolves].dst_subres = dst_subresource;
resolves[num_resolves].format = RD_TO_D3D12_FORMAT[src_tex_info->format].general_format;
num_resolves++;
}
_resource_transitions_flush(cmd_buf_info);
// There can be enhanced barriers to flush only when we need to resolve textures.
if (num_resolves != 0) {
if (!resolves.is_empty()) {
_render_pass_enhanced_barriers_flush(p_cmd_buffer);
}
for (uint32_t i = 0; i < num_resolves; i++) {
cmd_buf_info->cmd_list->ResolveSubresource(resolves[i].dst_res, resolves[i].dst_subres, resolves[i].src_res, resolves[i].src_subres, resolves[i].format);
for (const Resolve &resolve : resolves) {
cmd_buf_info->cmd_list->ResolveSubresource(resolve.dst_res, resolve.dst_subres, resolve.src_res, resolve.src_subres, resolve.format);
}
}