mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-16 05:21:22 +00:00
Increase and adjust descriptor slots
This commit is contained in:
@@ -228,13 +228,13 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format, VkEx
|
||||
const VkExtent2D extent{.width = frame->width, .height = frame->height};
|
||||
const f32 flow_scale = ConfiguredFlowScale(peak_guest_extent, extent);
|
||||
if (!chain || built_extent.width != extent.width || built_extent.height != extent.height ||
|
||||
built_format != format || built_flow_scale != flow_scale ||
|
||||
built_generations != ConfiguredGenerations()) {
|
||||
built_format != format || built_flow_scale != flow_scale) {
|
||||
Rebuild(device, extent, format, flow_scale);
|
||||
}
|
||||
|
||||
const u64 count = frame_count++;
|
||||
last_count = count;
|
||||
last_generations = ConfiguredGenerations();
|
||||
generated = generate && count + 1 >= LSFG_REQUIRED_FRAMES;
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
@@ -263,18 +263,21 @@ size_t FrameGen::WantedGenerations() const {
|
||||
}
|
||||
|
||||
size_t FrameGen::GeneratedFrameCount() const {
|
||||
return generated && chain ? chain->GenerationCount() : 0;
|
||||
return generated ? last_generations : 0;
|
||||
}
|
||||
|
||||
void FrameGen::GenerateInto(const Device& device, Frame* destination, size_t generation) {
|
||||
chain->SetTarget(device, generation, destination->index, *destination->storage_view);
|
||||
chain->SetTarget(device, last_generations, generation, destination->index,
|
||||
*destination->storage_view);
|
||||
|
||||
const VkExtent2D extent{.width = destination->width, .height = destination->height};
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([this, count = last_count, generation, target = destination->index,
|
||||
image = *destination->image, extent](vk::CommandBuffer cmdbuf) {
|
||||
chain->DispatchGeneration(cmdbuf, count, generation, target, image, extent);
|
||||
scheduler.Record([this, count = last_count, generation_count = last_generations, generation,
|
||||
target = destination->index, image = *destination->image,
|
||||
extent](vk::CommandBuffer cmdbuf) {
|
||||
chain->DispatchGeneration(cmdbuf, count, generation_count, generation, target, image,
|
||||
extent);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -283,10 +286,8 @@ void FrameGen::Rebuild(const Device& device, VkExtent2D extent, VkFormat format,
|
||||
chain.reset();
|
||||
|
||||
built_flow_scale = flow_scale;
|
||||
built_generations = ConfiguredGenerations();
|
||||
|
||||
chain.emplace(device, memory_allocator, *shaders, extent, format, built_flow_scale,
|
||||
built_generations);
|
||||
chain.emplace(device, memory_allocator, *shaders, extent, format, built_flow_scale);
|
||||
built_extent = extent;
|
||||
built_format = format;
|
||||
frame_count = 0;
|
||||
|
||||
@@ -43,9 +43,9 @@ private:
|
||||
VkExtent2D built_extent{};
|
||||
VkFormat built_format{VK_FORMAT_UNDEFINED};
|
||||
f32 built_flow_scale{};
|
||||
size_t built_generations{};
|
||||
u64 frame_count{};
|
||||
u64 last_count{};
|
||||
size_t last_generations{};
|
||||
bool generated{};
|
||||
bool unavailable{};
|
||||
bool dumped{};
|
||||
|
||||
@@ -15,19 +15,18 @@ namespace Vulkan {
|
||||
namespace {
|
||||
|
||||
constexpr u32 FIXED_DESCRIPTOR_SETS = 64;
|
||||
constexpr u32 DESCRIPTOR_SETS_PER_GENERATION = 112;
|
||||
constexpr u32 DESCRIPTOR_SETS_PER_SLOT = 112;
|
||||
constexpr size_t FIRST_DELTA_LEVEL = 4;
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
LsfgChain::LsfgChain(const Device& device, MemoryAllocator& memory_allocator,
|
||||
const LsfgShaders& shaders, VkExtent2D extent, VkFormat format,
|
||||
f32 flow_scale, size_t generation_count_)
|
||||
: generation_count{generation_count_},
|
||||
resources{device, memory_allocator, flow_scale},
|
||||
f32 flow_scale)
|
||||
: resources{device, memory_allocator, flow_scale},
|
||||
descriptor_pool{CreateLsfgDescriptorPool(
|
||||
device, FIXED_DESCRIPTOR_SETS +
|
||||
DESCRIPTOR_SETS_PER_GENERATION * static_cast<u32>(generation_count))} {
|
||||
DESCRIPTOR_SETS_PER_SLOT * static_cast<u32>(LSFG_GENERATION_SLOTS))} {
|
||||
for (auto& image : frames) {
|
||||
image = LsfgImage(device, memory_allocator, extent, format);
|
||||
}
|
||||
@@ -49,7 +48,7 @@ LsfgChain::LsfgChain(const Device& device, MemoryAllocator& memory_allocator,
|
||||
gamma[i] = LsfgGamma(device, memory_allocator, shaders, resources, descriptor_pool,
|
||||
alpha[level].Outputs(),
|
||||
beta.Output(std::min(level, LSFG_BETA_OUTPUTS - 1)),
|
||||
i == 0 ? nullptr : &gamma[i - 1].Output(), generation_count);
|
||||
i == 0 ? nullptr : &gamma[i - 1].Output());
|
||||
|
||||
if (i < FIRST_DELTA_LEVEL) {
|
||||
continue;
|
||||
@@ -60,13 +59,13 @@ LsfgChain::LsfgChain(const Device& device, MemoryAllocator& memory_allocator,
|
||||
device, memory_allocator, shaders, resources, descriptor_pool, alpha[level].Outputs(),
|
||||
beta.Output(level), i == FIRST_DELTA_LEVEL ? nullptr : &gamma[i - 1].Output(),
|
||||
i == FIRST_DELTA_LEVEL ? nullptr : &delta[index - 1].Output1(),
|
||||
i == FIRST_DELTA_LEVEL ? nullptr : &delta[index - 1].Output2(), generation_count);
|
||||
i == FIRST_DELTA_LEVEL ? nullptr : &delta[index - 1].Output2());
|
||||
}
|
||||
|
||||
generate = LsfgGenerate(device, shaders, resources, descriptor_pool, frames,
|
||||
gamma[LSFG_MIP_LEVELS - 1].Output(),
|
||||
delta[LSFG_DELTA_INSTANCES - 1].Output1(),
|
||||
delta[LSFG_DELTA_INSTANCES - 1].Output2(), generation_count);
|
||||
delta[LSFG_DELTA_INSTANCES - 1].Output2());
|
||||
}
|
||||
|
||||
void LsfgChain::DispatchShared(vk::CommandBuffer cmdbuf, u64 frame_count) {
|
||||
@@ -88,15 +87,17 @@ void LsfgChain::DispatchShared(vk::CommandBuffer cmdbuf, u64 frame_count) {
|
||||
beta.Dispatch(cmdbuf, frame_count);
|
||||
}
|
||||
|
||||
void LsfgChain::DispatchGeneration(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation,
|
||||
u32 target, VkImage image, VkExtent2D extent) {
|
||||
void LsfgChain::DispatchGeneration(vk::CommandBuffer cmdbuf, u64 frame_count,
|
||||
size_t generation_count, size_t generation, u32 target,
|
||||
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, generation);
|
||||
gamma[i].Dispatch(cmdbuf, frame_count, slot);
|
||||
if (i >= FIRST_DELTA_LEVEL) {
|
||||
delta[i - FIRST_DELTA_LEVEL].Dispatch(cmdbuf, frame_count, generation);
|
||||
delta[i - FIRST_DELTA_LEVEL].Dispatch(cmdbuf, frame_count, slot);
|
||||
}
|
||||
}
|
||||
generate.Dispatch(cmdbuf, frame_count, generation, target, image, extent);
|
||||
generate.Dispatch(cmdbuf, frame_count, slot, target, image, extent);
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -27,28 +27,25 @@ constexpr size_t LSFG_DELTA_INSTANCES = 3;
|
||||
class LsfgChain {
|
||||
public:
|
||||
LsfgChain(const Device& device, MemoryAllocator& memory_allocator, const LsfgShaders& shaders,
|
||||
VkExtent2D extent, VkFormat format, f32 flow_scale, size_t generation_count_);
|
||||
VkExtent2D extent, VkFormat format, f32 flow_scale);
|
||||
|
||||
LsfgChain(const LsfgChain&) = delete;
|
||||
LsfgChain& operator=(const LsfgChain&) = delete;
|
||||
|
||||
void DispatchShared(vk::CommandBuffer cmdbuf, u64 frame_count);
|
||||
|
||||
void DispatchGeneration(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation,
|
||||
u32 target, VkImage image, VkExtent2D extent);
|
||||
void DispatchGeneration(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation_count,
|
||||
size_t generation, u32 target, VkImage image, VkExtent2D extent);
|
||||
|
||||
void SetTarget(const Device& device, size_t generation, u32 target, VkImageView view) {
|
||||
generate.SetTarget(device, generation, target, view);
|
||||
void SetTarget(const Device& device, size_t generation_count, size_t generation, u32 target,
|
||||
VkImageView view) {
|
||||
generate.SetTarget(device, LsfgGenerationSlot(generation_count, generation), target, view);
|
||||
}
|
||||
|
||||
[[nodiscard]] LsfgImage& Input(u64 frame_count) {
|
||||
return frames[frame_count % frames.size()];
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t GenerationCount() const {
|
||||
return generation_count;
|
||||
}
|
||||
|
||||
[[nodiscard]] LsfgImage& FlowLevel(size_t level) {
|
||||
return mipmaps.Output(level);
|
||||
}
|
||||
@@ -74,7 +71,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
size_t generation_count{};
|
||||
LsfgResources resources;
|
||||
vk::DescriptorPool descriptor_pool;
|
||||
|
||||
|
||||
@@ -28,11 +28,31 @@ constexpr VkFormat LSFG_MOTION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
constexpr size_t LSFG_HISTORY_SLOTS = 3;
|
||||
constexpr size_t LSFG_MAX_TARGETS = 7;
|
||||
constexpr size_t LSFG_MAX_GENERATIONS = 3;
|
||||
|
||||
constexpr size_t LSFG_GENERATION_SLOTS = LSFG_MAX_GENERATIONS * (LSFG_MAX_GENERATIONS + 1) / 2;
|
||||
|
||||
[[nodiscard]] constexpr size_t LsfgGenerationSlot(size_t generation_count, size_t generation) {
|
||||
return (generation_count - 1) * generation_count / 2 + generation;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr f32 LsfgTimestamp(size_t generation, size_t generation_count) {
|
||||
return static_cast<f32>(generation + 1) / static_cast<f32>(generation_count + 1);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_t LsfgSlotCount(size_t slot) {
|
||||
size_t count = 1;
|
||||
while (LsfgGenerationSlot(count + 1, 0) <= slot) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr f32 LsfgSlotTimestamp(size_t slot) {
|
||||
const size_t count = LsfgSlotCount(slot);
|
||||
return LsfgTimestamp(slot - LsfgGenerationSlot(count, 0), count);
|
||||
}
|
||||
|
||||
class LsfgImage {
|
||||
public:
|
||||
LsfgImage() = default;
|
||||
|
||||
@@ -28,7 +28,7 @@ LsfgDelta::LsfgDelta(const Device& device, MemoryAllocator& memory_allocator,
|
||||
const LsfgShaders& shaders, LsfgResources& resources,
|
||||
vk::DescriptorPool& descriptor_pool, LsfgImageHistory& inputs_,
|
||||
LsfgImage& flow_input_, LsfgImage* previous_gamma_, LsfgImage* previous1_,
|
||||
LsfgImage* previous2_, size_t generation_count)
|
||||
LsfgImage* previous2_)
|
||||
: inputs{&inputs_}, flow_input{&flow_input_}, previous_gamma{previous_gamma_},
|
||||
previous1{previous1_}, previous2{previous2_} {
|
||||
using namespace VideoCore::FrameGen::PerformanceShader;
|
||||
@@ -83,7 +83,7 @@ LsfgDelta::LsfgDelta(const Device& device, MemoryAllocator& memory_allocator,
|
||||
out_image2 = LsfgImage(device, memory_allocator, extent, LSFG_MOTION_FORMAT);
|
||||
|
||||
std::vector<VkDescriptorSetLayout> layouts;
|
||||
for (size_t generation = 0; generation < generation_count; ++generation) {
|
||||
for (size_t slot = 0; slot < LSFG_GENERATION_SLOTS; ++slot) {
|
||||
for (size_t i = 0; i < LSFG_HISTORY_SLOTS; ++i) {
|
||||
layouts.push_back(passes[0].SetLayout());
|
||||
}
|
||||
@@ -104,12 +104,11 @@ LsfgDelta::LsfgDelta(const Device& device, MemoryAllocator& memory_allocator,
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_COMPARE_OP_NEVER, true);
|
||||
const VkSampler edge_sampler =
|
||||
resources.GetSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false);
|
||||
generations.resize(generation_count);
|
||||
size_t next = 0;
|
||||
for (size_t generation = 0; generation < generation_count; ++generation) {
|
||||
Generation& pass = generations[generation];
|
||||
const VkBuffer buffer = resources.GetBuffer(
|
||||
LsfgTimestamp(generation, generation_count), false, previous_gamma == nullptr);
|
||||
for (size_t slot = 0; slot < LSFG_GENERATION_SLOTS; ++slot) {
|
||||
Generation& pass = generations[slot];
|
||||
const VkBuffer buffer =
|
||||
resources.GetBuffer(LsfgSlotTimestamp(slot), false, previous_gamma == nullptr);
|
||||
|
||||
for (size_t i = 0; i < LSFG_HISTORY_SLOTS; ++i) {
|
||||
pass.first_descriptor_sets[i] = owned_sets[next++];
|
||||
@@ -197,23 +196,23 @@ LsfgDelta::LsfgDelta(const Device& device, MemoryAllocator& memory_allocator,
|
||||
}
|
||||
}
|
||||
|
||||
void LsfgDelta::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation) {
|
||||
const Generation& pass = generations[generation];
|
||||
void LsfgDelta::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot) {
|
||||
const Generation& pass = generations[slot];
|
||||
|
||||
const VkExtent2D extent = temp1[0].Extent();
|
||||
const u32 groups_x = GroupCount(extent.width);
|
||||
const u32 groups_y = GroupCount(extent.height);
|
||||
|
||||
const size_t slot = frame_count % LSFG_HISTORY_SLOTS;
|
||||
const size_t previous_slot = (frame_count + 2) % LSFG_HISTORY_SLOTS;
|
||||
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_slot])
|
||||
.WriteToReadAll((*inputs)[slot])
|
||||
.WriteToReadAll((*inputs)[previous_history])
|
||||
.WriteToReadAll((*inputs)[history])
|
||||
.WriteToRead(previous_gamma)
|
||||
.ReadToWriteAll(temp1)
|
||||
.Build();
|
||||
passes[0].Bind(cmdbuf, pass.first_descriptor_sets[slot]);
|
||||
passes[0].Bind(cmdbuf, pass.first_descriptor_sets[history]);
|
||||
cmdbuf.Dispatch(groups_x, groups_y, 1);
|
||||
|
||||
LsfgBarriers(cmdbuf).WriteToReadAll(temp1).ReadToWriteAll(temp2).Build();
|
||||
@@ -238,13 +237,13 @@ void LsfgDelta::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t gener
|
||||
cmdbuf.Dispatch(groups_x, groups_y, 1);
|
||||
|
||||
LsfgBarriers(cmdbuf)
|
||||
.WriteToReadAll((*inputs)[previous_slot])
|
||||
.WriteToReadAll((*inputs)[slot])
|
||||
.WriteToReadAll((*inputs)[previous_history])
|
||||
.WriteToReadAll((*inputs)[history])
|
||||
.WriteToRead(previous_gamma)
|
||||
.WriteToRead(previous1)
|
||||
.ReadToWriteAll(temp2)
|
||||
.Build();
|
||||
passes[5].Bind(cmdbuf, pass.sixth_descriptor_sets[slot]);
|
||||
passes[5].Bind(cmdbuf, pass.sixth_descriptor_sets[history]);
|
||||
cmdbuf.Dispatch(groups_x, groups_y, 1);
|
||||
|
||||
LsfgBarriers(cmdbuf)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_vulkan/present/lsfg_common.h"
|
||||
@@ -26,9 +25,9 @@ public:
|
||||
LsfgDelta(const Device& device, MemoryAllocator& memory_allocator, const LsfgShaders& shaders,
|
||||
LsfgResources& resources, vk::DescriptorPool& descriptor_pool,
|
||||
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous_gamma,
|
||||
LsfgImage* previous1, LsfgImage* previous2, size_t generation_count);
|
||||
LsfgImage* previous1, LsfgImage* previous2);
|
||||
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation);
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot);
|
||||
|
||||
[[nodiscard]] LsfgImage& Output1() {
|
||||
return out_image1;
|
||||
@@ -52,7 +51,7 @@ private:
|
||||
LsfgImage* previous2{};
|
||||
|
||||
std::array<LsfgPass, LSFG_DELTA_STAGES> passes;
|
||||
std::vector<Generation> generations;
|
||||
std::array<Generation, LSFG_GENERATION_SLOTS> generations{};
|
||||
vk::DescriptorSets owned_sets;
|
||||
|
||||
std::array<LsfgImage, LSFG_DELTA_TEMPS> temp1;
|
||||
|
||||
@@ -27,7 +27,7 @@ constexpr u32 DISPATCH_TILE_SHIFT = 3;
|
||||
LsfgGamma::LsfgGamma(const Device& device, MemoryAllocator& memory_allocator,
|
||||
const LsfgShaders& shaders, LsfgResources& resources,
|
||||
vk::DescriptorPool& descriptor_pool, LsfgImageHistory& inputs_,
|
||||
LsfgImage& flow_input_, LsfgImage* previous_, size_t generation_count)
|
||||
LsfgImage& flow_input_, LsfgImage* previous_)
|
||||
: inputs{&inputs_}, flow_input{&flow_input_}, previous{previous_} {
|
||||
using namespace VideoCore::FrameGen::PerformanceShader;
|
||||
|
||||
@@ -64,7 +64,7 @@ LsfgGamma::LsfgGamma(const Device& device, MemoryAllocator& memory_allocator,
|
||||
out_image = LsfgImage(device, memory_allocator, extent, LSFG_MOTION_FORMAT);
|
||||
|
||||
std::vector<VkDescriptorSetLayout> layouts;
|
||||
for (size_t generation = 0; generation < generation_count; ++generation) {
|
||||
for (size_t slot = 0; slot < LSFG_GENERATION_SLOTS; ++slot) {
|
||||
for (size_t i = 0; i < LSFG_HISTORY_SLOTS; ++i) {
|
||||
layouts.push_back(passes[0].SetLayout());
|
||||
}
|
||||
@@ -80,12 +80,11 @@ LsfgGamma::LsfgGamma(const Device& device, MemoryAllocator& memory_allocator,
|
||||
const VkSampler edge_sampler =
|
||||
resources.GetSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false);
|
||||
|
||||
generations.resize(generation_count);
|
||||
size_t next = 0;
|
||||
for (size_t generation = 0; generation < generation_count; ++generation) {
|
||||
Generation& pass = generations[generation];
|
||||
const VkBuffer buffer = resources.GetBuffer(
|
||||
LsfgTimestamp(generation, generation_count), previous == nullptr);
|
||||
for (size_t slot = 0; slot < LSFG_GENERATION_SLOTS; ++slot) {
|
||||
Generation& pass = generations[slot];
|
||||
const VkBuffer buffer =
|
||||
resources.GetBuffer(LsfgSlotTimestamp(slot), previous == nullptr);
|
||||
|
||||
for (size_t i = 0; i < LSFG_HISTORY_SLOTS; ++i) {
|
||||
pass.first_descriptor_sets[i] = owned_sets[next++];
|
||||
@@ -134,23 +133,23 @@ LsfgGamma::LsfgGamma(const Device& device, MemoryAllocator& memory_allocator,
|
||||
}
|
||||
}
|
||||
|
||||
void LsfgGamma::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation) {
|
||||
const Generation& pass = generations[generation];
|
||||
void LsfgGamma::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot) {
|
||||
const Generation& pass = generations[slot];
|
||||
|
||||
const VkExtent2D extent = temp1[0].Extent();
|
||||
const u32 groups_x = GroupCount(extent.width);
|
||||
const u32 groups_y = GroupCount(extent.height);
|
||||
|
||||
const size_t slot = frame_count % LSFG_HISTORY_SLOTS;
|
||||
const size_t previous_slot = (frame_count + 2) % LSFG_HISTORY_SLOTS;
|
||||
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_slot])
|
||||
.WriteToReadAll((*inputs)[slot])
|
||||
.WriteToReadAll((*inputs)[previous_history])
|
||||
.WriteToReadAll((*inputs)[history])
|
||||
.WriteToRead(previous)
|
||||
.ReadToWriteAll(temp1)
|
||||
.Build();
|
||||
passes[0].Bind(cmdbuf, pass.first_descriptor_sets[slot]);
|
||||
passes[0].Bind(cmdbuf, pass.first_descriptor_sets[history]);
|
||||
cmdbuf.Dispatch(groups_x, groups_y, 1);
|
||||
|
||||
LsfgBarriers(cmdbuf).WriteToReadAll(temp1).ReadToWriteAll(temp2).Build();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_vulkan/present/lsfg_common.h"
|
||||
@@ -25,10 +24,9 @@ public:
|
||||
LsfgGamma() = default;
|
||||
LsfgGamma(const Device& device, MemoryAllocator& memory_allocator, const LsfgShaders& shaders,
|
||||
LsfgResources& resources, vk::DescriptorPool& descriptor_pool,
|
||||
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous,
|
||||
size_t generation_count);
|
||||
LsfgImageHistory& inputs, LsfgImage& flow_input, LsfgImage* previous);
|
||||
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation);
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot);
|
||||
|
||||
[[nodiscard]] LsfgImage& Output() {
|
||||
return out_image;
|
||||
@@ -45,7 +43,7 @@ private:
|
||||
LsfgImage* previous{};
|
||||
|
||||
std::array<LsfgPass, LSFG_GAMMA_STAGES> passes;
|
||||
std::vector<Generation> generations;
|
||||
std::array<Generation, LSFG_GENERATION_SLOTS> generations{};
|
||||
vk::DescriptorSets owned_sets;
|
||||
|
||||
std::array<LsfgImage, LSFG_GAMMA_TEMPS> temp1;
|
||||
|
||||
@@ -49,7 +49,7 @@ VkImageMemoryBarrier MakeTargetBarrier(VkImage image, VkAccessFlags src_access,
|
||||
LsfgGenerate::LsfgGenerate(const Device& device, const LsfgShaders& shaders,
|
||||
LsfgResources& resources, vk::DescriptorPool& descriptor_pool,
|
||||
LsfgImagePair& frames_, LsfgImage& motion_, LsfgImage& detail1_,
|
||||
LsfgImage& detail2_, size_t generation_count)
|
||||
LsfgImage& detail2_)
|
||||
: frames{&frames_}, motion{&motion_}, detail1{&detail1_}, detail2{&detail2_} {
|
||||
using namespace VideoCore::FrameGen::PerformanceShader;
|
||||
|
||||
@@ -63,35 +63,33 @@ LsfgGenerate::LsfgGenerate(const Device& device, const LsfgShaders& shaders,
|
||||
edge_sampler =
|
||||
resources.GetSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false);
|
||||
|
||||
generations.resize(generation_count);
|
||||
|
||||
const std::vector<VkDescriptorSetLayout> layouts(
|
||||
generation_count * LSFG_MAX_TARGETS * 2, pass.SetLayout());
|
||||
LSFG_GENERATION_SLOTS * LSFG_MAX_TARGETS * 2, pass.SetLayout());
|
||||
owned_sets = CreateWrappedDescriptorSets(descriptor_pool, layouts);
|
||||
|
||||
size_t next = 0;
|
||||
for (size_t generation = 0; generation < generation_count; ++generation) {
|
||||
Generation& target = generations[generation];
|
||||
target.buffer = resources.GetBuffer(LsfgTimestamp(generation, generation_count));
|
||||
for (size_t slot = 0; slot < LSFG_GENERATION_SLOTS; ++slot) {
|
||||
Generation& target = generations[slot];
|
||||
target.buffer = resources.GetBuffer(LsfgSlotTimestamp(slot));
|
||||
|
||||
for (auto& slot : target.targets) {
|
||||
for (auto& set : slot.descriptor_sets) {
|
||||
for (auto& entry : target.targets) {
|
||||
for (auto& set : entry.descriptor_sets) {
|
||||
set = owned_sets[next++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LsfgGenerate::SetTarget(const Device& device, size_t generation, u32 target, VkImageView view) {
|
||||
Target& slot = generations[generation].targets[target];
|
||||
if (slot.view == view) {
|
||||
void LsfgGenerate::SetTarget(const Device& device, size_t slot, u32 target, VkImageView view) {
|
||||
Target& entry = generations[slot].targets[target];
|
||||
if (entry.view == view) {
|
||||
return;
|
||||
}
|
||||
slot.view = view;
|
||||
entry.view = view;
|
||||
|
||||
for (size_t i = 0; i < slot.descriptor_sets.size(); ++i) {
|
||||
LsfgDescriptorWriter(slot.descriptor_sets[i])
|
||||
.AddUniformBuffer(generations[generation].buffer, LsfgResources::BufferSize())
|
||||
for (size_t i = 0; i < entry.descriptor_sets.size(); ++i) {
|
||||
LsfgDescriptorWriter(entry.descriptor_sets[i])
|
||||
.AddUniformBuffer(generations[slot].buffer, LsfgResources::BufferSize())
|
||||
.AddSampler(sampler)
|
||||
.AddSampler(edge_sampler)
|
||||
.AddSampledImage((*frames)[1 - i])
|
||||
@@ -104,9 +102,9 @@ void LsfgGenerate::SetTarget(const Device& device, size_t generation, u32 target
|
||||
}
|
||||
}
|
||||
|
||||
void LsfgGenerate::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation,
|
||||
u32 target, VkImage image, VkExtent2D extent) {
|
||||
const Target& slot = generations[generation].targets[target];
|
||||
void LsfgGenerate::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, u32 target,
|
||||
VkImage image, VkExtent2D extent) {
|
||||
const Target& entry = generations[slot].targets[target];
|
||||
|
||||
LsfgBarriers(cmdbuf)
|
||||
.WriteToReadAll(*frames)
|
||||
@@ -116,7 +114,7 @@ void LsfgGenerate::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t ge
|
||||
.DiscardToWrite(image)
|
||||
.Build();
|
||||
|
||||
pass.Bind(cmdbuf, slot.descriptor_sets[frame_count % slot.descriptor_sets.size()]);
|
||||
pass.Bind(cmdbuf, entry.descriptor_sets[frame_count % entry.descriptor_sets.size()]);
|
||||
cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1);
|
||||
|
||||
const std::array after{MakeTargetBarrier(
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_vulkan/present/lsfg_common.h"
|
||||
@@ -22,11 +21,11 @@ public:
|
||||
LsfgGenerate() = default;
|
||||
LsfgGenerate(const Device& device, const LsfgShaders& shaders, LsfgResources& resources,
|
||||
vk::DescriptorPool& descriptor_pool, LsfgImagePair& frames, LsfgImage& motion,
|
||||
LsfgImage& detail1, LsfgImage& detail2, size_t generation_count);
|
||||
LsfgImage& detail1, LsfgImage& detail2);
|
||||
|
||||
void SetTarget(const Device& device, size_t generation, u32 target, VkImageView view);
|
||||
void SetTarget(const Device& device, size_t slot, u32 target, VkImageView view);
|
||||
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t generation, u32 target,
|
||||
void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count, size_t slot, u32 target,
|
||||
VkImage image, VkExtent2D extent);
|
||||
|
||||
private:
|
||||
@@ -48,7 +47,7 @@ private:
|
||||
VkSampler edge_sampler{};
|
||||
|
||||
LsfgPass pass;
|
||||
std::vector<Generation> generations;
|
||||
std::array<Generation, LSFG_GENERATION_SLOTS> generations{};
|
||||
vk::DescriptorSets owned_sets;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user