layers takein device

This commit is contained in:
lizzie 2026-06-10 10:09:10 +00:00
parent 66a85f2a01
commit 84943dfaf9
10 changed files with 213 additions and 229 deletions

View file

@ -11,12 +11,12 @@
namespace Vulkan {
class Scheduler;
class Device;
class AntiAliasPass {
public:
virtual ~AntiAliasPass() = default;
virtual void Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image,
VkImageView* inout_image_view) = 0;
virtual void Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) = 0;
};
} // namespace Vulkan

View file

@ -25,74 +25,74 @@ using namespace FSR;
using PushConstants = std::array<u32, 4 * 4>;
FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count,
VkExtent2D extent)
: m_device{device}, m_memory_allocator{memory_allocator},
m_image_count{image_count}, m_extent{extent} {
CreateImages();
CreateRenderPasses();
CreateSampler();
CreateShaders();
CreateDescriptorPool();
CreateDescriptorSetLayout();
CreateDescriptorSets();
CreatePipelineLayouts();
CreatePipelines();
FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, VkExtent2D extent)
: m_memory_allocator{memory_allocator}
, m_image_count{image_count}
, m_extent{extent}
{
CreateImages(device);
CreateRenderPasses(device);
CreateSampler(device);
CreateShaders(device);
CreateDescriptorPool(device);
CreateDescriptorSetLayout(device);
CreateDescriptorSets(device);
CreatePipelineLayouts(device);
CreatePipelines(device);
}
void FSR::CreateImages() {
void FSR::CreateImages(const Device& device) {
m_dynamic_images.resize(m_image_count);
for (auto& images : m_dynamic_images) {
images.images[Easu] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
images.images[Rcas] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_views[Easu] = CreateWrappedImageView(m_device, images.images[Easu], VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_views[Rcas] = CreateWrappedImageView(m_device, images.images[Rcas], 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);
}
}
void FSR::CreateRenderPasses() {
m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
void FSR::CreateRenderPasses(const Device& device) {
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
for (auto& images : m_dynamic_images) {
images.framebuffers[Easu] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Easu], m_extent);
images.framebuffers[Rcas] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Rcas], m_extent);
images.framebuffers[Easu] = CreateWrappedFramebuffer(device, m_renderpass, images.image_views[Easu], m_extent);
images.framebuffers[Rcas] = CreateWrappedFramebuffer(device, m_renderpass, images.image_views[Rcas], m_extent);
}
}
void FSR::CreateSampler() {
m_sampler = CreateBilinearSampler(m_device);
void FSR::CreateSampler(const Device& device) {
m_sampler = CreateBilinearSampler(device);
}
void FSR::CreateShaders() {
m_vert_shader = BuildShader(m_device, VULKAN_FIDELITYFX_FSR_VERT_SPV);
void FSR::CreateShaders(const Device& device) {
m_vert_shader = BuildShader(device, VULKAN_FIDELITYFX_FSR_VERT_SPV);
if (m_device.IsFloat16Supported()) {
m_easu_shader = BuildShader(m_device, VULKAN_FIDELITYFX_FSR_EASU_FP16_FRAG_SPV);
m_rcas_shader = BuildShader(m_device, VULKAN_FIDELITYFX_FSR_RCAS_FP16_FRAG_SPV);
if (device.IsFloat16Supported()) {
m_easu_shader = BuildShader(device, VULKAN_FIDELITYFX_FSR_EASU_FP16_FRAG_SPV);
m_rcas_shader = BuildShader(device, VULKAN_FIDELITYFX_FSR_RCAS_FP16_FRAG_SPV);
} else {
m_easu_shader = BuildShader(m_device, VULKAN_FIDELITYFX_FSR_EASU_FP32_FRAG_SPV);
m_rcas_shader = BuildShader(m_device, VULKAN_FIDELITYFX_FSR_RCAS_FP32_FRAG_SPV);
m_easu_shader = BuildShader(device, VULKAN_FIDELITYFX_FSR_EASU_FP32_FRAG_SPV);
m_rcas_shader = BuildShader(device, VULKAN_FIDELITYFX_FSR_RCAS_FP32_FRAG_SPV);
}
}
void FSR::CreateDescriptorPool() {
void FSR::CreateDescriptorPool(const Device& device) {
// EASU: 1 descriptor
// RCAS: 1 descriptor
// 2 descriptors, 2 descriptor sets per invocation
m_descriptor_pool = CreateWrappedDescriptorPool(m_device, 2 * m_image_count, 2 * m_image_count);
m_descriptor_pool = CreateWrappedDescriptorPool(device, 2 * m_image_count, 2 * m_image_count);
}
void FSR::CreateDescriptorSetLayout() {
m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
void FSR::CreateDescriptorSetLayout(const Device& device) {
m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
}
void FSR::CreateDescriptorSets() {
void FSR::CreateDescriptorSets(const Device& device) {
std::vector<VkDescriptorSetLayout> layouts(MaxFsrStage, *m_descriptor_set_layout);
for (auto& images : m_dynamic_images)
images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts);
}
void FSR::CreatePipelineLayouts() {
void FSR::CreatePipelineLayouts(const Device& device) {
const VkPushConstantRange range{
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = 0,
@ -108,17 +108,17 @@ void FSR::CreatePipelineLayouts() {
.pPushConstantRanges = &range,
};
m_pipeline_layout = m_device.GetLogical().CreatePipelineLayout(ci);
m_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
}
void FSR::CreatePipelines() {
m_easu_pipeline = CreateWrappedPipeline(m_device, m_renderpass, m_pipeline_layout,
void FSR::CreatePipelines(const Device& device) {
m_easu_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
std::tie(m_vert_shader, m_easu_shader));
m_rcas_pipeline = CreateWrappedPipeline(m_device, m_renderpass, m_pipeline_layout,
m_rcas_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
std::tie(m_vert_shader, m_rcas_shader));
}
void FSR::UpdateDescriptorSets(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];
std::vector<VkDescriptorImageInfo> image_infos;
image_infos.reserve(2);
@ -126,10 +126,10 @@ void FSR::UpdateDescriptorSets(VkImageView image_view, size_t image_index) {
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[Easu], 0),
CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], images.descriptor_sets[Rcas], 0)
};
m_device.GetLogical().UpdateDescriptorSets(updates, {});
device.GetLogical().UpdateDescriptorSets(updates, {});
}
void FSR::UploadImages(Scheduler& scheduler) {
void FSR::UploadImages(const Device& device, Scheduler& scheduler) {
if (!m_images_ready) {
m_images_ready = true;
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
@ -142,7 +142,7 @@ void FSR::UploadImages(Scheduler& scheduler) {
}
}
VkImageView FSR::Draw(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,
const Common::Rectangle<f32>& crop_rect) {
Images& images = m_dynamic_images[image_index];
@ -179,8 +179,8 @@ VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_i
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
FsrRcasCon(rcas_con.data(), sharpening);
UploadImages(scheduler);
UpdateDescriptorSets(source_image_view, image_index);
UploadImages(device, scheduler);
UpdateDescriptorSets(device, source_image_view, image_index);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([=](vk::CommandBuffer cmdbuf) {

View file

@ -14,27 +14,25 @@ class Scheduler;
class FSR {
public:
explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count,
VkExtent2D extent);
VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,
explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, VkExtent2D extent);
VkImageView 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);
private:
void CreateImages();
void CreateRenderPasses();
void CreateSampler();
void CreateShaders();
void CreateDescriptorPool();
void CreateDescriptorSetLayout();
void CreateDescriptorSets();
void CreatePipelineLayouts();
void CreatePipelines();
void CreateImages(const Device& device);
void CreateRenderPasses(const Device& device);
void CreateSampler(const Device& device);
void CreateShaders(const Device& device);
void CreateDescriptorPool(const Device& device);
void CreateDescriptorSetLayout(const Device& device);
void CreateDescriptorSets(const Device& device);
void CreatePipelineLayouts(const Device& device);
void CreatePipelines(const Device& device);
void UploadImages(Scheduler& scheduler);
void UpdateDescriptorSets(VkImageView image_view, size_t image_index);
void UploadImages(const Device& device, Scheduler& scheduler);
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
const Device& m_device;
MemoryAllocator& m_memory_allocator;
const size_t m_image_count;
const VkExtent2D m_extent;

View file

@ -14,61 +14,60 @@
namespace Vulkan {
FXAA::FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count, VkExtent2D extent)
: m_device(device), m_allocator(allocator), m_extent(extent),
m_image_count(static_cast<u32>(image_count)) {
CreateImages();
CreateRenderPasses();
CreateSampler();
CreateShaders();
CreateDescriptorPool();
CreateDescriptorSetLayouts();
CreateDescriptorSets();
CreatePipelineLayouts();
CreatePipelines();
: m_extent(extent)
, m_image_count(u32(image_count))
{
CreateImages(device, allocator);
CreateRenderPasses(device);
CreateSampler(device);
CreateShaders(device);
CreateDescriptorPool(device);
CreateDescriptorSetLayouts(device);
CreateDescriptorSets(device);
CreatePipelineLayouts(device);
CreatePipelines(device);
}
FXAA::~FXAA() = default;
void FXAA::CreateImages() {
void FXAA::CreateImages(const Device& device, MemoryAllocator& allocator) {
for (u32 i = 0; i < m_image_count; i++) {
Image& image = m_dynamic_images.emplace_back();
image.image = CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
image.image_view =
CreateWrappedImageView(m_device, image.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::CreateRenderPasses() {
m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
void FXAA::CreateRenderPasses(const Device& device) {
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
for (auto& image : m_dynamic_images) {
image.framebuffer =
CreateWrappedFramebuffer(m_device, m_renderpass, image.image_view, m_extent);
CreateWrappedFramebuffer(device, m_renderpass, image.image_view, m_extent);
}
}
void FXAA::CreateSampler() {
m_sampler = CreateWrappedSampler(m_device);
void FXAA::CreateSampler(const Device& device) {
m_sampler = CreateWrappedSampler(device);
}
void FXAA::CreateShaders() {
m_vertex_shader = CreateWrappedShaderModule(m_device, FXAA_VERT_SPV);
m_fragment_shader = CreateWrappedShaderModule(m_device, FXAA_FRAG_SPV);
void FXAA::CreateShaders(const Device& device) {
m_vertex_shader = CreateWrappedShaderModule(device, FXAA_VERT_SPV);
m_fragment_shader = CreateWrappedShaderModule(device, FXAA_FRAG_SPV);
}
void FXAA::CreateDescriptorPool() {
void FXAA::CreateDescriptorPool(const Device& device) {
// 2 descriptors, 1 descriptor set per image
m_descriptor_pool = CreateWrappedDescriptorPool(m_device, 2 * m_image_count, m_image_count);
m_descriptor_pool = CreateWrappedDescriptorPool(device, 2 * m_image_count, m_image_count);
}
void FXAA::CreateDescriptorSetLayouts() {
void FXAA::CreateDescriptorSetLayouts(const Device& device) {
m_descriptor_set_layout =
CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
}
void FXAA::CreateDescriptorSets() {
void FXAA::CreateDescriptorSets(const Device& device) {
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
for (auto& images : m_dynamic_images) {
@ -76,30 +75,28 @@ void FXAA::CreateDescriptorSets() {
}
}
void FXAA::CreatePipelineLayouts() {
m_pipeline_layout = CreateWrappedPipelineLayout(m_device, m_descriptor_set_layout);
void FXAA::CreatePipelineLayouts(const Device& device) {
m_pipeline_layout = CreateWrappedPipelineLayout(device, m_descriptor_set_layout);
}
void FXAA::CreatePipelines() {
m_pipeline = CreateWrappedPipeline(m_device, m_renderpass, m_pipeline_layout,
void FXAA::CreatePipelines(const Device& device) {
m_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
std::tie(m_vertex_shader, m_fragment_shader));
}
void FXAA::UpdateDescriptorSets(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];
std::vector<VkDescriptorImageInfo> image_infos;
std::vector<VkWriteDescriptorSet> updates;
image_infos.reserve(2);
updates.push_back(
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 0));
updates.push_back(
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 1));
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 0));
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, image.descriptor_sets[0], 1));
m_device.GetLogical().UpdateDescriptorSets(updates, {});
device.GetLogical().UpdateDescriptorSets(updates, {});
}
void FXAA::UploadImages(Scheduler& scheduler) {
void FXAA::UploadImages(const Device& device, Scheduler& scheduler) {
if (m_images_ready) {
return;
}
@ -114,8 +111,7 @@ void FXAA::UploadImages(Scheduler& scheduler) {
m_images_ready = true;
}
void FXAA::Draw(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 output_image{*image.image};
@ -126,8 +122,8 @@ void FXAA::Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image,
const VkPipelineLayout layout{*m_pipeline_layout};
const VkExtent2D extent{m_extent};
UploadImages(scheduler);
UpdateDescriptorSets(*inout_image_view, image_index);
UploadImages(device, scheduler);
UpdateDescriptorSets(device, *inout_image_view, image_index);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([=](vk::CommandBuffer cmdbuf) {

View file

@ -15,38 +15,23 @@ class StagingBufferPool;
class FXAA final : public AntiAliasPass {
public:
explicit FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
VkExtent2D extent);
explicit FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count, VkExtent2D extent);
~FXAA() override;
void Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image,
VkImageView* inout_image_view) override;
void Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) override;
private:
void CreateImages();
void CreateRenderPasses();
void CreateSampler();
void CreateShaders();
void CreateDescriptorPool();
void CreateDescriptorSetLayouts();
void CreateDescriptorSets();
void CreatePipelineLayouts();
void CreatePipelines();
void UpdateDescriptorSets(VkImageView image_view, size_t image_index);
void UploadImages(Scheduler& scheduler);
const Device& m_device;
MemoryAllocator& m_allocator;
const VkExtent2D m_extent;
const u32 m_image_count;
vk::ShaderModule m_vertex_shader{};
vk::ShaderModule m_fragment_shader{};
vk::DescriptorPool m_descriptor_pool{};
vk::DescriptorSetLayout m_descriptor_set_layout{};
vk::PipelineLayout m_pipeline_layout{};
vk::Pipeline m_pipeline{};
vk::RenderPass m_renderpass{};
void CreateImages(const Device& device, MemoryAllocator& allocator);
void CreateRenderPasses(const Device& device);
void CreateSampler(const Device& device);
void CreateShaders(const Device& device);
void CreateDescriptorPool(const Device& device);
void CreateDescriptorSetLayouts(const Device& device);
void CreateDescriptorSets(const Device& device);
void CreatePipelineLayouts(const Device& device);
void CreatePipelines(const Device& device);
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
void UploadImages(const Device& device, Scheduler& scheduler);
struct Image {
vk::DescriptorSets descriptor_sets{};
@ -55,9 +40,17 @@ private:
vk::ImageView image_view{};
};
std::vector<Image> m_dynamic_images{};
bool m_images_ready{};
const VkExtent2D m_extent;
const u32 m_image_count;
vk::ShaderModule m_vertex_shader{};
vk::ShaderModule m_fragment_shader{};
vk::DescriptorPool m_descriptor_pool{};
vk::DescriptorSetLayout m_descriptor_set_layout{};
vk::PipelineLayout m_pipeline_layout{};
vk::Pipeline m_pipeline{};
vk::RenderPass m_renderpass{};
vk::Sampler m_sampler{};
bool m_images_ready{};
};
} // namespace Vulkan

View file

@ -108,9 +108,9 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants,
texture_info ? texture_info->image_view : *raw_image_views[image_index];
if (auto* fxaa = std::get_if<FXAA>(&anti_alias)) {
fxaa->Draw(scheduler, image_index, &source_image, &source_image_view);
fxaa->Draw(device, scheduler, image_index, &source_image, &source_image_view);
} else if (auto* smaa = std::get_if<SMAA>(&anti_alias)) {
smaa->Draw(scheduler, image_index, &source_image, &source_image_view);
smaa->Draw(device, scheduler, image_index, &source_image, &source_image_view);
}
auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height);
@ -120,10 +120,10 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants,
};
if (auto* fsr = std::get_if<FSR>(&sr_filter)) {
source_image_view = fsr->Draw(scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
source_image_view = fsr->Draw(device, scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
crop_rect = {0, 0, 1, 1};
} else if (auto* sgsr = std::get_if<SGSR>(&sr_filter)) {
source_image_view = sgsr->Draw(scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
source_image_view = sgsr->Draw(device, scheduler, image_index, source_image, source_image_view, render_extent, crop_rect);
crop_rect = {0, 0, 1, 1};
}

View file

@ -20,8 +20,7 @@ namespace Vulkan {
using PushConstants = std::array<u32, 4 + 2 + 1>;
SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, VkExtent2D extent, bool edge_dir)
: m_device{device}
, m_memory_allocator{memory_allocator}
: m_memory_allocator{memory_allocator}
, m_image_count{image_count}
, m_extent{extent}
, m_edge_dir{edge_dir}
@ -30,21 +29,21 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image
m_dynamic_images.resize(m_image_count);
for (auto& images : m_dynamic_images) {
images.image = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_view = CreateWrappedImageView(m_device, images.image, VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_view = CreateWrappedImageView(device, images.image, VK_FORMAT_R16G16B16A16_SFLOAT);
}
m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
for (auto& images : m_dynamic_images)
images.framebuffer = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_view, m_extent);
images.framebuffer = CreateWrappedFramebuffer(device, m_renderpass, images.image_view, m_extent);
m_sampler = CreateBilinearSampler(m_device);
m_vert_shader = BuildShader(m_device, SGSR1_SHADER_VERT_SPV);
m_sampler = CreateBilinearSampler(device);
m_vert_shader = BuildShader(device, SGSR1_SHADER_VERT_SPV);
m_stage_shader = m_edge_dir
? BuildShader(m_device, SGSR1_SHADER_MOBILE_EDGE_DIRECTION_FRAG_SPV)
: BuildShader(m_device, SGSR1_SHADER_MOBILE_FRAG_SPV);
? BuildShader(device, SGSR1_SHADER_MOBILE_EDGE_DIRECTION_FRAG_SPV)
: BuildShader(device, SGSR1_SHADER_MOBILE_FRAG_SPV);
// 2 descriptors, 2 descriptor sets per invocation
m_descriptor_pool = CreateWrappedDescriptorPool(m_device, m_image_count, m_image_count);
m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
m_descriptor_pool = CreateWrappedDescriptorPool(device, m_image_count, m_image_count);
m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
VkDescriptorSetLayout layout = *m_descriptor_set_layout;
for (auto& images : m_dynamic_images)
@ -64,20 +63,20 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image
.pushConstantRangeCount = 1,
.pPushConstantRanges = &range,
};
m_pipeline_layout = m_device.GetLogical().CreatePipelineLayout(ci);
m_stage_pipeline = CreateWrappedPipeline(m_device, m_renderpass, m_pipeline_layout, std::tie(m_vert_shader, m_stage_shader));
m_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
m_stage_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout, std::tie(m_vert_shader, m_stage_shader));
}
void SGSR::UpdateDescriptorSets(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<VkWriteDescriptorSet> updates;
image_infos.reserve(1);
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[0], 0));
m_device.GetLogical().UpdateDescriptorSets(updates, {});
device.GetLogical().UpdateDescriptorSets(updates, {});
}
void SGSR::UploadImages(Scheduler& scheduler) {
void SGSR::UploadImages(const Device& device, Scheduler& scheduler) {
if (!m_images_ready) {
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
for (auto& image : m_dynamic_images)
@ -88,7 +87,7 @@ void SGSR::UploadImages(Scheduler& scheduler) {
}
}
VkImageView SGSR::Draw(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 = *images.image;
auto const descriptor_set = images.descriptor_sets[0];
@ -122,8 +121,8 @@ VkImageView SGSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_
viewport_con[5] = std::bit_cast<u32>(viewport_height / input_image_height);
viewport_con[6] = std::bit_cast<u32>(sharpening);
UploadImages(scheduler);
UpdateDescriptorSets(source_image_view, image_index);
UploadImages(device, scheduler);
UpdateDescriptorSets(device, source_image_view, image_index);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([=](vk::CommandBuffer cmdbuf) {

View file

@ -16,13 +16,12 @@ class SGSR {
public:
static constexpr size_t SGSR_STAGE_COUNT = 1;
explicit SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, VkExtent2D extent, bool edge_dir);
VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImage source_image, VkImageView source_image_view, VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect);
VkImageView 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);
private:
void Initialize();
void UploadImages(Scheduler& scheduler);
void UpdateDescriptorSets(VkImageView image_view, size_t image_index);
void Initialize(const Device& device);
void UploadImages(const Device& device, Scheduler& scheduler);
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
const Device& m_device;
MemoryAllocator& m_memory_allocator;
const size_t m_image_count;
const VkExtent2D m_extent;

View file

@ -27,22 +27,24 @@
namespace Vulkan {
SMAA::SMAA(const Device& device, MemoryAllocator& allocator, size_t image_count, VkExtent2D extent)
: m_device(device), m_allocator(allocator), m_extent(extent),
m_image_count(static_cast<u32>(image_count)) {
CreateImages();
CreateRenderPasses();
CreateSampler();
CreateShaders();
CreateDescriptorPool();
CreateDescriptorSetLayouts();
CreateDescriptorSets();
CreatePipelineLayouts();
CreatePipelines();
: m_allocator(allocator)
, m_extent(extent)
, m_image_count(u32(image_count))
{
CreateImages(device);
CreateRenderPasses(device);
CreateSampler(device);
CreateShaders(device);
CreateDescriptorPool(device);
CreateDescriptorSetLayouts(device);
CreateDescriptorSets(device);
CreatePipelineLayouts(device);
CreatePipelines(device);
}
SMAA::~SMAA() = default;
void SMAA::CreateImages() {
void SMAA::CreateImages(const Device& device) {
static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
@ -50,9 +52,9 @@ void SMAA::CreateImages() {
m_static_images[Search] = CreateWrappedImage(m_allocator, search_extent, VK_FORMAT_R8_UNORM);
m_static_image_views[Area] =
CreateWrappedImageView(m_device, m_static_images[Area], VK_FORMAT_R8G8_UNORM);
CreateWrappedImageView(device, m_static_images[Area], VK_FORMAT_R8G8_UNORM);
m_static_image_views[Search] =
CreateWrappedImageView(m_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++) {
Images& images = m_dynamic_images.emplace_back();
@ -64,39 +66,39 @@ void SMAA::CreateImages() {
CreateWrappedImage(m_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_views[Blend] =
CreateWrappedImageView(m_device, images.images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT);
CreateWrappedImageView(device, images.images[Blend], VK_FORMAT_R16G16B16A16_SFLOAT);
images.image_views[Edges] =
CreateWrappedImageView(m_device, images.images[Edges], VK_FORMAT_R16G16_SFLOAT);
CreateWrappedImageView(device, images.images[Edges], VK_FORMAT_R16G16_SFLOAT);
images.image_views[Output] =
CreateWrappedImageView(m_device, images.images[Output], VK_FORMAT_R16G16B16A16_SFLOAT);
CreateWrappedImageView(device, images.images[Output], VK_FORMAT_R16G16B16A16_SFLOAT);
}
}
void SMAA::CreateRenderPasses() {
m_renderpasses[EdgeDetection] = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16_SFLOAT);
void SMAA::CreateRenderPasses(const Device& device) {
m_renderpasses[EdgeDetection] = CreateWrappedRenderPass(device, VK_FORMAT_R16G16_SFLOAT);
m_renderpasses[BlendingWeightCalculation] =
CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
m_renderpasses[NeighborhoodBlending] =
CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
for (auto& images : m_dynamic_images) {
images.framebuffers[EdgeDetection] = CreateWrappedFramebuffer(
m_device, m_renderpasses[EdgeDetection], images.image_views[Edges], m_extent);
device, m_renderpasses[EdgeDetection], images.image_views[Edges], m_extent);
images.framebuffers[BlendingWeightCalculation] =
CreateWrappedFramebuffer(m_device, m_renderpasses[BlendingWeightCalculation],
CreateWrappedFramebuffer(device, m_renderpasses[BlendingWeightCalculation],
images.image_views[Blend], m_extent);
images.framebuffers[NeighborhoodBlending] = CreateWrappedFramebuffer(
m_device, m_renderpasses[NeighborhoodBlending], images.image_views[Output], m_extent);
device, m_renderpasses[NeighborhoodBlending], images.image_views[Output], m_extent);
}
}
void SMAA::CreateSampler() {
m_sampler = CreateWrappedSampler(m_device);
void SMAA::CreateSampler(const Device& device) {
m_sampler = CreateWrappedSampler(device);
}
void SMAA::CreateShaders() {
void SMAA::CreateShaders(const Device& device) {
// These match the order of the SMAAStage enum
static constexpr std::array vert_shader_sources{
ARRAY_TO_SPAN(SMAA_EDGE_DETECTION_VERT_SPV),
@ -110,33 +112,33 @@ void SMAA::CreateShaders() {
};
for (size_t i = 0; i < MaxSMAAStage; i++) {
m_vertex_shaders[i] = CreateWrappedShaderModule(m_device, vert_shader_sources[i]);
m_fragment_shaders[i] = CreateWrappedShaderModule(m_device, frag_shader_sources[i]);
m_vertex_shaders[i] = CreateWrappedShaderModule(device, vert_shader_sources[i]);
m_fragment_shaders[i] = CreateWrappedShaderModule(device, frag_shader_sources[i]);
}
}
void SMAA::CreateDescriptorPool() {
void SMAA::CreateDescriptorPool(const Device& device) {
// Edge detection: 1 descriptor
// Blending weight calculation: 3 descriptors
// Neighborhood blending: 2 descriptors
// 6 descriptors, 3 descriptor sets per image
m_descriptor_pool = CreateWrappedDescriptorPool(m_device, 6 * m_image_count, 3 * m_image_count);
m_descriptor_pool = CreateWrappedDescriptorPool(device, 6 * m_image_count, 3 * m_image_count);
}
void SMAA::CreateDescriptorSetLayouts() {
void SMAA::CreateDescriptorSetLayouts(const Device& device) {
m_descriptor_set_layouts[EdgeDetection] =
CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
m_descriptor_set_layouts[BlendingWeightCalculation] =
CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
m_descriptor_set_layouts[NeighborhoodBlending] =
CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
}
void SMAA::CreateDescriptorSets() {
void SMAA::CreateDescriptorSets(const Device& device) {
std::vector<VkDescriptorSetLayout> layouts(m_descriptor_set_layouts.size());
std::ranges::transform(m_descriptor_set_layouts, layouts.begin(),
[](auto& layout) { return *layout; });
@ -146,21 +148,21 @@ void SMAA::CreateDescriptorSets() {
}
}
void SMAA::CreatePipelineLayouts() {
void SMAA::CreatePipelineLayouts(const Device& device) {
for (size_t i = 0; i < MaxSMAAStage; i++) {
m_pipeline_layouts[i] = CreateWrappedPipelineLayout(m_device, m_descriptor_set_layouts[i]);
m_pipeline_layouts[i] = CreateWrappedPipelineLayout(device, m_descriptor_set_layouts[i]);
}
}
void SMAA::CreatePipelines() {
void SMAA::CreatePipelines(const Device& device) {
for (size_t i = 0; i < MaxSMAAStage; i++) {
m_pipelines[i] =
CreateWrappedPipeline(m_device, m_renderpasses[i], m_pipeline_layouts[i],
CreateWrappedPipeline(device, m_renderpasses[i], m_pipeline_layouts[i],
std::tie(m_vertex_shaders[i], m_fragment_shaders[i]));
}
}
void SMAA::UpdateDescriptorSets(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];
std::vector<VkDescriptorImageInfo> image_infos;
std::vector<VkWriteDescriptorSet> updates;
@ -184,10 +186,10 @@ void SMAA::UpdateDescriptorSets(VkImageView image_view, size_t image_index) {
updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Blend],
images.descriptor_sets[NeighborhoodBlending], 1));
m_device.GetLogical().UpdateDescriptorSets(updates, {});
device.GetLogical().UpdateDescriptorSets(updates, {});
}
void SMAA::UploadImages(Scheduler& scheduler) {
void SMAA::UploadImages(const Device& device, Scheduler& scheduler) {
if (m_images_ready) {
return;
}
@ -195,9 +197,9 @@ void SMAA::UploadImages(Scheduler& scheduler) {
static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
UploadImage(m_device, m_allocator, scheduler, m_static_images[Area], area_extent,
UploadImage(device, m_allocator, scheduler, m_static_images[Area], area_extent,
VK_FORMAT_R8G8_UNORM, ARRAY_TO_SPAN(areaTexBytes));
UploadImage(m_device, m_allocator, scheduler, m_static_images[Search], search_extent,
UploadImage(device, m_allocator, scheduler, m_static_images[Search], search_extent,
VK_FORMAT_R8_UNORM, ARRAY_TO_SPAN(searchTexBytes));
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
@ -212,8 +214,7 @@ void SMAA::UploadImages(Scheduler& scheduler) {
m_images_ready = true;
}
void SMAA::Draw(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];
VkImage input_image = *inout_image;
@ -232,8 +233,8 @@ void SMAA::Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image,
*images.framebuffers[BlendingWeightCalculation];
VkFramebuffer neighborhood_blending_framebuffer = *images.framebuffers[NeighborhoodBlending];
UploadImages(scheduler);
UpdateDescriptorSets(*inout_image_view, image_index);
UploadImages(device, scheduler);
UpdateDescriptorSets(device, *inout_image_view, image_index);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([=, this](vk::CommandBuffer cmdbuf) {

View file

@ -16,11 +16,10 @@ class StagingBufferPool;
class SMAA final : public AntiAliasPass {
public:
explicit SMAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
VkExtent2D extent);
explicit SMAA(const Device& device, MemoryAllocator& allocator, size_t image_count, VkExtent2D extent);
~SMAA() override;
void Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image,
void Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image,
VkImageView* inout_image_view) override;
private:
@ -44,19 +43,18 @@ private:
MaxDynamicImage = 3,
};
void CreateImages();
void CreateRenderPasses();
void CreateSampler();
void CreateShaders();
void CreateDescriptorPool();
void CreateDescriptorSetLayouts();
void CreateDescriptorSets();
void CreatePipelineLayouts();
void CreatePipelines();
void UpdateDescriptorSets(VkImageView image_view, size_t image_index);
void UploadImages(Scheduler& scheduler);
void CreateImages(const Device& device);
void CreateRenderPasses(const Device& device);
void CreateSampler(const Device& device);
void CreateShaders(const Device& device);
void CreateDescriptorPool(const Device& device);
void CreateDescriptorSetLayouts(const Device& device);
void CreateDescriptorSets(const Device& device);
void CreatePipelineLayouts(const Device& device);
void CreatePipelines(const Device& device);
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
void UploadImages(const Device& device, Scheduler& scheduler);
const Device& m_device;
MemoryAllocator& m_allocator;
const VkExtent2D m_extent;
const u32 m_image_count;