Просмотр исходного кода

OpenGL: Limit lmem warmup to NVIDIA

:frog:
ameerj 3 лет назад
Родитель
Сommit
4f160633d3

+ 1 - 0
src/video_core/renderer_opengl/gl_device.cpp

@@ -194,6 +194,7 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
             has_bool_ref_bug = true;
         }
     }
+    has_lmem_perf_bug = is_nvidia;
 
     strict_context_required = emu_window.StrictContextRequired();
     // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation.

+ 5 - 0
src/video_core/renderer_opengl/gl_device.h

@@ -192,6 +192,10 @@ public:
         return supports_conditional_barriers;
     }
 
+    bool HasLmemPerfBug() const {
+        return has_lmem_perf_bug;
+    }
+
 private:
     static bool TestVariableAoffi();
     static bool TestPreciseBug();
@@ -238,6 +242,7 @@ private:
     bool can_report_memory{};
     bool strict_context_required{};
     bool supports_conditional_barriers{};
+    bool has_lmem_perf_bug{};
 
     std::string vendor_name;
 };

+ 9 - 4
src/video_core/renderer_opengl/gl_shader_manager.cpp

@@ -14,12 +14,15 @@ static constexpr std::array ASSEMBLY_PROGRAM_ENUMS{
     GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV,
 };
 
-ProgramManager::ProgramManager(const Device& device)
-    : lmem_warmup_program(CreateProgram(HostShaders::OPENGL_LMEM_WARMUP_COMP, GL_COMPUTE_SHADER)) {
+ProgramManager::ProgramManager(const Device& device) {
     glCreateProgramPipelines(1, &pipeline.handle);
     if (device.UseAssemblyShaders()) {
         glEnable(GL_COMPUTE_PROGRAM_NV);
     }
+    if (device.HasLmemPerfBug()) {
+        lmem_warmup_program =
+            CreateProgram(HostShaders::OPENGL_LMEM_WARMUP_COMP, GL_COMPUTE_SHADER);
+    }
 }
 
 void ProgramManager::BindComputeProgram(GLuint program) {
@@ -102,8 +105,10 @@ void ProgramManager::BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NU
 void ProgramManager::RestoreGuestCompute() {}
 
 void ProgramManager::LocalMemoryWarmup() {
-    BindComputeProgram(lmem_warmup_program.handle);
-    glDispatchCompute(1, 1, 1);
+    if (lmem_warmup_program.handle != 0) {
+        BindComputeProgram(lmem_warmup_program.handle);
+        glDispatchCompute(1, 1, 1);
+    }
 }
 
 void ProgramManager::BindPipeline() {