mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-06 08:40:28 +01:00
249 lines
7 KiB
C++
249 lines
7 KiB
C++
#pragma once
|
|
|
|
#include "../Common/simple_array.hpp"
|
|
#include "../Overlays/overlay_controls.h"
|
|
|
|
#include "VKProgramPipeline.h"
|
|
#include "VKHelpers.h"
|
|
|
|
#include "vkutils/data_heap.h"
|
|
#include "vkutils/descriptors.h"
|
|
#include "vkutils/graphics_pipeline_state.hpp"
|
|
|
|
#include "Emu/IdManager.h"
|
|
|
|
#include <unordered_map>
|
|
|
|
namespace rsx
|
|
{
|
|
namespace overlays
|
|
{
|
|
struct overlay;
|
|
}
|
|
}
|
|
|
|
namespace vk
|
|
{
|
|
struct framebuffer;
|
|
struct sampler;
|
|
struct image_view;
|
|
class image;
|
|
class viewable_image;
|
|
class command_buffer;
|
|
class render_target;
|
|
|
|
namespace glsl
|
|
{
|
|
class program;
|
|
}
|
|
|
|
// TODO: Refactor text print class to inherit from this base class
|
|
struct overlay_pass
|
|
{
|
|
vk::glsl::shader m_vertex_shader;
|
|
vk::glsl::shader m_fragment_shader;
|
|
|
|
vk::descriptor_pool m_descriptor_pool;
|
|
descriptor_set m_descriptor_set;
|
|
VkDescriptorSetLayout m_descriptor_layout = nullptr;
|
|
VkPipelineLayout m_pipeline_layout = nullptr;
|
|
u32 m_used_descriptors = 0;
|
|
|
|
VkFilter m_sampler_filter = VK_FILTER_LINEAR;
|
|
u32 m_num_usable_samplers = 1;
|
|
u32 m_num_input_attachments = 0;
|
|
|
|
std::unordered_map<u64, std::unique_ptr<vk::glsl::program>> m_program_cache;
|
|
std::unique_ptr<vk::sampler> m_sampler;
|
|
std::unique_ptr<vk::framebuffer> m_draw_fbo;
|
|
vk::data_heap m_vao;
|
|
vk::data_heap m_ubo;
|
|
const vk::render_device* m_device = nullptr;
|
|
|
|
std::string vs_src;
|
|
std::string fs_src;
|
|
|
|
graphics_pipeline_state renderpass_config;
|
|
|
|
bool initialized = false;
|
|
bool compiled = false;
|
|
|
|
u32 num_drawable_elements = 4;
|
|
u32 first_vertex = 0;
|
|
|
|
u32 m_ubo_length = 128;
|
|
u32 m_ubo_offset = 0;
|
|
u32 m_vao_offset = 0;
|
|
|
|
overlay_pass();
|
|
~overlay_pass();
|
|
|
|
u64 get_pipeline_key(VkRenderPass pass);
|
|
|
|
void check_heap();
|
|
|
|
void init_descriptors();
|
|
|
|
virtual void update_uniforms(vk::command_buffer& /*cmd*/, vk::glsl::program* /*program*/) {}
|
|
|
|
virtual std::vector<vk::glsl::program_input> get_vertex_inputs();
|
|
virtual std::vector<vk::glsl::program_input> get_fragment_inputs();
|
|
|
|
virtual void get_dynamic_state_entries(std::vector<VkDynamicState>& /*state_descriptors*/) {}
|
|
|
|
virtual std::vector<VkPushConstantRange> get_push_constants()
|
|
{
|
|
return {};
|
|
}
|
|
|
|
template <typename T>
|
|
void upload_vertex_data(T* data, u32 count)
|
|
{
|
|
check_heap();
|
|
|
|
const auto size = count * sizeof(T);
|
|
m_vao_offset = static_cast<u32>(m_vao.alloc<16>(size));
|
|
auto dst = m_vao.map(m_vao_offset, size);
|
|
std::memcpy(dst, data, size);
|
|
m_vao.unmap();
|
|
}
|
|
|
|
vk::glsl::program* build_pipeline(u64 storage_key, VkRenderPass render_pass);
|
|
|
|
void load_program(vk::command_buffer& cmd, VkRenderPass pass, const std::vector<vk::image_view*>& src);
|
|
|
|
virtual void create(const vk::render_device& dev);
|
|
virtual void destroy();
|
|
|
|
void free_resources();
|
|
|
|
vk::framebuffer* get_framebuffer(vk::image* target, VkRenderPass render_pass);
|
|
|
|
virtual void emit_geometry(vk::command_buffer& cmd);
|
|
|
|
virtual void set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h);
|
|
|
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* fbo, const std::vector<vk::image_view*>& src, VkRenderPass render_pass);
|
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::image* target, const std::vector<vk::image_view*>& src, VkRenderPass render_pass);
|
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::image* target, vk::image_view* src, VkRenderPass render_pass);
|
|
};
|
|
|
|
struct ui_overlay_renderer : public overlay_pass
|
|
{
|
|
f32 m_time = 0.f;
|
|
f32 m_blur_strength = 0.f;
|
|
color4f m_scale_offset;
|
|
color4f m_color;
|
|
bool m_pulse_glow = false;
|
|
bool m_skip_texture_read = false;
|
|
bool m_clip_enabled = false;
|
|
int m_texture_type;
|
|
areaf m_clip_region;
|
|
coordf m_viewport;
|
|
|
|
std::vector<std::unique_ptr<vk::image>> resources;
|
|
std::unordered_map<u64, std::unique_ptr<vk::image>> font_cache;
|
|
std::unordered_map<u64, std::unique_ptr<vk::image_view>> view_cache;
|
|
std::unordered_map<u64, std::pair<u32, std::unique_ptr<vk::image>>> temp_image_cache;
|
|
std::unordered_map<u64, std::unique_ptr<vk::image_view>> temp_view_cache;
|
|
rsx::overlays::primitive_type m_current_primitive_type = rsx::overlays::primitive_type::quad_list;
|
|
|
|
ui_overlay_renderer();
|
|
|
|
vk::image_view* upload_simple_texture(vk::render_device& dev, vk::command_buffer& cmd,
|
|
vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, void* pixel_src, u32 owner_uid);
|
|
|
|
void init(vk::command_buffer& cmd, vk::data_heap& upload_heap);
|
|
|
|
void destroy() override;
|
|
|
|
void remove_temp_resources(u32 key);
|
|
|
|
vk::image_view* find_font(rsx::overlays::font* font, vk::command_buffer& cmd, vk::data_heap& upload_heap);
|
|
vk::image_view* find_temp_image(rsx::overlays::image_info* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid);
|
|
|
|
void update_uniforms(vk::command_buffer& /*cmd*/, vk::glsl::program* /*program*/) override;
|
|
|
|
void set_primitive_type(rsx::overlays::primitive_type type);
|
|
|
|
void emit_geometry(vk::command_buffer& cmd) override;
|
|
|
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target, VkRenderPass render_pass,
|
|
vk::data_heap& upload_heap, rsx::overlays::overlay& ui);
|
|
};
|
|
|
|
struct attachment_clear_pass : public overlay_pass
|
|
{
|
|
color4f clear_color = { 0.f, 0.f, 0.f, 0.f };
|
|
color4f colormask = { 1.f, 1.f, 1.f, 1.f };
|
|
VkRect2D region = {};
|
|
|
|
attachment_clear_pass();
|
|
|
|
std::vector<VkPushConstantRange> get_push_constants() override;
|
|
|
|
void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) override;
|
|
|
|
void set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) override;
|
|
|
|
void run(vk::command_buffer& cmd, vk::framebuffer* target, VkRect2D rect, u32 clearmask, color4f color, VkRenderPass render_pass);
|
|
};
|
|
|
|
struct stencil_clear_pass : public overlay_pass
|
|
{
|
|
VkRect2D region = {};
|
|
|
|
stencil_clear_pass();
|
|
|
|
void set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) override;
|
|
|
|
void run(vk::command_buffer& cmd, vk::render_target* target, VkRect2D rect, u32 stencil_clear, u32 stencil_write_mask, VkRenderPass render_pass);
|
|
};
|
|
|
|
struct video_out_calibration_pass : public overlay_pass
|
|
{
|
|
union config_t
|
|
{
|
|
struct
|
|
{
|
|
float gamma;
|
|
int limit_range;
|
|
int stereo;
|
|
int stereo_image_count;
|
|
};
|
|
|
|
float data[4];
|
|
}
|
|
config;
|
|
|
|
video_out_calibration_pass();
|
|
|
|
std::vector<VkPushConstantRange> get_push_constants() override;
|
|
|
|
void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* /*program*/) override;
|
|
|
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target,
|
|
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb, bool _3d, VkRenderPass render_pass);
|
|
};
|
|
|
|
// TODO: Replace with a proper manager
|
|
extern std::unordered_map<u32, std::unique_ptr<vk::overlay_pass>> g_overlay_passes;
|
|
|
|
template<class T>
|
|
T* get_overlay_pass()
|
|
{
|
|
u32 index = id_manager::typeinfo::get_index<T>();
|
|
auto& e = g_overlay_passes[index];
|
|
|
|
if (!e)
|
|
{
|
|
e = std::make_unique<T>();
|
|
e->create(*vk::get_current_renderer());
|
|
}
|
|
|
|
return static_cast<T*>(e.get());
|
|
}
|
|
|
|
void reset_overlay_passes();
|
|
}
|