@@ -1145,6 +1145,138 @@ VkResult VulkanVirtualSwapchain::QueuePresentKHR(VkResult
11451145 return func (queue, &modified_present_info);
11461146}
11471147
1148+ void VulkanVirtualSwapchain::ProcessSetSwapchainImageStateCommand (
1149+ const VulkanDeviceInfo* device_info,
1150+ VulkanSwapchainKHRInfo* swapchain_info,
1151+ uint32_t last_presented_image,
1152+ const std::vector<format::SwapchainImageStateInfo>& image_infos,
1153+ const CommonObjectInfoTable& object_info_table,
1154+ SwapchainImageTracker& swapchain_image_tracker)
1155+ {
1156+ GFXRECON_UNREFERENCED_PARAMETER (last_presented_image);
1157+ GFXRECON_UNREFERENCED_PARAMETER (swapchain_image_tracker);
1158+
1159+ GFXRECON_ASSERT (device_table_ != nullptr );
1160+
1161+ VkDevice device = device_info->handle ;
1162+ uint32_t queue_family_index = swapchain_info->queue_family_indices [0 ];
1163+
1164+ VkQueue transition_queue = GetDeviceQueue (device_table_, device_info, queue_family_index, 0 );
1165+ if (transition_queue == VK_NULL_HANDLE )
1166+ {
1167+ GFXRECON_LOG_WARNING (" Failed image layout restore for VkSwapchainKHR object (ID = %" PRIu64
1168+ " ), could not get device queue %u" ,
1169+ swapchain_info->capture_id ,
1170+ queue_family_index);
1171+ return ;
1172+ }
1173+
1174+ // trim-state setup has already run, so mark as injected from here
1175+ util::MarkInjectedCommandsHelper mark_injected_commands_helper;
1176+
1177+ VkCommandPool transition_pool = VK_NULL_HANDLE ;
1178+ VkCommandBuffer transition_command = VK_NULL_HANDLE ;
1179+
1180+ VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
1181+ pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT ;
1182+ pool_create_info.queueFamilyIndex = queue_family_index;
1183+
1184+ VkResult result = device_table_->CreateCommandPool (device, &pool_create_info, nullptr , &transition_pool);
1185+
1186+ if (result == VK_SUCCESS )
1187+ {
1188+ VkCommandBufferAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
1189+ allocate_info.commandPool = transition_pool;
1190+ allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY ;
1191+ allocate_info.commandBufferCount = 1 ;
1192+
1193+ result = device_table_->AllocateCommandBuffers (device, &allocate_info, &transition_command);
1194+ }
1195+
1196+ if (result == VK_SUCCESS )
1197+ {
1198+ VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
1199+ begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT ;
1200+ result = device_table_->BeginCommandBuffer (transition_command, &begin_info);
1201+ }
1202+
1203+ if (result == VK_SUCCESS )
1204+ {
1205+ // Transition the virtual images to their captured layouts. They are plain images, so no acquire is
1206+ // required; the real swapchain images are transitioned separately on first acquire.
1207+ VkImageMemoryBarrier image_barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
1208+ image_barrier.srcAccessMask = VK_ACCESS_NONE ;
1209+ image_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT ;
1210+ image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
1211+ image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
1212+ image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
1213+ image_barrier.subresourceRange .baseMipLevel = 0 ;
1214+ image_barrier.subresourceRange .levelCount = VK_REMAINING_MIP_LEVELS ;
1215+ image_barrier.subresourceRange .baseArrayLayer = 0 ;
1216+ image_barrier.subresourceRange .layerCount = VK_REMAINING_ARRAY_LAYERS ;
1217+
1218+ uint32_t barrier_count = 0 ;
1219+
1220+ for (const auto & entry : image_infos)
1221+ {
1222+ const VulkanImageInfo* image_info = object_info_table.GetVkImageInfo (entry.image_id );
1223+ if (image_info == nullptr )
1224+ {
1225+ GFXRECON_LOG_WARNING (" Skipping layout restore for unrecognized VkImage object (ID = %" PRIu64 " )" ,
1226+ entry.image_id );
1227+ continue ;
1228+ }
1229+
1230+ auto image_layout = static_cast <VkImageLayout>(entry.image_layout );
1231+ if (image_layout == VK_IMAGE_LAYOUT_UNDEFINED )
1232+ {
1233+ continue ;
1234+ }
1235+
1236+ image_barrier.newLayout = image_layout;
1237+ image_barrier.image = image_info->handle ;
1238+ image_barrier.subresourceRange .aspectMask = graphics::GetFormatAspects (image_info->format );
1239+
1240+ device_table_->CmdPipelineBarrier (transition_command,
1241+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ,
1242+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT ,
1243+ 0 ,
1244+ 0 ,
1245+ nullptr ,
1246+ 0 ,
1247+ nullptr ,
1248+ 1 ,
1249+ &image_barrier);
1250+ ++barrier_count;
1251+ }
1252+ result = device_table_->EndCommandBuffer (transition_command);
1253+
1254+ if (result == VK_SUCCESS && barrier_count > 0 )
1255+ {
1256+ VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
1257+ submit_info.commandBufferCount = 1 ;
1258+ submit_info.pCommandBuffers = &transition_command;
1259+ result = device_table_->QueueSubmit (transition_queue, 1 , &submit_info, VK_NULL_HANDLE );
1260+
1261+ if (result == VK_SUCCESS )
1262+ {
1263+ result = device_table_->QueueWaitIdle (transition_queue);
1264+ }
1265+ }
1266+ }
1267+
1268+ if (result != VK_SUCCESS )
1269+ {
1270+ GFXRECON_LOG_WARNING (" Failed image layout restore for VkSwapchainKHR object (ID = %" PRIu64 " )" ,
1271+ swapchain_info->capture_id );
1272+ }
1273+
1274+ if (transition_pool != VK_NULL_HANDLE )
1275+ {
1276+ device_table_->DestroyCommandPool (device, transition_pool, nullptr );
1277+ }
1278+ }
1279+
11481280VkResult VulkanVirtualSwapchain::CreateRenderPass (VkResult original_result,
11491281 PFN_vkCreateRenderPass func,
11501282 const VulkanDeviceInfo* device_info,
0 commit comments