diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index b4508ada5b..4851895537 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -520,7 +520,7 @@ error_code cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; } - if (g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled) + if (g_cfg.video.stereo_enabled) { // 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 e0db365933..a51ffbf756 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp @@ -202,7 +202,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptrresolutionId, &res) != CELL_OK || - (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && g_cfg.video.stereo_render_mode == stereo_render_mode_options::disabled)) + (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && !g_cfg.video.stereo_enabled)) { // Resolution not supported cellSysutil.error("Unusual resolution requested: 0x%x", config->resolutionId); @@ -211,7 +211,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptrget(); conf.resolution_id = config->resolutionId; - 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.stereo_enabled = (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING) && g_cfg.video.stereo_enabled; conf.aspect = config->aspect; conf.format = config->format; conf.scanline_pitch = config->pitch; @@ -393,7 +393,7 @@ error_code cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr& source, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, 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, + bool stereo_enabled, stereo_render_mode_options stereo_mode, gl::filter input_filter) { if (m_input_filter != input_filter) { @@ -498,7 +499,7 @@ namespace gl program_handle.uniforms["gamma"] = gamma; program_handle.uniforms["limit_range"] = limited_rgb + 0; - program_handle.uniforms["stereo_display_mode"] = static_cast(stereo_mode); + program_handle.uniforms["stereo_display_mode"] = stereo_enabled ? static_cast(stereo_mode) : 0; program_handle.uniforms["stereo_image_count"] = (source[1] == GL_NONE? 1 : 2); saved_sampler_state saved(GL_TEMP_IMAGE_SLOT(0), m_sampler); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index bd2be2d0ed..4399993cc7 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -97,7 +97,8 @@ 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, stereo_render_mode_options stereo_mode, gl::filter input_filter); + void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, + bool stereo_enabled, stereo_render_mode_options stereo_mode, gl::filter input_filter); }; struct rp_ssbo_to_generic_texture final : public overlay_pass diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index 33547c63cc..238999ea98 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -221,7 +221,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) image_to_flip = get_present_source(&present_info, avconfig); - if (avconfig.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] + if (avconfig.stereo_enabled) [[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) @@ -323,7 +323,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) } } - if (!backbuffer_has_alpha && use_full_rgb_range_output && rsx::fcmp(avconfig.gamma, 1.f) && avconfig.stereo_mode == stereo_render_mode_options::disabled) + if (!backbuffer_has_alpha && use_full_rgb_range_output && rsx::fcmp(avconfig.gamma, 1.f) && !avconfig.stereo_enabled) { // Blit source image to the screen m_upscaler->scale_output(cmd, image_to_flip, screen_area, aspect_ratio.flipped_vertical(), UPSCALE_AND_COMMIT | UPSCALE_DEFAULT_VIEW); @@ -335,7 +335,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const auto filter = m_output_scaling == output_scaling_mode::nearest ? gl::filter::nearest : gl::filter::linear; rsx::simple_array images{ image_to_flip, image_to_flip2 }; - if (m_output_scaling == output_scaling_mode::fsr && avconfig.stereo_mode == stereo_render_mode_options::disabled) // 3D will be implemented later + if (m_output_scaling == output_scaling_mode::fsr && !avconfig.stereo_enabled) // 3D will be implemented later { for (unsigned i = 0; i < 2 && images[i]; ++i) { @@ -345,7 +345,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) } gl::screen.bind(); - m_video_output_pass.run(cmd, areau(aspect_ratio), images.map(FN(x ? x->id() : GL_NONE)), gamma, limited_range, avconfig.stereo_mode, filter); + m_video_output_pass.run(cmd, areau(aspect_ratio), images.map(FN(x ? x->id() : GL_NONE)), gamma, limited_range, avconfig.stereo_enabled, g_cfg.video.stereo_render_mode, filter); } } diff --git a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp index c153712443..5f7959f77b 100644 --- a/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp +++ b/rpcs3/Emu/RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp @@ -49,6 +49,11 @@ namespace rsx add_checkbox(&g_cfg.video.stretch_to_display_area, localized_string_id::HOME_MENU_SETTINGS_VIDEO_STRETCH_TO_DISPLAY); + if (g_cfg.video.stereo_enabled) + { + add_dropdown(&g_cfg.video.stereo_render_mode, localized_string_id::HOME_MENU_SETTINGS_VIDEO_STEREO_MODE); + } + apply_layout(); } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index f0a72c05fc..bdb75531e7 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -737,7 +737,7 @@ namespace rsx return; } - ar(stereo_mode, format, aspect, resolution_id, scanline_pitch, gamma, resolution_x, resolution_y, state, scan_mode); + ar(stereo_enabled, format, aspect, resolution_id, scanline_pitch, gamma, resolution_x, resolution_y, state, scan_mode); } void thread::capture_frame(const std::string& name) diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index 34ca64ca66..e377e1efdf 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -894,11 +894,12 @@ 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, stereo_render_mode_options stereo_mode, VkRenderPass render_pass) + const rsx::simple_array& src, f32 gamma, bool limited_rgb, + bool stereo_enabled, stereo_render_mode_options stereo_mode, VkRenderPass render_pass) { config.gamma = gamma; config.limit_range = limited_rgb? 1 : 0; - config.stereo_display_mode = static_cast(stereo_mode); + config.stereo_display_mode = stereo_enabled ? static_cast(stereo_mode) : 0; 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 a968f706a1..3a812f1f2c 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -220,7 +220,8 @@ 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, stereo_render_mode_options stereo_mode, VkRenderPass render_pass); + const rsx::simple_array& src, f32 gamma, bool limited_rgb, + bool stereo_enabled, 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 f5b43e5cd8..fa729f319c 100644 --- a/rpcs3/Emu/RSX/VK/VKPresent.cpp +++ b/rpcs3/Emu/RSX/VK/VKPresent.cpp @@ -483,7 +483,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) }; image_to_flip = get_present_source(&present_info, avconfig); - if (avconfig.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] + if (avconfig.stereo_enabled) [[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.stereo_mode != stereo_render_mode_options::disabled) [[unlikely]] + if (!use_full_rgb_range_output || !rsx::fcmp(avconfig.gamma, 1.f) || avconfig.stereo_enabled) [[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.stereo_mode == stereo_render_mode_options::disabled) // 3D will be implemented later + if (m_output_scaling == output_scaling_mode::fsr && !avconfig.stereo_enabled) // 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.stereo_mode, single_target_pass); + avconfig.gamma, !use_full_rgb_range_output, avconfig.stereo_enabled, g_cfg.video.stereo_render_mode, single_target_pass); direct_fbo->release(); } diff --git a/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp b/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp index 03ce077bcc..257d93e42e 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp @@ -47,35 +47,35 @@ namespace vk vkDestroyFramebuffer(m_device, value, nullptr); } - u32 width() + u32 width() const { return m_width; } - u32 height() + u32 height() const { return m_height; } - u8 samples() + u8 samples() const { ensure(!attachments.empty()); return attachments[0]->image()->samples(); } - VkFormat format() + VkFormat format() const { ensure(!attachments.empty()); return attachments[0]->image()->format(); } - VkFormat depth_format() + VkFormat depth_format() const { ensure(!attachments.empty()); return attachments.back()->image()->format(); } - bool matches(const std::vector& fbo_images, u32 width, u32 height) + bool matches(const std::vector& fbo_images, u32 width, u32 height) const { if (m_width != width || m_height != height) return false; diff --git a/rpcs3/Emu/RSX/rsx_utils.cpp b/rpcs3/Emu/RSX/rsx_utils.cpp index 62914df054..9ce4565139 100644 --- a/rpcs3/Emu/RSX/rsx_utils.cpp +++ b/rpcs3/Emu/RSX/rsx_utils.cpp @@ -189,7 +189,7 @@ namespace rsx size2u avconf::video_frame_size() const { - if (state && stereo_mode != stereo_render_mode_options::disabled) + if (state && stereo_enabled) { return size2u{ resolution_x, (resolution_y - 30) / 2 }; } diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 5ff3f0851a..8fec69f88a 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -149,16 +149,16 @@ namespace rsx struct avconf { - 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 - u32 scanline_pitch = 0; // PACKED - atomic_t gamma = 1.f; // NO GAMMA CORRECTION - u32 resolution_x = 1280; // X RES - u32 resolution_y = 720; // Y RES - atomic_t state = 0; // 1 after cellVideoOutConfigure was called - u8 scan_mode = 1; // CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE + bool stereo_enabled = false; // Stereo 3D display mode + u8 format = 0; // XRGB + u8 aspect = 0; // AUTO + u8 resolution_id = 2; // 720p + u32 scanline_pitch = 0; // PACKED + atomic_t gamma = 1.f; // NO GAMMA CORRECTION + u32 resolution_x = 1280; // X RES + u32 resolution_y = 720; // Y RES + atomic_t state = 0; // 1 after cellVideoOutConfigure was called + u8 scan_mode = 1; // CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE ENABLE_BITWISE_SERIALIZATION; SAVESTATE_INIT_POS(12); diff --git a/rpcs3/Emu/localized_string_id.h b/rpcs3/Emu/localized_string_id.h index ce0139943d..7f741f10d6 100644 --- a/rpcs3/Emu/localized_string_id.h +++ b/rpcs3/Emu/localized_string_id.h @@ -217,6 +217,7 @@ enum class localized_string_id HOME_MENU_SETTINGS_VIDEO_OUTPUT_SCALING, HOME_MENU_SETTINGS_VIDEO_RCAS_SHARPENING, HOME_MENU_SETTINGS_VIDEO_STRETCH_TO_DISPLAY, + HOME_MENU_SETTINGS_VIDEO_STEREO_MODE, HOME_MENU_SETTINGS_INPUT, HOME_MENU_SETTINGS_INPUT_BACKGROUND_INPUT, HOME_MENU_SETTINGS_INPUT_KEEP_PADS_CONNECTED, diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 326ed991d6..826d3580bf 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -162,7 +162,8 @@ struct cfg_root : cfg::node cfg::_bool multithreaded_rsx{ this, "Multithreaded RSX", false }; cfg::_bool relaxed_zcull_sync{ this, "Relaxed ZCULL Sync", false }; cfg::_bool force_hw_MSAA_resolve{ this, "Force Hardware MSAA Resolve", false, true }; - cfg::_enum stereo_render_mode{ this, "3D Display Mode", stereo_render_mode_options::disabled }; + cfg::_bool stereo_enabled{ this, "3D Display Enabled", false }; + cfg::_enum stereo_render_mode{ this, "3D Display Mode", stereo_render_mode_options::disabled, true }; 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/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 62d2fbee1a..68afe18184 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -81,6 +81,7 @@ enum class emu_settings_type DisableFIFOReordering, StrictTextureFlushing, ShaderPrecisionQuality, + StereoRenderEnabled, StereoRenderMode, AnisotropicFilterOverride, TextureLodBias, @@ -284,6 +285,7 @@ inline static const std::map 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::StereoRenderEnabled, { "Video", "3D Display Enabled"}}, { emu_settings_type::StereoRenderMode, { "Video", "3D Display Mode"}}, { emu_settings_type::StrictTextureFlushing, { "Video", "Strict Texture Flushing"}}, { emu_settings_type::ForceCPUBlitEmulation, { "Video", "Force CPU Blit"}}, diff --git a/rpcs3/rpcs3qt/localized_emu.h b/rpcs3/rpcs3qt/localized_emu.h index 930cf0a1f3..8bb2bb5c34 100644 --- a/rpcs3/rpcs3qt/localized_emu.h +++ b/rpcs3/rpcs3qt/localized_emu.h @@ -238,6 +238,7 @@ private: case localized_string_id::HOME_MENU_SETTINGS_VIDEO_OUTPUT_SCALING: return tr("Output Scaling", "Video"); case localized_string_id::HOME_MENU_SETTINGS_VIDEO_RCAS_SHARPENING: return tr("FidelityFX CAS Sharpening Intensity", "Video"); case localized_string_id::HOME_MENU_SETTINGS_VIDEO_STRETCH_TO_DISPLAY: return tr("Stretch To Display Area", "Video"); + case localized_string_id::HOME_MENU_SETTINGS_VIDEO_STEREO_MODE: return tr("Stereo Mode", "Video"); case localized_string_id::HOME_MENU_SETTINGS_INPUT: return tr("Input"); case localized_string_id::HOME_MENU_SETTINGS_INPUT_BACKGROUND_INPUT: return tr("Background Input Enabled", "Input"); case localized_string_id::HOME_MENU_SETTINGS_INPUT_KEEP_PADS_CONNECTED: return tr("Keep Pads Connected", "Input"); diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 4ce035722d..8132f4bb28 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -640,21 +640,27 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std // 3D m_emu_settings->EnhanceComboBox(ui->stereoRenderMode, emu_settings_type::StereoRenderMode); + m_emu_settings->EnhanceCheckBox(ui->stereoRenderEnabled, emu_settings_type::StereoRenderEnabled); SubscribeTooltip(ui->gb_stereo, tooltips.settings.stereo_render_mode); if (game) { - const auto on_resolution = [this](int index) + const auto enable_3D_modes = [this]() { - const auto [text, value] = get_data(ui->resBox, index); - ui->stereoRenderMode->setEnabled(value == static_cast(video_resolution::_720p)); + const auto [text, value] = get_data(ui->resBox, ui->resBox->currentIndex()); + const bool stereo_allowed = value == static_cast(video_resolution::_720p); + const bool stereo_enabled = ui->stereoRenderEnabled->checkState() == Qt::CheckState::Checked; + ui->stereoRenderMode->setEnabled(stereo_allowed && stereo_enabled); + ui->stereoRenderEnabled->setEnabled(stereo_allowed); }; - connect(ui->resBox, QOverload::of(&QComboBox::currentIndexChanged), this, on_resolution); - on_resolution(ui->resBox->currentIndex()); + connect(ui->resBox, QOverload::of(&QComboBox::currentIndexChanged), this, [enable_3D_modes](int){ enable_3D_modes(); }); + connect(ui->stereoRenderEnabled, &QCheckBox::checkStateChanged, this, [enable_3D_modes](Qt::CheckState){ enable_3D_modes(); }); + enable_3D_modes(); } else { ui->stereoRenderMode->setCurrentIndex(find_item(ui->stereoRenderMode, static_cast(g_cfg.video.stereo_render_mode.def))); - ui->stereoRenderMode->setEnabled(false); + ui->stereoRenderEnabled->setChecked(false); + ui->gb_stereo->setEnabled(false); } // Checkboxes: main options diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 4c19e65d66..b1a54adcb9 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -551,6 +551,13 @@ 3D + + + + Enable 3D Support + + +