2023-09-13 00:28:50 +02:00
|
|
|
// Copyright 2023 Citra Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/math_util.h"
|
|
|
|
#include "video_core/renderer_base.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_present_window.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_renderpass_cache.h"
|
|
|
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
|
|
|
|
|
|
|
namespace Core {
|
|
|
|
class System;
|
2023-10-12 00:11:43 +02:00
|
|
|
}
|
2023-09-13 00:28:50 +02:00
|
|
|
|
|
|
|
namespace Memory {
|
|
|
|
class MemorySystem;
|
|
|
|
}
|
|
|
|
|
2023-12-28 11:46:57 +01:00
|
|
|
namespace Pica {
|
|
|
|
class PicaCore;
|
|
|
|
}
|
|
|
|
|
2023-09-13 00:28:50 +02:00
|
|
|
namespace Layout {
|
|
|
|
struct FramebufferLayout;
|
|
|
|
}
|
|
|
|
|
2023-12-28 11:46:57 +01:00
|
|
|
namespace VideoCore {
|
|
|
|
class GPU;
|
|
|
|
}
|
|
|
|
|
2023-09-13 00:28:50 +02:00
|
|
|
namespace Vulkan {
|
|
|
|
|
|
|
|
struct TextureInfo {
|
|
|
|
u32 width;
|
|
|
|
u32 height;
|
2023-12-28 11:46:57 +01:00
|
|
|
Pica::PixelFormat format;
|
2023-09-13 00:28:50 +02:00
|
|
|
vk::Image image;
|
|
|
|
vk::ImageView image_view;
|
|
|
|
VmaAllocation allocation;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ScreenInfo {
|
|
|
|
TextureInfo texture;
|
|
|
|
Common::Rectangle<f32> texcoords;
|
|
|
|
vk::ImageView image_view;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PresentUniformData {
|
|
|
|
std::array<f32, 4 * 4> modelview;
|
|
|
|
Common::Vec4f i_resolution;
|
|
|
|
Common::Vec4f o_resolution;
|
|
|
|
int screen_id_l = 0;
|
|
|
|
int screen_id_r = 0;
|
|
|
|
int layer = 0;
|
|
|
|
int reverse_interlaced = 0;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(PresentUniformData) == 112,
|
|
|
|
"PresentUniformData does not structure in shader!");
|
|
|
|
|
|
|
|
class RendererVulkan : public VideoCore::RendererBase {
|
|
|
|
static constexpr std::size_t PRESENT_PIPELINES = 3;
|
|
|
|
|
|
|
|
public:
|
2023-12-28 11:46:57 +01:00
|
|
|
explicit RendererVulkan(Core::System& system, Pica::PicaCore& pica, Frontend::EmuWindow& window,
|
2023-09-13 00:28:50 +02:00
|
|
|
Frontend::EmuWindow* secondary_window);
|
|
|
|
~RendererVulkan() override;
|
|
|
|
|
|
|
|
[[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() override {
|
|
|
|
return &rasterizer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NotifySurfaceChanged() override {
|
|
|
|
main_window.NotifySurfaceChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwapBuffers() override;
|
|
|
|
void TryPresent(int timeout_ms, bool is_secondary) override {}
|
|
|
|
void Sync() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void ReloadPipeline();
|
|
|
|
void CompileShaders();
|
|
|
|
void BuildLayouts();
|
|
|
|
void BuildPipelines();
|
|
|
|
void ConfigureFramebufferTexture(TextureInfo& texture,
|
2023-12-28 11:46:57 +01:00
|
|
|
const Pica::FramebufferConfig& framebuffer);
|
2023-09-13 00:28:50 +02:00
|
|
|
void ConfigureRenderPipeline();
|
|
|
|
void PrepareRendertarget();
|
|
|
|
void RenderScreenshot();
|
2023-11-12 22:02:55 +01:00
|
|
|
void RenderScreenshotWithStagingCopy();
|
|
|
|
bool TryRenderScreenshotWithHostMemory();
|
2023-09-13 00:28:50 +02:00
|
|
|
void PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout);
|
|
|
|
void RenderToWindow(PresentWindow& window, const Layout::FramebufferLayout& layout,
|
|
|
|
bool flipped);
|
|
|
|
|
|
|
|
void DrawScreens(Frame* frame, const Layout::FramebufferLayout& layout, bool flipped);
|
|
|
|
void DrawBottomScreen(const Layout::FramebufferLayout& layout,
|
|
|
|
const Common::Rectangle<u32>& bottom_screen);
|
|
|
|
void DrawTopScreen(const Layout::FramebufferLayout& layout,
|
|
|
|
const Common::Rectangle<u32>& top_screen);
|
|
|
|
void DrawSingleScreen(u32 screen_id, float x, float y, float w, float h,
|
|
|
|
Layout::DisplayOrientation orientation);
|
|
|
|
void DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, float w,
|
|
|
|
float h, Layout::DisplayOrientation orientation);
|
2023-12-28 11:46:57 +01:00
|
|
|
void LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer, ScreenInfo& screen_info,
|
|
|
|
bool right_eye);
|
|
|
|
void FillScreen(Common::Vec3<u8> color, const TextureInfo& texture);
|
2023-09-13 00:28:50 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
Memory::MemorySystem& memory;
|
2023-12-28 11:46:57 +01:00
|
|
|
Pica::PicaCore& pica;
|
2023-09-13 00:28:50 +02:00
|
|
|
|
|
|
|
Instance instance;
|
|
|
|
Scheduler scheduler;
|
|
|
|
RenderpassCache renderpass_cache;
|
|
|
|
DescriptorPool pool;
|
|
|
|
PresentWindow main_window;
|
|
|
|
StreamBuffer vertex_buffer;
|
|
|
|
RasterizerVulkan rasterizer;
|
|
|
|
std::unique_ptr<PresentWindow> second_window;
|
|
|
|
|
|
|
|
vk::UniquePipelineLayout present_pipeline_layout;
|
|
|
|
DescriptorSetProvider present_set_provider;
|
|
|
|
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;
|
|
|
|
std::array<vk::ShaderModule, PRESENT_PIPELINES> present_shaders;
|
|
|
|
std::array<vk::Sampler, 2> present_samplers;
|
|
|
|
vk::ShaderModule present_vertex_shader;
|
|
|
|
u32 current_pipeline = 0;
|
|
|
|
|
|
|
|
std::array<ScreenInfo, 3> screen_infos{};
|
|
|
|
std::array<DescriptorData, 3> present_textures{};
|
|
|
|
PresentUniformData draw_info{};
|
|
|
|
vk::ClearColorValue clear_color{};
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Vulkan
|