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