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