diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index b1eb4fa82d..1ea8aa5f39 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -437,7 +437,7 @@ error_code cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; } - if (g_cfg.video.enable_3d) + if (g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled) { // Return Playstation 3D display value // Some games call this function when 3D is enabled diff --git a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp index cb4a8ed4cf..eaf3ef4b51 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp @@ -181,7 +181,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptrresolutionId, &res) != CELL_OK || - (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && !g_cfg.video.enable_3d)) + (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && g_cfg.video.stereo_render_mode == stereo_render_mode_options::disabled)) { // Resolution not supported cellSysutil.error("Unusual resolution requested: 0x%x", config->resolutionId); @@ -190,7 +190,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptrget(); conf.resolution_id = config->resolutionId; - conf._3d = config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING; + conf.stereo_mode = (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING) ? g_cfg.video.stereo_render_mode.get() : stereo_render_mode_options::disabled; conf.aspect = config->aspect; conf.format = config->format; conf.scanline_pitch = config->pitch; @@ -301,7 +301,7 @@ error_code cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptravailableModes[0].resolutionId = ::at32(g_video_out_resolution_id, g_cfg.video.resolution); info->availableModes[0].scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE; - if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720) + if (g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled && g_cfg.video.resolution == video_resolution::_720) { // Register 3D-capable display mode info->availableModes[1] = info->availableModes[0]; @@ -346,7 +346,7 @@ error_code cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, return not_an_error(1); } - if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720) + if ((g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled) && g_cfg.video.resolution == video_resolution::_720) { switch (resolutionId) { diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 3a81bd890e..4777d8b7f1 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -467,30 +467,69 @@ namespace gl "layout(location=0) in vec2 tc0;\n" "layout(location=0) out vec4 ocol;\n" "\n" + "#define STEREO_MODE_DISABLED 0\n" + "#define STEREO_MODE_ANAGLYPH 1\n" + "#define STEREO_MODE_SIDE_BY_SIDE 2\n" + "#define STEREO_MODE_OVER_UNDER 3\n" + "\n" + "vec2 sbs_single_matrix = vec2(2.0,0.4898f);\n" + "vec2 sbs_multi_matrix = vec2(2.0,1.0);\n" + "vec2 ou_single_matrix = vec2(1.0,0.9796f);\n" + "vec2 ou_multi_matrix = vec2(1.0,2.0);\n" + "\n" "uniform float gamma;\n" "uniform int limit_range;\n" - "uniform int stereo;\n" + "uniform int stereo_display_mode;\n" "uniform int stereo_image_count;\n" "\n" "vec4 read_source()\n" "{\n" - " if (stereo == 0) return texture(fs0, tc0);\n" + " if (stereo_display_mode == STEREO_MODE_DISABLED) return texture(fs0, tc0);\n" "\n" " vec4 left, right;\n" - " if (stereo_image_count == 2)\n" + " if (stereo_image_count == 1)\n" " {\n" - " left = texture(fs0, tc0);\n" - " right = texture(fs1, tc0);\n" + " switch (stereo_display_mode)\n" + " {\n" + " case STEREO_MODE_ANAGLYPH:\n" + " left = texture(fs0, tc0 * vec2(1.f, 0.4898f));\n" + " right = texture(fs0, (tc0 * vec2(1.f, 0.4898f)) + vec2(0.f, 0.510204f));\n" + " return vec4(left.r, right.g, right.b, 1.f);\n" + " case STEREO_MODE_SIDE_BY_SIDE:\n" + " if (tc0.x < 0.5) return texture(fs0, tc0* sbs_single_matrix);\n" + " else return texture(fs0, (tc0* sbs_single_matrix) + vec2(-1.f, 0.510204f));\n" + " case STEREO_MODE_OVER_UNDER:\n" + " if (tc0.y < 0.5) return texture(fs0, tc0* ou_single_matrix);\n" + " else return texture(fs0, (tc0* ou_single_matrix) + vec2(0.f, 0.020408f) );\n" + " default:\n" // undefined behavior + " return texture(fs0,tc0);\n" + " }\n" + " }\n" + " else if (stereo_image_count == 2)\n" + " {\n" + " switch (stereo_display_mode)\n" + " {\n" + " case STEREO_MODE_ANAGLYPH:\n" + " left = texture(fs0, tc0);\n" + " right = texture(fs1, tc0);\n" + " return vec4(left.r, right.g, right.b, 1.f);\n" + " case STEREO_MODE_SIDE_BY_SIDE:\n" + " if (tc0.x < 0.5) return texture(fs0,(tc0 * sbs_multi_matrix));\n" + " else return texture(fs1,(tc0 * sbs_multi_matrix) + vec2(-1.f,0.f));\n" + " case STEREO_MODE_OVER_UNDER:\n" + " if (tc0.y < 0.5) return texture(fs0,(tc0 * ou_multi_matrix));\n" + " else return texture(fs1,(tc0 * ou_multi_matrix) + vec2(0.f,-1.f));\n" + " default:\n" // undefined behavior + " return texture(fs0,tc0);\n" + " }\n" " }\n" - " else\n" " {\n" " vec2 coord_left = tc0 * vec2(1.f, 0.4898f);\n" " vec2 coord_right = coord_left + vec2(0.f, 0.510204f);\n" " left = texture(fs0, coord_left);\n" " right = texture(fs0, coord_right);\n" + " return vec4(left.r, right.g, right.b, 1.);\n" " }\n" - "\n" - " return vec4(left.r, right.g, right.b, 1.);\n" "}\n" "\n" "void main()\n" @@ -506,7 +545,7 @@ namespace gl m_input_filter = gl::filter::linear; } - void video_out_calibration_pass::run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d, gl::filter input_filter) + void video_out_calibration_pass::run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, gl::filter input_filter) { if (m_input_filter != input_filter) { @@ -516,7 +555,7 @@ namespace gl } program_handle.uniforms["gamma"] = gamma; program_handle.uniforms["limit_range"] = limited_rgb + 0; - program_handle.uniforms["stereo"] = _3d + 0; + program_handle.uniforms["stereo_display_mode"] = static_cast(stereo_mode); program_handle.uniforms["stereo_image_count"] = (source[1] == GL_NONE? 1 : 2); saved_sampler_state saved(31, m_sampler); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index c4c5e0f1b5..5a9a9385b3 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -93,7 +93,7 @@ namespace gl { video_out_calibration_pass(); - void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d, gl::filter input_filter); + void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, gl::filter input_filter); }; struct rp_ssbo_to_generic_texture : public overlay_pass diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index d4c8e5d4f3..85d373b929 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -149,7 +149,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) if (!buffer_pitch) buffer_pitch = buffer_width * avconfig.get_bpp(); - const u32 video_frame_height = (!avconfig._3d ? avconfig.resolution_y : (avconfig.resolution_y - 30) / 2); + const u32 video_frame_height = (avconfig.stereo_mode == stereo_render_mode_options::disabled? avconfig.resolution_y : ((avconfig.resolution_y - 30) / 2)); buffer_width = std::min(buffer_width, avconfig.resolution_x); buffer_height = std::min(buffer_height, video_frame_height); } @@ -181,7 +181,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const auto image_to_flip_ = get_present_source(&present_info, avconfig); image_to_flip = image_to_flip_->id(); - if (avconfig._3d) [[unlikely]] + if (avconfig.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] { const auto [unused, min_expected_height] = rsx::apply_resolution_scale(RSX_SURFACE_DIMENSION_IGNORED, buffer_height + 30); if (image_to_flip_->height() < min_expected_height) @@ -269,7 +269,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) // TODO: Implement FSR for OpenGL and remove this fallback to bilinear const gl::filter filter = g_cfg.video.output_scaling == output_scaling_mode::nearest ? gl::filter::nearest : gl::filter::linear; - if (use_full_rgb_range_output && rsx::fcmp(avconfig.gamma, 1.f) && !avconfig._3d) + if (use_full_rgb_range_output && rsx::fcmp(avconfig.gamma, 1.f) && avconfig.stereo_mode == stereo_render_mode_options::disabled) { // Blit source image to the screen m_flip_fbo.recreate(); @@ -286,7 +286,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const rsx::simple_array images{ image_to_flip, image_to_flip2 }; gl::screen.bind(); - m_video_output_pass.run(cmd, areau(aspect_ratio), images, gamma, limited_range, avconfig._3d, filter); + m_video_output_pass.run(cmd, areau(aspect_ratio), images, gamma, limited_range, avconfig.stereo_mode, filter); } } diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index 87f856020e..b3b378cc00 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -893,23 +893,64 @@ namespace vk "layout(location=0) in vec2 tc0;\n" "layout(location=0) out vec4 ocol;\n" "\n" + "#define STEREO_MODE_DISABLED 0\n" + "#define STEREO_MODE_ANAGLYPH 1\n" + "#define STEREO_MODE_SIDE_BY_SIDE 2\n" + "#define STEREO_MODE_OVER_UNDER 3\n" + "\n" + "vec2 sbs_single_matrix = vec2(2.0,0.4898f);\n" + "vec2 sbs_multi_matrix = vec2(2.0,1.0);\n" + "vec2 ou_single_matrix = vec2(1.0,0.9796f);\n" + "vec2 ou_multi_matrix = vec2(1.0,2.0);\n" + "\n" "layout(push_constant) uniform static_data\n" "{\n" " float gamma;\n" " int limit_range;\n" - " int stereo;\n" + " int stereo_display_mode;\n" " int stereo_image_count;\n" "};\n" "\n" "vec4 read_source()\n" "{\n" - " if (stereo == 0) return texture(fs0, tc0);\n" + " if (stereo_display_mode == STEREO_MODE_DISABLED) return texture(fs0, tc0);\n" "\n" " vec4 left, right;\n" - " if (stereo_image_count == 2)\n" + " if (stereo_image_count == 1)\n" " {\n" - " left = texture(fs0, tc0);\n" - " right = texture(fs1, tc0);\n" + " switch (stereo_display_mode)\n" + " {\n" + " case STEREO_MODE_ANAGLYPH:\n" + " left = texture(fs0, tc0 * vec2(1.f, 0.4898f));\n" + " right = texture(fs0, (tc0 * vec2(1.f, 0.4898f)) + vec2(0.f, 0.510204f));\n" + " return vec4(left.r, right.g, right.b, 1.f);\n" + " case STEREO_MODE_SIDE_BY_SIDE:\n" + " if (tc0.x < 0.5) return texture(fs0, tc0* sbs_single_matrix);\n" + " else return texture(fs0, (tc0* sbs_single_matrix) + vec2(-1.f, 0.510204f));\n" + " case STEREO_MODE_OVER_UNDER:\n" + " if (tc0.y < 0.5) return texture(fs0, tc0* ou_single_matrix);\n" + " else return texture(fs0, (tc0* ou_single_matrix) + vec2(0.f, 0.020408f) );\n" + " default:\n" // undefined behavior + " return texture(fs0,tc0);\n" + " }\n" + " }\n" + " else if (stereo_image_count == 2)\n" + " {\n" + " switch (stereo_display_mode)\n" + " {\n" + " case STEREO_MODE_ANAGLYPH:\n" + " left = texture(fs0, tc0);\n" + " right = texture(fs1, tc0);\n" + " return vec4(left.r, right.g, right.b, 1.f);\n" + " case STEREO_MODE_SIDE_BY_SIDE:\n" + " if (tc0.x < 0.5) return texture(fs0,(tc0 * sbs_multi_matrix));\n" + " else return texture(fs1,(tc0 * sbs_multi_matrix) + vec2(-1.f,0.f));\n" + " case STEREO_MODE_OVER_UNDER:\n" + " if (tc0.y < 0.5) return texture(fs0,(tc0 * ou_multi_matrix));\n" + " else return texture(fs1,(tc0 * ou_multi_matrix) + vec2(0.f,-1.f));\n" + " default:\n" // undefined behavior + " return texture(fs0,tc0);\n" + " }\n" " }\n" " else\n" " {\n" @@ -917,9 +958,8 @@ namespace vk " vec2 coord_right = coord_left + vec2(0.f, 0.510204f);\n" " left = texture(fs0, coord_left);\n" " right = texture(fs0, coord_right);\n" + " return vec4(left.r, right.g, right.b, 1.);\n" " }\n" - "\n" - " return vec4(left.r, right.g, right.b, 1.);\n" "}\n" "\n" "void main()\n" @@ -955,11 +995,11 @@ namespace vk } void video_out_calibration_pass::run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target, - const rsx::simple_array& src, f32 gamma, bool limited_rgb, bool _3d, VkRenderPass render_pass) + const rsx::simple_array& src, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, VkRenderPass render_pass) { config.gamma = gamma; config.limit_range = limited_rgb? 1 : 0; - config.stereo = _3d? 1 : 0; + config.stereo_display_mode = static_cast(stereo_mode); config.stereo_image_count = std::min(::size32(src), 2u); std::vector views; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index 1df1104ac7..26ad73f74e 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -211,7 +211,7 @@ namespace vk { float gamma; int limit_range; - int stereo; + int stereo_display_mode; int stereo_image_count; }; @@ -226,7 +226,7 @@ namespace vk 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& src, f32 gamma, bool limited_rgb, bool _3d, VkRenderPass render_pass); + const rsx::simple_array& src, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, VkRenderPass render_pass); }; // TODO: Replace with a proper manager diff --git a/rpcs3/Emu/RSX/VK/VKPresent.cpp b/rpcs3/Emu/RSX/VK/VKPresent.cpp index 27c09b49e5..85c7067ece 100644 --- a/rpcs3/Emu/RSX/VK/VKPresent.cpp +++ b/rpcs3/Emu/RSX/VK/VKPresent.cpp @@ -460,7 +460,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) if (!buffer_pitch) buffer_pitch = buffer_width * avconfig.get_bpp(); - const u32 video_frame_height = (!avconfig._3d? avconfig.resolution_y : (avconfig.resolution_y - 30) / 2); + const u32 video_frame_height = (avconfig.stereo_mode == stereo_render_mode_options::disabled? avconfig.resolution_y : ((avconfig.resolution_y - 30) / 2)); buffer_width = std::min(buffer_width, avconfig.resolution_x); buffer_height = std::min(buffer_height, video_frame_height); } @@ -484,7 +484,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) image_to_flip = get_present_source(&present_info, avconfig); - if (avconfig._3d) [[unlikely]] + if (avconfig.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] { const auto [unused, min_expected_height] = rsx::apply_resolution_scale(RSX_SURFACE_DIMENSION_IGNORED, buffer_height + 30); if (image_to_flip->height() < min_expected_height) @@ -617,12 +617,12 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) { const bool use_full_rgb_range_output = g_cfg.video.full_rgb_range_output.get(); - if (!use_full_rgb_range_output || !rsx::fcmp(avconfig.gamma, 1.f) || avconfig._3d) [[unlikely]] + if (!use_full_rgb_range_output || !rsx::fcmp(avconfig.gamma, 1.f) || avconfig.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] { if (image_to_flip) calibration_src.push_back(image_to_flip); if (image_to_flip2) calibration_src.push_back(image_to_flip2); - if (m_output_scaling == output_scaling_mode::fsr && !avconfig._3d) // 3D will be implemented later + if (m_output_scaling == output_scaling_mode::fsr && avconfig.stereo_mode == stereo_render_mode_options::disabled) // 3D will be implemented later { // Run upscaling pass before the rest of the output effects pipeline // This can be done with all upscalers but we already get bilinear upscaling for free if we just out the filters directly @@ -653,7 +653,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) vk::get_overlay_pass()->run( *m_current_command_buffer, areau(aspect_ratio), direct_fbo, calibration_src, - avconfig.gamma, !use_full_rgb_range_output, avconfig._3d, single_target_pass); + avconfig.gamma, !use_full_rgb_range_output, avconfig.stereo_mode, single_target_pass); direct_fbo->release(); } diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 636f61c590..a8bf25c5bf 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -153,7 +153,7 @@ namespace rsx struct avconf { - bool _3d = false; // Stereo 3D off + stereo_render_mode_options stereo_mode = stereo_render_mode_options::disabled; // Stereo 3D display mode u8 format = 0; // XRGB u8 aspect = 0; // AUTO u8 resolution_id = 2; // 720p diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index d732fa670e..e2f3488330 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -160,7 +160,7 @@ struct cfg_root : cfg::node cfg::_bool strict_texture_flushing{ this, "Strict Texture Flushing", false }; cfg::_bool multithreaded_rsx{ this, "Multithreaded RSX", false }; cfg::_bool relaxed_zcull_sync{ this, "Relaxed ZCULL Sync", false }; - cfg::_bool enable_3d{ this, "Enable 3D", false }; + cfg::_enum stereo_render_mode{ this, "3D Display Mode", stereo_render_mode_options::disabled }; cfg::_bool debug_program_analyser{ this, "Debug Program Analyser", false }; cfg::_bool precise_zpass_count{ this, "Accurate ZCULL stats", true }; cfg::_int<1, 8> consecutive_frames_to_draw{ this, "Consecutive Frames To Draw", 1, true}; diff --git a/rpcs3/Emu/system_config_types.cpp b/rpcs3/Emu/system_config_types.cpp index b096b52f10..9dd821486d 100644 --- a/rpcs3/Emu/system_config_types.cpp +++ b/rpcs3/Emu/system_config_types.cpp @@ -632,6 +632,23 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](stereo_render_mode_options value) + { + switch (value) + { + case stereo_render_mode_options::disabled: return "Disabled"; + case stereo_render_mode_options::anaglyph: return "Anaglyph"; + case stereo_render_mode_options::side_by_side: return "Side-by-Side"; + case stereo_render_mode_options::over_under: return "Over-Under"; + } + + return unknown; + }); +} + template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/rpcs3/Emu/system_config_types.h b/rpcs3/Emu/system_config_types.h index 5b414f311f..a257416d65 100644 --- a/rpcs3/Emu/system_config_types.h +++ b/rpcs3/Emu/system_config_types.h @@ -312,3 +312,11 @@ enum class output_scaling_mode bilinear, fsr }; + +enum class stereo_render_mode_options +{ + disabled, + anaglyph, + side_by_side, + over_under +}; diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index 3ebc6fdda5..282f5279f5 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -1267,6 +1267,15 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_ case vk_exclusive_fs_mode::enable: return tr("Prefer exclusive fullscreen", "Exclusive Fullscreen Mode"); } break; + case emu_settings_type::StereoRenderMode: + switch (static_cast(index)) + { + case stereo_render_mode_options::disabled: return tr("Disabled", "3D Display Mode"); + case stereo_render_mode_options::anaglyph: return tr("Anaglyph", "3D Display Mode"); + case stereo_render_mode_options::side_by_side: return tr("Side-by-side", "3D Display Mode"); + case stereo_render_mode_options::over_under: return tr("Over-under", "3D Display Mode"); + } + break; default: break; } diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 5806dfa8a1..da7bd4fa23 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -78,7 +78,7 @@ enum class emu_settings_type DisableFIFOReordering, StrictTextureFlushing, ShaderPrecisionQuality, - Enable3D, + StereoRenderMode, AnisotropicFilterOverride, TextureLodBias, ResolutionScale, @@ -253,7 +253,7 @@ inline static const QMap settings_location = { emu_settings_type::DisableOcclusionQueries, { "Video", "Disable ZCull Occlusion Queries"}}, { emu_settings_type::DisableVideoOutput, { "Video", "Disable Video Output"}}, { emu_settings_type::DisableFIFOReordering, { "Video", "Disable FIFO Reordering"}}, - { emu_settings_type::Enable3D, { "Video", "Enable 3D"}}, + { emu_settings_type::StereoRenderMode, { "Video", "3D Display Mode"}}, { emu_settings_type::StrictTextureFlushing, { "Video", "Strict Texture Flushing"}}, { emu_settings_type::ForceCPUBlitEmulation, { "Video", "Force CPU Blit"}}, { emu_settings_type::DisableOnDiskShaderCache, { "Video", "Disable On-Disk Shader Cache"}}, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 43e98dd67d..c9233da3a9 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -629,6 +629,10 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceComboBox(ui->outputScalingMode, emu_settings_type::OutputScalingMode); SubscribeTooltip(ui->outputScalingMode, tooltips.settings.output_scaling_mode); + // 3D + m_emu_settings->EnhanceComboBox(ui->stereoRenderMode, emu_settings_type::StereoRenderMode); + SubscribeTooltip(ui->gb_stereo, tooltips.settings.stereo_render_mode); + // Checkboxes: main options m_emu_settings->EnhanceCheckBox(ui->dumpColor, emu_settings_type::WriteColorBuffers); SubscribeTooltip(ui->dumpColor, tooltips.settings.dump_color); @@ -2207,9 +2211,6 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std m_emu_settings->EnhanceCheckBox(ui->strictTextureFlushing, emu_settings_type::StrictTextureFlushing); SubscribeTooltip(ui->strictTextureFlushing, tooltips.settings.strict_texture_flushing); - m_emu_settings->EnhanceCheckBox(ui->Enable3D, emu_settings_type::Enable3D); - SubscribeTooltip(ui->Enable3D, tooltips.settings.enable_3d); - m_emu_settings->EnhanceCheckBox(ui->gpuTextureScaling, emu_settings_type::GPUTextureScaling); SubscribeTooltip(ui->gpuTextureScaling, tooltips.settings.gpu_texture_scaling); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index a4c7fa4ff5..82f79e267c 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -559,6 +559,18 @@ + + + + 3D + + + + + + + + @@ -969,13 +981,6 @@ - - - - Enable 3D - - - diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index c522674217..5690f72102 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -112,7 +112,7 @@ public: const QString disable_fifo_reordering = tr("Disables RSX FIFO optimizations completely. Draws are processed as they are received by the DMA puller."); const QString gpu_texture_scaling = tr("Force all texture transfer, scaling and conversion operations on the GPU.\nMay cause texture corruption in some cases."); const QString strict_texture_flushing = tr("Forces texture flushing even in situations where it is not necessary/correct. Known to cause visual artifacts, but useful for debugging certain texture cache issues."); - const QString enable_3d = tr("Enables 3D stereo rendering.\nNote that only anaglyph viewing is supported at the moment."); + const QString stereo_render_mode = tr("Sets the 3D stereo rendering mode.\nAnaglyph is traditional blue-red.\nSide-by-Side is more commonly supported by VR viewer apps.\nOver-Under is closer to the native stereo output, but less commonly supported."); const QString accurate_ppu_128_loop = tr("When enabled, PPU atomic operations will operate on entire cache line data, as opposed to a single 64bit block of memory when disabled.\nNumerical values control whether or not to enable the accurate version based on the atomic operation's length."); const QString enable_performance_report = tr("Measure certain events and print a chart after the emulator is stopped. Don't enable if not asked to."); const QString num_ppu_threads = tr("Affects maximum amount of PPU threads running concurrently, the value of 1 has very low compatibility with games.\n2 is the default, if unsure do not modify this setting.");