mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 06:18:23 +00:00
Overlap barriers on window adapt filter + lsfg dedup
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -223,14 +224,15 @@ void FrameGen::Process(const Device& device, VkImageView source, VkExtent2D exte
|
|||||||
}
|
}
|
||||||
|
|
||||||
const f32 flow_scale = ConfiguredFlowScale();
|
const f32 flow_scale = ConfiguredFlowScale();
|
||||||
|
const size_t generations = Settings::FrameGenMaxGenerations();
|
||||||
if (!chain || built_extent.width != extent.width || built_extent.height != extent.height ||
|
if (!chain || built_extent.width != extent.width || built_extent.height != extent.height ||
|
||||||
built_flow_scale != flow_scale) {
|
built_flow_scale != flow_scale || built_generations != generations) {
|
||||||
Rebuild(device, extent, flow_scale);
|
Rebuild(device, extent, flow_scale, generations);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u64 count = frame_count++;
|
const u64 count = frame_count++;
|
||||||
last_count = 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 size_t input_slot = count % INPUT_SLOTS;
|
||||||
const bool warm = plan.warm && count + 1 >= LSFG_REQUIRED_FRAMES &&
|
const bool warm = plan.warm && count + 1 >= LSFG_REQUIRED_FRAMES &&
|
||||||
@@ -304,7 +306,8 @@ void FrameGen::CreateInputPass(const Device& device) {
|
|||||||
input_sampler = CreateNearestNeighborSampler(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();
|
scheduler.Finish();
|
||||||
chain.reset();
|
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,
|
chain.emplace(device, memory_allocator, *shaders, extent, LSFG_DEFAULT_FORMAT,
|
||||||
built_flow_scale);
|
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);
|
output = LsfgImage(device, memory_allocator, extent, LSFG_DEFAULT_FORMAT);
|
||||||
}
|
}
|
||||||
built_extent = extent;
|
built_extent = extent;
|
||||||
|
built_generations = generations;
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
warm_streak = 0;
|
warm_streak = 0;
|
||||||
generated = false;
|
generated = false;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ private:
|
|||||||
static constexpr size_t INPUT_SLOTS = 4;
|
static constexpr size_t INPUT_SLOTS = 4;
|
||||||
|
|
||||||
void CreateInputPass(const Device& device);
|
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);
|
void DumpDebugImages(u64 count);
|
||||||
|
|
||||||
MemoryAllocator& memory_allocator;
|
MemoryAllocator& memory_allocator;
|
||||||
@@ -58,6 +58,7 @@ private:
|
|||||||
FrameGenPlan plan{};
|
FrameGenPlan plan{};
|
||||||
VkExtent2D built_extent{};
|
VkExtent2D built_extent{};
|
||||||
f32 built_flow_scale{};
|
f32 built_flow_scale{};
|
||||||
|
size_t built_generations{};
|
||||||
u64 frame_count{};
|
u64 frame_count{};
|
||||||
u64 last_count{};
|
u64 last_count{};
|
||||||
size_t last_generations{};
|
size_t last_generations{};
|
||||||
|
|||||||
@@ -41,12 +41,9 @@ FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FSR::CreateImages(const Device& device) {
|
void FSR::CreateImages(const Device& device) {
|
||||||
m_dynamic_images.resize(m_image_count);
|
for (size_t stage = 0; stage < MaxFsrStage; ++stage) {
|
||||||
for (auto& images : m_dynamic_images) {
|
m_images[stage] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
images.images[Easu] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
m_image_views[stage] = CreateWrappedImageView(device, m_images[stage], 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +76,8 @@ void FSR::CreateDescriptorSetLayout(const Device& device) {
|
|||||||
|
|
||||||
void FSR::CreateDescriptorSets(const Device& device) {
|
void FSR::CreateDescriptorSets(const Device& device) {
|
||||||
std::vector<VkDescriptorSetLayout> layouts(MaxFsrStage, *m_descriptor_set_layout);
|
std::vector<VkDescriptorSetLayout> layouts(MaxFsrStage, *m_descriptor_set_layout);
|
||||||
for (auto& images : m_dynamic_images)
|
for (size_t i = 0; i < m_image_count; ++i)
|
||||||
images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts);
|
m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, layouts));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSR::CreatePipelineLayouts(const Device& device) {
|
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) {
|
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<VkDescriptorImageInfo> image_infos;
|
std::vector<VkDescriptorImageInfo> image_infos;
|
||||||
image_infos.reserve(2);
|
image_infos.reserve(2);
|
||||||
std::vector<VkWriteDescriptorSet> updates{
|
std::vector<VkWriteDescriptorSet> updates{
|
||||||
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[Easu], 0),
|
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, descriptor_sets[Easu], 0),
|
||||||
CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], images.descriptor_sets[Rcas], 0)
|
CreateWriteDescriptorSet(image_infos, *m_sampler, *m_image_views[Easu], descriptor_sets[Rcas], 0)
|
||||||
};
|
};
|
||||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
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 FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image,
|
||||||
VkImageView source_image_view, VkExtent2D input_image_extent,
|
VkImageView source_image_view, VkExtent2D input_image_extent,
|
||||||
const Common::Rectangle<f32>& crop_rect) {
|
const Common::Rectangle<f32>& 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 easu_image = *m_images[Easu];
|
||||||
VkImage rcas_image = *images.images[Rcas];
|
VkImage rcas_image = *m_images[Rcas];
|
||||||
VkDescriptorSet easu_descriptor_set = images.descriptor_sets[Easu];
|
VkDescriptorSet easu_descriptor_set = descriptor_sets[Easu];
|
||||||
VkDescriptorSet rcas_descriptor_set = images.descriptor_sets[Rcas];
|
VkDescriptorSet rcas_descriptor_set = descriptor_sets[Rcas];
|
||||||
VkImageView easu_view = *images.image_views[Easu];
|
VkImageView easu_view = *m_image_views[Easu];
|
||||||
VkImageView rcas_view = *images.image_views[Rcas];
|
VkImageView rcas_view = *m_image_views[Rcas];
|
||||||
VkPipeline easu_pipeline = *m_easu_pipeline;
|
VkPipeline easu_pipeline = *m_easu_pipeline;
|
||||||
VkPipeline rcas_pipeline = *m_rcas_pipeline;
|
VkPipeline rcas_pipeline = *m_rcas_pipeline;
|
||||||
VkPipelineLayout pipeline_layout = *m_pipeline_layout;
|
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);
|
TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
return *images.image_views[Rcas];
|
return rcas_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -54,12 +54,9 @@ private:
|
|||||||
vk::Pipeline m_rcas_pipeline;
|
vk::Pipeline m_rcas_pipeline;
|
||||||
vk::Sampler m_sampler;
|
vk::Sampler m_sampler;
|
||||||
|
|
||||||
struct Images {
|
std::array<vk::Image, MaxFsrStage> m_images;
|
||||||
vk::DescriptorSets descriptor_sets;
|
std::array<vk::ImageView, MaxFsrStage> m_image_views;
|
||||||
std::array<vk::Image, MaxFsrStage> images;
|
std::vector<vk::DescriptorSets> m_descriptor_sets;
|
||||||
std::array<vk::ImageView, MaxFsrStage> image_views;
|
|
||||||
};
|
|
||||||
std::vector<Images> m_dynamic_images;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -33,11 +33,8 @@ FXAA::FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
|
|||||||
FXAA::~FXAA() = default;
|
FXAA::~FXAA() = default;
|
||||||
|
|
||||||
void FXAA::CreateImages(const Device& device, MemoryAllocator& allocator) {
|
void FXAA::CreateImages(const Device& device, MemoryAllocator& allocator) {
|
||||||
for (u32 i = 0; i < m_image_count; i++) {
|
m_image = CreateWrappedImage(allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
Image& image = m_dynamic_images.emplace_back();
|
m_image_view = CreateWrappedImageView(device, m_image, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
image.image = CreateWrappedImage(allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
|
||||||
image.image_view = CreateWrappedImageView(device, image.image, VK_FORMAT_R16G16B16A16_SFLOAT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FXAA::CreateSampler(const Device& device) {
|
void FXAA::CreateSampler(const Device& device) {
|
||||||
@@ -63,8 +60,8 @@ void FXAA::CreateDescriptorSetLayouts(const Device& device) {
|
|||||||
void FXAA::CreateDescriptorSets(const Device& device) {
|
void FXAA::CreateDescriptorSets(const Device& device) {
|
||||||
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
|
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
|
||||||
|
|
||||||
for (auto& images : m_dynamic_images) {
|
for (u32 i = 0; i < m_image_count; i++) {
|
||||||
images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, {layout});
|
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) {
|
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<VkDescriptorImageInfo> image_infos;
|
std::vector<VkDescriptorImageInfo> image_infos;
|
||||||
std::vector<VkWriteDescriptorSet> updates;
|
std::vector<VkWriteDescriptorSet> updates;
|
||||||
image_infos.reserve(2);
|
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, descriptor_set, 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, 1));
|
||||||
|
|
||||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
device.GetLogical().UpdateDescriptorSets(updates, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FXAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) {
|
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 input_image{*inout_image};
|
||||||
const VkImage output_image{*image.image};
|
const VkImage output_image{*m_image};
|
||||||
const VkImageView output_view{*image.image_view};
|
const VkImageView output_view{*m_image_view};
|
||||||
const VkDescriptorSet descriptor_set{image.descriptor_sets[0]};
|
const VkDescriptorSet descriptor_set{m_descriptor_sets[image_index][0]};
|
||||||
const VkPipeline pipeline{*m_pipeline};
|
const VkPipeline pipeline{*m_pipeline};
|
||||||
const VkPipelineLayout layout{*m_pipeline_layout};
|
const VkPipelineLayout layout{*m_pipeline_layout};
|
||||||
const VkExtent2D extent{m_extent};
|
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);
|
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
*inout_image = *image.image;
|
*inout_image = output_image;
|
||||||
*inout_image_view = *image.image_view;
|
*inout_image_view = output_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -34,12 +34,9 @@ private:
|
|||||||
void CreatePipelines(const Device& device);
|
void CreatePipelines(const Device& device);
|
||||||
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
|
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
|
||||||
|
|
||||||
struct Image {
|
vk::Image m_image{};
|
||||||
vk::DescriptorSets descriptor_sets{};
|
vk::ImageView m_image_view{};
|
||||||
vk::Image image{};
|
std::vector<vk::DescriptorSets> m_descriptor_sets{};
|
||||||
vk::ImageView image_view{};
|
|
||||||
};
|
|
||||||
std::vector<Image> m_dynamic_images{};
|
|
||||||
const VkExtent2D m_extent;
|
const VkExtent2D m_extent;
|
||||||
const u32 m_image_count;
|
const u32 m_image_count;
|
||||||
vk::ShaderModule m_vertex_shader{};
|
vk::ShaderModule m_vertex_shader{};
|
||||||
|
|||||||
@@ -18,6 +18,34 @@ constexpr u32 FIXED_DESCRIPTOR_SETS = 64;
|
|||||||
constexpr u32 DESCRIPTOR_SETS_PER_SLOT = 100;
|
constexpr u32 DESCRIPTOR_SETS_PER_SLOT = 100;
|
||||||
constexpr size_t FIRST_DELTA_LEVEL = 4;
|
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 <typename Func>
|
||||||
|
void ForEachWaveStage(std::array<LsfgGamma, LSFG_MIP_LEVELS>& gamma,
|
||||||
|
std::array<LsfgDelta, LSFG_DELTA_INSTANCES>& 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
|
} // Anonymous namespace
|
||||||
|
|
||||||
LsfgChain::LsfgChain(const Device& device, MemoryAllocator& memory_allocator,
|
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,
|
size_t generation_count, size_t generation, VkImage image,
|
||||||
VkExtent2D extent) {
|
VkExtent2D extent) {
|
||||||
const size_t slot = LsfgGenerationSlot(generation_count, generation);
|
const size_t slot = LsfgGenerationSlot(generation_count, generation);
|
||||||
for (size_t i = 0; i < LSFG_MIP_LEVELS; ++i) {
|
for (size_t wave = 0; wave < GENERATION_WAVES; ++wave) {
|
||||||
gamma[i].Dispatch(cmdbuf, frame_count, slot);
|
LsfgBarriers barriers(cmdbuf);
|
||||||
if (i >= FIRST_DELTA_LEVEL) {
|
ForEachWaveStage(gamma, delta, wave, [&barriers, frame_count](auto& pass, size_t stage) {
|
||||||
delta[i - FIRST_DELTA_LEVEL].Dispatch(cmdbuf, frame_count, slot);
|
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);
|
generate.Dispatch(cmdbuf, frame_count, slot, image, extent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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 VkExtent2D extent = temp1[0].Extent();
|
||||||
const u32 groups_x = GroupCount(extent.width);
|
cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ public:
|
|||||||
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous_gamma,
|
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous_gamma,
|
||||||
LsfgImage* previous1, LsfgImage* previous2);
|
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() {
|
[[nodiscard]] LsfgImage& Output1() {
|
||||||
return out_image1;
|
return out_image1;
|
||||||
|
|||||||
@@ -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];
|
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 VkExtent2D extent = temp1[0].Extent();
|
||||||
const u32 groups_x = GroupCount(extent.width);
|
cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ public:
|
|||||||
LsfgResources& resources, vk::DescriptorPool& descriptor_pool,
|
LsfgResources& resources, vk::DescriptorPool& descriptor_pool,
|
||||||
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous);
|
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() {
|
[[nodiscard]] LsfgImage& Output() {
|
||||||
return out_image;
|
return out_image;
|
||||||
|
|||||||
@@ -27,12 +27,8 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image
|
|||||||
, m_extent{extent}
|
, m_extent{extent}
|
||||||
, m_edge_dir{edge_dir}
|
, m_edge_dir{edge_dir}
|
||||||
{
|
{
|
||||||
// Not finished yet initializing at ctor time?
|
m_image = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
m_dynamic_images.resize(m_image_count);
|
m_image_view = CreateWrappedImageView(device, m_image, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
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_sampler = CreateBilinearSampler(device);
|
m_sampler = CreateBilinearSampler(device);
|
||||||
m_vert_shader = BuildShader(device, SGSR1_SHADER_VERT_SPV);
|
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});
|
m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
|
||||||
|
|
||||||
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
|
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
|
||||||
for (auto& images : m_dynamic_images)
|
for (size_t i = 0; i < m_image_count; ++i)
|
||||||
images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layout);
|
m_descriptor_sets.push_back(CreateWrappedDescriptorSets(m_descriptor_pool, layout));
|
||||||
|
|
||||||
const VkPushConstantRange range{
|
const VkPushConstantRange range{
|
||||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
.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) {
|
void SGSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) {
|
||||||
Images& images = m_dynamic_images[image_index];
|
|
||||||
std::vector<VkDescriptorImageInfo> image_infos;
|
std::vector<VkDescriptorImageInfo> image_infos;
|
||||||
std::vector<VkWriteDescriptorSet> updates;
|
std::vector<VkWriteDescriptorSet> updates;
|
||||||
image_infos.reserve(1);
|
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, {});
|
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<f32>& crop_rect) {
|
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<f32>& crop_rect) {
|
||||||
Images& images = m_dynamic_images[image_index];
|
auto const output_image = *m_image;
|
||||||
auto const output_image = *images.image;
|
auto const output_view = *m_image_view;
|
||||||
auto const output_view = *images.image_view;
|
auto const descriptor_set = m_descriptor_sets[image_index][0];
|
||||||
auto const descriptor_set = images.descriptor_sets[0];
|
|
||||||
auto const pipeline = *m_stage_pipeline;
|
auto const pipeline = *m_stage_pipeline;
|
||||||
|
|
||||||
VkPipelineLayout layout = *m_pipeline_layout;
|
VkPipelineLayout layout = *m_pipeline_layout;
|
||||||
@@ -126,7 +120,7 @@ VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_
|
|||||||
cmdbuf.EndRendering();
|
cmdbuf.EndRendering();
|
||||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
});
|
});
|
||||||
return *images.image_view;
|
return output_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -33,12 +33,9 @@ private:
|
|||||||
vk::Pipeline m_stage_pipeline;
|
vk::Pipeline m_stage_pipeline;
|
||||||
vk::Sampler m_sampler;
|
vk::Sampler m_sampler;
|
||||||
|
|
||||||
struct Images {
|
vk::Image m_image;
|
||||||
vk::DescriptorSets descriptor_sets;
|
vk::ImageView m_image_view;
|
||||||
vk::Image image;
|
std::vector<vk::DescriptorSets> m_descriptor_sets;
|
||||||
vk::ImageView image_view;
|
|
||||||
};
|
|
||||||
std::vector<Images> m_dynamic_images;
|
|
||||||
bool m_edge_dir{};
|
bool m_edge_dir{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -55,22 +55,18 @@ void SMAA::CreateImages(const Device& device) {
|
|||||||
m_static_image_views[Search] =
|
m_static_image_views[Search] =
|
||||||
CreateWrappedImageView(device, m_static_images[Search], VK_FORMAT_R8_UNORM);
|
CreateWrappedImageView(device, m_static_images[Search], VK_FORMAT_R8_UNORM);
|
||||||
|
|
||||||
for (u32 i = 0; i < m_image_count; i++) {
|
m_dynamic_images[Blend] =
|
||||||
Images& images = m_dynamic_images.emplace_back();
|
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] =
|
m_dynamic_image_views[Blend] =
|
||||||
CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
CreateWrappedImageView(device, m_dynamic_images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||||
images.images[Edges] = CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16_SFLOAT);
|
m_dynamic_image_views[Edges] =
|
||||||
images.images[Output] =
|
CreateWrappedImageView(device, m_dynamic_images[Edges], VK_FORMAT_R16G16_SFLOAT);
|
||||||
CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
|
m_dynamic_image_views[Output] =
|
||||||
|
CreateWrappedImageView(device, m_dynamic_images[Output], 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMAA::CreateSampler(const Device& device) {
|
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(),
|
std::ranges::transform(m_descriptor_set_layouts, layouts.begin(),
|
||||||
[](auto& layout) { return *layout; });
|
[](auto& layout) { return *layout; });
|
||||||
|
|
||||||
for (auto& images : m_dynamic_images) {
|
for (u32 i = 0; i < m_image_count; i++) {
|
||||||
images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts);
|
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) {
|
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<VkDescriptorImageInfo> image_infos;
|
std::vector<VkDescriptorImageInfo> image_infos;
|
||||||
std::vector<VkWriteDescriptorSet> updates;
|
std::vector<VkWriteDescriptorSet> updates;
|
||||||
image_infos.reserve(6);
|
image_infos.reserve(6);
|
||||||
|
|
||||||
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view,
|
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],
|
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler,
|
||||||
images.descriptor_sets[BlendingWeightCalculation],
|
*m_dynamic_image_views[Edges],
|
||||||
|
descriptor_sets[BlendingWeightCalculation],
|
||||||
0));
|
0));
|
||||||
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *m_static_image_views[Area],
|
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *m_static_image_views[Area],
|
||||||
images.descriptor_sets[BlendingWeightCalculation],
|
descriptor_sets[BlendingWeightCalculation],
|
||||||
1));
|
1));
|
||||||
updates.push_back(
|
updates.push_back(
|
||||||
CreateWriteDescriptorSet(image_infos, *m_sampler, *m_static_image_views[Search],
|
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,
|
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view,
|
||||||
images.descriptor_sets[NeighborhoodBlending], 0));
|
descriptor_sets[NeighborhoodBlending], 0));
|
||||||
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Blend],
|
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler,
|
||||||
images.descriptor_sets[NeighborhoodBlending], 1));
|
*m_dynamic_image_views[Blend],
|
||||||
|
descriptor_sets[NeighborhoodBlending], 1));
|
||||||
|
|
||||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
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) {
|
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 input_image = *inout_image;
|
||||||
VkImage output_image = *images.images[Output];
|
VkImage output_image = *m_dynamic_images[Output];
|
||||||
VkImage edges_image = *images.images[Edges];
|
VkImage edges_image = *m_dynamic_images[Edges];
|
||||||
VkImage blend_image = *images.images[Blend];
|
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 =
|
VkDescriptorSet blending_weight_calculation_descriptor_set =
|
||||||
images.descriptor_sets[BlendingWeightCalculation];
|
descriptor_sets[BlendingWeightCalculation];
|
||||||
VkDescriptorSet neighborhood_blending_descriptor_set =
|
VkDescriptorSet neighborhood_blending_descriptor_set =
|
||||||
images.descriptor_sets[NeighborhoodBlending];
|
descriptor_sets[NeighborhoodBlending];
|
||||||
|
|
||||||
VkImageView edges_view = *images.image_views[Edges];
|
VkImageView edges_view = *m_dynamic_image_views[Edges];
|
||||||
VkImageView blend_view = *images.image_views[Blend];
|
VkImageView blend_view = *m_dynamic_image_views[Blend];
|
||||||
VkImageView output_view = *images.image_views[Output];
|
VkImageView output_view = *m_dynamic_image_views[Output];
|
||||||
|
|
||||||
UploadImages(device, scheduler);
|
UploadImages(device, scheduler);
|
||||||
UpdateDescriptorSets(device, *inout_image_view, image_index);
|
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);
|
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
*inout_image = *images.images[Output];
|
*inout_image = *m_dynamic_images[Output];
|
||||||
*inout_image_view = *images.image_views[Output];
|
*inout_image_view = *m_dynamic_image_views[Output];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|||||||
@@ -71,12 +71,9 @@ private:
|
|||||||
std::array<vk::Image, MaxStaticImage> m_static_images{};
|
std::array<vk::Image, MaxStaticImage> m_static_images{};
|
||||||
std::array<vk::ImageView, MaxStaticImage> m_static_image_views{};
|
std::array<vk::ImageView, MaxStaticImage> m_static_image_views{};
|
||||||
|
|
||||||
struct Images {
|
std::array<vk::Image, MaxDynamicImage> m_dynamic_images{};
|
||||||
vk::DescriptorSets descriptor_sets{};
|
std::array<vk::ImageView, MaxDynamicImage> m_dynamic_image_views{};
|
||||||
std::array<vk::Image, MaxDynamicImage> images{};
|
std::vector<vk::DescriptorSets> m_descriptor_sets{};
|
||||||
std::array<vk::ImageView, MaxDynamicImage> image_views{};
|
|
||||||
};
|
|
||||||
std::vector<Images> m_dynamic_images{};
|
|
||||||
bool m_images_ready{};
|
bool m_images_ready{};
|
||||||
|
|
||||||
vk::Sampler m_sampler{};
|
vk::Sampler m_sampler{};
|
||||||
|
|||||||
Reference in New Issue
Block a user