mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-30 07:15:32 +02: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:
parent
f8facda35f
commit
3aa0d46259
307 changed files with 4419 additions and 4477 deletions
|
|
@ -502,9 +502,9 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
|
|||
two_textures_set_layout(device.GetLogical().CreateDescriptorSetLayout(
|
||||
TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)),
|
||||
one_texture_descriptor_allocator{
|
||||
descriptor_pool.Allocator(*one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)},
|
||||
descriptor_pool.Allocator(device_, scheduler_, *one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)},
|
||||
two_textures_descriptor_allocator{
|
||||
descriptor_pool.Allocator(*two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)},
|
||||
descriptor_pool.Allocator(device_, scheduler_, *two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)},
|
||||
one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
|
||||
one_texture_set_layout.address(),
|
||||
PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstants)>))),
|
||||
|
|
|
|||
|
|
@ -31,14 +31,13 @@ static u64 GetUint64(const VkPipelineExecutableStatisticKHR& statistic) {
|
|||
}
|
||||
}
|
||||
|
||||
PipelineStatistics::PipelineStatistics(const Device& device_) : device{device_} {}
|
||||
PipelineStatistics::PipelineStatistics(const Device& device_) {}
|
||||
|
||||
void PipelineStatistics::Collect(VkPipeline pipeline) {
|
||||
const auto& dev{device.GetLogical()};
|
||||
const std::vector properties{dev.GetPipelineExecutablePropertiesKHR(pipeline)};
|
||||
void PipelineStatistics::Collect(const Device& device, VkPipeline pipeline) {
|
||||
const std::vector properties{device.GetLogical().GetPipelineExecutablePropertiesKHR(pipeline)};
|
||||
const u32 num_executables{static_cast<u32>(properties.size())};
|
||||
for (u32 executable = 0; executable < num_executables; ++executable) {
|
||||
const auto statistics{dev.GetPipelineExecutableStatisticsKHR(pipeline, executable)};
|
||||
const auto statistics{device.GetLogical().GetPipelineExecutableStatisticsKHR(pipeline, executable)};
|
||||
if (statistics.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -16,9 +19,7 @@ class Device;
|
|||
class PipelineStatistics {
|
||||
public:
|
||||
explicit PipelineStatistics(const Device& device_);
|
||||
|
||||
void Collect(VkPipeline pipeline);
|
||||
|
||||
void Collect(const Device& device, VkPipeline pipeline);
|
||||
void Report() const;
|
||||
|
||||
private:
|
||||
|
|
@ -30,8 +31,6 @@ private:
|
|||
u64 branches_count{};
|
||||
u64 basic_block_count{};
|
||||
};
|
||||
|
||||
const Device& device;
|
||||
mutable std::mutex mutex;
|
||||
std::vector<Stats> collected_stats;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebu
|
|||
Frame* frame = present_manager.GetRenderFrame();
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
blit_swapchain.DrawToFrame(rasterizer, frame, framebuffers,
|
||||
blit_swapchain.DrawToFrame(device, rasterizer, frame, framebuffers,
|
||||
render_window.GetFramebufferLayout(), swapchain.GetImageCount(),
|
||||
swapchain.GetImageViewFormat());
|
||||
scheduler.Flush(*frame->render_ready);
|
||||
|
|
@ -226,12 +226,12 @@ vk::Buffer RendererVulkan::RenderToBuffer(std::span<const Tegra::FramebufferConf
|
|||
f.image =
|
||||
CreateWrappedImage(memory_allocator, VkExtent2D{layout.width, layout.height}, format);
|
||||
f.image_view = CreateWrappedImageView(device, f.image, format);
|
||||
f.framebuffer = blit_capture.CreateFramebuffer(layout, *f.image_view, format);
|
||||
f.framebuffer = blit_capture.CreateFramebuffer(device, layout, *f.image_view, format);
|
||||
return f;
|
||||
}();
|
||||
|
||||
auto dst_buffer = CreateWrappedBuffer(memory_allocator, buffer_size, MemoryUsage::Download);
|
||||
blit_capture.DrawToFrame(rasterizer, &frame, framebuffers, layout, 1, format);
|
||||
blit_capture.DrawToFrame(device, rasterizer, &frame, framebuffers, layout, 1, format);
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
|
||||
|
|
@ -295,12 +295,12 @@ void RendererVulkan::RenderAppletCaptureLayer(
|
|||
if (!applet_frame.image) {
|
||||
applet_frame.image = CreateWrappedImage(memory_allocator, CaptureImageSize, CaptureFormat);
|
||||
applet_frame.image_view = CreateWrappedImageView(device, applet_frame.image, CaptureFormat);
|
||||
applet_frame.framebuffer = blit_applet.CreateFramebuffer(
|
||||
applet_frame.framebuffer = blit_applet.CreateFramebuffer(device,
|
||||
VideoCore::Capture::Layout, *applet_frame.image_view, CaptureFormat);
|
||||
}
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
blit_applet.DrawToFrame(rasterizer, &applet_frame, framebuffers, VideoCore::Capture::Layout, 1,
|
||||
blit_applet.DrawToFrame(device, rasterizer, &applet_frame, framebuffers, VideoCore::Capture::Layout, 1,
|
||||
CaptureFormat);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,23 +18,26 @@
|
|||
|
||||
namespace Vulkan {
|
||||
|
||||
BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const Device& device_,
|
||||
MemoryAllocator& memory_allocator_, PresentManager& present_manager_,
|
||||
Scheduler& scheduler_, const PresentFilters& filters_)
|
||||
: device_memory{device_memory_}, device{device_}, memory_allocator{memory_allocator_},
|
||||
present_manager{present_manager_}, scheduler{scheduler_}, filters{filters_},
|
||||
image_count{1}, image_index{0},
|
||||
swapchain_view_format{VK_FORMAT_B8G8R8A8_UNORM} {}
|
||||
BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const Device& device_, MemoryAllocator& memory_allocator_, PresentManager& present_manager_, Scheduler& scheduler_, const PresentFilters& filters_)
|
||||
: device_memory{device_memory_}
|
||||
, memory_allocator{memory_allocator_}
|
||||
, present_manager{present_manager_}
|
||||
, scheduler{scheduler_}
|
||||
, filters{filters_}
|
||||
, image_count{1}
|
||||
, image_index{0}
|
||||
, swapchain_view_format{VK_FORMAT_B8G8R8A8_UNORM}
|
||||
{}
|
||||
|
||||
BlitScreen::~BlitScreen() = default;
|
||||
|
||||
void BlitScreen::WaitIdle() {
|
||||
void BlitScreen::WaitIdle(const Device& device) {
|
||||
present_manager.WaitPresent();
|
||||
scheduler.Finish();
|
||||
device.GetLogical().WaitIdle();
|
||||
}
|
||||
|
||||
void BlitScreen::SetWindowAdaptPass() {
|
||||
void BlitScreen::SetWindowAdaptPass(const Device& device) {
|
||||
layers.clear();
|
||||
scaling_filter = filters.get_scaling_filter();
|
||||
|
||||
|
|
@ -82,7 +85,7 @@ void BlitScreen::SetWindowAdaptPass() {
|
|||
}
|
||||
}
|
||||
|
||||
void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
|
||||
void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer, Frame* frame,
|
||||
std::span<const Tegra::FramebufferConfig> framebuffers,
|
||||
const Layout::FramebufferLayout& layout,
|
||||
size_t current_swapchain_image_count,
|
||||
|
|
@ -107,8 +110,8 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
|
|||
}
|
||||
|
||||
if (resource_update_required) {
|
||||
WaitIdle();
|
||||
SetWindowAdaptPass();
|
||||
WaitIdle(device);
|
||||
SetWindowAdaptPass(device);
|
||||
|
||||
if (presentation_recreate_required) {
|
||||
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
|
||||
|
|
@ -131,22 +134,22 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
|
|||
}
|
||||
}
|
||||
|
||||
window_adapt->Draw(rasterizer, scheduler, image_index, layers, framebuffers, layout, frame);
|
||||
window_adapt->Draw(device, rasterizer, scheduler, image_index, layers, framebuffers, layout, frame);
|
||||
|
||||
if (++image_index >= image_count) {
|
||||
image_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const Layout::FramebufferLayout& layout,
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const Device& device, const Layout::FramebufferLayout& layout,
|
||||
VkImageView image_view,
|
||||
VkFormat current_view_format) {
|
||||
bool format_updated = swapchain_view_format != current_view_format;
|
||||
swapchain_view_format = current_view_format;
|
||||
|
||||
if (!window_adapt || scaling_filter != filters.get_scaling_filter() || format_updated) {
|
||||
WaitIdle();
|
||||
SetWindowAdaptPass();
|
||||
WaitIdle(device);
|
||||
SetWindowAdaptPass(device);
|
||||
image_index = 0;
|
||||
}
|
||||
|
||||
|
|
@ -155,10 +158,10 @@ vk::Framebuffer BlitScreen::CreateFramebuffer(const Layout::FramebufferLayout& l
|
|||
.height = layout.height,
|
||||
};
|
||||
|
||||
return CreateFramebuffer(image_view, extent, window_adapt->GetRenderPass());
|
||||
return CreateFramebuffer(device, image_view, extent, window_adapt->GetRenderPass());
|
||||
}
|
||||
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent,
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const Device& device, const VkImageView& image_view, VkExtent2D extent,
|
||||
VkRenderPass render_pass) {
|
||||
return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -52,23 +55,22 @@ public:
|
|||
Scheduler& scheduler, const PresentFilters& filters);
|
||||
~BlitScreen();
|
||||
|
||||
void DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
|
||||
void DrawToFrame(const Device& device, RasterizerVulkan& rasterizer, Frame* frame,
|
||||
std::span<const Tegra::FramebufferConfig> framebuffers,
|
||||
const Layout::FramebufferLayout& layout, size_t current_swapchain_image_count,
|
||||
VkFormat current_swapchain_view_format);
|
||||
|
||||
[[nodiscard]] vk::Framebuffer CreateFramebuffer(const Layout::FramebufferLayout& layout,
|
||||
[[nodiscard]] vk::Framebuffer CreateFramebuffer(const Device& device, const Layout::FramebufferLayout& layout,
|
||||
VkImageView image_view,
|
||||
VkFormat current_view_format);
|
||||
|
||||
private:
|
||||
void WaitIdle();
|
||||
void SetWindowAdaptPass();
|
||||
vk::Framebuffer CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent,
|
||||
void WaitIdle(const Device& device);
|
||||
void SetWindowAdaptPass(const Device& device);
|
||||
vk::Framebuffer CreateFramebuffer(const Device& device, const VkImageView& image_view, VkExtent2D extent,
|
||||
VkRenderPass render_pass);
|
||||
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||
const Device& device;
|
||||
MemoryAllocator& memory_allocator;
|
||||
PresentManager& present_manager;
|
||||
Scheduler& scheduler;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ struct ConditionalRenderingResolvePushConstants {
|
|||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
|
||||
ComputePass::ComputePass(const Device& device_, Scheduler& scheduler, DescriptorPool& descriptor_pool,
|
||||
vk::Span<VkDescriptorSetLayoutBinding> bindings,
|
||||
vk::Span<VkDescriptorUpdateTemplateEntry> templates,
|
||||
const DescriptorBankInfo& bank_info,
|
||||
|
|
@ -270,7 +270,7 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
|
|||
.pipelineLayout = *layout,
|
||||
.set = 0,
|
||||
});
|
||||
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, bank_info);
|
||||
descriptor_allocator = descriptor_pool.Allocator(device, scheduler, *descriptor_set_layout, bank_info);
|
||||
}
|
||||
if (code.empty()) {
|
||||
return;
|
||||
|
|
@ -313,7 +313,7 @@ ComputePass::~ComputePass() = default;
|
|||
Uint8Pass::Uint8Pass(const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
: ComputePass(device_, scheduler_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {},
|
||||
VULKAN_UINT8_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
|
|
@ -355,7 +355,7 @@ QuadIndexedPass::QuadIndexedPass(const Device& device_, Scheduler& scheduler_,
|
|||
DescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
: ComputePass(device_, scheduler_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 3>, VULKAN_QUAD_INDEXED_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
|
|
@ -416,7 +416,7 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
|
|||
ConditionalRenderingResolvePass::ConditionalRenderingResolvePass(
|
||||
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
: ComputePass(device_, scheduler_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(ConditionalRenderingResolvePushConstants)>,
|
||||
RESOLVE_CONDITIONAL_RENDER_COMP_SPV),
|
||||
|
|
@ -470,7 +470,7 @@ QueriesPrefixScanPass::QueriesPrefixScanPass(
|
|||
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(
|
||||
device_, descriptor_pool_, QUERIES_SCAN_DESCRIPTOR_SET_BINDINGS,
|
||||
device_, scheduler_, descriptor_pool_, QUERIES_SCAN_DESCRIPTOR_SET_BINDINGS,
|
||||
QUERIES_SCAN_DESCRIPTOR_UPDATE_TEMPLATE, QUERIES_SCAN_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(QueriesPrefixScanPushConstants)>,
|
||||
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_BASIC_BIT) &&
|
||||
|
|
@ -547,7 +547,7 @@ ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_,
|
|||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_,
|
||||
MemoryAllocator& memory_allocator_)
|
||||
: ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS,
|
||||
: ComputePass(device_, scheduler_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS,
|
||||
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
|
|
@ -746,7 +746,7 @@ BlockLinearUnswizzle3DPass::BlockLinearUnswizzle3DPass(
|
|||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(
|
||||
device_, descriptor_pool_,
|
||||
device_, scheduler_, descriptor_pool_,
|
||||
BL3D_DESCRIPTOR_SET_BINDINGS,
|
||||
BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY,
|
||||
BL3D_BANK_INFO,
|
||||
|
|
@ -941,7 +941,7 @@ MSAACopyPass::MSAACopyPass(const Device& device_, Scheduler& scheduler_,
|
|||
DescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, descriptor_pool_, MSAA_DESCRIPTOR_SET_BINDINGS,
|
||||
: ComputePass(device_, scheduler_, descriptor_pool_, MSAA_DESCRIPTOR_SET_BINDINGS,
|
||||
MSAA_DESCRIPTOR_UPDATE_TEMPLATE, MSAA_BANK_INFO, {},
|
||||
CONVERT_NON_MSAA_TO_MSAA_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
|
|
|
|||
|
|
@ -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 2019 yuzu Emulator Project
|
||||
|
|
@ -35,7 +35,7 @@ struct StagingBufferRef;
|
|||
|
||||
class ComputePass {
|
||||
public:
|
||||
explicit ComputePass(const Device& device, DescriptorPool& descriptor_pool,
|
||||
explicit ComputePass(const Device& device, Scheduler& scheduler, DescriptorPool& descriptor_pool,
|
||||
vk::Span<VkDescriptorSetLayoutBinding> bindings,
|
||||
vk::Span<VkDescriptorUpdateTemplateEntry> templates,
|
||||
const DescriptorBankInfo& bank_info,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ using Shader::ImageBufferDescriptor;
|
|||
using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET;
|
||||
using Tegra::Texture::TexturePair;
|
||||
|
||||
ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipeline_cache_,
|
||||
ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk::PipelineCache& pipeline_cache_,
|
||||
DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue_,
|
||||
Common::ThreadWorker* thread_worker,
|
||||
|
|
@ -46,7 +46,7 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
|
|||
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
|
||||
uniform_buffer_sizes.begin());
|
||||
|
||||
auto func{[this, &descriptor_pool, shader_notify, pipeline_statistics] {
|
||||
auto func{[this, &scheduler, &descriptor_pool, shader_notify, pipeline_statistics] {
|
||||
DescriptorLayoutBuilder builder{device};
|
||||
builder.Add(info, VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
|
|||
descriptor_update_template =
|
||||
builder.CreateTemplate(*descriptor_set_layout, *pipeline_layout, uses_push_descriptor);
|
||||
if (!uses_push_descriptor) {
|
||||
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, info);
|
||||
descriptor_allocator = descriptor_pool.Allocator(device, scheduler, *descriptor_set_layout, info);
|
||||
}
|
||||
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT,
|
||||
|
|
@ -94,7 +94,7 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
|
|||
}
|
||||
|
||||
if (pipeline_statistics) {
|
||||
pipeline_statistics->Collect(*pipeline);
|
||||
pipeline_statistics->Collect(device, *pipeline);
|
||||
}
|
||||
std::scoped_lock lock{build_mutex};
|
||||
is_built = true;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class Scheduler;
|
|||
|
||||
class ComputePipeline {
|
||||
public:
|
||||
explicit ComputePipeline(const Device& device, vk::PipelineCache& pipeline_cache,
|
||||
explicit ComputePipeline(const Device& device, Scheduler& scheduler, vk::PipelineCache& pipeline_cache,
|
||||
DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue,
|
||||
Common::ThreadWorker* thread_worker,
|
||||
|
|
|
|||
|
|
@ -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 2019 yuzu Emulator Project
|
||||
|
|
@ -125,27 +125,22 @@ vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) {
|
|||
throw vk::Exception(VK_ERROR_OUT_OF_POOL_MEMORY);
|
||||
}
|
||||
|
||||
DescriptorPool::DescriptorPool(const Device& device_, Scheduler& scheduler)
|
||||
: device{device_}, master_semaphore{scheduler.GetMasterSemaphore()} {}
|
||||
|
||||
DescriptorPool::DescriptorPool(const Device& device_, Scheduler& scheduler) {}
|
||||
DescriptorPool::~DescriptorPool() = default;
|
||||
|
||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||
std::span<const Shader::Info> infos) {
|
||||
return Allocator(layout, MakeBankInfo(infos));
|
||||
DescriptorAllocator DescriptorPool::Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, std::span<const Shader::Info> infos) {
|
||||
return Allocator(device, scheduler, layout, MakeBankInfo(infos));
|
||||
}
|
||||
|
||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||
const Shader::Info& info) {
|
||||
return Allocator(layout, MakeBankInfo(std::array{info}));
|
||||
DescriptorAllocator DescriptorPool::Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, const Shader::Info& info) {
|
||||
return Allocator(device, scheduler, layout, MakeBankInfo(std::array{info}));
|
||||
}
|
||||
|
||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||
const DescriptorBankInfo& info) {
|
||||
return DescriptorAllocator(device, master_semaphore, Bank(info), layout);
|
||||
DescriptorAllocator DescriptorPool::Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, const DescriptorBankInfo& info) {
|
||||
return DescriptorAllocator(device, scheduler.GetMasterSemaphore(), Bank(device, info), layout);
|
||||
}
|
||||
|
||||
DescriptorBank& DescriptorPool::Bank(const DescriptorBankInfo& reqs) {
|
||||
DescriptorBank& DescriptorPool::Bank(const Device& device, const DescriptorBankInfo& reqs) {
|
||||
std::shared_lock read_lock{banks_mutex};
|
||||
const auto it = std::ranges::find_if(bank_infos, [&reqs](const DescriptorBankInfo& bank) {
|
||||
return std::abs(bank.score - reqs.score) < SCORE_THRESHOLD && bank.IsSuperset(reqs);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -68,17 +71,12 @@ public:
|
|||
DescriptorPool& operator=(const DescriptorPool&) = delete;
|
||||
DescriptorPool(const DescriptorPool&) = delete;
|
||||
|
||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout,
|
||||
std::span<const Shader::Info> infos);
|
||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const Shader::Info& info);
|
||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const DescriptorBankInfo& info);
|
||||
DescriptorAllocator Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, std::span<const Shader::Info> infos);
|
||||
DescriptorAllocator Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, const Shader::Info& info);
|
||||
DescriptorAllocator Allocator(const Device& device, Scheduler& scheduler, VkDescriptorSetLayout layout, const DescriptorBankInfo& info);
|
||||
|
||||
private:
|
||||
DescriptorBank& Bank(const DescriptorBankInfo& reqs);
|
||||
|
||||
const Device& device;
|
||||
MasterSemaphore& master_semaphore;
|
||||
|
||||
DescriptorBank& Bank(const Device& device, const DescriptorBankInfo& reqs);
|
||||
std::shared_mutex banks_mutex;
|
||||
std::vector<DescriptorBankInfo> bank_infos;
|
||||
std::vector<std::unique_ptr<DescriptorBank>> banks;
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
descriptor_set_layout = builder.CreateDescriptorSetLayout(uses_push_descriptor);
|
||||
|
||||
if (!uses_push_descriptor) {
|
||||
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, stage_infos);
|
||||
descriptor_allocator = descriptor_pool.Allocator(device, scheduler, *descriptor_set_layout, stage_infos);
|
||||
}
|
||||
|
||||
const VkDescriptorSetLayout set_layout{*descriptor_set_layout};
|
||||
|
|
@ -288,7 +288,7 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
Validate();
|
||||
MakePipeline(render_pass);
|
||||
if (pipeline_statistics) {
|
||||
pipeline_statistics->Collect(*pipeline);
|
||||
pipeline_statistics->Collect(device, *pipeline);
|
||||
}
|
||||
|
||||
std::scoped_lock lock{build_mutex};
|
||||
|
|
|
|||
|
|
@ -915,7 +915,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
|||
spv_module.SetObjectNameEXT(name.c_str());
|
||||
}
|
||||
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
|
||||
return std::make_unique<ComputePipeline>(device, vulkan_pipeline_cache, descriptor_pool,
|
||||
return std::make_unique<ComputePipeline>(device, scheduler, vulkan_pipeline_cache, descriptor_pool,
|
||||
guest_descriptor_queue, thread_worker, statistics,
|
||||
&shader_notify, program.info, std::move(spv_module));
|
||||
|
||||
|
|
|
|||
|
|
@ -126,16 +126,14 @@ public:
|
|||
current_query = nullptr;
|
||||
amend_value = 0;
|
||||
accumulation_value = 0;
|
||||
queries_prefix_scan_pass = std::make_unique<QueriesPrefixScanPass>(
|
||||
device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
queries_prefix_scan_pass.emplace(device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
|
||||
const VkBufferCreateInfo buffer_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = 8,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
|
|
@ -592,8 +590,7 @@ private:
|
|||
VideoCommon::HostQueryBase* current_query;
|
||||
bool has_started{};
|
||||
std::mutex flush_guard;
|
||||
|
||||
std::unique_ptr<QueriesPrefixScanPass> queries_prefix_scan_pass;
|
||||
std::optional<QueriesPrefixScanPass> queries_prefix_scan_pass;
|
||||
};
|
||||
|
||||
// Transform feedback queries
|
||||
|
|
@ -1266,41 +1263,23 @@ private:
|
|||
} // namespace
|
||||
|
||||
struct QueryCacheRuntimeImpl {
|
||||
QueryCacheRuntimeImpl(QueryCacheRuntime& runtime, VideoCore::RasterizerInterface* rasterizer_,
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
Vulkan::BufferCache& buffer_cache_, const Device& device_,
|
||||
const MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
|
||||
StagingBufferPool& staging_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool, TextureCache& texture_cache_)
|
||||
: rasterizer{rasterizer_}, device_memory{device_memory_}, buffer_cache{buffer_cache_},
|
||||
device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
|
||||
staging_pool{staging_pool_}, guest_streamer(0, runtime),
|
||||
sample_streamer(static_cast<size_t>(QueryType::ZPassPixelCount64), runtime, rasterizer,
|
||||
texture_cache_, device, scheduler, memory_allocator,
|
||||
compute_pass_descriptor_queue, descriptor_pool),
|
||||
tfb_streamer(static_cast<size_t>(QueryType::StreamingByteCount), runtime, device,
|
||||
scheduler, memory_allocator, staging_pool),
|
||||
primitives_succeeded_streamer(
|
||||
static_cast<size_t>(QueryType::StreamingPrimitivesSucceeded), runtime, tfb_streamer,
|
||||
device_memory_),
|
||||
primitives_needed_minus_succeeded_streamer(
|
||||
static_cast<size_t>(QueryType::StreamingPrimitivesNeededMinusSucceeded), runtime, 0u),
|
||||
hcr_setup{}, hcr_is_set{}, is_hcr_running{}, maxwell3d{} {
|
||||
QueryCacheRuntimeImpl(QueryCacheRuntime& runtime, VideoCore::RasterizerInterface* rasterizer_, Tegra::MaxwellDeviceMemoryManager& device_memory_, Vulkan::BufferCache& buffer_cache_, const Device& device_, const MemoryAllocator& memory_allocator_, Scheduler& scheduler_, StagingBufferPool& staging_pool_, ComputePassDescriptorQueue& compute_pass_descriptor_queue, DescriptorPool& descriptor_pool, TextureCache& texture_cache_)
|
||||
: rasterizer{rasterizer_}, device_memory{device_memory_}, buffer_cache{buffer_cache_}
|
||||
, device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}
|
||||
, staging_pool{staging_pool_}, guest_streamer(0, runtime)
|
||||
, sample_streamer(size_t(QueryType::ZPassPixelCount64), runtime, rasterizer, texture_cache_, device, scheduler, memory_allocator, compute_pass_descriptor_queue, descriptor_pool)
|
||||
, tfb_streamer(size_t(QueryType::StreamingByteCount), runtime, device, scheduler, memory_allocator, staging_pool)
|
||||
, primitives_succeeded_streamer(size_t(QueryType::StreamingPrimitivesSucceeded), runtime, tfb_streamer, device_memory_)
|
||||
, primitives_needed_minus_succeeded_streamer(size_t(QueryType::StreamingPrimitivesNeededMinusSucceeded), runtime, 0u)
|
||||
, hcr_setup{}, hcr_is_set{}, is_hcr_running{}, maxwell3d{} {
|
||||
|
||||
hcr_setup.sType = VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT;
|
||||
hcr_setup.pNext = nullptr;
|
||||
hcr_setup.flags = 0;
|
||||
|
||||
const bool has_conditional_rendering = device.IsExtConditionalRendering();
|
||||
if (has_conditional_rendering) {
|
||||
conditional_resolve_pass = std::make_unique<ConditionalRenderingResolvePass>(
|
||||
device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
}
|
||||
|
||||
VkBufferUsageFlags hcr_buffer_usage =
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
if (has_conditional_rendering) {
|
||||
VkBufferUsageFlags hcr_buffer_usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
if (device.IsExtConditionalRendering()) {
|
||||
conditional_resolve_pass.emplace(device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
hcr_buffer_usage |= VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT;
|
||||
}
|
||||
|
||||
|
|
@ -1339,7 +1318,7 @@ struct QueryCacheRuntimeImpl {
|
|||
std::vector<std::vector<VkBufferCopy>> copies_setup;
|
||||
|
||||
// Host conditional rendering data
|
||||
std::unique_ptr<ConditionalRenderingResolvePass> conditional_resolve_pass;
|
||||
std::optional<ConditionalRenderingResolvePass> conditional_resolve_pass;
|
||||
vk::Buffer hcr_resolve_buffer;
|
||||
VkConditionalRenderingBeginInfoEXT hcr_setup;
|
||||
VkBuffer hcr_buffer;
|
||||
|
|
@ -1351,13 +1330,7 @@ struct QueryCacheRuntimeImpl {
|
|||
Maxwell3D* maxwell3d;
|
||||
};
|
||||
|
||||
QueryCacheRuntime::QueryCacheRuntime(VideoCore::RasterizerInterface* rasterizer,
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
Vulkan::BufferCache& buffer_cache_, const Device& device_,
|
||||
const MemoryAllocator& memory_allocator_,
|
||||
Scheduler& scheduler_, StagingBufferPool& staging_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
|
||||
DescriptorPool& descriptor_pool, TextureCache& texture_cache_) {
|
||||
QueryCacheRuntime::QueryCacheRuntime(VideoCore::RasterizerInterface* rasterizer, Tegra::MaxwellDeviceMemoryManager& device_memory_, Vulkan::BufferCache& buffer_cache_, const Device& device_, const MemoryAllocator& memory_allocator_, Scheduler& scheduler_, StagingBufferPool& staging_pool_, ComputePassDescriptorQueue& compute_pass_descriptor_queue, DescriptorPool& descriptor_pool, TextureCache& texture_cache_) {
|
||||
impl = std::make_unique<QueryCacheRuntimeImpl>(
|
||||
*this, rasterizer, device_memory_, buffer_cache_, device_, memory_allocator_, scheduler_,
|
||||
staging_pool_, compute_pass_descriptor_queue, descriptor_pool, texture_cache_);
|
||||
|
|
@ -1686,8 +1659,7 @@ void QueryCacheRuntime::SyncValues(std::span<SyncValuesType> values, VkBuffer ba
|
|||
}
|
||||
|
||||
impl->scheduler.RequestOutsideRenderPassOperationContext();
|
||||
impl->scheduler.Record([src_buffer, dst_buffers = std::move(impl->buffers_to_upload_to),
|
||||
vk_copies = std::move(impl->copies_setup)](vk::CommandBuffer cmdbuf) {
|
||||
impl->scheduler.Record([src_buffer, dst_buffers = std::move(impl->buffers_to_upload_to), vk_copies = std::move(impl->copies_setup)](vk::CommandBuffer cmdbuf) {
|
||||
size_t size = dst_buffers.size();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
cmdbuf.CopyBuffer(src_buffer, dst_buffers[i].first, vk_copies[i]);
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ void SetupRasterModes(Maxwell3D::DirtyState::Tables &tables) {
|
|||
} // Anonymous namespace
|
||||
|
||||
void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
|
||||
auto& tables{channel_state.maxwell_3d->dirty.tables};
|
||||
auto& tables{channel_state.payload->maxwell_3d.dirty.tables};
|
||||
SetupDirtyFlags(tables);
|
||||
SetupDirtyViewports(tables);
|
||||
SetupDirtyScissors(tables);
|
||||
|
|
@ -258,7 +258,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
|
|||
}
|
||||
|
||||
void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {
|
||||
flags = &channel_state.maxwell_3d->dirty.flags;
|
||||
flags = &channel_state.payload->maxwell_3d.dirty.flags;
|
||||
}
|
||||
|
||||
void StateTracker::InvalidateState() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <variant>
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
|
@ -12,20 +15,15 @@ namespace Vulkan {
|
|||
class Device;
|
||||
class Scheduler;
|
||||
|
||||
struct DescriptorUpdateEntry {
|
||||
struct Empty {};
|
||||
|
||||
union DescriptorUpdateEntry {
|
||||
DescriptorUpdateEntry() = default;
|
||||
DescriptorUpdateEntry(VkDescriptorImageInfo image_) : image{image_} {}
|
||||
DescriptorUpdateEntry(VkDescriptorBufferInfo buffer_) : buffer{buffer_} {}
|
||||
DescriptorUpdateEntry(VkBufferView texel_buffer_) : texel_buffer{texel_buffer_} {}
|
||||
|
||||
union {
|
||||
Empty empty{};
|
||||
VkDescriptorImageInfo image;
|
||||
VkDescriptorBufferInfo buffer;
|
||||
VkBufferView texel_buffer;
|
||||
};
|
||||
std::monostate empty{};
|
||||
VkDescriptorImageInfo image;
|
||||
VkDescriptorBufferInfo buffer;
|
||||
VkBufferView texel_buffer;
|
||||
};
|
||||
|
||||
class UpdateDescriptorQueue final {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue