blit screen temp
This commit is contained in:
@ -21,7 +21,7 @@ class MemorySystem;
|
|||||||
namespace GPU {
|
namespace GPU {
|
||||||
|
|
||||||
// Measured on hardware to be 2240568 timer cycles or 4481136 ARM11 cycles
|
// Measured on hardware to be 2240568 timer cycles or 4481136 ARM11 cycles
|
||||||
constexpr u64 frame_ticks = /*4481136ull*/2240568ull;
|
constexpr u64 frame_ticks = 4481136ull;
|
||||||
|
|
||||||
// Refresh rate defined by ratio of ARM11 frequency to ARM11 ticks per frame
|
// Refresh rate defined by ratio of ARM11 frequency to ARM11 ticks per frame
|
||||||
// (268,111,856) / (4,481,136) = 59.83122493939037Hz
|
// (268,111,856) / (4,481,136) = 59.83122493939037Hz
|
||||||
|
@ -86,6 +86,8 @@ add_library(video_core STATIC
|
|||||||
renderer_vulkan/renderer_vulkan.h
|
renderer_vulkan/renderer_vulkan.h
|
||||||
renderer_vulkan/vk_blit_helper.cpp
|
renderer_vulkan/vk_blit_helper.cpp
|
||||||
renderer_vulkan/vk_blit_helper.h
|
renderer_vulkan/vk_blit_helper.h
|
||||||
|
renderer_vulkan/vk_blit_screen.cpp
|
||||||
|
renderer_vulkan/vk_blit_screen.h
|
||||||
renderer_vulkan/vk_common.cpp
|
renderer_vulkan/vk_common.cpp
|
||||||
renderer_vulkan/vk_common.h
|
renderer_vulkan/vk_common.h
|
||||||
renderer_vulkan/vk_descriptor_manager.cpp
|
renderer_vulkan/vk_descriptor_manager.cpp
|
||||||
|
0
src/video_core/host_shaders/vulkan_present.frag
Normal file
0
src/video_core/host_shaders/vulkan_present.frag
Normal file
0
src/video_core/host_shaders/vulkan_present.vert
Normal file
0
src/video_core/host_shaders/vulkan_present.vert
Normal file
@ -149,15 +149,12 @@ struct ScreenRectVertex {
|
|||||||
Common::Vec2f tex_coord;
|
Common::Vec2f tex_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr u32 VERTEX_BUFFER_SIZE = sizeof(ScreenRectVertex) * 8192;
|
|
||||||
|
|
||||||
RendererVulkan::RendererVulkan(Frontend::EmuWindow& window)
|
RendererVulkan::RendererVulkan(Frontend::EmuWindow& window)
|
||||||
: RendererBase{window}, instance{window, Settings::values.physical_device},
|
: RendererBase{window}, instance{window, Settings::values.physical_device},
|
||||||
scheduler{instance, renderpass_cache, *this},
|
scheduler{instance, renderpass_cache, *this},
|
||||||
renderpass_cache{instance, scheduler}, desc_manager{instance, scheduler},
|
renderpass_cache{instance, scheduler}, desc_manager{instance, scheduler},
|
||||||
runtime{instance, scheduler, renderpass_cache, desc_manager},
|
runtime{instance, scheduler, renderpass_cache, desc_manager},
|
||||||
swapchain{instance, scheduler, renderpass_cache},
|
swapchain{instance, scheduler, renderpass_cache},
|
||||||
vertex_buffer{instance, scheduler, VERTEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eVertexBuffer, {}},
|
|
||||||
rasterizer{render_window, instance, scheduler, desc_manager, runtime, renderpass_cache} {
|
rasterizer{render_window, instance, scheduler, desc_manager, runtime, renderpass_cache} {
|
||||||
|
|
||||||
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();
|
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "common/math_util.h"
|
#include "common/math_util.h"
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_blit_screen.h"
|
||||||
#include "video_core/renderer_vulkan/vk_descriptor_manager.h"
|
#include "video_core/renderer_vulkan/vk_descriptor_manager.h"
|
||||||
#include "video_core/renderer_vulkan/vk_renderpass_cache.h"
|
#include "video_core/renderer_vulkan/vk_renderpass_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
||||||
@ -23,42 +23,6 @@ struct FramebufferLayout;
|
|||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
/// Structure used for storing information about the textures for each 3DS screen
|
|
||||||
struct TextureInfo {
|
|
||||||
ImageAlloc alloc;
|
|
||||||
u32 width;
|
|
||||||
u32 height;
|
|
||||||
GPU::Regs::PixelFormat format;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Structure used for storing information about the display target for each 3DS screen
|
|
||||||
struct ScreenInfo {
|
|
||||||
ImageAlloc* display_texture = nullptr;
|
|
||||||
Common::Rectangle<float> display_texcoords;
|
|
||||||
TextureInfo texture;
|
|
||||||
vk::Sampler sampler;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Uniform data used for presenting the 3DS screens
|
|
||||||
struct PresentUniformData {
|
|
||||||
glm::mat4 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;
|
|
||||||
|
|
||||||
// Returns an immutable byte view of the uniform data
|
|
||||||
auto AsBytes() const {
|
|
||||||
return std::as_bytes(std::span{this, 1});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(PresentUniformData) < 256, "PresentUniformData must be below 256 bytes!");
|
|
||||||
|
|
||||||
constexpr u32 PRESENT_PIPELINES = 3;
|
|
||||||
|
|
||||||
class RasterizerVulkan;
|
class RasterizerVulkan;
|
||||||
|
|
||||||
class RendererVulkan : public RendererBase {
|
class RendererVulkan : public RendererBase {
|
||||||
@ -109,25 +73,10 @@ private:
|
|||||||
DescriptorManager desc_manager;
|
DescriptorManager desc_manager;
|
||||||
TextureRuntime runtime;
|
TextureRuntime runtime;
|
||||||
Swapchain swapchain;
|
Swapchain swapchain;
|
||||||
StreamBuffer vertex_buffer;
|
|
||||||
RasterizerVulkan rasterizer;
|
RasterizerVulkan rasterizer;
|
||||||
|
|
||||||
// Present pipelines (Normal, Anaglyph, Interlaced)
|
// Display information for top and bottom screens respectively
|
||||||
vk::PipelineLayout present_pipeline_layout;
|
|
||||||
vk::DescriptorSetLayout present_descriptor_layout;
|
|
||||||
vk::DescriptorUpdateTemplate present_update_template;
|
|
||||||
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;
|
|
||||||
std::array<vk::DescriptorSet, PRESENT_PIPELINES> present_descriptor_sets;
|
|
||||||
std::array<vk::ShaderModule, PRESENT_PIPELINES> present_shaders;
|
|
||||||
std::array<vk::Sampler, 2> present_samplers;
|
|
||||||
vk::ShaderModule present_vertex_shader;
|
|
||||||
u32 current_pipeline = 0;
|
|
||||||
u32 current_sampler = 0;
|
|
||||||
|
|
||||||
/// Display information for top and bottom screens respectively
|
|
||||||
std::array<ScreenInfo, 3> screen_infos{};
|
std::array<ScreenInfo, 3> screen_infos{};
|
||||||
PresentUniformData draw_info{};
|
|
||||||
vk::ClearColorValue clear_color{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
1015
src/video_core/renderer_vulkan/vk_blit_screen.cpp
Normal file
1015
src/video_core/renderer_vulkan/vk_blit_screen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
src/video_core/renderer_vulkan/vk_blit_screen.h
Normal file
152
src/video_core/renderer_vulkan/vk_blit_screen.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "video_core/renderer_vulkan/vk_texture_runtime.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Frontend {
|
||||||
|
class EmuWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace VideoCore {
|
||||||
|
class RasterizerInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Layout {
|
||||||
|
struct FramebufferLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
struct ScreenInfo;
|
||||||
|
|
||||||
|
class Instance;
|
||||||
|
class RasterizerVulkan;
|
||||||
|
class Scheduler;
|
||||||
|
class Swapchain;
|
||||||
|
class RenderpassCache;
|
||||||
|
class DescriptorManager;
|
||||||
|
|
||||||
|
struct ScreenInfo {
|
||||||
|
vk::ImageView image_view{};
|
||||||
|
u32 width{};
|
||||||
|
u32 height{};
|
||||||
|
Common::Rectangle<f32> texcoords;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Images = std::array<vk::Image, 3>;
|
||||||
|
|
||||||
|
struct PresentUniformData {
|
||||||
|
glm::mat4 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;
|
||||||
|
|
||||||
|
// Returns an immutable byte view of the uniform data
|
||||||
|
auto AsBytes() const {
|
||||||
|
return std::as_bytes(std::span{this, 1});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr u32 PRESENT_PIPELINES = 3;
|
||||||
|
|
||||||
|
class BlitScreen {
|
||||||
|
public:
|
||||||
|
explicit BlitScreen(Frontend::EmuWindow& render_window, const Instance& instance,
|
||||||
|
Scheduler& scheduler, Swapchain& swapchain, RenderpassCache& renderpass_cache,
|
||||||
|
DescriptorManager& desc_manager, std::array<ScreenInfo, 3>& screen_infos);
|
||||||
|
~BlitScreen();
|
||||||
|
|
||||||
|
void Recreate();
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Semaphore Draw(const GPU::Regs::FramebufferConfig& framebuffer,
|
||||||
|
const vk::Framebuffer& host_framebuffer,
|
||||||
|
const Layout::FramebufferLayout layout, vk::Extent2D render_area,
|
||||||
|
bool use_accelerated, u32 screen);
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Semaphore DrawToSwapchain(const GPU::Regs::FramebufferConfig& framebuffer,
|
||||||
|
bool use_accelerated);
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Framebuffer CreateFramebuffer(const vk::ImageView& image_view,
|
||||||
|
vk::Extent2D extent);
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Framebuffer CreateFramebuffer(const vk::ImageView& image_view,
|
||||||
|
vk::Extent2D extent, vk::RenderPass& rd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CreateStaticResources();
|
||||||
|
void CreateShaders();
|
||||||
|
void CreateSemaphores();
|
||||||
|
void CreateDescriptorPool();
|
||||||
|
void CreateRenderPass();
|
||||||
|
vk::RenderPass CreateRenderPassImpl(vk::Format format, bool is_present = true);
|
||||||
|
void CreateDescriptorSetLayout();
|
||||||
|
void CreateDescriptorSets();
|
||||||
|
void CreatePipelineLayout();
|
||||||
|
void CreateGraphicsPipeline();
|
||||||
|
void CreateSampler();
|
||||||
|
|
||||||
|
void CreateDynamicResources();
|
||||||
|
void CreateFramebuffers();
|
||||||
|
|
||||||
|
void RefreshResources(const GPU::Regs::FramebufferConfig& framebuffer);
|
||||||
|
void ReleaseRawImages();
|
||||||
|
void CreateStagingBuffer(const GPU::Regs::FramebufferConfig& framebuffer);
|
||||||
|
void CreateRawImages(const GPU::Regs::FramebufferConfig& framebuffer);
|
||||||
|
|
||||||
|
struct BufferData;
|
||||||
|
|
||||||
|
void UpdateDescriptorSet(std::size_t image_index, bool use_accelerated) const;
|
||||||
|
void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const;
|
||||||
|
void SetVertexData(BufferData& data, const Layout::FramebufferLayout layout) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Frontend::EmuWindow& render_window;
|
||||||
|
const Instance& instance;
|
||||||
|
Scheduler& scheduler;
|
||||||
|
Swapchain& swapchain;
|
||||||
|
RenderpassCache& renderpass_cache;
|
||||||
|
DescriptorManager& desc_manager;
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
|
std::array<ScreenInfo, 3>& screen_infos;
|
||||||
|
std::size_t image_count;
|
||||||
|
PresentUniformData draw_info{};
|
||||||
|
StreamBuffer vertex_buffer;
|
||||||
|
|
||||||
|
vk::PipelineLayout pipeline_layout;
|
||||||
|
vk::DescriptorSetLayout descriptor_set_layout;
|
||||||
|
vk::DescriptorUpdateTemplate update_template;
|
||||||
|
std::array<vk::Pipeline, PRESENT_PIPELINES> pipelines;
|
||||||
|
std::array<vk::DescriptorSet, PRESENT_PIPELINES> descriptor_sets;
|
||||||
|
std::array<vk::ShaderModule, PRESENT_PIPELINES> shaders;
|
||||||
|
std::array<vk::Sampler, 2> samplers;
|
||||||
|
vk::ShaderModule vertex_shader;
|
||||||
|
u32 current_pipeline = 0;
|
||||||
|
u32 current_sampler = 0;
|
||||||
|
|
||||||
|
vk::RenderPass renderpass;
|
||||||
|
std::vector<vk::Framebuffer> framebuffers;
|
||||||
|
std::vector<u64> resource_ticks;
|
||||||
|
std::vector<vk::Semaphore> semaphores;
|
||||||
|
std::vector<Images> raw_images;
|
||||||
|
GPU::Regs::PixelFormat pixel_format;
|
||||||
|
u32 raw_width;
|
||||||
|
u32 raw_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
@ -5,7 +5,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
// Include vulkan-hpp header
|
// Include vulkan-hpp header
|
||||||
#define VK_NO_PROTOTYPES 1
|
#define VK_NO_PROTOTYPES 1
|
||||||
|
@ -31,40 +31,48 @@ public:
|
|||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
/// Returns true when the swapchain should be recreated
|
/// Returns true when the swapchain should be recreated
|
||||||
[[nodiscard]] bool NeedsRecreation() const {
|
bool NeedsRecreation() const {
|
||||||
return is_suboptimal || is_outdated;
|
return is_suboptimal || is_outdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t GetImageCount() const {
|
||||||
|
return image_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t GetImageIndex() const {
|
||||||
|
return image_index;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns current swapchain state
|
/// Returns current swapchain state
|
||||||
[[nodiscard]] vk::Extent2D GetExtent() const {
|
vk::Extent2D GetExtent() const {
|
||||||
return extent;
|
return extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the swapchain surface
|
/// Returns the swapchain surface
|
||||||
[[nodiscard]] vk::SurfaceKHR GetSurface() const {
|
vk::SurfaceKHR GetSurface() const {
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current framebuffe
|
/// Returns the current framebuffe
|
||||||
[[nodiscard]] vk::Framebuffer GetFramebuffer() const {
|
vk::Framebuffer GetFramebuffer() const {
|
||||||
return framebuffers[image_index];
|
return framebuffers[image_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the swapchain format
|
/// Returns the swapchain format
|
||||||
[[nodiscard]] vk::SurfaceFormatKHR GetSurfaceFormat() const {
|
vk::Format GetImageFormat() const {
|
||||||
return surface_format;
|
return surface_format.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Vulkan swapchain handle
|
/// Returns the Vulkan swapchain handle
|
||||||
[[nodiscard]] vk::SwapchainKHR GetHandle() const {
|
vk::SwapchainKHR GetHandle() const {
|
||||||
return swapchain;
|
return swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] vk::Semaphore GetImageAcquiredSemaphore() const {
|
vk::Semaphore GetImageAcquiredSemaphore() const {
|
||||||
return image_acquired[frame_index];
|
return image_acquired[frame_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] vk::Semaphore GetPresentReadySemaphore() const {
|
vk::Semaphore GetPresentReadySemaphore() const {
|
||||||
return present_ready[image_index];
|
return present_ready[image_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +108,9 @@ private:
|
|||||||
std::vector<u64> resource_ticks;
|
std::vector<u64> resource_ticks;
|
||||||
std::vector<vk::Semaphore> image_acquired;
|
std::vector<vk::Semaphore> image_acquired;
|
||||||
std::vector<vk::Semaphore> present_ready;
|
std::vector<vk::Semaphore> present_ready;
|
||||||
u32 image_count = 0;
|
std::size_t image_count = 0;
|
||||||
u32 image_index = 0;
|
std::size_t image_index = 0;
|
||||||
u32 frame_index = 0;
|
std::size_t frame_index = 0;
|
||||||
bool is_outdated = true;
|
bool is_outdated = true;
|
||||||
bool is_suboptimal = true;
|
bool is_suboptimal = true;
|
||||||
};
|
};
|
||||||
|
@ -124,7 +124,7 @@ void TextureRuntime::FlushBuffers() {
|
|||||||
MICROPROFILE_DEFINE(Vulkan_Finish, "Vulkan", "Scheduler Finish", MP_RGB(52, 192, 235));
|
MICROPROFILE_DEFINE(Vulkan_Finish, "Vulkan", "Scheduler Finish", MP_RGB(52, 192, 235));
|
||||||
void TextureRuntime::Finish() {
|
void TextureRuntime::Finish() {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Finish);
|
MICROPROFILE_SCOPE(Vulkan_Finish);
|
||||||
//scheduler.Finish();
|
scheduler.Finish();
|
||||||
download_buffer.Invalidate();
|
download_buffer.Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user