mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-08 06:36:01 +00:00
[video_core, hle] remove redundant parent references in system structs (#3908)
reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: maufeat <sahyno1996@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -14,27 +17,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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -14,61 +17,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 +78,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 +114,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 +125,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) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -15,38 +18,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 +43,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
|
||||
|
||||
@@ -56,13 +56,15 @@ VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) {
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, size_t image_count_,
|
||||
VkExtent2D output_size, VkDescriptorSetLayout layout, const PresentFilters& filters_)
|
||||
: device(device_), memory_allocator(memory_allocator_), scheduler(scheduler_),
|
||||
device_memory(device_memory_), filters(filters_), image_count(image_count_) {
|
||||
CreateDescriptorPool();
|
||||
CreateDescriptorSets(layout);
|
||||
Layer::Layer(const Device& device, MemoryAllocator& memory_allocator_, Scheduler& scheduler_, Tegra::MaxwellDeviceMemoryManager& device_memory_, size_t image_count_, VkExtent2D output_size, VkDescriptorSetLayout layout, const PresentFilters& filters_)
|
||||
: memory_allocator(memory_allocator_)
|
||||
, scheduler(scheduler_)
|
||||
, device_memory(device_memory_)
|
||||
, filters(filters_)
|
||||
, image_count(image_count_)
|
||||
{
|
||||
CreateDescriptorPool(device);
|
||||
CreateDescriptorSets(device, layout);
|
||||
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
|
||||
sr_filter.emplace<FSR>(device, memory_allocator, image_count, output_size);
|
||||
} else if (filters.get_scaling_filter() == Settings::ScalingFilter::Sgsr) {
|
||||
@@ -76,7 +78,7 @@ Layer::~Layer() {
|
||||
ReleaseRawImages();
|
||||
}
|
||||
|
||||
void Layer::ConfigureDraw(PresentPushConstants* out_push_constants,
|
||||
void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_constants,
|
||||
VkDescriptorSet* out_descriptor_set, RasterizerVulkan& rasterizer,
|
||||
VkSampler sampler, size_t image_index,
|
||||
const Tegra::FramebufferConfig& framebuffer,
|
||||
@@ -89,8 +91,8 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants,
|
||||
const u32 scaled_height = texture_info ? texture_info->scaled_height : texture_height;
|
||||
const bool use_accelerated = texture_info.has_value();
|
||||
|
||||
RefreshResources(framebuffer);
|
||||
SetAntiAliasPass();
|
||||
RefreshResources(device, framebuffer);
|
||||
SetAntiAliasPass(device);
|
||||
|
||||
// Finish any pending renderpass
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
@@ -108,9 +110,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,30 +122,30 @@ 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};
|
||||
}
|
||||
|
||||
SetMatrixData(*out_push_constants, layout);
|
||||
SetVertexData(*out_push_constants, layout, crop_rect);
|
||||
SetMatrixData(device, *out_push_constants, layout);
|
||||
SetVertexData(device, *out_push_constants, layout, crop_rect);
|
||||
|
||||
UpdateDescriptorSet(source_image_view, sampler, image_index);
|
||||
UpdateDescriptorSet(device, source_image_view, sampler, image_index);
|
||||
*out_descriptor_set = descriptor_sets[image_index];
|
||||
}
|
||||
|
||||
void Layer::CreateDescriptorPool() {
|
||||
void Layer::CreateDescriptorPool(const Device& device) {
|
||||
descriptor_pool = CreateWrappedDescriptorPool(device, image_count, image_count);
|
||||
}
|
||||
|
||||
void Layer::CreateDescriptorSets(VkDescriptorSetLayout layout) {
|
||||
void Layer::CreateDescriptorSets(const Device& device, VkDescriptorSetLayout layout) {
|
||||
const std::vector layouts(image_count, layout);
|
||||
descriptor_sets = CreateWrappedDescriptorSets(descriptor_pool, layouts);
|
||||
}
|
||||
|
||||
void Layer::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) {
|
||||
void Layer::CreateStagingBuffer(const Device& device, const Tegra::FramebufferConfig& framebuffer) {
|
||||
const VkBufferCreateInfo ci{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -159,7 +161,7 @@ void Layer::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) {
|
||||
buffer = memory_allocator.CreateBuffer(ci, MemoryUsage::Upload);
|
||||
}
|
||||
|
||||
void Layer::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||
void Layer::CreateRawImages(const Device& device, const Tegra::FramebufferConfig& framebuffer) {
|
||||
const auto format = GetFormat(framebuffer);
|
||||
resource_ticks.resize(image_count);
|
||||
raw_images.resize(image_count);
|
||||
@@ -172,7 +174,7 @@ void Layer::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
|
||||
void Layer::RefreshResources(const Device& device, const Tegra::FramebufferConfig& framebuffer) {
|
||||
if (framebuffer.width == raw_width && framebuffer.height == raw_height &&
|
||||
framebuffer.pixel_format == pixel_format && !raw_images.empty()) {
|
||||
return;
|
||||
@@ -184,11 +186,11 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
|
||||
anti_alias.emplace<std::monostate>();
|
||||
|
||||
ReleaseRawImages();
|
||||
CreateStagingBuffer(framebuffer);
|
||||
CreateRawImages(framebuffer);
|
||||
CreateStagingBuffer(device, framebuffer);
|
||||
CreateRawImages(device, framebuffer);
|
||||
}
|
||||
|
||||
void Layer::SetAntiAliasPass() {
|
||||
void Layer::SetAntiAliasPass(const Device& device) {
|
||||
if (!std::holds_alternative<std::monostate>(anti_alias) && anti_alias_setting == filters.get_anti_aliasing())
|
||||
return;
|
||||
|
||||
@@ -229,20 +231,17 @@ u64 Layer::GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer,
|
||||
return GetSizeInBytes(framebuffer) * image_index;
|
||||
}
|
||||
|
||||
void Layer::SetMatrixData(PresentPushConstants& data,
|
||||
const Layout::FramebufferLayout& layout) const {
|
||||
data.modelview_matrix =
|
||||
MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height));
|
||||
void Layer::SetMatrixData(const Device& device, PresentPushConstants& data, const Layout::FramebufferLayout& layout) const {
|
||||
data.modelview_matrix = MakeOrthographicMatrix(f32(layout.width), static_cast<f32>(layout.height));
|
||||
}
|
||||
|
||||
void Layer::SetVertexData(PresentPushConstants& data, const Layout::FramebufferLayout& layout,
|
||||
const Common::Rectangle<f32>& crop) const {
|
||||
void Layer::SetVertexData(const Device& device, PresentPushConstants& data, const Layout::FramebufferLayout& layout, const Common::Rectangle<f32>& crop) const {
|
||||
// Map the coordinates to the screen.
|
||||
const auto& screen = layout.screen;
|
||||
const auto x = static_cast<f32>(screen.left);
|
||||
const auto y = static_cast<f32>(screen.top);
|
||||
const auto w = static_cast<f32>(screen.GetWidth());
|
||||
const auto h = static_cast<f32>(screen.GetHeight());
|
||||
const auto x = f32(screen.left);
|
||||
const auto y = f32(screen.top);
|
||||
const auto w = f32(screen.GetWidth());
|
||||
const auto h = f32(screen.GetHeight());
|
||||
|
||||
data.vertices[0] = ScreenRectVertex(x, y, crop.left, crop.top);
|
||||
data.vertices[1] = ScreenRectVertex(x + w, y, crop.right, crop.top);
|
||||
@@ -250,7 +249,7 @@ void Layer::SetVertexData(PresentPushConstants& data, const Layout::FramebufferL
|
||||
data.vertices[3] = ScreenRectVertex(x + w, y + h, crop.right, crop.bottom);
|
||||
}
|
||||
|
||||
void Layer::UpdateDescriptorSet(VkImageView image_view, VkSampler sampler, size_t image_index) {
|
||||
void Layer::UpdateDescriptorSet(const Device& device, VkImageView image_view, VkSampler sampler, size_t image_index) {
|
||||
const VkDescriptorImageInfo image_info{
|
||||
.sampler = sampler,
|
||||
.imageView = image_view,
|
||||
|
||||
@@ -52,33 +52,31 @@ public:
|
||||
const PresentFilters& filters);
|
||||
~Layer();
|
||||
|
||||
void ConfigureDraw(PresentPushConstants* out_push_constants,
|
||||
void ConfigureDraw(const Device& device, PresentPushConstants* out_push_constants,
|
||||
VkDescriptorSet* out_descriptor_set, RasterizerVulkan& rasterizer,
|
||||
VkSampler sampler, size_t image_index,
|
||||
const Tegra::FramebufferConfig& framebuffer,
|
||||
const Layout::FramebufferLayout& layout);
|
||||
|
||||
private:
|
||||
void CreateDescriptorPool();
|
||||
void CreateDescriptorSets(VkDescriptorSetLayout layout);
|
||||
void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer);
|
||||
void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
|
||||
void CreateDescriptorPool(const Device& device);
|
||||
void CreateDescriptorSets(const Device& device, VkDescriptorSetLayout layout);
|
||||
void CreateStagingBuffer(const Device& device, const Tegra::FramebufferConfig& framebuffer);
|
||||
void CreateRawImages(const Device& device, const Tegra::FramebufferConfig& framebuffer);
|
||||
|
||||
void RefreshResources(const Tegra::FramebufferConfig& framebuffer);
|
||||
void SetAntiAliasPass();
|
||||
void RefreshResources(const Device& device, const Tegra::FramebufferConfig& framebuffer);
|
||||
void SetAntiAliasPass(const Device& device);
|
||||
void ReleaseRawImages();
|
||||
|
||||
u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const;
|
||||
u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, size_t image_index) const;
|
||||
|
||||
void SetMatrixData(PresentPushConstants& data, const Layout::FramebufferLayout& layout) const;
|
||||
void SetVertexData(PresentPushConstants& data, const Layout::FramebufferLayout& layout,
|
||||
const Common::Rectangle<f32>& crop) const;
|
||||
void UpdateDescriptorSet(VkImageView image_view, VkSampler sampler, size_t image_index);
|
||||
void SetMatrixData(const Device& device, PresentPushConstants& data, const Layout::FramebufferLayout& layout) const;
|
||||
void SetVertexData(const Device& device, PresentPushConstants& data, const Layout::FramebufferLayout& layout, const Common::Rectangle<f32>& crop) const;
|
||||
void UpdateDescriptorSet(const Device& device, VkImageView image_view, VkSampler sampler, size_t image_index);
|
||||
void UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t image_index);
|
||||
|
||||
private:
|
||||
const Device& device;
|
||||
MemoryAllocator& memory_allocator;
|
||||
Scheduler& scheduler;
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -16,11 +19,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 +46,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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -15,19 +18,20 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
WindowAdaptPass::WindowAdaptPass(const Device& device_, VkFormat frame_format,
|
||||
vk::Sampler&& sampler_, vk::ShaderModule&& fragment_shader_)
|
||||
: device(device_), sampler(std::move(sampler_)), fragment_shader(std::move(fragment_shader_)) {
|
||||
CreateDescriptorSetLayout();
|
||||
CreatePipelineLayout();
|
||||
CreateVertexShader();
|
||||
CreateRenderPass(frame_format);
|
||||
CreatePipelines();
|
||||
WindowAdaptPass::WindowAdaptPass(const Device& device, VkFormat frame_format, vk::Sampler&& sampler_, vk::ShaderModule&& fragment_shader_)
|
||||
: sampler(std::move(sampler_))
|
||||
, fragment_shader(std::move(fragment_shader_))
|
||||
{
|
||||
CreateDescriptorSetLayout(device);
|
||||
CreatePipelineLayout(device);
|
||||
CreateVertexShader(device);
|
||||
CreateRenderPass(device, frame_format);
|
||||
CreatePipelines(device);
|
||||
}
|
||||
|
||||
WindowAdaptPass::~WindowAdaptPass() = default;
|
||||
|
||||
void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, size_t image_index,
|
||||
void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, Scheduler& scheduler, size_t image_index,
|
||||
std::list<Layer>& layers,
|
||||
std::span<const Tegra::FramebufferConfig> configs,
|
||||
const Layout::FramebufferLayout& layout, Frame* dst) {
|
||||
@@ -60,7 +64,7 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
||||
break;
|
||||
}
|
||||
|
||||
layer_it->ConfigureDraw(&push_constants[i], &descriptor_sets[i], rasterizer, *sampler,
|
||||
layer_it->ConfigureDraw(device, &push_constants[i], &descriptor_sets[i], rasterizer, *sampler,
|
||||
image_index, configs[i], layout);
|
||||
layer_it++;
|
||||
}
|
||||
@@ -111,12 +115,12 @@ VkRenderPass WindowAdaptPass::GetRenderPass() {
|
||||
return *render_pass;
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreateDescriptorSetLayout() {
|
||||
void WindowAdaptPass::CreateDescriptorSetLayout(const Device& device) {
|
||||
descriptor_set_layout =
|
||||
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreatePipelineLayout() {
|
||||
void WindowAdaptPass::CreatePipelineLayout(const Device& device) {
|
||||
const VkPushConstantRange range{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
@@ -134,15 +138,15 @@ void WindowAdaptPass::CreatePipelineLayout() {
|
||||
});
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreateVertexShader() {
|
||||
void WindowAdaptPass::CreateVertexShader(const Device& device) {
|
||||
vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV);
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreateRenderPass(VkFormat frame_format) {
|
||||
void WindowAdaptPass::CreateRenderPass(const Device& device, VkFormat frame_format) {
|
||||
render_pass = CreateWrappedRenderPass(device, frame_format, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreatePipelines() {
|
||||
void WindowAdaptPass::CreatePipelines(const Device& device) {
|
||||
opaque_pipeline = CreateWrappedPipeline(device, render_pass, pipeline_layout,
|
||||
std::tie(vertex_shader, fragment_shader));
|
||||
premultiplied_pipeline = CreateWrappedPremultipliedBlendingPipeline(
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -30,7 +33,7 @@ public:
|
||||
vk::ShaderModule&& fragment_shader);
|
||||
~WindowAdaptPass();
|
||||
|
||||
void Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, size_t image_index,
|
||||
void Draw(const Device& device, RasterizerVulkan& rasterizer, Scheduler& scheduler, size_t image_index,
|
||||
std::list<Layer>& layers, std::span<const Tegra::FramebufferConfig> configs,
|
||||
const Layout::FramebufferLayout& layout, Frame* dst);
|
||||
|
||||
@@ -38,14 +41,12 @@ public:
|
||||
VkRenderPass GetRenderPass();
|
||||
|
||||
private:
|
||||
void CreateDescriptorSetLayout();
|
||||
void CreatePipelineLayout();
|
||||
void CreateVertexShader();
|
||||
void CreateRenderPass(VkFormat frame_format);
|
||||
void CreatePipelines();
|
||||
void CreateDescriptorSetLayout(const Device& device);
|
||||
void CreatePipelineLayout(const Device& device);
|
||||
void CreateVertexShader(const Device& device);
|
||||
void CreateRenderPass(const Device& device, VkFormat frame_format);
|
||||
void CreatePipelines(const Device& device);
|
||||
|
||||
private:
|
||||
const Device& device;
|
||||
vk::DescriptorSetLayout descriptor_set_layout;
|
||||
vk::PipelineLayout pipeline_layout;
|
||||
vk::Sampler sampler;
|
||||
|
||||
Reference in New Issue
Block a user