diff --git a/src/video_core/renderer_vulkan/present/frame_gen.cpp b/src/video_core/renderer_vulkan/present/frame_gen.cpp index dc57ad8428..186562a6e7 100644 --- a/src/video_core/renderer_vulkan/present/frame_gen.cpp +++ b/src/video_core/renderer_vulkan/present/frame_gen.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include +#include #include #include @@ -223,14 +224,15 @@ void FrameGen::Process(const Device& device, VkImageView source, VkExtent2D exte } const f32 flow_scale = ConfiguredFlowScale(); + const size_t generations = Settings::FrameGenMaxGenerations(); if (!chain || built_extent.width != extent.width || built_extent.height != extent.height || - built_flow_scale != flow_scale) { - Rebuild(device, extent, flow_scale); + built_flow_scale != flow_scale || built_generations != generations) { + Rebuild(device, extent, flow_scale, generations); } const u64 count = frame_count++; last_count = count; - last_generations = plan.generations; + last_generations = (std::min)(plan.generations, built_generations); const size_t input_slot = count % INPUT_SLOTS; const bool warm = plan.warm && count + 1 >= LSFG_REQUIRED_FRAMES && @@ -304,7 +306,8 @@ void FrameGen::CreateInputPass(const Device& device) { input_sampler = CreateNearestNeighborSampler(device); } -void FrameGen::Rebuild(const Device& device, VkExtent2D extent, f32 flow_scale) { +void FrameGen::Rebuild(const Device& device, VkExtent2D extent, f32 flow_scale, + size_t generations) { scheduler.Finish(); chain.reset(); @@ -312,10 +315,12 @@ void FrameGen::Rebuild(const Device& device, VkExtent2D extent, f32 flow_scale) chain.emplace(device, memory_allocator, *shaders, extent, LSFG_DEFAULT_FORMAT, built_flow_scale); - for (LsfgImage& output : outputs) { + outputs = {}; + for (LsfgImage& output : std::span{outputs}.first(generations)) { output = LsfgImage(device, memory_allocator, extent, LSFG_DEFAULT_FORMAT); } built_extent = extent; + built_generations = generations; frame_count = 0; warm_streak = 0; generated = false; diff --git a/src/video_core/renderer_vulkan/present/frame_gen.h b/src/video_core/renderer_vulkan/present/frame_gen.h index 6b03db3f25..51cc142277 100644 --- a/src/video_core/renderer_vulkan/present/frame_gen.h +++ b/src/video_core/renderer_vulkan/present/frame_gen.h @@ -36,7 +36,7 @@ private: static constexpr size_t INPUT_SLOTS = 4; void CreateInputPass(const Device& device); - void Rebuild(const Device& device, VkExtent2D extent, f32 flow_scale); + void Rebuild(const Device& device, VkExtent2D extent, f32 flow_scale, size_t generations); void DumpDebugImages(u64 count); MemoryAllocator& memory_allocator; @@ -58,6 +58,7 @@ private: FrameGenPlan plan{}; VkExtent2D built_extent{}; f32 built_flow_scale{}; + size_t built_generations{}; u64 frame_count{}; u64 last_count{}; size_t last_generations{}; diff --git a/src/video_core/renderer_vulkan/present/fsr.cpp b/src/video_core/renderer_vulkan/present/fsr.cpp index a5833710b6..bb3138e7e6 100644 --- a/src/video_core/renderer_vulkan/present/fsr.cpp +++ b/src/video_core/renderer_vulkan/present/fsr.cpp @@ -41,12 +41,9 @@ FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_c } void FSR::CreateImages(const Device& device) { - m_dynamic_images.resize(m_image_count); - for (auto& images : m_dynamic_images) { - images.images[Easu] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.images[Rcas] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_views[Easu] = CreateWrappedImageView(device, images.images[Easu], VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_views[Rcas] = CreateWrappedImageView(device, images.images[Rcas], VK_FORMAT_R16G16B16A16_SFLOAT); + for (size_t stage = 0; stage < MaxFsrStage; ++stage) { + m_images[stage] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + m_image_views[stage] = CreateWrappedImageView(device, m_images[stage], VK_FORMAT_R16G16B16A16_SFLOAT); } } @@ -79,8 +76,8 @@ void FSR::CreateDescriptorSetLayout(const Device& device) { void FSR::CreateDescriptorSets(const Device& device) { std::vector layouts(MaxFsrStage, *m_descriptor_set_layout); - for (auto& images : m_dynamic_images) - images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts); + for (size_t i = 0; i < m_image_count; ++i) + m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, layouts)); } void FSR::CreatePipelineLayouts(const Device& device) { @@ -112,12 +109,12 @@ void FSR::CreatePipelines(const Device& device) { } void FSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) { - Images& images = m_dynamic_images[image_index]; + const vk::DescriptorSets& descriptor_sets = m_descriptor_sets[image_index]; std::vector image_infos; image_infos.reserve(2); std::vector updates{ - CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[Easu], 0), - CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], images.descriptor_sets[Rcas], 0) + CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, descriptor_sets[Easu], 0), + CreateWriteDescriptorSet(image_infos, *m_sampler, *m_image_views[Easu], descriptor_sets[Rcas], 0) }; device.GetLogical().UpdateDescriptorSets(updates, {}); } @@ -125,14 +122,14 @@ void FSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, siz VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image, VkImageView source_image_view, VkExtent2D input_image_extent, const Common::Rectangle& crop_rect) { - Images& images = m_dynamic_images[image_index]; + const vk::DescriptorSets& descriptor_sets = m_descriptor_sets[image_index]; - VkImage easu_image = *images.images[Easu]; - VkImage rcas_image = *images.images[Rcas]; - VkDescriptorSet easu_descriptor_set = images.descriptor_sets[Easu]; - VkDescriptorSet rcas_descriptor_set = images.descriptor_sets[Rcas]; - VkImageView easu_view = *images.image_views[Easu]; - VkImageView rcas_view = *images.image_views[Rcas]; + VkImage easu_image = *m_images[Easu]; + VkImage rcas_image = *m_images[Rcas]; + VkDescriptorSet easu_descriptor_set = descriptor_sets[Easu]; + VkDescriptorSet rcas_descriptor_set = descriptor_sets[Rcas]; + VkImageView easu_view = *m_image_views[Easu]; + VkImageView rcas_view = *m_image_views[Rcas]; VkPipeline easu_pipeline = *m_easu_pipeline; VkPipeline rcas_pipeline = *m_rcas_pipeline; VkPipelineLayout pipeline_layout = *m_pipeline_layout; @@ -187,7 +184,7 @@ VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_i TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL); }); - return *images.image_views[Rcas]; + return rcas_view; } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/fsr.h b/src/video_core/renderer_vulkan/present/fsr.h index 1cdab4a81e..373a985339 100644 --- a/src/video_core/renderer_vulkan/present/fsr.h +++ b/src/video_core/renderer_vulkan/present/fsr.h @@ -54,12 +54,9 @@ private: vk::Pipeline m_rcas_pipeline; vk::Sampler m_sampler; - struct Images { - vk::DescriptorSets descriptor_sets; - std::array images; - std::array image_views; - }; - std::vector m_dynamic_images; + std::array m_images; + std::array m_image_views; + std::vector m_descriptor_sets; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/fxaa.cpp b/src/video_core/renderer_vulkan/present/fxaa.cpp index 8e7b964a5e..6eb07b004f 100644 --- a/src/video_core/renderer_vulkan/present/fxaa.cpp +++ b/src/video_core/renderer_vulkan/present/fxaa.cpp @@ -33,11 +33,8 @@ FXAA::FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count, FXAA::~FXAA() = default; void FXAA::CreateImages(const Device& device, MemoryAllocator& allocator) { - for (u32 i = 0; i < m_image_count; i++) { - Image& image = m_dynamic_images.emplace_back(); - image.image = CreateWrappedImage(allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - image.image_view = CreateWrappedImageView(device, image.image, VK_FORMAT_R16G16B16A16_SFLOAT); - } + m_image = CreateWrappedImage(allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + m_image_view = CreateWrappedImageView(device, m_image, VK_FORMAT_R16G16B16A16_SFLOAT); } void FXAA::CreateSampler(const Device& device) { @@ -63,8 +60,8 @@ void FXAA::CreateDescriptorSetLayouts(const Device& device) { void FXAA::CreateDescriptorSets(const Device& device) { VkDescriptorSetLayout layout = *m_descriptor_set_layout; - for (auto& images : m_dynamic_images) { - images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, {layout}); + for (u32 i = 0; i < m_image_count; i++) { + m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, {layout})); } } @@ -78,23 +75,22 @@ void FXAA::CreatePipelines(const Device& device) { } void FXAA::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) { - Image& image = m_dynamic_images[image_index]; + const VkDescriptorSet descriptor_set = m_descriptor_sets[image_index][0]; std::vector image_infos; std::vector updates; image_infos.reserve(2); - updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 0)); - updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 1)); + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, descriptor_set, 0)); + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, descriptor_set, 1)); device.GetLogical().UpdateDescriptorSets(updates, {}); } void FXAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) { - const Image& image{m_dynamic_images[image_index]}; const VkImage input_image{*inout_image}; - const VkImage output_image{*image.image}; - const VkImageView output_view{*image.image_view}; - const VkDescriptorSet descriptor_set{image.descriptor_sets[0]}; + const VkImage output_image{*m_image}; + const VkImageView output_view{*m_image_view}; + const VkDescriptorSet descriptor_set{m_descriptor_sets[image_index][0]}; const VkPipeline pipeline{*m_pipeline}; const VkPipelineLayout layout{*m_pipeline_layout}; const VkExtent2D extent{m_extent}; @@ -114,8 +110,8 @@ void FXAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); }); - *inout_image = *image.image; - *inout_image_view = *image.image_view; + *inout_image = output_image; + *inout_image_view = output_view; } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/fxaa.h b/src/video_core/renderer_vulkan/present/fxaa.h index 8acd0bce36..7f5599db16 100644 --- a/src/video_core/renderer_vulkan/present/fxaa.h +++ b/src/video_core/renderer_vulkan/present/fxaa.h @@ -34,12 +34,9 @@ private: void CreatePipelines(const Device& device); void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index); - struct Image { - vk::DescriptorSets descriptor_sets{}; - vk::Image image{}; - vk::ImageView image_view{}; - }; - std::vector m_dynamic_images{}; + vk::Image m_image{}; + vk::ImageView m_image_view{}; + std::vector m_descriptor_sets{}; const VkExtent2D m_extent; const u32 m_image_count; vk::ShaderModule m_vertex_shader{}; diff --git a/src/video_core/renderer_vulkan/present/lsfg_chain.cpp b/src/video_core/renderer_vulkan/present/lsfg_chain.cpp index c9fce12758..a7ecfc5d71 100644 --- a/src/video_core/renderer_vulkan/present/lsfg_chain.cpp +++ b/src/video_core/renderer_vulkan/present/lsfg_chain.cpp @@ -18,6 +18,34 @@ constexpr u32 FIXED_DESCRIPTOR_SETS = 64; constexpr u32 DESCRIPTOR_SETS_PER_SLOT = 100; constexpr size_t FIRST_DELTA_LEVEL = 4; +[[nodiscard]] constexpr size_t DeltaStartWave(size_t index) { + if (index == 0) { + return 0; + } + return (FIRST_DELTA_LEVEL + index) * LSFG_GAMMA_STAGES; +} + +constexpr size_t GENERATION_WAVES = + DeltaStartWave(LSFG_DELTA_INSTANCES - 1) + LSFG_DELTA_STAGES; + +template +void ForEachWaveStage(std::array& gamma, + std::array& delta, size_t wave, + Func&& func) { + for (size_t i = 0; i < gamma.size(); ++i) { + const size_t start = i * LSFG_GAMMA_STAGES; + if (wave >= start && wave - start < LSFG_GAMMA_STAGES) { + func(gamma[i], wave - start); + } + } + for (size_t i = 0; i < delta.size(); ++i) { + const size_t start = DeltaStartWave(i); + if (wave >= start && wave - start < LSFG_DELTA_STAGES) { + func(delta[i], wave - start); + } + } +} + } // Anonymous namespace LsfgChain::LsfgChain(const Device& device, MemoryAllocator& memory_allocator, @@ -91,11 +119,15 @@ void LsfgChain::DispatchGeneration(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation_count, size_t generation, VkImage image, VkExtent2D extent) { const size_t slot = LsfgGenerationSlot(generation_count, generation); - for (size_t i = 0; i < LSFG_MIP_LEVELS; ++i) { - gamma[i].Dispatch(cmdbuf, frame_count, slot); - if (i >= FIRST_DELTA_LEVEL) { - delta[i - FIRST_DELTA_LEVEL].Dispatch(cmdbuf, frame_count, slot); - } + for (size_t wave = 0; wave < GENERATION_WAVES; ++wave) { + LsfgBarriers barriers(cmdbuf); + ForEachWaveStage(gamma, delta, wave, [&barriers, frame_count](auto& pass, size_t stage) { + pass.PushBarriers(barriers, frame_count, stage); + }); + barriers.Build(); + ForEachWaveStage(gamma, delta, wave, [cmdbuf, frame_count, slot](auto& pass, size_t stage) { + pass.DispatchStage(cmdbuf, frame_count, slot, stage); + }); } generate.Dispatch(cmdbuf, frame_count, slot, image, extent); } diff --git a/src/video_core/renderer_vulkan/present/lsfg_delta.cpp b/src/video_core/renderer_vulkan/present/lsfg_delta.cpp index dc6eec383f..9ced1f5a47 100644 --- a/src/video_core/renderer_vulkan/present/lsfg_delta.cpp +++ b/src/video_core/renderer_vulkan/present/lsfg_delta.cpp @@ -196,88 +196,68 @@ LsfgDelta::LsfgDelta(const Device& device, MemoryAllocator& memory_allocator, } } -void LsfgDelta::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot) { +void LsfgDelta::PushBarriers(LsfgBarriers& barriers, u64 frame_count, size_t stage) { + auto& history = (*inputs)[frame_count % LSFG_HISTORY_SLOTS]; + auto& previous_history = (*inputs)[(frame_count + 2) % LSFG_HISTORY_SLOTS]; + switch (stage) { + case 0: + barriers.WriteToReadAll(previous_history) + .WriteToReadAll(history) + .WriteToRead(previous_gamma) + .ReadToWriteAll(temp1); + break; + case 1: + case 3: + barriers.WriteToReadAll(temp1).ReadToWriteAll(temp2); + break; + case 2: + barriers.WriteToReadAll(temp2).ReadToWriteAll(temp1); + break; + case 4: + barriers.WriteToReadAll(temp2) + .WriteToRead(previous_gamma) + .WriteToRead(*flow_input) + .ReadToWrite(out_image1); + break; + case 5: + barriers.WriteToReadAll(previous_history) + .WriteToReadAll(history) + .WriteToRead(previous_gamma) + .WriteToRead(previous1) + .ReadToWriteAll(temp2); + break; + case 6: + case 8: + barriers.WriteToReadAll(temp2).ReadToWrite(temp1[0]).ReadToWrite(temp1[1]); + break; + case 7: + barriers.WriteToRead(temp1[0]).WriteToRead(temp1[1]).ReadToWriteAll(temp2); + break; + default: + barriers.WriteToRead(temp1[0]) + .WriteToRead(temp1[1]) + .WriteToRead(previous2) + .ReadToWrite(out_image2); + break; + } +} + +void LsfgDelta::DispatchStage(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, + size_t stage) const { const Generation& pass = generations[slot]; + const size_t history = frame_count % LSFG_HISTORY_SLOTS; + VkDescriptorSet set = pass.first_descriptor_sets[history]; + if (stage == 5) { + set = pass.sixth_descriptor_sets[history]; + } else if (stage > 5) { + set = pass.descriptor_sets[stage - 2]; + } else if (stage != 0) { + set = pass.descriptor_sets[stage - 1]; + } + passes[stage].Bind(cmdbuf, set); const VkExtent2D extent = temp1[0].Extent(); - const u32 groups_x = GroupCount(extent.width); - const u32 groups_y = GroupCount(extent.height); - - const size_t history = frame_count % LSFG_HISTORY_SLOTS; - const size_t previous_history = (frame_count + 2) % LSFG_HISTORY_SLOTS; - - LsfgBarriers(cmdbuf) - .WriteToReadAll((*inputs)[previous_history]) - .WriteToReadAll((*inputs)[history]) - .WriteToRead(previous_gamma) - .ReadToWriteAll(temp1) - .Build(); - passes[0].Bind(cmdbuf, pass.first_descriptor_sets[history]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf).WriteToReadAll(temp1).ReadToWriteAll(temp2).Build(); - passes[1].Bind(cmdbuf, pass.descriptor_sets[0]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf).WriteToReadAll(temp2).ReadToWriteAll(temp1).Build(); - passes[2].Bind(cmdbuf, pass.descriptor_sets[1]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf).WriteToReadAll(temp1).ReadToWriteAll(temp2).Build(); - passes[3].Bind(cmdbuf, pass.descriptor_sets[2]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll(temp2) - .WriteToRead(previous_gamma) - .WriteToRead(*flow_input) - .ReadToWrite(out_image1) - .Build(); - passes[4].Bind(cmdbuf, pass.descriptor_sets[3]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll((*inputs)[previous_history]) - .WriteToReadAll((*inputs)[history]) - .WriteToRead(previous_gamma) - .WriteToRead(previous1) - .ReadToWriteAll(temp2) - .Build(); - passes[5].Bind(cmdbuf, pass.sixth_descriptor_sets[history]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll(temp2) - .ReadToWrite(temp1[0]) - .ReadToWrite(temp1[1]) - .Build(); - passes[6].Bind(cmdbuf, pass.descriptor_sets[4]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToRead(temp1[0]) - .WriteToRead(temp1[1]) - .ReadToWriteAll(temp2) - .Build(); - passes[7].Bind(cmdbuf, pass.descriptor_sets[5]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll(temp2) - .ReadToWrite(temp1[0]) - .ReadToWrite(temp1[1]) - .Build(); - passes[8].Bind(cmdbuf, pass.descriptor_sets[6]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToRead(temp1[0]) - .WriteToRead(temp1[1]) - .WriteToRead(previous2) - .ReadToWrite(out_image2) - .Build(); - passes[9].Bind(cmdbuf, pass.descriptor_sets[7]); - cmdbuf.Dispatch(groups_x, groups_y, 1); + cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1); } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/lsfg_delta.h b/src/video_core/renderer_vulkan/present/lsfg_delta.h index 1bbcfe6745..a3beda0b77 100644 --- a/src/video_core/renderer_vulkan/present/lsfg_delta.h +++ b/src/video_core/renderer_vulkan/present/lsfg_delta.h @@ -27,7 +27,9 @@ public: LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous_gamma, LsfgImage* previous1, LsfgImage* previous2); - void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot); + void PushBarriers(LsfgBarriers& barriers, u64 frame_count, size_t stage); + + void DispatchStage(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, size_t stage) const; [[nodiscard]] LsfgImage& Output1() { return out_image1; diff --git a/src/video_core/renderer_vulkan/present/lsfg_gamma.cpp b/src/video_core/renderer_vulkan/present/lsfg_gamma.cpp index 067d124b6f..fff0b57d0e 100644 --- a/src/video_core/renderer_vulkan/present/lsfg_gamma.cpp +++ b/src/video_core/renderer_vulkan/present/lsfg_gamma.cpp @@ -133,53 +133,43 @@ LsfgGamma::LsfgGamma(const Device& device, MemoryAllocator& memory_allocator, } } -void LsfgGamma::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot) { +void LsfgGamma::PushBarriers(LsfgBarriers& barriers, u64 frame_count, size_t stage) { + switch (stage) { + case 0: + barriers.WriteToReadAll((*inputs)[(frame_count + 2) % LSFG_HISTORY_SLOTS]) + .WriteToReadAll((*inputs)[frame_count % LSFG_HISTORY_SLOTS]) + .WriteToRead(previous) + .ReadToWriteAll(temp1); + break; + case 1: + barriers.WriteToReadAll(temp1).ReadToWriteAll(temp2); + break; + case 2: + barriers.WriteToReadAll(temp2).ReadToWrite(temp1[0]).ReadToWrite(temp1[1]); + break; + case 3: + barriers.WriteToRead(temp1[0]).WriteToRead(temp1[1]).ReadToWriteAll(temp2); + break; + default: + barriers.WriteToReadAll(temp2) + .WriteToRead(previous) + .WriteToRead(*flow_input) + .ReadToWrite(out_image); + break; + } +} + +void LsfgGamma::DispatchStage(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, + size_t stage) const { const Generation& pass = generations[slot]; + VkDescriptorSet set = pass.first_descriptor_sets[frame_count % LSFG_HISTORY_SLOTS]; + if (stage != 0) { + set = pass.descriptor_sets[stage - 1]; + } + passes[stage].Bind(cmdbuf, set); const VkExtent2D extent = temp1[0].Extent(); - const u32 groups_x = GroupCount(extent.width); - const u32 groups_y = GroupCount(extent.height); - - const size_t history = frame_count % LSFG_HISTORY_SLOTS; - const size_t previous_history = (frame_count + 2) % LSFG_HISTORY_SLOTS; - - LsfgBarriers(cmdbuf) - .WriteToReadAll((*inputs)[previous_history]) - .WriteToReadAll((*inputs)[history]) - .WriteToRead(previous) - .ReadToWriteAll(temp1) - .Build(); - passes[0].Bind(cmdbuf, pass.first_descriptor_sets[history]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf).WriteToReadAll(temp1).ReadToWriteAll(temp2).Build(); - passes[1].Bind(cmdbuf, pass.descriptor_sets[0]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll(temp2) - .ReadToWrite(temp1[0]) - .ReadToWrite(temp1[1]) - .Build(); - passes[2].Bind(cmdbuf, pass.descriptor_sets[1]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToRead(temp1[0]) - .WriteToRead(temp1[1]) - .ReadToWriteAll(temp2) - .Build(); - passes[3].Bind(cmdbuf, pass.descriptor_sets[2]); - cmdbuf.Dispatch(groups_x, groups_y, 1); - - LsfgBarriers(cmdbuf) - .WriteToReadAll(temp2) - .WriteToRead(previous) - .WriteToRead(*flow_input) - .ReadToWrite(out_image) - .Build(); - passes[4].Bind(cmdbuf, pass.descriptor_sets[3]); - cmdbuf.Dispatch(groups_x, groups_y, 1); + cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1); } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/lsfg_gamma.h b/src/video_core/renderer_vulkan/present/lsfg_gamma.h index 848c380bfe..cda230d449 100644 --- a/src/video_core/renderer_vulkan/present/lsfg_gamma.h +++ b/src/video_core/renderer_vulkan/present/lsfg_gamma.h @@ -26,7 +26,9 @@ public: LsfgResources& resources, vk::DescriptorPool& descriptor_pool, LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous); - void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot); + void PushBarriers(LsfgBarriers& barriers, u64 frame_count, size_t stage); + + void DispatchStage(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, size_t stage) const; [[nodiscard]] LsfgImage& Output() { return out_image; diff --git a/src/video_core/renderer_vulkan/present/sgsr.cpp b/src/video_core/renderer_vulkan/present/sgsr.cpp index 7a7446ce33..1787b43e80 100644 --- a/src/video_core/renderer_vulkan/present/sgsr.cpp +++ b/src/video_core/renderer_vulkan/present/sgsr.cpp @@ -27,12 +27,8 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image , m_extent{extent} , m_edge_dir{edge_dir} { - // Not finished yet initializing at ctor time? - m_dynamic_images.resize(m_image_count); - for (auto& images : m_dynamic_images) { - images.image = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_view = CreateWrappedImageView(device, images.image, VK_FORMAT_R16G16B16A16_SFLOAT); - } + m_image = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + m_image_view = CreateWrappedImageView(device, m_image, VK_FORMAT_R16G16B16A16_SFLOAT); m_sampler = CreateBilinearSampler(device); m_vert_shader = BuildShader(device, SGSR1_SHADER_VERT_SPV); @@ -44,8 +40,8 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER}); VkDescriptorSetLayout layout = *m_descriptor_set_layout; - for (auto& images : m_dynamic_images) - images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layout); + for (size_t i = 0; i < m_image_count; ++i) + m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, layout)); const VkPushConstantRange range{ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, @@ -68,19 +64,17 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image } void SGSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) { - Images& images = m_dynamic_images[image_index]; std::vector image_infos; std::vector updates; image_infos.reserve(1); - updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[0], 0)); + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, m_descriptor_sets[image_index][0], 0)); device.GetLogical().UpdateDescriptorSets(updates, {}); } VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image, VkImageView source_image_view, VkExtent2D input_image_extent, const Common::Rectangle& crop_rect) { - Images& images = m_dynamic_images[image_index]; - auto const output_image = *images.image; - auto const output_view = *images.image_view; - auto const descriptor_set = images.descriptor_sets[0]; + auto const output_image = *m_image; + auto const output_view = *m_image_view; + auto const descriptor_set = m_descriptor_sets[image_index][0]; auto const pipeline = *m_stage_pipeline; VkPipelineLayout layout = *m_pipeline_layout; @@ -126,7 +120,7 @@ VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_ cmdbuf.EndRendering(); TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); }); - return *images.image_view; + return output_view; } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/sgsr.h b/src/video_core/renderer_vulkan/present/sgsr.h index d626bbe1ba..52a645b09f 100644 --- a/src/video_core/renderer_vulkan/present/sgsr.h +++ b/src/video_core/renderer_vulkan/present/sgsr.h @@ -33,12 +33,9 @@ private: vk::Pipeline m_stage_pipeline; vk::Sampler m_sampler; - struct Images { - vk::DescriptorSets descriptor_sets; - vk::Image image; - vk::ImageView image_view; - }; - std::vector m_dynamic_images; + vk::Image m_image; + vk::ImageView m_image_view; + std::vector m_descriptor_sets; bool m_edge_dir{}; }; diff --git a/src/video_core/renderer_vulkan/present/smaa.cpp b/src/video_core/renderer_vulkan/present/smaa.cpp index 0527adf73b..e4258d4b5c 100644 --- a/src/video_core/renderer_vulkan/present/smaa.cpp +++ b/src/video_core/renderer_vulkan/present/smaa.cpp @@ -55,22 +55,18 @@ void SMAA::CreateImages(const Device& device) { m_static_image_views[Search] = CreateWrappedImageView(device, m_static_images[Search], VK_FORMAT_R8_UNORM); - for (u32 i = 0; i < m_image_count; i++) { - Images& images = m_dynamic_images.emplace_back(); + m_dynamic_images[Blend] = + CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + m_dynamic_images[Edges] = CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16_SFLOAT); + m_dynamic_images[Output] = + CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.images[Blend] = - CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.images[Edges] = CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16_SFLOAT); - images.images[Output] = - CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - - images.image_views[Blend] = - CreateWrappedImageView(device, images.images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_views[Edges] = - CreateWrappedImageView(device, images.images[Edges], VK_FORMAT_R16G16_SFLOAT); - images.image_views[Output] = - CreateWrappedImageView(device, images.images[Output], VK_FORMAT_R16G16B16A16_SFLOAT); - } + m_dynamic_image_views[Blend] = + CreateWrappedImageView(device, m_dynamic_images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT); + m_dynamic_image_views[Edges] = + CreateWrappedImageView(device, m_dynamic_images[Edges], VK_FORMAT_R16G16_SFLOAT); + m_dynamic_image_views[Output] = + CreateWrappedImageView(device, m_dynamic_images[Output], VK_FORMAT_R16G16B16A16_SFLOAT); } void SMAA::CreateSampler(const Device& device) { @@ -122,8 +118,8 @@ void SMAA::CreateDescriptorSets(const Device& device) { std::ranges::transform(m_descriptor_set_layouts, layouts.begin(), [](auto& layout) { return *layout; }); - for (auto& images : m_dynamic_images) { - images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts); + for (u32 i = 0; i < m_image_count; i++) { + m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, layouts)); } } @@ -147,28 +143,30 @@ void SMAA::CreatePipelines(const Device& device) { } void SMAA::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) { - Images& images = m_dynamic_images[image_index]; + const vk::DescriptorSets& descriptor_sets = m_descriptor_sets[image_index]; std::vector image_infos; std::vector updates; image_infos.reserve(6); updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, - images.descriptor_sets[EdgeDetection], 0)); + descriptor_sets[EdgeDetection], 0)); - updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Edges], - images.descriptor_sets[BlendingWeightCalculation], + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, + *m_dynamic_image_views[Edges], + descriptor_sets[BlendingWeightCalculation], 0)); updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *m_static_image_views[Area], - images.descriptor_sets[BlendingWeightCalculation], + descriptor_sets[BlendingWeightCalculation], 1)); updates.push_back( CreateWriteDescriptorSet(image_infos, *m_sampler, *m_static_image_views[Search], - images.descriptor_sets[BlendingWeightCalculation], 2)); + descriptor_sets[BlendingWeightCalculation], 2)); updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, - images.descriptor_sets[NeighborhoodBlending], 0)); - updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Blend], - images.descriptor_sets[NeighborhoodBlending], 1)); + descriptor_sets[NeighborhoodBlending], 0)); + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, + *m_dynamic_image_views[Blend], + descriptor_sets[NeighborhoodBlending], 1)); device.GetLogical().UpdateDescriptorSets(updates, {}); } @@ -190,22 +188,22 @@ void SMAA::UploadImages(const Device& device, Scheduler& scheduler) { } void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) { - Images& images = m_dynamic_images[image_index]; + const vk::DescriptorSets& descriptor_sets = m_descriptor_sets[image_index]; VkImage input_image = *inout_image; - VkImage output_image = *images.images[Output]; - VkImage edges_image = *images.images[Edges]; - VkImage blend_image = *images.images[Blend]; + VkImage output_image = *m_dynamic_images[Output]; + VkImage edges_image = *m_dynamic_images[Edges]; + VkImage blend_image = *m_dynamic_images[Blend]; - VkDescriptorSet edge_detection_descriptor_set = images.descriptor_sets[EdgeDetection]; + VkDescriptorSet edge_detection_descriptor_set = descriptor_sets[EdgeDetection]; VkDescriptorSet blending_weight_calculation_descriptor_set = - images.descriptor_sets[BlendingWeightCalculation]; + descriptor_sets[BlendingWeightCalculation]; VkDescriptorSet neighborhood_blending_descriptor_set = - images.descriptor_sets[NeighborhoodBlending]; + descriptor_sets[NeighborhoodBlending]; - VkImageView edges_view = *images.image_views[Edges]; - VkImageView blend_view = *images.image_views[Blend]; - VkImageView output_view = *images.image_views[Output]; + VkImageView edges_view = *m_dynamic_image_views[Edges]; + VkImageView blend_view = *m_dynamic_image_views[Blend]; + VkImageView output_view = *m_dynamic_image_views[Output]; UploadImages(device, scheduler); UpdateDescriptorSets(device, *inout_image_view, image_index); @@ -248,8 +246,8 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); }); - *inout_image = *images.images[Output]; - *inout_image_view = *images.image_views[Output]; + *inout_image = *m_dynamic_images[Output]; + *inout_image_view = *m_dynamic_image_views[Output]; } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/smaa.h b/src/video_core/renderer_vulkan/present/smaa.h index 54a820b7a9..f9c87c9c6a 100644 --- a/src/video_core/renderer_vulkan/present/smaa.h +++ b/src/video_core/renderer_vulkan/present/smaa.h @@ -71,12 +71,9 @@ private: std::array m_static_images{}; std::array m_static_image_views{}; - struct Images { - vk::DescriptorSets descriptor_sets{}; - std::array images{}; - std::array image_views{}; - }; - std::vector m_dynamic_images{}; + std::array m_dynamic_images{}; + std::array m_dynamic_image_views{}; + std::vector m_descriptor_sets{}; bool m_images_ready{}; vk::Sampler m_sampler{};