mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 17:58:37 +12:00
rsx/overlays: Add support for other primitive types other than triangle_strips
This commit is contained in:
parent
e3e7051ed3
commit
78aefe5b5e
3 changed files with 106 additions and 20 deletions
|
@ -358,7 +358,7 @@ namespace gl
|
||||||
std::unordered_map<u64, std::unique_ptr<gl::texture_view>> temp_view_cache;
|
std::unordered_map<u64, std::unique_ptr<gl::texture_view>> temp_view_cache;
|
||||||
std::unordered_map<u64, std::unique_ptr<gl::texture>> font_cache;
|
std::unordered_map<u64, std::unique_ptr<gl::texture>> font_cache;
|
||||||
std::unordered_map<u64, std::unique_ptr<gl::texture_view>> view_cache;
|
std::unordered_map<u64, std::unique_ptr<gl::texture_view>> view_cache;
|
||||||
bool is_font_draw = false;
|
rsx::overlays::primitive_type m_current_primitive_type = rsx::overlays::primitive_type::quad_list;
|
||||||
|
|
||||||
ui_overlay_renderer()
|
ui_overlay_renderer()
|
||||||
{
|
{
|
||||||
|
@ -577,14 +577,32 @@ namespace gl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_primitive_type(rsx::overlays::primitive_type type)
|
||||||
|
{
|
||||||
|
m_current_primitive_type = type;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case rsx::overlays::primitive_type::quad_list:
|
||||||
|
case rsx::overlays::primitive_type::triangle_strip:
|
||||||
|
primitives = GL_TRIANGLE_STRIP;
|
||||||
|
break;
|
||||||
|
case rsx::overlays::primitive_type::line_list:
|
||||||
|
primitives = GL_LINES;
|
||||||
|
break;
|
||||||
|
case rsx::overlays::primitive_type::line_strip:
|
||||||
|
primitives = GL_LINE_STRIP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unexpected primitive type %d" HERE, static_cast<s32>(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void emit_geometry() override
|
void emit_geometry() override
|
||||||
{
|
{
|
||||||
if (!is_font_draw)
|
if (m_current_primitive_type == rsx::overlays::primitive_type::quad_list)
|
||||||
{
|
|
||||||
overlay_pass::emit_geometry();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// Emulate quads with disjointed triangle strips
|
||||||
int num_quads = num_drawable_elements / 4;
|
int num_quads = num_drawable_elements / 4;
|
||||||
std::vector<GLint> firsts;
|
std::vector<GLint> firsts;
|
||||||
std::vector<GLsizei> counts;
|
std::vector<GLsizei> counts;
|
||||||
|
@ -606,6 +624,10 @@ namespace gl
|
||||||
|
|
||||||
glBindVertexArray(old_vao);
|
glBindVertexArray(old_vao);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
overlay_pass::emit_geometry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui)
|
void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui)
|
||||||
|
@ -618,9 +640,9 @@ namespace gl
|
||||||
|
|
||||||
for (auto &cmd : ui.get_compiled().draw_commands)
|
for (auto &cmd : ui.get_compiled().draw_commands)
|
||||||
{
|
{
|
||||||
|
set_primitive_type(cmd.config.primitives);
|
||||||
upload_vertex_data((f32*)cmd.verts.data(), (u32)cmd.verts.size() * 4u);
|
upload_vertex_data((f32*)cmd.verts.data(), (u32)cmd.verts.size() * 4u);
|
||||||
num_drawable_elements = (u32)cmd.verts.size();
|
num_drawable_elements = (u32)cmd.verts.size();
|
||||||
is_font_draw = false;
|
|
||||||
GLint texture_exists = GL_TRUE;
|
GLint texture_exists = GL_TRUE;
|
||||||
|
|
||||||
switch (cmd.config.texture_ref)
|
switch (cmd.config.texture_ref)
|
||||||
|
@ -641,7 +663,6 @@ namespace gl
|
||||||
}
|
}
|
||||||
case rsx::overlays::image_resource_id::font_file:
|
case rsx::overlays::image_resource_id::font_file:
|
||||||
{
|
{
|
||||||
is_font_draw = true;
|
|
||||||
glBindTexture(GL_TEXTURE_2D, find_font(cmd.config.font_ref)->id());
|
glBindTexture(GL_TEXTURE_2D, find_font(cmd.config.font_ref)->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,14 @@ namespace rsx
|
||||||
backbuffer = 255 // Use current backbuffer contents
|
backbuffer = 255 // Use current backbuffer contents
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class primitive_type : u8
|
||||||
|
{
|
||||||
|
quad_list = 0,
|
||||||
|
triangle_strip = 1,
|
||||||
|
line_list = 2,
|
||||||
|
line_strip = 3
|
||||||
|
};
|
||||||
|
|
||||||
struct vertex
|
struct vertex
|
||||||
{
|
{
|
||||||
float values[4];
|
float values[4];
|
||||||
|
@ -353,6 +361,8 @@ namespace rsx
|
||||||
{
|
{
|
||||||
struct command_config
|
struct command_config
|
||||||
{
|
{
|
||||||
|
primitive_type primitives = primitive_type::quad_list;
|
||||||
|
|
||||||
color4f color = { 1.f, 1.f, 1.f, 1.f };
|
color4f color = { 1.f, 1.f, 1.f, 1.f };
|
||||||
bool pulse_glow = false;
|
bool pulse_glow = false;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace vk
|
||||||
VkFilter m_sampler_filter = VK_FILTER_LINEAR;
|
VkFilter m_sampler_filter = VK_FILTER_LINEAR;
|
||||||
u32 m_num_usable_samplers = 1;
|
u32 m_num_usable_samplers = 1;
|
||||||
|
|
||||||
std::unordered_map<VkRenderPass, std::unique_ptr<vk::glsl::program>> m_program_cache;
|
std::unordered_map<u64, std::unique_ptr<vk::glsl::program>> m_program_cache;
|
||||||
std::unique_ptr<vk::sampler> m_sampler;
|
std::unique_ptr<vk::sampler> m_sampler;
|
||||||
std::unique_ptr<vk::framebuffer> m_draw_fbo;
|
std::unique_ptr<vk::framebuffer> m_draw_fbo;
|
||||||
vk::data_heap m_vao;
|
vk::data_heap m_vao;
|
||||||
|
@ -37,6 +37,7 @@ namespace vk
|
||||||
std::string fs_src;
|
std::string fs_src;
|
||||||
|
|
||||||
graphics_pipeline_state renderpass_config;
|
graphics_pipeline_state renderpass_config;
|
||||||
|
bool multi_primitive = false;
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
bool compiled = false;
|
bool compiled = false;
|
||||||
|
@ -56,6 +57,25 @@ namespace vk
|
||||||
|
|
||||||
~overlay_pass() = default;
|
~overlay_pass() = default;
|
||||||
|
|
||||||
|
u64 get_pipeline_key(VkRenderPass pass)
|
||||||
|
{
|
||||||
|
if (!multi_primitive)
|
||||||
|
{
|
||||||
|
// Default fast path
|
||||||
|
return reinterpret_cast<u64>(pass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u64 pass_value;
|
||||||
|
u64 config;
|
||||||
|
}
|
||||||
|
key{ reinterpret_cast<uintptr_t>(pass), static_cast<u64>(renderpass_config.ia.topology) };
|
||||||
|
return rpcs3::hash_struct(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void check_heap()
|
void check_heap()
|
||||||
{
|
{
|
||||||
if (!m_vao.heap)
|
if (!m_vao.heap)
|
||||||
|
@ -157,7 +177,7 @@ namespace vk
|
||||||
m_vao.unmap();
|
m_vao.unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::glsl::program* build_pipeline(VkRenderPass render_pass)
|
vk::glsl::program* build_pipeline(u64 storage_key, VkRenderPass render_pass)
|
||||||
{
|
{
|
||||||
if (!compiled)
|
if (!compiled)
|
||||||
{
|
{
|
||||||
|
@ -226,7 +246,7 @@ namespace vk
|
||||||
|
|
||||||
auto program = std::make_unique<vk::glsl::program>(*m_device, pipeline, get_vertex_inputs(), get_fragment_inputs());
|
auto program = std::make_unique<vk::glsl::program>(*m_device, pipeline, get_vertex_inputs(), get_fragment_inputs());
|
||||||
auto result = program.get();
|
auto result = program.get();
|
||||||
m_program_cache[render_pass] = std::move(program);
|
m_program_cache[storage_key] = std::move(program);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -234,11 +254,13 @@ namespace vk
|
||||||
void load_program(vk::command_buffer& cmd, VkRenderPass pass, const std::vector<vk::image_view*>& src)
|
void load_program(vk::command_buffer& cmd, VkRenderPass pass, const std::vector<vk::image_view*>& src)
|
||||||
{
|
{
|
||||||
vk::glsl::program *program = nullptr;
|
vk::glsl::program *program = nullptr;
|
||||||
auto found = m_program_cache.find(pass);
|
const auto key = get_pipeline_key(pass);
|
||||||
|
|
||||||
|
auto found = m_program_cache.find(key);
|
||||||
if (found != m_program_cache.end())
|
if (found != m_program_cache.end())
|
||||||
program = found->second.get();
|
program = found->second.get();
|
||||||
else
|
else
|
||||||
program = build_pipeline(pass);
|
program = build_pipeline(key, pass);
|
||||||
|
|
||||||
verify(HERE), m_used_descriptors < VK_OVERLAY_MAX_DRAW_CALLS;
|
verify(HERE), m_used_descriptors < VK_OVERLAY_MAX_DRAW_CALLS;
|
||||||
|
|
||||||
|
@ -457,6 +479,7 @@ namespace vk
|
||||||
std::unordered_map<u64, std::unique_ptr<vk::image_view>> view_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::pair<u32, std::unique_ptr<vk::image>>> temp_image_cache;
|
||||||
std::unordered_map<u64, std::unique_ptr<vk::image_view>> temp_view_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()
|
ui_overlay_renderer()
|
||||||
{
|
{
|
||||||
|
@ -573,6 +596,9 @@ namespace vk
|
||||||
" ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n"
|
" ocol = sample_image(fs0, tc0, parameters2.x).bgra * diff_color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
// Allow mixed primitive rendering
|
||||||
|
multi_primitive = true;
|
||||||
|
|
||||||
renderpass_config.set_attachment_count(1);
|
renderpass_config.set_attachment_count(1);
|
||||||
renderpass_config.set_color_mask(0, true, true, true, true);
|
renderpass_config.set_color_mask(0, true, true, true, true);
|
||||||
renderpass_config.set_depth_mask(false);
|
renderpass_config.set_depth_mask(false);
|
||||||
|
@ -745,9 +771,32 @@ namespace vk
|
||||||
m_ubo.unmap();
|
m_ubo.unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_primitive_type(rsx::overlays::primitive_type type)
|
||||||
|
{
|
||||||
|
m_current_primitive_type = type;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case rsx::overlays::primitive_type::quad_list:
|
||||||
|
case rsx::overlays::primitive_type::triangle_strip:
|
||||||
|
renderpass_config.set_primitive_type(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
|
||||||
|
break;
|
||||||
|
case rsx::overlays::primitive_type::line_list:
|
||||||
|
renderpass_config.set_primitive_type(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||||
|
break;
|
||||||
|
case rsx::overlays::primitive_type::line_strip:
|
||||||
|
renderpass_config.set_primitive_type(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unexpected primitive type %d" HERE, static_cast<s32>(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void emit_geometry(vk::command_buffer &cmd) override
|
void emit_geometry(vk::command_buffer &cmd) override
|
||||||
{
|
{
|
||||||
//Split into groups of 4
|
if (m_current_primitive_type == rsx::overlays::primitive_type::quad_list)
|
||||||
|
{
|
||||||
|
// Emulate quads with disjointed triangle strips
|
||||||
u32 first = 0;
|
u32 first = 0;
|
||||||
u32 num_quads = num_drawable_elements / 4;
|
u32 num_quads = num_drawable_elements / 4;
|
||||||
|
|
||||||
|
@ -757,6 +806,11 @@ namespace vk
|
||||||
first += 4;
|
first += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
overlay_pass::emit_geometry(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* target, VkRenderPass render_pass,
|
void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* target, VkRenderPass render_pass,
|
||||||
vk::data_heap &upload_heap, rsx::overlays::overlay &ui)
|
vk::data_heap &upload_heap, rsx::overlays::overlay &ui)
|
||||||
|
@ -771,6 +825,7 @@ namespace vk
|
||||||
const u32 value_count = num_drawable_elements * 4;
|
const u32 value_count = num_drawable_elements * 4;
|
||||||
|
|
||||||
upload_vertex_data((f32*)command.verts.data(), value_count);
|
upload_vertex_data((f32*)command.verts.data(), value_count);
|
||||||
|
set_primitive_type(command.config.primitives);
|
||||||
|
|
||||||
m_skip_texture_read = false;
|
m_skip_texture_read = false;
|
||||||
m_color = command.config.color;
|
m_color = command.config.color;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue