diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 99add8735b..6b94dfa70b 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -1068,10 +1068,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, .layerCount = VK_REMAINING_ARRAY_LAYERS, }; const std::array pre_barriers{ - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + VkImageMemoryBarrier2{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .pNext = nullptr, + .srcStageMask = aspect_info.pre_src_stages, .srcAccessMask = aspect_info.pre_src_access, + .dstStageMask = aspect_info.pre_src_dst_stages, .dstAccessMask = aspect_info.pre_src_dst_access, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, @@ -1080,10 +1082,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, .image = src, .subresourceRange = barrier_range, }, - VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + VkImageMemoryBarrier2{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .pNext = nullptr, + .srcStageMask = aspect_info.pre_src_stages, .srcAccessMask = aspect_info.pre_src_access, + .dstStageMask = aspect_info.pre_dst_dst_stages, .dstAccessMask = aspect_info.pre_dst_dst_access, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, @@ -1093,8 +1097,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, .subresourceRange = barrier_range, }, }; - cmdbuf.PipelineBarrier(aspect_info.pre_src_stages, aspect_info.pre_dst_stages, 0, - nullptr, nullptr, pre_barriers); + cmdbuf.PipelineBarrier2Images(0, pre_barriers); const VkRenderPassBeginInfo renderpass_bi{ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .pNext = nullptr, @@ -1130,10 +1133,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants); cmdbuf.Draw(3, 1, 0, 0); cmdbuf.EndRenderPass(); - const VkImageMemoryBarrier post_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + const VkImageMemoryBarrier2 post_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .pNext = nullptr, + .srcStageMask = aspect_info.post_src_stages, .srcAccessMask = aspect_info.post_src_access, + .dstStageMask = aspect_info.post_dst_stages, .dstAccessMask = aspect_info.post_dst_access, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, @@ -1142,8 +1147,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, .image = dst, .subresourceRange = barrier_range, }; - cmdbuf.PipelineBarrier(aspect_info.post_src_stages, aspect_info.post_dst_stages, 0, - post_barrier); + cmdbuf.PipelineBarrier2Images(0, post_barrier); }); msaa_copy_resources.push_back(MSAACopyResources{ .tick = scheduler.CurrentTick(), @@ -1192,21 +1196,23 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i .src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .barrier_aspect = VK_IMAGE_ASPECT_COLOR_BIT, - .pre_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT | - VK_ACCESS_TRANSFER_WRITE_BIT, - .pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT, + .pre_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_SHADER_WRITE_BIT | + VK_ACCESS_2_TRANSFER_WRITE_BIT, + .pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, .pre_dst_dst_access = - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .pre_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, - .pre_dst_stages = - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .post_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, - .post_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .post_dst_stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + .pre_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_2_TRANSFER_BIT, + .pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + .pre_dst_dst_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + .post_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + .post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT, + .post_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + .post_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | + VK_PIPELINE_STAGE_2_TRANSFER_BIT, }; const VkFormat src_vk_format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format; @@ -1702,19 +1708,19 @@ void BlitImageHelper::CopyMSAADepth(RenderPassCache& render_pass_cache, VkImage .attachment_aspect = attachment_aspect, .barrier_aspect = attachment_aspect, .pre_src_access = - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, - .pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT, - .pre_dst_dst_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .pre_src_stages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_TRANSFER_BIT, - .pre_dst_stages = - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .post_src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - .post_src_stages = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT, + .pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, + .pre_dst_dst_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .pre_src_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_TRANSFER_BIT, + .pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + .pre_dst_dst_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT, + .post_src_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT | + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + .post_src_stages = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, .post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, }; const VkFormat src_vk_format = diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index cc6dc421ed..08cab788aa 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -140,15 +140,16 @@ private: VkImageAspectFlags src_view_aspect; VkImageAspectFlags attachment_aspect; VkImageAspectFlags barrier_aspect; - VkAccessFlags pre_src_access; - VkAccessFlags pre_src_dst_access; - VkAccessFlags pre_dst_dst_access; - VkPipelineStageFlags pre_src_stages; - VkPipelineStageFlags pre_dst_stages; - VkAccessFlags post_src_access; - VkAccessFlags post_dst_access; - VkPipelineStageFlags post_src_stages; - VkPipelineStageFlags post_dst_stages; + VkAccessFlags2 pre_src_access; + VkAccessFlags2 pre_src_dst_access; + VkAccessFlags2 pre_dst_dst_access; + VkPipelineStageFlags2 pre_src_stages; + VkPipelineStageFlags2 pre_src_dst_stages; + VkPipelineStageFlags2 pre_dst_dst_stages; + VkAccessFlags2 post_src_access; + VkAccessFlags2 post_dst_access; + VkPipelineStageFlags2 post_src_stages; + VkPipelineStageFlags2 post_dst_stages; }; void CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, VkPipelineLayout layout, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f22d1e1ae8..04bce948f1 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -363,8 +363,6 @@ void RasterizerVulkan::DrawTexture() { UpdateDynamicStates(); - query_cache.NotifySegment(true); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state; const auto& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false); const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture); @@ -495,10 +493,10 @@ void RasterizerVulkan::Clear(u32 layer_count) { (!use_color || color_full_channels) && ds_deferrable; if (!can_defer_clear) { scheduler.RequestRenderpass(framebuffer); + query_cache.NotifySegment(true); + query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); } - query_cache.NotifySegment(true); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); UpdateViewportsState(regs); const u32 color_attachment = regs.clear_surface.RT; @@ -1877,19 +1875,13 @@ void RasterizerVulkan::UpdateColorWriteEnable(Tegra::Engines::Maxwell3D::Regs& r if (!state_tracker.TouchColorMask()) { return; } - size_t num_attachments{}; - for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) { - if (regs.rt[index].format != Tegra::RenderTargetFormat::NONE) { - num_attachments = index + 1; - } - } std::array setup_enables{}; for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) { const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : index]; setup_enables[index] = (mask.R || mask.G || mask.B || mask.A) ? VK_TRUE : VK_FALSE; } - scheduler.Record([setup_enables, num_attachments](vk::CommandBuffer cmdbuf) { - cmdbuf.SetColorWriteEnableEXT(vk::Span(setup_enables.data(), num_attachments)); + scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) { + cmdbuf.SetColorWriteEnableEXT(setup_enables); }); } diff --git a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp index a00d147db5..b992f6361c 100644 --- a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp @@ -331,10 +331,6 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) { }; if (device->HasSynchronization2()) { counter_resume_dependency2.pNext = &counter_resume_barrier; - counter_resume_dependency2.srcStageMask = 0; - counter_resume_dependency2.dstStageMask = 0; - counter_resume_dependency2.srcAccessMask = 0; - counter_resume_dependency2.dstAccessMask = 0; } const VkSubpassDependency2 feedback_loop_dependency2{ .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 31e852e943..1310476c6a 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -421,18 +421,21 @@ void Scheduler::EndRenderPass() Record([num_images = num_renderpass_images, images = renderpass_images, ranges = renderpass_image_ranges, - consumer_stages = device.AttachmentConsumerStages(), + shader_stages = device.ShaderConsumerStages(), has_transform_feedback = device.IsExtTransformFeedbackSupported()]( vk::CommandBuffer cmdbuf) { - static constexpr VkAccessFlags SHADER_ACCESS = - VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - static constexpr VkAccessFlags COLOR_ACCESS = - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - static constexpr VkAccessFlags DEPTH_STENCIL_ACCESS = - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + static constexpr VkAccessFlags2 SHADER_ACCESS = + VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; + static constexpr VkAccessFlags2 COLOR_ACCESS = + VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + static constexpr VkAccessFlags2 DEPTH_STENCIL_ACCESS = + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + static constexpr VkPipelineStageFlags2 DEPTH_STENCIL_STAGES = + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; - std::array barriers; + std::array barriers; 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; @@ -440,25 +443,37 @@ void Scheduler::EndRenderPass() & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=0; - VkAccessFlags src_access = 0; - VkAccessFlags dst_access = SHADER_ACCESS; + VkPipelineStageFlags2 src_stages = 0; + VkAccessFlags2 src_access = 0; + VkPipelineStageFlags2 dst_stages = shader_stages; + VkAccessFlags2 dst_access = SHADER_ACCESS; if (is_color) { - src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + src_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + src_access |= VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + dst_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; dst_access |= COLOR_ACCESS; } else if (is_depth_stencil) { - src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + src_stages |= DEPTH_STENCIL_STAGES; + src_access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + dst_stages |= DEPTH_STENCIL_STAGES; dst_access |= DEPTH_STENCIL_ACCESS; } else { - src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT - | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + src_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT + | DEPTH_STENCIL_STAGES; + src_access |= VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT + | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + dst_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT + | DEPTH_STENCIL_STAGES; dst_access |= COLOR_ACCESS | DEPTH_STENCIL_ACCESS; } - barriers[i] = VkImageMemoryBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + barriers[i] = VkImageMemoryBarrier2{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .pNext = nullptr, + .srcStageMask = src_stages, .srcAccessMask = src_access, + .dstStageMask = dst_stages, .dstAccessMask = dst_access, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, @@ -469,19 +484,19 @@ void Scheduler::EndRenderPass() }; } 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, consumer_stages, - 0, nullptr, nullptr, vk::Span(barriers.data(), num_images)); + cmdbuf.PipelineBarrier2Images(0, vk::Span(barriers.data(), num_images)); if (has_transform_feedback) { - static constexpr VkMemoryBarrier XFB_OUTPUT_BARRIER{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + static constexpr VkMemoryBarrier2 XFB_OUTPUT_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .pNext = nullptr, - .srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, - .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, + .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT, + .srcAccessMask = VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, + .dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT | + VK_PIPELINE_STAGE_2_TRANSFER_BIT, + .dstAccessMask = VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT | + VK_ACCESS_2_TRANSFER_READ_BIT, }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, XFB_OUTPUT_BARRIER); + cmdbuf.PipelineBarrier2Memory(0, XFB_OUTPUT_BARRIER); } }); diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index d32aa95668..8083e376fe 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -1027,14 +1027,11 @@ FN_MAX_LIMIT_LIST return features2.features.geometryShader; } - VkPipelineStageFlags AttachmentConsumerStages() const { + VkPipelineStageFlags ShaderConsumerStages() const { VkPipelineStageFlags stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; if (features2.features.geometryShader) { stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; @@ -1042,6 +1039,12 @@ FN_MAX_LIMIT_LIST return stages; } + VkPipelineStageFlags AttachmentConsumerStages() const { + return ShaderConsumerStages() | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + } + /// Returns true if the device supports VK_KHR_maintenance1. bool IsKhrMaintenance1Supported() const { return extensions.maintenance1; diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 33173e956d..9013bb3c49 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "common/common_types.h" #include "common/logging.h" #include "video_core/vulkan_common/vk_enum_string_helper.h" @@ -296,6 +298,76 @@ void SetObjectName(const DeviceDispatch* dld, VkDevice device, T handle, VkObjec } // Anonymous namespace +void PipelineBarrierDowngrade(const DeviceDispatch& dld, VkCommandBuffer handle, + VkDependencyFlags dependency_flags, + Span memory_barriers, + Span buffer_barriers, + Span image_barriers) { + VkPipelineStageFlags2 src_stages = 0; + VkPipelineStageFlags2 dst_stages = 0; + for (const VkMemoryBarrier2& barrier : memory_barriers) { + src_stages |= barrier.srcStageMask; + dst_stages |= barrier.dstStageMask; + } + for (const VkBufferMemoryBarrier2& barrier : buffer_barriers) { + src_stages |= barrier.srcStageMask; + dst_stages |= barrier.dstStageMask; + } + for (const VkImageMemoryBarrier2& barrier : image_barriers) { + src_stages |= barrier.srcStageMask; + dst_stages |= barrier.dstStageMask; + } + + boost::container::small_vector memory; + memory.reserve(memory_barriers.size()); + for (const VkMemoryBarrier2& barrier : memory_barriers) { + memory.push_back(VkMemoryBarrier{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask), + .dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask), + }); + } + boost::container::small_vector buffers; + buffers.reserve(buffer_barriers.size()); + for (const VkBufferMemoryBarrier2& barrier : buffer_barriers) { + buffers.push_back(VkBufferMemoryBarrier{ + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask), + .dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask), + .srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, + .dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, + .buffer = barrier.buffer, + .offset = barrier.offset, + .size = barrier.size, + }); + } + boost::container::small_vector images; + images.reserve(image_barriers.size()); + for (const VkImageMemoryBarrier2& barrier : image_barriers) { + images.push_back(VkImageMemoryBarrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask), + .dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask), + .oldLayout = barrier.oldLayout, + .newLayout = barrier.newLayout, + .srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, + .dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, + .image = barrier.image, + .subresourceRange = barrier.subresourceRange, + }); + } + + dld.vkCmdPipelineBarrier(handle, + DowngradeStageMask(src_stages, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT), + DowngradeStageMask(dst_stages, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT), + dependency_flags, static_cast(memory.size()), memory.data(), + static_cast(buffers.size()), buffers.data(), + static_cast(images.size()), images.data()); +} + bool Load(InstanceDispatch& dld) noexcept { #define X(name) Proc(dld.name, dld, #name) return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) && diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index d4e8e2aebc..f29eb176f6 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -158,6 +158,41 @@ inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_H inline constexpr VkPipelineStageFlags PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_HOST_BIT; +constexpr VkPipelineStageFlags DowngradeStageMask(VkPipelineStageFlags2 mask, + VkPipelineStageFlags empty) noexcept { + VkPipelineStageFlags result = static_cast(mask & 0xFFFFFFFFULL); + if ((mask & (VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_RESOLVE_BIT | + VK_PIPELINE_STAGE_2_BLIT_BIT | VK_PIPELINE_STAGE_2_CLEAR_BIT)) != 0) { + result |= VK_PIPELINE_STAGE_TRANSFER_BIT; + } + if ((mask & VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT) != 0) { + result |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; + } + if ((mask & VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT) != 0) { + result |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + } + if ((mask & VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT) != 0) { + result |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + } + if (result == 0) { + return empty; + } + return result; +} + +constexpr VkAccessFlags DowngradeAccessMask(VkAccessFlags2 mask) noexcept { + VkAccessFlags result = static_cast(mask & 0xFFFFFFFFULL); + if ((mask & (VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_SHADER_STORAGE_READ_BIT)) != 0) { + result |= VK_ACCESS_SHADER_READ_BIT; + } + if ((mask & VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT) != 0) { + result |= VK_ACCESS_SHADER_WRITE_BIT; + } + return result; +} + /// Table holding Vulkan instance function pointers. struct InstanceDispatch { @@ -1197,6 +1232,12 @@ private: const InstanceDispatch* dld = nullptr; }; +void PipelineBarrierDowngrade(const DeviceDispatch& dld, VkCommandBuffer handle, + VkDependencyFlags dependency_flags, + Span memory_barriers, + Span buffer_barriers, + Span image_barriers); + class CommandBuffer { public: CommandBuffer() noexcept = default; @@ -1347,78 +1388,45 @@ public: VkDependencyFlags dependency_flags, Span memory_barriers, Span buffer_barriers, Span image_barriers) const noexcept { - static constexpr u32 MaxBarriers = 16; - if (dld->vkCmdPipelineBarrier2 && memory_barriers.size() <= MaxBarriers && - buffer_barriers.size() <= MaxBarriers && image_barriers.size() <= MaxBarriers) { - const auto src_stage_mask2 = static_cast(src_stage_mask); - const auto dst_stage_mask2 = static_cast(dst_stage_mask); - - std::array memory_barriers2; - for (u32 i = 0; i < memory_barriers.size(); ++i) { - memory_barriers2[i] = VkMemoryBarrier2{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = src_stage_mask2, - .srcAccessMask = static_cast(memory_barriers[i].srcAccessMask), - .dstStageMask = dst_stage_mask2, - .dstAccessMask = static_cast(memory_barriers[i].dstAccessMask), - }; - } - std::array buffer_barriers2; - for (u32 i = 0; i < buffer_barriers.size(); ++i) { - const auto& barrier = buffer_barriers[i]; - buffer_barriers2[i] = VkBufferMemoryBarrier2{ - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = src_stage_mask2, - .srcAccessMask = static_cast(barrier.srcAccessMask), - .dstStageMask = dst_stage_mask2, - .dstAccessMask = static_cast(barrier.dstAccessMask), - .srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, - .dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, - .buffer = barrier.buffer, - .offset = barrier.offset, - .size = barrier.size, - }; - } - std::array image_barriers2; - for (u32 i = 0; i < image_barriers.size(); ++i) { - const auto& barrier = image_barriers[i]; - image_barriers2[i] = VkImageMemoryBarrier2{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = src_stage_mask2, - .srcAccessMask = static_cast(barrier.srcAccessMask), - .dstStageMask = dst_stage_mask2, - .dstAccessMask = static_cast(barrier.dstAccessMask), - .oldLayout = barrier.oldLayout, - .newLayout = barrier.newLayout, - .srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, - .dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, - .image = barrier.image, - .subresourceRange = barrier.subresourceRange, - }; - } - const VkDependencyInfo dependency_info{ - .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - .pNext = nullptr, - .dependencyFlags = dependency_flags, - .memoryBarrierCount = memory_barriers.size(), - .pMemoryBarriers = memory_barriers2.data(), - .bufferMemoryBarrierCount = buffer_barriers.size(), - .pBufferMemoryBarriers = buffer_barriers2.data(), - .imageMemoryBarrierCount = image_barriers.size(), - .pImageMemoryBarriers = image_barriers2.data(), - }; - dld->vkCmdPipelineBarrier2(handle, &dependency_info); - return; - } dld->vkCmdPipelineBarrier(handle, src_stage_mask, dst_stage_mask, dependency_flags, memory_barriers.size(), memory_barriers.data(), buffer_barriers.size(), buffer_barriers.data(), image_barriers.size(), image_barriers.data()); } + void PipelineBarrier2(VkDependencyFlags dependency_flags, + Span memory_barriers, + Span buffer_barriers, + Span image_barriers) const noexcept { + if (!dld->vkCmdPipelineBarrier2) { + PipelineBarrierDowngrade(*dld, handle, dependency_flags, memory_barriers, + buffer_barriers, image_barriers); + return; + } + const VkDependencyInfo dependency_info{ + .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + .pNext = nullptr, + .dependencyFlags = dependency_flags, + .memoryBarrierCount = memory_barriers.size(), + .pMemoryBarriers = memory_barriers.data(), + .bufferMemoryBarrierCount = buffer_barriers.size(), + .pBufferMemoryBarriers = buffer_barriers.data(), + .imageMemoryBarrierCount = image_barriers.size(), + .pImageMemoryBarriers = image_barriers.data(), + }; + dld->vkCmdPipelineBarrier2(handle, &dependency_info); + } + + void PipelineBarrier2Images(VkDependencyFlags dependency_flags, + Span image_barriers) const noexcept { + PipelineBarrier2(dependency_flags, {}, {}, image_barriers); + } + + void PipelineBarrier2Memory(VkDependencyFlags dependency_flags, + Span memory_barriers) const noexcept { + PipelineBarrier2(dependency_flags, memory_barriers, {}, {}); + } + void PipelineBarrier(VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, VkDependencyFlags dependency_flags = 0) const noexcept { PipelineBarrier(src_stage_mask, dst_stage_mask, dependency_flags, {}, {}, {});