Add alternate 3D display modes (#13582)

This commit is contained in:
headassbtw 2023-04-07 11:08:07 -07:00 committed by GitHub
parent 60fc51ed22
commit ec3114d6d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 170 additions and 51 deletions

View File

@ -437,7 +437,7 @@ error_code cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<f32> 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

View File

@ -181,7 +181,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
CellVideoOutResolution res;
if (_IntGetResolutionInfo(config->resolutionId, &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::ptr<CellVideoOutConfiguration
auto& conf = g_fxo->get<rsx::avconf>();
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::ptr<Cell
info->availableModes[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)
{

View File

@ -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<GLuint>& 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<GLuint>& 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<u8>(stereo_mode);
program_handle.uniforms["stereo_image_count"] = (source[1] == GL_NONE? 1 : 2);
saved_sampler_state saved(31, m_sampler);

View File

@ -93,7 +93,7 @@ namespace gl
{
video_out_calibration_pass();
void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array<GLuint>& 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<GLuint>& 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

View File

@ -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<true>(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<GLuint> 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);
}
}

View File

@ -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<vk::viewable_image*>& src, f32 gamma, bool limited_rgb, bool _3d, VkRenderPass render_pass)
const rsx::simple_array<vk::viewable_image*>& 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<u8>(stereo_mode);
config.stereo_image_count = std::min(::size32(src), 2u);
std::vector<vk::image_view*> views;

View File

@ -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<vk::viewable_image*>& src, f32 gamma, bool limited_rgb, bool _3d, VkRenderPass render_pass);
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb, stereo_render_mode_options stereo_mode, VkRenderPass render_pass);
};
// TODO: Replace with a proper manager

View File

@ -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<true>(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<vk::video_out_calibration_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();
}

View File

@ -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

View File

@ -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_options> 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};

View File

@ -632,6 +632,23 @@ void fmt_class_string<vk_exclusive_fs_mode>::format(std::string& out, u64 arg)
});
}
template <>
void fmt_class_string<stereo_render_mode_options>::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<output_scaling_mode>::format(std::string& out, u64 arg)
{

View File

@ -312,3 +312,11 @@ enum class output_scaling_mode
bilinear,
fsr
};
enum class stereo_render_mode_options
{
disabled,
anaglyph,
side_by_side,
over_under
};

View File

@ -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<stereo_render_mode_options>(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;
}

View File

@ -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<emu_settings_type, cfg_location> 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"}},

View File

@ -629,6 +629,10 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> 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> 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);

View File

@ -559,6 +559,18 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_stereo">
<property name="title">
<string>3D</string>
</property>
<layout class="QVBoxLayout" name="gb_stereo_layout">
<item>
<widget class="QComboBox" name="stereoRenderMode"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="gpu_tab_layout_right_spacer">
<property name="orientation">
@ -969,13 +981,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="Enable3D">
<property name="text">
<string>Enable 3D</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="disableVertexCache">
<property name="text">

View File

@ -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.");