diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 1f953779dd..67d0cb3695 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -564,3 +564,34 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, rsx::surface_ac // TODO: Preserve memory outside surface clip region on_write(newest_tag); } + +// MSAA support +gl::viewable_image* gl::render_target::get_resolve_target_safe(gl::command_context& cmd) +{ + if (!resolve_surface) + { + // Create a resolve surface + const auto resolve_w = width() * samples_x; + const auto resolve_h = height() * samples_y; + + resolve_surface.reset(new gl::viewable_image( + GL_TEXTURE_2D, + resolve_w, resolve_h, + 1, 1, 1, + static_cast(get_internal_format()), + format_class() + )); + } + + return static_cast(resolve_surface.get()); +} + +void gl::render_target::resolve(gl::command_context& cmd) +{ + // TODO +} + +void gl::render_target::unresolve(gl::command_context& cmd) +{ + // TODO +} diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index 20cefe206f..7e0abb91f4 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -53,9 +53,17 @@ namespace gl void load_memory(gl::command_context& cmd); void initialize_memory(gl::command_context& cmd, rsx::surface_access access); + // MSAA support: + // Get the linear resolve target bound to this surface. Initialize if none exists + gl::viewable_image* get_resolve_target_safe(gl::command_context& cmd); + // Resolve the planar MSAA data into a linear block + void resolve(gl::command_context& cmd); + // Unresolve the linear data into planar MSAA data + void unresolve(gl::command_context& cmd); + public: - render_target(GLuint width, GLuint height, GLenum sized_format, rsx::format_class format_class) - : viewable_image(GL_TEXTURE_2D, width, height, 1, 1, sized_format, format_class) + render_target(GLuint width, GLuint height, GLubyte samples, GLenum sized_format, rsx::format_class format_class) + : viewable_image(GL_TEXTURE_2D, width, height, 1, 1, samples, sized_format, format_class) {} // Internal pitch is the actual row length in bytes of the openGL texture @@ -141,7 +149,20 @@ struct gl_render_target_traits auto format = rsx::internals::surface_color_format_to_gl(surface_color_format); const auto [width_, height_] = rsx::apply_resolution_scale(static_cast(width), static_cast(height)); - std::unique_ptr result(new gl::render_target(width_, height_, + u8 samples; + rsx::surface_sample_layout sample_layout; + if (g_cfg.video.antialiasing_level == msaa_level::_auto) + { + samples = get_format_sample_count(antialias); + sample_layout = rsx::surface_sample_layout::ps3; + } + else + { + samples = 1; + sample_layout = rsx::surface_sample_layout::null; + } + + std::unique_ptr result(new gl::render_target(width_, height_, samples, static_cast(format.internal_format), RSX_FORMAT_CLASS_COLOR)); result->set_aa_mode(antialias); @@ -170,7 +191,20 @@ struct gl_render_target_traits auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format); const auto [width_, height_] = rsx::apply_resolution_scale(static_cast(width), static_cast(height)); - std::unique_ptr result(new gl::render_target(width_, height_, + u8 samples; + rsx::surface_sample_layout sample_layout; + if (g_cfg.video.antialiasing_level == msaa_level::_auto) + { + samples = get_format_sample_count(antialias); + sample_layout = rsx::surface_sample_layout::ps3; + } + else + { + samples = 1; + sample_layout = rsx::surface_sample_layout::null; + } + + std::unique_ptr result(new gl::render_target(width_, height_, samples, static_cast(format.internal_format), rsx::classify_format(surface_depth_format))); result->set_aa_mode(antialias); @@ -200,7 +234,7 @@ struct gl_render_target_traits const auto [new_w, new_h] = rsx::apply_resolution_scale(prev.width, prev.height, ref->get_surface_width(), ref->get_surface_height()); - sink = std::make_unique(new_w, new_h, internal_format, ref->format_class()); + sink = std::make_unique(new_w, new_h, ref->samples(), internal_format, ref->format_class()); sink->add_ref(); sink->memory_usage_flags = rsx::surface_usage_flags::storage;