diff options
| author | Nekle <224100951+ne-kle@users.noreply.github.com> | 2026-02-07 01:37:47 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-02-07 01:37:47 +0100 |
| commit | 75fda70db293123817b8852632fd47a6984741a4 (patch) | |
| tree | 3d0d2e8569b16ca82411783d1923cc0872fe4b10 /src/video_core/renderer_vulkan/vk_scheduler.cpp | |
| parent | b9e052b3a7b9d3f265c16e9c5dacb68473b2bd4c (diff) | |
[vk] Simplified layouts per driver configuration (#3271)
Replaces VK_PIPELINE_STAGE_ALL_COMMANDS_BIT with more specific pipeline stage flags in Vulkan pipeline barriers across renderer modules.
Co-authored-by: DraVee <dravee@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3271
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: DraVee <dravee@eden-emu.dev>
Co-authored-by: Nekle <224100951+ne-kle@users.noreply.github.com>
Co-committed-by: Nekle <224100951+ne-kle@users.noreply.github.com>
Diffstat (limited to 'src/video_core/renderer_vulkan/vk_scheduler.cpp')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.cpp | 96 |
1 files changed, 73 insertions, 23 deletions
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index e526d606dc..aafcfdf65b 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -264,14 +264,26 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se const u64 signal_value = master_semaphore->NextTick(); RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) { + // Specific access flags for upload destinations: vertex input, uniforms, storage, index, textures static constexpr VkMemoryBarrier WRITE_BARRIER{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDEX_READ_BIT | + VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | + VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, }; + // Specify exact stages that need the transfer results instead of ALL_COMMANDS_BIT upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + 0, WRITE_BARRIER); upload_cmdbuf.End(); cmdbuf.End(); @@ -332,11 +344,11 @@ void Scheduler::EndRenderPass() query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false); query_cache->NotifySegment(false); - Record([num_images = num_renderpass_images, images = renderpass_images, ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) { std::array<VkImageMemoryBarrier, 9> barriers; + VkPipelineStageFlags src_stages = 0; for (size_t i = 0; i < num_images; ++i) { const VkImageSubresourceRange& range = ranges[i]; const bool is_color = (range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; @@ -344,38 +356,76 @@ void Scheduler::EndRenderPass() & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=0; + // Determine optimal destination layout based on image usage + // After render pass, images may be used as shader resources or as attachments again + // Use optimal layouts to allow driver optimizations VkAccessFlags src_access = 0; - - if (is_color) - src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - else if (is_depth_stencil) - src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - else - src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT - | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - + VkAccessFlags dst_access = 0; + VkPipelineStageFlags this_stage = 0; + VkImageLayout new_layout; + + if (is_color) { + // Color attachments can be read as textures or used as attachments again + src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + this_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + new_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + dst_access = VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } else if (is_depth_stencil) { + // Depth attachments can be read as textures or used as attachments again + src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + this_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + new_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + dst_access = VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } else { + // Fallback to GENERAL for unknown usage + src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + this_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + new_layout = VK_IMAGE_LAYOUT_GENERAL; + dst_access = VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_SHADER_WRITE_BIT + | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + src_stages |= this_stage; barriers[i] = VkImageMemoryBarrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = src_access, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT - | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT - | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT - | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT - | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .dstAccessMask = dst_access, + .oldLayout = is_color ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + : (is_depth_stencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_GENERAL), + .newLayout = new_layout, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .image = images[i], .subresourceRange = range, }; } + cmdbuf.EndRenderPass(); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + + // Use specific pipeline stages instead of ALL_COMMANDS_BIT for better parallelism + // The destination stages depend on how the images will be used next + const VkPipelineStageFlags dst_stages = + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + + cmdbuf.PipelineBarrier(src_stages, + dst_stages, 0, nullptr, nullptr, |
