mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #5230 from B3n30/circumvent_apple_intel_hw_shader_issue
Add flag to disable seperable shaders for osx Intel GPUs.
This commit is contained in:
		
						commit
						007fb63e47
					
				
					 10 changed files with 54 additions and 14 deletions
				
			
		|  | @ -110,13 +110,13 @@ void Config::ReadValues() { | ||||||
|     // Renderer
 |     // Renderer
 | ||||||
|     Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", false); |     Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", false); | ||||||
|     Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); |     Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); | ||||||
|  |     Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true); | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
|     // Hardware shader is broken on macos thanks to poor drivers.
 |     // Separable shader is broken on macos with Intel GPU thanks to poor drivers.
 | ||||||
|     // We still want to provide this option for test/development purposes, but disable it by
 |     // We still want to provide this option for test/development purposes, but disable it by
 | ||||||
|     // default.
 |     // default.
 | ||||||
|     Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", false); |     Settings::values.separable_shader = | ||||||
| #else |         sdl2_config->GetBoolean("Renderer", "separable_shader", false); | ||||||
|     Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true); |  | ||||||
| #endif | #endif | ||||||
|     Settings::values.shaders_accurate_mul = |     Settings::values.shaders_accurate_mul = | ||||||
|         sdl2_config->GetBoolean("Renderer", "shaders_accurate_mul", false); |         sdl2_config->GetBoolean("Renderer", "shaders_accurate_mul", false); | ||||||
|  |  | ||||||
|  | @ -110,6 +110,10 @@ use_hw_renderer = | ||||||
| # 0: Software, 1 (default): Hardware | # 0: Software, 1 (default): Hardware | ||||||
| use_hw_shader = | use_hw_shader = | ||||||
| 
 | 
 | ||||||
|  | # Whether to use separable shaders to emulate 3DS shaders (macOS only) | ||||||
|  | # 0: Off (Default), 1 : On | ||||||
|  | separable_shader = | ||||||
|  | 
 | ||||||
| # Whether to use accurate multiplication in hardware shaders | # Whether to use accurate multiplication in hardware shaders | ||||||
| # 0: Off (Default. Faster, but causes issues in some games) 1: On (Slower, but correct) | # 0: Off (Default. Faster, but causes issues in some games) 1: On (Slower, but correct) | ||||||
| shaders_accurate_mul = | shaders_accurate_mul = | ||||||
|  |  | ||||||
|  | @ -431,13 +431,13 @@ void Config::ReadRendererValues() { | ||||||
| 
 | 
 | ||||||
|     Settings::values.use_hw_renderer = |     Settings::values.use_hw_renderer = | ||||||
|         ReadSetting(QStringLiteral("use_hw_renderer"), true).toBool(); |         ReadSetting(QStringLiteral("use_hw_renderer"), true).toBool(); | ||||||
|  |     Settings::values.use_hw_shader = ReadSetting(QStringLiteral("use_hw_shader"), true).toBool(); | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
|     // Hardware shader is broken on macos thanks to poor drivers.
 |     // Hardware shader is broken on macos with Intel GPUs thanks to poor drivers.
 | ||||||
|     // We still want to provide this option for test/development purposes, but disable it by
 |     // We still want to provide this option for test/development purposes, but disable it by
 | ||||||
|     // default.
 |     // default.
 | ||||||
|     Settings::values.use_hw_shader = ReadSetting(QStringLiteral("use_hw_shader"), false).toBool(); |     Settings::values.separable_shader = | ||||||
| #else |         ReadSetting(QStringLiteral("separable_shader"), false).toBool(); | ||||||
|     Settings::values.use_hw_shader = ReadSetting(QStringLiteral("use_hw_shader"), true).toBool(); |  | ||||||
| #endif | #endif | ||||||
|     Settings::values.shaders_accurate_mul = |     Settings::values.shaders_accurate_mul = | ||||||
|         ReadSetting(QStringLiteral("shaders_accurate_mul"), false).toBool(); |         ReadSetting(QStringLiteral("shaders_accurate_mul"), false).toBool(); | ||||||
|  | @ -916,13 +916,11 @@ void Config::SaveRendererValues() { | ||||||
|     qt_config->beginGroup(QStringLiteral("Renderer")); |     qt_config->beginGroup(QStringLiteral("Renderer")); | ||||||
| 
 | 
 | ||||||
|     WriteSetting(QStringLiteral("use_hw_renderer"), Settings::values.use_hw_renderer, true); |     WriteSetting(QStringLiteral("use_hw_renderer"), Settings::values.use_hw_renderer, true); | ||||||
|  |     WriteSetting(QStringLiteral("use_hw_shader"), Settings::values.use_hw_shader, true); | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
|     // Hardware shader is broken on macos thanks to poor drivers.
 |     // Hardware shader is broken on macos thanks to poor drivers.
 | ||||||
|     // We still want to provide this option for test/development purposes, but disable it by
 |     // TODO: enable this for none Intel GPUs
 | ||||||
|     // default.
 |     WriteSetting(QStringLiteral("use_separable_shader"), Settings::values.separable_shader, false); | ||||||
|     WriteSetting(QStringLiteral("use_hw_shader"), Settings::values.use_hw_shader, false); |  | ||||||
| #else |  | ||||||
|     WriteSetting(QStringLiteral("use_hw_shader"), Settings::values.use_hw_shader, true); |  | ||||||
| #endif | #endif | ||||||
|     WriteSetting(QStringLiteral("shaders_accurate_mul"), Settings::values.shaders_accurate_mul, |     WriteSetting(QStringLiteral("shaders_accurate_mul"), Settings::values.shaders_accurate_mul, | ||||||
|                  false); |                  false); | ||||||
|  |  | ||||||
|  | @ -29,15 +29,24 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) | ||||||
|     connect(ui->toggle_hw_shader, &QCheckBox::toggled, ui->hw_shader_group, &QWidget::setEnabled); |     connect(ui->toggle_hw_shader, &QCheckBox::toggled, ui->hw_shader_group, &QWidget::setEnabled); | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
|     connect(ui->toggle_hw_shader, &QCheckBox::stateChanged, this, [this](int state) { |     connect(ui->toggle_hw_shader, &QCheckBox::stateChanged, this, [this](int state) { | ||||||
|  |         if (state == Qt::Checked) { | ||||||
|  |             ui->toggle_separable_shader->setEnabled(true); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |     connect(ui->toggle_separable_shader, &QCheckBox::stateChanged, this, [this](int state) { | ||||||
|         if (state == Qt::Checked) { |         if (state == Qt::Checked) { | ||||||
|             QMessageBox::warning( |             QMessageBox::warning( | ||||||
|                 this, tr("Hardware Shader Warning"), |                 this, tr("Hardware Shader Warning"), | ||||||
|                 tr("Hardware Shader support is broken on macOS, and will cause graphical issues " |                 tr("Separable Shader support is broken on macOS with Intel GPUs, and will cause " | ||||||
|  |                    "graphical issues " | ||||||
|                    "like showing a black screen.<br><br>The option is only there for " |                    "like showing a black screen.<br><br>The option is only there for " | ||||||
|                    "test/development purposes. If you experience graphical issues with Hardware " |                    "test/development purposes. If you experience graphical issues with Hardware " | ||||||
|                    "Shader, please turn it off.")); |                    "Shader, please turn it off.")); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
|  | #else | ||||||
|  |     // TODO(B3N30): Hide this for macs with none Intel GPUs, too.
 | ||||||
|  |     ui->toggle_separable_shader->setVisible(false); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -46,6 +55,7 @@ ConfigureGraphics::~ConfigureGraphics() = default; | ||||||
| void ConfigureGraphics::SetConfiguration() { | void ConfigureGraphics::SetConfiguration() { | ||||||
|     ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer); |     ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer); | ||||||
|     ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader); |     ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader); | ||||||
|  |     ui->toggle_separable_shader->setChecked(Settings::values.separable_shader); | ||||||
|     ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul); |     ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul); | ||||||
|     ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit); |     ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit); | ||||||
|     ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new); |     ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new); | ||||||
|  | @ -54,6 +64,7 @@ void ConfigureGraphics::SetConfiguration() { | ||||||
| void ConfigureGraphics::ApplyConfiguration() { | void ConfigureGraphics::ApplyConfiguration() { | ||||||
|     Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked(); |     Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked(); | ||||||
|     Settings::values.use_hw_shader = ui->toggle_hw_shader->isChecked(); |     Settings::values.use_hw_shader = ui->toggle_hw_shader->isChecked(); | ||||||
|  |     Settings::values.separable_shader = ui->toggle_separable_shader->isChecked(); | ||||||
|     Settings::values.shaders_accurate_mul = ui->toggle_accurate_mul->isChecked(); |     Settings::values.shaders_accurate_mul = ui->toggle_accurate_mul->isChecked(); | ||||||
|     Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked(); |     Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked(); | ||||||
|     Settings::values.use_vsync_new = ui->toggle_vsync_new->isChecked(); |     Settings::values.use_vsync_new = ui->toggle_vsync_new->isChecked(); | ||||||
|  |  | ||||||
|  | @ -76,6 +76,13 @@ | ||||||
|             <property name="bottomMargin"> |             <property name="bottomMargin"> | ||||||
|              <number>0</number> |              <number>0</number> | ||||||
|             </property> |             </property> | ||||||
|  |             <item> | ||||||
|  |              <widget class="QCheckBox" name="toggle_separable_shader"> | ||||||
|  |               <property name="text"> | ||||||
|  |                <string>Separable Shader (Intel GPUs only)</string> | ||||||
|  |               </property> | ||||||
|  |              </widget> | ||||||
|  |             </item> | ||||||
|             <item> |             <item> | ||||||
|              <widget class="QCheckBox" name="toggle_accurate_mul"> |              <widget class="QCheckBox" name="toggle_accurate_mul"> | ||||||
|               <property name="toolTip"> |               <property name="toolTip"> | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ void Apply() { | ||||||
|     VideoCore::g_hw_renderer_enabled = values.use_hw_renderer; |     VideoCore::g_hw_renderer_enabled = values.use_hw_renderer; | ||||||
|     VideoCore::g_shader_jit_enabled = values.use_shader_jit; |     VideoCore::g_shader_jit_enabled = values.use_shader_jit; | ||||||
|     VideoCore::g_hw_shader_enabled = values.use_hw_shader; |     VideoCore::g_hw_shader_enabled = values.use_hw_shader; | ||||||
|  |     VideoCore::g_separable_shader_enabled = values.separable_shader; | ||||||
|     VideoCore::g_hw_shader_accurate_mul = values.shaders_accurate_mul; |     VideoCore::g_hw_shader_accurate_mul = values.shaders_accurate_mul; | ||||||
|     VideoCore::g_use_disk_shader_cache = values.use_disk_shader_cache; |     VideoCore::g_use_disk_shader_cache = values.use_disk_shader_cache; | ||||||
| 
 | 
 | ||||||
|  | @ -78,6 +79,7 @@ void LogSettings() { | ||||||
|     LogSetting("Renderer_UseGLES", Settings::values.use_gles); |     LogSetting("Renderer_UseGLES", Settings::values.use_gles); | ||||||
|     LogSetting("Renderer_UseHwRenderer", Settings::values.use_hw_renderer); |     LogSetting("Renderer_UseHwRenderer", Settings::values.use_hw_renderer); | ||||||
|     LogSetting("Renderer_UseHwShader", Settings::values.use_hw_shader); |     LogSetting("Renderer_UseHwShader", Settings::values.use_hw_shader); | ||||||
|  |     LogSetting("Renderer_SeparableShader", Settings::values.separable_shader); | ||||||
|     LogSetting("Renderer_ShadersAccurateMul", Settings::values.shaders_accurate_mul); |     LogSetting("Renderer_ShadersAccurateMul", Settings::values.shaders_accurate_mul); | ||||||
|     LogSetting("Renderer_UseShaderJit", Settings::values.use_shader_jit); |     LogSetting("Renderer_UseShaderJit", Settings::values.use_shader_jit); | ||||||
|     LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); |     LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); | ||||||
|  |  | ||||||
|  | @ -142,6 +142,7 @@ struct Values { | ||||||
|     bool use_gles; |     bool use_gles; | ||||||
|     bool use_hw_renderer; |     bool use_hw_renderer; | ||||||
|     bool use_hw_shader; |     bool use_hw_shader; | ||||||
|  |     bool separable_shader; | ||||||
|     bool use_disk_shader_cache; |     bool use_disk_shader_cache; | ||||||
|     bool shaders_accurate_mul; |     bool shaders_accurate_mul; | ||||||
|     bool use_shader_jit; |     bool use_shader_jit; | ||||||
|  |  | ||||||
|  | @ -43,6 +43,10 @@ static bool IsVendorAmd() { | ||||||
|     const std::string_view gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; |     const std::string_view gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; | ||||||
|     return gpu_vendor == "ATI Technologies Inc." || gpu_vendor == "Advanced Micro Devices, Inc."; |     return gpu_vendor == "ATI Technologies Inc." || gpu_vendor == "Advanced Micro Devices, Inc."; | ||||||
| } | } | ||||||
|  | static bool IsVendorIntel() { | ||||||
|  |     std::string gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; | ||||||
|  |     return gpu_vendor == "Intel Inc."; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| RasterizerOpenGL::RasterizerOpenGL() | RasterizerOpenGL::RasterizerOpenGL() | ||||||
|     : is_amd(IsVendorAmd()), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), |     : is_amd(IsVendorAmd()), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), | ||||||
|  | @ -160,8 +164,19 @@ RasterizerOpenGL::RasterizerOpenGL() | ||||||
|     state.Apply(); |     state.Apply(); | ||||||
|     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.GetHandle()); |     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.GetHandle()); | ||||||
| 
 | 
 | ||||||
|  | #ifdef __APPLE__ | ||||||
|  |     if (IsVendorIntel()) { | ||||||
|  |         shader_program_manager = std::make_unique<ShaderProgramManager>( | ||||||
|  |             VideoCore::g_separable_shader_enabled ? GLAD_GL_ARB_separate_shader_objects : false, | ||||||
|  |             is_amd); | ||||||
|  |     } else { | ||||||
|  |         shader_program_manager = | ||||||
|  |             std::make_unique<ShaderProgramManager>(GLAD_GL_ARB_separate_shader_objects, is_amd); | ||||||
|  |     } | ||||||
|  | #else | ||||||
|     shader_program_manager = |     shader_program_manager = | ||||||
|         std::make_unique<ShaderProgramManager>(GLAD_GL_ARB_separate_shader_objects, is_amd); |         std::make_unique<ShaderProgramManager>(GLAD_GL_ARB_separate_shader_objects, is_amd); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     glEnable(GL_BLEND); |     glEnable(GL_BLEND); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | ||||||
| std::atomic<bool> g_hw_renderer_enabled; | std::atomic<bool> g_hw_renderer_enabled; | ||||||
| std::atomic<bool> g_shader_jit_enabled; | std::atomic<bool> g_shader_jit_enabled; | ||||||
| std::atomic<bool> g_hw_shader_enabled; | std::atomic<bool> g_hw_shader_enabled; | ||||||
|  | std::atomic<bool> g_separable_shader_enabled; | ||||||
| std::atomic<bool> g_hw_shader_accurate_mul; | std::atomic<bool> g_hw_shader_accurate_mul; | ||||||
| std::atomic<bool> g_use_disk_shader_cache; | std::atomic<bool> g_use_disk_shader_cache; | ||||||
| std::atomic<bool> g_renderer_bg_color_update_requested; | std::atomic<bool> g_renderer_bg_color_update_requested; | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | ||||||
| extern std::atomic<bool> g_hw_renderer_enabled; | extern std::atomic<bool> g_hw_renderer_enabled; | ||||||
| extern std::atomic<bool> g_shader_jit_enabled; | extern std::atomic<bool> g_shader_jit_enabled; | ||||||
| extern std::atomic<bool> g_hw_shader_enabled; | extern std::atomic<bool> g_hw_shader_enabled; | ||||||
|  | extern std::atomic<bool> g_separable_shader_enabled; | ||||||
| extern std::atomic<bool> g_hw_shader_accurate_mul; | extern std::atomic<bool> g_hw_shader_accurate_mul; | ||||||
| extern std::atomic<bool> g_use_disk_shader_cache; | extern std::atomic<bool> g_use_disk_shader_cache; | ||||||
| extern std::atomic<bool> g_renderer_bg_color_update_requested; | extern std::atomic<bool> g_renderer_bg_color_update_requested; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue