diff --git a/bin/resources/shaders/vulkan/tfx.glsl b/bin/resources/shaders/vulkan/tfx.glsl index 4099a6d0e1..49d0879738 100644 --- a/bin/resources/shaders/vulkan/tfx.glsl +++ b/bin/resources/shaders/vulkan/tfx.glsl @@ -349,7 +349,7 @@ layout(set = 1, binding = 1) uniform texture2D Palette; #endif #if PS_FEEDBACK_LOOP_IS_NEEDED - #if defined(DISABLE_TEXTURE_BARRIER) + #if defined(DISABLE_TEXTURE_BARRIER) || defined(HAS_FEEDBACK_LOOP_LAYOUT) layout(set = 1, binding = 2) uniform texture2D RtSampler; vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); } #else diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index 450ff59116..38547adf44 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -414,6 +414,8 @@ bool GSDeviceVK::SelectDeviceExtensions(ExtensionList* extension_list, bool enab SupportsExtension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, false); m_optional_extensions.vk_ext_rasterization_order_attachment_access = SupportsExtension(VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false); + m_optional_extensions.vk_ext_attachment_feedback_loop_layout = + SupportsExtension(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, false); m_optional_extensions.vk_ext_line_rasterization = SupportsExtension(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, require_line_rasterization); m_optional_extensions.vk_khr_driver_properties = SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false); @@ -616,6 +618,8 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT}; VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_feature = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT}; + VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachment_feedback_loop_feature = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT}; VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT}; @@ -634,6 +638,11 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE; Vulkan::AddPointerToChain(&device_info, &rasterization_order_access_feature); } + if (m_optional_extensions.vk_ext_attachment_feedback_loop_layout) + { + attachment_feedback_loop_feature.attachmentFeedbackLoopLayout = VK_TRUE; + Vulkan::AddPointerToChain(&device_info, &attachment_feedback_loop_feature); + } if (m_optional_extensions.vk_ext_swapchain_maintenance1) { swapchain_maintenance1_feature.swapchainMaintenance1 = VK_TRUE; @@ -706,6 +715,8 @@ bool GSDeviceVK::ProcessDeviceExtensions() VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT}; VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, nullptr, VK_TRUE}; + VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachment_feedback_loop_feature = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT}; // add in optional feature structs if (m_optional_extensions.vk_ext_provoking_vertex) @@ -714,6 +725,8 @@ bool GSDeviceVK::ProcessDeviceExtensions() Vulkan::AddPointerToChain(&features2, &line_rasterization_feature); if (m_optional_extensions.vk_ext_rasterization_order_attachment_access) Vulkan::AddPointerToChain(&features2, &rasterization_order_access_feature); + if (m_optional_extensions.vk_ext_attachment_feedback_loop_layout) + Vulkan::AddPointerToChain(&features2, &attachment_feedback_loop_feature); if (m_optional_extensions.vk_ext_swapchain_maintenance1) Vulkan::AddPointerToChain(&features2, &swapchain_maintenance1_feature); @@ -724,6 +737,8 @@ bool GSDeviceVK::ProcessDeviceExtensions() m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE); m_optional_extensions.vk_ext_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE); + m_optional_extensions.vk_ext_attachment_feedback_loop_layout &= + (attachment_feedback_loop_feature.attachmentFeedbackLoopLayout == VK_TRUE); VkPhysicalDeviceProperties2 properties2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; @@ -810,6 +825,8 @@ bool GSDeviceVK::ProcessDeviceExtensions() m_optional_extensions.vk_ext_full_screen_exclusive ? "supported" : "NOT supported"); Console.WriteLn("VK_KHR_driver_properties is %s", m_optional_extensions.vk_khr_driver_properties ? "supported" : "NOT supported"); + Console.WriteLn("VK_EXT_attachment_feedback_loop_layout is %s", + m_optional_extensions.vk_ext_attachment_feedback_loop_layout ? "supported" : "NOT supported"); return true; } @@ -1506,7 +1523,10 @@ VkRenderPass GSDeviceVK::CreateCachedRenderPass(RenderPassCacheKey key) u32 num_attachments = 0; if (key.color_format != VK_FORMAT_UNDEFINED) { - const VkImageLayout layout = key.color_feedback_loop ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + const VkImageLayout layout = + key.color_feedback_loop ? (UseFeedbackLoopLayout() ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : + VK_IMAGE_LAYOUT_GENERAL) : + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments[num_attachments] = {0, static_cast(key.color_format), VK_SAMPLE_COUNT_1_BIT, static_cast(key.color_load_op), static_cast(key.color_store_op), VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, layout, layout}; @@ -1516,9 +1536,12 @@ VkRenderPass GSDeviceVK::CreateCachedRenderPass(RenderPassCacheKey key) if (key.color_feedback_loop) { - input_reference.attachment = num_attachments; - input_reference.layout = layout; - input_reference_ptr = &input_reference; + if (!UseFeedbackLoopLayout()) + { + input_reference.attachment = num_attachments; + input_reference.layout = layout; + input_reference_ptr = &input_reference; + } if (!m_features.framebuffer_fetch) { @@ -1527,9 +1550,13 @@ VkRenderPass GSDeviceVK::CreateCachedRenderPass(RenderPassCacheKey key) subpass_dependency.dstSubpass = 0; subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - subpass_dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - subpass_dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + subpass_dependency.srcAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + subpass_dependency.dstAccessMask = + UseFeedbackLoopLayout() ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + subpass_dependency.dependencyFlags = + UseFeedbackLoopLayout() ? (VK_DEPENDENCY_BY_REGION_BIT | VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT) : + VK_DEPENDENCY_BY_REGION_BIT; subpass_dependency_ptr = &subpass_dependency; } } @@ -1538,7 +1565,10 @@ VkRenderPass GSDeviceVK::CreateCachedRenderPass(RenderPassCacheKey key) } if (key.depth_format != VK_FORMAT_UNDEFINED) { - const VkImageLayout layout = key.depth_sampling ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + const VkImageLayout layout = + key.depth_sampling ? (UseFeedbackLoopLayout() ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : + VK_IMAGE_LAYOUT_GENERAL) : + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachments[num_attachments] = {0, static_cast(key.depth_format), VK_SAMPLE_COUNT_1_BIT, static_cast(key.depth_load_op), static_cast(key.depth_store_op), static_cast(key.stencil_load_op), @@ -3586,6 +3616,8 @@ static void AddShaderHeader(std::stringstream& ss) if (!features.texture_barrier) ss << "#define DISABLE_TEXTURE_BARRIER 1\n"; + if (features.texture_barrier && dev->UseFeedbackLoopLayout()) + ss << "#define HAS_FEEDBACK_LOOP_LAYOUT 1\n"; } static void AddShaderStageMacro(std::stringstream& ss, bool vs, bool gs, bool fs) @@ -3740,7 +3772,8 @@ bool GSDeviceVK::CreatePipelineLayouts() dslb.AddBinding(TFX_TEXTURE_TEXTURE, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); dslb.AddBinding(TFX_TEXTURE_PALETTE, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT); dslb.AddBinding(TFX_TEXTURE_RT, - m_features.texture_barrier ? VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + (m_features.texture_barrier && !UseFeedbackLoopLayout()) ? VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT); dslb.AddBinding(TFX_TEXTURE_PRIMID, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT); if ((m_tfx_texture_ds_layout = dslb.Create(dev)) == VK_NULL_HANDLE) @@ -5372,7 +5405,7 @@ bool GSDeviceVK::ApplyTFXState(bool already_execed) } if (flags & DIRTY_FLAG_TFX_TEXTURE_RT) { - if (m_features.texture_barrier) + if (m_features.texture_barrier && !UseFeedbackLoopLayout()) { dsub.AddInputAttachmentDescriptorWrite( VK_NULL_HANDLE, TFX_TEXTURE_RT, m_tfx_textures[TFX_TEXTURE_RT]->GetView(), VK_IMAGE_LAYOUT_GENERAL); @@ -5923,12 +5956,21 @@ void GSDeviceVK::UploadHWDrawVerticesAndIndices(const GSHWDrawConfig& config) VkImageMemoryBarrier GSDeviceVK::GetColorBufferBarrier(GSTextureVK* rt) const { + const VkImageLayout layout = + UseFeedbackLoopLayout() ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : VK_IMAGE_LAYOUT_GENERAL; + const VkAccessFlags dst_access = + UseFeedbackLoopLayout() ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; return {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, nullptr, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dst_access, layout, layout, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, rt->GetImage(), {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}}; } +VkDependencyFlags GSDeviceVK::GetColorBufferBarrierFlags() const +{ + return UseFeedbackLoopLayout() ? (VK_DEPENDENCY_BY_REGION_BIT | VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT) : + VK_DEPENDENCY_BY_REGION_BIT; +} + void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, bool one_barrier, bool full_barrier, bool skip_first_barrier) { @@ -5942,7 +5984,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, if ((one_barrier || full_barrier) && !m_pipeline_selector.ps.IsFeedbackLoop()) [[unlikely]] Console.Warning("GS: Possible unnecessary barrier detected."); #endif - + const VkDependencyFlags barrier_flags = GetColorBufferBarrierFlags(); if (full_barrier) { const VkImageMemoryBarrier barrier = GetColorBufferBarrier(draw_rt); @@ -5971,7 +6013,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, for (; n < draw_list_size; n++) { vkCmdPipelineBarrier(GetCurrentCommandBuffer(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier_flags, 0, nullptr, 0, nullptr, 1, &barrier); const u32 count = (*config.drawlist)[n] * indices_per_prim; DrawIndexedPrimitive(p, count); @@ -5994,7 +6036,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, for (; p < config.nindices; p += indices_per_prim) { vkCmdPipelineBarrier(GetCurrentCommandBuffer(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier_flags, 0, nullptr, 0, nullptr, 1, &barrier); DrawIndexedPrimitive(p, indices_per_prim); } @@ -6009,7 +6051,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, const VkImageMemoryBarrier barrier = GetColorBufferBarrier(draw_rt); vkCmdPipelineBarrier(GetCurrentCommandBuffer(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier_flags, 0, nullptr, 0, nullptr, 1, &barrier); } DrawIndexedPrimitive(); diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h index 60377ff079..b1aeb3a82c 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h @@ -44,6 +44,7 @@ public: bool vk_ext_swapchain_maintenance1 : 1; bool vk_khr_driver_properties : 1; bool vk_khr_shader_non_semantic_info : 1; + bool vk_ext_attachment_feedback_loop_layout : 1; }; // Global state accessors @@ -56,6 +57,13 @@ public: __fi const VkPhysicalDeviceProperties& GetDeviceProperties() const { return m_device_properties; } __fi const OptionalExtensions& GetOptionalExtensions() const { return m_optional_extensions; } + // The interaction between raster order attachment access and fbfetch is unclear. + __fi bool UseFeedbackLoopLayout() const + { + return (m_optional_extensions.vk_ext_attachment_feedback_loop_layout && + !m_optional_extensions.vk_ext_rasterization_order_attachment_access); + } + // Helpers for getting constants __fi u32 GetBufferCopyOffsetAlignment() const { @@ -563,6 +571,7 @@ public: void UpdateHWPipelineSelector(GSHWDrawConfig& config, PipelineSelector& pipe); void UploadHWDrawVerticesAndIndices(const GSHWDrawConfig& config); VkImageMemoryBarrier GetColorBufferBarrier(GSTextureVK* rt) const; + VkDependencyFlags GetColorBufferBarrierFlags() const; void SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt, bool one_barrier, bool full_barrier, bool skip_first_barrier); diff --git a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp index 533fb563b1..7a01fb673c 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSTextureVK.cpp @@ -32,7 +32,15 @@ static VkImageLayout GetVkImageLayout(GSTextureVK::Layout layout) VK_IMAGE_LAYOUT_GENERAL, // ComputeReadWriteImage VK_IMAGE_LAYOUT_GENERAL, // General }}; - return s_vk_layout_mapping[static_cast(layout)]; + return (layout == GSTextureVK::Layout::FeedbackLoop && GSDeviceVK::GetInstance()->UseFeedbackLoopLayout()) ? + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : + s_vk_layout_mapping[static_cast(layout)]; +} + +static VkAccessFlagBits GetFeedbackLoopInputAccessBits() +{ + return GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_ACCESS_SHADER_READ_BIT : + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; } GSTextureVK::GSTextureVK(Type type, Format format, int width, int height, int levels, VkImage image, @@ -91,16 +99,22 @@ std::unique_ptr GSTextureVK::Create(Type type, Format format, int w case Type::RenderTarget: { pxAssert(levels == 1); - ici.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + ici.usage = + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + (GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT : + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); } break; case Type::DepthStencil: { pxAssert(levels == 1); - ici.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + ici.usage = + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + (GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT : + 0); vci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; } break; @@ -626,7 +640,7 @@ void GSTextureVK::TransitionSubresourcesToLayout( case Layout::FeedbackLoop: barrier.srcAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ? (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) : + GetFeedbackLoopInputAccessBits()) : (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT); srcStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ? @@ -702,7 +716,7 @@ void GSTextureVK::TransitionSubresourcesToLayout( case Layout::FeedbackLoop: barrier.dstAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ? (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) : + GetFeedbackLoopInputAccessBits()) : (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT); dstStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ? diff --git a/pcsx2/ShaderCacheVersion.h b/pcsx2/ShaderCacheVersion.h index 1931a92ee6..ae9254c108 100644 --- a/pcsx2/ShaderCacheVersion.h +++ b/pcsx2/ShaderCacheVersion.h @@ -3,4 +3,4 @@ /// Version number for GS and other shaders. Increment whenever any of the contents of the /// shaders change, to invalidate the cache. -static constexpr u32 SHADER_CACHE_VERSION = 53; +static constexpr u32 SHADER_CACHE_VERSION = 54;