@@ -81,6 +81,7 @@ static std::mutex s_instance_mutex;
8181// Device extensions that are required for PCSX2.
8282static constexpr const char * s_required_device_extensions[] = {
8383 VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME ,
84+ VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME ,
8485};
8586
8687GSDeviceVK::GSDeviceVK ()
@@ -1975,21 +1976,32 @@ void GSDeviceVK::SubmitSpinCommand(u32 index, u32 cycles)
19751976 {
19761977 m_spin_buffer_initialized = true ;
19771978 vkCmdFillBuffer (resources.command_buffer , m_spin_buffer, 0 , VK_WHOLE_SIZE , 0 );
1978- VkBufferMemoryBarrier barrier = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
1979+ VkBufferMemoryBarrier2 barrier = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 };
1980+ barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT ;
1981+ barrier.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT ;
19791982 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ;
19801983 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT ;
19811984 barrier.srcQueueFamilyIndex = m_spin_queue_family_index;
19821985 barrier.dstQueueFamilyIndex = m_spin_queue_family_index;
19831986 barrier.buffer = m_spin_buffer;
19841987 barrier.offset = 0 ;
19851988 barrier.size = VK_WHOLE_SIZE ;
1986- vkCmdPipelineBarrier (resources.command_buffer , VK_PIPELINE_STAGE_TRANSFER_BIT ,
1987- VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT , 0 , 0 , nullptr , 1 , &barrier, 0 , nullptr );
1989+ VkDependencyInfo dependency = {VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
1990+ dependency.bufferMemoryBarrierCount = 1 ;
1991+ dependency.pBufferMemoryBarriers = &barrier;
1992+ vkCmdPipelineBarrier2KHR (resources.command_buffer , &dependency);
19881993 }
19891994
19901995 if (m_spin_queue_is_graphics_queue)
1991- vkCmdPipelineBarrier (resources.command_buffer , VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT ,
1992- VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT , 0 , 0 , nullptr , 0 , nullptr , 0 , nullptr );
1996+ {
1997+ VkMemoryBarrier2 barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 };
1998+ barrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT ;
1999+ barrier.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT ;
2000+ VkDependencyInfo dependency = {VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
2001+ dependency.memoryBarrierCount = 1 ;
2002+ dependency.pMemoryBarriers = &barrier;
2003+ vkCmdPipelineBarrier2KHR (resources.command_buffer , &dependency);
2004+ }
19932005
19942006 const u32 timestamp_base = (index + NUM_COMMAND_BUFFERS ) * 2 ;
19952007 vkCmdResetQueryPool (resources.command_buffer , m_timestamp_query_pool, timestamp_base, 2 );
@@ -3028,9 +3040,9 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
30283040 sTexVK ->SetUseFenceCounter (GetCurrentFenceCounter ());
30293041 dTexVK->SetUseFenceCounter (GetCurrentFenceCounter ());
30303042 sTexVK ->TransitionToLayout (
3031- (dTexVK == sTexVK ) ? GSTextureVK::Layout::TransferSelf : GSTextureVK::Layout::TransferSrc );
3043+ (dTexVK == sTexVK ) ? GSTextureVK::Layout::CopySelf : GSTextureVK::Layout::CopySrc );
30323044 dTexVK->TransitionToLayout (
3033- (dTexVK == sTexVK ) ? GSTextureVK::Layout::TransferSelf : GSTextureVK::Layout::TransferDst );
3045+ (dTexVK == sTexVK ) ? GSTextureVK::Layout::CopySelf : GSTextureVK::Layout::CopyDst );
30343046
30353047 vkCmdCopyImage (GetCurrentCommandBuffer (), sTexVK ->GetImage (), sTexVK ->GetVkLayout (), dTexVK->GetImage (),
30363048 dTexVK->GetVkLayout (), 1 , &ic);
@@ -3298,8 +3310,8 @@ void GSDeviceVK::BlitRect(GSTexture* sTex, const GSVector4i& sRect, u32 sLevel,
32983310
32993311 EndRenderPass ();
33003312
3301- sTexVK ->TransitionToLayout (GSTextureVK::Layout::TransferSrc );
3302- dTexVK->TransitionToLayout (GSTextureVK::Layout::TransferDst );
3313+ sTexVK ->TransitionToLayout (GSTextureVK::Layout::BlitSrc );
3314+ dTexVK->TransitionToLayout (GSTextureVK::Layout::BlitDst );
33033315
33043316 // ensure we don't leave this bound later on
33053317 if (m_tfx_textures[0 ] == sTexVK )
@@ -4734,7 +4746,7 @@ void GSDeviceVK::RenderBlankFrame()
47344746
47354747 VkCommandBuffer cmdbuffer = GetCurrentCommandBuffer ();
47364748 GSTextureVK* sctex = m_swap_chain->GetCurrentTexture ();
4737- sctex->TransitionToLayout (cmdbuffer, GSTextureVK::Layout::TransferDst );
4749+ sctex->TransitionToLayout (cmdbuffer, GSTextureVK::Layout::ClearDst );
47384750
47394751 constexpr VkImageSubresourceRange srr = {VK_IMAGE_ASPECT_COLOR_BIT , 0 , 1 , 0 , 1 };
47404752 vkCmdClearColorImage (
@@ -6523,27 +6535,9 @@ void GSDeviceVK::UploadHWDrawVerticesAndIndices(GSHWDrawConfig& config)
65236535 }
65246536}
65256537
6526- VkImageMemoryBarrier GSDeviceVK::GetColorBufferFeedbackBarrier (GSTextureVK* rt) const
6527- {
6528- const VkImageLayout layout =
6529- UseFeedbackLoopLayout () ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : VK_IMAGE_LAYOUT_GENERAL ;
6530- const VkAccessFlags dst_access =
6531- UseFeedbackLoopLayout () ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_INPUT_ATTACHMENT_READ_BIT ;
6532- return {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER , nullptr ,
6533- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT , dst_access, layout, layout,
6534- VK_QUEUE_FAMILY_IGNORED , VK_QUEUE_FAMILY_IGNORED , rt->GetImage (), {VK_IMAGE_ASPECT_COLOR_BIT , 0u , 1u , 0u , 1u }};
6535- }
6536-
6537- VkImageMemoryBarrier GSDeviceVK::GetDepthStencilBufferFeedbackBarrier (GSTextureVK* ds) const
6538+ VkImageLayout GSDeviceVK::GetFeedbackLoopLayout () const
65386539{
6539- const VkImageLayout layout =
6540- UseFeedbackLoopLayout () ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : VK_IMAGE_LAYOUT_GENERAL ;
6541- const VkAccessFlags dst_access =
6542- UseFeedbackLoopLayout () ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_INPUT_ATTACHMENT_READ_BIT ;
6543- return {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER , nullptr ,
6544- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT , dst_access, layout, layout,
6545- VK_QUEUE_FAMILY_IGNORED , VK_QUEUE_FAMILY_IGNORED , ds->GetImage (),
6546- {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT , 0u , 1u , 0u , 1u }};
6540+ return UseFeedbackLoopLayout () ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : VK_IMAGE_LAYOUT_GENERAL ;
65476541}
65486542
65496543VkDependencyFlags GSDeviceVK::GetFeedbackBarrierDependencyFlags () const
@@ -6552,6 +6546,50 @@ VkDependencyFlags GSDeviceVK::GetFeedbackBarrierDependencyFlags() const
65526546 VK_DEPENDENCY_BY_REGION_BIT ;
65536547}
65546548
6549+ VkAccessFlagBits2 GSDeviceVK::GetFeedbackLoopInputAccessBits () const
6550+ {
6551+ return UseFeedbackLoopLayout () ? VK_ACCESS_2_SHADER_READ_BIT : VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT ;
6552+ }
6553+
6554+ void GSDeviceVK::FeedbackBarrier (GSTextureVK* rt, GSTextureVK* ds)
6555+ {
6556+ VkImageMemoryBarrier2 barrier_template = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
6557+ barrier_template.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT ;
6558+ barrier_template.dstAccessMask = GetFeedbackLoopInputAccessBits ();
6559+ barrier_template.oldLayout = GetFeedbackLoopLayout ();
6560+ barrier_template.newLayout = GetFeedbackLoopLayout ();
6561+ barrier_template.subresourceRange .levelCount = 1 ;
6562+ barrier_template.subresourceRange .layerCount = 1 ;
6563+
6564+ std::array<VkImageMemoryBarrier2, 2 > barriers;
6565+ u32 num_barriers = 0 ;
6566+
6567+ if (rt)
6568+ {
6569+ VkImageMemoryBarrier2& barrier = barriers[num_barriers++] = barrier_template;
6570+ barrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT ;
6571+ barrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT ;
6572+ barrier.image = rt->GetImage ();
6573+ barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
6574+ }
6575+
6576+ if (ds)
6577+ {
6578+ VkImageMemoryBarrier2& barrier = barriers[num_barriers++] = barrier_template;
6579+ barrier.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT ;
6580+ barrier.srcAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
6581+ barrier.image = ds->GetImage ();
6582+ barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT ; // We don't do stencil feedback, so depth only
6583+ }
6584+
6585+ VkDependencyInfo dependency = {VK_STRUCTURE_TYPE_DEPENDENCY_INFO };
6586+ dependency.dependencyFlags = GetFeedbackBarrierDependencyFlags ();
6587+ dependency.imageMemoryBarrierCount = num_barriers;
6588+ dependency.pImageMemoryBarriers = barriers.data ();
6589+
6590+ vkCmdPipelineBarrier2KHR (GetCurrentCommandBuffer (), &dependency);
6591+ }
6592+
65556593void GSDeviceVK::SendHWDraw (const GSHWDrawConfig& config, GSTextureVK* draw_rt, GSTextureVK* draw_ds,
65566594 bool one_barrier, bool full_barrier)
65576595{
@@ -6565,38 +6603,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt,
65656603 if ((one_barrier || full_barrier) && !(config.IsFeedbackLoopRT (m_pipeline_selector.ps ) || config.IsFeedbackLoopDepth (m_pipeline_selector.ps ))) [[unlikely]]
65666604 Console.Warning (" VK: Possible unnecessary barrier detected." );
65676605#endif
6568- VkDependencyFlags barrier_flags = GetFeedbackBarrierDependencyFlags ();
6569-
6570- std::array<VkImageMemoryBarrier, 2 > barriers;
6571- u32 n_barriers = 0 ;
6572- if (full_barrier || one_barrier)
6573- {
6574- if (draw_rt)
6575- {
6576- barriers[0 ] = GetColorBufferFeedbackBarrier (draw_rt);
6577- n_barriers++;
6578- }
6579- if (draw_ds)
6580- {
6581- barriers[1 ] = GetDepthStencilBufferFeedbackBarrier (draw_ds);
6582- n_barriers++;
6583- }
6584- }
6585-
6586- const auto IssueBarriers = [&]() {
6587- if (draw_rt)
6588- {
6589- vkCmdPipelineBarrier (GetCurrentCommandBuffer (),
6590- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT ,
6591- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT , barrier_flags, 0 , nullptr , 0 , nullptr , 1 , &barriers[0 ]);
6592- }
6593- if (draw_ds)
6594- {
6595- vkCmdPipelineBarrier (GetCurrentCommandBuffer (),
6596- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT ,
6597- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT , barrier_flags, 0 , nullptr , 0 , nullptr , 1 , &barriers[1 ]);
6598- }
6599- };
6606+ const int n_barriers = (draw_rt ? 1 : 0 ) + (draw_ds ? 1 : 0 );
66006607
66016608 if (full_barrier)
66026609 {
@@ -6610,7 +6617,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt,
66106617
66116618 for (u32 n = 0 , p = 0 ; n < draw_list_size; n++)
66126619 {
6613- IssueBarriers ( );
6620+ FeedbackBarrier (draw_rt, draw_ds );
66146621
66156622 const u32 count = config.drawlist ->at (n) * indices_per_prim;
66166623 Draw (config, p, count);
@@ -6623,7 +6630,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt,
66236630 if (one_barrier)
66246631 {
66256632 g_perfmon.Put (GSPerfMon::Barriers, n_barriers);
6626- IssueBarriers ( );
6633+ FeedbackBarrier (draw_rt, draw_ds );
66276634 }
66286635
66296636 Draw (config);
0 commit comments