mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
gl: Implement remaining resolvers
- Add support for NVIDIA cards - Implement all depth-stencil resolver passes
This commit is contained in:
parent
558ff9fea6
commit
4c545430f1
5 changed files with 135 additions and 15 deletions
|
@ -75,7 +75,7 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
void overlay_pass::emit_geometry()
|
||||
void overlay_pass::emit_geometry(gl::command_context& /*cmd*/)
|
||||
{
|
||||
int old_vao;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
|
||||
|
@ -176,7 +176,7 @@ namespace gl
|
|||
cmd->use_program(program_handle.id());
|
||||
on_load();
|
||||
bind_resources();
|
||||
emit_geometry();
|
||||
emit_geometry(cmd);
|
||||
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
|
||||
|
@ -350,7 +350,7 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
void ui_overlay_renderer::emit_geometry()
|
||||
void ui_overlay_renderer::emit_geometry(gl::command_context& cmd)
|
||||
{
|
||||
if (m_current_primitive_type == rsx::overlays::primitive_type::quad_list)
|
||||
{
|
||||
|
@ -378,7 +378,7 @@ namespace gl
|
|||
}
|
||||
else
|
||||
{
|
||||
overlay_pass::emit_geometry();
|
||||
overlay_pass::emit_geometry(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace gl
|
|||
m_vertex_data_buffer.data(elements_count * sizeof(T), data);
|
||||
}
|
||||
|
||||
virtual void emit_geometry();
|
||||
virtual void emit_geometry(gl::command_context& cmd);
|
||||
|
||||
void run(gl::command_context& cmd, const areau& region, GLuint target_texture, GLuint image_aspect_bits, bool enable_blending = false);
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ namespace gl
|
|||
|
||||
void set_primitive_type(rsx::overlays::primitive_type type);
|
||||
|
||||
void emit_geometry() override;
|
||||
void emit_geometry(gl::command_context& cmd) override;
|
||||
|
||||
void run(gl::command_context& cmd, const areau& viewport, GLuint target, rsx::overlays::overlay& ui);
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace gl
|
|||
{
|
||||
ensure(src->samples() > 1 && dst->samples() == 1);
|
||||
|
||||
ensure(src->format_class() == RSX_FORMAT_CLASS_COLOR); // TODO
|
||||
if (src->aspect() == gl::image_aspect::color) [[ likely ]]
|
||||
{
|
||||
auto& job = g_resolve_helpers[src->get_internal_format()];
|
||||
if (!job)
|
||||
|
@ -50,7 +50,50 @@ namespace gl
|
|||
}
|
||||
|
||||
job->run(cmd, src, dst);
|
||||
return;
|
||||
}
|
||||
|
||||
auto get_resolver_pass = [](GLuint aspect_bits) -> std::unique_ptr<ds_resolve_pass_base>&
|
||||
{
|
||||
auto& pass = g_depth_resolvers[aspect_bits];
|
||||
if (!pass)
|
||||
{
|
||||
ds_resolve_pass_base* ptr = nullptr;
|
||||
switch (aspect_bits)
|
||||
{
|
||||
case gl::image_aspect::depth:
|
||||
ptr = new depth_only_resolver();
|
||||
break;
|
||||
case gl::image_aspect::stencil:
|
||||
ptr = new stencil_only_resolver();
|
||||
break;
|
||||
case (gl::image_aspect::depth | gl::image_aspect::stencil):
|
||||
ptr = new depth_stencil_resolver();
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unreachable");
|
||||
}
|
||||
|
||||
pass.reset(ptr);
|
||||
}
|
||||
|
||||
return pass;
|
||||
};
|
||||
|
||||
if (src->aspect() == (gl::image_aspect::depth | gl::image_aspect::stencil) &&
|
||||
!gl::get_driver_caps().ARB_shader_stencil_export_supported)
|
||||
{
|
||||
// Special case, NVIDIA-only fallback
|
||||
auto& depth_pass = get_resolver_pass(gl::image_aspect::depth);
|
||||
depth_pass->run(cmd, src, dst);
|
||||
|
||||
auto& stencil_pass = get_resolver_pass(gl::image_aspect::stencil);
|
||||
stencil_pass->run(cmd, src, dst);
|
||||
return;
|
||||
}
|
||||
|
||||
auto& pass = get_resolver_pass(src->aspect());
|
||||
pass->run(cmd, src, dst);
|
||||
}
|
||||
|
||||
void unresolve_image(gl::command_context& cmd, gl::viewable_image* dst, gl::viewable_image* src)
|
||||
|
@ -100,8 +143,12 @@ namespace gl
|
|||
if (src->aspect() == (gl::image_aspect::depth | gl::image_aspect::stencil) &&
|
||||
!gl::get_driver_caps().ARB_shader_stencil_export_supported)
|
||||
{
|
||||
// Special handling
|
||||
rsx_log.error("Unsupported.");
|
||||
// Special case, NVIDIA-only fallback
|
||||
auto& depth_pass = get_unresolver_pass(gl::image_aspect::depth);
|
||||
depth_pass->run(cmd, dst, src);
|
||||
|
||||
auto& stencil_pass = get_unresolver_pass(gl::image_aspect::stencil);
|
||||
stencil_pass->run(cmd, dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -227,8 +274,31 @@ namespace gl
|
|||
rsx_log.notice("Resolve shader:\n%s", fs_src);
|
||||
}
|
||||
|
||||
void ds_resolve_pass_base::update_config()
|
||||
{
|
||||
ensure(multisampled && multisampled->samples() > 1);
|
||||
switch (multisampled->samples())
|
||||
{
|
||||
case 2:
|
||||
m_config.sample_count.x = 2;
|
||||
m_config.sample_count.y = 1;
|
||||
break;
|
||||
case 4:
|
||||
m_config.sample_count.x = m_config.sample_count.y = 2;
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unsupported sample count %d", multisampled->samples());
|
||||
}
|
||||
|
||||
program_handle.uniforms["sample_count"] = m_config.sample_count;
|
||||
}
|
||||
|
||||
void ds_resolve_pass_base::run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image)
|
||||
{
|
||||
multisampled = msaa_image;
|
||||
resolve = resolve_image;
|
||||
update_config();
|
||||
|
||||
const auto read_resource = m_config.is_unresolve ? resolve_image : msaa_image;
|
||||
saved_sampler_state saved(GL_TEMP_IMAGE_SLOT(0), m_sampler);
|
||||
cmd->bind_texture(GL_TEMP_IMAGE_SLOT(0), GL_TEXTURE_2D, read_resource->id());
|
||||
|
@ -242,4 +312,37 @@ namespace gl
|
|||
viewport.y2 = msaa_image->height();
|
||||
overlay_pass::run(cmd, viewport, GL_NONE, image_aspect_bits, false);
|
||||
}
|
||||
|
||||
void stencil_only_resolver_base::emit_geometry(gl::command_context& cmd)
|
||||
{
|
||||
// Modified version of the base overlay pass to emit 8 draws instead of 1
|
||||
int old_vao;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
|
||||
m_vao.bind();
|
||||
|
||||
// Start our inner loop
|
||||
for (s32 write_mask = 0x1; write_mask <= 0x80; write_mask <<= 1)
|
||||
{
|
||||
program_handle.uniforms["stencil_mask"] = write_mask;
|
||||
cmd->stencil_mask(write_mask);
|
||||
|
||||
glDrawArrays(primitives, 0, num_drawable_elements);
|
||||
}
|
||||
|
||||
glBindVertexArray(old_vao);
|
||||
}
|
||||
|
||||
void stencil_only_resolver_base::run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image)
|
||||
{
|
||||
const auto read_resource = m_config.is_unresolve ? resolve_image : msaa_image;
|
||||
auto stencil_view = read_resource->get_view(rsx::default_remap_vector.with_encoding(gl::GL_REMAP_IDENTITY), gl::image_aspect::stencil);
|
||||
|
||||
saved_sampler_state saved(GL_TEMP_IMAGE_SLOT(0), m_sampler);
|
||||
cmd->bind_texture(GL_TEMP_IMAGE_SLOT(0), GL_TEXTURE_2D, stencil_view->id());
|
||||
|
||||
areau viewport{};
|
||||
viewport.x2 = msaa_image->width();
|
||||
viewport.y2 = msaa_image->height();
|
||||
overlay_pass::run(cmd, viewport, GL_NONE, gl::image_aspect::stencil, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,11 +56,14 @@ namespace gl
|
|||
bool resolve_depth = false;
|
||||
bool resolve_stencil = false;
|
||||
bool is_unresolve = false;
|
||||
color2i sample_count;
|
||||
} m_config;
|
||||
|
||||
void build(bool depth, bool stencil, bool unresolve);
|
||||
|
||||
void run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image);
|
||||
void update_config();
|
||||
|
||||
virtual void run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image);
|
||||
};
|
||||
|
||||
struct depth_only_resolver : ds_resolve_pass_base
|
||||
|
@ -79,19 +82,33 @@ namespace gl
|
|||
}
|
||||
};
|
||||
|
||||
struct stencil_only_resolver : ds_resolve_pass_base
|
||||
struct stencil_only_resolver_base : ds_resolve_pass_base
|
||||
{
|
||||
virtual ~stencil_only_resolver_base() = default;
|
||||
|
||||
void build(bool is_unresolver)
|
||||
{
|
||||
ds_resolve_pass_base::build(false, true, is_unresolver);
|
||||
}
|
||||
|
||||
void emit_geometry(gl::command_context& cmd) override;
|
||||
|
||||
void run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image) override;
|
||||
};
|
||||
|
||||
struct stencil_only_resolver : stencil_only_resolver_base
|
||||
{
|
||||
stencil_only_resolver()
|
||||
{
|
||||
build(false, true, false);
|
||||
build(false);
|
||||
}
|
||||
};
|
||||
|
||||
struct stencil_only_unresolver : ds_resolve_pass_base
|
||||
struct stencil_only_unresolver : stencil_only_resolver_base
|
||||
{
|
||||
stencil_only_unresolver()
|
||||
{
|
||||
build(false, true, true);
|
||||
build(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace vk
|
|||
bool g_drv_sanitize_fp_values = false;
|
||||
bool g_drv_disable_fence_reset = false;
|
||||
bool g_drv_emulate_cond_render = false;
|
||||
bool g_drv_strict_query_scopes = false;
|
||||
bool g_drv_strict_query_scopes = true;
|
||||
bool g_drv_force_reuse_query_pools = false;
|
||||
|
||||
u64 g_num_processed_frames = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue