1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "VideoBackends/OGL/Render.h"
6 
7 #include <algorithm>
8 #include <cinttypes>
9 #include <cmath>
10 #include <cstdio>
11 #include <memory>
12 #include <string>
13 
14 #include "Common/Atomic.h"
15 #include "Common/CommonTypes.h"
16 #include "Common/GL/GLContext.h"
17 #include "Common/GL/GLUtil.h"
18 #include "Common/Logging/LogManager.h"
19 #include "Common/MathUtil.h"
20 #include "Common/MsgHandler.h"
21 #include "Common/StringUtil.h"
22 
23 #include "Core/Config/GraphicsSettings.h"
24 
25 #include "VideoBackends/OGL/BoundingBox.h"
26 #include "VideoBackends/OGL/OGLPipeline.h"
27 #include "VideoBackends/OGL/OGLShader.h"
28 #include "VideoBackends/OGL/OGLTexture.h"
29 #include "VideoBackends/OGL/ProgramShaderCache.h"
30 #include "VideoBackends/OGL/SamplerCache.h"
31 #include "VideoBackends/OGL/VertexManager.h"
32 
33 #include "VideoCommon/BPFunctions.h"
34 #include "VideoCommon/DriverDetails.h"
35 #include "VideoCommon/FramebufferManager.h"
36 #include "VideoCommon/OnScreenDisplay.h"
37 #include "VideoCommon/PostProcessing.h"
38 #include "VideoCommon/RenderState.h"
39 #include "VideoCommon/VideoCommon.h"
40 #include "VideoCommon/VideoConfig.h"
41 
42 namespace OGL
43 {
44 VideoConfig g_ogl_config;
45 
ErrorCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const char * message,const void * userParam)46 static void APIENTRY ErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
47                                    GLsizei length, const char* message, const void* userParam)
48 {
49   const char* s_source;
50   const char* s_type;
51 
52   // Performance - DualCore driver performance warning:
53   // DualCore application thread syncing with server thread
54   if (id == 0x200b0)
55     return;
56 
57   switch (source)
58   {
59   case GL_DEBUG_SOURCE_API_ARB:
60     s_source = "API";
61     break;
62   case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
63     s_source = "Window System";
64     break;
65   case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
66     s_source = "Shader Compiler";
67     break;
68   case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
69     s_source = "Third Party";
70     break;
71   case GL_DEBUG_SOURCE_APPLICATION_ARB:
72     s_source = "Application";
73     break;
74   case GL_DEBUG_SOURCE_OTHER_ARB:
75     s_source = "Other";
76     break;
77   default:
78     s_source = "Unknown";
79     break;
80   }
81   switch (type)
82   {
83   case GL_DEBUG_TYPE_ERROR_ARB:
84     s_type = "Error";
85     break;
86   case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
87     s_type = "Deprecated";
88     break;
89   case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
90     s_type = "Undefined";
91     break;
92   case GL_DEBUG_TYPE_PORTABILITY_ARB:
93     s_type = "Portability";
94     break;
95   case GL_DEBUG_TYPE_PERFORMANCE_ARB:
96     s_type = "Performance";
97     break;
98   case GL_DEBUG_TYPE_OTHER_ARB:
99     s_type = "Other";
100     break;
101   default:
102     s_type = "Unknown";
103     break;
104   }
105   switch (severity)
106   {
107   case GL_DEBUG_SEVERITY_HIGH_ARB:
108     ERROR_LOG(HOST_GPU, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message);
109     break;
110   case GL_DEBUG_SEVERITY_MEDIUM_ARB:
111     WARN_LOG(HOST_GPU, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message);
112     break;
113   case GL_DEBUG_SEVERITY_LOW_ARB:
114     DEBUG_LOG(HOST_GPU, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message);
115     break;
116   case GL_DEBUG_SEVERITY_NOTIFICATION:
117     DEBUG_LOG(HOST_GPU, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message);
118     break;
119   default:
120     ERROR_LOG(HOST_GPU, "id: %x, source: %s, type: %s - %s", id, s_source, s_type, message);
121     break;
122   }
123 }
124 
125 // Two small Fallbacks to avoid GL_ARB_ES2_compatibility
DepthRangef(GLfloat neardepth,GLfloat fardepth)126 static void APIENTRY DepthRangef(GLfloat neardepth, GLfloat fardepth)
127 {
128   glDepthRange(neardepth, fardepth);
129 }
ClearDepthf(GLfloat depthval)130 static void APIENTRY ClearDepthf(GLfloat depthval)
131 {
132   glClearDepth(depthval);
133 }
134 
InitDriverInfo()135 static void InitDriverInfo()
136 {
137   const std::string_view svendor(g_ogl_config.gl_vendor);
138   const std::string_view srenderer(g_ogl_config.gl_renderer);
139   const std::string_view sversion(g_ogl_config.gl_version);
140   DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
141   DriverDetails::Driver driver = DriverDetails::DRIVER_UNKNOWN;
142   DriverDetails::Family family = DriverDetails::Family::UNKNOWN;
143   double version = 0.0;
144 
145   // Get the vendor first
146   if (svendor == "NVIDIA Corporation")
147   {
148     if (srenderer != "NVIDIA Tegra")
149     {
150       vendor = DriverDetails::VENDOR_NVIDIA;
151     }
152     else
153     {
154       vendor = DriverDetails::VENDOR_TEGRA;
155     }
156   }
157   else if (svendor == "ATI Technologies Inc." || svendor == "Advanced Micro Devices, Inc.")
158   {
159     vendor = DriverDetails::VENDOR_ATI;
160   }
161   else if (sversion.find("Mesa") != std::string::npos)
162   {
163     vendor = DriverDetails::VENDOR_MESA;
164   }
165   else if (svendor.find("Intel") != std::string::npos)
166   {
167     vendor = DriverDetails::VENDOR_INTEL;
168   }
169   else if (svendor == "ARM")
170   {
171     vendor = DriverDetails::VENDOR_ARM;
172   }
173   else if (svendor == "http://limadriver.org/")
174   {
175     vendor = DriverDetails::VENDOR_ARM;
176     driver = DriverDetails::DRIVER_LIMA;
177   }
178   else if (svendor == "Qualcomm")
179   {
180     vendor = DriverDetails::VENDOR_QUALCOMM;
181   }
182   else if (svendor == "Imagination Technologies")
183   {
184     vendor = DriverDetails::VENDOR_IMGTEC;
185   }
186   else if (svendor == "Vivante Corporation")
187   {
188     vendor = DriverDetails::VENDOR_VIVANTE;
189   }
190 
191   // Get device family and driver version...if we care about it
192   switch (vendor)
193   {
194   case DriverDetails::VENDOR_QUALCOMM:
195   {
196     driver = DriverDetails::DRIVER_QUALCOMM;
197     double glVersion;
198     sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
199   }
200   break;
201   case DriverDetails::VENDOR_ARM:
202     // Currently the Mali-T line has two families in it.
203     // Mali-T6xx and Mali-T7xx
204     // These two families are similar enough that they share bugs in their drivers.
205     //
206     // Mali drivers provide no way to explicitly find out what video driver is running.
207     // This is similar to how we can't find the Nvidia driver version in Windows.
208     // Good thing is that ARM introduces a new video driver about once every two years so we can
209     // find the driver version by the features it exposes.
210     // r2p0 - No OpenGL ES 3.0 support (We don't support this)
211     // r3p0 - OpenGL ES 3.0 support
212     // r4p0 - Supports 'GL_EXT_shader_pixel_local_storage' extension.
213 
214     driver = DriverDetails::DRIVER_ARM;
215     if (GLExtensions::Supports("GL_EXT_shader_pixel_local_storage"))
216       version = 400;
217     else
218       version = 300;
219     break;
220   case DriverDetails::VENDOR_MESA:
221   {
222     if (svendor == "nouveau")
223     {
224       driver = DriverDetails::DRIVER_NOUVEAU;
225     }
226     else if (svendor == "Intel Open Source Technology Center")
227     {
228       driver = DriverDetails::DRIVER_I965;
229       if (srenderer.find("Sandybridge") != std::string::npos)
230         family = DriverDetails::Family::INTEL_SANDY;
231       else if (srenderer.find("Ivybridge") != std::string::npos)
232         family = DriverDetails::Family::INTEL_IVY;
233     }
234     else if (srenderer.find("AMD") != std::string::npos ||
235              srenderer.find("ATI") != std::string::npos)
236     {
237       driver = DriverDetails::DRIVER_R600;
238     }
239 
240     int major = 0;
241     int minor = 0;
242     int release = 0;
243     sscanf(g_ogl_config.gl_version, "%*s (Core Profile) Mesa %d.%d.%d", &major, &minor, &release);
244     version = 100 * major + 10 * minor + release;
245   }
246   break;
247   case DriverDetails::VENDOR_INTEL:  // Happens in OS X/Windows
248   {
249     u32 market_name;
250     sscanf(g_ogl_config.gl_renderer, "Intel HD Graphics %d", &market_name);
251     switch (market_name)
252     {
253     case 2000:
254     case 3000:
255       family = DriverDetails::Family::INTEL_SANDY;
256       break;
257     case 2500:
258     case 4000:
259       family = DriverDetails::Family::INTEL_IVY;
260       break;
261     default:
262       family = DriverDetails::Family::UNKNOWN;
263       break;
264     };
265 #ifdef _WIN32
266     int glmajor = 0;
267     int glminor = 0;
268     int major = 0;
269     int minor = 0;
270     int release = 0;
271     int revision = 0;
272     // Example version string: '4.3.0 - Build 10.18.10.3907'
273     sscanf(g_ogl_config.gl_version, "%d.%d.0 - Build %d.%d.%d.%d", &glmajor, &glminor, &major,
274            &minor, &release, &revision);
275     version = 100000000 * major + 1000000 * minor + 10000 * release + revision;
276     version /= 10000;
277 #endif
278   }
279   break;
280   case DriverDetails::VENDOR_NVIDIA:
281   {
282     int glmajor = 0;
283     int glminor = 0;
284     int glrelease = 0;
285     int major = 0;
286     int minor = 0;
287     // TODO: this is known to be broken on Windows
288     // Nvidia seems to have removed their driver version from this string, so we can't get it.
289     // hopefully we'll never have to workaround Nvidia bugs
290     sscanf(g_ogl_config.gl_version, "%d.%d.%d NVIDIA %d.%d", &glmajor, &glminor, &glrelease, &major,
291            &minor);
292     version = 100 * major + minor;
293   }
294   break;
295   case DriverDetails::VENDOR_IMGTEC:
296   {
297     // Example version string:
298     // "OpenGL ES 3.2 build 1.9@4850625"
299     // Ends up as "109.4850625" - "1.9" being the branch, "4850625" being the build's change ID
300     // The change ID only makes sense to compare within a branch
301     driver = DriverDetails::DRIVER_IMGTEC;
302     double gl_version;
303     int major, minor, change;
304     constexpr double change_scale = 10000000;
305     sscanf(g_ogl_config.gl_version, "OpenGL ES %lg build %d.%d@%d", &gl_version, &major, &minor,
306            &change);
307     version = 100 * major + minor;
308     if (change >= change_scale)
309     {
310       ERROR_LOG(VIDEO, "Version changeID overflow - change:%d scale:%f", change, change_scale);
311     }
312     else
313     {
314       version += static_cast<double>(change) / change_scale;
315     }
316   }
317   break;
318   // We don't care about these
319   default:
320     break;
321   }
322   DriverDetails::Init(DriverDetails::API_OPENGL, vendor, driver, version, family);
323 }
324 
325 // Init functions
Renderer(std::unique_ptr<GLContext> main_gl_context,float backbuffer_scale)326 Renderer::Renderer(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scale)
327     : ::Renderer(static_cast<int>(std::max(main_gl_context->GetBackBufferWidth(), 1u)),
328                  static_cast<int>(std::max(main_gl_context->GetBackBufferHeight(), 1u)),
329                  backbuffer_scale, AbstractTextureFormat::RGBA8),
330       m_main_gl_context(std::move(main_gl_context)),
331       m_current_rasterization_state(RenderState::GetInvalidRasterizationState()),
332       m_current_depth_state(RenderState::GetInvalidDepthState()),
333       m_current_blend_state(RenderState::GetInvalidBlendingState())
334 {
335   // Create the window framebuffer.
336   if (!m_main_gl_context->IsHeadless())
337   {
338     m_system_framebuffer = std::make_unique<OGLFramebuffer>(
339         nullptr, nullptr, AbstractTextureFormat::RGBA8, AbstractTextureFormat::Undefined,
340         std::max(m_main_gl_context->GetBackBufferWidth(), 1u),
341         std::max(m_main_gl_context->GetBackBufferHeight(), 1u), 1, 1, 0);
342     m_current_framebuffer = m_system_framebuffer.get();
343   }
344 
345   bool bSuccess = true;
346   bool supports_glsl_cache = false;
347 
348   g_ogl_config.gl_vendor = (const char*)glGetString(GL_VENDOR);
349   g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER);
350   g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION);
351 
352   InitDriverInfo();
353 
354   if (!m_main_gl_context->IsGLES())
355   {
356     if (!GLExtensions::Supports("GL_ARB_framebuffer_object"))
357     {
358       // We want the ogl3 framebuffer instead of the ogl2 one for better blitting support.
359       // It's also compatible with the gles3 one.
360       PanicAlert("GPU: ERROR: Need GL_ARB_framebuffer_object for multiple render targets.\n"
361                  "GPU: Does your video card support OpenGL 3.0?");
362       bSuccess = false;
363     }
364 
365     if (!GLExtensions::Supports("GL_ARB_vertex_array_object"))
366     {
367       // This extension is used to replace lots of pointer setting function.
368       // Also gles3 requires to use it.
369       PanicAlert("GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n"
370                  "GPU: Does your video card support OpenGL 3.0?");
371       bSuccess = false;
372     }
373 
374     if (!GLExtensions::Supports("GL_ARB_map_buffer_range"))
375     {
376       // ogl3 buffer mapping for better streaming support.
377       // The ogl2 one also isn't in gles3.
378       PanicAlert("GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n"
379                  "GPU: Does your video card support OpenGL 3.0?");
380       bSuccess = false;
381     }
382 
383     if (!GLExtensions::Supports("GL_ARB_uniform_buffer_object"))
384     {
385       // ubo allow us to keep the current constants on shader switches
386       // we also can stream them much nicer and pack into it whatever we want to
387       PanicAlert("GPU: OGL ERROR: Need GL_ARB_uniform_buffer_object.\n"
388                  "GPU: Does your video card support OpenGL 3.1?");
389       bSuccess = false;
390     }
391     else if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_UBO))
392     {
393       PanicAlert(
394           "Buggy GPU driver detected.\n"
395           "Please either install the closed-source GPU driver or update your Mesa 3D version.");
396       bSuccess = false;
397     }
398 
399     if (!GLExtensions::Supports("GL_ARB_sampler_objects"))
400     {
401       // Our sampler cache uses this extension. It could easyly be workaround and it's by far the
402       // highest requirement, but it seems that no driver lacks support for it.
403       PanicAlert("GPU: OGL ERROR: Need GL_ARB_sampler_objects.\n"
404                  "GPU: Does your video card support OpenGL 3.3?");
405       bSuccess = false;
406     }
407 
408     // OpenGL 3 doesn't provide GLES like float functions for depth.
409     // They are in core in OpenGL 4.1, so almost every driver should support them.
410     // But for the oldest ones, we provide fallbacks to the old double functions.
411     if (!GLExtensions::Supports("GL_ARB_ES2_compatibility"))
412     {
413       glDepthRangef = DepthRangef;
414       glClearDepthf = ClearDepthf;
415     }
416   }
417 
418   // Copy the GPU name to g_Config, so Analytics can see it.
419   g_Config.backend_info.AdapterName = g_ogl_config.gl_renderer;
420 
421   g_Config.backend_info.bSupportsDualSourceBlend =
422       (GLExtensions::Supports("GL_ARB_blend_func_extended") ||
423        GLExtensions::Supports("GL_EXT_blend_func_extended"));
424   g_Config.backend_info.bSupportsPrimitiveRestart =
425       !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) &&
426       ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
427   g_Config.backend_info.bSupportsFragmentStoresAndAtomics =
428       GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
429   g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics;
430   g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
431   g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") &&
432                                         GLExtensions::Supports("GL_ARB_sample_shading");
433   g_Config.backend_info.bSupportsGeometryShaders =
434       GLExtensions::Version() >= 320 &&
435       !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_GEOMETRY_SHADERS);
436   g_Config.backend_info.bSupportsPaletteConversion =
437       GLExtensions::Supports("GL_ARB_texture_buffer_object") ||
438       GLExtensions::Supports("GL_OES_texture_buffer") ||
439       GLExtensions::Supports("GL_EXT_texture_buffer");
440   g_Config.backend_info.bSupportsClipControl = GLExtensions::Supports("GL_ARB_clip_control");
441   g_ogl_config.bSupportsCopySubImage =
442       (GLExtensions::Supports("GL_ARB_copy_image") || GLExtensions::Supports("GL_NV_copy_image") ||
443        GLExtensions::Supports("GL_EXT_copy_image") ||
444        GLExtensions::Supports("GL_OES_copy_image")) &&
445       !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_COPYIMAGE);
446   g_ogl_config.bSupportsTextureSubImage = GLExtensions::Supports("ARB_get_texture_sub_image");
447 
448   // Desktop OpenGL supports the binding layout if it supports 420pack
449   // OpenGL ES 3.1 supports it implicitly without an extension
450   g_Config.backend_info.bSupportsBindingLayout =
451       GLExtensions::Supports("GL_ARB_shading_language_420pack");
452 
453   // Clip distance support is useless without a method to clamp the depth range
454   g_Config.backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp");
455 
456   // Desktop OpenGL supports bitfield manulipation and dynamic sampler indexing if it supports
457   // shader5. OpenGL ES 3.1 supports it implicitly without an extension
458   g_Config.backend_info.bSupportsBitfield = GLExtensions::Supports("GL_ARB_gpu_shader5");
459   g_Config.backend_info.bSupportsDynamicSamplerIndexing =
460       GLExtensions::Supports("GL_ARB_gpu_shader5");
461 
462   g_ogl_config.bIsES = m_main_gl_context->IsGLES();
463   supports_glsl_cache = GLExtensions::Supports("GL_ARB_get_program_binary");
464   g_ogl_config.bSupportsGLPinnedMemory = GLExtensions::Supports("GL_AMD_pinned_memory");
465   g_ogl_config.bSupportsGLSync = GLExtensions::Supports("GL_ARB_sync");
466   g_ogl_config.bSupportsGLBaseVertex = GLExtensions::Supports("GL_ARB_draw_elements_base_vertex") ||
467                                        GLExtensions::Supports("GL_EXT_draw_elements_base_vertex") ||
468                                        GLExtensions::Supports("GL_OES_draw_elements_base_vertex");
469   g_ogl_config.bSupportsGLBufferStorage = GLExtensions::Supports("GL_ARB_buffer_storage") ||
470                                           GLExtensions::Supports("GL_EXT_buffer_storage");
471   g_ogl_config.bSupportsMSAA = GLExtensions::Supports("GL_ARB_texture_multisample");
472   g_ogl_config.bSupportViewportFloat = GLExtensions::Supports("GL_ARB_viewport_array");
473   g_ogl_config.bSupportsDebug =
474       GLExtensions::Supports("GL_KHR_debug") || GLExtensions::Supports("GL_ARB_debug_output");
475   g_ogl_config.bSupportsTextureStorage = GLExtensions::Supports("GL_ARB_texture_storage");
476   g_ogl_config.bSupports3DTextureStorageMultisample =
477       GLExtensions::Supports("GL_ARB_texture_storage_multisample") ||
478       GLExtensions::Supports("GL_OES_texture_storage_multisample_2d_array");
479   g_ogl_config.bSupports2DTextureStorageMultisample =
480       GLExtensions::Supports("GL_ARB_texture_storage_multisample");
481   g_ogl_config.bSupportsImageLoadStore = GLExtensions::Supports("GL_ARB_shader_image_load_store");
482   g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth");
483   g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic");
484   g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
485   g_Config.backend_info.bSupportsST3CTextures =
486       GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
487   g_Config.backend_info.bSupportsBPTCTextures =
488       GLExtensions::Supports("GL_ARB_texture_compression_bptc");
489 
490   if (m_main_gl_context->IsGLES())
491   {
492     g_ogl_config.SupportedESPointSize =
493         GLExtensions::Supports("GL_OES_geometry_point_size") ?
494             1 :
495             GLExtensions::Supports("GL_EXT_geometry_point_size") ? 2 : 0;
496     g_ogl_config.SupportedESTextureBuffer = GLExtensions::Supports("VERSION_GLES_3_2") ?
497                                                 EsTexbufType::TexbufCore :
498                                                 GLExtensions::Supports("GL_OES_texture_buffer") ?
499                                                 EsTexbufType::TexbufOes :
500                                                 GLExtensions::Supports("GL_EXT_texture_buffer") ?
501                                                 EsTexbufType::TexbufExt :
502                                                 EsTexbufType::TexbufNone;
503 
504     supports_glsl_cache = true;
505     g_ogl_config.bSupportsGLSync = true;
506 
507     // TODO: Implement support for GL_EXT_clip_cull_distance when there is an extension for
508     // depth clamping.
509     g_Config.backend_info.bSupportsDepthClamp = false;
510 
511     // GLES does not support logic op.
512     g_Config.backend_info.bSupportsLogicOp = false;
513 
514     // glReadPixels() can't be used with non-color formats. But, if we support
515     // ARB_get_texture_sub_image (unlikely, except maybe on NVIDIA), we can use that instead.
516     g_Config.backend_info.bSupportsDepthReadback = g_ogl_config.bSupportsTextureSubImage;
517 
518     if (GLExtensions::Supports("GL_EXT_shader_framebuffer_fetch"))
519     {
520       g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchExt;
521     }
522     else if (GLExtensions::Supports("GL_ARM_shader_framebuffer_fetch"))
523     {
524       g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchArm;
525     }
526     else
527     {
528       g_ogl_config.SupportedFramebufferFetch = EsFbFetchType::FbFetchNone;
529     }
530     g_Config.backend_info.bSupportsFramebufferFetch =
531         g_ogl_config.SupportedFramebufferFetch != EsFbFetchType::FbFetchNone;
532 
533     if (GLExtensions::Version() == 300)
534     {
535       g_ogl_config.eSupportedGLSLVersion = GlslEs300;
536       g_ogl_config.bSupportsAEP = false;
537       g_ogl_config.bSupportsTextureStorage = true;
538       g_Config.backend_info.bSupportsGeometryShaders = false;
539     }
540     else if (GLExtensions::Version() == 310)
541     {
542       g_ogl_config.eSupportedGLSLVersion = GlslEs310;
543       g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
544       g_Config.backend_info.bSupportsBindingLayout = true;
545       g_ogl_config.bSupportsImageLoadStore = true;
546       g_Config.backend_info.bSupportsGeometryShaders = g_ogl_config.bSupportsAEP;
547       g_Config.backend_info.bSupportsComputeShaders = true;
548       g_Config.backend_info.bSupportsGSInstancing =
549           g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0;
550       g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP;
551       g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
552       g_ogl_config.bSupportsMSAA = true;
553       g_ogl_config.bSupportsTextureStorage = true;
554       g_ogl_config.bSupports2DTextureStorageMultisample = true;
555       g_Config.backend_info.bSupportsBitfield = true;
556       g_Config.backend_info.bSupportsDynamicSamplerIndexing = g_ogl_config.bSupportsAEP;
557       if (g_ActiveConfig.stereo_mode != StereoMode::Off && g_ActiveConfig.iMultisamples > 1 &&
558           !g_ogl_config.bSupports3DTextureStorageMultisample)
559       {
560         // GLES 3.1 can't support stereo rendering and MSAA
561         OSD::AddMessage("MSAA Stereo rendering isn't supported by your GPU.", 10000);
562         Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1));
563       }
564     }
565     else
566     {
567       g_ogl_config.eSupportedGLSLVersion = GlslEs320;
568       g_ogl_config.bSupportsAEP = GLExtensions::Supports("GL_ANDROID_extension_pack_es31a");
569       g_Config.backend_info.bSupportsBindingLayout = true;
570       g_ogl_config.bSupportsImageLoadStore = true;
571       g_Config.backend_info.bSupportsGeometryShaders = true;
572       g_Config.backend_info.bSupportsComputeShaders = true;
573       g_Config.backend_info.bSupportsGSInstancing = g_ogl_config.SupportedESPointSize > 0;
574       g_Config.backend_info.bSupportsPaletteConversion = true;
575       g_Config.backend_info.bSupportsSSAA = true;
576       g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true;
577       g_ogl_config.bSupportsCopySubImage = true;
578       g_ogl_config.bSupportsGLBaseVertex = true;
579       g_ogl_config.bSupportsDebug = true;
580       g_ogl_config.bSupportsMSAA = true;
581       g_ogl_config.bSupportsTextureStorage = true;
582       g_ogl_config.bSupports2DTextureStorageMultisample = true;
583       g_ogl_config.bSupports3DTextureStorageMultisample = true;
584       g_Config.backend_info.bSupportsBitfield = true;
585       g_Config.backend_info.bSupportsDynamicSamplerIndexing = true;
586     }
587   }
588   else
589   {
590     if (GLExtensions::Version() < 300)
591     {
592       PanicAlert("GPU: OGL ERROR: Need at least GLSL 1.30\n"
593                  "GPU: Does your video card support OpenGL 3.0?\n"
594                  "GPU: Your driver supports GLSL %s",
595                  (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
596       bSuccess = false;
597     }
598     else if (GLExtensions::Version() == 300)
599     {
600       g_ogl_config.eSupportedGLSLVersion = Glsl130;
601       g_ogl_config.bSupportsImageLoadStore = false;  // layout keyword is only supported on glsl150+
602       g_ogl_config.bSupportsConservativeDepth =
603           false;  // layout keyword is only supported on glsl150+
604       g_Config.backend_info.bSupportsGeometryShaders =
605           false;  // geometry shaders are only supported on glsl150+
606     }
607     else if (GLExtensions::Version() == 310)
608     {
609       g_ogl_config.eSupportedGLSLVersion = Glsl140;
610       g_ogl_config.bSupportsImageLoadStore = false;  // layout keyword is only supported on glsl150+
611       g_ogl_config.bSupportsConservativeDepth =
612           false;  // layout keyword is only supported on glsl150+
613       g_Config.backend_info.bSupportsGeometryShaders =
614           false;  // geometry shaders are only supported on glsl150+
615     }
616     else if (GLExtensions::Version() == 320)
617     {
618       g_ogl_config.eSupportedGLSLVersion = Glsl150;
619     }
620     else if (GLExtensions::Version() == 330)
621     {
622       g_ogl_config.eSupportedGLSLVersion = Glsl330;
623     }
624     else if (GLExtensions::Version() >= 430)
625     {
626       // TODO: We should really parse the GL_SHADING_LANGUAGE_VERSION token.
627       g_ogl_config.eSupportedGLSLVersion = Glsl430;
628       g_ogl_config.bSupportsTextureStorage = true;
629       g_ogl_config.bSupportsImageLoadStore = true;
630       g_Config.backend_info.bSupportsSSAA = true;
631 
632       // Compute shaders are core in GL4.3.
633       g_Config.backend_info.bSupportsComputeShaders = true;
634       if (GLExtensions::Version() >= 450)
635         g_ogl_config.bSupportsTextureSubImage = true;
636     }
637     else
638     {
639       g_ogl_config.eSupportedGLSLVersion = Glsl400;
640       g_Config.backend_info.bSupportsSSAA = true;
641 
642       if (GLExtensions::Version() == 420)
643       {
644         // Texture storage and shader image load/store are core in GL4.2.
645         g_ogl_config.bSupportsTextureStorage = true;
646         g_ogl_config.bSupportsImageLoadStore = true;
647       }
648     }
649 
650     // Desktop OpenGL can't have the Android Extension Pack
651     g_ogl_config.bSupportsAEP = false;
652 
653     // Desktop GL requires GL_PROGRAM_POINT_SIZE set to use gl_PointSize in shaders.
654     // It is implicitly enabled in GLES.
655     glEnable(GL_PROGRAM_POINT_SIZE);
656   }
657 
658   // Either method can do early-z tests. See PixelShaderGen for details.
659   g_Config.backend_info.bSupportsEarlyZ =
660       g_ogl_config.bSupportsImageLoadStore || g_ogl_config.bSupportsConservativeDepth;
661 
662   glGetIntegerv(GL_MAX_SAMPLES, &g_ogl_config.max_samples);
663   if (g_ogl_config.max_samples < 1 || !g_ogl_config.bSupportsMSAA)
664     g_ogl_config.max_samples = 1;
665 
666   g_ogl_config.bSupportsShaderThreadShuffleNV =
667       GLExtensions::Supports("GL_NV_shader_thread_shuffle");
668 
669   // We require texel buffers, image load store, and compute shaders to enable GPU texture decoding.
670   // If the driver doesn't expose the extensions, but supports GL4.3/GLES3.1, it will still be
671   // enabled in the version check below.
672   g_Config.backend_info.bSupportsGPUTextureDecoding =
673       g_Config.backend_info.bSupportsPaletteConversion &&
674       g_Config.backend_info.bSupportsComputeShaders && g_ogl_config.bSupportsImageLoadStore;
675 
676   // Background compiling is supported only when shared contexts aren't broken.
677   g_Config.backend_info.bSupportsBackgroundCompiling =
678       !DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION);
679 
680   // Program binaries are supported on GL4.1+, ARB_get_program_binary, or ES3.
681   if (supports_glsl_cache)
682   {
683     // We need to check the number of formats supported. If zero, don't bother getting the binaries.
684     GLint num_formats = 0;
685     glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats);
686     supports_glsl_cache = num_formats > 0;
687   }
688   g_Config.backend_info.bSupportsPipelineCacheData = supports_glsl_cache;
689 
690   if (g_ogl_config.bSupportsDebug)
691   {
692     if (GLExtensions::Supports("GL_KHR_debug"))
693     {
694       glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, true);
695       glDebugMessageCallback(ErrorCallback, nullptr);
696     }
697     else
698     {
699       glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, true);
700       glDebugMessageCallbackARB(ErrorCallback, nullptr);
701     }
702     if (Common::Log::LogManager::GetInstance()->IsEnabled(Common::Log::HOST_GPU,
703                                                           Common::Log::LERROR))
704     {
705       glEnable(GL_DEBUG_OUTPUT);
706     }
707     else
708     {
709       glDisable(GL_DEBUG_OUTPUT);
710     }
711   }
712 
713   int samples;
714   glGetIntegerv(GL_SAMPLES, &samples);
715   if (samples > 1)
716   {
717     // MSAA on default framebuffer isn't working because of glBlitFramebuffer.
718     // It also isn't useful as we don't render anything to the default framebuffer.
719     // We also try to get a non-msaa fb, so this only happens when forced by the driver.
720     PanicAlertT("The graphics driver is forcibly enabling anti-aliasing for Dolphin. You need to "
721                 "turn this off in the graphics driver's settings in order for Dolphin to work.\n\n"
722                 "(MSAA with %d samples found on default framebuffer)",
723                 samples);
724     bSuccess = false;
725   }
726 
727   if (!bSuccess)
728   {
729     // Not all needed extensions are supported, so we have to stop here.
730     // Else some of the next calls might crash.
731     return;
732   }
733 
734   g_Config.VerifyValidity();
735   UpdateActiveConfig();
736 
737   OSD::AddMessage(StringFromFormat("Video Info: %s, %s, %s", g_ogl_config.gl_vendor,
738                                    g_ogl_config.gl_renderer, g_ogl_config.gl_version),
739                   5000);
740 
741   if (!g_ogl_config.bSupportsGLBufferStorage && !g_ogl_config.bSupportsGLPinnedMemory)
742   {
743     OSD::AddMessage(StringFromFormat("Your OpenGL driver does not support %s_buffer_storage.",
744                                      m_main_gl_context->IsGLES() ? "EXT" : "ARB"),
745                     60000);
746     OSD::AddMessage("This device's performance will be terrible.", 60000);
747     OSD::AddMessage("Please ask your device vendor for an updated OpenGL driver.", 60000);
748   }
749 
750   WARN_LOG(VIDEO, "Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s%s%s%s%s",
751            g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
752            g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
753            g_ActiveConfig.backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
754            g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
755            supports_glsl_cache ? "" : "ShaderCache ",
756            g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
757            g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
758            g_ogl_config.bSupportsGLSync ? "" : "Sync ", g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
759            g_ActiveConfig.backend_info.bSupportsSSAA ? "" : "SSAA ",
760            g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing ",
761            g_ActiveConfig.backend_info.bSupportsClipControl ? "" : "ClipControl ",
762            g_ogl_config.bSupportsCopySubImage ? "" : "CopyImageSubData ",
763            g_ActiveConfig.backend_info.bSupportsDepthClamp ? "" : "DepthClamp ");
764 
765   // Handle VSync on/off
766   if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
767     m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
768 
769   if (g_ActiveConfig.backend_info.bSupportsClipControl)
770     glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
771 
772   if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
773   {
774     glEnable(GL_CLIP_DISTANCE0);
775     glEnable(GL_CLIP_DISTANCE1);
776     glEnable(GL_DEPTH_CLAMP);
777   }
778 
779   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);  // 4-byte pixel alignment
780 
781   glGenFramebuffers(1, &m_shared_read_framebuffer);
782   glGenFramebuffers(1, &m_shared_draw_framebuffer);
783 
784   if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart)
785     GLUtil::EnablePrimitiveRestart(m_main_gl_context.get());
786 
787   UpdateActiveConfig();
788 }
789 
790 Renderer::~Renderer() = default;
791 
IsHeadless() const792 bool Renderer::IsHeadless() const
793 {
794   return m_main_gl_context->IsHeadless();
795 }
796 
Initialize()797 bool Renderer::Initialize()
798 {
799   if (!::Renderer::Initialize())
800     return false;
801 
802   return true;
803 }
804 
Shutdown()805 void Renderer::Shutdown()
806 {
807   ::Renderer::Shutdown();
808 
809   glDeleteFramebuffers(1, &m_shared_draw_framebuffer);
810   glDeleteFramebuffers(1, &m_shared_read_framebuffer);
811 }
812 
CreateTexture(const TextureConfig & config)813 std::unique_ptr<AbstractTexture> Renderer::CreateTexture(const TextureConfig& config)
814 {
815   return std::make_unique<OGLTexture>(config);
816 }
817 
CreateStagingTexture(StagingTextureType type,const TextureConfig & config)818 std::unique_ptr<AbstractStagingTexture> Renderer::CreateStagingTexture(StagingTextureType type,
819                                                                        const TextureConfig& config)
820 {
821   return OGLStagingTexture::Create(type, config);
822 }
823 
CreateFramebuffer(AbstractTexture * color_attachment,AbstractTexture * depth_attachment)824 std::unique_ptr<AbstractFramebuffer> Renderer::CreateFramebuffer(AbstractTexture* color_attachment,
825                                                                  AbstractTexture* depth_attachment)
826 {
827   return OGLFramebuffer::Create(static_cast<OGLTexture*>(color_attachment),
828                                 static_cast<OGLTexture*>(depth_attachment));
829 }
830 
CreateShaderFromSource(ShaderStage stage,std::string_view source)831 std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage,
832                                                                  std::string_view source)
833 {
834   return OGLShader::CreateFromSource(stage, source);
835 }
836 
CreateShaderFromBinary(ShaderStage stage,const void * data,size_t length)837 std::unique_ptr<AbstractShader> Renderer::CreateShaderFromBinary(ShaderStage stage,
838                                                                  const void* data, size_t length)
839 {
840   return nullptr;
841 }
842 
CreatePipeline(const AbstractPipelineConfig & config,const void * cache_data,size_t cache_data_length)843 std::unique_ptr<AbstractPipeline> Renderer::CreatePipeline(const AbstractPipelineConfig& config,
844                                                            const void* cache_data,
845                                                            size_t cache_data_length)
846 {
847   return OGLPipeline::Create(config, cache_data, cache_data_length);
848 }
849 
SetScissorRect(const MathUtil::Rectangle<int> & rc)850 void Renderer::SetScissorRect(const MathUtil::Rectangle<int>& rc)
851 {
852   glScissor(rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
853 }
854 
BBoxRead(int index)855 u16 Renderer::BBoxRead(int index)
856 {
857   // swap 2 and 3 for top/bottom
858   if (index >= 2)
859     index ^= 1;
860 
861   int value = BoundingBox::Get(index);
862   if (index >= 2)
863   {
864     // up/down -- we have to swap up and down
865     value = EFB_HEIGHT - value;
866   }
867 
868   return static_cast<u16>(value);
869 }
870 
BBoxWrite(int index,u16 value)871 void Renderer::BBoxWrite(int index, u16 value)
872 {
873   s32 swapped_value = value;
874   if (index >= 2)
875   {
876     index ^= 1;  // swap 2 and 3 for top/bottom
877     swapped_value = EFB_HEIGHT - swapped_value;
878   }
879 
880   BoundingBox::Set(index, swapped_value);
881 }
882 
SetViewport(float x,float y,float width,float height,float near_depth,float far_depth)883 void Renderer::SetViewport(float x, float y, float width, float height, float near_depth,
884                            float far_depth)
885 {
886   if (g_ogl_config.bSupportViewportFloat)
887   {
888     glViewportIndexedf(0, x, y, width, height);
889   }
890   else
891   {
892     auto iceilf = [](float f) { return static_cast<GLint>(std::ceil(f)); };
893     glViewport(iceilf(x), iceilf(y), iceilf(width), iceilf(height));
894   }
895 
896   glDepthRangef(near_depth, far_depth);
897 }
898 
Draw(u32 base_vertex,u32 num_vertices)899 void Renderer::Draw(u32 base_vertex, u32 num_vertices)
900 {
901   glDrawArrays(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(), base_vertex,
902                num_vertices);
903 }
904 
DrawIndexed(u32 base_index,u32 num_indices,u32 base_vertex)905 void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
906 {
907   if (g_ogl_config.bSupportsGLBaseVertex)
908   {
909     glDrawElementsBaseVertex(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(),
910                              num_indices, GL_UNSIGNED_SHORT,
911                              static_cast<u16*>(nullptr) + base_index, base_vertex);
912   }
913   else
914   {
915     glDrawElements(static_cast<const OGLPipeline*>(m_current_pipeline)->GetGLPrimitive(),
916                    num_indices, GL_UNSIGNED_SHORT, static_cast<u16*>(nullptr) + base_index);
917   }
918 }
919 
DispatchComputeShader(const AbstractShader * shader,u32 groups_x,u32 groups_y,u32 groups_z)920 void Renderer::DispatchComputeShader(const AbstractShader* shader, u32 groups_x, u32 groups_y,
921                                      u32 groups_z)
922 {
923   glUseProgram(static_cast<const OGLShader*>(shader)->GetGLComputeProgramID());
924   glDispatchCompute(groups_x, groups_y, groups_z);
925 
926   // We messed up the program binding, so restore it.
927   ProgramShaderCache::InvalidateLastProgram();
928   if (m_current_pipeline)
929     static_cast<const OGLPipeline*>(m_current_pipeline)->GetProgram()->shader.Bind();
930 
931   // Barrier to texture can be used for reads.
932   if (m_bound_image_texture)
933     glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
934 }
935 
ClearScreen(const MathUtil::Rectangle<int> & rc,bool colorEnable,bool alphaEnable,bool zEnable,u32 color,u32 z)936 void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable,
937                            bool zEnable, u32 color, u32 z)
938 {
939   g_framebuffer_manager->FlushEFBPokes();
940   g_framebuffer_manager->FlagPeekCacheAsOutOfDate();
941 
942   u32 clear_mask = 0;
943   if (colorEnable || alphaEnable)
944   {
945     glColorMask(colorEnable, colorEnable, colorEnable, alphaEnable);
946     glClearColor(float((color >> 16) & 0xFF) / 255.0f, float((color >> 8) & 0xFF) / 255.0f,
947                  float((color >> 0) & 0xFF) / 255.0f, float((color >> 24) & 0xFF) / 255.0f);
948     clear_mask = GL_COLOR_BUFFER_BIT;
949   }
950   if (zEnable)
951   {
952     glDepthMask(zEnable ? GL_TRUE : GL_FALSE);
953     glClearDepthf(float(z & 0xFFFFFF) / 16777216.0f);
954     clear_mask |= GL_DEPTH_BUFFER_BIT;
955   }
956 
957   // Update rect for clearing the picture
958   // glColorMask/glDepthMask/glScissor affect glClear (glViewport does not)
959   const auto converted_target_rc =
960       ConvertFramebufferRectangle(ConvertEFBRectangle(rc), m_current_framebuffer);
961   SetScissorRect(converted_target_rc);
962 
963   glClear(clear_mask);
964 
965   // Restore color/depth mask.
966   if (colorEnable || alphaEnable)
967   {
968     glColorMask(m_current_blend_state.colorupdate, m_current_blend_state.colorupdate,
969                 m_current_blend_state.colorupdate, m_current_blend_state.alphaupdate);
970   }
971   if (zEnable)
972     glDepthMask(m_current_depth_state.updateenable);
973 
974   // Scissor rect must be restored.
975   BPFunctions::SetScissor();
976 }
977 
RenderXFBToScreen(const MathUtil::Rectangle<int> & target_rc,const AbstractTexture * source_texture,const MathUtil::Rectangle<int> & source_rc)978 void Renderer::RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
979                                  const AbstractTexture* source_texture,
980                                  const MathUtil::Rectangle<int>& source_rc)
981 {
982   // Quad-buffered stereo is annoying on GL.
983   if (g_ActiveConfig.stereo_mode != StereoMode::QuadBuffer)
984     return ::Renderer::RenderXFBToScreen(target_rc, source_texture, source_rc);
985 
986   glDrawBuffer(GL_BACK_LEFT);
987   m_post_processor->BlitFromTexture(target_rc, source_rc, source_texture, 0);
988 
989   glDrawBuffer(GL_BACK_RIGHT);
990   m_post_processor->BlitFromTexture(target_rc, source_rc, source_texture, 1);
991 
992   glDrawBuffer(GL_BACK);
993 }
994 
SetFramebuffer(AbstractFramebuffer * framebuffer)995 void Renderer::SetFramebuffer(AbstractFramebuffer* framebuffer)
996 {
997   if (m_current_framebuffer == framebuffer)
998     return;
999 
1000   glBindFramebuffer(GL_FRAMEBUFFER, static_cast<OGLFramebuffer*>(framebuffer)->GetFBO());
1001   m_current_framebuffer = framebuffer;
1002 }
1003 
SetAndDiscardFramebuffer(AbstractFramebuffer * framebuffer)1004 void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
1005 {
1006   // EXT_discard_framebuffer could be used here to save bandwidth on tilers.
1007   SetFramebuffer(framebuffer);
1008 }
1009 
SetAndClearFramebuffer(AbstractFramebuffer * framebuffer,const ClearColor & color_value,float depth_value)1010 void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer,
1011                                       const ClearColor& color_value, float depth_value)
1012 {
1013   SetFramebuffer(framebuffer);
1014 
1015   glDisable(GL_SCISSOR_TEST);
1016   GLbitfield clear_mask = 0;
1017   if (framebuffer->HasColorBuffer())
1018   {
1019     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1020     glClearColor(color_value[0], color_value[1], color_value[2], color_value[3]);
1021     clear_mask |= GL_COLOR_BUFFER_BIT;
1022   }
1023   if (framebuffer->HasDepthBuffer())
1024   {
1025     glDepthMask(GL_TRUE);
1026     glClearDepthf(depth_value);
1027     clear_mask |= GL_DEPTH_BUFFER_BIT;
1028   }
1029   glClear(clear_mask);
1030   glEnable(GL_SCISSOR_TEST);
1031 
1032   // Restore color/depth mask.
1033   if (framebuffer->HasColorBuffer())
1034   {
1035     glColorMask(m_current_blend_state.colorupdate, m_current_blend_state.colorupdate,
1036                 m_current_blend_state.colorupdate, m_current_blend_state.alphaupdate);
1037   }
1038   if (framebuffer->HasDepthBuffer())
1039     glDepthMask(m_current_depth_state.updateenable);
1040 }
1041 
BindBackbuffer(const ClearColor & clear_color)1042 void Renderer::BindBackbuffer(const ClearColor& clear_color)
1043 {
1044   CheckForSurfaceChange();
1045   CheckForSurfaceResize();
1046   SetAndClearFramebuffer(m_system_framebuffer.get(), clear_color);
1047 }
1048 
PresentBackbuffer()1049 void Renderer::PresentBackbuffer()
1050 {
1051   if (g_ogl_config.bSupportsDebug)
1052   {
1053     if (Common::Log::LogManager::GetInstance()->IsEnabled(Common::Log::HOST_GPU,
1054                                                           Common::Log::LERROR))
1055     {
1056       glEnable(GL_DEBUG_OUTPUT);
1057     }
1058     else
1059     {
1060       glDisable(GL_DEBUG_OUTPUT);
1061     }
1062   }
1063 
1064   // Swap the back and front buffers, presenting the image.
1065   m_main_gl_context->Swap();
1066 }
1067 
OnConfigChanged(u32 bits)1068 void Renderer::OnConfigChanged(u32 bits)
1069 {
1070   if (bits & CONFIG_CHANGE_BIT_VSYNC && !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC))
1071     m_main_gl_context->SwapInterval(g_ActiveConfig.bVSyncActive);
1072 
1073   if (bits & CONFIG_CHANGE_BIT_ANISOTROPY)
1074     g_sampler_cache->Clear();
1075 }
1076 
Flush()1077 void Renderer::Flush()
1078 {
1079   // ensure all commands are sent to the GPU.
1080   // Otherwise the driver could batch several frames together.
1081   glFlush();
1082 }
1083 
WaitForGPUIdle()1084 void Renderer::WaitForGPUIdle()
1085 {
1086   glFinish();
1087 }
1088 
CheckForSurfaceChange()1089 void Renderer::CheckForSurfaceChange()
1090 {
1091   if (!m_surface_changed.TestAndClear())
1092     return;
1093 
1094   m_main_gl_context->UpdateSurface(m_new_surface_handle);
1095   m_new_surface_handle = nullptr;
1096 
1097   // With a surface change, the window likely has new dimensions.
1098   m_backbuffer_width = m_main_gl_context->GetBackBufferWidth();
1099   m_backbuffer_height = m_main_gl_context->GetBackBufferHeight();
1100   m_system_framebuffer->UpdateDimensions(m_backbuffer_width, m_backbuffer_height);
1101 }
1102 
CheckForSurfaceResize()1103 void Renderer::CheckForSurfaceResize()
1104 {
1105   if (!m_surface_resized.TestAndClear())
1106     return;
1107 
1108   m_main_gl_context->Update();
1109   m_backbuffer_width = m_main_gl_context->GetBackBufferWidth();
1110   m_backbuffer_height = m_main_gl_context->GetBackBufferHeight();
1111   m_system_framebuffer->UpdateDimensions(m_backbuffer_width, m_backbuffer_height);
1112 }
1113 
BeginUtilityDrawing()1114 void Renderer::BeginUtilityDrawing()
1115 {
1116   ::Renderer::BeginUtilityDrawing();
1117   if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
1118   {
1119     glDisable(GL_CLIP_DISTANCE0);
1120     glDisable(GL_CLIP_DISTANCE1);
1121   }
1122 }
1123 
EndUtilityDrawing()1124 void Renderer::EndUtilityDrawing()
1125 {
1126   ::Renderer::EndUtilityDrawing();
1127   if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
1128   {
1129     glEnable(GL_CLIP_DISTANCE0);
1130     glEnable(GL_CLIP_DISTANCE1);
1131   }
1132 }
1133 
ApplyRasterizationState(const RasterizationState state)1134 void Renderer::ApplyRasterizationState(const RasterizationState state)
1135 {
1136   if (m_current_rasterization_state == state)
1137     return;
1138 
1139   // none, ccw, cw, ccw
1140   if (state.cullmode != GenMode::CULL_NONE)
1141   {
1142     // TODO: GX_CULL_ALL not supported, yet!
1143     glEnable(GL_CULL_FACE);
1144     glFrontFace(state.cullmode == GenMode::CULL_FRONT ? GL_CCW : GL_CW);
1145   }
1146   else
1147   {
1148     glDisable(GL_CULL_FACE);
1149   }
1150 
1151   m_current_rasterization_state = state;
1152 }
1153 
ApplyDepthState(const DepthState state)1154 void Renderer::ApplyDepthState(const DepthState state)
1155 {
1156   if (m_current_depth_state == state)
1157     return;
1158 
1159   const GLenum glCmpFuncs[8] = {GL_NEVER,   GL_LESS,     GL_EQUAL,  GL_LEQUAL,
1160                                 GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS};
1161 
1162   if (state.testenable)
1163   {
1164     glEnable(GL_DEPTH_TEST);
1165     glDepthMask(state.updateenable ? GL_TRUE : GL_FALSE);
1166     glDepthFunc(glCmpFuncs[state.func]);
1167   }
1168   else
1169   {
1170     // if the test is disabled write is disabled too
1171     // TODO: When PE performance metrics are being emulated via occlusion queries, we should
1172     // (probably?) enable depth test with depth function ALWAYS here
1173     glDisable(GL_DEPTH_TEST);
1174     glDepthMask(GL_FALSE);
1175   }
1176 
1177   m_current_depth_state = state;
1178 }
1179 
ApplyBlendingState(const BlendingState state)1180 void Renderer::ApplyBlendingState(const BlendingState state)
1181 {
1182   if (m_current_blend_state == state)
1183     return;
1184 
1185   bool useDualSource =
1186       state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
1187       (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
1188   // Only use shader blend if we need to and we don't support dual-source blending directly
1189   bool useShaderBlend = !useDualSource && state.usedualsrc && state.dstalpha &&
1190                         g_ActiveConfig.backend_info.bSupportsFramebufferFetch;
1191 
1192   if (useShaderBlend)
1193   {
1194     glDisable(GL_BLEND);
1195   }
1196   else
1197   {
1198     const GLenum src_factors[8] = {GL_ZERO,
1199                                    GL_ONE,
1200                                    GL_DST_COLOR,
1201                                    GL_ONE_MINUS_DST_COLOR,
1202                                    useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
1203                                    useDualSource ? GL_ONE_MINUS_SRC1_ALPHA :
1204                                                    (GLenum)GL_ONE_MINUS_SRC_ALPHA,
1205                                    GL_DST_ALPHA,
1206                                    GL_ONE_MINUS_DST_ALPHA};
1207     const GLenum dst_factors[8] = {GL_ZERO,
1208                                    GL_ONE,
1209                                    GL_SRC_COLOR,
1210                                    GL_ONE_MINUS_SRC_COLOR,
1211                                    useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA,
1212                                    useDualSource ? GL_ONE_MINUS_SRC1_ALPHA :
1213                                                    (GLenum)GL_ONE_MINUS_SRC_ALPHA,
1214                                    GL_DST_ALPHA,
1215                                    GL_ONE_MINUS_DST_ALPHA};
1216 
1217     if (state.blendenable)
1218       glEnable(GL_BLEND);
1219     else
1220       glDisable(GL_BLEND);
1221 
1222     // Always call glBlendEquationSeparate and glBlendFuncSeparate, even when
1223     // GL_BLEND is disabled, as a workaround for some bugs (possibly graphics
1224     // driver issues?). See https://bugs.dolphin-emu.org/issues/10120 : "Sonic
1225     // Adventure 2 Battle: graphics crash when loading first Dark level"
1226     GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
1227     GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
1228     glBlendEquationSeparate(equation, equationAlpha);
1229     glBlendFuncSeparate(src_factors[state.srcfactor], dst_factors[state.dstfactor],
1230                         src_factors[state.srcfactoralpha], dst_factors[state.dstfactoralpha]);
1231   }
1232 
1233   const GLenum logic_op_codes[16] = {
1234       GL_CLEAR,         GL_AND,         GL_AND_REVERSE, GL_COPY,  GL_AND_INVERTED, GL_NOOP,
1235       GL_XOR,           GL_OR,          GL_NOR,         GL_EQUIV, GL_INVERT,       GL_OR_REVERSE,
1236       GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND,        GL_SET};
1237 
1238   // Logic ops aren't available in GLES3
1239   if (!IsGLES())
1240   {
1241     if (state.logicopenable)
1242     {
1243       glEnable(GL_COLOR_LOGIC_OP);
1244       glLogicOp(logic_op_codes[state.logicmode]);
1245     }
1246     else
1247     {
1248       glDisable(GL_COLOR_LOGIC_OP);
1249     }
1250   }
1251 
1252   glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
1253   m_current_blend_state = state;
1254 }
1255 
SetPipeline(const AbstractPipeline * pipeline)1256 void Renderer::SetPipeline(const AbstractPipeline* pipeline)
1257 {
1258   if (m_current_pipeline == pipeline)
1259     return;
1260 
1261   if (pipeline)
1262   {
1263     ApplyRasterizationState(static_cast<const OGLPipeline*>(pipeline)->GetRasterizationState());
1264     ApplyDepthState(static_cast<const OGLPipeline*>(pipeline)->GetDepthState());
1265     ApplyBlendingState(static_cast<const OGLPipeline*>(pipeline)->GetBlendingState());
1266     ProgramShaderCache::BindVertexFormat(
1267         static_cast<const OGLPipeline*>(pipeline)->GetVertexFormat());
1268     static_cast<const OGLPipeline*>(pipeline)->GetProgram()->shader.Bind();
1269   }
1270   else
1271   {
1272     ProgramShaderCache::InvalidateLastProgram();
1273     glUseProgram(0);
1274   }
1275   m_current_pipeline = pipeline;
1276 }
1277 
SetTexture(u32 index,const AbstractTexture * texture)1278 void Renderer::SetTexture(u32 index, const AbstractTexture* texture)
1279 {
1280   const OGLTexture* gl_texture = static_cast<const OGLTexture*>(texture);
1281   if (m_bound_textures[index] == gl_texture)
1282     return;
1283 
1284   glActiveTexture(GL_TEXTURE0 + index);
1285   if (gl_texture)
1286     glBindTexture(gl_texture->GetGLTarget(), gl_texture->GetGLTextureId());
1287   else
1288     glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1289   m_bound_textures[index] = gl_texture;
1290 }
1291 
SetSamplerState(u32 index,const SamplerState & state)1292 void Renderer::SetSamplerState(u32 index, const SamplerState& state)
1293 {
1294   g_sampler_cache->SetSamplerState(index, state);
1295 }
1296 
SetComputeImageTexture(AbstractTexture * texture,bool read,bool write)1297 void Renderer::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
1298 {
1299   if (m_bound_image_texture == texture)
1300     return;
1301 
1302   if (texture)
1303   {
1304     const GLenum access = read ? (write ? GL_READ_WRITE : GL_READ_ONLY) : GL_WRITE_ONLY;
1305     glBindImageTexture(0, static_cast<OGLTexture*>(texture)->GetGLTextureId(), 0, GL_TRUE, 0,
1306                        access, static_cast<OGLTexture*>(texture)->GetGLFormatForImageTexture());
1307   }
1308   else
1309   {
1310     glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
1311   }
1312 
1313   m_bound_image_texture = texture;
1314 }
1315 
UnbindTexture(const AbstractTexture * texture)1316 void Renderer::UnbindTexture(const AbstractTexture* texture)
1317 {
1318   for (size_t i = 0; i < m_bound_textures.size(); i++)
1319   {
1320     if (m_bound_textures[i] != texture)
1321       continue;
1322 
1323     glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
1324     glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1325     m_bound_textures[i] = nullptr;
1326   }
1327 
1328   if (m_bound_image_texture == texture)
1329   {
1330     glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
1331     m_bound_image_texture = nullptr;
1332   }
1333 }
1334 
CreateAsyncShaderCompiler()1335 std::unique_ptr<VideoCommon::AsyncShaderCompiler> Renderer::CreateAsyncShaderCompiler()
1336 {
1337   return std::make_unique<SharedContextAsyncShaderCompiler>();
1338 }
1339 
BindSharedReadFramebuffer()1340 void Renderer::BindSharedReadFramebuffer()
1341 {
1342   glBindFramebuffer(GL_READ_FRAMEBUFFER, m_shared_read_framebuffer);
1343 }
1344 
BindSharedDrawFramebuffer()1345 void Renderer::BindSharedDrawFramebuffer()
1346 {
1347   glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_shared_draw_framebuffer);
1348 }
1349 
RestoreFramebufferBinding()1350 void Renderer::RestoreFramebufferBinding()
1351 {
1352   glBindFramebuffer(
1353       GL_FRAMEBUFFER,
1354       m_current_framebuffer ? static_cast<OGLFramebuffer*>(m_current_framebuffer)->GetFBO() : 0);
1355 }
1356 
1357 }  // namespace OGL
1358