blit screen temp

This commit is contained in:
GPUCode
2022-11-16 21:54:09 +02:00
parent 37ce0540ed
commit 797d0e45ce
11 changed files with 1193 additions and 71 deletions

View File

@ -21,7 +21,7 @@ class MemorySystem;
namespace GPU {
// 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
// (268,111,856) / (4,481,136) = 59.83122493939037Hz

View File

@ -86,6 +86,8 @@ add_library(video_core STATIC
renderer_vulkan/renderer_vulkan.h
renderer_vulkan/vk_blit_helper.cpp
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.h
renderer_vulkan/vk_descriptor_manager.cpp

View File

@ -149,15 +149,12 @@ struct ScreenRectVertex {
Common::Vec2f tex_coord;
};
constexpr u32 VERTEX_BUFFER_SIZE = sizeof(ScreenRectVertex) * 8192;
RendererVulkan::RendererVulkan(Frontend::EmuWindow& window)
: RendererBase{window}, instance{window, Settings::values.physical_device},
scheduler{instance, renderpass_cache, *this},
renderpass_cache{instance, scheduler}, desc_manager{instance, scheduler},
runtime{instance, scheduler, renderpass_cache, desc_manager},
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} {
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();

View File

@ -10,7 +10,7 @@
#include "common/math_util.h"
#include "core/hw/gpu.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_renderpass_cache.h"
#include "video_core/renderer_vulkan/vk_swapchain.h"
@ -23,42 +23,6 @@ struct FramebufferLayout;
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 RendererVulkan : public RendererBase {
@ -109,25 +73,10 @@ private:
DescriptorManager desc_manager;
TextureRuntime runtime;
Swapchain swapchain;
StreamBuffer vertex_buffer;
RasterizerVulkan rasterizer;
// Present pipelines (Normal, Anaglyph, Interlaced)
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
// Display information for top and bottom screens respectively
std::array<ScreenInfo, 3> screen_infos{};
PresentUniformData draw_info{};
vk::ClearColorValue clear_color{};
};
} // namespace Vulkan

File diff suppressed because it is too large Load Diff

View 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

View File

@ -5,7 +5,6 @@
#pragma once
#include <algorithm>
#include "common/common_types.h"
// Include vulkan-hpp header
#define VK_NO_PROTOTYPES 1

View File

@ -31,40 +31,48 @@ public:
void Present();
/// Returns true when the swapchain should be recreated
[[nodiscard]] bool NeedsRecreation() const {
bool NeedsRecreation() const {
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
[[nodiscard]] vk::Extent2D GetExtent() const {
vk::Extent2D GetExtent() const {
return extent;
}
/// Returns the swapchain surface
[[nodiscard]] vk::SurfaceKHR GetSurface() const {
vk::SurfaceKHR GetSurface() const {
return surface;
}
/// Returns the current framebuffe
[[nodiscard]] vk::Framebuffer GetFramebuffer() const {
vk::Framebuffer GetFramebuffer() const {
return framebuffers[image_index];
}
/// Returns the swapchain format
[[nodiscard]] vk::SurfaceFormatKHR GetSurfaceFormat() const {
return surface_format;
vk::Format GetImageFormat() const {
return surface_format.format;
}
/// Returns the Vulkan swapchain handle
[[nodiscard]] vk::SwapchainKHR GetHandle() const {
vk::SwapchainKHR GetHandle() const {
return swapchain;
}
[[nodiscard]] vk::Semaphore GetImageAcquiredSemaphore() const {
vk::Semaphore GetImageAcquiredSemaphore() const {
return image_acquired[frame_index];
}
[[nodiscard]] vk::Semaphore GetPresentReadySemaphore() const {
vk::Semaphore GetPresentReadySemaphore() const {
return present_ready[image_index];
}
@ -100,9 +108,9 @@ private:
std::vector<u64> resource_ticks;
std::vector<vk::Semaphore> image_acquired;
std::vector<vk::Semaphore> present_ready;
u32 image_count = 0;
u32 image_index = 0;
u32 frame_index = 0;
std::size_t image_count = 0;
std::size_t image_index = 0;
std::size_t frame_index = 0;
bool is_outdated = true;
bool is_suboptimal = true;
};

View File

@ -124,7 +124,7 @@ void TextureRuntime::FlushBuffers() {
MICROPROFILE_DEFINE(Vulkan_Finish, "Vulkan", "Scheduler Finish", MP_RGB(52, 192, 235));
void TextureRuntime::Finish() {
MICROPROFILE_SCOPE(Vulkan_Finish);
//scheduler.Finish();
scheduler.Finish();
download_buffer.Invalidate();
}