summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitmodules9
-rw-r--r--CMakeLists.txt2
-rw-r--r--dist/qt_themes/qdarkstyle/LICENSE.md183
-rw-r--r--dist/qt_themes/qdarkstyle/style.qss607
-rw-r--r--externals/CMakeLists.txt14
m---------externals/cubeb0
m---------externals/dynarmic0
-rw-r--r--externals/glad/include/glad/glad.h23
-rw-r--r--externals/glad/src/glad.c6385
m---------externals/mbedtls0
m---------externals/opus0
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/audio_core/CMakeLists.txt27
-rw-r--r--src/audio_core/audio_out.cpp58
-rw-r--r--src/audio_core/audio_out.h43
-rw-r--r--src/audio_core/audio_renderer.cpp234
-rw-r--r--src/audio_core/audio_renderer.h206
-rw-r--r--src/audio_core/buffer.h45
-rw-r--r--src/audio_core/codec.cpp77
-rw-r--r--src/audio_core/codec.h44
-rw-r--r--src/audio_core/cubeb_sink.cpp200
-rw-r--r--src/audio_core/cubeb_sink.h32
-rw-r--r--src/audio_core/null_sink.h27
-rw-r--r--src/audio_core/sink.h31
-rw-r--r--src/audio_core/sink_details.cpp44
-rw-r--r--src/audio_core/sink_details.h35
-rw-r--r--src/audio_core/sink_stream.h32
-rw-r--r--src/audio_core/stream.cpp127
-rw-r--r--src/audio_core/stream.h102
-rw-r--r--src/common/common_funcs.h4
-rw-r--r--src/common/common_paths.h1
-rw-r--r--src/common/file_util.cpp14
-rw-r--r--src/common/file_util.h3
-rw-r--r--src/common/logging/backend.cpp16
-rw-r--r--src/common/logging/log.h16
-rw-r--r--src/common/logging/text_formatter.h1
-rw-r--r--src/common/math_util.h10
-rw-r--r--src/common/string_util.cpp8
-rw-r--r--src/common/swap.h2
-rw-r--r--src/common/threadsafe_queue.h32
-rw-r--r--src/common/timer.cpp95
-rw-r--r--src/common/timer.h17
-rw-r--r--src/core/CMakeLists.txt86
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp18
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp2
-rw-r--r--src/core/core.cpp38
-rw-r--r--src/core/core.h60
-rw-r--r--src/core/core_cpu.cpp1
-rw-r--r--src/core/core_timing.cpp14
-rw-r--r--src/core/core_timing.h11
-rw-r--r--src/core/crypto/aes_util.cpp115
-rw-r--r--src/core/crypto/aes_util.h64
-rw-r--r--src/core/crypto/ctr_encryption_layer.cpp56
-rw-r--r--src/core/crypto/ctr_encryption_layer.h33
-rw-r--r--src/core/crypto/encryption_layer.cpp42
-rw-r--r--src/core/crypto/encryption_layer.h33
-rw-r--r--src/core/crypto/key_manager.cpp208
-rw-r--r--src/core/crypto/key_manager.h120
-rw-r--r--src/core/crypto/sha_util.cpp5
-rw-r--r--src/core/crypto/sha_util.h20
-rw-r--r--src/core/file_sys/card_image.cpp149
-rw-r--r--src/core/file_sys/card_image.h96
-rw-r--r--src/core/file_sys/content_archive.cpp236
-rw-r--r--src/core/file_sys/content_archive.h31
-rw-r--r--src/core/file_sys/partition_filesystem.cpp5
-rw-r--r--src/core/file_sys/romfs.cpp124
-rw-r--r--src/core/file_sys/romfs.h35
-rw-r--r--src/core/file_sys/vfs.cpp43
-rw-r--r--src/core/file_sys/vfs.h23
-rw-r--r--src/core/file_sys/vfs_offset.cpp7
-rw-r--r--src/core/file_sys/vfs_offset.h3
-rw-r--r--src/core/file_sys/vfs_real.cpp6
-rw-r--r--src/core/file_sys/vfs_real.h3
-rw-r--r--src/core/file_sys/vfs_vector.cpp86
-rw-r--r--src/core/file_sys/vfs_vector.h44
-rw-r--r--src/core/gdbstub/gdbstub.cpp175
-rw-r--r--src/core/gdbstub/gdbstub.h8
-rw-r--r--src/core/hle/ipc_helpers.h7
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp38
-rw-r--r--src/core/hle/kernel/address_arbiter.h4
-rw-r--r--src/core/hle/kernel/client_port.cpp17
-rw-r--r--src/core/hle/kernel/client_port.h16
-rw-r--r--src/core/hle/kernel/client_session.cpp2
-rw-r--r--src/core/hle/kernel/client_session.h2
-rw-r--r--src/core/hle/kernel/event.cpp4
-rw-r--r--src/core/hle/kernel/event.h14
-rw-r--r--src/core/hle/kernel/handle_table.cpp1
-rw-r--r--src/core/hle/kernel/handle_table.h2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp7
-rw-r--r--src/core/hle/kernel/hle_ipc.h3
-rw-r--r--src/core/hle/kernel/kernel.cpp8
-rw-r--r--src/core/hle/kernel/kernel.h112
-rw-r--r--src/core/hle/kernel/memory.cpp92
-rw-r--r--src/core/hle/kernel/memory.h31
-rw-r--r--src/core/hle/kernel/mutex.cpp7
-rw-r--r--src/core/hle/kernel/mutex.h8
-rw-r--r--src/core/hle/kernel/object.cpp35
-rw-r--r--src/core/hle/kernel/object.h100
-rw-r--r--src/core/hle/kernel/object_address_table.cpp36
-rw-r--r--src/core/hle/kernel/object_address_table.h62
-rw-r--r--src/core/hle/kernel/process.cpp84
-rw-r--r--src/core/hle/kernel/process.h64
-rw-r--r--src/core/hle/kernel/resource_limit.h2
-rw-r--r--src/core/hle/kernel/scheduler.cpp4
-rw-r--r--src/core/hle/kernel/scheduler.h4
-rw-r--r--src/core/hle/kernel/server_port.cpp2
-rw-r--r--src/core/hle/kernel/server_port.h3
-rw-r--r--src/core/hle/kernel/server_session.cpp4
-rw-r--r--src/core/hle/kernel/server_session.h6
-rw-r--r--src/core/hle/kernel/session.h2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp37
-rw-r--r--src/core/hle/kernel/shared_memory.h8
-rw-r--r--src/core/hle/kernel/svc.cpp6
-rw-r--r--src/core/hle/kernel/thread.cpp56
-rw-r--r--src/core/hle/kernel/thread.h15
-rw-r--r--src/core/hle/kernel/timer.cpp2
-rw-r--r--src/core/hle/kernel/timer.h2
-rw-r--r--src/core/hle/kernel/vm_manager.cpp36
-rw-r--r--src/core/hle/kernel/vm_manager.h8
-rw-r--r--src/core/hle/kernel/wait_object.cpp5
-rw-r--r--src/core/hle/kernel/wait_object.h2
-rw-r--r--src/core/hle/service/acc/acc.cpp30
-rw-r--r--src/core/hle/service/am/am.cpp9
-rw-r--r--src/core/hle/service/am/idle.cpp24
-rw-r--r--src/core/hle/service/am/idle.h16
-rw-r--r--src/core/hle/service/am/omm.cpp42
-rw-r--r--src/core/hle/service/am/omm.h16
-rw-r--r--src/core/hle/service/am/spsm.cpp30
-rw-r--r--src/core/hle/service/am/spsm.h16
-rw-r--r--src/core/hle/service/apm/apm.cpp1
-rw-r--r--src/core/hle/service/apm/interface.cpp25
-rw-r--r--src/core/hle/service/apm/interface.h8
-rw-r--r--src/core/hle/service/arp/arp.cpp75
-rw-r--r--src/core/hle/service/arp/arp.h16
-rw-r--r--src/core/hle/service/audio/audctl.cpp45
-rw-r--r--src/core/hle/service/audio/audctl.h16
-rw-r--r--src/core/hle/service/audio/auddbg.cpp20
-rw-r--r--src/core/hle/service/audio/auddbg.h16
-rw-r--r--src/core/hle/service/audio/audin_a.cpp22
-rw-r--r--src/core/hle/service/audio/audin_a.h16
-rw-r--r--src/core/hle/service/audio/audio.cpp16
-rw-r--r--src/core/hle/service/audio/audout_a.cpp24
-rw-r--r--src/core/hle/service/audio/audout_a.h16
-rw-r--r--src/core/hle/service/audio/audout_u.cpp199
-rw-r--r--src/core/hle/service/audio/audout_u.h24
-rw-r--r--src/core/hle/service/audio/audrec_a.cpp20
-rw-r--r--src/core/hle/service/audio/audrec_a.h16
-rw-r--r--src/core/hle/service/audio/audren_a.cpp26
-rw-r--r--src/core/hle/service/audio/audren_a.h16
-rw-r--r--src/core/hle/service/audio/audren_u.cpp208
-rw-r--r--src/core/hle/service/audio/audren_u.h19
-rw-r--r--src/core/hle/service/audio/hwopus.cpp135
-rw-r--r--src/core/hle/service/audio/hwopus.h1
-rw-r--r--src/core/hle/service/bpc/bpc.cpp57
-rw-r--r--src/core/hle/service/bpc/bpc.h15
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp72
-rw-r--r--src/core/hle/service/btdrv/btdrv.h16
-rw-r--r--src/core/hle/service/btm/btm.cpp121
-rw-r--r--src/core/hle/service/btm/btm.h15
-rw-r--r--src/core/hle/service/caps/caps.cpp152
-rw-r--r--src/core/hle/service/caps/caps.h15
-rw-r--r--src/core/hle/service/fgm/fgm.cpp75
-rw-r--r--src/core/hle/service/fgm/fgm.h15
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp4
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.cpp22
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.h16
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.cpp23
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.h16
-rw-r--r--src/core/hle/service/hid/hid.cpp19
-rw-r--r--src/core/hle/service/lbl/lbl.cpp90
-rw-r--r--src/core/hle/service/lbl/lbl.h15
-rw-r--r--src/core/hle/service/lm/lm.cpp8
-rw-r--r--src/core/hle/service/mig/mig.cpp34
-rw-r--r--src/core/hle/service/mig/mig.h15
-rw-r--r--src/core/hle/service/mii/mii.cpp107
-rw-r--r--src/core/hle/service/mii/mii.h15
-rw-r--r--src/core/hle/service/ncm/ncm.cpp59
-rw-r--r--src/core/hle/service/ncm/ncm.h15
-rw-r--r--src/core/hle/service/nfc/nfc.cpp222
-rw-r--r--src/core/hle/service/nfc/nfc.h15
-rw-r--r--src/core/hle/service/ns/ns.cpp447
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp16
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp16
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h1
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp2
-rw-r--r--src/core/hle/service/nvdrv/interface.h1
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp2
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp5
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp13
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h8
-rw-r--r--src/core/hle/service/pcie/pcie.cpp64
-rw-r--r--src/core/hle/service/pcie/pcie.h15
-rw-r--r--src/core/hle/service/pcv/pcv.cpp84
-rw-r--r--src/core/hle/service/pcv/pcv.h15
-rw-r--r--src/core/hle/service/psc/psc.cpp77
-rw-r--r--src/core/hle/service/psc/psc.h15
-rw-r--r--src/core/hle/service/service.cpp36
-rw-r--r--src/core/hle/service/service.h3
-rw-r--r--src/core/hle/service/set/set.cpp15
-rw-r--r--src/core/hle/service/set/set.h2
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/hle/service/time/time.cpp4
-rw-r--r--src/core/hle/service/usb/usb.cpp238
-rw-r--r--src/core/hle/service/usb/usb.h15
-rw-r--r--src/core/hle/service/wlan/wlan.cpp172
-rw-r--r--src/core/hle/service/wlan/wlan.h15
-rw-r--r--src/core/hw/aes/ccm.cpp28
-rw-r--r--src/core/hw/hw.cpp96
-rw-r--r--src/core/hw/hw.h50
-rw-r--r--src/core/hw/lcd.cpp67
-rw-r--r--src/core/hw/lcd.h86
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp11
-rw-r--r--src/core/loader/deconstructed_rom_directory.h6
-rw-r--r--src/core/loader/elf.cpp6
-rw-r--r--src/core/loader/loader.cpp9
-rw-r--r--src/core/loader/loader.h6
-rw-r--r--src/core/loader/nca.cpp63
-rw-r--r--src/core/loader/nca.h6
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nro.h2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/loader/nso.h2
-rw-r--r--src/core/loader/xci.cpp74
-rw-r--r--src/core/loader/xci.h44
-rw-r--r--src/core/memory.cpp146
-rw-r--r--src/core/memory.h111
-rw-r--r--src/core/perf_stats.cpp17
-rw-r--r--src/core/perf_stats.h8
-rw-r--r--src/core/settings.cpp10
-rw-r--r--src/core/settings.h9
-rw-r--r--src/input_common/keyboard.cpp5
-rw-r--r--src/input_common/motion_emu.cpp2
-rw-r--r--src/input_common/sdl/sdl.cpp20
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/core/memory/memory.cpp56
-rw-r--r--src/video_core/engines/maxwell_3d.cpp12
-rw-r--r--src/video_core/engines/maxwell_3d.h8
-rw-r--r--src/video_core/gpu.cpp6
-rw-r--r--src/video_core/gpu.h7
-rw-r--r--src/video_core/macro_interpreter.cpp4
-rw-r--r--src/video_core/macro_interpreter.h4
-rw-r--r--src/video_core/renderer_base.cpp18
-rw-r--r--src/video_core/renderer_base.h29
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h36
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp9
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_state.h5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp30
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h17
-rw-r--r--src/video_core/textures/decoders.cpp4
-rw-r--r--src/video_core/video_core.cpp28
-rw-r--r--src/video_core/video_core.h24
-rw-r--r--src/yuzu/CMakeLists.txt3
-rw-r--r--src/yuzu/about_dialog.cpp7
-rw-r--r--src/yuzu/about_dialog.h2
-rw-r--r--src/yuzu/aboutdialog.ui4
-rw-r--r--src/yuzu/bootmanager.h2
-rw-r--r--src/yuzu/configuration/config.cpp19
-rw-r--r--src/yuzu/configuration/configure.ui21
-rw-r--r--src/yuzu/configuration/configure_audio.cpp90
-rw-r--r--src/yuzu/configuration/configure_audio.h31
-rw-r--r--src/yuzu/configuration/configure_audio.ui130
-rw-r--r--src/yuzu/configuration/configure_debug.cpp3
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp8
-rw-r--r--src/yuzu/configuration/configure_dialog.h4
-rw-r--r--src/yuzu/configuration/configure_general.cpp7
-rw-r--r--src/yuzu/configuration/configure_general.h4
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp3
-rw-r--r--src/yuzu/configuration/configure_input.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp10
-rw-r--r--src/yuzu/configuration/configure_system.ui29
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp6
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoint_observer.h8
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.cpp26
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.h11
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints_p.h1
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp37
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.h15
-rw-r--r--src/yuzu/debugger/wait_tree.cpp4
-rw-r--r--src/yuzu/debugger/wait_tree.h6
-rw-r--r--src/yuzu/game_list.cpp46
-rw-r--r--src/yuzu/game_list_p.h17
-rw-r--r--src/yuzu/hotkeys.cpp67
-rw-r--r--src/yuzu/hotkeys.h107
-rw-r--r--src/yuzu/main.cpp173
-rw-r--r--src/yuzu/main.h5
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/default_ini.h22
-rw-r--r--src/yuzu_cmd/yuzu.cpp20
301 files changed, 11786 insertions, 5934 deletions
diff --git a/.gitmodules b/.gitmodules
index a08850c1a..4f4e8690b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,6 +7,9 @@
[submodule "catch"]
path = externals/catch
url = https://github.com/philsquared/Catch.git
+[submodule "cubeb"]
+ path = externals/cubeb
+ url = https://github.com/kinetiknz/cubeb.git
[submodule "dynarmic"]
path = externals/dynarmic
url = https://github.com/MerryMage/dynarmic.git
@@ -22,3 +25,9 @@
[submodule "unicorn"]
path = externals/unicorn
url = https://github.com/yuzu-emu/unicorn
+[submodule "mbedtls"]
+ path = externals/mbedtls
+ url = https://github.com/DarkLordZach/mbedtls
+[submodule "opus"]
+ path = externals/opus
+ url = https://github.com/ogniK5377/opus.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86d2423ed..3639b623c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,8 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "EN
option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
+option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
+
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
message(STATUS "Copying pre-commit hook")
file(COPY hooks/pre-commit
diff --git a/dist/qt_themes/qdarkstyle/LICENSE.md b/dist/qt_themes/qdarkstyle/LICENSE.md
new file mode 100644
index 000000000..d8910aea5
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/LICENSE.md
@@ -0,0 +1,183 @@
+# License
+
+## The MIT License (MIT) - Code
+
+Copyright (c) 2013-2018 Colin Duquesnoy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+## Creative Commons Attribution International 4.0 - Images
+
+QDarkStyle (c) 2013-2018 Colin Duquesnoy
+
+Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+
+### Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+
+* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
+
+* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
+
+## Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+
+### Section 1 – Definitions
+
+a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+
+b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+
+c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+
+e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+
+f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+
+g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+
+h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
+
+i. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+
+j. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+
+k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+
+### Section 2 – Scope
+
+a. ___License grant.___
+
+ 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+
+ A. reproduce and Share the Licensed Material, in whole or in part; and
+
+ B. produce, reproduce, and Share Adapted Material.
+
+ 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+
+ 3. __Term.__ The term of this Public License is specified in Section 6(a).
+
+ 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+
+ 5. __Downstream recipients.__
+
+ A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+
+ B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+
+ 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+
+b. ___Other rights.___
+
+ 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this Public License.
+
+ 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+
+### Section 3 – License Conditions
+
+Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+
+a. ___Attribution.___
+
+ 1. If You Share the Licensed Material (including in modified form), You must:
+
+ A. retain the following if it is supplied by the Licensor with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+ B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+
+ C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+
+ 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
+
+### Section 4 – Sui Generis Database Rights
+
+Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+
+a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+
+b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
+
+c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+
+### Section 5 – Disclaimer of Warranties and Limitation of Liability
+
+a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
+
+b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
+
+c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+### Section 6 – Term and Termination
+
+a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+
+b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+
+c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+
+d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+### Section 7 – Other Terms and Conditions
+
+a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+
+b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+
+### Section 8 – Interpretation
+
+a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+
+b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+
+c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+
+d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+
+> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+>
+> Creative Commons may be contacted at creativecommons.org \ No newline at end of file
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
index c8e50312a..399c38dce 100644
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -1,40 +1,15 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) <2013-2014> <Colin Duquesnoy>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-QToolTip
-{
+QToolTip {
border: 1px solid #76797C;
- background-color: rgb(90, 102, 117);;
+ background-color: #5A7566;
color: white;
- padding: 5px;
+ padding: 0px; /*remove padding, for fix combobox tooltip.*/
opacity: 200;
}
-QWidget
-{
+QWidget {
color: #eff0f1;
background-color: #31363b;
- selection-background-color:#3daee9;
+ selection-background-color: #3daee9;
selection-color: #eff0f1;
background-clip: border;
border-image: none;
@@ -42,43 +17,38 @@ QWidget
outline: 0;
}
-QWidget:item:hover
-{
+QWidget:item:hover {
background-color: #18465d;
color: #eff0f1;
}
-QWidget:item:selected
-{
+QWidget:item:selected {
background-color: #18465d;
}
-QCheckBox
-{
+QCheckBox {
spacing: 5px;
outline: none;
color: #eff0f1;
margin-bottom: 2px;
}
-QCheckBox:disabled
-{
+QCheckBox:disabled {
color: #76797C;
}
QCheckBox::indicator,
-QGroupBox::indicator
-{
+QGroupBox::indicator {
width: 18px;
height: 18px;
}
-QGroupBox::indicator
-{
+
+QGroupBox::indicator {
margin-left: 2px;
}
-QCheckBox::indicator:unchecked
-{
+QCheckBox::indicator:unchecked,
+QGroupBox::indicator:unchecked {
image: url(:/qss_icons/rc/checkbox_unchecked.png);
}
@@ -87,14 +57,13 @@ QCheckBox::indicator:unchecked:focus,
QCheckBox::indicator:unchecked:pressed,
QGroupBox::indicator:unchecked:hover,
QGroupBox::indicator:unchecked:focus,
-QGroupBox::indicator:unchecked:pressed
-{
- border: none;
+QGroupBox::indicator:unchecked:pressed {
+ border: none;
image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
}
-QCheckBox::indicator:checked
-{
+QCheckBox::indicator:checked,
+QGroupBox::indicator:checked {
image: url(:/qss_icons/rc/checkbox_checked.png);
}
@@ -103,72 +72,60 @@ QCheckBox::indicator:checked:focus,
QCheckBox::indicator:checked:pressed,
QGroupBox::indicator:checked:hover,
QGroupBox::indicator:checked:focus,
-QGroupBox::indicator:checked:pressed
-{
- border: none;
+QGroupBox::indicator:checked:pressed {
+ border: none;
image: url(:/qss_icons/rc/checkbox_checked_focus.png);
}
-
-QCheckBox::indicator:indeterminate
-{
+QCheckBox::indicator:indeterminate {
image: url(:/qss_icons/rc/checkbox_indeterminate.png);
}
QCheckBox::indicator:indeterminate:focus,
QCheckBox::indicator:indeterminate:hover,
-QCheckBox::indicator:indeterminate:pressed
-{
+QCheckBox::indicator:indeterminate:pressed {
image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
}
QCheckBox::indicator:checked:disabled,
-QGroupBox::indicator:checked:disabled
-{
+QGroupBox::indicator:checked:disabled {
image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
}
QCheckBox::indicator:unchecked:disabled,
-QGroupBox::indicator:unchecked:disabled
-{
+QGroupBox::indicator:unchecked:disabled {
image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png);
}
-QRadioButton
-{
+QRadioButton {
spacing: 5px;
outline: none;
color: #eff0f1;
margin-bottom: 2px;
}
-QRadioButton:disabled
-{
+QRadioButton:disabled {
color: #76797C;
}
-QRadioButton::indicator
-{
+
+QRadioButton::indicator {
width: 21px;
height: 21px;
}
-QRadioButton::indicator:unchecked
-{
+QRadioButton::indicator:unchecked {
image: url(:/qss_icons/rc/radio_unchecked.png);
}
-
QRadioButton::indicator:unchecked:hover,
QRadioButton::indicator:unchecked:focus,
-QRadioButton::indicator:unchecked:pressed
-{
+QRadioButton::indicator:unchecked:pressed {
border: none;
outline: none;
image: url(:/qss_icons/rc/radio_unchecked_focus.png);
}
-QRadioButton::indicator:checked
-{
+QRadioButton::indicator:checked {
border: none;
outline: none;
image: url(:/qss_icons/rc/radio_checked.png);
@@ -176,72 +133,60 @@ QRadioButton::indicator:checked
QRadioButton::indicator:checked:hover,
QRadioButton::indicator:checked:focus,
-QRadioButton::indicator:checked:pressed
-{
+QRadioButton::indicator:checked:pressed {
border: none;
outline: none;
image: url(:/qss_icons/rc/radio_checked_focus.png);
}
-QRadioButton::indicator:checked:disabled
-{
+QRadioButton::indicator:checked:disabled {
outline: none;
image: url(:/qss_icons/rc/radio_checked_disabled.png);
}
-QRadioButton::indicator:unchecked:disabled
-{
+QRadioButton::indicator:unchecked:disabled {
image: url(:/qss_icons/rc/radio_unchecked_disabled.png);
}
-
-QMenuBar
-{
+QMenuBar {
background-color: #31363b;
color: #eff0f1;
}
-QMenuBar::item
-{
+QMenuBar::item {
background: transparent;
}
-QMenuBar::item:selected
-{
+QMenuBar::item:selected {
background: transparent;
border: 1px solid #76797C;
}
-QMenuBar::item:pressed
-{
+QMenuBar::item:pressed {
border: 1px solid #76797C;
background-color: #3daee9;
color: #eff0f1;
- margin-bottom:-1px;
- padding-bottom:1px;
+ margin-bottom: -1px;
+ padding-bottom: 1px;
}
-QMenu
-{
+QMenu {
border: 1px solid #76797C;
color: #eff0f1;
margin: 2px;
}
-QMenu::icon
-{
+QMenu::icon {
margin: 5px;
}
-QMenu::item
-{
+QMenu::item {
padding: 5px 30px 5px 30px;
- margin-left: 5px;
- border: 1px solid transparent; /* reserve space for selection border */
+ border: 1px solid transparent;
+ /* reserve space for selection border */
}
-QMenu::item:selected
-{
+QMenu::item:selected {
color: #eff0f1;
}
@@ -257,8 +202,10 @@ QMenu::indicator {
height: 18px;
}
+
/* non-exclusive indicator = check box style indicator
(see QActionGroup::setExclusive) */
+
QMenu::indicator:non-exclusive:unchecked {
image: url(:/qss_icons/rc/checkbox_unchecked.png);
}
@@ -275,7 +222,9 @@ QMenu::indicator:non-exclusive:checked:selected {
image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
}
+
/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
+
QMenu::indicator:exclusive:unchecked {
image: url(:/qss_icons/rc/radio_unchecked.png);
}
@@ -297,33 +246,31 @@ QMenu::right-arrow {
image: url(:/qss_icons/rc/right_arrow.png)
}
-
-QWidget:disabled
-{
+QWidget:disabled {
color: #454545;
background-color: #31363b;
}
-QAbstractItemView
-{
+QAbstractItemView {
alternate-background-color: #31363b;
color: #eff0f1;
- border: 1px solid 3A3939;
+ border: 1px solid #3A3939;
border-radius: 2px;
}
-QWidget:focus, QMenuBar:focus
-{
+QWidget:focus,
+QMenuBar:focus {
border: 1px solid #3daee9;
}
-QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus
-{
+QTabWidget:focus,
+QCheckBox:focus,
+QRadioButton:focus,
+QSlider:focus {
border: none;
}
-QLineEdit
-{
+QLineEdit {
background-color: #232629;
padding: 5px;
border-style: solid;
@@ -332,13 +279,12 @@ QLineEdit
color: #eff0f1;
}
-QAbstractItemView QLineEdit
-{
+QAbstractItemView QLineEdit {
padding: 0;
}
QGroupBox {
- border:1px solid #76797C;
+ border: 1px solid #76797C;
border-radius: 2px;
margin-top: 20px;
}
@@ -351,15 +297,13 @@ QGroupBox::title {
padding-top: 10px;
}
-QAbstractScrollArea
-{
+QAbstractScrollArea {
border-radius: 2px;
border: 1px solid #76797C;
background-color: transparent;
}
-QScrollBar:horizontal
-{
+QScrollBar:horizontal {
height: 15px;
margin: 3px 15px 3px 15px;
border: 1px transparent #2A2929;
@@ -367,15 +311,13 @@ QScrollBar:horizontal
background-color: #2A2929;
}
-QScrollBar::handle:horizontal
-{
+QScrollBar::handle:horizontal {
background-color: #605F5F;
min-width: 5px;
border-radius: 4px;
}
-QScrollBar::add-line:horizontal
-{
+QScrollBar::add-line:horizontal {
margin: 0px 3px 0px 3px;
border-image: url(:/qss_icons/rc/right_arrow_disabled.png);
width: 10px;
@@ -384,8 +326,7 @@ QScrollBar::add-line:horizontal
subcontrol-origin: margin;
}
-QScrollBar::sub-line:horizontal
-{
+QScrollBar::sub-line:horizontal {
margin: 0px 3px 0px 3px;
border-image: url(:/qss_icons/rc/left_arrow_disabled.png);
height: 10px;
@@ -394,8 +335,8 @@ QScrollBar::sub-line:horizontal
subcontrol-origin: margin;
}
-QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on
-{
+QScrollBar::add-line:horizontal:hover,
+QScrollBar::add-line:horizontal:on {
border-image: url(:/qss_icons/rc/right_arrow.png);
height: 10px;
width: 10px;
@@ -403,9 +344,8 @@ QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on
subcontrol-origin: margin;
}
-
-QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on
-{
+QScrollBar::sub-line:horizontal:hover,
+QScrollBar::sub-line:horizontal:on {
border-image: url(:/qss_icons/rc/left_arrow.png);
height: 10px;
width: 10px;
@@ -413,19 +353,17 @@ QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on
subcontrol-origin: margin;
}
-QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal
-{
+QScrollBar::up-arrow:horizontal,
+QScrollBar::down-arrow:horizontal {
background: none;
}
-
-QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
-{
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
background: none;
}
-QScrollBar:vertical
-{
+QScrollBar:vertical {
background-color: #2A2929;
width: 15px;
margin: 15px 3px 15px 3px;
@@ -433,15 +371,13 @@ QScrollBar:vertical
border-radius: 4px;
}
-QScrollBar::handle:vertical
-{
+QScrollBar::handle:vertical {
background-color: #605F5F;
min-height: 5px;
border-radius: 4px;
}
-QScrollBar::sub-line:vertical
-{
+QScrollBar::sub-line:vertical {
margin: 3px 0px 3px 0px;
border-image: url(:/qss_icons/rc/up_arrow_disabled.png);
height: 10px;
@@ -450,8 +386,7 @@ QScrollBar::sub-line:vertical
subcontrol-origin: margin;
}
-QScrollBar::add-line:vertical
-{
+QScrollBar::add-line:vertical {
margin: 3px 0px 3px 0px;
border-image: url(:/qss_icons/rc/down_arrow_disabled.png);
height: 10px;
@@ -460,9 +395,8 @@ QScrollBar::add-line:vertical
subcontrol-origin: margin;
}
-QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on
-{
-
+QScrollBar::sub-line:vertical:hover,
+QScrollBar::sub-line:vertical:on {
border-image: url(:/qss_icons/rc/up_arrow.png);
height: 10px;
width: 10px;
@@ -470,9 +404,8 @@ QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on
subcontrol-origin: margin;
}
-
-QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on
-{
+QScrollBar::add-line:vertical:hover,
+QScrollBar::add-line:vertical:on {
border-image: url(:/qss_icons/rc/down_arrow.png);
height: 10px;
width: 10px;
@@ -480,34 +413,31 @@ QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on
subcontrol-origin: margin;
}
-QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
-{
+QScrollBar::up-arrow:vertical,
+QScrollBar::down-arrow:vertical {
background: none;
}
-
-QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
-{
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
background: none;
}
-QTextEdit
-{
+QTextEdit {
background-color: #232629;
color: #eff0f1;
border: 1px solid #76797C;
}
-QPlainTextEdit
-{
- background-color: #232629;;
+QPlainTextEdit {
+ background-color: #232629;
+ ;
color: #eff0f1;
border-radius: 2px;
border: 1px solid #76797C;
}
-QHeaderView::section
-{
+QHeaderView::section {
background-color: #76797C;
color: #eff0f1;
padding: 5px;
@@ -520,9 +450,7 @@ QSizeGrip {
height: 12px;
}
-
-QMainWindow::separator
-{
+QMainWindow::separator {
background-color: #31363b;
color: white;
padding-left: 4px;
@@ -530,9 +458,7 @@ QMainWindow::separator
border: 1px dashed #76797C;
}
-QMainWindow::separator:hover
-{
-
+QMainWindow::separator:hover {
background-color: #787876;
color: white;
padding-left: 4px;
@@ -540,9 +466,7 @@ QMainWindow::separator:hover
spacing: 2px;
}
-
-QMenu::separator
-{
+QMenu::separator {
height: 1px;
background-color: #76797C;
color: white;
@@ -551,21 +475,17 @@ QMenu::separator
margin-right: 5px;
}
-
-QFrame
-{
+QFrame {
border-radius: 2px;
border: 1px solid #76797C;
}
-QFrame[frameShape="0"]
-{
+QFrame[frameShape="0"] {
border-radius: 2px;
border: 1px transparent #76797C;
}
-QStackedWidget
-{
+QStackedWidget {
border: 1px transparent black;
}
@@ -578,21 +498,24 @@ QToolBar {
QToolBar::handle:horizontal {
image: url(:/qss_icons/rc/Hmovetoolbar.png);
}
+
QToolBar::handle:vertical {
image: url(:/qss_icons/rc/Vmovetoolbar.png);
}
+
QToolBar::separator:horizontal {
image: url(:/qss_icons/rc/Hsepartoolbar.png);
}
+
QToolBar::separator:vertical {
image: url(:/qss_icons/rc/Vsepartoolbar.png);
}
+
QToolButton#qt_toolbar_ext_button {
background: #58595a
}
-QPushButton
-{
+QPushButton {
color: #eff0f1;
background-color: #31363b;
border-width: 1px;
@@ -603,8 +526,7 @@ QPushButton
outline: none;
}
-QPushButton:disabled
-{
+QPushButton:disabled {
background-color: #31363b;
border-width: 1px;
border-color: #454545;
@@ -622,15 +544,13 @@ QPushButton:focus {
color: white;
}
-QPushButton:pressed
-{
+QPushButton:pressed {
background-color: #3daee9;
padding-top: -15px;
padding-bottom: -17px;
}
-QComboBox
-{
+QComboBox {
selection-background-color: #3daee9;
border-style: solid;
border: 1px solid #76797C;
@@ -639,38 +559,40 @@ QComboBox
min-width: 75px;
}
-QPushButton:checked{
+QPushButton:checked {
background-color: #76797C;
border-color: #6A6969;
}
-QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover
-{
+QComboBox:hover,
+QPushButton:hover,
+QAbstractSpinBox:hover,
+QLineEdit:hover,
+QTextEdit:hover,
+QPlainTextEdit:hover,
+QAbstractView:hover,
+QTreeView:hover {
border: 1px solid #3daee9;
color: #eff0f1;
}
-QComboBox:on
-{
+QComboBox:on {
padding-top: 3px;
padding-left: 4px;
selection-background-color: #4a4a4a;
}
-QComboBox QAbstractItemView
-{
+QComboBox QAbstractItemView {
background-color: #232629;
border-radius: 2px;
border: 1px solid #76797C;
selection-background-color: #18465d;
}
-QComboBox::drop-down
-{
+QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 15px;
-
border-left-width: 0px;
border-left-color: darkgray;
border-left-style: solid;
@@ -678,14 +600,13 @@ QComboBox::drop-down
border-bottom-right-radius: 3px;
}
-QComboBox::down-arrow
-{
+QComboBox::down-arrow {
image: url(:/qss_icons/rc/down_arrow_disabled.png);
}
-QComboBox::down-arrow:on, QComboBox::down-arrow:hover,
-QComboBox::down-arrow:focus
-{
+QComboBox::down-arrow:on,
+QComboBox::down-arrow:hover,
+QComboBox::down-arrow:focus {
image: url(:/qss_icons/rc/down_arrow.png);
}
@@ -698,49 +619,47 @@ QAbstractSpinBox {
min-width: 75px;
}
-QAbstractSpinBox:up-button
-{
+QAbstractSpinBox:up-button {
background-color: transparent;
subcontrol-origin: border;
subcontrol-position: center right;
}
-QAbstractSpinBox:down-button
-{
+QAbstractSpinBox:down-button {
background-color: transparent;
subcontrol-origin: border;
subcontrol-position: center left;
}
-QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off {
+QAbstractSpinBox::up-arrow,
+QAbstractSpinBox::up-arrow:disabled,
+QAbstractSpinBox::up-arrow:off {
image: url(:/qss_icons/rc/up_arrow_disabled.png);
width: 10px;
height: 10px;
}
-QAbstractSpinBox::up-arrow:hover
-{
+
+QAbstractSpinBox::up-arrow:hover {
image: url(:/qss_icons/rc/up_arrow.png);
}
-
-QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off
-{
+QAbstractSpinBox::down-arrow,
+QAbstractSpinBox::down-arrow:disabled,
+QAbstractSpinBox::down-arrow:off {
image: url(:/qss_icons/rc/down_arrow_disabled.png);
width: 10px;
height: 10px;
}
-QAbstractSpinBox::down-arrow:hover
-{
+
+QAbstractSpinBox::down-arrow:hover {
image: url(:/qss_icons/rc/down_arrow.png);
}
-
-QLabel
-{
+QLabel {
border: 0px solid black;
}
-QTabWidget{
+QTabWidget {
border: 0px transparent black;
}
@@ -751,27 +670,24 @@ QTabWidget::pane {
}
QTabWidget::tab-bar {
- left: 5px; /* move to the right by 5px */
+ /* left: 5px; move to the right by 5px */
}
-QTabBar
-{
+QTabBar {
qproperty-drawBase: 0;
border-radius: 3px;
}
-QTabBar:focus
-{
+QTabBar:focus {
border: 0px transparent black;
}
-QTabBar::close-button {
+QTabBar::close-button {
image: url(:/qss_icons/rc/close.png);
background: transparent;
}
-QTabBar::close-button:hover
-{
+QTabBar::close-button:hover {
image: url(:/qss_icons/rc/close-hover.png);
background: transparent;
}
@@ -781,7 +697,9 @@ QTabBar::close-button:pressed {
background: transparent;
}
+
/* TOP TABS */
+
QTabBar::tab:top {
color: #eff0f1;
border: 1px solid #76797C;
@@ -793,12 +711,11 @@ QTabBar::tab:top {
border-top-right-radius: 2px;
}
-QTabBar::tab:top:!selected
-{
+QTabBar::tab:top:selected {
color: #eff0f1;
background-color: #54575B;
border: 1px solid #76797C;
- border-bottom: 1px transparent black;
+ border-bottom: 2px solid #3daee9;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
@@ -807,7 +724,9 @@ QTabBar::tab:top:!selected:hover {
background-color: #3daee9;
}
+
/* BOTTOM TABS */
+
QTabBar::tab:bottom {
color: #eff0f1;
border: 1px solid #76797C;
@@ -819,12 +738,11 @@ QTabBar::tab:bottom {
min-width: 50px;
}
-QTabBar::tab:bottom:!selected
-{
+QTabBar::tab:bottom:selected {
color: #eff0f1;
background-color: #54575B;
border: 1px solid #76797C;
- border-top: 1px transparent black;
+ border-top: 2px solid #3daee9;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
@@ -833,7 +751,9 @@ QTabBar::tab:bottom:!selected:hover {
background-color: #3daee9;
}
+
/* LEFT TABS */
+
QTabBar::tab:left {
color: #eff0f1;
border: 1px solid #76797C;
@@ -845,12 +765,11 @@ QTabBar::tab:left {
min-height: 50px;
}
-QTabBar::tab:left:!selected
-{
+QTabBar::tab:left:selected {
color: #eff0f1;
background-color: #54575B;
border: 1px solid #76797C;
- border-left: 1px transparent black;
+ border-left: 2px solid #3daee9;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
@@ -861,6 +780,7 @@ QTabBar::tab:left:!selected:hover {
/* RIGHT TABS */
+
QTabBar::tab:right {
color: #eff0f1;
border: 1px solid #76797C;
@@ -872,12 +792,11 @@ QTabBar::tab:right {
min-height: 50px;
}
-QTabBar::tab:right:!selected
-{
+QTabBar::tab:right:selected {
color: #eff0f1;
background-color: #54575B;
border: 1px solid #76797C;
- border-right: 1px transparent black;
+ border-right: 2px solid #3daee9;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
@@ -887,21 +806,20 @@ QTabBar::tab:right:!selected:hover {
}
QTabBar QToolButton::right-arrow:enabled {
- image: url(:/qss_icons/rc/right_arrow.png);
- }
+ image: url(:/qss_icons/rc/right_arrow.png);
+}
- QTabBar QToolButton::left-arrow:enabled {
- image: url(:/qss_icons/rc/left_arrow.png);
- }
+QTabBar QToolButton::left-arrow:enabled {
+ image: url(:/qss_icons/rc/left_arrow.png);
+}
QTabBar QToolButton::right-arrow:disabled {
- image: url(:/qss_icons/rc/right_arrow_disabled.png);
- }
-
- QTabBar QToolButton::left-arrow:disabled {
- image: url(:/qss_icons/rc/left_arrow_disabled.png);
- }
+ image: url(:/qss_icons/rc/right_arrow_disabled.png);
+}
+QTabBar QToolButton::left-arrow:disabled {
+ image: url(:/qss_icons/rc/left_arrow_disabled.png);
+}
QDockWidget {
background: #31363b;
@@ -910,29 +828,32 @@ QDockWidget {
titlebar-normal-icon: url(:/qss_icons/rc/undock.png);
}
-QDockWidget::close-button, QDockWidget::float-button {
+QDockWidget::close-button,
+QDockWidget::float-button {
border: 1px solid transparent;
border-radius: 2px;
background: transparent;
}
-QDockWidget::close-button:hover, QDockWidget::float-button:hover {
+QDockWidget::close-button:hover,
+QDockWidget::float-button:hover {
background: rgba(255, 255, 255, 10);
}
-QDockWidget::close-button:pressed, QDockWidget::float-button:pressed {
+QDockWidget::close-button:pressed,
+QDockWidget::float-button:pressed {
padding: 1px -1px -1px 1px;
background: rgba(255, 255, 255, 10);
}
-QTreeView, QListView
-{
+QTreeView,
+QListView {
border: 1px solid #76797C;
background-color: #232629;
}
-QTreeView:branch:selected, QTreeView:branch:hover
-{
+QTreeView:branch:selected,
+QTreeView:branch:hover {
background: url(:/qss_icons/rc/transparent.png);
}
@@ -954,31 +875,75 @@ QTreeView::branch:closed:has-children:has-siblings {
}
QTreeView::branch:open:has-children:!has-siblings,
-QTreeView::branch:open:has-children:has-siblings {
+QTreeView::branch:open:has-children:has-siblings {
image: url(:/qss_icons/rc/branch_open.png);
}
QTreeView::branch:has-children:!has-siblings:closed:hover,
QTreeView::branch:closed:has-children:has-siblings:hover {
image: url(:/qss_icons/rc/branch_closed-on.png);
- }
+}
QTreeView::branch:open:has-children:!has-siblings:hover,
-QTreeView::branch:open:has-children:has-siblings:hover {
+QTreeView::branch:open:has-children:has-siblings:hover {
image: url(:/qss_icons/rc/branch_open-on.png);
- }
+}
-QListView::item:!selected:hover, QTreeView::item:!selected:hover {
+QListView::item:!selected:hover,
+QTreeView::item:!selected:hover {
background: #18465d;
outline: 0;
color: #eff0f1
}
-QListView::item:selected:hover, QTreeView::item:selected:hover {
+QListView::item:selected:hover,
+QTreeView::item:selected:hover {
background: #287399;
color: #eff0f1;
}
+QTreeView::indicator:checked,
+QListView::indicator:checked {
+ image: url(:/qss_icons/rc/checkbox_checked.png);
+}
+
+QTreeView::indicator:unchecked,
+QListView::indicator:unchecked {
+ image: url(:/qss_icons/rc/checkbox_unchecked.png);
+}
+
+QTreeView::indicator:indeterminate,
+QListView::indicator:indeterminate {
+ image: url(:/qss_icons/rc/checkbox_indeterminate.png);
+}
+
+QTreeView::indicator:checked:hover,
+QTreeView::indicator:checked:focus,
+QTreeView::indicator:checked:pressed,
+QListView::indicator:checked:hover,
+QListView::indicator:checked:focus,
+QListView::indicator:checked:pressed {
+ image: url(:/qss_icons/rc/checkbox_checked_focus.png);
+}
+
+QTreeView::indicator:unchecked:hover,
+QTreeView::indicator:unchecked:focus,
+QTreeView::indicator:unchecked:pressed,
+QListView::indicator:unchecked:hover,
+QListView::indicator:unchecked:focus,
+QListView::indicator:unchecked:pressed {
+ image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
+}
+
+QTreeView::indicator:indeterminate:hover,
+QTreeView::indicator:indeterminate:focus,
+QTreeView::indicator:indeterminate:pressed,
+QListView::indicator:indeterminate:hover,
+QListView::indicator:indeterminate:focus,
+QListView::indicator:indeterminate:pressed {
+ image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
+}
+
QSlider::groove:horizontal {
border: 1px solid #565a5e;
height: 4px;
@@ -1021,38 +986,49 @@ QToolButton {
padding: 5px;
}
-QToolButton[popupMode="1"] { /* only for MenuButtonPopup */
- padding-right: 20px; /* make way for the popup button */
- border: 1px #76797C;
- border-radius: 5px;
+QToolButton[popupMode="1"] {
+ /* only for MenuButtonPopup */
+ padding-right: 20px;
+ /* make way for the popup button */
+ border: 1px #76797C;
+ border-radius: 5px;
}
-QToolButton[popupMode="2"] { /* only for InstantPopup */
- padding-right: 10px; /* make way for the popup button */
- border: 1px #76797C;
+QToolButton[popupMode="2"] {
+ /* only for InstantPopup */
+ padding-right: 10px;
+ /* make way for the popup button */
+ border: 1px #76797C;
}
-
-QToolButton:hover, QToolButton::menu-button:hover {
+QToolButton:hover,
+QToolButton::menu-button:hover {
background-color: transparent;
border: 1px solid #3daee9;
padding: 5px;
}
-QToolButton:checked, QToolButton:pressed,
- QToolButton::menu-button:pressed {
+QToolButton:checked,
+QToolButton:pressed,
+QToolButton::menu-button:pressed {
background-color: #3daee9;
border: 1px solid #3daee9;
padding: 5px;
}
+
/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */
+
QToolButton::menu-indicator {
image: url(:/qss_icons/rc/down_arrow.png);
- top: -7px; left: -2px; /* shift it a bit */
+ top: -7px;
+ left: -2px;
+ /* shift it a bit */
}
+
/* the subcontrols below are used only in the MenuButtonPopup mode */
+
QToolButton::menu-button {
border: 1px transparent #76797C;
border-top-right-radius: 6px;
@@ -1070,47 +1046,46 @@ QToolButton::menu-arrow:open {
border: 1px solid #76797C;
}
-QPushButton::menu-indicator {
+QPushButton::menu-indicator {
subcontrol-origin: padding;
subcontrol-position: bottom right;
left: 8px;
}
-QTableView
-{
+QTableView {
border: 1px solid #76797C;
gridline-color: #31363b;
background-color: #232629;
}
-
-QTableView, QHeaderView
-{
+QTableView,
+QHeaderView {
border-radius: 0px;
}
-QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed {
+QTableView::item:pressed,
+QListView::item:pressed,
+QTreeView::item:pressed {
background: #18465d;
color: #eff0f1;
}
-QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active {
+QTableView::item:selected:active,
+QTreeView::item:selected:active,
+QListView::item:selected:active {
background: #287399;
color: #eff0f1;
}
-
-QHeaderView
-{
+QHeaderView {
background-color: #31363b;
border: 1px transparent;
border-radius: 0px;
margin: 0px;
padding: 0px;
-
}
-QHeaderView::section {
+QHeaderView::section {
background-color: #31363b;
color: #eff0f1;
padding: 5px;
@@ -1119,34 +1094,32 @@ QHeaderView::section {
text-align: center;
}
-QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one
-{
+QHeaderView::section::vertical::first,
+QHeaderView::section::vertical::only-one {
border-top: 1px solid #76797C;
}
-QHeaderView::section::vertical
-{
+QHeaderView::section::vertical {
border-top: transparent;
}
-QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one
-{
+QHeaderView::section::horizontal::first,
+QHeaderView::section::horizontal::only-one {
border-left: 1px solid #76797C;
}
-QHeaderView::section::horizontal
-{
+QHeaderView::section::horizontal {
border-left: transparent;
}
-
-QHeaderView::section:checked
- {
+QHeaderView::section:checked {
color: white;
background-color: #334e5e;
- }
+}
+
+
+/* style the sort indicator */
- /* style the sort indicator */
QHeaderView::down-arrow {
image: url(:/qss_icons/rc/down_arrow.png);
}
@@ -1155,14 +1128,13 @@ QHeaderView::up-arrow {
image: url(:/qss_icons/rc/up_arrow.png);
}
-
QTableCornerButton::section {
background-color: #31363b;
border: 1px transparent #76797C;
border-radius: 0px;
}
-QToolBox {
+QToolBox {
padding: 5px;
border: 1px transparent black;
}
@@ -1176,22 +1148,22 @@ QToolBox::tab {
border-top-right-radius: 5px;
}
-QToolBox::tab:selected { /* italicize selected tabs */
+QToolBox::tab:selected {
+ /* italicize selected tabs */
font: italic;
background-color: #31363b;
border-color: #3daee9;
- }
+}
QStatusBar::item {
border: 0px transparent dark;
- }
-
+}
-QFrame[height="3"], QFrame[width="3"] {
+QFrame[height="3"],
+QFrame[width="3"] {
background-color: #76797C;
}
-
QSplitter::handle {
border: 1px dashed #76797C;
}
@@ -1219,8 +1191,7 @@ QProgressBar::chunk {
background-color: #05B8CC;
}
-QDateEdit
-{
+QDateEdit {
selection-background-color: #3daee9;
border-style: solid;
border: 1px solid #3375A3;
@@ -1229,23 +1200,20 @@ QDateEdit
min-width: 75px;
}
-QDateEdit:on
-{
+QDateEdit:on {
padding-top: 3px;
padding-left: 4px;
selection-background-color: #4a4a4a;
}
-QDateEdit QAbstractItemView
-{
+QDateEdit QAbstractItemView {
background-color: #232629;
border-radius: 2px;
border: 1px solid #3375A3;
selection-background-color: #3daee9;
}
-QDateEdit::drop-down
-{
+QDateEdit::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 15px;
@@ -1256,13 +1224,12 @@ QDateEdit::drop-down
border-bottom-right-radius: 3px;
}
-QDateEdit::down-arrow
-{
+QDateEdit::down-arrow {
image: url(:/qss_icons/rc/down_arrow_disabled.png);
}
-QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover,
-QDateEdit::down-arrow:focus
-{
+QDateEdit::down-arrow:on,
+QDateEdit::down-arrow:hover,
+QDateEdit::down-arrow:focus {
image: url(:/qss_icons/rc/down_arrow.png);
}
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index d2b0652a5..db21f3d50 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -35,6 +35,10 @@ set(LZ4_BUNDLED_MODE ON)
add_subdirectory(lz4/contrib/cmake_unofficial)
target_include_directories(lz4_static INTERFACE ./lz4/lib)
+# mbedtls
+add_subdirectory(mbedtls EXCLUDE_FROM_ALL)
+target_include_directories(mbedtls PUBLIC ./mbedtls/include)
+
# MicroProfile
add_library(microprofile INTERFACE)
target_include_directories(microprofile INTERFACE ./microprofile)
@@ -50,3 +54,13 @@ if (ARCHITECTURE_x86_64)
target_include_directories(xbyak INTERFACE ./xbyak/xbyak)
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
endif()
+
+# Opus
+add_subdirectory(opus)
+target_include_directories(opus INTERFACE ./opus/include)
+
+# Cubeb
+if(ENABLE_CUBEB)
+ set(BUILD_TESTS OFF CACHE BOOL "")
+ add_subdirectory(cubeb EXCLUDE_FROM_ALL)
+endif()
diff --git a/externals/cubeb b/externals/cubeb
new file mode 160000
+Subproject 12b78c0edfa40007e41dbdcd9dfe367fbb98d01
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject 98e23801297167db1fd266696484a49096e734c
+Subproject 4f96c63025af34c1490c59f6729497b9866ffa3
diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h
index 5f4b962d9..fd41dc702 100644
--- a/externals/glad/include/glad/glad.h
+++ b/externals/glad/include/glad/glad.h
@@ -1,6 +1,6 @@
/*
- OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018.
+ OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018.
Language/Generator: C/C++
Specification: gl
@@ -15,6 +15,7 @@
GL_AMD_debug_output,
GL_AMD_depth_clamp_separate,
GL_AMD_draw_buffers_blend,
+ GL_AMD_framebuffer_multisample_advanced,
GL_AMD_framebuffer_sample_positions,
GL_AMD_gcn_shader,
GL_AMD_gpu_shader_half_float,
@@ -600,7 +601,7 @@
Omit khrplatform: False
Commandline:
- --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog"
+ --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog"
Online:
Too many extensions
*/
@@ -1409,7 +1410,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void);
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_MAX_SAMPLES 0x8D57
-#define GL_INDEX 0x8222
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#define GL_HALF_FLOAT 0x140B
#define GL_MAP_READ_BIT 0x0001
@@ -2780,6 +2780,12 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
+#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
+#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
+#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
+#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
+#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE
#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF
@@ -3157,6 +3163,7 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_INDEX 0x8222
#define GL_LINES_ADJACENCY_ARB 0x000A
#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
@@ -6433,6 +6440,16 @@ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)(GLuint buf, GL
GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD;
#define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD
#endif
+#ifndef GL_AMD_framebuffer_multisample_advanced
+#define GL_AMD_framebuffer_multisample_advanced 1
+GLAPI int GLAD_GL_AMD_framebuffer_multisample_advanced;
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD;
+#define glRenderbufferStorageMultisampleAdvancedAMD glad_glRenderbufferStorageMultisampleAdvancedAMD
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD;
+#define glNamedRenderbufferStorageMultisampleAdvancedAMD glad_glNamedRenderbufferStorageMultisampleAdvancedAMD
+#endif
#ifndef GL_AMD_framebuffer_sample_positions
#define GL_AMD_framebuffer_sample_positions 1
GLAPI int GLAD_GL_AMD_framebuffer_sample_positions;
diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c
index 13607e449..1cf0890b9 100644
--- a/externals/glad/src/glad.c
+++ b/externals/glad/src/glad.c
@@ -1,6 +1,6 @@
/*
- OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018.
+ OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018.
Language/Generator: C/C++
Specification: gl
@@ -15,6 +15,7 @@
GL_AMD_debug_output,
GL_AMD_depth_clamp_separate,
GL_AMD_draw_buffers_blend,
+ GL_AMD_framebuffer_multisample_advanced,
GL_AMD_framebuffer_sample_positions,
GL_AMD_gcn_shader,
GL_AMD_gpu_shader_half_float,
@@ -600,7 +601,7 @@
Omit khrplatform: False
Commandline:
- --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog"
+ --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog"
Online:
Too many extensions
*/
@@ -739,7 +740,7 @@ int gladLoadGL(void) {
return status;
}
-struct gladGLversionStruct GLVersion;
+struct gladGLversionStruct GLVersion = { 0, 0 };
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
#define _GLAD_IS_SOME_NEW_VERSION 1
@@ -838,3190 +839,3193 @@ static int has_ext(const char *ext) {
return 0;
}
-int GLAD_GL_VERSION_1_0;
-int GLAD_GL_VERSION_1_1;
-int GLAD_GL_VERSION_1_2;
-int GLAD_GL_VERSION_1_3;
-int GLAD_GL_VERSION_1_4;
-int GLAD_GL_VERSION_1_5;
-int GLAD_GL_VERSION_2_0;
-int GLAD_GL_VERSION_2_1;
-int GLAD_GL_VERSION_3_0;
-int GLAD_GL_VERSION_3_1;
-int GLAD_GL_VERSION_3_2;
-int GLAD_GL_VERSION_3_3;
-PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D;
-PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui;
-PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate;
-PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
-PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D;
-PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv;
-PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv;
-PFNGLBINDSAMPLERPROC glad_glBindSampler;
-PFNGLLINEWIDTHPROC glad_glLineWidth;
-PFNGLCOLORP3UIVPROC glad_glColorP3uiv;
-PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v;
-PFNGLCOMPILESHADERPROC glad_glCompileShader;
-PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying;
-PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
-PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui;
-PFNGLVERTEXP4UIPROC glad_glVertexP4ui;
-PFNGLENABLEIPROC glad_glEnablei;
-PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui;
-PFNGLCREATESHADERPROC glad_glCreateShader;
-PFNGLISBUFFERPROC glad_glIsBuffer;
-PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv;
-PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
-PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
-PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
-PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f;
-PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
-PFNGLHINTPROC glad_glHint;
-PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s;
-PFNGLSAMPLEMASKIPROC glad_glSampleMaski;
-PFNGLVERTEXP2UIPROC glad_glVertexP2ui;
-PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv;
-PFNGLPOINTSIZEPROC glad_glPointSize;
-PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv;
-PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
-PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv;
-PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
-PFNGLWAITSYNCPROC glad_glWaitSync;
-PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv;
-PFNGLUNIFORM3IPROC glad_glUniform3i;
-PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv;
-PFNGLUNIFORM3FPROC glad_glUniform3f;
-PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv;
-PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv;
-PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui;
-PFNGLCOLORMASKIPROC glad_glColorMaski;
-PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi;
-PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
-PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui;
-PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv;
-PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex;
-PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv;
-PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv;
-PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui;
-PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
-PFNGLDRAWARRAYSPROC glad_glDrawArrays;
-PFNGLUNIFORM1UIPROC glad_glUniform1ui;
-PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i;
-PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui;
-PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d;
-PFNGLCLEARPROC glad_glClear;
-PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName;
-PFNGLISENABLEDPROC glad_glIsEnabled;
-PFNGLSTENCILOPPROC glad_glStencilOp;
-PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
-PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv;
-PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub;
-PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation;
-PFNGLTEXIMAGE1DPROC glad_glTexImage1D;
-PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
-PFNGLGETTEXIMAGEPROC glad_glGetTexImage;
-PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v;
-PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
-PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders;
-PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer;
-PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
-PFNGLISVERTEXARRAYPROC glad_glIsVertexArray;
-PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
-PFNGLGETQUERYIVPROC glad_glGetQueryiv;
-PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv;
-PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices;
-PFNGLISSHADERPROC glad_glIsShader;
-PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv;
-PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv;
-PFNGLENABLEPROC glad_glEnable;
-PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv;
-PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation;
-PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv;
-PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv;
-PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui;
-PFNGLGETUNIFORMFVPROC glad_glGetUniformfv;
-PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv;
-PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv;
-PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
-PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv;
-PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced;
-PFNGLFLUSHPROC glad_glFlush;
-PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv;
-PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv;
-PFNGLFENCESYNCPROC glad_glFenceSync;
-PFNGLCOLORP3UIPROC glad_glColorP3ui;
-PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv;
-PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender;
-PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv;
-PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv;
-PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate;
-PFNGLGENSAMPLERSPROC glad_glGenSamplers;
-PFNGLCLAMPCOLORPROC glad_glClampColor;
-PFNGLUNIFORM4IVPROC glad_glUniform4iv;
-PFNGLCLEARSTENCILPROC glad_glClearStencil;
-PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv;
-PFNGLGENTEXTURESPROC glad_glGenTextures;
-PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv;
-PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv;
-PFNGLISSYNCPROC glad_glIsSync;
-PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName;
-PFNGLUNIFORM2IPROC glad_glUniform2i;
-PFNGLUNIFORM2FPROC glad_glUniform2f;
-PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui;
-PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
-PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
-PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer;
-PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange;
-PFNGLGENQUERIESPROC glad_glGenQueries;
-PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui;
-PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D;
-PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v;
-PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers;
-PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D;
-PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
-PFNGLISENABLEDIPROC glad_glIsEnabledi;
-PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui;
-PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed;
-PFNGLUNIFORM2IVPROC glad_glUniform2iv;
-PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv;
-PFNGLUNIFORM4UIVPROC glad_glUniform4uiv;
-PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D;
-PFNGLGETSHADERIVPROC glad_glGetShaderiv;
-PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation;
-PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset;
-PFNGLGETDOUBLEVPROC glad_glGetDoublev;
-PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d;
-PFNGLGETUNIFORMIVPROC glad_glGetUniformiv;
-PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv;
-PFNGLUNIFORM3FVPROC glad_glUniform3fv;
-PFNGLDEPTHRANGEPROC glad_glDepthRange;
-PFNGLMAPBUFFERPROC glad_glMapBuffer;
-PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D;
-PFNGLDELETESYNCPROC glad_glDeleteSync;
-PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D;
-PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv;
-PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements;
-PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv;
-PFNGLUNIFORM3IVPROC glad_glUniform3iv;
-PFNGLPOLYGONMODEPROC glad_glPolygonMode;
-PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
-PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv;
-PFNGLUSEPROGRAMPROC glad_glUseProgram;
-PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
-PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
-PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
-PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv;
-PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex;
-PFNGLUNIFORM2UIVPROC glad_glUniform2uiv;
-PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D;
-PFNGLFINISHPROC glad_glFinish;
-PFNGLDELETESHADERPROC glad_glDeleteShader;
-PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv;
-PFNGLVIEWPORTPROC glad_glViewport;
-PFNGLUNIFORM1UIVPROC glad_glUniform1uiv;
-PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings;
-PFNGLUNIFORM2UIPROC glad_glUniform2ui;
-PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i;
-PFNGLCLEARDEPTHPROC glad_glClearDepth;
-PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv;
-PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
-PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
-PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource;
-PFNGLTEXBUFFERPROC glad_glTexBuffer;
-PFNGLPIXELSTOREIPROC glad_glPixelStorei;
-PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
-PFNGLPIXELSTOREFPROC glad_glPixelStoref;
-PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v;
-PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv;
-PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv;
-PFNGLLINKPROGRAMPROC glad_glLinkProgram;
-PFNGLBINDTEXTUREPROC glad_glBindTexture;
-PFNGLGETSTRINGPROC glad_glGetString;
-PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv;
-PFNGLDETACHSHADERPROC glad_glDetachShader;
-PFNGLENDQUERYPROC glad_glEndQuery;
-PFNGLNORMALP3UIPROC glad_glNormalP3ui;
-PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui;
-PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
-PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate;
-PFNGLDELETEQUERIESPROC glad_glDeleteQueries;
-PFNGLNORMALP3UIVPROC glad_glNormalP3uiv;
-PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
-PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d;
-PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv;
-PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s;
-PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex;
-PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage;
-PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri;
-PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf;
-PFNGLUNIFORM1FPROC glad_glUniform1f;
-PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv;
-PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage;
-PFNGLUNIFORM1IPROC glad_glUniform1i;
-PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
-PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
-PFNGLDISABLEPROC glad_glDisable;
-PFNGLLOGICOPPROC glad_glLogicOp;
-PFNGLUNIFORM4UIPROC glad_glUniform4ui;
-PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
-PFNGLCULLFACEPROC glad_glCullFace;
-PFNGLGETSTRINGIPROC glad_glGetStringi;
-PFNGLATTACHSHADERPROC glad_glAttachShader;
-PFNGLQUERYCOUNTERPROC glad_glQueryCounter;
-PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex;
-PFNGLDRAWELEMENTSPROC glad_glDrawElements;
-PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv;
-PFNGLUNIFORM1IVPROC glad_glUniform1iv;
-PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv;
-PFNGLREADBUFFERPROC glad_glReadBuffer;
-PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv;
-PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced;
-PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
-PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv;
-PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f;
-PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv;
-PFNGLPOINTPARAMETERIPROC glad_glPointParameteri;
-PFNGLBLENDCOLORPROC glad_glBlendColor;
-PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv;
-PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
-PFNGLPOINTPARAMETERFPROC glad_glPointParameterf;
-PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s;
-PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
-PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv;
-PFNGLISPROGRAMPROC glad_glIsProgram;
-PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv;
-PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv;
-PFNGLUNIFORM4IPROC glad_glUniform4i;
-PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
-PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
-PFNGLREADPIXELSPROC glad_glReadPixels;
-PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv;
-PFNGLUNIFORM4FPROC glad_glUniform4f;
-PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
-PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
-PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex;
-PFNGLSTENCILFUNCPROC glad_glStencilFunc;
-PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding;
-PFNGLCOLORP4UIPROC glad_glColorP4ui;
-PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv;
-PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
-PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i;
-PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData;
-PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate;
-PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui;
-PFNGLGENBUFFERSPROC glad_glGenBuffers;
-PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv;
-PFNGLBLENDFUNCPROC glad_glBlendFunc;
-PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
-PFNGLTEXIMAGE3DPROC glad_glTexImage3D;
-PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer;
-PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex;
-PFNGLGETINTEGER64VPROC glad_glGetInteger64v;
-PFNGLSCISSORPROC glad_glScissor;
-PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv;
-PFNGLGETBOOLEANVPROC glad_glGetBooleanv;
-PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv;
-PFNGLUNIFORM3UIVPROC glad_glUniform3uiv;
-PFNGLCLEARCOLORPROC glad_glClearColor;
-PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv;
-PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv;
-PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v;
-PFNGLCOLORP4UIVPROC glad_glColorP4uiv;
-PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv;
-PFNGLUNIFORM3UIPROC glad_glUniform3ui;
-PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv;
-PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv;
-PFNGLUNIFORM2FVPROC glad_glUniform2fv;
-PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv;
-PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange;
-PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv;
-PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv;
-PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv;
-PFNGLDEPTHFUNCPROC glad_glDepthFunc;
-PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
-PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv;
-PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv;
-PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui;
-PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync;
-PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui;
-PFNGLCOLORMASKPROC glad_glColorMask;
-PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv;
-PFNGLBLENDEQUATIONPROC glad_glBlendEquation;
-PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
-PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback;
-PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv;
-PFNGLUNIFORM4FVPROC glad_glUniform4fv;
-PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback;
-PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv;
-PFNGLISSAMPLERPROC glad_glIsSampler;
-PFNGLVERTEXP3UIPROC glad_glVertexP3ui;
-PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor;
-PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D;
-PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D;
-PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
-PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
-PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender;
-PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv;
-PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
-PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv;
-PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv;
-PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
-PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv;
-PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase;
-PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
-PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv;
-PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange;
-PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture;
-PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays;
-PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv;
-PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv;
-PFNGLDISABLEIPROC glad_glDisablei;
-PFNGLSHADERSOURCEPROC glad_glShaderSource;
-PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
-PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv;
-PFNGLGETSYNCIVPROC glad_glGetSynciv;
-PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv;
-PFNGLBEGINQUERYPROC glad_glBeginQuery;
-PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
-PFNGLBINDBUFFERPROC glad_glBindBuffer;
-PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
-PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv;
-PFNGLBUFFERDATAPROC glad_glBufferData;
-PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv;
-PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui;
-PFNGLGETERRORPROC glad_glGetError;
-PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui;
-PFNGLGETFLOATVPROC glad_glGetFloatv;
-PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D;
-PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv;
-PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv;
-PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i;
-PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv;
-PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
-PFNGLGETINTEGERVPROC glad_glGetIntegerv;
-PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv;
-PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D;
-PFNGLISQUERYPROC glad_glIsQuery;
-PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv;
-PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
-PFNGLSTENCILMASKPROC glad_glStencilMask;
-PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv;
-PFNGLISTEXTUREPROC glad_glIsTexture;
-PFNGLUNIFORM1FVPROC glad_glUniform1fv;
-PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv;
-PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
-PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv;
-PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData;
-PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv;
-PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d;
-PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f;
-PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv;
-PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v;
-PFNGLDEPTHMASKPROC glad_glDepthMask;
-PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s;
-PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample;
-PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
-PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
-PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
-PFNGLFRONTFACEPROC glad_glFrontFace;
-int GLAD_GL_SGIX_pixel_tiles;
-int GLAD_GL_EXT_post_depth_coverage;
-int GLAD_GL_APPLE_element_array;
-int GLAD_GL_AMD_multi_draw_indirect;
-int GLAD_GL_EXT_blend_subtract;
-int GLAD_GL_SGIX_tag_sample_buffer;
-int GLAD_GL_NV_point_sprite;
-int GLAD_GL_IBM_texture_mirrored_repeat;
-int GLAD_GL_APPLE_transform_hint;
-int GLAD_GL_ATI_separate_stencil;
-int GLAD_GL_NV_shader_atomic_int64;
-int GLAD_GL_EXT_semaphore_win32;
-int GLAD_GL_NV_vertex_program2_option;
-int GLAD_GL_EXT_texture_buffer_object;
-int GLAD_GL_ARB_vertex_blend;
-int GLAD_GL_OVR_multiview;
-int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch;
-int GLAD_GL_NV_vertex_program2;
-int GLAD_GL_ARB_program_interface_query;
-int GLAD_GL_EXT_misc_attribute;
-int GLAD_GL_NV_multisample_coverage;
-int GLAD_GL_ARB_shading_language_packing;
-int GLAD_GL_EXT_texture_cube_map;
-int GLAD_GL_NV_viewport_array2;
-int GLAD_GL_ARB_texture_stencil8;
-int GLAD_GL_EXT_index_func;
-int GLAD_GL_EXT_memory_object_fd;
-int GLAD_GL_OES_compressed_paletted_texture;
-int GLAD_GL_MESA_shader_integer_functions;
-int GLAD_GL_NV_shader_buffer_load;
-int GLAD_GL_EXT_color_subtable;
-int GLAD_GL_SUNX_constant_data;
-int GLAD_GL_EXT_texture_compression_s3tc;
-int GLAD_GL_EXT_multi_draw_arrays;
-int GLAD_GL_ARB_shader_atomic_counters;
-int GLAD_GL_ARB_arrays_of_arrays;
-int GLAD_GL_NV_conditional_render;
-int GLAD_GL_EXT_texture_env_combine;
-int GLAD_GL_NV_fog_distance;
-int GLAD_GL_SGIX_async_histogram;
-int GLAD_GL_MESA_resize_buffers;
-int GLAD_GL_NV_light_max_exponent;
-int GLAD_GL_NV_texture_env_combine4;
-int GLAD_GL_ARB_spirv_extensions;
-int GLAD_GL_ARB_texture_view;
-int GLAD_GL_ARB_texture_env_combine;
-int GLAD_GL_ARB_map_buffer_range;
-int GLAD_GL_EXT_convolution;
-int GLAD_GL_NV_compute_program5;
-int GLAD_GL_NV_vertex_attrib_integer_64bit;
-int GLAD_GL_EXT_paletted_texture;
-int GLAD_GL_ARB_texture_buffer_object;
-int GLAD_GL_ATI_pn_triangles;
-int GLAD_GL_SGIX_resample;
-int GLAD_GL_SGIX_flush_raster;
-int GLAD_GL_EXT_light_texture;
-int GLAD_GL_ARB_point_sprite;
-int GLAD_GL_SUN_convolution_border_modes;
-int GLAD_GL_EXT_semaphore_fd;
-int GLAD_GL_NV_parameter_buffer_object2;
-int GLAD_GL_ARB_half_float_pixel;
-int GLAD_GL_NV_tessellation_program5;
-int GLAD_GL_REND_screen_coordinates;
-int GLAD_GL_EXT_shared_texture_palette;
-int GLAD_GL_EXT_packed_float;
-int GLAD_GL_OML_subsample;
-int GLAD_GL_SGIX_vertex_preclip;
-int GLAD_GL_SGIX_texture_scale_bias;
-int GLAD_GL_AMD_draw_buffers_blend;
-int GLAD_GL_APPLE_texture_range;
-int GLAD_GL_EXT_texture_array;
-int GLAD_GL_NV_texture_barrier;
-int GLAD_GL_ARB_texture_query_levels;
-int GLAD_GL_NV_texgen_emboss;
-int GLAD_GL_EXT_texture_swizzle;
-int GLAD_GL_ARB_texture_rg;
-int GLAD_GL_ARB_vertex_type_2_10_10_10_rev;
-int GLAD_GL_ARB_fragment_shader;
-int GLAD_GL_3DFX_tbuffer;
-int GLAD_GL_GREMEDY_frame_terminator;
-int GLAD_GL_IBM_cull_vertex;
-int GLAD_GL_EXT_separate_shader_objects;
-int GLAD_GL_NV_texture_multisample;
-int GLAD_GL_ARB_shader_objects;
-int GLAD_GL_ARB_framebuffer_object;
-int GLAD_GL_EXT_external_buffer;
-int GLAD_GL_ATI_envmap_bumpmap;
-int GLAD_GL_AMD_shader_explicit_vertex_parameter;
-int GLAD_GL_ARB_robust_buffer_access_behavior;
-int GLAD_GL_ARB_shader_stencil_export;
-int GLAD_GL_NV_texture_rectangle;
-int GLAD_GL_ARB_enhanced_layouts;
-int GLAD_GL_ARB_texture_rectangle;
-int GLAD_GL_SGI_texture_color_table;
-int GLAD_GL_NV_viewport_swizzle;
-int GLAD_GL_ATI_map_object_buffer;
-int GLAD_GL_ARB_robustness;
-int GLAD_GL_NV_pixel_data_range;
-int GLAD_GL_EXT_framebuffer_blit;
-int GLAD_GL_ARB_gpu_shader_fp64;
-int GLAD_GL_NV_command_list;
-int GLAD_GL_SGIX_depth_texture;
-int GLAD_GL_AMD_framebuffer_sample_positions;
-int GLAD_GL_GREMEDY_string_marker;
-int GLAD_GL_ARB_texture_compression_bptc;
-int GLAD_GL_EXT_subtexture;
-int GLAD_GL_EXT_pixel_transform_color_table;
-int GLAD_GL_EXT_texture_compression_rgtc;
-int GLAD_GL_ARB_shader_atomic_counter_ops;
-int GLAD_GL_SGIX_depth_pass_instrument;
-int GLAD_GL_EXT_gpu_program_parameters;
-int GLAD_GL_NV_evaluators;
-int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent;
-int GLAD_GL_SGIS_texture_filter4;
-int GLAD_GL_AMD_performance_monitor;
-int GLAD_GL_NV_geometry_shader4;
-int GLAD_GL_EXT_stencil_clear_tag;
-int GLAD_GL_NV_vertex_program1_1;
-int GLAD_GL_NV_present_video;
-int GLAD_GL_ARB_texture_compression_rgtc;
-int GLAD_GL_HP_convolution_border_modes;
-int GLAD_GL_EXT_shader_integer_mix;
-int GLAD_GL_SGIX_framezoom;
-int GLAD_GL_ARB_stencil_texturing;
-int GLAD_GL_ARB_shader_clock;
-int GLAD_GL_NV_shader_atomic_fp16_vector;
-int GLAD_GL_SGIX_fog_offset;
-int GLAD_GL_ARB_draw_elements_base_vertex;
-int GLAD_GL_INGR_interlace_read;
-int GLAD_GL_NV_transform_feedback;
-int GLAD_GL_NV_fragment_program;
-int GLAD_GL_AMD_stencil_operation_extended;
-int GLAD_GL_ARB_seamless_cubemap_per_texture;
-int GLAD_GL_ARB_instanced_arrays;
-int GLAD_GL_ARB_get_texture_sub_image;
-int GLAD_GL_NV_vertex_array_range2;
-int GLAD_GL_KHR_robustness;
-int GLAD_GL_AMD_sparse_texture;
-int GLAD_GL_ARB_clip_control;
-int GLAD_GL_NV_fragment_coverage_to_color;
-int GLAD_GL_NV_fence;
-int GLAD_GL_ARB_texture_buffer_range;
-int GLAD_GL_SUN_mesh_array;
-int GLAD_GL_ARB_vertex_attrib_binding;
-int GLAD_GL_ARB_framebuffer_no_attachments;
-int GLAD_GL_ARB_cl_event;
-int GLAD_GL_EXT_vertex_weighting;
-int GLAD_GL_ARB_derivative_control;
-int GLAD_GL_NV_packed_depth_stencil;
-int GLAD_GL_OES_single_precision;
-int GLAD_GL_NV_primitive_restart;
-int GLAD_GL_SUN_global_alpha;
-int GLAD_GL_ARB_fragment_shader_interlock;
-int GLAD_GL_EXT_texture_object;
-int GLAD_GL_AMD_name_gen_delete;
-int GLAD_GL_NV_texture_compression_vtc;
-int GLAD_GL_NV_sample_mask_override_coverage;
-int GLAD_GL_NV_texture_shader3;
-int GLAD_GL_MESA_tile_raster_order;
-int GLAD_GL_ARB_texture_filter_anisotropic;
-int GLAD_GL_EXT_texture;
-int GLAD_GL_ARB_buffer_storage;
-int GLAD_GL_AMD_shader_atomic_counter_ops;
-int GLAD_GL_APPLE_vertex_program_evaluators;
-int GLAD_GL_AMD_texture_gather_bias_lod;
-int GLAD_GL_NV_texgen_reflection;
-int GLAD_GL_ARB_explicit_uniform_location;
-int GLAD_GL_ARB_depth_buffer_float;
-int GLAD_GL_NV_path_rendering_shared_edge;
-int GLAD_GL_SGIX_shadow_ambient;
-int GLAD_GL_ARB_texture_cube_map;
-int GLAD_GL_AMD_vertex_shader_viewport_index;
-int GLAD_GL_SGIX_list_priority;
-int GLAD_GL_NV_vertex_buffer_unified_memory;
-int GLAD_GL_NV_uniform_buffer_unified_memory;
-int GLAD_GL_ARB_clear_texture;
-int GLAD_GL_ATI_texture_env_combine3;
-int GLAD_GL_NV_depth_clamp;
-int GLAD_GL_ARB_map_buffer_alignment;
-int GLAD_GL_EXT_memory_object;
-int GLAD_GL_NV_blend_equation_advanced;
-int GLAD_GL_SGIS_sharpen_texture;
-int GLAD_GL_KHR_robust_buffer_access_behavior;
-int GLAD_GL_ARB_pipeline_statistics_query;
-int GLAD_GL_ARB_vertex_program;
-int GLAD_GL_ARB_texture_rgb10_a2ui;
-int GLAD_GL_OML_interlace;
-int GLAD_GL_ATI_pixel_format_float;
-int GLAD_GL_NV_clip_space_w_scaling;
-int GLAD_GL_ARB_vertex_buffer_object;
-int GLAD_GL_EXT_shadow_funcs;
-int GLAD_GL_ATI_text_fragment_shader;
-int GLAD_GL_NV_vertex_array_range;
-int GLAD_GL_SGIX_fragment_lighting;
-int GLAD_GL_AMD_shader_ballot;
-int GLAD_GL_NV_texture_expand_normal;
-int GLAD_GL_NV_framebuffer_multisample_coverage;
-int GLAD_GL_EXT_timer_query;
-int GLAD_GL_EXT_vertex_array_bgra;
-int GLAD_GL_NV_bindless_texture;
-int GLAD_GL_KHR_debug;
-int GLAD_GL_SGIS_texture_border_clamp;
-int GLAD_GL_ATI_vertex_attrib_array_object;
-int GLAD_GL_SGIX_clipmap;
-int GLAD_GL_EXT_geometry_shader4;
-int GLAD_GL_ARB_shader_texture_image_samples;
-int GLAD_GL_MESA_ycbcr_texture;
-int GLAD_GL_MESAX_texture_stack;
-int GLAD_GL_AMD_seamless_cubemap_per_texture;
-int GLAD_GL_EXT_bindable_uniform;
-int GLAD_GL_KHR_texture_compression_astc_hdr;
-int GLAD_GL_ARB_shader_ballot;
-int GLAD_GL_KHR_blend_equation_advanced;
-int GLAD_GL_ARB_fragment_program_shadow;
-int GLAD_GL_ATI_element_array;
-int GLAD_GL_AMD_texture_texture4;
-int GLAD_GL_SGIX_reference_plane;
-int GLAD_GL_EXT_stencil_two_side;
-int GLAD_GL_ARB_transform_feedback_overflow_query;
-int GLAD_GL_SGIX_texture_lod_bias;
-int GLAD_GL_KHR_no_error;
-int GLAD_GL_NV_explicit_multisample;
-int GLAD_GL_NV_stereo_view_rendering;
-int GLAD_GL_IBM_static_data;
-int GLAD_GL_EXT_clip_volume_hint;
-int GLAD_GL_EXT_texture_perturb_normal;
-int GLAD_GL_NV_fragment_program2;
-int GLAD_GL_NV_fragment_program4;
-int GLAD_GL_EXT_point_parameters;
-int GLAD_GL_PGI_misc_hints;
-int GLAD_GL_EXT_EGL_image_storage;
-int GLAD_GL_SGIX_subsample;
-int GLAD_GL_AMD_shader_stencil_export;
-int GLAD_GL_ARB_shader_texture_lod;
-int GLAD_GL_ARB_vertex_shader;
-int GLAD_GL_ARB_depth_clamp;
-int GLAD_GL_SGIS_texture_select;
-int GLAD_GL_NV_texture_shader;
-int GLAD_GL_ARB_tessellation_shader;
-int GLAD_GL_EXT_draw_buffers2;
-int GLAD_GL_ARB_vertex_attrib_64bit;
-int GLAD_GL_EXT_texture_filter_minmax;
-int GLAD_GL_NV_query_resource;
-int GLAD_GL_AMD_interleaved_elements;
-int GLAD_GL_ARB_fragment_program;
-int GLAD_GL_OML_resample;
-int GLAD_GL_APPLE_ycbcr_422;
-int GLAD_GL_SGIX_texture_add_env;
-int GLAD_GL_ARB_shadow_ambient;
-int GLAD_GL_ARB_texture_storage;
-int GLAD_GL_EXT_pixel_buffer_object;
-int GLAD_GL_ARB_copy_image;
-int GLAD_GL_SGIS_pixel_texture;
-int GLAD_GL_SGIS_generate_mipmap;
-int GLAD_GL_SGIX_instruments;
-int GLAD_GL_ARB_fragment_layer_viewport;
-int GLAD_GL_ARB_shader_storage_buffer_object;
-int GLAD_GL_EXT_sparse_texture2;
-int GLAD_GL_EXT_blend_minmax;
-int GLAD_GL_MESA_pack_invert;
-int GLAD_GL_ARB_base_instance;
-int GLAD_GL_SGIX_convolution_accuracy;
-int GLAD_GL_PGI_vertex_hints;
-int GLAD_GL_AMD_transform_feedback4;
-int GLAD_GL_ARB_ES3_1_compatibility;
-int GLAD_GL_EXT_memory_object_win32;
-int GLAD_GL_EXT_texture_integer;
-int GLAD_GL_ARB_texture_multisample;
-int GLAD_GL_ATI_vertex_streams;
-int GLAD_GL_AMD_gpu_shader_int64;
-int GLAD_GL_S3_s3tc;
-int GLAD_GL_ARB_query_buffer_object;
-int GLAD_GL_AMD_vertex_shader_tessellator;
-int GLAD_GL_ARB_invalidate_subdata;
-int GLAD_GL_NV_draw_vulkan_image;
-int GLAD_GL_EXT_index_material;
-int GLAD_GL_NVX_linked_gpu_multicast;
-int GLAD_GL_NV_blend_equation_advanced_coherent;
-int GLAD_GL_KHR_texture_compression_astc_sliced_3d;
-int GLAD_GL_INTEL_parallel_arrays;
-int GLAD_GL_ATI_draw_buffers;
-int GLAD_GL_WIN_specular_fog;
-int GLAD_GL_EXT_cmyka;
-int GLAD_GL_SGIX_pixel_texture;
-int GLAD_GL_APPLE_specular_vector;
-int GLAD_GL_ARB_compatibility;
-int GLAD_GL_ARB_timer_query;
-int GLAD_GL_SGIX_interlace;
-int GLAD_GL_NV_parameter_buffer_object;
-int GLAD_GL_AMD_shader_trinary_minmax;
-int GLAD_GL_ARB_direct_state_access;
-int GLAD_GL_EXT_rescale_normal;
-int GLAD_GL_ARB_pixel_buffer_object;
-int GLAD_GL_ARB_uniform_buffer_object;
-int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev;
-int GLAD_GL_ARB_texture_swizzle;
-int GLAD_GL_NV_transform_feedback2;
-int GLAD_GL_SGIX_async_pixel;
-int GLAD_GL_NV_fragment_program_option;
-int GLAD_GL_ARB_explicit_attrib_location;
-int GLAD_GL_EXT_blend_color;
-int GLAD_GL_NV_shader_thread_group;
-int GLAD_GL_EXT_stencil_wrap;
-int GLAD_GL_EXT_index_array_formats;
-int GLAD_GL_OVR_multiview2;
-int GLAD_GL_EXT_histogram;
-int GLAD_GL_EXT_polygon_offset;
-int GLAD_GL_SGIS_point_parameters;
-int GLAD_GL_SGIX_ycrcb;
-int GLAD_GL_EXT_direct_state_access;
-int GLAD_GL_ARB_cull_distance;
-int GLAD_GL_AMD_sample_positions;
-int GLAD_GL_NV_vertex_program;
-int GLAD_GL_NV_shader_thread_shuffle;
-int GLAD_GL_ARB_shader_precision;
-int GLAD_GL_EXT_vertex_shader;
-int GLAD_GL_EXT_blend_func_separate;
-int GLAD_GL_APPLE_fence;
-int GLAD_GL_NV_query_resource_tag;
-int GLAD_GL_OES_byte_coordinates;
-int GLAD_GL_ARB_transpose_matrix;
-int GLAD_GL_ARB_provoking_vertex;
-int GLAD_GL_EXT_fog_coord;
-int GLAD_GL_EXT_vertex_array;
-int GLAD_GL_ARB_half_float_vertex;
-int GLAD_GL_EXT_blend_equation_separate;
-int GLAD_GL_NV_framebuffer_mixed_samples;
-int GLAD_GL_NVX_conditional_render;
-int GLAD_GL_ARB_multi_draw_indirect;
-int GLAD_GL_EXT_raster_multisample;
-int GLAD_GL_NV_copy_image;
-int GLAD_GL_HP_texture_lighting;
-int GLAD_GL_INTEL_framebuffer_CMAA;
-int GLAD_GL_ARB_transform_feedback2;
-int GLAD_GL_ARB_transform_feedback3;
-int GLAD_GL_SGIX_ycrcba;
-int GLAD_GL_EXT_debug_marker;
-int GLAD_GL_EXT_bgra;
-int GLAD_GL_ARB_sparse_texture_clamp;
-int GLAD_GL_EXT_pixel_transform;
-int GLAD_GL_ARB_conservative_depth;
-int GLAD_GL_ATI_fragment_shader;
-int GLAD_GL_ARB_vertex_array_object;
-int GLAD_GL_SUN_triangle_list;
-int GLAD_GL_EXT_texture_env_add;
-int GLAD_GL_EXT_packed_depth_stencil;
-int GLAD_GL_EXT_texture_mirror_clamp;
-int GLAD_GL_NV_multisample_filter_hint;
-int GLAD_GL_APPLE_float_pixels;
-int GLAD_GL_ARB_transform_feedback_instanced;
-int GLAD_GL_SGIX_async;
-int GLAD_GL_EXT_texture_compression_latc;
-int GLAD_GL_NV_robustness_video_memory_purge;
-int GLAD_GL_ARB_shading_language_100;
-int GLAD_GL_INTEL_performance_query;
-int GLAD_GL_ARB_texture_mirror_clamp_to_edge;
-int GLAD_GL_NV_gpu_shader5;
-int GLAD_GL_NV_bindless_multi_draw_indirect_count;
-int GLAD_GL_ARB_ES2_compatibility;
-int GLAD_GL_ARB_indirect_parameters;
-int GLAD_GL_EXT_window_rectangles;
-int GLAD_GL_NV_half_float;
-int GLAD_GL_ARB_ES3_2_compatibility;
-int GLAD_GL_ATI_texture_mirror_once;
-int GLAD_GL_IBM_rasterpos_clip;
-int GLAD_GL_EXT_semaphore;
-int GLAD_GL_SGIX_shadow;
-int GLAD_GL_EXT_polygon_offset_clamp;
-int GLAD_GL_NV_deep_texture3D;
-int GLAD_GL_ARB_shader_draw_parameters;
-int GLAD_GL_SGIX_calligraphic_fragment;
-int GLAD_GL_ARB_shader_bit_encoding;
-int GLAD_GL_EXT_compiled_vertex_array;
-int GLAD_GL_NV_depth_buffer_float;
-int GLAD_GL_NV_occlusion_query;
-int GLAD_GL_APPLE_flush_buffer_range;
-int GLAD_GL_ARB_imaging;
-int GLAD_GL_NV_shader_atomic_float;
-int GLAD_GL_ARB_draw_buffers_blend;
-int GLAD_GL_AMD_gcn_shader;
-int GLAD_GL_AMD_blend_minmax_factor;
-int GLAD_GL_EXT_texture_sRGB_decode;
-int GLAD_GL_ARB_shading_language_420pack;
-int GLAD_GL_ARB_shader_viewport_layer_array;
-int GLAD_GL_ATI_meminfo;
-int GLAD_GL_EXT_abgr;
-int GLAD_GL_AMD_pinned_memory;
-int GLAD_GL_EXT_texture_snorm;
-int GLAD_GL_SGIX_texture_coordinate_clamp;
-int GLAD_GL_ARB_clear_buffer_object;
-int GLAD_GL_ARB_multisample;
-int GLAD_GL_EXT_debug_label;
-int GLAD_GL_ARB_sample_shading;
-int GLAD_GL_NV_internalformat_sample_query;
-int GLAD_GL_INTEL_map_texture;
-int GLAD_GL_ARB_texture_env_crossbar;
-int GLAD_GL_EXT_422_pixels;
-int GLAD_GL_NV_blend_minmax_factor;
-int GLAD_GL_NV_conservative_raster_pre_snap_triangles;
-int GLAD_GL_ARB_compute_shader;
-int GLAD_GL_EXT_blend_logic_op;
-int GLAD_GL_ARB_blend_func_extended;
-int GLAD_GL_IBM_vertex_array_lists;
-int GLAD_GL_ARB_color_buffer_float;
-int GLAD_GL_ARB_bindless_texture;
-int GLAD_GL_ARB_window_pos;
-int GLAD_GL_ARB_internalformat_query;
-int GLAD_GL_ARB_shadow;
-int GLAD_GL_ARB_texture_mirrored_repeat;
-int GLAD_GL_EXT_shader_image_load_store;
-int GLAD_GL_EXT_copy_texture;
-int GLAD_GL_NV_register_combiners2;
-int GLAD_GL_SGIX_ycrcb_subsample;
-int GLAD_GL_NV_alpha_to_coverage_dither_control;
-int GLAD_GL_SGIX_ir_instrument1;
-int GLAD_GL_NV_draw_texture;
-int GLAD_GL_EXT_texture_shared_exponent;
-int GLAD_GL_NV_texture_shader2;
-int GLAD_GL_EXT_draw_instanced;
-int GLAD_GL_NV_copy_depth_to_color;
-int GLAD_GL_ARB_viewport_array;
-int GLAD_GL_ARB_separate_shader_objects;
-int GLAD_GL_NV_conservative_raster_pre_snap;
-int GLAD_GL_EXT_depth_bounds_test;
-int GLAD_GL_HP_image_transform;
-int GLAD_GL_ARB_texture_env_add;
-int GLAD_GL_NV_video_capture;
-int GLAD_GL_ARB_sampler_objects;
-int GLAD_GL_ARB_matrix_palette;
-int GLAD_GL_SGIS_texture_color_mask;
-int GLAD_GL_EXT_packed_pixels;
-int GLAD_GL_EXT_coordinate_frame;
-int GLAD_GL_ARB_texture_compression;
-int GLAD_GL_ARB_multi_bind;
-int GLAD_GL_APPLE_aux_depth_stencil;
-int GLAD_GL_ARB_shader_subroutine;
-int GLAD_GL_EXT_framebuffer_sRGB;
-int GLAD_GL_ARB_texture_storage_multisample;
-int GLAD_GL_KHR_blend_equation_advanced_coherent;
-int GLAD_GL_EXT_vertex_attrib_64bit;
-int GLAD_GL_NV_shader_atomic_float64;
-int GLAD_GL_ARB_depth_texture;
-int GLAD_GL_NV_shader_buffer_store;
-int GLAD_GL_OES_query_matrix;
-int GLAD_GL_MESA_window_pos;
-int GLAD_GL_NV_fill_rectangle;
-int GLAD_GL_NV_shader_storage_buffer_object;
-int GLAD_GL_ARB_texture_query_lod;
-int GLAD_GL_ARB_copy_buffer;
-int GLAD_GL_ARB_shader_image_size;
-int GLAD_GL_NV_shader_atomic_counters;
-int GLAD_GL_APPLE_object_purgeable;
-int GLAD_GL_ARB_occlusion_query;
-int GLAD_GL_INGR_color_clamp;
-int GLAD_GL_SGI_color_table;
-int GLAD_GL_NV_gpu_program5_mem_extended;
-int GLAD_GL_ARB_texture_cube_map_array;
-int GLAD_GL_SGIX_scalebias_hint;
-int GLAD_GL_EXT_gpu_shader4;
-int GLAD_GL_NV_geometry_program4;
-int GLAD_GL_EXT_framebuffer_multisample_blit_scaled;
-int GLAD_GL_AMD_debug_output;
-int GLAD_GL_ARB_texture_border_clamp;
-int GLAD_GL_EXT_win32_keyed_mutex;
-int GLAD_GL_ARB_fragment_coord_conventions;
-int GLAD_GL_ARB_multitexture;
-int GLAD_GL_SGIX_polynomial_ffd;
-int GLAD_GL_EXT_texture_env_dot3;
-int GLAD_GL_EXT_provoking_vertex;
-int GLAD_GL_ARB_point_parameters;
-int GLAD_GL_ARB_shader_image_load_store;
-int GLAD_GL_ARB_conditional_render_inverted;
-int GLAD_GL_HP_occlusion_test;
-int GLAD_GL_ARB_ES3_compatibility;
-int GLAD_GL_ARB_texture_barrier;
-int GLAD_GL_ARB_texture_buffer_object_rgb32;
-int GLAD_GL_NV_bindless_multi_draw_indirect;
-int GLAD_GL_SGIX_texture_multi_buffer;
-int GLAD_GL_INTEL_blackhole_render;
-int GLAD_GL_AMD_shader_image_load_store_lod;
-int GLAD_GL_KHR_texture_compression_astc_ldr;
-int GLAD_GL_3DFX_multisample;
-int GLAD_GL_INTEL_fragment_shader_ordering;
-int GLAD_GL_ARB_texture_env_dot3;
-int GLAD_GL_NV_gpu_program4;
-int GLAD_GL_NV_gpu_program5;
-int GLAD_GL_NV_float_buffer;
-int GLAD_GL_SGIS_texture_edge_clamp;
-int GLAD_GL_ARB_framebuffer_sRGB;
-int GLAD_GL_SUN_slice_accum;
-int GLAD_GL_EXT_index_texture;
-int GLAD_GL_EXT_shader_image_load_formatted;
-int GLAD_GL_ARB_geometry_shader4;
-int GLAD_GL_EXT_separate_specular_color;
-int GLAD_GL_AMD_depth_clamp_separate;
-int GLAD_GL_NV_conservative_raster;
-int GLAD_GL_ARB_sparse_texture2;
-int GLAD_GL_SGIX_sprite;
-int GLAD_GL_ARB_get_program_binary;
-int GLAD_GL_AMD_occlusion_query_event;
-int GLAD_GL_SGIS_multisample;
-int GLAD_GL_EXT_framebuffer_object;
-int GLAD_GL_ARB_robustness_isolation;
-int GLAD_GL_ARB_vertex_array_bgra;
-int GLAD_GL_APPLE_vertex_array_range;
-int GLAD_GL_AMD_query_buffer_object;
-int GLAD_GL_NV_register_combiners;
-int GLAD_GL_ARB_draw_buffers;
-int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers;
-int GLAD_GL_AMD_gpu_shader_int16;
-int GLAD_GL_ARB_debug_output;
-int GLAD_GL_EXT_shader_framebuffer_fetch;
-int GLAD_GL_SGI_color_matrix;
-int GLAD_GL_EXT_cull_vertex;
-int GLAD_GL_EXT_texture_sRGB;
-int GLAD_GL_APPLE_row_bytes;
-int GLAD_GL_NV_conservative_raster_underestimation;
-int GLAD_GL_IBM_multimode_draw_arrays;
-int GLAD_GL_KHR_parallel_shader_compile;
-int GLAD_GL_APPLE_vertex_array_object;
-int GLAD_GL_3DFX_texture_compression_FXT1;
-int GLAD_GL_NV_fragment_shader_interlock;
-int GLAD_GL_AMD_conservative_depth;
-int GLAD_GL_ARB_texture_float;
-int GLAD_GL_ARB_compressed_texture_pixel_storage;
-int GLAD_GL_SGIS_detail_texture;
-int GLAD_GL_NV_geometry_shader_passthrough;
-int GLAD_GL_ARB_draw_instanced;
-int GLAD_GL_OES_read_format;
-int GLAD_GL_ATI_texture_float;
-int GLAD_GL_ARB_texture_gather;
-int GLAD_GL_AMD_vertex_shader_layer;
-int GLAD_GL_ARB_shading_language_include;
-int GLAD_GL_APPLE_client_storage;
-int GLAD_GL_WIN_phong_shading;
-int GLAD_GL_INGR_blend_func_separate;
-int GLAD_GL_NV_path_rendering;
-int GLAD_GL_NV_conservative_raster_dilate;
-int GLAD_GL_AMD_gpu_shader_half_float;
-int GLAD_GL_ARB_post_depth_coverage;
-int GLAD_GL_ARB_texture_non_power_of_two;
-int GLAD_GL_APPLE_rgb_422;
-int GLAD_GL_EXT_texture_lod_bias;
-int GLAD_GL_ARB_gpu_shader_int64;
-int GLAD_GL_ARB_seamless_cube_map;
-int GLAD_GL_ARB_shader_group_vote;
-int GLAD_GL_NV_vdpau_interop;
-int GLAD_GL_ARB_occlusion_query2;
-int GLAD_GL_ARB_internalformat_query2;
-int GLAD_GL_EXT_texture_filter_anisotropic;
-int GLAD_GL_SUN_vertex;
-int GLAD_GL_EXT_transform_feedback;
-int GLAD_GL_SGIX_igloo_interface;
-int GLAD_GL_SGIS_texture_lod;
-int GLAD_GL_NV_vertex_program3;
-int GLAD_GL_ARB_draw_indirect;
-int GLAD_GL_NV_vertex_program4;
-int GLAD_GL_AMD_transform_feedback3_lines_triangles;
-int GLAD_GL_SGIS_fog_function;
-int GLAD_GL_EXT_x11_sync_object;
-int GLAD_GL_ARB_sync;
-int GLAD_GL_NV_texture_rectangle_compressed;
-int GLAD_GL_NV_sample_locations;
-int GLAD_GL_NV_gpu_multicast;
-int GLAD_GL_ARB_gl_spirv;
-int GLAD_GL_ARB_compute_variable_group_size;
-int GLAD_GL_OES_fixed_point;
-int GLAD_GL_MESA_program_binary_formats;
-int GLAD_GL_NV_blend_square;
-int GLAD_GL_EXT_framebuffer_multisample;
-int GLAD_GL_ARB_gpu_shader5;
-int GLAD_GL_SGIS_texture4D;
-int GLAD_GL_EXT_texture3D;
-int GLAD_GL_EXT_multisample;
-int GLAD_GL_EXT_secondary_color;
-int GLAD_GL_INTEL_conservative_rasterization;
-int GLAD_GL_ARB_texture_filter_minmax;
-int GLAD_GL_ATI_vertex_array_object;
-int GLAD_GL_ARB_parallel_shader_compile;
-int GLAD_GL_NVX_gpu_memory_info;
-int GLAD_GL_ARB_sparse_texture;
-int GLAD_GL_SGIS_point_line_texgen;
-int GLAD_GL_ARB_sample_locations;
-int GLAD_GL_ARB_sparse_buffer;
-int GLAD_GL_ARB_polygon_offset_clamp;
-int GLAD_GL_EXT_draw_range_elements;
-int GLAD_GL_SGIX_blend_alpha_minmax;
-int GLAD_GL_KHR_context_flush_control;
-PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX;
-PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD;
-PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD;
-PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD;
-PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD;
-PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD;
-PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD;
-PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD;
-PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD;
-PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD;
-PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD;
-PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD;
-PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD;
-PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV;
-PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV;
-PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV;
-PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV;
-PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV;
-PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV;
-PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV;
-PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV;
-PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV;
-PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV;
-PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV;
-PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV;
-PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV;
-PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV;
-PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV;
-PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV;
-PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV;
-PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV;
-PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV;
-PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV;
-PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV;
-PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV;
-PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV;
-PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV;
-PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV;
-PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV;
-PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV;
-PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV;
-PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV;
-PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV;
-PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV;
-PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV;
-PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV;
-PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV;
-PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD;
-PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD;
-PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD;
-PFNGLGENNAMESAMDPROC glad_glGenNamesAMD;
-PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD;
-PFNGLISNAMEAMDPROC glad_glIsNameAMD;
-PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD;
-PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD;
-PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD;
-PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD;
-PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD;
-PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD;
-PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD;
-PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD;
-PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD;
-PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD;
-PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD;
-PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD;
-PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD;
-PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD;
-PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD;
-PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD;
-PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD;
-PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD;
-PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE;
-PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE;
-PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE;
-PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE;
-PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE;
-PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE;
-PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE;
-PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE;
-PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE;
-PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE;
-PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE;
-PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE;
-PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE;
-PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE;
-PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE;
-PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE;
-PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE;
-PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE;
-PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE;
-PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE;
-PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE;
-PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE;
-PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE;
-PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE;
-PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE;
-PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE;
-PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE;
-PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE;
-PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE;
-PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE;
-PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE;
-PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE;
-PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE;
-PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE;
-PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
-PFNGLSHADERBINARYPROC glad_glShaderBinary;
-PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
-PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
-PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
-PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion;
-PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB;
-PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance;
-PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance;
-PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance;
-PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB;
-PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB;
-PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB;
-PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB;
-PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB;
-PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB;
-PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB;
-PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB;
-PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB;
-PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB;
-PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB;
-PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB;
-PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB;
-PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB;
-PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB;
-PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB;
-PFNGLBUFFERSTORAGEPROC glad_glBufferStorage;
-PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB;
-PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData;
-PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData;
-PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage;
-PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage;
-PFNGLCLIPCONTROLPROC glad_glClipControl;
-PFNGLCLAMPCOLORARBPROC glad_glClampColorARB;
-PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute;
-PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect;
-PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB;
-PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData;
-PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB;
-PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB;
-PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB;
-PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB;
-PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks;
-PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase;
-PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange;
-PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv;
-PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v;
-PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v;
-PFNGLCREATEBUFFERSPROC glad_glCreateBuffers;
-PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage;
-PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData;
-PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData;
-PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData;
-PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData;
-PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData;
-PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer;
-PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange;
-PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer;
-PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange;
-PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv;
-PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v;
-PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv;
-PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData;
-PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers;
-PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer;
-PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri;
-PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture;
-PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer;
-PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer;
-PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers;
-PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer;
-PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData;
-PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData;
-PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv;
-PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv;
-PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv;
-PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi;
-PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer;
-PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus;
-PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv;
-PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv;
-PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers;
-PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage;
-PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample;
-PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv;
-PFNGLCREATETEXTURESPROC glad_glCreateTextures;
-PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer;
-PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange;
-PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D;
-PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D;
-PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D;
-PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample;
-PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample;
-PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D;
-PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D;
-PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D;
-PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D;
-PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D;
-PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D;
-PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf;
-PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv;
-PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri;
-PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv;
-PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv;
-PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv;
-PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap;
-PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit;
-PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage;
-PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage;
-PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv;
-PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv;
-PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv;
-PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv;
-PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv;
-PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv;
-PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays;
-PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib;
-PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib;
-PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer;
-PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer;
-PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers;
-PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding;
-PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat;
-PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat;
-PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat;
-PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor;
-PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv;
-PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv;
-PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv;
-PFNGLCREATESAMPLERSPROC glad_glCreateSamplers;
-PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines;
-PFNGLCREATEQUERIESPROC glad_glCreateQueries;
-PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v;
-PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv;
-PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v;
-PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv;
-PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB;
-PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB;
-PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB;
-PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB;
-PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB;
-PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect;
-PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect;
-PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB;
-PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB;
-PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB;
-PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB;
-PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB;
-PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB;
-PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB;
-PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB;
-PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB;
-PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB;
-PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB;
-PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB;
-PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB;
-PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB;
-PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB;
-PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB;
-PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB;
-PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB;
-PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB;
-PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB;
-PFNGLISPROGRAMARBPROC glad_glIsProgramARB;
-PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri;
-PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv;
-PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB;
-PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB;
-PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB;
-PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB;
-PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary;
-PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
-PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri;
-PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage;
-PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage;
-PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB;
-PFNGLUNIFORM1DPROC glad_glUniform1d;
-PFNGLUNIFORM2DPROC glad_glUniform2d;
-PFNGLUNIFORM3DPROC glad_glUniform3d;
-PFNGLUNIFORM4DPROC glad_glUniform4d;
-PFNGLUNIFORM1DVPROC glad_glUniform1dv;
-PFNGLUNIFORM2DVPROC glad_glUniform2dv;
-PFNGLUNIFORM3DVPROC glad_glUniform3dv;
-PFNGLUNIFORM4DVPROC glad_glUniform4dv;
-PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv;
-PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv;
-PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv;
-PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv;
-PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv;
-PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv;
-PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv;
-PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv;
-PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv;
-PFNGLGETUNIFORMDVPROC glad_glGetUniformdv;
-PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB;
-PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB;
-PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB;
-PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB;
-PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB;
-PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB;
-PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB;
-PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB;
-PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB;
-PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB;
-PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB;
-PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB;
-PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB;
-PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB;
-PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB;
-PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB;
-PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB;
-PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB;
-PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB;
-PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB;
-PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB;
-PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB;
-PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB;
-PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB;
-PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB;
-PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB;
-PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB;
-PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB;
-PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB;
-PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB;
-PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB;
-PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB;
-PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB;
-PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB;
-PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB;
-PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB;
-PFNGLCOLORTABLEPROC glad_glColorTable;
-PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv;
-PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv;
-PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable;
-PFNGLGETCOLORTABLEPROC glad_glGetColorTable;
-PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv;
-PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv;
-PFNGLCOLORSUBTABLEPROC glad_glColorSubTable;
-PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable;
-PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D;
-PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D;
-PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf;
-PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv;
-PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri;
-PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv;
-PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D;
-PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D;
-PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter;
-PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv;
-PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv;
-PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter;
-PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D;
-PFNGLGETHISTOGRAMPROC glad_glGetHistogram;
-PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv;
-PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv;
-PFNGLGETMINMAXPROC glad_glGetMinmax;
-PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv;
-PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv;
-PFNGLHISTOGRAMPROC glad_glHistogram;
-PFNGLMINMAXPROC glad_glMinmax;
-PFNGLRESETHISTOGRAMPROC glad_glResetHistogram;
-PFNGLRESETMINMAXPROC glad_glResetMinmax;
-PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB;
-PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB;
-PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB;
-PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
-PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v;
-PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage;
-PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage;
-PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData;
-PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData;
-PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer;
-PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer;
-PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB;
-PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB;
-PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB;
-PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB;
-PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB;
-PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase;
-PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange;
-PFNGLBINDTEXTURESPROC glad_glBindTextures;
-PFNGLBINDSAMPLERSPROC glad_glBindSamplers;
-PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures;
-PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers;
-PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect;
-PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect;
-PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB;
-PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB;
-PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB;
-PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB;
-PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB;
-PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB;
-PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB;
-PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB;
-PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB;
-PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB;
-PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB;
-PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB;
-PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB;
-PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB;
-PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB;
-PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB;
-PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB;
-PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB;
-PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB;
-PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB;
-PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB;
-PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB;
-PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB;
-PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB;
-PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB;
-PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB;
-PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB;
-PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB;
-PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB;
-PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB;
-PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB;
-PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB;
-PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB;
-PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB;
-PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB;
-PFNGLGENQUERIESARBPROC glad_glGenQueriesARB;
-PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB;
-PFNGLISQUERYARBPROC glad_glIsQueryARB;
-PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB;
-PFNGLENDQUERYARBPROC glad_glEndQueryARB;
-PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB;
-PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB;
-PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB;
-PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB;
-PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB;
-PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB;
-PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp;
-PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv;
-PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex;
-PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName;
-PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv;
-PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation;
-PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex;
-PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB;
-PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB;
-PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB;
-PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB;
-PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB;
-PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB;
-PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB;
-PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB;
-PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB;
-PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB;
-PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB;
-PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB;
-PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB;
-PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB;
-PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB;
-PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB;
-PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB;
-PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB;
-PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB;
-PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB;
-PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB;
-PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB;
-PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB;
-PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB;
-PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages;
-PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram;
-PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv;
-PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline;
-PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines;
-PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines;
-PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline;
-PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv;
-PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i;
-PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv;
-PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f;
-PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv;
-PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d;
-PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv;
-PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui;
-PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv;
-PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i;
-PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv;
-PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f;
-PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv;
-PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d;
-PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv;
-PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui;
-PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv;
-PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i;
-PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv;
-PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f;
-PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv;
-PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d;
-PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv;
-PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui;
-PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv;
-PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i;
-PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv;
-PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f;
-PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv;
-PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d;
-PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv;
-PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui;
-PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv;
-PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv;
-PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv;
-PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv;
-PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv;
-PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv;
-PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv;
-PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv;
-PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv;
-PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv;
-PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv;
-PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv;
-PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv;
-PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv;
-PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv;
-PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv;
-PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv;
-PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv;
-PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv;
-PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline;
-PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog;
-PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv;
-PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture;
-PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier;
-PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB;
-PFNGLGETHANDLEARBPROC glad_glGetHandleARB;
-PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB;
-PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB;
-PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB;
-PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB;
-PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB;
-PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB;
-PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB;
-PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB;
-PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB;
-PFNGLUNIFORM1FARBPROC glad_glUniform1fARB;
-PFNGLUNIFORM2FARBPROC glad_glUniform2fARB;
-PFNGLUNIFORM3FARBPROC glad_glUniform3fARB;
-PFNGLUNIFORM4FARBPROC glad_glUniform4fARB;
-PFNGLUNIFORM1IARBPROC glad_glUniform1iARB;
-PFNGLUNIFORM2IARBPROC glad_glUniform2iARB;
-PFNGLUNIFORM3IARBPROC glad_glUniform3iARB;
-PFNGLUNIFORM4IARBPROC glad_glUniform4iARB;
-PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB;
-PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB;
-PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB;
-PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB;
-PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB;
-PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB;
-PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB;
-PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB;
-PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB;
-PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB;
-PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB;
-PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB;
-PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB;
-PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB;
-PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB;
-PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB;
-PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB;
-PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB;
-PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB;
-PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB;
-PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding;
-PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation;
-PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex;
-PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv;
-PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName;
-PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName;
-PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv;
-PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv;
-PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv;
-PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB;
-PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB;
-PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB;
-PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB;
-PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB;
-PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB;
-PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB;
-PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT;
-PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB;
-PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB;
-PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri;
-PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv;
-PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier;
-PFNGLTEXBUFFERARBPROC glad_glTexBufferARB;
-PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange;
-PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB;
-PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB;
-PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB;
-PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB;
-PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB;
-PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB;
-PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB;
-PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
-PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D;
-PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D;
-PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample;
-PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample;
-PFNGLTEXTUREVIEWPROC glad_glTextureView;
-PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback;
-PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks;
-PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks;
-PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback;
-PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback;
-PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
-PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback;
-PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream;
-PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed;
-PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed;
-PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv;
-PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced;
-PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced;
-PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB;
-PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB;
-PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB;
-PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB;
-PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d;
-PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d;
-PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d;
-PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d;
-PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv;
-PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv;
-PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv;
-PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv;
-PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer;
-PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv;
-PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer;
-PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat;
-PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat;
-PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat;
-PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding;
-PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor;
-PFNGLWEIGHTBVARBPROC glad_glWeightbvARB;
-PFNGLWEIGHTSVARBPROC glad_glWeightsvARB;
-PFNGLWEIGHTIVARBPROC glad_glWeightivARB;
-PFNGLWEIGHTFVARBPROC glad_glWeightfvARB;
-PFNGLWEIGHTDVARBPROC glad_glWeightdvARB;
-PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB;
-PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB;
-PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB;
-PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB;
-PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB;
-PFNGLBINDBUFFERARBPROC glad_glBindBufferARB;
-PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB;
-PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB;
-PFNGLISBUFFERARBPROC glad_glIsBufferARB;
-PFNGLBUFFERDATAARBPROC glad_glBufferDataARB;
-PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB;
-PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB;
-PFNGLMAPBUFFERARBPROC glad_glMapBufferARB;
-PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB;
-PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB;
-PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB;
-PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB;
-PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB;
-PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB;
-PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB;
-PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB;
-PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB;
-PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB;
-PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB;
-PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB;
-PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB;
-PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB;
-PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB;
-PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB;
-PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB;
-PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB;
-PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB;
-PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB;
-PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB;
-PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB;
-PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB;
-PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB;
-PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB;
-PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB;
-PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB;
-PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB;
-PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB;
-PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB;
-PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB;
-PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB;
-PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB;
-PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB;
-PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB;
-PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB;
-PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB;
-PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB;
-PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB;
-PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB;
-PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB;
-PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB;
-PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB;
-PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB;
-PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB;
-PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB;
-PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB;
-PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB;
-PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB;
-PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv;
-PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf;
-PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv;
-PFNGLSCISSORARRAYVPROC glad_glScissorArrayv;
-PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed;
-PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv;
-PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv;
-PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
-PFNGLGETFLOATI_VPROC glad_glGetFloati_v;
-PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v;
-PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB;
-PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB;
-PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB;
-PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB;
-PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB;
-PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB;
-PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB;
-PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB;
-PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB;
-PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB;
-PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB;
-PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB;
-PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB;
-PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB;
-PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB;
-PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB;
-PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI;
-PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI;
-PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI;
-PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI;
-PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI;
-PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI;
-PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI;
-PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI;
-PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI;
-PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI;
-PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI;
-PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI;
-PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI;
-PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI;
-PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI;
-PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI;
-PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI;
-PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI;
-PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI;
-PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI;
-PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI;
-PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI;
-PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI;
-PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI;
-PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI;
-PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI;
-PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI;
-PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI;
-PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI;
-PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI;
-PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI;
-PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI;
-PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI;
-PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI;
-PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI;
-PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI;
-PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI;
-PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI;
-PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI;
-PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI;
-PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI;
-PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI;
-PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI;
-PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI;
-PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI;
-PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI;
-PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI;
-PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI;
-PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI;
-PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI;
-PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI;
-PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI;
-PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI;
-PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI;
-PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI;
-PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI;
-PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI;
-PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI;
-PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI;
-PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI;
-PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI;
-PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI;
-PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI;
-PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI;
-PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI;
-PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI;
-PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI;
-PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI;
-PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI;
-PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI;
-PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI;
-PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI;
-PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI;
-PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI;
-PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI;
-PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI;
-PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI;
-PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI;
-PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI;
-PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI;
-PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI;
-PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI;
-PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI;
-PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI;
-PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI;
-PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI;
-PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI;
-PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI;
-PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT;
-PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT;
-PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT;
-PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT;
-PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT;
-PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT;
-PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT;
-PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT;
-PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT;
-PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT;
-PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT;
-PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT;
-PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT;
-PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT;
-PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT;
-PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT;
-PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT;
-PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT;
-PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT;
-PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT;
-PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT;
-PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT;
-PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT;
-PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT;
-PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT;
-PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT;
-PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT;
-PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT;
-PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT;
-PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT;
-PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT;
-PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT;
-PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT;
-PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT;
-PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT;
-PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT;
-PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT;
-PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT;
-PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT;
-PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT;
-PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT;
-PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT;
-PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT;
-PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT;
-PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT;
-PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT;
-PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT;
-PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT;
-PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT;
-PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT;
-PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT;
-PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT;
-PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT;
-PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT;
-PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT;
-PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT;
-PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT;
-PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT;
-PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT;
-PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT;
-PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT;
-PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT;
-PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT;
-PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT;
-PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT;
-PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT;
-PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT;
-PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT;
-PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT;
-PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT;
-PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT;
-PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT;
-PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT;
-PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT;
-PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT;
-PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT;
-PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT;
-PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT;
-PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT;
-PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT;
-PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT;
-PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT;
-PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT;
-PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT;
-PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT;
-PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT;
-PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT;
-PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT;
-PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT;
-PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT;
-PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT;
-PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT;
-PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT;
-PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT;
-PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT;
-PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT;
-PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT;
-PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT;
-PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT;
-PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT;
-PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT;
-PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT;
-PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT;
-PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT;
-PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT;
-PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT;
-PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT;
-PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT;
-PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT;
-PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT;
-PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT;
-PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT;
-PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT;
-PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT;
-PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT;
-PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT;
-PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT;
-PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT;
-PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT;
-PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT;
-PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT;
-PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT;
-PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT;
-PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT;
-PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT;
-PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT;
-PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT;
-PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT;
-PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT;
-PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT;
-PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT;
-PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT;
-PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT;
-PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT;
-PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT;
-PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT;
-PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT;
-PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT;
-PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT;
-PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT;
-PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT;
-PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT;
-PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT;
-PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT;
-PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT;
-PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT;
-PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT;
-PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT;
-PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT;
-PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT;
-PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT;
-PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT;
-PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT;
-PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT;
-PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT;
-PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT;
-PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT;
-PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT;
-PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT;
-PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT;
-PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT;
-PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT;
-PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT;
-PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT;
-PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT;
-PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT;
-PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT;
-PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT;
-PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT;
-PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT;
-PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT;
-PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT;
-PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT;
-PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT;
-PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT;
-PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT;
-PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT;
-PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT;
-PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT;
-PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT;
-PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT;
-PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT;
-PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT;
-PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT;
-PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT;
-PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT;
-PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT;
-PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT;
-PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT;
-PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT;
-PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT;
-PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT;
-PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT;
-PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT;
-PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT;
-PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT;
-PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT;
-PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT;
-PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT;
-PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT;
-PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT;
-PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT;
-PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT;
-PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT;
-PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT;
-PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT;
-PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT;
-PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT;
-PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT;
-PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT;
-PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT;
-PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT;
-PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT;
-PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT;
-PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT;
-PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT;
-PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT;
-PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT;
-PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT;
-PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT;
-PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT;
-PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT;
-PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT;
-PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT;
-PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT;
-PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT;
-PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT;
-PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT;
-PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT;
-PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT;
-PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT;
-PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT;
-PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT;
-PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT;
-PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT;
-PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT;
-PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT;
-PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT;
-PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT;
-PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT;
-PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT;
-PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT;
-PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT;
-PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT;
-PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT;
-PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT;
-PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT;
-PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT;
-PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT;
-PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT;
-PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT;
-PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT;
-PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT;
-PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT;
-PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT;
-PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT;
-PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT;
-PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT;
-PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT;
-PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT;
-PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT;
-PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT;
-PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT;
-PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT;
-PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT;
-PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT;
-PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT;
-PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT;
-PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT;
-PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT;
-PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT;
-PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT;
-PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT;
-PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT;
-PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT;
-PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT;
-PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT;
-PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT;
-PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT;
-PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT;
-PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT;
-PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT;
-PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT;
-PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT;
-PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT;
-PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT;
-PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT;
-PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT;
-PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT;
-PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT;
-PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT;
-PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT;
-PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT;
-PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT;
-PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT;
-PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT;
-PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT;
-PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT;
-PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT;
-PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT;
-PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT;
-PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT;
-PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT;
-PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT;
-PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT;
-PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT;
-PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT;
-PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT;
-PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT;
-PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT;
-PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT;
-PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT;
-PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT;
-PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT;
-PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT;
-PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT;
-PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT;
-PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT;
-PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT;
-PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT;
-PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT;
-PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT;
-PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT;
-PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT;
-PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT;
-PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT;
-PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT;
-PFNGLMINMAXEXTPROC glad_glMinmaxEXT;
-PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT;
-PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT;
-PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT;
-PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT;
-PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT;
-PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT;
-PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT;
-PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT;
-PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT;
-PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT;
-PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT;
-PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT;
-PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT;
-PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT;
-PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT;
-PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT;
-PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT;
-PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT;
-PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT;
-PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT;
-PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT;
-PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT;
-PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT;
-PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT;
-PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT;
-PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT;
-PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT;
-PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT;
-PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT;
-PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT;
-PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT;
-PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT;
-PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT;
-PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT;
-PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT;
-PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT;
-PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT;
-PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT;
-PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT;
-PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT;
-PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT;
-PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT;
-PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT;
-PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT;
-PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT;
-PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT;
-PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT;
-PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT;
-PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT;
-PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT;
-PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT;
-PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT;
-PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT;
-PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT;
-PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT;
-PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT;
-PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT;
-PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT;
-PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT;
-PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT;
-PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT;
-PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT;
-PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT;
-PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT;
-PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT;
-PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT;
-PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT;
-PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT;
-PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT;
-PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT;
-PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT;
-PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT;
-PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT;
-PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT;
-PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT;
-PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT;
-PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT;
-PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT;
-PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT;
-PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT;
-PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT;
-PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT;
-PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT;
-PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT;
-PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT;
-PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT;
-PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT;
-PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT;
-PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT;
-PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT;
-PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT;
-PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT;
-PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT;
-PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT;
-PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT;
-PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT;
-PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT;
-PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT;
-PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT;
-PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT;
-PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT;
-PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT;
-PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT;
-PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT;
-PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT;
-PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT;
-PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT;
-PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT;
-PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT;
-PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT;
-PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT;
-PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT;
-PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT;
-PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT;
-PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT;
-PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT;
-PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT;
-PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT;
-PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT;
-PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT;
-PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT;
-PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT;
-PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT;
-PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT;
-PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT;
-PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT;
-PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT;
-PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT;
-PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT;
-PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT;
-PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT;
-PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT;
-PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT;
-PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT;
-PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT;
-PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT;
-PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT;
-PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT;
-PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT;
-PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT;
-PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT;
-PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT;
-PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT;
-PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT;
-PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT;
-PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT;
-PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT;
-PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT;
-PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT;
-PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT;
-PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT;
-PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT;
-PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT;
-PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT;
-PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT;
-PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT;
-PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT;
-PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT;
-PFNGLVARIANTIVEXTPROC glad_glVariantivEXT;
-PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT;
-PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT;
-PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT;
-PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT;
-PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT;
-PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT;
-PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT;
-PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT;
-PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT;
-PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT;
-PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT;
-PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT;
-PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT;
-PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT;
-PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT;
-PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT;
-PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT;
-PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT;
-PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT;
-PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT;
-PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT;
-PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT;
-PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT;
-PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT;
-PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT;
-PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT;
-PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT;
-PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT;
-PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT;
-PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT;
-PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT;
-PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY;
-PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY;
-PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP;
-PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP;
-PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP;
-PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP;
-PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP;
-PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP;
-PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM;
-PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM;
-PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM;
-PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM;
-PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM;
-PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM;
-PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM;
-PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM;
-PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM;
-PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM;
-PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM;
-PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR;
-PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL;
-PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL;
-PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL;
-PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL;
-PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL;
-PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL;
-PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL;
-PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL;
-PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL;
-PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL;
-PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL;
-PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL;
-PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL;
-PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL;
-PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL;
-PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL;
-PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL;
-PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL;
-PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR;
-PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl;
-PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert;
-PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback;
-PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog;
-PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
-PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
-PFNGLOBJECTLABELPROC glad_glObjectLabel;
-PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel;
-PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel;
-PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel;
-PFNGLGETPOINTERVPROC glad_glGetPointerv;
-PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR;
-PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR;
-PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR;
-PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR;
-PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR;
-PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR;
-PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR;
-PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR;
-PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR;
-PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR;
-PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR;
-PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR;
-PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus;
-PFNGLREADNPIXELSPROC glad_glReadnPixels;
-PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv;
-PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv;
-PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
-PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR;
-PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR;
-PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR;
-PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR;
-PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR;
-PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA;
-PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA;
-PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA;
-PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA;
-PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA;
-PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA;
-PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA;
-PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA;
-PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA;
-PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA;
-PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA;
-PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA;
-PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA;
-PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA;
-PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA;
-PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA;
-PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA;
-PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA;
-PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA;
-PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA;
-PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA;
-PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA;
-PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA;
-PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA;
-PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA;
-PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX;
-PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX;
-PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX;
-PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX;
-PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX;
-PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV;
-PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV;
-PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV;
-PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV;
-PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV;
-PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV;
-PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV;
-PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV;
-PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV;
-PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV;
-PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV;
-PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV;
-PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV;
-PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV;
-PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV;
-PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV;
-PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV;
-PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV;
-PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV;
-PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV;
-PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV;
-PFNGLCREATESTATESNVPROC glad_glCreateStatesNV;
-PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV;
-PFNGLISSTATENVPROC glad_glIsStateNV;
-PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV;
-PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV;
-PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV;
-PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV;
-PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV;
-PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV;
-PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV;
-PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV;
-PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV;
-PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV;
-PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV;
-PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV;
-PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV;
-PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV;
-PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV;
-PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV;
-PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV;
-PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV;
-PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV;
-PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV;
-PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV;
-PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV;
-PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV;
-PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV;
-PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV;
-PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV;
-PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV;
-PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV;
-PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV;
-PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV;
-PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV;
-PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV;
-PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV;
-PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV;
-PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV;
-PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV;
-PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV;
-PFNGLEVALMAPSNVPROC glad_glEvalMapsNV;
-PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV;
-PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV;
-PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV;
-PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV;
-PFNGLGENFENCESNVPROC glad_glGenFencesNV;
-PFNGLISFENCENVPROC glad_glIsFenceNV;
-PFNGLTESTFENCENVPROC glad_glTestFenceNV;
-PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV;
-PFNGLFINISHFENCENVPROC glad_glFinishFenceNV;
-PFNGLSETFENCENVPROC glad_glSetFenceNV;
-PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV;
-PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV;
-PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV;
-PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV;
-PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV;
-PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV;
-PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV;
-PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV;
-PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV;
-PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV;
-PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV;
-PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV;
-PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT;
-PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT;
-PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV;
-PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV;
-PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV;
-PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV;
-PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV;
-PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV;
-PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV;
-PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV;
-PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV;
-PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV;
-PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV;
-PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV;
-PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV;
-PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV;
-PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV;
-PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV;
-PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV;
-PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV;
-PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV;
-PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV;
-PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV;
-PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV;
-PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV;
-PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV;
-PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV;
-PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV;
-PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV;
-PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV;
-PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV;
-PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV;
-PFNGLVERTEX2HNVPROC glad_glVertex2hNV;
-PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV;
-PFNGLVERTEX3HNVPROC glad_glVertex3hNV;
-PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV;
-PFNGLVERTEX4HNVPROC glad_glVertex4hNV;
-PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV;
-PFNGLNORMAL3HNVPROC glad_glNormal3hNV;
-PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV;
-PFNGLCOLOR3HNVPROC glad_glColor3hNV;
-PFNGLCOLOR3HVNVPROC glad_glColor3hvNV;
-PFNGLCOLOR4HNVPROC glad_glColor4hNV;
-PFNGLCOLOR4HVNVPROC glad_glColor4hvNV;
-PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV;
-PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV;
-PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV;
-PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV;
-PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV;
-PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV;
-PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV;
-PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV;
-PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV;
-PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV;
-PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV;
-PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV;
-PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV;
-PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV;
-PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV;
-PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV;
-PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV;
-PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV;
-PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV;
-PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV;
-PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV;
-PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV;
-PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV;
-PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV;
-PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV;
-PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV;
-PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV;
-PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV;
-PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV;
-PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV;
-PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV;
-PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV;
-PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV;
-PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV;
-PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV;
-PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV;
-PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV;
-PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV;
-PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV;
-PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV;
-PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV;
-PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV;
-PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV;
-PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV;
-PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV;
-PFNGLGENPATHSNVPROC glad_glGenPathsNV;
-PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV;
-PFNGLISPATHNVPROC glad_glIsPathNV;
-PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV;
-PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV;
-PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV;
-PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV;
-PFNGLPATHSTRINGNVPROC glad_glPathStringNV;
-PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV;
-PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV;
-PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV;
-PFNGLCOPYPATHNVPROC glad_glCopyPathNV;
-PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV;
-PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV;
-PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV;
-PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV;
-PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV;
-PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV;
-PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV;
-PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV;
-PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV;
-PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV;
-PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV;
-PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV;
-PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV;
-PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV;
-PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV;
-PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV;
-PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV;
-PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV;
-PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV;
-PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV;
-PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV;
-PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV;
-PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV;
-PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV;
-PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV;
-PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV;
-PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV;
-PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV;
-PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV;
-PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV;
-PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV;
-PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV;
-PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV;
-PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV;
-PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV;
-PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV;
-PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV;
-PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV;
-PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV;
-PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV;
-PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV;
-PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV;
-PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV;
-PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV;
-PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV;
-PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV;
-PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV;
-PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV;
-PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV;
-PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV;
-PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV;
-PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV;
-PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV;
-PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV;
-PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV;
-PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV;
-PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV;
-PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV;
-PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV;
-PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV;
-PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV;
-PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV;
-PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV;
-PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV;
-PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV;
-PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV;
-PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV;
-PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV;
-PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV;
-PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV;
-PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV;
-PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV;
-PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV;
-PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV;
-PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV;
-PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV;
-PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV;
-PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV;
-PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV;
-PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV;
-PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV;
-PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV;
-PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV;
-PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV;
-PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV;
-PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV;
-PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV;
-PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV;
-PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV;
-PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV;
-PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV;
-PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV;
-PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV;
-PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV;
-PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV;
-PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV;
-PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV;
-PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV;
-PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV;
-PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV;
-PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV;
-PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV;
-PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV;
-PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV;
-PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV;
-PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV;
-PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV;
-PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV;
-PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV;
-PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV;
-PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV;
-PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV;
-PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV;
-PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV;
-PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV;
-PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV;
-PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV;
-PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV;
-PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV;
-PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV;
-PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV;
-PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV;
-PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV;
-PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV;
-PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV;
-PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV;
-PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV;
-PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV;
-PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV;
-PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV;
-PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV;
-PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV;
-PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV;
-PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV;
-PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV;
-PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV;
-PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV;
-PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV;
-PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV;
-PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV;
-PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV;
-PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV;
-PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV;
-PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV;
-PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV;
-PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV;
-PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV;
-PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV;
-PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV;
-PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV;
-PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV;
-PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV;
-PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV;
-PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV;
-PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV;
-PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV;
-PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV;
-PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV;
-PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV;
-PFNGLCOLORFORMATNVPROC glad_glColorFormatNV;
-PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV;
-PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV;
-PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV;
-PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV;
-PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV;
-PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV;
-PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV;
-PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV;
-PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV;
-PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV;
-PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV;
-PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV;
-PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV;
-PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV;
-PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV;
-PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV;
-PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV;
-PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV;
-PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV;
-PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV;
-PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV;
-PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV;
-PFNGLISPROGRAMNVPROC glad_glIsProgramNV;
-PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV;
-PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV;
-PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV;
-PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV;
-PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV;
-PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV;
-PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV;
-PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV;
-PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV;
-PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV;
-PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV;
-PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV;
-PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV;
-PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV;
-PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV;
-PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV;
-PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV;
-PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV;
-PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV;
-PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV;
-PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV;
-PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV;
-PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV;
-PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV;
-PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV;
-PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV;
-PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV;
-PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV;
-PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV;
-PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV;
-PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV;
-PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV;
-PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV;
-PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV;
-PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV;
-PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV;
-PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV;
-PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV;
-PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV;
-PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV;
-PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV;
-PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV;
-PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV;
-PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV;
-PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV;
-PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV;
-PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV;
-PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV;
-PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV;
-PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT;
-PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT;
-PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT;
-PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT;
-PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT;
-PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT;
-PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT;
-PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT;
-PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT;
-PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT;
-PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT;
-PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT;
-PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT;
-PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT;
-PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT;
-PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT;
-PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT;
-PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT;
-PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT;
-PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT;
-PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT;
-PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT;
-PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT;
-PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV;
-PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV;
-PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV;
-PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV;
-PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV;
-PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV;
-PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV;
-PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV;
-PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV;
-PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV;
-PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV;
-PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV;
-PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV;
-PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES;
-PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES;
-PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES;
-PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES;
-PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES;
-PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES;
-PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES;
-PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES;
-PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES;
-PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES;
-PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES;
-PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES;
-PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES;
-PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES;
-PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES;
-PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES;
-PFNGLVERTEX2BOESPROC glad_glVertex2bOES;
-PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES;
-PFNGLVERTEX3BOESPROC glad_glVertex3bOES;
-PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES;
-PFNGLVERTEX4BOESPROC glad_glVertex4bOES;
-PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES;
-PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES;
-PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES;
-PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES;
-PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES;
-PFNGLCOLOR4XOESPROC glad_glColor4xOES;
-PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES;
-PFNGLFOGXOESPROC glad_glFogxOES;
-PFNGLFOGXVOESPROC glad_glFogxvOES;
-PFNGLFRUSTUMXOESPROC glad_glFrustumxOES;
-PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES;
-PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES;
-PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES;
-PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES;
-PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES;
-PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES;
-PFNGLLIGHTXOESPROC glad_glLightxOES;
-PFNGLLIGHTXVOESPROC glad_glLightxvOES;
-PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES;
-PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES;
-PFNGLMATERIALXOESPROC glad_glMaterialxOES;
-PFNGLMATERIALXVOESPROC glad_glMaterialxvOES;
-PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES;
-PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES;
-PFNGLNORMAL3XOESPROC glad_glNormal3xOES;
-PFNGLORTHOXOESPROC glad_glOrthoxOES;
-PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES;
-PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES;
-PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES;
-PFNGLROTATEXOESPROC glad_glRotatexOES;
-PFNGLSCALEXOESPROC glad_glScalexOES;
-PFNGLTEXENVXOESPROC glad_glTexEnvxOES;
-PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES;
-PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES;
-PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES;
-PFNGLTRANSLATEXOESPROC glad_glTranslatexOES;
-PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES;
-PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES;
-PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES;
-PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES;
-PFNGLACCUMXOESPROC glad_glAccumxOES;
-PFNGLBITMAPXOESPROC glad_glBitmapxOES;
-PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES;
-PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES;
-PFNGLCOLOR3XOESPROC glad_glColor3xOES;
-PFNGLCOLOR3XVOESPROC glad_glColor3xvOES;
-PFNGLCOLOR4XVOESPROC glad_glColor4xvOES;
-PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES;
-PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES;
-PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES;
-PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES;
-PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES;
-PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES;
-PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES;
-PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES;
-PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES;
-PFNGLGETLIGHTXOESPROC glad_glGetLightxOES;
-PFNGLGETMAPXVOESPROC glad_glGetMapxvOES;
-PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES;
-PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv;
-PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES;
-PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES;
-PFNGLINDEXXOESPROC glad_glIndexxOES;
-PFNGLINDEXXVOESPROC glad_glIndexxvOES;
-PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES;
-PFNGLMAP1XOESPROC glad_glMap1xOES;
-PFNGLMAP2XOESPROC glad_glMap2xOES;
-PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES;
-PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES;
-PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES;
-PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES;
-PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES;
-PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES;
-PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES;
-PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES;
-PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES;
-PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES;
-PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES;
-PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES;
-PFNGLPIXELMAPXPROC glad_glPixelMapx;
-PFNGLPIXELSTOREXPROC glad_glPixelStorex;
-PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES;
-PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES;
-PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES;
-PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES;
-PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES;
-PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES;
-PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES;
-PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES;
-PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES;
-PFNGLRECTXOESPROC glad_glRectxOES;
-PFNGLRECTXVOESPROC glad_glRectxvOES;
-PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES;
-PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES;
-PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES;
-PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES;
-PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES;
-PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES;
-PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES;
-PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES;
-PFNGLTEXGENXOESPROC glad_glTexGenxOES;
-PFNGLTEXGENXVOESPROC glad_glTexGenxvOES;
-PFNGLVERTEX2XOESPROC glad_glVertex2xOES;
-PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES;
-PFNGLVERTEX3XOESPROC glad_glVertex3xOES;
-PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES;
-PFNGLVERTEX4XOESPROC glad_glVertex4xOES;
-PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES;
-PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES;
-PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES;
-PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES;
-PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES;
-PFNGLFRUSTUMFOESPROC glad_glFrustumfOES;
-PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES;
-PFNGLORTHOFOESPROC glad_glOrthofOES;
-PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR;
-PFNGLHINTPGIPROC glad_glHintPGI;
-PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS;
-PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS;
-PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS;
-PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS;
-PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS;
-PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS;
-PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS;
-PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS;
-PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS;
-PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS;
-PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS;
-PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS;
-PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS;
-PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS;
-PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS;
-PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS;
-PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS;
-PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS;
-PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS;
-PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS;
-PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS;
-PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX;
-PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX;
-PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX;
-PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX;
-PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX;
-PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX;
-PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX;
-PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX;
-PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX;
-PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX;
-PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX;
-PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX;
-PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX;
-PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX;
-PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX;
-PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX;
-PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX;
-PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX;
-PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX;
-PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX;
-PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX;
-PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX;
-PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX;
-PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX;
-PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX;
-PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX;
-PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX;
-PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX;
-PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX;
-PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX;
-PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX;
-PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX;
-PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX;
-PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX;
-PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX;
-PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX;
-PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX;
-PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX;
-PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX;
-PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX;
-PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX;
-PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX;
-PFNGLDEFORMSGIXPROC glad_glDeformSGIX;
-PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX;
-PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX;
-PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX;
-PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX;
-PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX;
-PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX;
-PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX;
-PFNGLCOLORTABLESGIPROC glad_glColorTableSGI;
-PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI;
-PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI;
-PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI;
-PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI;
-PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI;
-PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI;
-PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX;
-PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN;
-PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN;
-PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN;
-PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN;
-PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN;
-PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN;
-PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN;
-PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN;
-PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN;
-PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN;
-PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN;
-PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN;
-PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN;
-PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN;
-PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN;
-PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN;
-PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN;
-PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN;
-PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN;
-PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN;
-PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN;
-PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN;
-PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN;
-PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN;
-PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN;
-PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN;
-PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN;
-PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN;
-PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN;
-PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN;
-PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN;
-PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN;
-PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN;
-PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN;
-PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN;
-PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN;
-PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN;
-PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN;
-PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN;
-PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN;
-PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN;
-PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN;
-PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN;
-PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN;
-PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN;
-PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN;
-PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN;
-PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN;
-PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN;
-PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN;
-PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN;
+int GLAD_GL_VERSION_1_0 = 0;
+int GLAD_GL_VERSION_1_1 = 0;
+int GLAD_GL_VERSION_1_2 = 0;
+int GLAD_GL_VERSION_1_3 = 0;
+int GLAD_GL_VERSION_1_4 = 0;
+int GLAD_GL_VERSION_1_5 = 0;
+int GLAD_GL_VERSION_2_0 = 0;
+int GLAD_GL_VERSION_2_1 = 0;
+int GLAD_GL_VERSION_3_0 = 0;
+int GLAD_GL_VERSION_3_1 = 0;
+int GLAD_GL_VERSION_3_2 = 0;
+int GLAD_GL_VERSION_3_3 = 0;
+PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL;
+PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL;
+PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL;
+PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL;
+PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL;
+PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
+PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
+PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL;
+PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
+PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
+PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL;
+PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL;
+PFNGLENABLEIPROC glad_glEnablei = NULL;
+PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL;
+PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
+PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
+PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL;
+PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
+PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
+PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
+PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
+PFNGLHINTPROC glad_glHint = NULL;
+PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL;
+PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL;
+PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL;
+PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
+PFNGLPOINTSIZEPROC glad_glPointSize = NULL;
+PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL;
+PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
+PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL;
+PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
+PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
+PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
+PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
+PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL;
+PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
+PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL;
+PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
+PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL;
+PFNGLCOLORMASKIPROC glad_glColorMaski = NULL;
+PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL;
+PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
+PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL;
+PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL;
+PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL;
+PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL;
+PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
+PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL;
+PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
+PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
+PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL;
+PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL;
+PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL;
+PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL;
+PFNGLCLEARPROC glad_glClear = NULL;
+PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL;
+PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
+PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
+PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL;
+PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
+PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL;
+PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
+PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL;
+PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL;
+PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
+PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
+PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
+PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
+PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
+PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL;
+PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL;
+PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
+PFNGLISSHADERPROC glad_glIsShader = NULL;
+PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL;
+PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL;
+PFNGLENABLEPROC glad_glEnable = NULL;
+PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL;
+PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
+PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL;
+PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL;
+PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL;
+PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
+PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
+PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
+PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
+PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
+PFNGLFLUSHPROC glad_glFlush = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
+PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
+PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL;
+PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL;
+PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL;
+PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL;
+PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL;
+PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
+PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
+PFNGLCLAMPCOLORPROC glad_glClampColor = NULL;
+PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
+PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
+PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL;
+PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
+PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL;
+PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL;
+PFNGLISSYNCPROC glad_glIsSync = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL;
+PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
+PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
+PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL;
+PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
+PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
+PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
+PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL;
+PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
+PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
+PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL;
+PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
+PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
+PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL;
+PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL;
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL;
+PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
+PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
+PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL;
+PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
+PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL;
+PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
+PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL;
+PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL;
+PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
+PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL;
+PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
+PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
+PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL;
+PFNGLDELETESYNCPROC glad_glDeleteSync = NULL;
+PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
+PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
+PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL;
+PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
+PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
+PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL;
+PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL;
+PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
+PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
+PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
+PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
+PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL;
+PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL;
+PFNGLFINISHPROC glad_glFinish = NULL;
+PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
+PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL;
+PFNGLVIEWPORTPROC glad_glViewport = NULL;
+PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
+PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL;
+PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL;
+PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL;
+PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL;
+PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
+PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
+PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
+PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL;
+PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
+PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
+PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL;
+PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL;
+PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL;
+PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL;
+PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
+PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
+PFNGLGETSTRINGPROC glad_glGetString = NULL;
+PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL;
+PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
+PFNGLENDQUERYPROC glad_glEndQuery = NULL;
+PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL;
+PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL;
+PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
+PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
+PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL;
+PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL;
+PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
+PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL;
+PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
+PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL;
+PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL;
+PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
+PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL;
+PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL;
+PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
+PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL;
+PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
+PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
+PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
+PFNGLDISABLEPROC glad_glDisable = NULL;
+PFNGLLOGICOPPROC glad_glLogicOp = NULL;
+PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL;
+PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
+PFNGLCULLFACEPROC glad_glCullFace = NULL;
+PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
+PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
+PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL;
+PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL;
+PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
+PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL;
+PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
+PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL;
+PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
+PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL;
+PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
+PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
+PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL;
+PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
+PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL;
+PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL;
+PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
+PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL;
+PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
+PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL;
+PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL;
+PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
+PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL;
+PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
+PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL;
+PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
+PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
+PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
+PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
+PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL;
+PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
+PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
+PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
+PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL;
+PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL;
+PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL;
+PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
+PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL;
+PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL;
+PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
+PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL;
+PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
+PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL;
+PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
+PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
+PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL;
+PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL;
+PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
+PFNGLSCISSORPROC glad_glScissor = NULL;
+PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL;
+PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
+PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL;
+PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL;
+PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
+PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL;
+PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL;
+PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL;
+PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL;
+PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL;
+PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL;
+PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL;
+PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL;
+PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
+PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL;
+PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
+PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
+PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
+PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL;
+PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
+PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL;
+PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
+PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL;
+PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
+PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL;
+PFNGLCOLORMASKPROC glad_glColorMask = NULL;
+PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL;
+PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
+PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
+PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL;
+PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
+PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL;
+PFNGLISSAMPLERPROC glad_glIsSampler = NULL;
+PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL;
+PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
+PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL;
+PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
+PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL;
+PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL;
+PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
+PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
+PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL;
+PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
+PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL;
+PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
+PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
+PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL;
+PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL;
+PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL;
+PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL;
+PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL;
+PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL;
+PFNGLDISABLEIPROC glad_glDisablei = NULL;
+PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
+PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
+PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL;
+PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
+PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL;
+PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
+PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
+PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
+PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
+PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
+PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
+PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL;
+PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL;
+PFNGLGETERRORPROC glad_glGetError = NULL;
+PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL;
+PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
+PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL;
+PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
+PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL;
+PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL;
+PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL;
+PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL;
+PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
+PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL;
+PFNGLISQUERYPROC glad_glIsQuery = NULL;
+PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL;
+PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
+PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
+PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL;
+PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
+PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
+PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL;
+PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
+PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL;
+PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
+PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL;
+PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL;
+PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
+PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL;
+PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL;
+PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
+PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL;
+PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
+PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
+int GLAD_GL_SGIX_pixel_tiles = 0;
+int GLAD_GL_EXT_post_depth_coverage = 0;
+int GLAD_GL_APPLE_element_array = 0;
+int GLAD_GL_AMD_multi_draw_indirect = 0;
+int GLAD_GL_EXT_blend_subtract = 0;
+int GLAD_GL_SGIX_tag_sample_buffer = 0;
+int GLAD_GL_NV_point_sprite = 0;
+int GLAD_GL_IBM_texture_mirrored_repeat = 0;
+int GLAD_GL_APPLE_transform_hint = 0;
+int GLAD_GL_ATI_separate_stencil = 0;
+int GLAD_GL_NV_shader_atomic_int64 = 0;
+int GLAD_GL_EXT_semaphore_win32 = 0;
+int GLAD_GL_NV_vertex_program2_option = 0;
+int GLAD_GL_EXT_texture_buffer_object = 0;
+int GLAD_GL_ARB_vertex_blend = 0;
+int GLAD_GL_OVR_multiview = 0;
+int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = 0;
+int GLAD_GL_NV_vertex_program2 = 0;
+int GLAD_GL_ARB_program_interface_query = 0;
+int GLAD_GL_EXT_misc_attribute = 0;
+int GLAD_GL_NV_multisample_coverage = 0;
+int GLAD_GL_ARB_shading_language_packing = 0;
+int GLAD_GL_EXT_texture_cube_map = 0;
+int GLAD_GL_NV_viewport_array2 = 0;
+int GLAD_GL_ARB_texture_stencil8 = 0;
+int GLAD_GL_EXT_index_func = 0;
+int GLAD_GL_EXT_memory_object_fd = 0;
+int GLAD_GL_OES_compressed_paletted_texture = 0;
+int GLAD_GL_MESA_shader_integer_functions = 0;
+int GLAD_GL_NV_shader_buffer_load = 0;
+int GLAD_GL_EXT_color_subtable = 0;
+int GLAD_GL_SUNX_constant_data = 0;
+int GLAD_GL_EXT_texture_compression_s3tc = 0;
+int GLAD_GL_EXT_multi_draw_arrays = 0;
+int GLAD_GL_ARB_shader_atomic_counters = 0;
+int GLAD_GL_ARB_arrays_of_arrays = 0;
+int GLAD_GL_NV_conditional_render = 0;
+int GLAD_GL_EXT_texture_env_combine = 0;
+int GLAD_GL_NV_fog_distance = 0;
+int GLAD_GL_SGIX_async_histogram = 0;
+int GLAD_GL_MESA_resize_buffers = 0;
+int GLAD_GL_NV_light_max_exponent = 0;
+int GLAD_GL_NV_texture_env_combine4 = 0;
+int GLAD_GL_ARB_spirv_extensions = 0;
+int GLAD_GL_ARB_texture_view = 0;
+int GLAD_GL_ARB_texture_env_combine = 0;
+int GLAD_GL_ARB_map_buffer_range = 0;
+int GLAD_GL_EXT_convolution = 0;
+int GLAD_GL_NV_compute_program5 = 0;
+int GLAD_GL_NV_vertex_attrib_integer_64bit = 0;
+int GLAD_GL_EXT_paletted_texture = 0;
+int GLAD_GL_ARB_texture_buffer_object = 0;
+int GLAD_GL_ATI_pn_triangles = 0;
+int GLAD_GL_SGIX_resample = 0;
+int GLAD_GL_SGIX_flush_raster = 0;
+int GLAD_GL_EXT_light_texture = 0;
+int GLAD_GL_ARB_point_sprite = 0;
+int GLAD_GL_SUN_convolution_border_modes = 0;
+int GLAD_GL_EXT_semaphore_fd = 0;
+int GLAD_GL_NV_parameter_buffer_object2 = 0;
+int GLAD_GL_ARB_half_float_pixel = 0;
+int GLAD_GL_NV_tessellation_program5 = 0;
+int GLAD_GL_REND_screen_coordinates = 0;
+int GLAD_GL_EXT_shared_texture_palette = 0;
+int GLAD_GL_EXT_packed_float = 0;
+int GLAD_GL_OML_subsample = 0;
+int GLAD_GL_SGIX_vertex_preclip = 0;
+int GLAD_GL_SGIX_texture_scale_bias = 0;
+int GLAD_GL_AMD_draw_buffers_blend = 0;
+int GLAD_GL_APPLE_texture_range = 0;
+int GLAD_GL_EXT_texture_array = 0;
+int GLAD_GL_NV_texture_barrier = 0;
+int GLAD_GL_ARB_texture_query_levels = 0;
+int GLAD_GL_NV_texgen_emboss = 0;
+int GLAD_GL_EXT_texture_swizzle = 0;
+int GLAD_GL_ARB_texture_rg = 0;
+int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0;
+int GLAD_GL_ARB_fragment_shader = 0;
+int GLAD_GL_3DFX_tbuffer = 0;
+int GLAD_GL_GREMEDY_frame_terminator = 0;
+int GLAD_GL_IBM_cull_vertex = 0;
+int GLAD_GL_EXT_separate_shader_objects = 0;
+int GLAD_GL_NV_texture_multisample = 0;
+int GLAD_GL_ARB_shader_objects = 0;
+int GLAD_GL_ARB_framebuffer_object = 0;
+int GLAD_GL_EXT_external_buffer = 0;
+int GLAD_GL_ATI_envmap_bumpmap = 0;
+int GLAD_GL_AMD_shader_explicit_vertex_parameter = 0;
+int GLAD_GL_ARB_robust_buffer_access_behavior = 0;
+int GLAD_GL_ARB_shader_stencil_export = 0;
+int GLAD_GL_NV_texture_rectangle = 0;
+int GLAD_GL_ARB_enhanced_layouts = 0;
+int GLAD_GL_ARB_texture_rectangle = 0;
+int GLAD_GL_SGI_texture_color_table = 0;
+int GLAD_GL_NV_viewport_swizzle = 0;
+int GLAD_GL_ATI_map_object_buffer = 0;
+int GLAD_GL_ARB_robustness = 0;
+int GLAD_GL_NV_pixel_data_range = 0;
+int GLAD_GL_EXT_framebuffer_blit = 0;
+int GLAD_GL_ARB_gpu_shader_fp64 = 0;
+int GLAD_GL_NV_command_list = 0;
+int GLAD_GL_SGIX_depth_texture = 0;
+int GLAD_GL_AMD_framebuffer_sample_positions = 0;
+int GLAD_GL_GREMEDY_string_marker = 0;
+int GLAD_GL_ARB_texture_compression_bptc = 0;
+int GLAD_GL_EXT_subtexture = 0;
+int GLAD_GL_EXT_pixel_transform_color_table = 0;
+int GLAD_GL_EXT_texture_compression_rgtc = 0;
+int GLAD_GL_ARB_shader_atomic_counter_ops = 0;
+int GLAD_GL_SGIX_depth_pass_instrument = 0;
+int GLAD_GL_EXT_gpu_program_parameters = 0;
+int GLAD_GL_NV_evaluators = 0;
+int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = 0;
+int GLAD_GL_SGIS_texture_filter4 = 0;
+int GLAD_GL_AMD_performance_monitor = 0;
+int GLAD_GL_NV_geometry_shader4 = 0;
+int GLAD_GL_EXT_stencil_clear_tag = 0;
+int GLAD_GL_NV_vertex_program1_1 = 0;
+int GLAD_GL_NV_present_video = 0;
+int GLAD_GL_ARB_texture_compression_rgtc = 0;
+int GLAD_GL_HP_convolution_border_modes = 0;
+int GLAD_GL_EXT_shader_integer_mix = 0;
+int GLAD_GL_SGIX_framezoom = 0;
+int GLAD_GL_ARB_stencil_texturing = 0;
+int GLAD_GL_ARB_shader_clock = 0;
+int GLAD_GL_NV_shader_atomic_fp16_vector = 0;
+int GLAD_GL_SGIX_fog_offset = 0;
+int GLAD_GL_ARB_draw_elements_base_vertex = 0;
+int GLAD_GL_INGR_interlace_read = 0;
+int GLAD_GL_NV_transform_feedback = 0;
+int GLAD_GL_NV_fragment_program = 0;
+int GLAD_GL_AMD_stencil_operation_extended = 0;
+int GLAD_GL_ARB_seamless_cubemap_per_texture = 0;
+int GLAD_GL_ARB_instanced_arrays = 0;
+int GLAD_GL_ARB_get_texture_sub_image = 0;
+int GLAD_GL_NV_vertex_array_range2 = 0;
+int GLAD_GL_KHR_robustness = 0;
+int GLAD_GL_AMD_sparse_texture = 0;
+int GLAD_GL_ARB_clip_control = 0;
+int GLAD_GL_NV_fragment_coverage_to_color = 0;
+int GLAD_GL_NV_fence = 0;
+int GLAD_GL_ARB_texture_buffer_range = 0;
+int GLAD_GL_SUN_mesh_array = 0;
+int GLAD_GL_ARB_vertex_attrib_binding = 0;
+int GLAD_GL_ARB_framebuffer_no_attachments = 0;
+int GLAD_GL_ARB_cl_event = 0;
+int GLAD_GL_EXT_vertex_weighting = 0;
+int GLAD_GL_ARB_derivative_control = 0;
+int GLAD_GL_NV_packed_depth_stencil = 0;
+int GLAD_GL_OES_single_precision = 0;
+int GLAD_GL_NV_primitive_restart = 0;
+int GLAD_GL_SUN_global_alpha = 0;
+int GLAD_GL_ARB_fragment_shader_interlock = 0;
+int GLAD_GL_EXT_texture_object = 0;
+int GLAD_GL_AMD_name_gen_delete = 0;
+int GLAD_GL_NV_texture_compression_vtc = 0;
+int GLAD_GL_NV_sample_mask_override_coverage = 0;
+int GLAD_GL_NV_texture_shader3 = 0;
+int GLAD_GL_MESA_tile_raster_order = 0;
+int GLAD_GL_ARB_texture_filter_anisotropic = 0;
+int GLAD_GL_EXT_texture = 0;
+int GLAD_GL_ARB_buffer_storage = 0;
+int GLAD_GL_AMD_shader_atomic_counter_ops = 0;
+int GLAD_GL_APPLE_vertex_program_evaluators = 0;
+int GLAD_GL_AMD_texture_gather_bias_lod = 0;
+int GLAD_GL_NV_texgen_reflection = 0;
+int GLAD_GL_ARB_explicit_uniform_location = 0;
+int GLAD_GL_ARB_depth_buffer_float = 0;
+int GLAD_GL_NV_path_rendering_shared_edge = 0;
+int GLAD_GL_SGIX_shadow_ambient = 0;
+int GLAD_GL_ARB_texture_cube_map = 0;
+int GLAD_GL_AMD_vertex_shader_viewport_index = 0;
+int GLAD_GL_SGIX_list_priority = 0;
+int GLAD_GL_NV_vertex_buffer_unified_memory = 0;
+int GLAD_GL_NV_uniform_buffer_unified_memory = 0;
+int GLAD_GL_ARB_clear_texture = 0;
+int GLAD_GL_ATI_texture_env_combine3 = 0;
+int GLAD_GL_NV_depth_clamp = 0;
+int GLAD_GL_ARB_map_buffer_alignment = 0;
+int GLAD_GL_EXT_memory_object = 0;
+int GLAD_GL_NV_blend_equation_advanced = 0;
+int GLAD_GL_SGIS_sharpen_texture = 0;
+int GLAD_GL_KHR_robust_buffer_access_behavior = 0;
+int GLAD_GL_ARB_pipeline_statistics_query = 0;
+int GLAD_GL_ARB_vertex_program = 0;
+int GLAD_GL_ARB_texture_rgb10_a2ui = 0;
+int GLAD_GL_OML_interlace = 0;
+int GLAD_GL_ATI_pixel_format_float = 0;
+int GLAD_GL_NV_clip_space_w_scaling = 0;
+int GLAD_GL_ARB_vertex_buffer_object = 0;
+int GLAD_GL_EXT_shadow_funcs = 0;
+int GLAD_GL_ATI_text_fragment_shader = 0;
+int GLAD_GL_NV_vertex_array_range = 0;
+int GLAD_GL_SGIX_fragment_lighting = 0;
+int GLAD_GL_AMD_shader_ballot = 0;
+int GLAD_GL_NV_texture_expand_normal = 0;
+int GLAD_GL_NV_framebuffer_multisample_coverage = 0;
+int GLAD_GL_EXT_timer_query = 0;
+int GLAD_GL_EXT_vertex_array_bgra = 0;
+int GLAD_GL_NV_bindless_texture = 0;
+int GLAD_GL_KHR_debug = 0;
+int GLAD_GL_SGIS_texture_border_clamp = 0;
+int GLAD_GL_ATI_vertex_attrib_array_object = 0;
+int GLAD_GL_SGIX_clipmap = 0;
+int GLAD_GL_EXT_geometry_shader4 = 0;
+int GLAD_GL_ARB_shader_texture_image_samples = 0;
+int GLAD_GL_MESA_ycbcr_texture = 0;
+int GLAD_GL_MESAX_texture_stack = 0;
+int GLAD_GL_AMD_seamless_cubemap_per_texture = 0;
+int GLAD_GL_EXT_bindable_uniform = 0;
+int GLAD_GL_KHR_texture_compression_astc_hdr = 0;
+int GLAD_GL_ARB_shader_ballot = 0;
+int GLAD_GL_KHR_blend_equation_advanced = 0;
+int GLAD_GL_ARB_fragment_program_shadow = 0;
+int GLAD_GL_ATI_element_array = 0;
+int GLAD_GL_AMD_texture_texture4 = 0;
+int GLAD_GL_SGIX_reference_plane = 0;
+int GLAD_GL_EXT_stencil_two_side = 0;
+int GLAD_GL_ARB_transform_feedback_overflow_query = 0;
+int GLAD_GL_SGIX_texture_lod_bias = 0;
+int GLAD_GL_KHR_no_error = 0;
+int GLAD_GL_NV_explicit_multisample = 0;
+int GLAD_GL_NV_stereo_view_rendering = 0;
+int GLAD_GL_IBM_static_data = 0;
+int GLAD_GL_EXT_clip_volume_hint = 0;
+int GLAD_GL_EXT_texture_perturb_normal = 0;
+int GLAD_GL_NV_fragment_program2 = 0;
+int GLAD_GL_NV_fragment_program4 = 0;
+int GLAD_GL_EXT_point_parameters = 0;
+int GLAD_GL_PGI_misc_hints = 0;
+int GLAD_GL_EXT_EGL_image_storage = 0;
+int GLAD_GL_SGIX_subsample = 0;
+int GLAD_GL_AMD_shader_stencil_export = 0;
+int GLAD_GL_ARB_shader_texture_lod = 0;
+int GLAD_GL_ARB_vertex_shader = 0;
+int GLAD_GL_ARB_depth_clamp = 0;
+int GLAD_GL_SGIS_texture_select = 0;
+int GLAD_GL_NV_texture_shader = 0;
+int GLAD_GL_ARB_tessellation_shader = 0;
+int GLAD_GL_EXT_draw_buffers2 = 0;
+int GLAD_GL_ARB_vertex_attrib_64bit = 0;
+int GLAD_GL_EXT_texture_filter_minmax = 0;
+int GLAD_GL_NV_query_resource = 0;
+int GLAD_GL_AMD_interleaved_elements = 0;
+int GLAD_GL_ARB_fragment_program = 0;
+int GLAD_GL_OML_resample = 0;
+int GLAD_GL_APPLE_ycbcr_422 = 0;
+int GLAD_GL_SGIX_texture_add_env = 0;
+int GLAD_GL_ARB_shadow_ambient = 0;
+int GLAD_GL_ARB_texture_storage = 0;
+int GLAD_GL_EXT_pixel_buffer_object = 0;
+int GLAD_GL_ARB_copy_image = 0;
+int GLAD_GL_SGIS_pixel_texture = 0;
+int GLAD_GL_SGIS_generate_mipmap = 0;
+int GLAD_GL_SGIX_instruments = 0;
+int GLAD_GL_ARB_fragment_layer_viewport = 0;
+int GLAD_GL_ARB_shader_storage_buffer_object = 0;
+int GLAD_GL_EXT_sparse_texture2 = 0;
+int GLAD_GL_EXT_blend_minmax = 0;
+int GLAD_GL_MESA_pack_invert = 0;
+int GLAD_GL_ARB_base_instance = 0;
+int GLAD_GL_SGIX_convolution_accuracy = 0;
+int GLAD_GL_PGI_vertex_hints = 0;
+int GLAD_GL_AMD_transform_feedback4 = 0;
+int GLAD_GL_ARB_ES3_1_compatibility = 0;
+int GLAD_GL_EXT_memory_object_win32 = 0;
+int GLAD_GL_EXT_texture_integer = 0;
+int GLAD_GL_ARB_texture_multisample = 0;
+int GLAD_GL_ATI_vertex_streams = 0;
+int GLAD_GL_AMD_gpu_shader_int64 = 0;
+int GLAD_GL_S3_s3tc = 0;
+int GLAD_GL_ARB_query_buffer_object = 0;
+int GLAD_GL_AMD_vertex_shader_tessellator = 0;
+int GLAD_GL_ARB_invalidate_subdata = 0;
+int GLAD_GL_NV_draw_vulkan_image = 0;
+int GLAD_GL_EXT_index_material = 0;
+int GLAD_GL_NVX_linked_gpu_multicast = 0;
+int GLAD_GL_NV_blend_equation_advanced_coherent = 0;
+int GLAD_GL_KHR_texture_compression_astc_sliced_3d = 0;
+int GLAD_GL_INTEL_parallel_arrays = 0;
+int GLAD_GL_ATI_draw_buffers = 0;
+int GLAD_GL_WIN_specular_fog = 0;
+int GLAD_GL_EXT_cmyka = 0;
+int GLAD_GL_SGIX_pixel_texture = 0;
+int GLAD_GL_APPLE_specular_vector = 0;
+int GLAD_GL_ARB_compatibility = 0;
+int GLAD_GL_ARB_timer_query = 0;
+int GLAD_GL_SGIX_interlace = 0;
+int GLAD_GL_NV_parameter_buffer_object = 0;
+int GLAD_GL_AMD_shader_trinary_minmax = 0;
+int GLAD_GL_ARB_direct_state_access = 0;
+int GLAD_GL_EXT_rescale_normal = 0;
+int GLAD_GL_ARB_pixel_buffer_object = 0;
+int GLAD_GL_ARB_uniform_buffer_object = 0;
+int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = 0;
+int GLAD_GL_ARB_texture_swizzle = 0;
+int GLAD_GL_NV_transform_feedback2 = 0;
+int GLAD_GL_SGIX_async_pixel = 0;
+int GLAD_GL_NV_fragment_program_option = 0;
+int GLAD_GL_ARB_explicit_attrib_location = 0;
+int GLAD_GL_EXT_blend_color = 0;
+int GLAD_GL_NV_shader_thread_group = 0;
+int GLAD_GL_EXT_stencil_wrap = 0;
+int GLAD_GL_EXT_index_array_formats = 0;
+int GLAD_GL_OVR_multiview2 = 0;
+int GLAD_GL_EXT_histogram = 0;
+int GLAD_GL_EXT_polygon_offset = 0;
+int GLAD_GL_SGIS_point_parameters = 0;
+int GLAD_GL_SGIX_ycrcb = 0;
+int GLAD_GL_EXT_direct_state_access = 0;
+int GLAD_GL_ARB_cull_distance = 0;
+int GLAD_GL_AMD_sample_positions = 0;
+int GLAD_GL_NV_vertex_program = 0;
+int GLAD_GL_NV_shader_thread_shuffle = 0;
+int GLAD_GL_ARB_shader_precision = 0;
+int GLAD_GL_EXT_vertex_shader = 0;
+int GLAD_GL_EXT_blend_func_separate = 0;
+int GLAD_GL_APPLE_fence = 0;
+int GLAD_GL_NV_query_resource_tag = 0;
+int GLAD_GL_OES_byte_coordinates = 0;
+int GLAD_GL_ARB_transpose_matrix = 0;
+int GLAD_GL_ARB_provoking_vertex = 0;
+int GLAD_GL_EXT_fog_coord = 0;
+int GLAD_GL_EXT_vertex_array = 0;
+int GLAD_GL_ARB_half_float_vertex = 0;
+int GLAD_GL_EXT_blend_equation_separate = 0;
+int GLAD_GL_NV_framebuffer_mixed_samples = 0;
+int GLAD_GL_NVX_conditional_render = 0;
+int GLAD_GL_ARB_multi_draw_indirect = 0;
+int GLAD_GL_EXT_raster_multisample = 0;
+int GLAD_GL_NV_copy_image = 0;
+int GLAD_GL_HP_texture_lighting = 0;
+int GLAD_GL_INTEL_framebuffer_CMAA = 0;
+int GLAD_GL_ARB_transform_feedback2 = 0;
+int GLAD_GL_ARB_transform_feedback3 = 0;
+int GLAD_GL_SGIX_ycrcba = 0;
+int GLAD_GL_EXT_debug_marker = 0;
+int GLAD_GL_EXT_bgra = 0;
+int GLAD_GL_ARB_sparse_texture_clamp = 0;
+int GLAD_GL_EXT_pixel_transform = 0;
+int GLAD_GL_ARB_conservative_depth = 0;
+int GLAD_GL_ATI_fragment_shader = 0;
+int GLAD_GL_ARB_vertex_array_object = 0;
+int GLAD_GL_SUN_triangle_list = 0;
+int GLAD_GL_EXT_texture_env_add = 0;
+int GLAD_GL_EXT_packed_depth_stencil = 0;
+int GLAD_GL_EXT_texture_mirror_clamp = 0;
+int GLAD_GL_NV_multisample_filter_hint = 0;
+int GLAD_GL_APPLE_float_pixels = 0;
+int GLAD_GL_ARB_transform_feedback_instanced = 0;
+int GLAD_GL_SGIX_async = 0;
+int GLAD_GL_EXT_texture_compression_latc = 0;
+int GLAD_GL_NV_robustness_video_memory_purge = 0;
+int GLAD_GL_ARB_shading_language_100 = 0;
+int GLAD_GL_INTEL_performance_query = 0;
+int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0;
+int GLAD_GL_NV_gpu_shader5 = 0;
+int GLAD_GL_NV_bindless_multi_draw_indirect_count = 0;
+int GLAD_GL_ARB_ES2_compatibility = 0;
+int GLAD_GL_ARB_indirect_parameters = 0;
+int GLAD_GL_EXT_window_rectangles = 0;
+int GLAD_GL_NV_half_float = 0;
+int GLAD_GL_ARB_ES3_2_compatibility = 0;
+int GLAD_GL_ATI_texture_mirror_once = 0;
+int GLAD_GL_IBM_rasterpos_clip = 0;
+int GLAD_GL_EXT_semaphore = 0;
+int GLAD_GL_SGIX_shadow = 0;
+int GLAD_GL_EXT_polygon_offset_clamp = 0;
+int GLAD_GL_NV_deep_texture3D = 0;
+int GLAD_GL_ARB_shader_draw_parameters = 0;
+int GLAD_GL_SGIX_calligraphic_fragment = 0;
+int GLAD_GL_ARB_shader_bit_encoding = 0;
+int GLAD_GL_EXT_compiled_vertex_array = 0;
+int GLAD_GL_NV_depth_buffer_float = 0;
+int GLAD_GL_NV_occlusion_query = 0;
+int GLAD_GL_APPLE_flush_buffer_range = 0;
+int GLAD_GL_ARB_imaging = 0;
+int GLAD_GL_NV_shader_atomic_float = 0;
+int GLAD_GL_ARB_draw_buffers_blend = 0;
+int GLAD_GL_AMD_gcn_shader = 0;
+int GLAD_GL_AMD_blend_minmax_factor = 0;
+int GLAD_GL_EXT_texture_sRGB_decode = 0;
+int GLAD_GL_ARB_shading_language_420pack = 0;
+int GLAD_GL_ARB_shader_viewport_layer_array = 0;
+int GLAD_GL_ATI_meminfo = 0;
+int GLAD_GL_EXT_abgr = 0;
+int GLAD_GL_AMD_pinned_memory = 0;
+int GLAD_GL_EXT_texture_snorm = 0;
+int GLAD_GL_SGIX_texture_coordinate_clamp = 0;
+int GLAD_GL_ARB_clear_buffer_object = 0;
+int GLAD_GL_ARB_multisample = 0;
+int GLAD_GL_EXT_debug_label = 0;
+int GLAD_GL_ARB_sample_shading = 0;
+int GLAD_GL_NV_internalformat_sample_query = 0;
+int GLAD_GL_INTEL_map_texture = 0;
+int GLAD_GL_ARB_texture_env_crossbar = 0;
+int GLAD_GL_EXT_422_pixels = 0;
+int GLAD_GL_NV_blend_minmax_factor = 0;
+int GLAD_GL_NV_conservative_raster_pre_snap_triangles = 0;
+int GLAD_GL_ARB_compute_shader = 0;
+int GLAD_GL_EXT_blend_logic_op = 0;
+int GLAD_GL_ARB_blend_func_extended = 0;
+int GLAD_GL_IBM_vertex_array_lists = 0;
+int GLAD_GL_ARB_color_buffer_float = 0;
+int GLAD_GL_ARB_bindless_texture = 0;
+int GLAD_GL_ARB_window_pos = 0;
+int GLAD_GL_ARB_internalformat_query = 0;
+int GLAD_GL_ARB_shadow = 0;
+int GLAD_GL_ARB_texture_mirrored_repeat = 0;
+int GLAD_GL_EXT_shader_image_load_store = 0;
+int GLAD_GL_EXT_copy_texture = 0;
+int GLAD_GL_NV_register_combiners2 = 0;
+int GLAD_GL_SGIX_ycrcb_subsample = 0;
+int GLAD_GL_NV_alpha_to_coverage_dither_control = 0;
+int GLAD_GL_SGIX_ir_instrument1 = 0;
+int GLAD_GL_NV_draw_texture = 0;
+int GLAD_GL_EXT_texture_shared_exponent = 0;
+int GLAD_GL_NV_texture_shader2 = 0;
+int GLAD_GL_EXT_draw_instanced = 0;
+int GLAD_GL_NV_copy_depth_to_color = 0;
+int GLAD_GL_ARB_viewport_array = 0;
+int GLAD_GL_ARB_separate_shader_objects = 0;
+int GLAD_GL_NV_conservative_raster_pre_snap = 0;
+int GLAD_GL_EXT_depth_bounds_test = 0;
+int GLAD_GL_HP_image_transform = 0;
+int GLAD_GL_ARB_texture_env_add = 0;
+int GLAD_GL_NV_video_capture = 0;
+int GLAD_GL_ARB_sampler_objects = 0;
+int GLAD_GL_ARB_matrix_palette = 0;
+int GLAD_GL_SGIS_texture_color_mask = 0;
+int GLAD_GL_EXT_packed_pixels = 0;
+int GLAD_GL_EXT_coordinate_frame = 0;
+int GLAD_GL_ARB_texture_compression = 0;
+int GLAD_GL_ARB_multi_bind = 0;
+int GLAD_GL_APPLE_aux_depth_stencil = 0;
+int GLAD_GL_ARB_shader_subroutine = 0;
+int GLAD_GL_EXT_framebuffer_sRGB = 0;
+int GLAD_GL_ARB_texture_storage_multisample = 0;
+int GLAD_GL_KHR_blend_equation_advanced_coherent = 0;
+int GLAD_GL_EXT_vertex_attrib_64bit = 0;
+int GLAD_GL_NV_shader_atomic_float64 = 0;
+int GLAD_GL_ARB_depth_texture = 0;
+int GLAD_GL_NV_shader_buffer_store = 0;
+int GLAD_GL_OES_query_matrix = 0;
+int GLAD_GL_MESA_window_pos = 0;
+int GLAD_GL_NV_fill_rectangle = 0;
+int GLAD_GL_NV_shader_storage_buffer_object = 0;
+int GLAD_GL_ARB_texture_query_lod = 0;
+int GLAD_GL_ARB_copy_buffer = 0;
+int GLAD_GL_ARB_shader_image_size = 0;
+int GLAD_GL_NV_shader_atomic_counters = 0;
+int GLAD_GL_APPLE_object_purgeable = 0;
+int GLAD_GL_ARB_occlusion_query = 0;
+int GLAD_GL_INGR_color_clamp = 0;
+int GLAD_GL_SGI_color_table = 0;
+int GLAD_GL_NV_gpu_program5_mem_extended = 0;
+int GLAD_GL_ARB_texture_cube_map_array = 0;
+int GLAD_GL_SGIX_scalebias_hint = 0;
+int GLAD_GL_EXT_gpu_shader4 = 0;
+int GLAD_GL_NV_geometry_program4 = 0;
+int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0;
+int GLAD_GL_AMD_debug_output = 0;
+int GLAD_GL_ARB_texture_border_clamp = 0;
+int GLAD_GL_EXT_win32_keyed_mutex = 0;
+int GLAD_GL_ARB_fragment_coord_conventions = 0;
+int GLAD_GL_ARB_multitexture = 0;
+int GLAD_GL_SGIX_polynomial_ffd = 0;
+int GLAD_GL_EXT_texture_env_dot3 = 0;
+int GLAD_GL_EXT_provoking_vertex = 0;
+int GLAD_GL_ARB_point_parameters = 0;
+int GLAD_GL_ARB_shader_image_load_store = 0;
+int GLAD_GL_ARB_conditional_render_inverted = 0;
+int GLAD_GL_HP_occlusion_test = 0;
+int GLAD_GL_ARB_ES3_compatibility = 0;
+int GLAD_GL_ARB_texture_barrier = 0;
+int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0;
+int GLAD_GL_NV_bindless_multi_draw_indirect = 0;
+int GLAD_GL_SGIX_texture_multi_buffer = 0;
+int GLAD_GL_INTEL_blackhole_render = 0;
+int GLAD_GL_AMD_shader_image_load_store_lod = 0;
+int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
+int GLAD_GL_3DFX_multisample = 0;
+int GLAD_GL_INTEL_fragment_shader_ordering = 0;
+int GLAD_GL_ARB_texture_env_dot3 = 0;
+int GLAD_GL_NV_gpu_program4 = 0;
+int GLAD_GL_NV_gpu_program5 = 0;
+int GLAD_GL_NV_float_buffer = 0;
+int GLAD_GL_SGIS_texture_edge_clamp = 0;
+int GLAD_GL_ARB_framebuffer_sRGB = 0;
+int GLAD_GL_SUN_slice_accum = 0;
+int GLAD_GL_EXT_index_texture = 0;
+int GLAD_GL_EXT_shader_image_load_formatted = 0;
+int GLAD_GL_ARB_geometry_shader4 = 0;
+int GLAD_GL_EXT_separate_specular_color = 0;
+int GLAD_GL_AMD_depth_clamp_separate = 0;
+int GLAD_GL_NV_conservative_raster = 0;
+int GLAD_GL_ARB_sparse_texture2 = 0;
+int GLAD_GL_SGIX_sprite = 0;
+int GLAD_GL_ARB_get_program_binary = 0;
+int GLAD_GL_AMD_occlusion_query_event = 0;
+int GLAD_GL_SGIS_multisample = 0;
+int GLAD_GL_EXT_framebuffer_object = 0;
+int GLAD_GL_ARB_robustness_isolation = 0;
+int GLAD_GL_ARB_vertex_array_bgra = 0;
+int GLAD_GL_APPLE_vertex_array_range = 0;
+int GLAD_GL_AMD_query_buffer_object = 0;
+int GLAD_GL_NV_register_combiners = 0;
+int GLAD_GL_ARB_draw_buffers = 0;
+int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = 0;
+int GLAD_GL_AMD_gpu_shader_int16 = 0;
+int GLAD_GL_ARB_debug_output = 0;
+int GLAD_GL_EXT_shader_framebuffer_fetch = 0;
+int GLAD_GL_SGI_color_matrix = 0;
+int GLAD_GL_EXT_cull_vertex = 0;
+int GLAD_GL_AMD_framebuffer_multisample_advanced = 0;
+int GLAD_GL_EXT_texture_sRGB = 0;
+int GLAD_GL_APPLE_row_bytes = 0;
+int GLAD_GL_NV_conservative_raster_underestimation = 0;
+int GLAD_GL_IBM_multimode_draw_arrays = 0;
+int GLAD_GL_KHR_parallel_shader_compile = 0;
+int GLAD_GL_APPLE_vertex_array_object = 0;
+int GLAD_GL_3DFX_texture_compression_FXT1 = 0;
+int GLAD_GL_NV_fragment_shader_interlock = 0;
+int GLAD_GL_AMD_conservative_depth = 0;
+int GLAD_GL_ARB_texture_float = 0;
+int GLAD_GL_ARB_compressed_texture_pixel_storage = 0;
+int GLAD_GL_SGIS_detail_texture = 0;
+int GLAD_GL_NV_geometry_shader_passthrough = 0;
+int GLAD_GL_ARB_draw_instanced = 0;
+int GLAD_GL_OES_read_format = 0;
+int GLAD_GL_ATI_texture_float = 0;
+int GLAD_GL_ARB_texture_gather = 0;
+int GLAD_GL_AMD_vertex_shader_layer = 0;
+int GLAD_GL_ARB_shading_language_include = 0;
+int GLAD_GL_APPLE_client_storage = 0;
+int GLAD_GL_WIN_phong_shading = 0;
+int GLAD_GL_INGR_blend_func_separate = 0;
+int GLAD_GL_NV_path_rendering = 0;
+int GLAD_GL_NV_conservative_raster_dilate = 0;
+int GLAD_GL_AMD_gpu_shader_half_float = 0;
+int GLAD_GL_ARB_post_depth_coverage = 0;
+int GLAD_GL_ARB_texture_non_power_of_two = 0;
+int GLAD_GL_APPLE_rgb_422 = 0;
+int GLAD_GL_EXT_texture_lod_bias = 0;
+int GLAD_GL_ARB_gpu_shader_int64 = 0;
+int GLAD_GL_ARB_seamless_cube_map = 0;
+int GLAD_GL_ARB_shader_group_vote = 0;
+int GLAD_GL_NV_vdpau_interop = 0;
+int GLAD_GL_ARB_occlusion_query2 = 0;
+int GLAD_GL_ARB_internalformat_query2 = 0;
+int GLAD_GL_EXT_texture_filter_anisotropic = 0;
+int GLAD_GL_SUN_vertex = 0;
+int GLAD_GL_EXT_transform_feedback = 0;
+int GLAD_GL_SGIX_igloo_interface = 0;
+int GLAD_GL_SGIS_texture_lod = 0;
+int GLAD_GL_NV_vertex_program3 = 0;
+int GLAD_GL_ARB_draw_indirect = 0;
+int GLAD_GL_NV_vertex_program4 = 0;
+int GLAD_GL_AMD_transform_feedback3_lines_triangles = 0;
+int GLAD_GL_SGIS_fog_function = 0;
+int GLAD_GL_EXT_x11_sync_object = 0;
+int GLAD_GL_ARB_sync = 0;
+int GLAD_GL_NV_texture_rectangle_compressed = 0;
+int GLAD_GL_NV_sample_locations = 0;
+int GLAD_GL_NV_gpu_multicast = 0;
+int GLAD_GL_ARB_gl_spirv = 0;
+int GLAD_GL_ARB_compute_variable_group_size = 0;
+int GLAD_GL_OES_fixed_point = 0;
+int GLAD_GL_MESA_program_binary_formats = 0;
+int GLAD_GL_NV_blend_square = 0;
+int GLAD_GL_EXT_framebuffer_multisample = 0;
+int GLAD_GL_ARB_gpu_shader5 = 0;
+int GLAD_GL_SGIS_texture4D = 0;
+int GLAD_GL_EXT_texture3D = 0;
+int GLAD_GL_EXT_multisample = 0;
+int GLAD_GL_EXT_secondary_color = 0;
+int GLAD_GL_INTEL_conservative_rasterization = 0;
+int GLAD_GL_ARB_texture_filter_minmax = 0;
+int GLAD_GL_ATI_vertex_array_object = 0;
+int GLAD_GL_ARB_parallel_shader_compile = 0;
+int GLAD_GL_NVX_gpu_memory_info = 0;
+int GLAD_GL_ARB_sparse_texture = 0;
+int GLAD_GL_SGIS_point_line_texgen = 0;
+int GLAD_GL_ARB_sample_locations = 0;
+int GLAD_GL_ARB_sparse_buffer = 0;
+int GLAD_GL_ARB_polygon_offset_clamp = 0;
+int GLAD_GL_EXT_draw_range_elements = 0;
+int GLAD_GL_SGIX_blend_alpha_minmax = 0;
+int GLAD_GL_KHR_context_flush_control = 0;
+PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX = NULL;
+PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD = NULL;
+PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD = NULL;
+PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD = NULL;
+PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD = NULL;
+PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD = NULL;
+PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD = NULL;
+PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD = NULL;
+PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = NULL;
+PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD = NULL;
+PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV = NULL;
+PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV = NULL;
+PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV = NULL;
+PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV = NULL;
+PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV = NULL;
+PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV = NULL;
+PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV = NULL;
+PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV = NULL;
+PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV = NULL;
+PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV = NULL;
+PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV = NULL;
+PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV = NULL;
+PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV = NULL;
+PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV = NULL;
+PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV = NULL;
+PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV = NULL;
+PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV = NULL;
+PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV = NULL;
+PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV = NULL;
+PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV = NULL;
+PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV = NULL;
+PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV = NULL;
+PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV = NULL;
+PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV = NULL;
+PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV = NULL;
+PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV = NULL;
+PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV = NULL;
+PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV = NULL;
+PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV = NULL;
+PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV = NULL;
+PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV = NULL;
+PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD = NULL;
+PFNGLGENNAMESAMDPROC glad_glGenNamesAMD = NULL;
+PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD = NULL;
+PFNGLISNAMEAMDPROC glad_glIsNameAMD = NULL;
+PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD = NULL;
+PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD = NULL;
+PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD = NULL;
+PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD = NULL;
+PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD = NULL;
+PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD = NULL;
+PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD = NULL;
+PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD = NULL;
+PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD = NULL;
+PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD = NULL;
+PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD = NULL;
+PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD = NULL;
+PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD = NULL;
+PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD = NULL;
+PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE = NULL;
+PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE = NULL;
+PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE = NULL;
+PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE = NULL;
+PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE = NULL;
+PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE = NULL;
+PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE = NULL;
+PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE = NULL;
+PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE = NULL;
+PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE = NULL;
+PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE = NULL;
+PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE = NULL;
+PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE = NULL;
+PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE = NULL;
+PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE = NULL;
+PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE = NULL;
+PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE = NULL;
+PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE = NULL;
+PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE = NULL;
+PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE = NULL;
+PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE = NULL;
+PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE = NULL;
+PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE = NULL;
+PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE = NULL;
+PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE = NULL;
+PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE = NULL;
+PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE = NULL;
+PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE = NULL;
+PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE = NULL;
+PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
+PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
+PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
+PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
+PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
+PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL;
+PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB = NULL;
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
+PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB = NULL;
+PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB = NULL;
+PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB = NULL;
+PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB = NULL;
+PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB = NULL;
+PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB = NULL;
+PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB = NULL;
+PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB = NULL;
+PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB = NULL;
+PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB = NULL;
+PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
+PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB = NULL;
+PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL;
+PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL;
+PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
+PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
+PFNGLCLIPCONTROLPROC glad_glClipControl = NULL;
+PFNGLCLAMPCOLORARBPROC glad_glClampColorARB = NULL;
+PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL;
+PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB = NULL;
+PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL;
+PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL;
+PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL;
+PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL;
+PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL;
+PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL;
+PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL;
+PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL;
+PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL;
+PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL;
+PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL;
+PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL;
+PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL;
+PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL;
+PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL;
+PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL;
+PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL;
+PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL;
+PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL;
+PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL;
+PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL;
+PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL;
+PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL;
+PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL;
+PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL;
+PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL;
+PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL;
+PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL;
+PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL;
+PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL;
+PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL;
+PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL;
+PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL;
+PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL;
+PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL;
+PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL;
+PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL;
+PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL;
+PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL;
+PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL;
+PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL;
+PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL;
+PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL;
+PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL;
+PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL;
+PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL;
+PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL;
+PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL;
+PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL;
+PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL;
+PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL;
+PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL;
+PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL;
+PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL;
+PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL;
+PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL;
+PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL;
+PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB = NULL;
+PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB = NULL;
+PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB = NULL;
+PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB = NULL;
+PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
+PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL;
+PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL;
+PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL;
+PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB = NULL;
+PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB = NULL;
+PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB = NULL;
+PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB = NULL;
+PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB = NULL;
+PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB = NULL;
+PFNGLISPROGRAMARBPROC glad_glIsProgramARB = NULL;
+PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL;
+PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB = NULL;
+PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB = NULL;
+PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
+PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
+PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
+PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL;
+PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL;
+PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB = NULL;
+PFNGLUNIFORM1DPROC glad_glUniform1d = NULL;
+PFNGLUNIFORM2DPROC glad_glUniform2d = NULL;
+PFNGLUNIFORM3DPROC glad_glUniform3d = NULL;
+PFNGLUNIFORM4DPROC glad_glUniform4d = NULL;
+PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL;
+PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL;
+PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL;
+PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL;
+PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL;
+PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL;
+PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL;
+PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL;
+PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL;
+PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL;
+PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL;
+PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL;
+PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL;
+PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL;
+PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB = NULL;
+PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB = NULL;
+PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB = NULL;
+PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB = NULL;
+PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB = NULL;
+PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB = NULL;
+PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB = NULL;
+PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB = NULL;
+PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB = NULL;
+PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB = NULL;
+PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB = NULL;
+PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB = NULL;
+PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB = NULL;
+PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB = NULL;
+PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB = NULL;
+PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB = NULL;
+PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB = NULL;
+PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB = NULL;
+PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB = NULL;
+PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB = NULL;
+PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB = NULL;
+PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB = NULL;
+PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB = NULL;
+PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB = NULL;
+PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB = NULL;
+PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB = NULL;
+PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB = NULL;
+PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB = NULL;
+PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB = NULL;
+PFNGLCOLORTABLEPROC glad_glColorTable = NULL;
+PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv = NULL;
+PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv = NULL;
+PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable = NULL;
+PFNGLGETCOLORTABLEPROC glad_glGetColorTable = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv = NULL;
+PFNGLCOLORSUBTABLEPROC glad_glColorSubTable = NULL;
+PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable = NULL;
+PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D = NULL;
+PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D = NULL;
+PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf = NULL;
+PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv = NULL;
+PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri = NULL;
+PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D = NULL;
+PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv = NULL;
+PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter = NULL;
+PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D = NULL;
+PFNGLGETHISTOGRAMPROC glad_glGetHistogram = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv = NULL;
+PFNGLGETMINMAXPROC glad_glGetMinmax = NULL;
+PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv = NULL;
+PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv = NULL;
+PFNGLHISTOGRAMPROC glad_glHistogram = NULL;
+PFNGLMINMAXPROC glad_glMinmax = NULL;
+PFNGLRESETHISTOGRAMPROC glad_glResetHistogram = NULL;
+PFNGLRESETMINMAXPROC glad_glResetMinmax = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB = NULL;
+PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB = NULL;
+PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
+PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL;
+PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL;
+PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL;
+PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL;
+PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL;
+PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
+PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB = NULL;
+PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB = NULL;
+PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB = NULL;
+PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB = NULL;
+PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB = NULL;
+PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL;
+PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL;
+PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL;
+PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL;
+PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL;
+PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL;
+PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL;
+PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB = NULL;
+PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB = NULL;
+PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB = NULL;
+PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB = NULL;
+PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB = NULL;
+PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB = NULL;
+PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB = NULL;
+PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB = NULL;
+PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB = NULL;
+PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB = NULL;
+PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB = NULL;
+PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB = NULL;
+PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB = NULL;
+PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB = NULL;
+PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB = NULL;
+PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB = NULL;
+PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB = NULL;
+PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB = NULL;
+PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB = NULL;
+PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB = NULL;
+PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB = NULL;
+PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB = NULL;
+PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB = NULL;
+PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB = NULL;
+PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB = NULL;
+PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB = NULL;
+PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB = NULL;
+PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB = NULL;
+PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB = NULL;
+PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB = NULL;
+PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB = NULL;
+PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB = NULL;
+PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB = NULL;
+PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB = NULL;
+PFNGLGENQUERIESARBPROC glad_glGenQueriesARB = NULL;
+PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB = NULL;
+PFNGLISQUERYARBPROC glad_glIsQueryARB = NULL;
+PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB = NULL;
+PFNGLENDQUERYARBPROC glad_glEndQueryARB = NULL;
+PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB = NULL;
+PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB = NULL;
+PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB = NULL;
+PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB = NULL;
+PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB = NULL;
+PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB = NULL;
+PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL;
+PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL;
+PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL;
+PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL;
+PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL;
+PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL;
+PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL;
+PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL;
+PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL;
+PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL;
+PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL;
+PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL;
+PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL;
+PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL;
+PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL;
+PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL;
+PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL;
+PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL;
+PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL;
+PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL;
+PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL;
+PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL;
+PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL;
+PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL;
+PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB = NULL;
+PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB = NULL;
+PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB = NULL;
+PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL;
+PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL;
+PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL;
+PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL;
+PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL;
+PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL;
+PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL;
+PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL;
+PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL;
+PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL;
+PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL;
+PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL;
+PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL;
+PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL;
+PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL;
+PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL;
+PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL;
+PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL;
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL;
+PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL;
+PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL;
+PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB = NULL;
+PFNGLGETHANDLEARBPROC glad_glGetHandleARB = NULL;
+PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB = NULL;
+PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB = NULL;
+PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB = NULL;
+PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB = NULL;
+PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB = NULL;
+PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB = NULL;
+PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB = NULL;
+PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB = NULL;
+PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB = NULL;
+PFNGLUNIFORM1FARBPROC glad_glUniform1fARB = NULL;
+PFNGLUNIFORM2FARBPROC glad_glUniform2fARB = NULL;
+PFNGLUNIFORM3FARBPROC glad_glUniform3fARB = NULL;
+PFNGLUNIFORM4FARBPROC glad_glUniform4fARB = NULL;
+PFNGLUNIFORM1IARBPROC glad_glUniform1iARB = NULL;
+PFNGLUNIFORM2IARBPROC glad_glUniform2iARB = NULL;
+PFNGLUNIFORM3IARBPROC glad_glUniform3iARB = NULL;
+PFNGLUNIFORM4IARBPROC glad_glUniform4iARB = NULL;
+PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB = NULL;
+PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB = NULL;
+PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB = NULL;
+PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB = NULL;
+PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB = NULL;
+PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB = NULL;
+PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB = NULL;
+PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB = NULL;
+PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB = NULL;
+PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB = NULL;
+PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB = NULL;
+PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB = NULL;
+PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB = NULL;
+PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB = NULL;
+PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB = NULL;
+PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB = NULL;
+PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB = NULL;
+PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB = NULL;
+PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB = NULL;
+PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB = NULL;
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL;
+PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL;
+PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL;
+PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL;
+PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL;
+PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB = NULL;
+PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB = NULL;
+PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB = NULL;
+PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB = NULL;
+PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB = NULL;
+PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT = NULL;
+PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB = NULL;
+PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB = NULL;
+PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL;
+PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL;
+PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL;
+PFNGLTEXBUFFERARBPROC glad_glTexBufferARB = NULL;
+PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB = NULL;
+PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL;
+PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
+PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL;
+PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL;
+PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
+PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
+PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL;
+PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL;
+PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL;
+PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL;
+PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB = NULL;
+PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB = NULL;
+PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL;
+PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL;
+PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL;
+PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL;
+PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL;
+PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL;
+PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL;
+PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL;
+PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL;
+PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL;
+PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL;
+PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL;
+PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL;
+PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL;
+PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL;
+PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL;
+PFNGLWEIGHTBVARBPROC glad_glWeightbvARB = NULL;
+PFNGLWEIGHTSVARBPROC glad_glWeightsvARB = NULL;
+PFNGLWEIGHTIVARBPROC glad_glWeightivARB = NULL;
+PFNGLWEIGHTFVARBPROC glad_glWeightfvARB = NULL;
+PFNGLWEIGHTDVARBPROC glad_glWeightdvARB = NULL;
+PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB = NULL;
+PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB = NULL;
+PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB = NULL;
+PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB = NULL;
+PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB = NULL;
+PFNGLBINDBUFFERARBPROC glad_glBindBufferARB = NULL;
+PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB = NULL;
+PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB = NULL;
+PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL;
+PFNGLBUFFERDATAARBPROC glad_glBufferDataARB = NULL;
+PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB = NULL;
+PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB = NULL;
+PFNGLMAPBUFFERARBPROC glad_glMapBufferARB = NULL;
+PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB = NULL;
+PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB = NULL;
+PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB = NULL;
+PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB = NULL;
+PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB = NULL;
+PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB = NULL;
+PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB = NULL;
+PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB = NULL;
+PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB = NULL;
+PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB = NULL;
+PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB = NULL;
+PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB = NULL;
+PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB = NULL;
+PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB = NULL;
+PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB = NULL;
+PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB = NULL;
+PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB = NULL;
+PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB = NULL;
+PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB = NULL;
+PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB = NULL;
+PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB = NULL;
+PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB = NULL;
+PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB = NULL;
+PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB = NULL;
+PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB = NULL;
+PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB = NULL;
+PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB = NULL;
+PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB = NULL;
+PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB = NULL;
+PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB = NULL;
+PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB = NULL;
+PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB = NULL;
+PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB = NULL;
+PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB = NULL;
+PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB = NULL;
+PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB = NULL;
+PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB = NULL;
+PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB = NULL;
+PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB = NULL;
+PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB = NULL;
+PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB = NULL;
+PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB = NULL;
+PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB = NULL;
+PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB = NULL;
+PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB = NULL;
+PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB = NULL;
+PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
+PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
+PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
+PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL;
+PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL;
+PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL;
+PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
+PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
+PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL;
+PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL;
+PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB = NULL;
+PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB = NULL;
+PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB = NULL;
+PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB = NULL;
+PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB = NULL;
+PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB = NULL;
+PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB = NULL;
+PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB = NULL;
+PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB = NULL;
+PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB = NULL;
+PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB = NULL;
+PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB = NULL;
+PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB = NULL;
+PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB = NULL;
+PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB = NULL;
+PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB = NULL;
+PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI = NULL;
+PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI = NULL;
+PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI = NULL;
+PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI = NULL;
+PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI = NULL;
+PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI = NULL;
+PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI = NULL;
+PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI = NULL;
+PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI = NULL;
+PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI = NULL;
+PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI = NULL;
+PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI = NULL;
+PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI = NULL;
+PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI = NULL;
+PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI = NULL;
+PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI = NULL;
+PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI = NULL;
+PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI = NULL;
+PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI = NULL;
+PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI = NULL;
+PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI = NULL;
+PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI = NULL;
+PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI = NULL;
+PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI = NULL;
+PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI = NULL;
+PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI = NULL;
+PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI = NULL;
+PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI = NULL;
+PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI = NULL;
+PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI = NULL;
+PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI = NULL;
+PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI = NULL;
+PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI = NULL;
+PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI = NULL;
+PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI = NULL;
+PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI = NULL;
+PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI = NULL;
+PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI = NULL;
+PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI = NULL;
+PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI = NULL;
+PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI = NULL;
+PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI = NULL;
+PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI = NULL;
+PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI = NULL;
+PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI = NULL;
+PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI = NULL;
+PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI = NULL;
+PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI = NULL;
+PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI = NULL;
+PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI = NULL;
+PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI = NULL;
+PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI = NULL;
+PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI = NULL;
+PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI = NULL;
+PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI = NULL;
+PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI = NULL;
+PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI = NULL;
+PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI = NULL;
+PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI = NULL;
+PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI = NULL;
+PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI = NULL;
+PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI = NULL;
+PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI = NULL;
+PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI = NULL;
+PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI = NULL;
+PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI = NULL;
+PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI = NULL;
+PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI = NULL;
+PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI = NULL;
+PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI = NULL;
+PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI = NULL;
+PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI = NULL;
+PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI = NULL;
+PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI = NULL;
+PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI = NULL;
+PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI = NULL;
+PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI = NULL;
+PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI = NULL;
+PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI = NULL;
+PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI = NULL;
+PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI = NULL;
+PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI = NULL;
+PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI = NULL;
+PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI = NULL;
+PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI = NULL;
+PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI = NULL;
+PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT = NULL;
+PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT = NULL;
+PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT = NULL;
+PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT = NULL;
+PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT = NULL;
+PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT = NULL;
+PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT = NULL;
+PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT = NULL;
+PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT = NULL;
+PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT = NULL;
+PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT = NULL;
+PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT = NULL;
+PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT = NULL;
+PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT = NULL;
+PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT = NULL;
+PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT = NULL;
+PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT = NULL;
+PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT = NULL;
+PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT = NULL;
+PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT = NULL;
+PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT = NULL;
+PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT = NULL;
+PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT = NULL;
+PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT = NULL;
+PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT = NULL;
+PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT = NULL;
+PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT = NULL;
+PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT = NULL;
+PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT = NULL;
+PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT = NULL;
+PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT = NULL;
+PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT = NULL;
+PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT = NULL;
+PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT = NULL;
+PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT = NULL;
+PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT = NULL;
+PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT = NULL;
+PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT = NULL;
+PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT = NULL;
+PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT = NULL;
+PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT = NULL;
+PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT = NULL;
+PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT = NULL;
+PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT = NULL;
+PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT = NULL;
+PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT = NULL;
+PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT = NULL;
+PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT = NULL;
+PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT = NULL;
+PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT = NULL;
+PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT = NULL;
+PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT = NULL;
+PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT = NULL;
+PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT = NULL;
+PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT = NULL;
+PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT = NULL;
+PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT = NULL;
+PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT = NULL;
+PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT = NULL;
+PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT = NULL;
+PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT = NULL;
+PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT = NULL;
+PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT = NULL;
+PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT = NULL;
+PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT = NULL;
+PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT = NULL;
+PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT = NULL;
+PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT = NULL;
+PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT = NULL;
+PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT = NULL;
+PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT = NULL;
+PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT = NULL;
+PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT = NULL;
+PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT = NULL;
+PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT = NULL;
+PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT = NULL;
+PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT = NULL;
+PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT = NULL;
+PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT = NULL;
+PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT = NULL;
+PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT = NULL;
+PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT = NULL;
+PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT = NULL;
+PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT = NULL;
+PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT = NULL;
+PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT = NULL;
+PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT = NULL;
+PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT = NULL;
+PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT = NULL;
+PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT = NULL;
+PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT = NULL;
+PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT = NULL;
+PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT = NULL;
+PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT = NULL;
+PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT = NULL;
+PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT = NULL;
+PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT = NULL;
+PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT = NULL;
+PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT = NULL;
+PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT = NULL;
+PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT = NULL;
+PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT = NULL;
+PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT = NULL;
+PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT = NULL;
+PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT = NULL;
+PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT = NULL;
+PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT = NULL;
+PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT = NULL;
+PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT = NULL;
+PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT = NULL;
+PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT = NULL;
+PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT = NULL;
+PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT = NULL;
+PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT = NULL;
+PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT = NULL;
+PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT = NULL;
+PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT = NULL;
+PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT = NULL;
+PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT = NULL;
+PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT = NULL;
+PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT = NULL;
+PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT = NULL;
+PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT = NULL;
+PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT = NULL;
+PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT = NULL;
+PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT = NULL;
+PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT = NULL;
+PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT = NULL;
+PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT = NULL;
+PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT = NULL;
+PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT = NULL;
+PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT = NULL;
+PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT = NULL;
+PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT = NULL;
+PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT = NULL;
+PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT = NULL;
+PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT = NULL;
+PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT = NULL;
+PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT = NULL;
+PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT = NULL;
+PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT = NULL;
+PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT = NULL;
+PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT = NULL;
+PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT = NULL;
+PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT = NULL;
+PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT = NULL;
+PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT = NULL;
+PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT = NULL;
+PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT = NULL;
+PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT = NULL;
+PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT = NULL;
+PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT = NULL;
+PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT = NULL;
+PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT = NULL;
+PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT = NULL;
+PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT = NULL;
+PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT = NULL;
+PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT = NULL;
+PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT = NULL;
+PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT = NULL;
+PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT = NULL;
+PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT = NULL;
+PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT = NULL;
+PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT = NULL;
+PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT = NULL;
+PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT = NULL;
+PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT = NULL;
+PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT = NULL;
+PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT = NULL;
+PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT = NULL;
+PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT = NULL;
+PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT = NULL;
+PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT = NULL;
+PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL;
+PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL;
+PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT = NULL;
+PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT = NULL;
+PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT = NULL;
+PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT = NULL;
+PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT = NULL;
+PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL;
+PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT = NULL;
+PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT = NULL;
+PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT = NULL;
+PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT = NULL;
+PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT = NULL;
+PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT = NULL;
+PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT = NULL;
+PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL;
+PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL;
+PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL;
+PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL;
+PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL;
+PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL;
+PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL;
+PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL;
+PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL;
+PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL;
+PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT = NULL;
+PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT = NULL;
+PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT = NULL;
+PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT = NULL;
+PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT = NULL;
+PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT = NULL;
+PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT = NULL;
+PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT = NULL;
+PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT = NULL;
+PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT = NULL;
+PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT = NULL;
+PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT = NULL;
+PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT = NULL;
+PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT = NULL;
+PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT = NULL;
+PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT = NULL;
+PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT = NULL;
+PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT = NULL;
+PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT = NULL;
+PFNGLMINMAXEXTPROC glad_glMinmaxEXT = NULL;
+PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT = NULL;
+PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT = NULL;
+PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT = NULL;
+PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT = NULL;
+PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT = NULL;
+PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT = NULL;
+PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT = NULL;
+PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL;
+PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL;
+PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL;
+PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL;
+PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL;
+PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL;
+PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL;
+PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL;
+PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL;
+PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL;
+PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL;
+PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL;
+PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL;
+PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT = NULL;
+PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT = NULL;
+PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT = NULL;
+PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT = NULL;
+PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT = NULL;
+PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT = NULL;
+PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT = NULL;
+PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT = NULL;
+PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT = NULL;
+PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT = NULL;
+PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT = NULL;
+PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT = NULL;
+PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT = NULL;
+PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT = NULL;
+PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT = NULL;
+PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT = NULL;
+PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT = NULL;
+PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT = NULL;
+PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT = NULL;
+PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT = NULL;
+PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT = NULL;
+PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT = NULL;
+PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT = NULL;
+PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT = NULL;
+PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT = NULL;
+PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT = NULL;
+PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT = NULL;
+PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT = NULL;
+PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT = NULL;
+PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT = NULL;
+PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT = NULL;
+PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT = NULL;
+PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT = NULL;
+PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT = NULL;
+PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT = NULL;
+PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT = NULL;
+PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT = NULL;
+PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT = NULL;
+PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT = NULL;
+PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT = NULL;
+PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT = NULL;
+PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT = NULL;
+PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT = NULL;
+PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT = NULL;
+PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT = NULL;
+PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT = NULL;
+PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT = NULL;
+PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT = NULL;
+PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT = NULL;
+PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT = NULL;
+PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT = NULL;
+PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT = NULL;
+PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT = NULL;
+PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT = NULL;
+PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT = NULL;
+PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT = NULL;
+PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT = NULL;
+PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT = NULL;
+PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT = NULL;
+PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT = NULL;
+PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT = NULL;
+PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT = NULL;
+PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT = NULL;
+PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT = NULL;
+PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT = NULL;
+PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT = NULL;
+PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT = NULL;
+PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT = NULL;
+PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT = NULL;
+PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT = NULL;
+PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT = NULL;
+PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT = NULL;
+PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT = NULL;
+PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT = NULL;
+PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT = NULL;
+PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT = NULL;
+PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT = NULL;
+PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT = NULL;
+PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT = NULL;
+PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT = NULL;
+PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT = NULL;
+PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT = NULL;
+PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT = NULL;
+PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT = NULL;
+PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT = NULL;
+PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT = NULL;
+PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT = NULL;
+PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT = NULL;
+PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT = NULL;
+PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT = NULL;
+PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT = NULL;
+PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT = NULL;
+PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT = NULL;
+PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT = NULL;
+PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT = NULL;
+PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT = NULL;
+PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT = NULL;
+PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT = NULL;
+PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT = NULL;
+PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT = NULL;
+PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT = NULL;
+PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT = NULL;
+PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT = NULL;
+PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT = NULL;
+PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT = NULL;
+PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT = NULL;
+PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT = NULL;
+PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT = NULL;
+PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT = NULL;
+PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT = NULL;
+PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT = NULL;
+PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT = NULL;
+PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT = NULL;
+PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT = NULL;
+PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT = NULL;
+PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT = NULL;
+PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT = NULL;
+PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT = NULL;
+PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT = NULL;
+PFNGLVARIANTIVEXTPROC glad_glVariantivEXT = NULL;
+PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT = NULL;
+PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT = NULL;
+PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT = NULL;
+PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT = NULL;
+PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT = NULL;
+PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT = NULL;
+PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT = NULL;
+PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT = NULL;
+PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT = NULL;
+PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT = NULL;
+PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT = NULL;
+PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT = NULL;
+PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT = NULL;
+PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT = NULL;
+PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT = NULL;
+PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT = NULL;
+PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT = NULL;
+PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT = NULL;
+PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT = NULL;
+PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT = NULL;
+PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT = NULL;
+PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT = NULL;
+PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT = NULL;
+PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT = NULL;
+PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT = NULL;
+PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT = NULL;
+PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT = NULL;
+PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT = NULL;
+PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT = NULL;
+PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT = NULL;
+PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT = NULL;
+PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY = NULL;
+PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP = NULL;
+PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP = NULL;
+PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP = NULL;
+PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM = NULL;
+PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM = NULL;
+PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM = NULL;
+PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM = NULL;
+PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM = NULL;
+PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM = NULL;
+PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM = NULL;
+PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM = NULL;
+PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM = NULL;
+PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM = NULL;
+PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM = NULL;
+PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR = NULL;
+PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL = NULL;
+PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL = NULL;
+PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL = NULL;
+PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL = NULL;
+PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL = NULL;
+PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL = NULL;
+PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL = NULL;
+PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL = NULL;
+PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL = NULL;
+PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL = NULL;
+PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL = NULL;
+PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL = NULL;
+PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL = NULL;
+PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL = NULL;
+PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL = NULL;
+PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL = NULL;
+PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL = NULL;
+PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL = NULL;
+PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL;
+PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL;
+PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL;
+PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL;
+PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL;
+PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL;
+PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL;
+PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL;
+PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL;
+PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL;
+PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL;
+PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL;
+PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL;
+PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL;
+PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL;
+PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL;
+PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL;
+PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL;
+PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL;
+PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL;
+PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL;
+PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL;
+PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL;
+PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL;
+PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL;
+PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL;
+PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL;
+PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL;
+PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL;
+PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR = NULL;
+PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR = NULL;
+PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR = NULL;
+PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR = NULL;
+PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR = NULL;
+PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA = NULL;
+PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA = NULL;
+PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA = NULL;
+PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA = NULL;
+PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA = NULL;
+PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA = NULL;
+PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA = NULL;
+PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA = NULL;
+PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA = NULL;
+PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA = NULL;
+PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA = NULL;
+PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA = NULL;
+PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA = NULL;
+PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA = NULL;
+PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA = NULL;
+PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA = NULL;
+PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA = NULL;
+PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA = NULL;
+PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA = NULL;
+PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA = NULL;
+PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA = NULL;
+PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA = NULL;
+PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA = NULL;
+PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA = NULL;
+PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA = NULL;
+PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX = NULL;
+PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX = NULL;
+PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX = NULL;
+PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX = NULL;
+PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX = NULL;
+PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV = NULL;
+PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV = NULL;
+PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV = NULL;
+PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV = NULL;
+PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV = NULL;
+PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV = NULL;
+PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV = NULL;
+PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV = NULL;
+PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV = NULL;
+PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV = NULL;
+PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV = NULL;
+PFNGLCREATESTATESNVPROC glad_glCreateStatesNV = NULL;
+PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV = NULL;
+PFNGLISSTATENVPROC glad_glIsStateNV = NULL;
+PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV = NULL;
+PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV = NULL;
+PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV = NULL;
+PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV = NULL;
+PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV = NULL;
+PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV = NULL;
+PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV = NULL;
+PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV = NULL;
+PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV = NULL;
+PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV = NULL;
+PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV = NULL;
+PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV = NULL;
+PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV = NULL;
+PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV = NULL;
+PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV = NULL;
+PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV = NULL;
+PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV = NULL;
+PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV = NULL;
+PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV = NULL;
+PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV = NULL;
+PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV = NULL;
+PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV = NULL;
+PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV = NULL;
+PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV = NULL;
+PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV = NULL;
+PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV = NULL;
+PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV = NULL;
+PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV = NULL;
+PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV = NULL;
+PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV = NULL;
+PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV = NULL;
+PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV = NULL;
+PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV = NULL;
+PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV = NULL;
+PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV = NULL;
+PFNGLEVALMAPSNVPROC glad_glEvalMapsNV = NULL;
+PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV = NULL;
+PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV = NULL;
+PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV = NULL;
+PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV = NULL;
+PFNGLGENFENCESNVPROC glad_glGenFencesNV = NULL;
+PFNGLISFENCENVPROC glad_glIsFenceNV = NULL;
+PFNGLTESTFENCENVPROC glad_glTestFenceNV = NULL;
+PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV = NULL;
+PFNGLFINISHFENCENVPROC glad_glFinishFenceNV = NULL;
+PFNGLSETFENCENVPROC glad_glSetFenceNV = NULL;
+PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV = NULL;
+PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV = NULL;
+PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV = NULL;
+PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV = NULL;
+PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV = NULL;
+PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV = NULL;
+PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV = NULL;
+PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT = NULL;
+PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV = NULL;
+PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV = NULL;
+PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV = NULL;
+PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV = NULL;
+PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV = NULL;
+PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV = NULL;
+PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV = NULL;
+PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV = NULL;
+PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV = NULL;
+PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV = NULL;
+PFNGLVERTEX2HNVPROC glad_glVertex2hNV = NULL;
+PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV = NULL;
+PFNGLVERTEX3HNVPROC glad_glVertex3hNV = NULL;
+PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV = NULL;
+PFNGLVERTEX4HNVPROC glad_glVertex4hNV = NULL;
+PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV = NULL;
+PFNGLNORMAL3HNVPROC glad_glNormal3hNV = NULL;
+PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV = NULL;
+PFNGLCOLOR3HNVPROC glad_glColor3hNV = NULL;
+PFNGLCOLOR3HVNVPROC glad_glColor3hvNV = NULL;
+PFNGLCOLOR4HNVPROC glad_glColor4hNV = NULL;
+PFNGLCOLOR4HVNVPROC glad_glColor4hvNV = NULL;
+PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV = NULL;
+PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV = NULL;
+PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV = NULL;
+PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV = NULL;
+PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV = NULL;
+PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV = NULL;
+PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV = NULL;
+PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV = NULL;
+PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV = NULL;
+PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV = NULL;
+PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV = NULL;
+PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV = NULL;
+PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV = NULL;
+PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV = NULL;
+PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV = NULL;
+PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV = NULL;
+PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV = NULL;
+PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV = NULL;
+PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV = NULL;
+PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV = NULL;
+PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV = NULL;
+PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV = NULL;
+PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV = NULL;
+PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV = NULL;
+PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV = NULL;
+PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV = NULL;
+PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV = NULL;
+PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV = NULL;
+PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV = NULL;
+PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV = NULL;
+PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV = NULL;
+PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV = NULL;
+PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV = NULL;
+PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV = NULL;
+PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV = NULL;
+PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV = NULL;
+PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV = NULL;
+PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV = NULL;
+PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV = NULL;
+PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV = NULL;
+PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV = NULL;
+PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV = NULL;
+PFNGLGENPATHSNVPROC glad_glGenPathsNV = NULL;
+PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV = NULL;
+PFNGLISPATHNVPROC glad_glIsPathNV = NULL;
+PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV = NULL;
+PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV = NULL;
+PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV = NULL;
+PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV = NULL;
+PFNGLPATHSTRINGNVPROC glad_glPathStringNV = NULL;
+PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV = NULL;
+PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV = NULL;
+PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV = NULL;
+PFNGLCOPYPATHNVPROC glad_glCopyPathNV = NULL;
+PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV = NULL;
+PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV = NULL;
+PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV = NULL;
+PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV = NULL;
+PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV = NULL;
+PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV = NULL;
+PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV = NULL;
+PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV = NULL;
+PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV = NULL;
+PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV = NULL;
+PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV = NULL;
+PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV = NULL;
+PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV = NULL;
+PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV = NULL;
+PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV = NULL;
+PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV = NULL;
+PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV = NULL;
+PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV = NULL;
+PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV = NULL;
+PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV = NULL;
+PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV = NULL;
+PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV = NULL;
+PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV = NULL;
+PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV = NULL;
+PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV = NULL;
+PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV = NULL;
+PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV = NULL;
+PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV = NULL;
+PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV = NULL;
+PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV = NULL;
+PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV = NULL;
+PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV = NULL;
+PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV = NULL;
+PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV = NULL;
+PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV = NULL;
+PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV = NULL;
+PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV = NULL;
+PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV = NULL;
+PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV = NULL;
+PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV = NULL;
+PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV = NULL;
+PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV = NULL;
+PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV = NULL;
+PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV = NULL;
+PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV = NULL;
+PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV = NULL;
+PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV = NULL;
+PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV = NULL;
+PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV = NULL;
+PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV = NULL;
+PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV = NULL;
+PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV = NULL;
+PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV = NULL;
+PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV = NULL;
+PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV = NULL;
+PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV = NULL;
+PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV = NULL;
+PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV = NULL;
+PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV = NULL;
+PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV = NULL;
+PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV = NULL;
+PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV = NULL;
+PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV = NULL;
+PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV = NULL;
+PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV = NULL;
+PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV = NULL;
+PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV = NULL;
+PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV = NULL;
+PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV = NULL;
+PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV = NULL;
+PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV = NULL;
+PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV = NULL;
+PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV = NULL;
+PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV = NULL;
+PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV = NULL;
+PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV = NULL;
+PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV = NULL;
+PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV = NULL;
+PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV = NULL;
+PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV = NULL;
+PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV = NULL;
+PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV = NULL;
+PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV = NULL;
+PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV = NULL;
+PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV = NULL;
+PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV = NULL;
+PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV = NULL;
+PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV = NULL;
+PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV = NULL;
+PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV = NULL;
+PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV = NULL;
+PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV = NULL;
+PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV = NULL;
+PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV = NULL;
+PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV = NULL;
+PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV = NULL;
+PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV = NULL;
+PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV = NULL;
+PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV = NULL;
+PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV = NULL;
+PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV = NULL;
+PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV = NULL;
+PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV = NULL;
+PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV = NULL;
+PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV = NULL;
+PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV = NULL;
+PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV = NULL;
+PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV = NULL;
+PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV = NULL;
+PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV = NULL;
+PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV = NULL;
+PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV = NULL;
+PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV = NULL;
+PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV = NULL;
+PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV = NULL;
+PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV = NULL;
+PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV = NULL;
+PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV = NULL;
+PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV = NULL;
+PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV = NULL;
+PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV = NULL;
+PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV = NULL;
+PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV = NULL;
+PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV = NULL;
+PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV = NULL;
+PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV = NULL;
+PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV = NULL;
+PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV = NULL;
+PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV = NULL;
+PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV = NULL;
+PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV = NULL;
+PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV = NULL;
+PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV = NULL;
+PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV = NULL;
+PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV = NULL;
+PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV = NULL;
+PFNGLCOLORFORMATNVPROC glad_glColorFormatNV = NULL;
+PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV = NULL;
+PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV = NULL;
+PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV = NULL;
+PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV = NULL;
+PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV = NULL;
+PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV = NULL;
+PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV = NULL;
+PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV = NULL;
+PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV = NULL;
+PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV = NULL;
+PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV = NULL;
+PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV = NULL;
+PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV = NULL;
+PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV = NULL;
+PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV = NULL;
+PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV = NULL;
+PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV = NULL;
+PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV = NULL;
+PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV = NULL;
+PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV = NULL;
+PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV = NULL;
+PFNGLISPROGRAMNVPROC glad_glIsProgramNV = NULL;
+PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV = NULL;
+PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV = NULL;
+PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV = NULL;
+PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV = NULL;
+PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV = NULL;
+PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV = NULL;
+PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV = NULL;
+PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV = NULL;
+PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV = NULL;
+PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV = NULL;
+PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV = NULL;
+PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV = NULL;
+PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV = NULL;
+PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV = NULL;
+PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV = NULL;
+PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV = NULL;
+PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV = NULL;
+PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV = NULL;
+PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV = NULL;
+PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV = NULL;
+PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV = NULL;
+PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV = NULL;
+PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV = NULL;
+PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV = NULL;
+PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV = NULL;
+PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV = NULL;
+PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV = NULL;
+PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV = NULL;
+PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV = NULL;
+PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV = NULL;
+PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV = NULL;
+PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV = NULL;
+PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV = NULL;
+PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV = NULL;
+PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV = NULL;
+PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV = NULL;
+PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV = NULL;
+PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV = NULL;
+PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV = NULL;
+PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV = NULL;
+PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV = NULL;
+PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV = NULL;
+PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV = NULL;
+PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV = NULL;
+PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV = NULL;
+PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV = NULL;
+PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV = NULL;
+PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV = NULL;
+PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV = NULL;
+PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT = NULL;
+PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT = NULL;
+PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT = NULL;
+PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT = NULL;
+PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT = NULL;
+PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT = NULL;
+PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT = NULL;
+PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT = NULL;
+PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT = NULL;
+PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT = NULL;
+PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT = NULL;
+PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT = NULL;
+PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT = NULL;
+PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT = NULL;
+PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT = NULL;
+PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT = NULL;
+PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT = NULL;
+PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT = NULL;
+PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT = NULL;
+PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT = NULL;
+PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT = NULL;
+PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT = NULL;
+PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT = NULL;
+PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV = NULL;
+PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV = NULL;
+PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV = NULL;
+PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV = NULL;
+PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV = NULL;
+PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES = NULL;
+PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES = NULL;
+PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES = NULL;
+PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES = NULL;
+PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES = NULL;
+PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES = NULL;
+PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES = NULL;
+PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES = NULL;
+PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES = NULL;
+PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES = NULL;
+PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES = NULL;
+PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES = NULL;
+PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES = NULL;
+PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES = NULL;
+PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES = NULL;
+PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES = NULL;
+PFNGLVERTEX2BOESPROC glad_glVertex2bOES = NULL;
+PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES = NULL;
+PFNGLVERTEX3BOESPROC glad_glVertex3bOES = NULL;
+PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES = NULL;
+PFNGLVERTEX4BOESPROC glad_glVertex4bOES = NULL;
+PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES = NULL;
+PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES = NULL;
+PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES = NULL;
+PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES = NULL;
+PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES = NULL;
+PFNGLCOLOR4XOESPROC glad_glColor4xOES = NULL;
+PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES = NULL;
+PFNGLFOGXOESPROC glad_glFogxOES = NULL;
+PFNGLFOGXVOESPROC glad_glFogxvOES = NULL;
+PFNGLFRUSTUMXOESPROC glad_glFrustumxOES = NULL;
+PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES = NULL;
+PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES = NULL;
+PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES = NULL;
+PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES = NULL;
+PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES = NULL;
+PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES = NULL;
+PFNGLLIGHTXOESPROC glad_glLightxOES = NULL;
+PFNGLLIGHTXVOESPROC glad_glLightxvOES = NULL;
+PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES = NULL;
+PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES = NULL;
+PFNGLMATERIALXOESPROC glad_glMaterialxOES = NULL;
+PFNGLMATERIALXVOESPROC glad_glMaterialxvOES = NULL;
+PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES = NULL;
+PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES = NULL;
+PFNGLNORMAL3XOESPROC glad_glNormal3xOES = NULL;
+PFNGLORTHOXOESPROC glad_glOrthoxOES = NULL;
+PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES = NULL;
+PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES = NULL;
+PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES = NULL;
+PFNGLROTATEXOESPROC glad_glRotatexOES = NULL;
+PFNGLSCALEXOESPROC glad_glScalexOES = NULL;
+PFNGLTEXENVXOESPROC glad_glTexEnvxOES = NULL;
+PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES = NULL;
+PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES = NULL;
+PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES = NULL;
+PFNGLTRANSLATEXOESPROC glad_glTranslatexOES = NULL;
+PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES = NULL;
+PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES = NULL;
+PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES = NULL;
+PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES = NULL;
+PFNGLACCUMXOESPROC glad_glAccumxOES = NULL;
+PFNGLBITMAPXOESPROC glad_glBitmapxOES = NULL;
+PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES = NULL;
+PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES = NULL;
+PFNGLCOLOR3XOESPROC glad_glColor3xOES = NULL;
+PFNGLCOLOR3XVOESPROC glad_glColor3xvOES = NULL;
+PFNGLCOLOR4XVOESPROC glad_glColor4xvOES = NULL;
+PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES = NULL;
+PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES = NULL;
+PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES = NULL;
+PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES = NULL;
+PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES = NULL;
+PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES = NULL;
+PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES = NULL;
+PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES = NULL;
+PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES = NULL;
+PFNGLGETLIGHTXOESPROC glad_glGetLightxOES = NULL;
+PFNGLGETMAPXVOESPROC glad_glGetMapxvOES = NULL;
+PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES = NULL;
+PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv = NULL;
+PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES = NULL;
+PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES = NULL;
+PFNGLINDEXXOESPROC glad_glIndexxOES = NULL;
+PFNGLINDEXXVOESPROC glad_glIndexxvOES = NULL;
+PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES = NULL;
+PFNGLMAP1XOESPROC glad_glMap1xOES = NULL;
+PFNGLMAP2XOESPROC glad_glMap2xOES = NULL;
+PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES = NULL;
+PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES = NULL;
+PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES = NULL;
+PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES = NULL;
+PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES = NULL;
+PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES = NULL;
+PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES = NULL;
+PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES = NULL;
+PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES = NULL;
+PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES = NULL;
+PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES = NULL;
+PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES = NULL;
+PFNGLPIXELMAPXPROC glad_glPixelMapx = NULL;
+PFNGLPIXELSTOREXPROC glad_glPixelStorex = NULL;
+PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES = NULL;
+PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES = NULL;
+PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES = NULL;
+PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES = NULL;
+PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES = NULL;
+PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES = NULL;
+PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES = NULL;
+PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES = NULL;
+PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES = NULL;
+PFNGLRECTXOESPROC glad_glRectxOES = NULL;
+PFNGLRECTXVOESPROC glad_glRectxvOES = NULL;
+PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES = NULL;
+PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES = NULL;
+PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES = NULL;
+PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES = NULL;
+PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES = NULL;
+PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES = NULL;
+PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES = NULL;
+PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES = NULL;
+PFNGLTEXGENXOESPROC glad_glTexGenxOES = NULL;
+PFNGLTEXGENXVOESPROC glad_glTexGenxvOES = NULL;
+PFNGLVERTEX2XOESPROC glad_glVertex2xOES = NULL;
+PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES = NULL;
+PFNGLVERTEX3XOESPROC glad_glVertex3xOES = NULL;
+PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES = NULL;
+PFNGLVERTEX4XOESPROC glad_glVertex4xOES = NULL;
+PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES = NULL;
+PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES = NULL;
+PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES = NULL;
+PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES = NULL;
+PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES = NULL;
+PFNGLFRUSTUMFOESPROC glad_glFrustumfOES = NULL;
+PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES = NULL;
+PFNGLORTHOFOESPROC glad_glOrthofOES = NULL;
+PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL;
+PFNGLHINTPGIPROC glad_glHintPGI = NULL;
+PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS = NULL;
+PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS = NULL;
+PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS = NULL;
+PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS = NULL;
+PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS = NULL;
+PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS = NULL;
+PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS = NULL;
+PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS = NULL;
+PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS = NULL;
+PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS = NULL;
+PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS = NULL;
+PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS = NULL;
+PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS = NULL;
+PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS = NULL;
+PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS = NULL;
+PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS = NULL;
+PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS = NULL;
+PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS = NULL;
+PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS = NULL;
+PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS = NULL;
+PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS = NULL;
+PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX = NULL;
+PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX = NULL;
+PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX = NULL;
+PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX = NULL;
+PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX = NULL;
+PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX = NULL;
+PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX = NULL;
+PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX = NULL;
+PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX = NULL;
+PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX = NULL;
+PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX = NULL;
+PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX = NULL;
+PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX = NULL;
+PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX = NULL;
+PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX = NULL;
+PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX = NULL;
+PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX = NULL;
+PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX = NULL;
+PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX = NULL;
+PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX = NULL;
+PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX = NULL;
+PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX = NULL;
+PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX = NULL;
+PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX = NULL;
+PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX = NULL;
+PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX = NULL;
+PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX = NULL;
+PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX = NULL;
+PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX = NULL;
+PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX = NULL;
+PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX = NULL;
+PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX = NULL;
+PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX = NULL;
+PFNGLDEFORMSGIXPROC glad_glDeformSGIX = NULL;
+PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX = NULL;
+PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX = NULL;
+PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX = NULL;
+PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX = NULL;
+PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX = NULL;
+PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX = NULL;
+PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX = NULL;
+PFNGLCOLORTABLESGIPROC glad_glColorTableSGI = NULL;
+PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI = NULL;
+PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI = NULL;
+PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI = NULL;
+PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI = NULL;
+PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX = NULL;
+PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN = NULL;
+PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN = NULL;
+PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN = NULL;
+PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN = NULL;
+PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN = NULL;
+PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN = NULL;
+PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN = NULL;
+PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN = NULL;
+PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN = NULL;
+PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN = NULL;
+PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN = NULL;
+PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN = NULL;
+PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN = NULL;
+PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN = NULL;
+PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN = NULL;
+PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN = NULL;
+PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN = NULL;
+PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN = NULL;
+PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN = NULL;
+PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
static void load_GL_VERSION_1_0(GLADloadproc load) {
if(!GLAD_GL_VERSION_1_0) return;
glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
@@ -4453,6 +4457,11 @@ static void load_GL_AMD_draw_buffers_blend(GLADloadproc load) {
glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD");
glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD");
}
+static void load_GL_AMD_framebuffer_multisample_advanced(GLADloadproc load) {
+ if(!GLAD_GL_AMD_framebuffer_multisample_advanced) return;
+ glad_glRenderbufferStorageMultisampleAdvancedAMD = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glRenderbufferStorageMultisampleAdvancedAMD");
+ glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glNamedRenderbufferStorageMultisampleAdvancedAMD");
+}
static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) {
if(!GLAD_GL_AMD_framebuffer_sample_positions) return;
glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD");
@@ -7812,6 +7821,7 @@ static int find_extensionsGL(void) {
GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output");
GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate");
GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend");
+ GLAD_GL_AMD_framebuffer_multisample_advanced = has_ext("GL_AMD_framebuffer_multisample_advanced");
GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions");
GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader");
GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float");
@@ -8473,6 +8483,7 @@ int gladLoadGLLoader(GLADloadproc load) {
load_GL_3DFX_tbuffer(load);
load_GL_AMD_debug_output(load);
load_GL_AMD_draw_buffers_blend(load);
+ load_GL_AMD_framebuffer_multisample_advanced(load);
load_GL_AMD_framebuffer_sample_positions(load);
load_GL_AMD_gpu_shader_int64(load);
load_GL_AMD_interleaved_elements(load);
diff --git a/externals/mbedtls b/externals/mbedtls
new file mode 160000
+Subproject 06b1b55434dd5d821e911583d629cff39a04b38
diff --git a/externals/opus b/externals/opus
new file mode 160000
+Subproject b2871922a12abb49579512d604cabc471a59ad9
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 85354f43e..a88551fbc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,6 +3,7 @@ include_directories(.)
add_subdirectory(common)
add_subdirectory(core)
+add_subdirectory(audio_core)
add_subdirectory(video_core)
add_subdirectory(input_common)
add_subdirectory(tests)
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
new file mode 100644
index 000000000..ec71524a3
--- /dev/null
+++ b/src/audio_core/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_library(audio_core STATIC
+ audio_out.cpp
+ audio_out.h
+ audio_renderer.cpp
+ audio_renderer.h
+ buffer.h
+ codec.cpp
+ codec.h
+ null_sink.h
+ stream.cpp
+ stream.h
+ sink.h
+ sink_details.cpp
+ sink_details.h
+ sink_stream.h
+
+ $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h>
+)
+
+create_target_directory_groups(audio_core)
+
+target_link_libraries(audio_core PUBLIC common core)
+
+if(ENABLE_CUBEB)
+ target_link_libraries(audio_core PRIVATE cubeb)
+ target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
+endif()
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
new file mode 100644
index 000000000..12632a95c
--- /dev/null
+++ b/src/audio_core/audio_out.cpp
@@ -0,0 +1,58 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "audio_core/audio_out.h"
+#include "audio_core/sink.h"
+#include "audio_core/sink_details.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/settings.h"
+
+namespace AudioCore {
+
+/// Returns the stream format from the specified number of channels
+static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
+ switch (num_channels) {
+ case 1:
+ return Stream::Format::Mono16;
+ case 2:
+ return Stream::Format::Stereo16;
+ case 6:
+ return Stream::Format::Multi51Channel16;
+ }
+
+ LOG_CRITICAL(Audio, "Unimplemented num_channels={}", num_channels);
+ UNREACHABLE();
+ return {};
+}
+
+StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name,
+ Stream::ReleaseCallback&& release_callback) {
+ if (!sink) {
+ const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id);
+ sink = sink_details.factory(Settings::values.audio_device_id);
+ }
+
+ return std::make_shared<Stream>(
+ sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback),
+ sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name));
+}
+
+std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) {
+ return stream->GetTagsAndReleaseBuffers(max_count);
+}
+
+void AudioOut::StartStream(StreamPtr stream) {
+ stream->Play();
+}
+
+void AudioOut::StopStream(StreamPtr stream) {
+ stream->Stop();
+}
+
+bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data) {
+ return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data)));
+}
+
+} // namespace AudioCore
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h
new file mode 100644
index 000000000..39b7e656b
--- /dev/null
+++ b/src/audio_core/audio_out.h
@@ -0,0 +1,43 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "audio_core/buffer.h"
+#include "audio_core/sink.h"
+#include "audio_core/stream.h"
+#include "common/common_types.h"
+
+namespace AudioCore {
+
+/**
+ * Represents an audio playback interface, used to open and play audio streams
+ */
+class AudioOut {
+public:
+ /// Opens a new audio stream
+ StreamPtr OpenStream(u32 sample_rate, u32 num_channels, std::string&& name,
+ Stream::ReleaseCallback&& release_callback);
+
+ /// Returns a vector of recently released buffers specified by tag for the specified stream
+ std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count);
+
+ /// Starts an audio stream for playback
+ void StartStream(StreamPtr stream);
+
+ /// Stops an audio stream that is currently playing
+ void StopStream(StreamPtr stream);
+
+ /// Queues a buffer into the specified audio stream, returns true on success
+ bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data);
+
+private:
+ SinkPtr sink;
+};
+
+} // namespace AudioCore
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
new file mode 100644
index 000000000..282f345c5
--- /dev/null
+++ b/src/audio_core/audio_renderer.cpp
@@ -0,0 +1,234 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "audio_core/audio_renderer.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/memory.h"
+
+namespace AudioCore {
+
+constexpr u32 STREAM_SAMPLE_RATE{48000};
+constexpr u32 STREAM_NUM_CHANNELS{2};
+
+AudioRenderer::AudioRenderer(AudioRendererParameter params,
+ Kernel::SharedPtr<Kernel::Event> buffer_event)
+ : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) {
+
+ audio_core = std::make_unique<AudioCore::AudioOut>();
+ stream = audio_core->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer",
+ [=]() { buffer_event->Signal(); });
+ audio_core->StartStream(stream);
+
+ QueueMixedBuffer(0);
+ QueueMixedBuffer(1);
+ QueueMixedBuffer(2);
+}
+
+std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) {
+ // Copy UpdateDataHeader struct
+ UpdateDataHeader config{};
+ std::memcpy(&config, input_params.data(), sizeof(UpdateDataHeader));
+ u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
+
+ // Copy MemoryPoolInfo structs
+ std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
+ std::memcpy(mem_pool_info.data(),
+ input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size,
+ memory_pool_count * sizeof(MemoryPoolInfo));
+
+ // Copy VoiceInfo structs
+ size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
+ config.voice_resource_size};
+ for (auto& voice : voices) {
+ std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo));
+ offset += sizeof(VoiceInfo);
+ }
+
+ // Update voices
+ for (auto& voice : voices) {
+ voice.UpdateState();
+ if (!voice.GetInfo().is_in_use) {
+ continue;
+ }
+ if (voice.GetInfo().is_new) {
+ voice.SetWaveIndex(voice.GetInfo().wave_buffer_head);
+ }
+ }
+
+ // Update memory pool state
+ std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
+ for (size_t index = 0; index < memory_pool.size(); ++index) {
+ if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
+ memory_pool[index].state = MemoryPoolStates::Attached;
+ } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
+ memory_pool[index].state = MemoryPoolStates::Detached;
+ }
+ }
+
+ // Release previous buffers and queue next ones for playback
+ ReleaseAndQueueBuffers();
+
+ // Copy output header
+ UpdateDataHeader response_data{worker_params};
+ std::vector<u8> output_params(response_data.total_size);
+ std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader));
+
+ // Copy output memory pool entries
+ std::memcpy(output_params.data() + sizeof(UpdateDataHeader), memory_pool.data(),
+ response_data.memory_pools_size);
+
+ // Copy output voice status
+ size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
+ for (const auto& voice : voices) {
+ std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
+ sizeof(VoiceOutStatus));
+ voice_out_status_offset += sizeof(VoiceOutStatus);
+ }
+
+ return output_params;
+}
+
+void AudioRenderer::VoiceState::SetWaveIndex(size_t index) {
+ wave_index = index & 3;
+ is_refresh_pending = true;
+}
+
+std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) {
+ if (!IsPlaying()) {
+ return {};
+ }
+
+ if (is_refresh_pending) {
+ RefreshBuffer();
+ }
+
+ const size_t max_size{samples.size() - offset};
+ const size_t dequeue_offset{offset};
+ size_t size{sample_count * STREAM_NUM_CHANNELS};
+ if (size > max_size) {
+ size = max_size;
+ }
+
+ out_status.played_sample_count += size / STREAM_NUM_CHANNELS;
+ offset += size;
+
+ const auto& wave_buffer{info.wave_buffer[wave_index]};
+ if (offset == samples.size()) {
+ offset = 0;
+
+ if (!wave_buffer.is_looping) {
+ SetWaveIndex(wave_index + 1);
+ }
+
+ out_status.wave_buffer_consumed++;
+
+ if (wave_buffer.end_of_stream) {
+ info.play_state = PlayState::Paused;
+ }
+ }
+
+ return {samples.begin() + dequeue_offset, samples.begin() + dequeue_offset + size};
+}
+
+void AudioRenderer::VoiceState::UpdateState() {
+ if (is_in_use && !info.is_in_use) {
+ // No longer in use, reset state
+ is_refresh_pending = true;
+ wave_index = 0;
+ offset = 0;
+ out_status = {};
+ }
+ is_in_use = info.is_in_use;
+}
+
+void AudioRenderer::VoiceState::RefreshBuffer() {
+ std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16));
+ Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(),
+ info.wave_buffer[wave_index].buffer_sz);
+
+ switch (static_cast<Codec::PcmFormat>(info.sample_format)) {
+ case Codec::PcmFormat::Int16: {
+ // PCM16 is played as-is
+ break;
+ }
+ case Codec::PcmFormat::Adpcm: {
+ // Decode ADPCM to PCM16
+ Codec::ADPCM_Coeff coeffs;
+ Memory::ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff));
+ new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()),
+ new_samples.size() * sizeof(s16), coeffs, adpcm_state);
+ break;
+ }
+ default:
+ LOG_CRITICAL(Audio, "Unimplemented sample_format={}", info.sample_format);
+ UNREACHABLE();
+ break;
+ }
+
+ switch (info.channel_count) {
+ case 1:
+ // 1 channel is upsampled to 2 channel
+ samples.resize(new_samples.size() * 2);
+ for (size_t index = 0; index < new_samples.size(); ++index) {
+ samples[index * 2] = new_samples[index];
+ samples[index * 2 + 1] = new_samples[index];
+ }
+ break;
+ case 2: {
+ // 2 channel is played as is
+ samples = std::move(new_samples);
+ break;
+ }
+ default:
+ LOG_CRITICAL(Audio, "Unimplemented channel_count={}", info.channel_count);
+ UNREACHABLE();
+ break;
+ }
+
+ is_refresh_pending = false;
+}
+
+static constexpr s16 ClampToS16(s32 value) {
+ return static_cast<s16>(std::clamp(value, -32768, 32767));
+}
+
+void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
+ constexpr size_t BUFFER_SIZE{512};
+ std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
+
+ for (auto& voice : voices) {
+ if (!voice.IsPlaying()) {
+ continue;
+ }
+
+ size_t offset{};
+ s64 samples_remaining{BUFFER_SIZE};
+ while (samples_remaining > 0) {
+ const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};
+
+ if (samples.empty()) {
+ break;
+ }
+
+ samples_remaining -= samples.size();
+
+ for (const auto& sample : samples) {
+ const s32 buffer_sample{buffer[offset]};
+ buffer[offset++] =
+ ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume));
+ }
+ }
+ }
+ audio_core->QueueBuffer(stream, tag, std::move(buffer));
+}
+
+void AudioRenderer::ReleaseAndQueueBuffers() {
+ const auto released_buffers{audio_core->GetTagsAndReleaseBuffers(stream, 2)};
+ for (const auto& tag : released_buffers) {
+ QueueMixedBuffer(tag);
+ }
+}
+
+} // namespace AudioCore
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
new file mode 100644
index 000000000..6950a4681
--- /dev/null
+++ b/src/audio_core/audio_renderer.h
@@ -0,0 +1,206 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <memory>
+#include <vector>
+
+#include "audio_core/audio_out.h"
+#include "audio_core/codec.h"
+#include "audio_core/stream.h"
+#include "common/common_types.h"
+#include "common/swap.h"
+#include "core/hle/kernel/event.h"
+
+namespace AudioCore {
+
+enum class PlayState : u8 {
+ Started = 0,
+ Stopped = 1,
+ Paused = 2,
+};
+
+struct AudioRendererParameter {
+ u32_le sample_rate;
+ u32_le sample_count;
+ u32_le unknown_8;
+ u32_le unknown_c;
+ u32_le voice_count;
+ u32_le sink_count;
+ u32_le effect_count;
+ u32_le unknown_1c;
+ u8 unknown_20;
+ INSERT_PADDING_BYTES(3);
+ u32_le splitter_count;
+ u32_le unknown_2c;
+ INSERT_PADDING_WORDS(1);
+ u32_le revision;
+};
+static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
+
+enum class MemoryPoolStates : u32 { // Should be LE
+ Invalid = 0x0,
+ Unknown = 0x1,
+ RequestDetach = 0x2,
+ Detached = 0x3,
+ RequestAttach = 0x4,
+ Attached = 0x5,
+ Released = 0x6,
+};
+
+struct MemoryPoolEntry {
+ MemoryPoolStates state;
+ u32_le unknown_4;
+ u32_le unknown_8;
+ u32_le unknown_c;
+};
+static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
+
+struct MemoryPoolInfo {
+ u64_le pool_address;
+ u64_le pool_size;
+ MemoryPoolStates pool_state;
+ INSERT_PADDING_WORDS(3); // Unknown
+};
+static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
+struct BiquadFilter {
+ u8 enable;
+ INSERT_PADDING_BYTES(1);
+ std::array<s16_le, 3> numerator;
+ std::array<s16_le, 2> denominator;
+};
+static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
+
+struct WaveBuffer {
+ u64_le buffer_addr;
+ u64_le buffer_sz;
+ s32_le start_sample_offset;
+ s32_le end_sample_offset;
+ u8 is_looping;
+ u8 end_of_stream;
+ u8 sent_to_server;
+ INSERT_PADDING_BYTES(5);
+ u64 context_addr;
+ u64 context_sz;
+ INSERT_PADDING_BYTES(8);
+};
+static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
+
+struct VoiceInfo {
+ u32_le id;
+ u32_le node_id;
+ u8 is_new;
+ u8 is_in_use;
+ PlayState play_state;
+ u8 sample_format;
+ u32_le sample_rate;
+ u32_le priority;
+ u32_le sorting_order;
+ u32_le channel_count;
+ float_le pitch;
+ float_le volume;
+ std::array<BiquadFilter, 2> biquad_filter;
+ u32_le wave_buffer_count;
+ u32_le wave_buffer_head;
+ INSERT_PADDING_WORDS(1);
+ u64_le additional_params_addr;
+ u64_le additional_params_sz;
+ u32_le mix_id;
+ u32_le splitter_info_id;
+ std::array<WaveBuffer, 4> wave_buffer;
+ std::array<u32_le, 6> voice_channel_resource_ids;
+ INSERT_PADDING_BYTES(24);
+};
+static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
+
+struct VoiceOutStatus {
+ u64_le played_sample_count;
+ u32_le wave_buffer_consumed;
+ u32_le voice_drops_count;
+};
+static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
+
+struct UpdateDataHeader {
+ UpdateDataHeader() {}
+
+ explicit UpdateDataHeader(const AudioRendererParameter& config) {
+ revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
+ behavior_size = 0xb0;
+ memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
+ voices_size = config.voice_count * 0x10;
+ voice_resource_size = 0x0;
+ effects_size = config.effect_count * 0x10;
+ mixes_size = 0x0;
+ sinks_size = config.sink_count * 0x20;
+ performance_manager_size = 0x10;
+ total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
+ effects_size + sinks_size + performance_manager_size;
+ }
+
+ u32_le revision;
+ u32_le behavior_size;
+ u32_le memory_pools_size;
+ u32_le voices_size;
+ u32_le voice_resource_size;
+ u32_le effects_size;
+ u32_le mixes_size;
+ u32_le sinks_size;
+ u32_le performance_manager_size;
+ INSERT_PADDING_WORDS(6);
+ u32_le total_size;
+};
+static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
+
+class AudioRenderer {
+public:
+ AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
+ std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
+ void QueueMixedBuffer(Buffer::Tag tag);
+ void ReleaseAndQueueBuffers();
+
+private:
+ class VoiceState {
+ public:
+ bool IsPlaying() const {
+ return is_in_use && info.play_state == PlayState::Started;
+ }
+
+ const VoiceOutStatus& GetOutStatus() const {
+ return out_status;
+ }
+
+ const VoiceInfo& GetInfo() const {
+ return info;
+ }
+
+ VoiceInfo& Info() {
+ return info;
+ }
+
+ void SetWaveIndex(size_t index);
+ std::vector<s16> DequeueSamples(size_t sample_count);
+ void UpdateState();
+ void RefreshBuffer();
+
+ private:
+ bool is_in_use{};
+ bool is_refresh_pending{};
+ size_t wave_index{};
+ size_t offset{};
+ Codec::ADPCMState adpcm_state{};
+ std::vector<s16> samples;
+ VoiceOutStatus out_status{};
+ VoiceInfo info{};
+ };
+
+ AudioRendererParameter worker_params;
+ Kernel::SharedPtr<Kernel::Event> buffer_event;
+ std::vector<VoiceState> voices;
+ std::unique_ptr<AudioCore::AudioOut> audio_core;
+ AudioCore::StreamPtr stream;
+};
+
+} // namespace AudioCore
diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h
new file mode 100644
index 000000000..a323b23ec
--- /dev/null
+++ b/src/audio_core/buffer.h
@@ -0,0 +1,45 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace AudioCore {
+
+/**
+ * Represents a buffer of audio samples to be played in an audio stream
+ */
+class Buffer {
+public:
+ using Tag = u64;
+
+ Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
+
+ /// Returns the raw audio data for the buffer
+ std::vector<s16>& Samples() {
+ return samples;
+ }
+
+ /// Returns the raw audio data for the buffer
+ const std::vector<s16>& GetSamples() const {
+ return samples;
+ }
+
+ /// Returns the buffer tag, this is provided by the game to the audout service
+ Tag GetTag() const {
+ return tag;
+ }
+
+private:
+ Tag tag;
+ std::vector<s16> samples;
+};
+
+using BufferPtr = std::shared_ptr<Buffer>;
+
+} // namespace AudioCore
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
new file mode 100644
index 000000000..c3021403f
--- /dev/null
+++ b/src/audio_core/codec.cpp
@@ -0,0 +1,77 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+
+#include "audio_core/codec.h"
+
+namespace AudioCore::Codec {
+
+std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff,
+ ADPCMState& state) {
+ // GC-ADPCM with scale factor and variable coefficients.
+ // Frames are 8 bytes long containing 14 samples each.
+ // Samples are 4 bits (one nibble) long.
+
+ constexpr size_t FRAME_LEN = 8;
+ constexpr size_t SAMPLES_PER_FRAME = 14;
+ constexpr std::array<int, 16> SIGNED_NIBBLES = {
+ {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
+
+ const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
+ const size_t ret_size =
+ sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
+ std::vector<s16> ret(ret_size);
+
+ int yn1 = state.yn1, yn2 = state.yn2;
+
+ const size_t NUM_FRAMES =
+ (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
+ for (size_t framei = 0; framei < NUM_FRAMES; framei++) {
+ const int frame_header = data[framei * FRAME_LEN];
+ const int scale = 1 << (frame_header & 0xF);
+ const int idx = (frame_header >> 4) & 0x7;
+
+ // Coefficients are fixed point with 11 bits fractional part.
+ const int coef1 = coeff[idx * 2 + 0];
+ const int coef2 = coeff[idx * 2 + 1];
+
+ // Decodes an audio sample. One nibble produces one sample.
+ const auto decode_sample = [&](const int nibble) -> s16 {
+ const int xn = nibble * scale;
+ // We first transform everything into 11 bit fixed point, perform the second order
+ // digital filter, then transform back.
+ // 0x400 == 0.5 in 11 bit fixed point.
+ // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2]
+ int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11;
+ // Clamp to output range.
+ val = std::clamp<s32>(val, -32768, 32767);
+ // Advance output feedback.
+ yn2 = yn1;
+ yn1 = val;
+ return static_cast<s16>(val);
+ };
+
+ size_t outputi = framei * SAMPLES_PER_FRAME;
+ size_t datai = framei * FRAME_LEN + 1;
+ for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
+ const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
+ ret[outputi] = sample1;
+ outputi++;
+
+ const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]);
+ ret[outputi] = sample2;
+ outputi++;
+
+ datai++;
+ }
+ }
+
+ state.yn1 = yn1;
+ state.yn2 = yn2;
+
+ return ret;
+}
+
+} // namespace AudioCore::Codec
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h
new file mode 100644
index 000000000..3f845c42c
--- /dev/null
+++ b/src/audio_core/codec.h
@@ -0,0 +1,44 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace AudioCore::Codec {
+
+enum class PcmFormat : u32 {
+ Invalid = 0,
+ Int8 = 1,
+ Int16 = 2,
+ Int24 = 3,
+ Int32 = 4,
+ PcmFloat = 5,
+ Adpcm = 6,
+};
+
+/// See: Codec::DecodeADPCM
+struct ADPCMState {
+ // Two historical samples from previous processed buffer,
+ // required for ADPCM decoding
+ s16 yn1; ///< y[n-1]
+ s16 yn2; ///< y[n-2]
+};
+
+using ADPCM_Coeff = std::array<s16, 16>;
+
+/**
+ * @param data Pointer to buffer that contains ADPCM data to decode
+ * @param size Size of buffer in bytes
+ * @param coeff ADPCM coefficients
+ * @param state ADPCM state, this is updated with new state
+ * @return Decoded stereo signed PCM16 data, sample_count in length
+ */
+std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff,
+ ADPCMState& state);
+
+}; // namespace AudioCore::Codec
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
new file mode 100644
index 000000000..1501ef1f4
--- /dev/null
+++ b/src/audio_core/cubeb_sink.cpp
@@ -0,0 +1,200 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <cstring>
+
+#include "audio_core/cubeb_sink.h"
+#include "audio_core/stream.h"
+#include "common/logging/log.h"
+
+namespace AudioCore {
+
+class SinkStreamImpl final : public SinkStream {
+public:
+ SinkStreamImpl(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
+ const std::string& name)
+ : ctx{ctx}, num_channels{num_channels_} {
+
+ if (num_channels == 6) {
+ // 6-channel audio does not seem to work with cubeb + SDL, so we downsample this to 2
+ // channel for now
+ is_6_channel = true;
+ num_channels = 2;
+ }
+
+ cubeb_stream_params params{};
+ params.rate = sample_rate;
+ params.channels = num_channels;
+ params.format = CUBEB_SAMPLE_S16NE;
+ params.layout = num_channels == 1 ? CUBEB_LAYOUT_MONO : CUBEB_LAYOUT_STEREO;
+
+ u32 minimum_latency{};
+ if (cubeb_get_min_latency(ctx, &params, &minimum_latency) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error getting minimum latency");
+ }
+
+ if (cubeb_stream_init(ctx, &stream_backend, name.c_str(), nullptr, nullptr, output_device,
+ &params, std::max(512u, minimum_latency),
+ &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback,
+ this) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream");
+ return;
+ }
+
+ if (cubeb_stream_start(stream_backend) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream");
+ return;
+ }
+ }
+
+ ~SinkStreamImpl() {
+ if (!ctx) {
+ return;
+ }
+
+ if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
+ }
+
+ cubeb_stream_destroy(stream_backend);
+ }
+
+ void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) override {
+ if (!ctx) {
+ return;
+ }
+
+ queue.reserve(queue.size() + samples.size() * GetNumChannels());
+
+ if (is_6_channel) {
+ // Downsample 6 channels to 2
+ const size_t sample_count_copy_size = samples.size() * 2;
+ queue.reserve(sample_count_copy_size);
+ for (size_t i = 0; i < samples.size(); i += num_channels) {
+ queue.push_back(samples[i]);
+ queue.push_back(samples[i + 1]);
+ }
+ } else {
+ // Copy as-is
+ std::copy(samples.begin(), samples.end(), std::back_inserter(queue));
+ }
+ }
+
+ u32 GetNumChannels() const {
+ return num_channels;
+ }
+
+private:
+ std::vector<std::string> device_list;
+
+ cubeb* ctx{};
+ cubeb_stream* stream_backend{};
+ u32 num_channels{};
+ bool is_6_channel{};
+
+ std::vector<s16> queue;
+
+ static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
+ void* output_buffer, long num_frames);
+ static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state);
+};
+
+CubebSink::CubebSink(std::string target_device_name) {
+ if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
+ return;
+ }
+
+ if (target_device_name != auto_device_name && !target_device_name.empty()) {
+ cubeb_device_collection collection;
+ if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
+ LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
+ } else {
+ const auto collection_end{collection.device + collection.count};
+ const auto device{std::find_if(collection.device, collection_end,
+ [&](const cubeb_device_info& device) {
+ return target_device_name == device.friendly_name;
+ })};
+ if (device != collection_end) {
+ output_device = device->devid;
+ }
+ cubeb_device_collection_destroy(ctx, &collection);
+ }
+ }
+}
+
+CubebSink::~CubebSink() {
+ if (!ctx) {
+ return;
+ }
+
+ for (auto& sink_stream : sink_streams) {
+ sink_stream.reset();
+ }
+
+ cubeb_destroy(ctx);
+}
+
+SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
+ const std::string& name) {
+ sink_streams.push_back(
+ std::make_unique<SinkStreamImpl>(ctx, sample_rate, num_channels, output_device, name));
+ return *sink_streams.back();
+}
+
+long SinkStreamImpl::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
+ void* output_buffer, long num_frames) {
+ SinkStreamImpl* impl = static_cast<SinkStreamImpl*>(user_data);
+ u8* buffer = reinterpret_cast<u8*>(output_buffer);
+
+ if (!impl) {
+ return {};
+ }
+
+ const size_t frames_to_write{
+ std::min(impl->queue.size() / impl->GetNumChannels(), static_cast<size_t>(num_frames))};
+
+ memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * impl->GetNumChannels());
+ impl->queue.erase(impl->queue.begin(),
+ impl->queue.begin() + frames_to_write * impl->GetNumChannels());
+
+ if (frames_to_write < num_frames) {
+ // Fill the rest of the frames with silence
+ memset(buffer + frames_to_write * sizeof(s16) * impl->GetNumChannels(), 0,
+ (num_frames - frames_to_write) * sizeof(s16) * impl->GetNumChannels());
+ }
+
+ return num_frames;
+}
+
+void SinkStreamImpl::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
+
+std::vector<std::string> ListCubebSinkDevices() {
+ std::vector<std::string> device_list;
+ cubeb* ctx;
+
+ if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
+ return {};
+ }
+
+ cubeb_device_collection collection;
+ if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
+ LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
+ } else {
+ for (size_t i = 0; i < collection.count; i++) {
+ const cubeb_device_info& device = collection.device[i];
+ if (device.friendly_name) {
+ device_list.emplace_back(device.friendly_name);
+ }
+ }
+ cubeb_device_collection_destroy(ctx, &collection);
+ }
+
+ cubeb_destroy(ctx);
+ return device_list;
+}
+
+} // namespace AudioCore
diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h
new file mode 100644
index 000000000..59cbf05e9
--- /dev/null
+++ b/src/audio_core/cubeb_sink.h
@@ -0,0 +1,32 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <cubeb/cubeb.h>
+
+#include "audio_core/sink.h"
+
+namespace AudioCore {
+
+class CubebSink final : public Sink {
+public:
+ explicit CubebSink(std::string device_id);
+ ~CubebSink() override;
+
+ SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
+ const std::string& name) override;
+
+private:
+ cubeb* ctx{};
+ cubeb_devid output_device{};
+ std::vector<SinkStreamPtr> sink_streams;
+};
+
+std::vector<std::string> ListCubebSinkDevices();
+
+} // namespace AudioCore
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
new file mode 100644
index 000000000..f235d93e5
--- /dev/null
+++ b/src/audio_core/null_sink.h
@@ -0,0 +1,27 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "audio_core/sink.h"
+
+namespace AudioCore {
+
+class NullSink final : public Sink {
+public:
+ explicit NullSink(std::string){};
+ ~NullSink() override = default;
+
+ SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/,
+ const std::string& /*name*/) override {
+ return null_sink_stream;
+ }
+
+private:
+ struct NullSinkStreamImpl final : SinkStream {
+ void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {}
+ } null_sink_stream;
+};
+
+} // namespace AudioCore
diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h
new file mode 100644
index 000000000..95c7b2b6e
--- /dev/null
+++ b/src/audio_core/sink.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "audio_core/sink_stream.h"
+#include "common/common_types.h"
+
+namespace AudioCore {
+
+constexpr char auto_device_name[] = "auto";
+
+/**
+ * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed
+ * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate.
+ * They are dumb outputs.
+ */
+class Sink {
+public:
+ virtual ~Sink() = default;
+ virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
+ const std::string& name) = 0;
+};
+
+using SinkPtr = std::unique_ptr<Sink>;
+
+} // namespace AudioCore
diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp
new file mode 100644
index 000000000..955ba20fb
--- /dev/null
+++ b/src/audio_core/sink_details.cpp
@@ -0,0 +1,44 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+#include "audio_core/null_sink.h"
+#include "audio_core/sink_details.h"
+#ifdef HAVE_CUBEB
+#include "audio_core/cubeb_sink.h"
+#endif
+#include "common/logging/log.h"
+
+namespace AudioCore {
+
+// g_sink_details is ordered in terms of desirability, with the best choice at the top.
+const std::vector<SinkDetails> g_sink_details = {
+#ifdef HAVE_CUBEB
+ SinkDetails{"cubeb", &std::make_unique<CubebSink, std::string>, &ListCubebSinkDevices},
+#endif
+ SinkDetails{"null", &std::make_unique<NullSink, std::string>,
+ [] { return std::vector<std::string>{"null"}; }},
+};
+
+const SinkDetails& GetSinkDetails(std::string sink_id) {
+ auto iter =
+ std::find_if(g_sink_details.begin(), g_sink_details.end(),
+ [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
+
+ if (sink_id == "auto" || iter == g_sink_details.end()) {
+ if (sink_id != "auto") {
+ LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id);
+ }
+ // Auto-select.
+ // g_sink_details is ordered in terms of desirability, with the best choice at the front.
+ iter = g_sink_details.begin();
+ }
+
+ return *iter;
+}
+
+} // namespace AudioCore
diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h
new file mode 100644
index 000000000..ea666c554
--- /dev/null
+++ b/src/audio_core/sink_details.h
@@ -0,0 +1,35 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace AudioCore {
+
+class Sink;
+
+struct SinkDetails {
+ using FactoryFn = std::function<std::unique_ptr<Sink>(std::string)>;
+ using ListDevicesFn = std::function<std::vector<std::string>()>;
+
+ SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_)
+ : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {}
+
+ /// Name for this sink.
+ const char* id;
+ /// A method to call to construct an instance of this type of sink.
+ FactoryFn factory;
+ /// A method to call to list available devices.
+ ListDevicesFn list_devices;
+};
+
+extern const std::vector<SinkDetails> g_sink_details;
+
+const SinkDetails& GetSinkDetails(std::string sink_id);
+
+} // namespace AudioCore
diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h
new file mode 100644
index 000000000..41b6736d8
--- /dev/null
+++ b/src/audio_core/sink_stream.h
@@ -0,0 +1,32 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace AudioCore {
+
+/**
+ * Accepts samples in stereo signed PCM16 format to be output. Sinks *do not* handle resampling and
+ * expect the correct sample rate. They are dumb outputs.
+ */
+class SinkStream {
+public:
+ virtual ~SinkStream() = default;
+
+ /**
+ * Feed stereo samples to sink.
+ * @param num_channels Number of channels used.
+ * @param samples Samples in interleaved stereo PCM16 format.
+ */
+ virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0;
+};
+
+using SinkStreamPtr = std::unique_ptr<SinkStream>;
+
+} // namespace AudioCore
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
new file mode 100644
index 000000000..ad9e2915c
--- /dev/null
+++ b/src/audio_core/stream.cpp
@@ -0,0 +1,127 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <cmath>
+
+#include "audio_core/sink.h"
+#include "audio_core/sink_details.h"
+#include "audio_core/stream.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/core_timing.h"
+#include "core/core_timing_util.h"
+#include "core/settings.h"
+
+namespace AudioCore {
+
+constexpr size_t MaxAudioBufferCount{32};
+
+u32 Stream::GetNumChannels() const {
+ switch (format) {
+ case Format::Mono16:
+ return 1;
+ case Format::Stereo16:
+ return 2;
+ case Format::Multi51Channel16:
+ return 6;
+ }
+ LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ return {};
+}
+
+Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
+ SinkStream& sink_stream, std::string&& name_)
+ : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
+ sink_stream{sink_stream}, name{std::move(name_)} {
+
+ release_event = CoreTiming::RegisterEvent(
+ name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
+}
+
+void Stream::Play() {
+ state = State::Playing;
+ PlayNextBuffer();
+}
+
+void Stream::Stop() {
+ ASSERT_MSG(false, "Unimplemented");
+}
+
+s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
+ const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
+ return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
+}
+
+static void VolumeAdjustSamples(std::vector<s16>& samples) {
+ const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)};
+
+ if (volume == 1.0f) {
+ return;
+ }
+
+ // Implementation of a volume slider with a dynamic range of 60 dB
+ const float volume_scale_factor{std::exp(6.90775f * volume) * 0.001f};
+ for (auto& sample : samples) {
+ sample = static_cast<s16>(sample * volume_scale_factor);
+ }
+}
+
+void Stream::PlayNextBuffer() {
+ if (!IsPlaying()) {
+ // Ensure we are in playing state before playing the next buffer
+ return;
+ }
+
+ if (active_buffer) {
+ // Do not queue a new buffer if we are already playing a buffer
+ return;
+ }
+
+ if (queued_buffers.empty()) {
+ // No queued buffers - we are effectively paused
+ return;
+ }
+
+ active_buffer = queued_buffers.front();
+ queued_buffers.pop();
+
+ VolumeAdjustSamples(active_buffer->Samples());
+ sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
+
+ CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
+}
+
+void Stream::ReleaseActiveBuffer() {
+ ASSERT(active_buffer);
+ released_buffers.push(std::move(active_buffer));
+ release_callback();
+ PlayNextBuffer();
+}
+
+bool Stream::QueueBuffer(BufferPtr&& buffer) {
+ if (queued_buffers.size() < MaxAudioBufferCount) {
+ queued_buffers.push(std::move(buffer));
+ PlayNextBuffer();
+ return true;
+ }
+ return false;
+}
+
+bool Stream::ContainsBuffer(Buffer::Tag tag) const {
+ ASSERT_MSG(false, "Unimplemented");
+ return {};
+}
+
+std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) {
+ std::vector<Buffer::Tag> tags;
+ for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) {
+ tags.push_back(released_buffers.front()->GetTag());
+ released_buffers.pop();
+ }
+ return tags;
+}
+
+} // namespace AudioCore
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
new file mode 100644
index 000000000..049b92ca9
--- /dev/null
+++ b/src/audio_core/stream.h
@@ -0,0 +1,102 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+#include <queue>
+
+#include "audio_core/buffer.h"
+#include "audio_core/sink_stream.h"
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "core/core_timing.h"
+
+namespace AudioCore {
+
+/**
+ * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
+ */
+class Stream {
+public:
+ /// Audio format of the stream
+ enum class Format {
+ Mono16,
+ Stereo16,
+ Multi51Channel16,
+ };
+
+ /// Callback function type, used to change guest state on a buffer being released
+ using ReleaseCallback = std::function<void()>;
+
+ Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
+ SinkStream& sink_stream, std::string&& name_);
+
+ /// Plays the audio stream
+ void Play();
+
+ /// Stops the audio stream
+ void Stop();
+
+ /// Queues a buffer into the audio stream, returns true on success
+ bool QueueBuffer(BufferPtr&& buffer);
+
+ /// Returns true if the audio stream contains a buffer with the specified tag
+ bool ContainsBuffer(Buffer::Tag tag) const;
+
+ /// Returns a vector of recently released buffers specified by tag
+ std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count);
+
+ /// Returns true if the stream is currently playing
+ bool IsPlaying() const {
+ return state == State::Playing;
+ }
+
+ /// Returns the number of queued buffers
+ size_t GetQueueSize() const {
+ return queued_buffers.size();
+ }
+
+ /// Gets the sample rate
+ u32 GetSampleRate() const {
+ return sample_rate;
+ }
+
+ /// Gets the number of channels
+ u32 GetNumChannels() const;
+
+private:
+ /// Current state of the stream
+ enum class State {
+ Stopped,
+ Playing,
+ };
+
+ /// Plays the next queued buffer in the audio stream, starting playback if necessary
+ void PlayNextBuffer();
+
+ /// Releases the actively playing buffer, signalling that it has been completed
+ void ReleaseActiveBuffer();
+
+ /// Gets the number of core cycles when the specified buffer will be released
+ s64 GetBufferReleaseCycles(const Buffer& buffer) const;
+
+ u32 sample_rate; ///< Sample rate of the stream
+ Format format; ///< Format of the stream
+ ReleaseCallback release_callback; ///< Buffer release callback for the stream
+ State state{State::Stopped}; ///< Playback state of the stream
+ CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream
+ BufferPtr active_buffer; ///< Actively playing buffer in the stream
+ std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
+ std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
+ SinkStream& sink_stream; ///< Output sink for the stream
+ std::string name; ///< Name of the stream, must be unique
+};
+
+using StreamPtr = std::shared_ptr<Stream>;
+
+} // namespace AudioCore
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 93f1c0044..8b0d34da6 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -6,7 +6,7 @@
#include <string>
-#if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM)
+#if !defined(ARCHITECTURE_x86_64)
#include <cstdlib> // for exit
#endif
#include "common/common_types.h"
@@ -32,8 +32,6 @@
#ifdef ARCHITECTURE_x86_64
#define Crash() __asm__ __volatile__("int $3")
-#elif defined(ARCHITECTURE_ARM)
-#define Crash() __asm__ __volatile__("trap")
#else
#define Crash() exit(1)
#endif
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index 6799a357a..df2ce80b1 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -32,6 +32,7 @@
#define SDMC_DIR "sdmc"
#define NAND_DIR "nand"
#define SYSDATA_DIR "sysdata"
+#define KEYS_DIR "keys"
#define LOG_DIR "log"
// Filenames
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index b8dd92b65..7aeda737f 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -706,6 +706,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) {
paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP);
paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP);
paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP);
+ paths.emplace(UserPath::KeysDir, user_path + KEYS_DIR DIR_SEP);
// TODO: Put the logs in a better location for each OS
paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP);
}
@@ -736,6 +737,19 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) {
return paths[path];
}
+std::string GetHactoolConfigurationPath() {
+#ifdef _WIN32
+ PWSTR pw_local_path = nullptr;
+ if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pw_local_path) != S_OK)
+ return "";
+ std::string local_path = Common::UTF16ToUTF8(pw_local_path);
+ CoTaskMemFree(pw_local_path);
+ return local_path + "\\.switch";
+#else
+ return GetHomeDirectory() + "/.switch";
+#endif
+}
+
size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) {
return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size());
}
diff --git a/src/common/file_util.h b/src/common/file_util.h
index bc9272d89..28697d527 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -23,6 +23,7 @@ namespace FileUtil {
enum class UserPath {
CacheDir,
ConfigDir,
+ KeysDir,
LogDir,
NANDDir,
RootDir,
@@ -125,6 +126,8 @@ bool SetCurrentDir(const std::string& directory);
// directory. To be used in "multi-user" mode (that is, installed).
const std::string& GetUserPath(UserPath path, const std::string& new_path = "");
+std::string GetHactoolConfigurationPath();
+
// Returns the path to where the sys file are
std::string GetSysDirectory();
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index ad9edbcdf..355abd682 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -168,26 +168,41 @@ void FileBackend::Write(const Entry& entry) {
SUB(Service, AM) \
SUB(Service, AOC) \
SUB(Service, APM) \
+ SUB(Service, ARP) \
SUB(Service, BCAT) \
+ SUB(Service, BPC) \
+ SUB(Service, BTM) \
+ SUB(Service, Capture) \
SUB(Service, Fatal) \
+ SUB(Service, FGM) \
SUB(Service, Friend) \
SUB(Service, FS) \
SUB(Service, HID) \
+ SUB(Service, LBL) \
SUB(Service, LDN) \
SUB(Service, LM) \
+ SUB(Service, Migration) \
+ SUB(Service, Mii) \
SUB(Service, MM) \
+ SUB(Service, NCM) \
+ SUB(Service, NFC) \
SUB(Service, NFP) \
SUB(Service, NIFM) \
SUB(Service, NS) \
SUB(Service, NVDRV) \
+ SUB(Service, PCIE) \
SUB(Service, PCTL) \
+ SUB(Service, PCV) \
SUB(Service, PREPO) \
+ SUB(Service, PSC) \
SUB(Service, SET) \
SUB(Service, SM) \
SUB(Service, SPL) \
SUB(Service, SSL) \
SUB(Service, Time) \
+ SUB(Service, USB) \
SUB(Service, VI) \
+ SUB(Service, WLAN) \
CLS(HW) \
SUB(HW, Memory) \
SUB(HW, LCD) \
@@ -204,6 +219,7 @@ void FileBackend::Write(const Entry& entry) {
CLS(Input) \
CLS(Network) \
CLS(Loader) \
+ CLS(Crypto) \
CLS(WebService)
// GetClassName is a macro defined by Windows.h, grrr...
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index ad3cbf5d1..a889ebefa 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -54,27 +54,42 @@ enum class Class : ClassType {
Service_AM, ///< The AM (Applet manager) service
Service_AOC, ///< The AOC (AddOn Content) service
Service_APM, ///< The APM (Performance) service
+ Service_ARP, ///< The ARP service
Service_Audio, ///< The Audio (Audio control) service
Service_BCAT, ///< The BCAT service
+ Service_BPC, ///< The BPC service
+ Service_BTM, ///< The BTM service
+ Service_Capture, ///< The capture service
Service_Fatal, ///< The Fatal service
+ Service_FGM, ///< The FGM service
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
+ Service_LBL, ///< The LBL (LCD backlight) service
Service_LDN, ///< The LDN (Local domain network) service
Service_LM, ///< The LM (Logger) service
+ Service_Migration, ///< The migration service
+ Service_Mii, ///< The Mii service
Service_MM, ///< The MM (Multimedia) service
+ Service_NCM, ///< The NCM service
+ Service_NFC, ///< The NFC (Near-field communication) service
Service_NFP, ///< The NFP service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
+ Service_PCIE, ///< The PCIe service
Service_PCTL, ///< The PCTL (Parental control) service
+ Service_PCV, ///< The PCV service
Service_PREPO, ///< The PREPO (Play report) service
+ Service_PSC, ///< The PSC service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_SPL, ///< The SPL service
Service_SSL, ///< The SSL service
Service_Time, ///< The time service
+ Service_USB, ///< The USB (Universal Serial Bus) service
Service_VI, ///< The VI (Video interface) service
+ Service_WLAN, ///< The WLAN (Wireless local area network) service
HW, ///< Low-level hardware emulation
HW_Memory, ///< Memory-map and address translation
HW_LCD, ///< LCD register emulation
@@ -89,6 +104,7 @@ enum class Class : ClassType {
Audio_DSP, ///< The HLE implementation of the DSP
Audio_Sink, ///< Emulator audio output backend
Loader, ///< ROM loader
+ Crypto, ///< Cryptographic engine/functions
Input, ///< Input emulation
Network, ///< Network emulation
WebService, ///< Interface to yuzu Web Services
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h
index c587faefb..9609cec7c 100644
--- a/src/common/logging/text_formatter.h
+++ b/src/common/logging/text_formatter.h
@@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
+#include <string>
namespace Log {
diff --git a/src/common/math_util.h b/src/common/math_util.h
index c6a83c953..343cdd902 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -19,12 +19,12 @@ inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start
template <class T>
struct Rectangle {
- T left;
- T top;
- T right;
- T bottom;
+ T left{};
+ T top{};
+ T right{};
+ T bottom{};
- Rectangle() {}
+ Rectangle() = default;
Rectangle(T left, T top, T right, T bottom)
: left(left), top(top), right(right), bottom(bottom) {}
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 1f0456aee..0ca663032 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -2,12 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
-#include <boost/range/algorithm/transform.hpp>
#include "common/common_paths.h"
#include "common/logging/log.h"
#include "common/string_util.h"
@@ -24,13 +24,15 @@ namespace Common {
/// Make a string lowercase
std::string ToLower(std::string str) {
- boost::transform(str, str.begin(), ::tolower);
+ std::transform(str.begin(), str.end(), str.begin(),
+ [](unsigned char c) { return std::tolower(c); });
return str;
}
/// Make a string uppercase
std::string ToUpper(std::string str) {
- boost::transform(str, str.begin(), ::toupper);
+ std::transform(str.begin(), str.end(), str.begin(),
+ [](unsigned char c) { return std::toupper(c); });
return str;
}
diff --git a/src/common/swap.h b/src/common/swap.h
index fc7af4280..32af0b6ac 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -69,7 +69,7 @@ inline u32 swap32(u32 _data) {
inline u64 swap64(u64 _data) {
return _byteswap_uint64(_data);
}
-#elif ARCHITECTURE_ARM
+#elif defined(ARCHITECTURE_ARM) && (__ARM_ARCH >= 6)
inline u16 swap16(u16 _data) {
u32 data = _data;
__asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data));
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index a0c731e8c..edf13bc49 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -33,9 +33,11 @@ public:
bool Empty() const {
return !read_ptr->next.load();
}
+
T& Front() const {
return read_ptr->current;
}
+
template <typename Arg>
void Push(Arg&& t) {
// create the element, add it to the queue
@@ -108,15 +110,41 @@ private:
// single reader, multiple writer queue
template <typename T, bool NeedSize = true>
-class MPSCQueue : public SPSCQueue<T, NeedSize> {
+class MPSCQueue {
public:
+ u32 Size() const {
+ return spsc_queue.Size();
+ }
+
+ bool Empty() const {
+ return spsc_queue.Empty();
+ }
+
+ T& Front() const {
+ return spsc_queue.Front();
+ }
+
template <typename Arg>
void Push(Arg&& t) {
std::lock_guard<std::mutex> lock(write_lock);
- SPSCQueue<T, NeedSize>::Push(t);
+ spsc_queue.Push(t);
+ }
+
+ void Pop() {
+ return spsc_queue.Pop();
+ }
+
+ bool Pop(T& t) {
+ return spsc_queue.Pop(t);
+ }
+
+ // not thread-safe
+ void Clear() {
+ spsc_queue.Clear();
}
private:
+ SPSCQueue<T, NeedSize> spsc_queue;
std::mutex write_lock;
};
} // namespace Common
diff --git a/src/common/timer.cpp b/src/common/timer.cpp
index f0c5b1a43..2dc15e434 100644
--- a/src/common/timer.cpp
+++ b/src/common/timer.cpp
@@ -3,31 +3,16 @@
// Refer to the license.txt file included.
#include <ctime>
-
#include <fmt/format.h>
-
-#ifdef _WIN32
-#include <windows.h>
-// windows.h needs to be included before other windows headers
-#include <mmsystem.h>
-#include <sys/timeb.h>
-#else
-#include <sys/time.h>
-#endif
#include "common/common_types.h"
#include "common/string_util.h"
#include "common/timer.h"
namespace Common {
-u32 Timer::GetTimeMs() {
-#ifdef _WIN32
- return timeGetTime();
-#else
- struct timeval t;
- (void)gettimeofday(&t, nullptr);
- return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000));
-#endif
+std::chrono::milliseconds Timer::GetTimeMs() {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now().time_since_epoch());
}
// --------------------------------------------
@@ -63,7 +48,7 @@ void Timer::Update() {
// -------------------------------------
// Get the number of milliseconds since the last Update()
-u64 Timer::GetTimeDifference() {
+std::chrono::milliseconds Timer::GetTimeDifference() {
return GetTimeMs() - m_LastTime;
}
@@ -74,11 +59,11 @@ void Timer::AddTimeDifference() {
}
// Get the time elapsed since the Start()
-u64 Timer::GetTimeElapsed() {
+std::chrono::milliseconds Timer::GetTimeElapsed() {
// If we have not started yet, return 1 (because then I don't
// have to change the FPS calculation in CoreRerecording.cpp .
- if (m_StartTime == 0)
- return 1;
+ if (m_StartTime.count() == 0)
+ return std::chrono::milliseconds(1);
// Return the final timer time if the timer is stopped
if (!m_Running)
@@ -90,49 +75,34 @@ u64 Timer::GetTimeElapsed() {
// Get the formatted time elapsed since the Start()
std::string Timer::GetTimeElapsedFormatted() const {
// If we have not started yet, return zero
- if (m_StartTime == 0)
+ if (m_StartTime.count() == 0)
return "00:00:00:000";
// The number of milliseconds since the start.
// Use a different value if the timer is stopped.
- u64 Milliseconds;
+ std::chrono::milliseconds Milliseconds;
if (m_Running)
Milliseconds = GetTimeMs() - m_StartTime;
else
Milliseconds = m_LastTime - m_StartTime;
// Seconds
- u32 Seconds = (u32)(Milliseconds / 1000);
+ std::chrono::seconds Seconds = std::chrono::duration_cast<std::chrono::seconds>(Milliseconds);
// Minutes
- u32 Minutes = Seconds / 60;
+ std::chrono::minutes Minutes = std::chrono::duration_cast<std::chrono::minutes>(Milliseconds);
// Hours
- u32 Hours = Minutes / 60;
+ std::chrono::hours Hours = std::chrono::duration_cast<std::chrono::hours>(Milliseconds);
- std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours, Minutes % 60, Seconds % 60,
- Milliseconds % 1000);
+ std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours.count(), Minutes.count() % 60,
+ Seconds.count() % 60, Milliseconds.count() % 1000);
return TmpStr;
}
-// Get current time
-void Timer::IncreaseResolution() {
-#ifdef _WIN32
- timeBeginPeriod(1);
-#endif
-}
-
-void Timer::RestoreResolution() {
-#ifdef _WIN32
- timeEndPeriod(1);
-#endif
-}
-
// Get the number of seconds since January 1 1970
-u64 Timer::GetTimeSinceJan1970() {
- time_t ltime;
- time(&ltime);
- return ((u64)ltime);
+std::chrono::seconds Timer::GetTimeSinceJan1970() {
+ return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs());
}
-u64 Timer::GetLocalTimeSinceJan1970() {
+std::chrono::seconds Timer::GetLocalTimeSinceJan1970() {
time_t sysTime, tzDiff, tzDST;
struct tm* gmTime;
@@ -149,7 +119,7 @@ u64 Timer::GetLocalTimeSinceJan1970() {
gmTime = gmtime(&sysTime);
tzDiff = sysTime - mktime(gmTime);
- return (u64)(sysTime + tzDiff + tzDST);
+ return std::chrono::seconds(sysTime + tzDiff + tzDST);
}
// Return the current time formatted as Minutes:Seconds:Milliseconds
@@ -164,30 +134,16 @@ std::string Timer::GetTimeFormatted() {
strftime(tmp, 6, "%M:%S", gmTime);
-// Now tack on the milliseconds
-#ifdef _WIN32
- struct timeb tp;
- (void)::ftime(&tp);
- return fmt::format("{}:{:03}", tmp, tp.millitm);
-#else
- struct timeval t;
- (void)gettimeofday(&t, nullptr);
- return fmt::format("{}:{:03}", tmp, static_cast<int>(t.tv_usec / 1000));
-#endif
+ u64 milliseconds = static_cast<u64>(GetTimeMs().count()) % 1000;
+ return fmt::format("{}:{:03}", tmp, milliseconds);
}
// Returns a timestamp with decimals for precise time comparisons
// ----------------
double Timer::GetDoubleTime() {
-#ifdef _WIN32
- struct timeb tp;
- (void)::ftime(&tp);
-#else
- struct timeval t;
- (void)gettimeofday(&t, nullptr);
-#endif
// Get continuous timestamp
- u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970();
+ u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count());
+ double ms = static_cast<u64>(GetTimeMs().count()) % 1000;
// Remove a few years. We only really want enough seconds to make
// sure that we are detecting actual actions, perhaps 60 seconds is
@@ -196,12 +152,7 @@ double Timer::GetDoubleTime() {
TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
// Make a smaller integer that fits in the double
- u32 Seconds = (u32)TmpSeconds;
-#ifdef _WIN32
- double ms = tp.millitm / 1000.0 / 1000.0;
-#else
- double ms = t.tv_usec / 1000000.0;
-#endif
+ u32 Seconds = static_cast<u32>(TmpSeconds);
double TmpTime = Seconds + ms;
return TmpTime;
diff --git a/src/common/timer.h b/src/common/timer.h
index 78d37426b..27b521baa 100644
--- a/src/common/timer.h
+++ b/src/common/timer.h
@@ -4,6 +4,7 @@
#pragma once
+#include <chrono>
#include <string>
#include "common/common_types.h"
@@ -18,24 +19,22 @@ public:
// The time difference is always returned in milliseconds, regardless of alternative internal
// representation
- u64 GetTimeDifference();
+ std::chrono::milliseconds GetTimeDifference();
void AddTimeDifference();
- static void IncreaseResolution();
- static void RestoreResolution();
- static u64 GetTimeSinceJan1970();
- static u64 GetLocalTimeSinceJan1970();
+ static std::chrono::seconds GetTimeSinceJan1970();
+ static std::chrono::seconds GetLocalTimeSinceJan1970();
static double GetDoubleTime();
static std::string GetTimeFormatted();
std::string GetTimeElapsedFormatted() const;
- u64 GetTimeElapsed();
+ std::chrono::milliseconds GetTimeElapsed();
- static u32 GetTimeMs();
+ static std::chrono::milliseconds GetTimeMs();
private:
- u64 m_LastTime;
- u64 m_StartTime;
+ std::chrono::milliseconds m_LastTime;
+ std::chrono::milliseconds m_StartTime;
bool m_Running;
};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b74e495ef..0abf7edc1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -12,6 +12,16 @@ add_library(core STATIC
core_timing.h
core_timing_util.cpp
core_timing_util.h
+ crypto/aes_util.cpp
+ crypto/aes_util.h
+ crypto/encryption_layer.cpp
+ crypto/encryption_layer.h
+ crypto/key_manager.cpp
+ crypto/key_manager.h
+ crypto/ctr_encryption_layer.cpp
+ crypto/ctr_encryption_layer.h
+ file_sys/card_image.cpp
+ file_sys/card_image.h
file_sys/content_archive.cpp
file_sys/content_archive.h
file_sys/control_metadata.cpp
@@ -23,6 +33,8 @@ add_library(core STATIC
file_sys/partition_filesystem.h
file_sys/program_metadata.cpp
file_sys/program_metadata.h
+ file_sys/romfs.cpp
+ file_sys/romfs.h
file_sys/romfs_factory.cpp
file_sys/romfs_factory.h
file_sys/savedata_factory.cpp
@@ -35,6 +47,8 @@ add_library(core STATIC
file_sys/vfs_offset.h
file_sys/vfs_real.cpp
file_sys/vfs_real.h
+ file_sys/vfs_vector.cpp
+ file_sys/vfs_vector.h
frontend/emu_window.cpp
frontend/emu_window.h
frontend/framebuffer_layout.cpp
@@ -59,12 +73,10 @@ add_library(core STATIC
hle/kernel/hle_ipc.h
hle/kernel/kernel.cpp
hle/kernel/kernel.h
- hle/kernel/memory.cpp
- hle/kernel/memory.h
hle/kernel/mutex.cpp
hle/kernel/mutex.h
- hle/kernel/object_address_table.cpp
- hle/kernel/object_address_table.h
+ hle/kernel/object.cpp
+ hle/kernel/object.h
hle/kernel/process.cpp
hle/kernel/process.h
hle/kernel/resource_limit.cpp
@@ -110,23 +122,41 @@ add_library(core STATIC
hle/service/am/applet_ae.h
hle/service/am/applet_oe.cpp
hle/service/am/applet_oe.h
+ hle/service/am/idle.cpp
+ hle/service/am/idle.h
+ hle/service/am/omm.cpp
+ hle/service/am/omm.h
+ hle/service/am/spsm.cpp
+ hle/service/am/spsm.h
hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
hle/service/apm/apm.h
hle/service/apm/interface.cpp
hle/service/apm/interface.h
+ hle/service/arp/arp.cpp
+ hle/service/arp/arp.h
+ hle/service/audio/audctl.cpp
+ hle/service/audio/audctl.h
+ hle/service/audio/auddbg.cpp
+ hle/service/audio/auddbg.h
+ hle/service/audio/audin_a.cpp
+ hle/service/audio/audin_a.h
hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
+ hle/service/audio/audout_a.cpp
+ hle/service/audio/audout_a.h
hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h
+ hle/service/audio/audrec_a.cpp
+ hle/service/audio/audrec_a.h
hle/service/audio/audrec_u.cpp
hle/service/audio/audrec_u.h
+ hle/service/audio/audren_a.cpp
+ hle/service/audio/audren_a.h
hle/service/audio/audren_u.cpp
- hle/service/audio/audren_u.cpp
- hle/service/audio/audren_u.h
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
@@ -136,6 +166,14 @@ add_library(core STATIC
hle/service/bcat/bcat.h
hle/service/bcat/module.cpp
hle/service/bcat/module.h
+ hle/service/bpc/bpc.cpp
+ hle/service/bpc/bpc.h
+ hle/service/btdrv/btdrv.cpp
+ hle/service/btdrv/btdrv.h
+ hle/service/btm/btm.cpp
+ hle/service/btm/btm.h
+ hle/service/caps/caps.cpp
+ hle/service/caps/caps.h
hle/service/erpt/erpt.cpp
hle/service/erpt/erpt.h
hle/service/es/es.cpp
@@ -150,8 +188,14 @@ add_library(core STATIC
hle/service/fatal/fatal_u.h
hle/service/filesystem/filesystem.cpp
hle/service/filesystem/filesystem.h
+ hle/service/filesystem/fsp_ldr.cpp
+ hle/service/filesystem/fsp_ldr.h
+ hle/service/filesystem/fsp_pr.cpp
+ hle/service/filesystem/fsp_pr.h
hle/service/filesystem/fsp_srv.cpp
hle/service/filesystem/fsp_srv.h
+ hle/service/fgm/fgm.cpp
+ hle/service/fgm/fgm.h
hle/service/friend/friend.cpp
hle/service/friend/friend.h
hle/service/friend/interface.cpp
@@ -164,14 +208,24 @@ add_library(core STATIC
hle/service/hid/irs.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
+ hle/service/lbl/lbl.cpp
+ hle/service/lbl/lbl.h
hle/service/ldn/ldn.cpp
hle/service/ldn/ldn.h
hle/service/ldr/ldr.cpp
hle/service/ldr/ldr.h
hle/service/lm/lm.cpp
hle/service/lm/lm.h
+ hle/service/mig/mig.cpp
+ hle/service/mig/mig.h
+ hle/service/mii/mii.cpp
+ hle/service/mii/mii.h
hle/service/mm/mm_u.cpp
hle/service/mm/mm_u.h
+ hle/service/ncm/ncm.cpp
+ hle/service/ncm/ncm.h
+ hle/service/nfc/nfc.cpp
+ hle/service/nfc/nfc.h
hle/service/nfp/nfp.cpp
hle/service/nfp/nfp.h
hle/service/nfp/nfp_user.cpp
@@ -209,14 +263,20 @@ add_library(core STATIC
hle/service/nvflinger/buffer_queue.h
hle/service/nvflinger/nvflinger.cpp
hle/service/nvflinger/nvflinger.h
+ hle/service/pcie/pcie.cpp
+ hle/service/pcie/pcie.h
hle/service/pctl/module.cpp
hle/service/pctl/module.h
hle/service/pctl/pctl.cpp
hle/service/pctl/pctl.h
+ hle/service/pcv/pcv.cpp
+ hle/service/pcv/pcv.h
hle/service/pm/pm.cpp
hle/service/pm/pm.h
hle/service/prepo/prepo.cpp
hle/service/prepo/prepo.h
+ hle/service/psc/psc.cpp
+ hle/service/psc/psc.h
hle/service/service.cpp
hle/service/service.h
hle/service/set/set.cpp
@@ -255,6 +315,8 @@ add_library(core STATIC
hle/service/time/interface.h
hle/service/time/time.cpp
hle/service/time/time.h
+ hle/service/usb/usb.cpp
+ hle/service/usb/usb.h
hle/service/vi/vi.cpp
hle/service/vi/vi.h
hle/service/vi/vi_m.cpp
@@ -263,10 +325,8 @@ add_library(core STATIC
hle/service/vi/vi_s.h
hle/service/vi/vi_u.cpp
hle/service/vi/vi_u.h
- hw/hw.cpp
- hw/hw.h
- hw/lcd.cpp
- hw/lcd.h
+ hle/service/wlan/wlan.cpp
+ hle/service/wlan/wlan.h
loader/deconstructed_rom_directory.cpp
loader/deconstructed_rom_directory.h
loader/elf.cpp
@@ -281,6 +341,8 @@ add_library(core STATIC
loader/nro.h
loader/nso.cpp
loader/nso.h
+ loader/xci.cpp
+ loader/xci.h
memory.cpp
memory.h
memory_hook.cpp
@@ -299,8 +361,8 @@ add_library(core STATIC
create_target_directory_groups(core)
-target_link_libraries(core PUBLIC common PRIVATE video_core)
-target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn)
+target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
+target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn)
if (ARCHITECTURE_x86_64)
target_sources(core PRIVATE
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 57b8634b9..ceb3f7683 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -10,7 +10,7 @@
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/hle/kernel/memory.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
@@ -139,14 +139,12 @@ void ARM_Dynarmic::Step() {
}
ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index)
- : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)),
- jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(
- exclusive_monitor)},
- core_index{core_index} {
- ARM_Interface::ThreadContext ctx;
+ : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index},
+ exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} {
+ ThreadContext ctx;
inner_unicorn.SaveContext(ctx);
- LoadContext(ctx);
PageTableChanged();
+ LoadContext(ctx);
}
ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -205,7 +203,7 @@ u64 ARM_Dynarmic::GetTlsAddress() const {
return cb->tpidrro_el0;
}
-void ARM_Dynarmic::SetTlsAddress(u64 address) {
+void ARM_Dynarmic::SetTlsAddress(VAddr address) {
cb->tpidrro_el0 = address;
}
@@ -217,7 +215,7 @@ void ARM_Dynarmic::SetTPIDR_EL0(u64 value) {
cb->tpidr_el0 = value;
}
-void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
+void ARM_Dynarmic::SaveContext(ThreadContext& ctx) {
ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP();
ctx.pc = jit->GetPC();
@@ -226,7 +224,7 @@ void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
ctx.fpscr = jit->GetFpcr();
}
-void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
+void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
jit->SetRegisters(ctx.cpu_registers);
jit->SetSP(ctx.sp);
jit->SetPC(ctx.pc);
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 4c11f35a4..6bc349460 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
}
Kernel::Thread* thread = Kernel::GetCurrentThread();
SaveContext(thread->context);
- if (last_bkpt_hit || (num_instructions == 1)) {
+ if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
last_bkpt_hit = false;
GDBStub::Break();
GDBStub::SendTrap(thread, 5);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index b7f4b4532..085ba68d0 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -15,11 +15,10 @@
#include "core/hle/service/service.h"
#include "core/hle/service/sm/controller.h"
#include "core/hle/service/sm/sm.h"
-#include "core/hw/hw.h"
#include "core/loader/loader.h"
-#include "core/memory_setup.h"
#include "core/settings.h"
#include "file_sys/vfs_real.h"
+#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
namespace Core {
@@ -63,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
// execute. Otherwise, get out of the loop function.
if (GDBStub::GetCpuHaltFlag()) {
if (GDBStub::GetCpuStepFlag()) {
- GDBStub::SetCpuStepFlag(false);
tight_loop = false;
} else {
return ResultStatus::Success;
@@ -79,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
}
}
+ if (GDBStub::IsServerEnabled()) {
+ GDBStub::SetCpuStepFlag(false);
+ }
+
return status;
}
@@ -86,7 +88,7 @@ System::ResultStatus System::SingleStep() {
return RunLoop(false);
}
-System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
+System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) {
app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath));
if (!app_loader) {
@@ -101,8 +103,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
static_cast<int>(system_mode.second));
switch (system_mode.second) {
- case Loader::ResultStatus::ErrorEncrypted:
- return ResultStatus::ErrorLoader_ErrorEncrypted;
+ case Loader::ResultStatus::ErrorMissingKeys:
+ return ResultStatus::ErrorLoader_ErrorMissingKeys;
+ case Loader::ResultStatus::ErrorDecrypting:
+ return ResultStatus::ErrorLoader_ErrorDecrypting;
case Loader::ResultStatus::ErrorInvalidFormat:
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
case Loader::ResultStatus::ErrorUnsupportedArch:
@@ -112,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
}
}
- ResultStatus init_result{Init(emu_window, system_mode.first.get())};
+ ResultStatus init_result{Init(emu_window)};
if (init_result != ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
@@ -126,8 +130,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
System::Shutdown();
switch (load_result) {
- case Loader::ResultStatus::ErrorEncrypted:
- return ResultStatus::ErrorLoader_ErrorEncrypted;
+ case Loader::ResultStatus::ErrorMissingKeys:
+ return ResultStatus::ErrorLoader_ErrorMissingKeys;
+ case Loader::ResultStatus::ErrorDecrypting:
+ return ResultStatus::ErrorLoader_ErrorDecrypting;
case Loader::ResultStatus::ErrorInvalidFormat:
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
case Loader::ResultStatus::ErrorUnsupportedArch:
@@ -163,7 +169,7 @@ Cpu& System::CpuCore(size_t core_index) {
return *cpu_cores[core_index];
}
-System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
+System::ResultStatus System::Init(EmuWindow& emu_window) {
LOG_DEBUG(HW_Memory, "initialized OK");
CoreTiming::Init();
@@ -176,19 +182,20 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index);
}
- gpu_core = std::make_unique<Tegra::GPU>();
telemetry_session = std::make_unique<Core::TelemetrySession>();
service_manager = std::make_shared<Service::SM::ServiceManager>();
- HW::Init();
- Kernel::Init(system_mode);
+ Kernel::Init();
Service::Init(service_manager);
GDBStub::Init();
- if (!VideoCore::Init(emu_window)) {
+ renderer = VideoCore::CreateRenderer(emu_window);
+ if (!renderer->Init()) {
return ResultStatus::ErrorVideoCore;
}
+ gpu_core = std::make_unique<Tegra::GPU>(renderer->Rasterizer());
+
// Create threads for CPU cores 1-3, and build thread_to_cpu map
// CPU core 0 is run on the main thread
thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
@@ -220,11 +227,10 @@ void System::Shutdown() {
perf_results.frametime * 1000.0);
// Shutdown emulation session
- VideoCore::Shutdown();
+ renderer.reset();
GDBStub::Shutdown();
Service::Shutdown();
Kernel::Shutdown();
- HW::Shutdown();
service_manager.reset();
telemetry_session.reset();
gpu_core.reset();
diff --git a/src/core/core.h b/src/core/core.h
index c123fe401..c8ca4b247 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -11,7 +11,7 @@
#include "common/common_types.h"
#include "core/arm/exclusive_monitor.h"
#include "core/core_cpu.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/scheduler.h"
#include "core/loader/loader.h"
#include "core/memory.h"
@@ -27,6 +27,10 @@ namespace Service::SM {
class ServiceManager;
}
+namespace VideoCore {
+class RendererBase;
+}
+
namespace Core {
class System {
@@ -43,12 +47,14 @@ public:
/// Enumeration representing the return values of the System Initialize and Load process.
enum class ResultStatus : u32 {
- Success, ///< Succeeded
- ErrorNotInitialized, ///< Error trying to use core prior to initialization
- ErrorGetLoader, ///< Error finding the correct application loader
- ErrorSystemMode, ///< Error determining the system mode
- ErrorLoader, ///< Error loading the specified application
- ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
+ Success, ///< Succeeded
+ ErrorNotInitialized, ///< Error trying to use core prior to initialization
+ ErrorGetLoader, ///< Error finding the correct application loader
+ ErrorSystemMode, ///< Error determining the system mode
+ ErrorLoader, ///< Error loading the specified application
+ ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be
+ ///< found.
+ ErrorLoader_ErrorDecrypting, ///< Error loading the specified application due to encryption
ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
/// invalid format
ErrorSystemFiles, ///< Error in finding system files
@@ -76,16 +82,28 @@ public:
*/
ResultStatus SingleStep();
+ /**
+ * Invalidate the CPU instruction caches
+ * This function should only be used by GDB Stub to support breakpoints, memory updates and
+ * step/continue commands.
+ */
+ void InvalidateCpuInstructionCaches() {
+ for (auto& cpu : cpu_cores) {
+ cpu->ArmInterface().ClearInstructionCache();
+ }
+ }
+
/// Shutdown the emulated system.
void Shutdown();
/**
* Load an executable application.
- * @param emu_window Pointer to the host-system window used for video output and keyboard input.
+ * @param emu_window Reference to the host-system window used for video output and keyboard
+ * input.
* @param filepath String path to the executable application to load on the host file system.
* @returns ResultStatus code, indicating if the operation succeeded.
*/
- ResultStatus Load(EmuWindow* emu_window, const std::string& filepath);
+ ResultStatus Load(EmuWindow& emu_window, const std::string& filepath);
/**
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -126,11 +144,26 @@ public:
/// Gets a CPU interface to the CPU core with the specified index
Cpu& CpuCore(size_t core_index);
- /// Gets the GPU interface
+ /// Gets a mutable reference to the GPU interface
Tegra::GPU& GPU() {
return *gpu_core;
}
+ /// Gets an immutable reference to the GPU interface.
+ const Tegra::GPU& GPU() const {
+ return *gpu_core;
+ }
+
+ /// Gets a mutable reference to the renderer.
+ VideoCore::RendererBase& Renderer() {
+ return *renderer;
+ }
+
+ /// Gets an immutable reference to the renderer.
+ const VideoCore::RendererBase& Renderer() const {
+ return *renderer;
+ }
+
/// Gets the scheduler for the CPU core that is currently running
Kernel::Scheduler& CurrentScheduler() {
return *CurrentCpuCore().Scheduler();
@@ -186,14 +219,15 @@ private:
/**
* Initialize the emulated system.
- * @param emu_window Pointer to the host-system window used for video output and keyboard input.
- * @param system_mode The system mode.
+ * @param emu_window Reference to the host-system window used for video output and keyboard
+ * input.
* @return ResultStatus code, indicating if the operation succeeded.
*/
- ResultStatus Init(EmuWindow* emu_window, u32 system_mode);
+ ResultStatus Init(EmuWindow& emu_window);
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
+ std::unique_ptr<VideoCore::RendererBase> renderer;
std::unique_ptr<Tegra::GPU> gpu_core;
std::shared_ptr<Tegra::DebugContext> debug_context;
Kernel::SharedPtr<Kernel::Process> current_process;
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 54e15a701..46a522fcd 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -12,7 +12,6 @@
#include "core/arm/unicorn/arm_unicorn.h"
#include "core/core_cpu.h"
#include "core/core_timing.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h"
#include "core/settings.h"
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index a1b6f96f1..d3bb6f818 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -141,7 +141,7 @@ void ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 user
ForceExceptionCheck(cycles_into_future);
event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type});
- std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
+ std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) {
@@ -156,7 +156,7 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) {
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
- std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
+ std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
@@ -167,7 +167,7 @@ void RemoveEvent(const EventType* event_type) {
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
- std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
+ std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
@@ -190,7 +190,7 @@ void MoveEvents() {
for (Event ev; ts_queue.Pop(ev);) {
ev.fifo_order = event_fifo_id++;
event_queue.emplace_back(std::move(ev));
- std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
+ std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
@@ -205,7 +205,7 @@ void Advance() {
while (!event_queue.empty() && event_queue.front().time <= global_timer) {
Event evt = std::move(event_queue.front());
- std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
+ std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
event_queue.pop_back();
evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time));
}
@@ -226,8 +226,8 @@ void Idle() {
downcount = 0;
}
-u64 GetGlobalTimeUs() {
- return GetTicks() * 1000000 / BASE_CLOCK_RATE;
+std::chrono::microseconds GetGlobalTimeUs() {
+ return std::chrono::microseconds{GetTicks() * 1000000 / BASE_CLOCK_RATE};
}
int GetDowncount() {
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 7fe6380ad..dfa161c0d 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -17,12 +17,17 @@
* ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever")
*/
+#include <chrono>
#include <functional>
#include <string>
#include "common/common_types.h"
namespace CoreTiming {
+struct EventType;
+
+using TimedCallback = std::function<void(u64 userdata, int cycles_late)>;
+
/**
* CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is
* required to end slice -1 and start slice 0 before the first cycle of code is executed.
@@ -30,8 +35,6 @@ namespace CoreTiming {
void Init();
void Shutdown();
-typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback;
-
/**
* This should only be called from the emu thread, if you are calling it any other thread, you are
* doing something evil
@@ -40,8 +43,6 @@ u64 GetTicks();
u64 GetIdleTicks();
void AddTicks(u64 ticks);
-struct EventType;
-
/**
* Returns the event_type identifier. if name is not unique, it will assert.
*/
@@ -86,7 +87,7 @@ void ClearPendingEvents();
void ForceExceptionCheck(s64 cycles);
-u64 GetGlobalTimeUs();
+std::chrono::microseconds GetGlobalTimeUs();
int GetDowncount();
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp
new file mode 100644
index 000000000..a9876c83e
--- /dev/null
+++ b/src/core/crypto/aes_util.cpp
@@ -0,0 +1,115 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <mbedtls/cipher.h>
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/crypto/aes_util.h"
+#include "core/crypto/key_manager.h"
+
+namespace Core::Crypto {
+namespace {
+std::vector<u8> CalculateNintendoTweak(size_t sector_id) {
+ std::vector<u8> out(0x10);
+ for (size_t i = 0xF; i <= 0xF; --i) {
+ out[i] = sector_id & 0xFF;
+ sector_id >>= 8;
+ }
+ return out;
+}
+} // Anonymous namespace
+
+static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR),
+ "CTR has incorrect value.");
+static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB),
+ "ECB has incorrect value.");
+static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS),
+ "XTS has incorrect value.");
+
+// Structure to hide mbedtls types from header file
+struct CipherContext {
+ mbedtls_cipher_context_t encryption_context;
+ mbedtls_cipher_context_t decryption_context;
+};
+
+template <typename Key, size_t KeySize>
+Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
+ : ctx(std::make_unique<CipherContext>()) {
+ mbedtls_cipher_init(&ctx->encryption_context);
+ mbedtls_cipher_init(&ctx->decryption_context);
+
+ ASSERT_MSG((mbedtls_cipher_setup(
+ &ctx->encryption_context,
+ mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode))) ||
+ mbedtls_cipher_setup(
+ &ctx->decryption_context,
+ mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode)))) == 0,
+ "Failed to initialize mbedtls ciphers.");
+
+ ASSERT(
+ !mbedtls_cipher_setkey(&ctx->encryption_context, key.data(), KeySize * 8, MBEDTLS_ENCRYPT));
+ ASSERT(
+ !mbedtls_cipher_setkey(&ctx->decryption_context, key.data(), KeySize * 8, MBEDTLS_DECRYPT));
+ //"Failed to set key on mbedtls ciphers.");
+}
+
+template <typename Key, size_t KeySize>
+AESCipher<Key, KeySize>::~AESCipher() {
+ mbedtls_cipher_free(&ctx->encryption_context);
+ mbedtls_cipher_free(&ctx->decryption_context);
+}
+
+template <typename Key, size_t KeySize>
+void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) {
+ ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) ||
+ mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0,
+ "Failed to set IV on mbedtls ciphers.");
+}
+
+template <typename Key, size_t KeySize>
+void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) const {
+ auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context;
+
+ mbedtls_cipher_reset(context);
+
+ size_t written = 0;
+ if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) {
+ mbedtls_cipher_update(context, src, size, dest, &written);
+ if (written != size) {
+ LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.",
+ size, written);
+ }
+ } else {
+ const auto block_size = mbedtls_cipher_get_block_size(context);
+
+ for (size_t offset = 0; offset < size; offset += block_size) {
+ auto length = std::min<size_t>(block_size, size - offset);
+ mbedtls_cipher_update(context, src + offset, length, dest + offset, &written);
+ if (written != length) {
+ LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.",
+ length, written);
+ }
+ }
+ }
+
+ mbedtls_cipher_finish(context, nullptr, nullptr);
+}
+
+template <typename Key, size_t KeySize>
+void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id,
+ size_t sector_size, Op op) {
+ if (size % sector_size > 0) {
+ LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size.");
+ return;
+ }
+
+ for (size_t i = 0; i < size; i += sector_size) {
+ SetIV(CalculateNintendoTweak(sector_id++));
+ Transcode<u8, u8>(src + i, sector_size, dest + i, op);
+ }
+}
+
+template class AESCipher<Key128>;
+template class AESCipher<Key256>;
+} // namespace Core::Crypto \ No newline at end of file
diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h
new file mode 100644
index 000000000..8ce9d6612
--- /dev/null
+++ b/src/core/crypto/aes_util.h
@@ -0,0 +1,64 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <type_traits>
+#include <vector>
+#include "common/common_types.h"
+#include "core/file_sys/vfs.h"
+
+namespace Core::Crypto {
+
+struct CipherContext;
+
+enum class Mode {
+ CTR = 11,
+ ECB = 2,
+ XTS = 70,
+};
+
+enum class Op {
+ Encrypt,
+ Decrypt,
+};
+
+template <typename Key, size_t KeySize = sizeof(Key)>
+class AESCipher {
+ static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8.");
+ static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256.");
+
+public:
+ AESCipher(Key key, Mode mode);
+
+ ~AESCipher();
+
+ void SetIV(std::vector<u8> iv);
+
+ template <typename Source, typename Dest>
+ void Transcode(const Source* src, size_t size, Dest* dest, Op op) const {
+ static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
+ "Transcode source and destination types must be trivially copyable.");
+ Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op);
+ }
+
+ void Transcode(const u8* src, size_t size, u8* dest, Op op) const;
+
+ template <typename Source, typename Dest>
+ void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id,
+ size_t sector_size, Op op) {
+ static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
+ "XTSTranscode source and destination types must be trivially copyable.");
+ XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id,
+ sector_size, op);
+ }
+
+ void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size,
+ Op op);
+
+private:
+ std::unique_ptr<CipherContext> ctx;
+};
+} // namespace Core::Crypto
diff --git a/src/core/crypto/ctr_encryption_layer.cpp b/src/core/crypto/ctr_encryption_layer.cpp
new file mode 100644
index 000000000..106db02b3
--- /dev/null
+++ b/src/core/crypto/ctr_encryption_layer.cpp
@@ -0,0 +1,56 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cstring>
+#include "common/assert.h"
+#include "core/crypto/ctr_encryption_layer.h"
+
+namespace Core::Crypto {
+
+CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, size_t base_offset)
+ : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR),
+ iv(16, 0) {}
+
+size_t CTREncryptionLayer::Read(u8* data, size_t length, size_t offset) const {
+ if (length == 0)
+ return 0;
+
+ const auto sector_offset = offset & 0xF;
+ if (sector_offset == 0) {
+ UpdateIV(base_offset + offset);
+ std::vector<u8> raw = base->ReadBytes(length, offset);
+ if (raw.size() != length)
+ return Read(data, raw.size(), offset);
+ cipher.Transcode(raw.data(), length, data, Op::Decrypt);
+ return length;
+ }
+
+ // offset does not fall on block boundary (0x10)
+ std::vector<u8> block = base->ReadBytes(0x10, offset - sector_offset);
+ UpdateIV(base_offset + offset - sector_offset);
+ cipher.Transcode(block.data(), block.size(), block.data(), Op::Decrypt);
+ size_t read = 0x10 - sector_offset;
+
+ if (length + sector_offset < 0x10) {
+ std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read));
+ return read;
+ }
+ std::memcpy(data, block.data() + sector_offset, read);
+ return read + Read(data + read, length - read, offset + read);
+}
+
+void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) {
+ const auto length = std::min(iv_.size(), iv.size());
+ iv.assign(iv_.cbegin(), iv_.cbegin() + length);
+}
+
+void CTREncryptionLayer::UpdateIV(size_t offset) const {
+ offset >>= 4;
+ for (size_t i = 0; i < 8; ++i) {
+ iv[16 - i - 1] = offset & 0xFF;
+ offset >>= 8;
+ }
+ cipher.SetIV(iv);
+}
+} // namespace Core::Crypto
diff --git a/src/core/crypto/ctr_encryption_layer.h b/src/core/crypto/ctr_encryption_layer.h
new file mode 100644
index 000000000..11b8683c7
--- /dev/null
+++ b/src/core/crypto/ctr_encryption_layer.h
@@ -0,0 +1,33 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+#include "core/crypto/aes_util.h"
+#include "core/crypto/encryption_layer.h"
+#include "core/crypto/key_manager.h"
+
+namespace Core::Crypto {
+
+// Sits on top of a VirtualFile and provides CTR-mode AES decription.
+class CTREncryptionLayer : public EncryptionLayer {
+public:
+ CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, size_t base_offset);
+
+ size_t Read(u8* data, size_t length, size_t offset) const override;
+
+ void SetIV(const std::vector<u8>& iv);
+
+private:
+ size_t base_offset;
+
+ // Must be mutable as operations modify cipher contexts.
+ mutable AESCipher<Key128> cipher;
+ mutable std::vector<u8> iv;
+
+ void UpdateIV(size_t offset) const;
+};
+
+} // namespace Core::Crypto
diff --git a/src/core/crypto/encryption_layer.cpp b/src/core/crypto/encryption_layer.cpp
new file mode 100644
index 000000000..4204527e3
--- /dev/null
+++ b/src/core/crypto/encryption_layer.cpp
@@ -0,0 +1,42 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/crypto/encryption_layer.h"
+
+namespace Core::Crypto {
+
+EncryptionLayer::EncryptionLayer(FileSys::VirtualFile base_) : base(std::move(base_)) {}
+
+std::string EncryptionLayer::GetName() const {
+ return base->GetName();
+}
+
+size_t EncryptionLayer::GetSize() const {
+ return base->GetSize();
+}
+
+bool EncryptionLayer::Resize(size_t new_size) {
+ return false;
+}
+
+std::shared_ptr<FileSys::VfsDirectory> EncryptionLayer::GetContainingDirectory() const {
+ return base->GetContainingDirectory();
+}
+
+bool EncryptionLayer::IsWritable() const {
+ return false;
+}
+
+bool EncryptionLayer::IsReadable() const {
+ return true;
+}
+
+size_t EncryptionLayer::Write(const u8* data, size_t length, size_t offset) {
+ return 0;
+}
+
+bool EncryptionLayer::Rename(std::string_view name) {
+ return base->Rename(name);
+}
+} // namespace Core::Crypto
diff --git a/src/core/crypto/encryption_layer.h b/src/core/crypto/encryption_layer.h
new file mode 100644
index 000000000..7f05af9b4
--- /dev/null
+++ b/src/core/crypto/encryption_layer.h
@@ -0,0 +1,33 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/file_sys/vfs.h"
+
+namespace Core::Crypto {
+
+// Basically non-functional class that implements all of the methods that are irrelevant to an
+// EncryptionLayer. Reduces duplicate code.
+class EncryptionLayer : public FileSys::VfsFile {
+public:
+ explicit EncryptionLayer(FileSys::VirtualFile base);
+
+ size_t Read(u8* data, size_t length, size_t offset) const override = 0;
+
+ std::string GetName() const override;
+ size_t GetSize() const override;
+ bool Resize(size_t new_size) override;
+ std::shared_ptr<FileSys::VfsDirectory> GetContainingDirectory() const override;
+ bool IsWritable() const override;
+ bool IsReadable() const override;
+ size_t Write(const u8* data, size_t length, size_t offset) override;
+ bool Rename(std::string_view name) override;
+
+protected:
+ FileSys::VirtualFile base;
+};
+
+} // namespace Core::Crypto
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
new file mode 100644
index 000000000..fc45e7ab5
--- /dev/null
+++ b/src/core/crypto/key_manager.cpp
@@ -0,0 +1,208 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <array>
+#include <fstream>
+#include <locale>
+#include <sstream>
+#include <string_view>
+#include "common/common_paths.h"
+#include "common/file_util.h"
+#include "core/crypto/key_manager.h"
+#include "core/settings.h"
+
+namespace Core::Crypto {
+
+static u8 ToHexNibble(char c1) {
+ if (c1 >= 65 && c1 <= 70)
+ return c1 - 55;
+ if (c1 >= 97 && c1 <= 102)
+ return c1 - 87;
+ if (c1 >= 48 && c1 <= 57)
+ return c1 - 48;
+ throw std::logic_error("Invalid hex digit");
+}
+
+template <size_t Size>
+static std::array<u8, Size> HexStringToArray(std::string_view str) {
+ std::array<u8, Size> out{};
+ for (size_t i = 0; i < 2 * Size; i += 2) {
+ auto d1 = str[i];
+ auto d2 = str[i + 1];
+ out[i / 2] = (ToHexNibble(d1) << 4) | ToHexNibble(d2);
+ }
+ return out;
+}
+
+std::array<u8, 16> operator""_array16(const char* str, size_t len) {
+ if (len != 32)
+ throw std::logic_error("Not of correct size.");
+ return HexStringToArray<16>(str);
+}
+
+std::array<u8, 32> operator""_array32(const char* str, size_t len) {
+ if (len != 64)
+ throw std::logic_error("Not of correct size.");
+ return HexStringToArray<32>(str);
+}
+
+KeyManager::KeyManager() {
+ // Initialize keys
+ const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
+ const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
+ if (Settings::values.use_dev_keys) {
+ dev_mode = true;
+ AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false);
+ } else {
+ dev_mode = false;
+ AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false);
+ }
+
+ AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true);
+}
+
+void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
+ std::ifstream file(filename);
+ if (!file.is_open())
+ return;
+
+ std::string line;
+ while (std::getline(file, line)) {
+ std::vector<std::string> out;
+ std::stringstream stream(line);
+ std::string item;
+ while (std::getline(stream, item, '='))
+ out.push_back(std::move(item));
+
+ if (out.size() != 2)
+ continue;
+
+ out[0].erase(std::remove(out[0].begin(), out[0].end(), ' '), out[0].end());
+ out[1].erase(std::remove(out[1].begin(), out[1].end(), ' '), out[1].end());
+
+ if (is_title_keys) {
+ auto rights_id_raw = HexStringToArray<16>(out[0]);
+ u128 rights_id{};
+ std::memcpy(rights_id.data(), rights_id_raw.data(), rights_id_raw.size());
+ Key128 key = HexStringToArray<16>(out[1]);
+ SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
+ } else {
+ std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower);
+ if (s128_file_id.find(out[0]) != s128_file_id.end()) {
+ const auto index = s128_file_id.at(out[0]);
+ Key128 key = HexStringToArray<16>(out[1]);
+ SetKey(index.type, key, index.field1, index.field2);
+ } else if (s256_file_id.find(out[0]) != s256_file_id.end()) {
+ const auto index = s256_file_id.at(out[0]);
+ Key256 key = HexStringToArray<32>(out[1]);
+ SetKey(index.type, key, index.field1, index.field2);
+ }
+ }
+ }
+}
+
+void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
+ const std::string& filename, bool title) {
+ if (FileUtil::Exists(dir1 + DIR_SEP + filename))
+ LoadFromFile(dir1 + DIR_SEP + filename, title);
+ else if (FileUtil::Exists(dir2 + DIR_SEP + filename))
+ LoadFromFile(dir2 + DIR_SEP + filename, title);
+}
+
+bool KeyManager::HasKey(S128KeyType id, u64 field1, u64 field2) const {
+ return s128_keys.find({id, field1, field2}) != s128_keys.end();
+}
+
+bool KeyManager::HasKey(S256KeyType id, u64 field1, u64 field2) const {
+ return s256_keys.find({id, field1, field2}) != s256_keys.end();
+}
+
+Key128 KeyManager::GetKey(S128KeyType id, u64 field1, u64 field2) const {
+ if (!HasKey(id, field1, field2))
+ return {};
+ return s128_keys.at({id, field1, field2});
+}
+
+Key256 KeyManager::GetKey(S256KeyType id, u64 field1, u64 field2) const {
+ if (!HasKey(id, field1, field2))
+ return {};
+ return s256_keys.at({id, field1, field2});
+}
+
+void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
+ s128_keys[{id, field1, field2}] = key;
+}
+
+void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
+ s256_keys[{id, field1, field2}] = key;
+}
+
+bool KeyManager::KeyFileExists(bool title) {
+ const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
+ const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
+ if (title) {
+ return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") ||
+ FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys");
+ }
+
+ if (Settings::values.use_dev_keys) {
+ return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") ||
+ FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys");
+ }
+
+ return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") ||
+ FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys");
+}
+
+const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = {
+ {"master_key_00", {S128KeyType::Master, 0, 0}},
+ {"master_key_01", {S128KeyType::Master, 1, 0}},
+ {"master_key_02", {S128KeyType::Master, 2, 0}},
+ {"master_key_03", {S128KeyType::Master, 3, 0}},
+ {"master_key_04", {S128KeyType::Master, 4, 0}},
+ {"package1_key_00", {S128KeyType::Package1, 0, 0}},
+ {"package1_key_01", {S128KeyType::Package1, 1, 0}},
+ {"package1_key_02", {S128KeyType::Package1, 2, 0}},
+ {"package1_key_03", {S128KeyType::Package1, 3, 0}},
+ {"package1_key_04", {S128KeyType::Package1, 4, 0}},
+ {"package2_key_00", {S128KeyType::Package2, 0, 0}},
+ {"package2_key_01", {S128KeyType::Package2, 1, 0}},
+ {"package2_key_02", {S128KeyType::Package2, 2, 0}},
+ {"package2_key_03", {S128KeyType::Package2, 3, 0}},
+ {"package2_key_04", {S128KeyType::Package2, 4, 0}},
+ {"titlekek_00", {S128KeyType::Titlekek, 0, 0}},
+ {"titlekek_01", {S128KeyType::Titlekek, 1, 0}},
+ {"titlekek_02", {S128KeyType::Titlekek, 2, 0}},
+ {"titlekek_03", {S128KeyType::Titlekek, 3, 0}},
+ {"titlekek_04", {S128KeyType::Titlekek, 4, 0}},
+ {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}},
+ {"key_area_key_application_00",
+ {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Application)}},
+ {"key_area_key_application_01",
+ {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Application)}},
+ {"key_area_key_application_02",
+ {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Application)}},
+ {"key_area_key_application_03",
+ {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Application)}},
+ {"key_area_key_application_04",
+ {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Application)}},
+ {"key_area_key_ocean_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Ocean)}},
+ {"key_area_key_ocean_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Ocean)}},
+ {"key_area_key_ocean_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Ocean)}},
+ {"key_area_key_ocean_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Ocean)}},
+ {"key_area_key_ocean_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Ocean)}},
+ {"key_area_key_system_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::System)}},
+ {"key_area_key_system_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::System)}},
+ {"key_area_key_system_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::System)}},
+ {"key_area_key_system_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::System)}},
+ {"key_area_key_system_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::System)}},
+};
+
+const std::unordered_map<std::string, KeyIndex<S256KeyType>> KeyManager::s256_file_id = {
+ {"header_key", {S256KeyType::Header, 0, 0}},
+ {"sd_card_save_key", {S256KeyType::SDSave, 0, 0}},
+ {"sd_card_nca_key", {S256KeyType::SDNCA, 0, 0}},
+};
+} // namespace Core::Crypto
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
new file mode 100644
index 000000000..c4c53cefc
--- /dev/null
+++ b/src/core/crypto/key_manager.h
@@ -0,0 +1,120 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <vector>
+#include <fmt/format.h>
+#include "common/common_types.h"
+
+namespace Core::Crypto {
+
+using Key128 = std::array<u8, 0x10>;
+using Key256 = std::array<u8, 0x20>;
+using SHA256Hash = std::array<u8, 0x20>;
+
+static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
+static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big.");
+
+enum class S256KeyType : u64 {
+ Header, //
+ SDSave, //
+ SDNCA, //
+};
+
+enum class S128KeyType : u64 {
+ Master, // f1=crypto revision
+ Package1, // f1=crypto revision
+ Package2, // f1=crypto revision
+ Titlekek, // f1=crypto revision
+ ETicketRSAKek, //
+ KeyArea, // f1=crypto revision f2=type {app, ocean, system}
+ SDSeed, //
+ Titlekey, // f1=rights id LSB f2=rights id MSB
+};
+
+enum class KeyAreaKeyType : u8 {
+ Application,
+ Ocean,
+ System,
+};
+
+template <typename KeyType>
+struct KeyIndex {
+ KeyType type;
+ u64 field1;
+ u64 field2;
+
+ std::string DebugInfo() const {
+ u8 key_size = 16;
+ if constexpr (std::is_same_v<KeyType, S256KeyType>)
+ key_size = 32;
+ return fmt::format("key_size={:02X}, key={:02X}, field1={:016X}, field2={:016X}", key_size,
+ static_cast<u8>(type), field1, field2);
+ }
+};
+
+// The following two (== and hash) are so KeyIndex can be a key in unordered_map
+
+template <typename KeyType>
+bool operator==(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
+ return std::tie(lhs.type, lhs.field1, lhs.field2) == std::tie(rhs.type, rhs.field1, rhs.field2);
+}
+
+template <typename KeyType>
+bool operator!=(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
+ return !operator==(lhs, rhs);
+}
+
+} // namespace Core::Crypto
+
+namespace std {
+template <typename KeyType>
+struct hash<Core::Crypto::KeyIndex<KeyType>> {
+ size_t operator()(const Core::Crypto::KeyIndex<KeyType>& k) const {
+ using std::hash;
+
+ return ((hash<u64>()(static_cast<u64>(k.type)) ^ (hash<u64>()(k.field1) << 1)) >> 1) ^
+ (hash<u64>()(k.field2) << 1);
+ }
+};
+} // namespace std
+
+namespace Core::Crypto {
+
+std::array<u8, 0x10> operator"" _array16(const char* str, size_t len);
+std::array<u8, 0x20> operator"" _array32(const char* str, size_t len);
+
+class KeyManager {
+public:
+ KeyManager();
+
+ bool HasKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
+ bool HasKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
+
+ Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
+ Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
+
+ void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
+ void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
+
+ static bool KeyFileExists(bool title);
+
+private:
+ std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys;
+ std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys;
+
+ bool dev_mode;
+ void LoadFromFile(const std::string& filename, bool is_title_keys);
+ void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
+ const std::string& filename, bool title);
+
+ static const std::unordered_map<std::string, KeyIndex<S128KeyType>> s128_file_id;
+ static const std::unordered_map<std::string, KeyIndex<S256KeyType>> s256_file_id;
+};
+} // namespace Core::Crypto
diff --git a/src/core/crypto/sha_util.cpp b/src/core/crypto/sha_util.cpp
new file mode 100644
index 000000000..180008a85
--- /dev/null
+++ b/src/core/crypto/sha_util.cpp
@@ -0,0 +1,5 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+namespace Crypto {} // namespace Crypto
diff --git a/src/core/crypto/sha_util.h b/src/core/crypto/sha_util.h
new file mode 100644
index 000000000..fa3fa9d33
--- /dev/null
+++ b/src/core/crypto/sha_util.h
@@ -0,0 +1,20 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/assert.h"
+#include "core/file_sys/vfs.h"
+#include "key_manager.h"
+#include "mbedtls/cipher.h"
+
+namespace Crypto {
+typedef std::array<u8, 0x20> SHA256Hash;
+
+inline SHA256Hash operator"" _HASH(const char* data, size_t len) {
+ if (len != 0x40)
+ return {};
+}
+
+} // namespace Crypto
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
new file mode 100644
index 000000000..395eea8ae
--- /dev/null
+++ b/src/core/file_sys/card_image.cpp
@@ -0,0 +1,149 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <array>
+#include <string>
+#include <core/loader/loader.h>
+#include "core/file_sys/card_image.h"
+#include "core/file_sys/partition_filesystem.h"
+#include "core/file_sys/vfs_offset.h"
+
+namespace FileSys {
+
+XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {
+ if (file->ReadObject(&header) != sizeof(GamecardHeader)) {
+ status = Loader::ResultStatus::ErrorInvalidFormat;
+ return;
+ }
+
+ if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) {
+ status = Loader::ResultStatus::ErrorInvalidFormat;
+ return;
+ }
+
+ PartitionFilesystem main_hfs(
+ std::make_shared<OffsetVfsFile>(file, header.hfs_size, header.hfs_offset));
+
+ if (main_hfs.GetStatus() != Loader::ResultStatus::Success) {
+ status = main_hfs.GetStatus();
+ return;
+ }
+
+ static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure",
+ "logo"};
+
+ for (XCIPartition partition :
+ {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) {
+ auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]);
+ if (raw != nullptr)
+ partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw);
+ }
+
+ auto result = AddNCAFromPartition(XCIPartition::Secure);
+ if (result != Loader::ResultStatus::Success) {
+ status = result;
+ return;
+ }
+
+ result = AddNCAFromPartition(XCIPartition::Update);
+ if (result != Loader::ResultStatus::Success) {
+ status = result;
+ return;
+ }
+
+ result = AddNCAFromPartition(XCIPartition::Normal);
+ if (result != Loader::ResultStatus::Success) {
+ status = result;
+ return;
+ }
+
+ if (GetFormatVersion() >= 0x2) {
+ result = AddNCAFromPartition(XCIPartition::Logo);
+ if (result != Loader::ResultStatus::Success) {
+ status = result;
+ return;
+ }
+ }
+
+ status = Loader::ResultStatus::Success;
+}
+
+Loader::ResultStatus XCI::GetStatus() const {
+ return status;
+}
+
+VirtualDir XCI::GetPartition(XCIPartition partition) const {
+ return partitions[static_cast<size_t>(partition)];
+}
+
+VirtualDir XCI::GetSecurePartition() const {
+ return GetPartition(XCIPartition::Secure);
+}
+
+VirtualDir XCI::GetNormalPartition() const {
+ return GetPartition(XCIPartition::Normal);
+}
+
+VirtualDir XCI::GetUpdatePartition() const {
+ return GetPartition(XCIPartition::Update);
+}
+
+VirtualDir XCI::GetLogoPartition() const {
+ return GetPartition(XCIPartition::Logo);
+}
+
+std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const {
+ const auto iter =
+ std::find_if(ncas.begin(), ncas.end(),
+ [type](const std::shared_ptr<NCA>& nca) { return nca->GetType() == type; });
+ return iter == ncas.end() ? nullptr : *iter;
+}
+
+VirtualFile XCI::GetNCAFileByType(NCAContentType type) const {
+ auto nca = GetNCAByType(type);
+ if (nca != nullptr)
+ return nca->GetBaseFile();
+ return nullptr;
+}
+
+std::vector<std::shared_ptr<VfsFile>> XCI::GetFiles() const {
+ return {};
+}
+
+std::vector<std::shared_ptr<VfsDirectory>> XCI::GetSubdirectories() const {
+ return std::vector<std::shared_ptr<VfsDirectory>>();
+}
+
+std::string XCI::GetName() const {
+ return file->GetName();
+}
+
+std::shared_ptr<VfsDirectory> XCI::GetParentDirectory() const {
+ return file->GetContainingDirectory();
+}
+
+bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
+ return false;
+}
+
+Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
+ if (partitions[static_cast<size_t>(part)] == nullptr) {
+ return Loader::ResultStatus::ErrorInvalidFormat;
+ }
+
+ for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) {
+ if (file->GetExtension() != "nca")
+ continue;
+ auto nca = std::make_shared<NCA>(file);
+ if (nca->GetStatus() == Loader::ResultStatus::Success)
+ ncas.push_back(std::move(nca));
+ }
+
+ return Loader::ResultStatus::Success;
+}
+
+u8 XCI::GetFormatVersion() const {
+ return GetLogoPartition() == nullptr ? 0x1 : 0x2;
+}
+} // namespace FileSys
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
new file mode 100644
index 000000000..e089d737c
--- /dev/null
+++ b/src/core/file_sys/card_image.h
@@ -0,0 +1,96 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <vector>
+#include "common/common_types.h"
+#include "common/swap.h"
+#include "core/file_sys/content_archive.h"
+#include "core/file_sys/vfs.h"
+#include "core/loader/loader.h"
+
+namespace FileSys {
+
+enum class GamecardSize : u8 {
+ S_1GB = 0xFA,
+ S_2GB = 0xF8,
+ S_4GB = 0xF0,
+ S_8GB = 0xE0,
+ S_16GB = 0xE1,
+ S_32GB = 0xE2,
+};
+
+struct GamecardInfo {
+ std::array<u8, 0x70> data;
+};
+static_assert(sizeof(GamecardInfo) == 0x70, "GamecardInfo has incorrect size.");
+
+struct GamecardHeader {
+ std::array<u8, 0x100> signature;
+ u32_le magic;
+ u32_le secure_area_start;
+ u32_le backup_area_start;
+ u8 kek_index;
+ GamecardSize size;
+ u8 header_version;
+ u8 flags;
+ u64_le package_id;
+ u64_le valid_data_end;
+ u128 info_iv;
+ u64_le hfs_offset;
+ u64_le hfs_size;
+ std::array<u8, 0x20> hfs_header_hash;
+ std::array<u8, 0x20> initial_data_hash;
+ u32_le secure_mode_flag;
+ u32_le title_key_flag;
+ u32_le key_flag;
+ u32_le normal_area_end;
+ GamecardInfo info;
+};
+static_assert(sizeof(GamecardHeader) == 0x200, "GamecardHeader has incorrect size.");
+
+enum class XCIPartition : u8 { Update, Normal, Secure, Logo };
+
+class XCI : public ReadOnlyVfsDirectory {
+public:
+ explicit XCI(VirtualFile file);
+
+ Loader::ResultStatus GetStatus() const;
+
+ u8 GetFormatVersion() const;
+
+ VirtualDir GetPartition(XCIPartition partition) const;
+ VirtualDir GetSecurePartition() const;
+ VirtualDir GetNormalPartition() const;
+ VirtualDir GetUpdatePartition() const;
+ VirtualDir GetLogoPartition() const;
+
+ std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
+ VirtualFile GetNCAFileByType(NCAContentType type) const;
+
+ std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
+
+ std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
+
+ std::string GetName() const override;
+
+ std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
+
+protected:
+ bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
+
+private:
+ Loader::ResultStatus AddNCAFromPartition(XCIPartition part);
+
+ VirtualFile file;
+ GamecardHeader header{};
+
+ Loader::ResultStatus status;
+
+ std::vector<VirtualDir> partitions;
+ std::vector<std::shared_ptr<NCA>> ncas;
+};
+} // namespace FileSys
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index d6b20c047..3529166ac 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -4,9 +4,12 @@
#include <algorithm>
#include <utility>
-
+#include <boost/optional.hpp>
#include "common/logging/log.h"
+#include "core/crypto/aes_util.h"
+#include "core/crypto/ctr_encryption_layer.h"
#include "core/file_sys/content_archive.h"
+#include "core/file_sys/romfs.h"
#include "core/file_sys/vfs_offset.h"
#include "core/loader/loader.h"
@@ -28,11 +31,19 @@ enum class NCASectionFilesystemType : u8 {
struct NCASectionHeaderBlock {
INSERT_PADDING_BYTES(3);
NCASectionFilesystemType filesystem_type;
- u8 crypto_type;
+ NCASectionCryptoType crypto_type;
INSERT_PADDING_BYTES(3);
};
static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size.");
+struct NCASectionRaw {
+ NCASectionHeaderBlock header;
+ std::array<u8, 0x138> block_data;
+ std::array<u8, 0x8> section_ctr;
+ INSERT_PADDING_BYTES(0xB8);
+};
+static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size.");
+
struct PFS0Superblock {
NCASectionHeaderBlock header_block;
std::array<u8, 0x20> hash;
@@ -42,79 +53,200 @@ struct PFS0Superblock {
u64_le hash_table_size;
u64_le pfs0_header_offset;
u64_le pfs0_size;
- INSERT_PADDING_BYTES(432);
+ INSERT_PADDING_BYTES(0x1B0);
};
static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size.");
-struct IVFCLevel {
- u64_le offset;
- u64_le size;
- u32_le block_size;
- u32_le reserved;
-};
-static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
-
struct RomFSSuperblock {
NCASectionHeaderBlock header_block;
- u32_le magic;
- u32_le magic_number;
- INSERT_PADDING_BYTES(8);
- std::array<IVFCLevel, 6> levels;
- INSERT_PADDING_BYTES(64);
+ IVFCHeader ivfc;
+ INSERT_PADDING_BYTES(0x118);
};
-static_assert(sizeof(RomFSSuperblock) == 0xE8, "RomFSSuperblock has incorrect size.");
+static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size.");
+
+union NCASectionHeader {
+ NCASectionRaw raw;
+ PFS0Superblock pfs0;
+ RomFSSuperblock romfs;
+};
+static_assert(sizeof(NCASectionHeader) == 0x200, "NCASectionHeader has incorrect size.");
+
+bool IsValidNCA(const NCAHeader& header) {
+ // TODO(DarkLordZach): Add NCA2/NCA0 support.
+ return header.magic == Common::MakeMagic('N', 'C', 'A', '3');
+}
+
+u8 NCA::GetCryptoRevision() const {
+ u8 master_key_id = header.crypto_type;
+ if (header.crypto_type_2 > master_key_id)
+ master_key_id = header.crypto_type_2;
+ if (master_key_id > 0)
+ --master_key_id;
+ return master_key_id;
+}
+
+boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
+ const auto master_key_id = GetCryptoRevision();
+
+ if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index))
+ return boost::none;
+
+ std::vector<u8> key_area(header.key_area.begin(), header.key_area.end());
+ Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
+ keys.GetKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index),
+ Core::Crypto::Mode::ECB);
+ cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt);
+
+ Core::Crypto::Key128 out;
+ if (type == NCASectionCryptoType::XTS)
+ std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin());
+ else if (type == NCASectionCryptoType::CTR)
+ std::copy(key_area.begin() + 0x20, key_area.begin() + 0x30, out.begin());
+ else
+ LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}",
+ static_cast<u8>(type));
+ u128 out_128{};
+ memcpy(out_128.data(), out.data(), 16);
+ LOG_DEBUG(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}",
+ master_key_id, header.key_index, out_128[1], out_128[0]);
+
+ return out;
+}
+
+boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() const {
+ const auto master_key_id = GetCryptoRevision();
+
+ u128 rights_id{};
+ memcpy(rights_id.data(), header.rights_id.data(), 16);
+ if (rights_id == u128{})
+ return boost::none;
+
+ auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]);
+ if (titlekey == Core::Crypto::Key128{})
+ return boost::none;
+ Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
+ keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB);
+ cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt);
+
+ return titlekey;
+}
+
+VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) const {
+ if (!encrypted)
+ return in;
+
+ switch (s_header.raw.header.crypto_type) {
+ case NCASectionCryptoType::NONE:
+ LOG_DEBUG(Crypto, "called with mode=NONE");
+ return in;
+ case NCASectionCryptoType::CTR:
+ LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset);
+ {
+ boost::optional<Core::Crypto::Key128> key = boost::none;
+ if (std::find_if_not(header.rights_id.begin(), header.rights_id.end(),
+ [](char c) { return c == 0; }) == header.rights_id.end()) {
+ key = GetKeyAreaKey(NCASectionCryptoType::CTR);
+ } else {
+ key = GetTitlekey();
+ }
+
+ if (key == boost::none)
+ return nullptr;
+ auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(
+ std::move(in), key.value(), starting_offset);
+ std::vector<u8> iv(16);
+ for (u8 i = 0; i < 8; ++i)
+ iv[i] = s_header.raw.section_ctr[0x8 - i - 1];
+ out->SetIV(iv);
+ return std::static_pointer_cast<VfsFile>(out);
+ }
+ case NCASectionCryptoType::XTS:
+ // TODO(DarkLordZach): Implement XTSEncryptionLayer.
+ default:
+ LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}",
+ static_cast<u8>(s_header.raw.header.crypto_type));
+ return nullptr;
+ }
+}
NCA::NCA(VirtualFile file_) : file(std::move(file_)) {
if (sizeof(NCAHeader) != file->ReadObject(&header))
- LOG_CRITICAL(Loader, "File reader errored out during header read.");
+ LOG_ERROR(Loader, "File reader errored out during header read.");
+
+ encrypted = false;
if (!IsValidNCA(header)) {
- status = Loader::ResultStatus::ErrorInvalidFormat;
- return;
+ NCAHeader dec_header{};
+ Core::Crypto::AESCipher<Core::Crypto::Key256> cipher(
+ keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS);
+ cipher.XTSTranscode(&header, sizeof(NCAHeader), &dec_header, 0, 0x200,
+ Core::Crypto::Op::Decrypt);
+ if (IsValidNCA(dec_header)) {
+ header = dec_header;
+ encrypted = true;
+ } else {
+ if (!keys.HasKey(Core::Crypto::S256KeyType::Header))
+ status = Loader::ResultStatus::ErrorMissingKeys;
+ else
+ status = Loader::ResultStatus::ErrorDecrypting;
+ return;
+ }
}
- std::ptrdiff_t number_sections =
+ const std::ptrdiff_t number_sections =
std::count_if(std::begin(header.section_tables), std::end(header.section_tables),
[](NCASectionTableEntry entry) { return entry.media_offset > 0; });
+ std::vector<NCASectionHeader> sections(number_sections);
+ const auto length_sections = SECTION_HEADER_SIZE * number_sections;
+
+ if (encrypted) {
+ auto raw = file->ReadBytes(length_sections, SECTION_HEADER_OFFSET);
+ Core::Crypto::AESCipher<Core::Crypto::Key256> cipher(
+ keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS);
+ cipher.XTSTranscode(raw.data(), length_sections, sections.data(), 2, SECTION_HEADER_SIZE,
+ Core::Crypto::Op::Decrypt);
+ } else {
+ file->ReadBytes(sections.data(), length_sections, SECTION_HEADER_OFFSET);
+ }
+
for (std::ptrdiff_t i = 0; i < number_sections; ++i) {
- // Seek to beginning of this section.
- NCASectionHeaderBlock block{};
- if (sizeof(NCASectionHeaderBlock) !=
- file->ReadObject(&block, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE))
- LOG_CRITICAL(Loader, "File reader errored out during header read.");
-
- if (block.filesystem_type == NCASectionFilesystemType::ROMFS) {
- RomFSSuperblock sb{};
- if (sizeof(RomFSSuperblock) !=
- file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE))
- LOG_CRITICAL(Loader, "File reader errored out during header read.");
+ auto section = sections[i];
+ if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) {
const size_t romfs_offset =
header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER +
- sb.levels[IVFC_MAX_LEVEL - 1].offset;
- const size_t romfs_size = sb.levels[IVFC_MAX_LEVEL - 1].size;
- files.emplace_back(std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset));
- romfs = files.back();
- } else if (block.filesystem_type == NCASectionFilesystemType::PFS0) {
- PFS0Superblock sb{};
- // Seek back to beginning of this section.
- if (sizeof(PFS0Superblock) !=
- file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE))
- LOG_CRITICAL(Loader, "File reader errored out during header read.");
-
+ section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
+ const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
+ auto dec =
+ Decrypt(section, std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset),
+ romfs_offset);
+ if (dec != nullptr) {
+ files.push_back(std::move(dec));
+ romfs = files.back();
+ } else {
+ status = Loader::ResultStatus::ErrorMissingKeys;
+ return;
+ }
+ } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) {
u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) *
MEDIA_OFFSET_MULTIPLIER) +
- sb.pfs0_header_offset;
+ section.pfs0.pfs0_header_offset;
u64 size = MEDIA_OFFSET_MULTIPLIER * (header.section_tables[i].media_end_offset -
header.section_tables[i].media_offset);
- auto npfs = std::make_shared<PartitionFilesystem>(
- std::make_shared<OffsetVfsFile>(file, size, offset));
+ auto dec =
+ Decrypt(section, std::make_shared<OffsetVfsFile>(file, size, offset), offset);
+ if (dec != nullptr) {
+ auto npfs = std::make_shared<PartitionFilesystem>(std::move(dec));
- if (npfs->GetStatus() == Loader::ResultStatus::Success) {
- dirs.emplace_back(npfs);
- if (IsDirectoryExeFS(dirs.back()))
- exefs = dirs.back();
+ if (npfs->GetStatus() == Loader::ResultStatus::Success) {
+ dirs.push_back(std::move(npfs));
+ if (IsDirectoryExeFS(dirs.back()))
+ exefs = dirs.back();
+ }
+ } else {
+ status = Loader::ResultStatus::ErrorMissingKeys;
+ return;
}
}
}
@@ -164,6 +296,10 @@ VirtualDir NCA::GetExeFS() const {
return exefs;
}
+VirtualFile NCA::GetBaseFile() const {
+ return file;
+}
+
bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
return false;
}
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h
index 0b8b9db61..a8879d9a8 100644
--- a/src/core/file_sys/content_archive.h
+++ b/src/core/file_sys/content_archive.h
@@ -8,14 +8,18 @@
#include <memory>
#include <string>
#include <vector>
-
+#include <boost/optional.hpp>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
+#include "core/crypto/key_manager.h"
#include "core/file_sys/partition_filesystem.h"
+#include "core/loader/loader.h"
namespace FileSys {
+union NCASectionHeader;
+
enum class NCAContentType : u8 {
Program = 0,
Meta = 1,
@@ -24,6 +28,13 @@ enum class NCAContentType : u8 {
Data = 4,
};
+enum class NCASectionCryptoType : u8 {
+ NONE = 1,
+ XTS = 2,
+ CTR = 3,
+ BKTR = 4,
+};
+
struct NCASectionTableEntry {
u32_le media_offset;
u32_le media_end_offset;
@@ -48,7 +59,7 @@ struct NCAHeader {
std::array<u8, 0x10> rights_id;
std::array<NCASectionTableEntry, 0x4> section_tables;
std::array<std::array<u8, 0x20>, 0x4> hash_tables;
- std::array<std::array<u8, 0x10>, 0x4> key_area;
+ std::array<u8, 0x40> key_area;
INSERT_PADDING_BYTES(0xC0);
};
static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
@@ -58,10 +69,7 @@ inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) {
return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
}
-inline bool IsValidNCA(const NCAHeader& header) {
- return header.magic == Common::MakeMagic('N', 'C', 'A', '2') ||
- header.magic == Common::MakeMagic('N', 'C', 'A', '3');
-}
+bool IsValidNCA(const NCAHeader& header);
// An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner.
// After construction, use GetStatus to determine if the file is valid and ready to be used.
@@ -81,10 +89,17 @@ public:
VirtualFile GetRomFS() const;
VirtualDir GetExeFS() const;
+ VirtualFile GetBaseFile() const;
+
protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
private:
+ u8 GetCryptoRevision() const;
+ boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const;
+ boost::optional<Core::Crypto::Key128> GetTitlekey() const;
+ VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const;
+
std::vector<VirtualDir> dirs;
std::vector<VirtualFile> files;
@@ -95,6 +110,10 @@ private:
NCAHeader header{};
Loader::ResultStatus status{};
+
+ bool encrypted;
+
+ Core::Crypto::KeyManager keys;
};
} // namespace FileSys
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index 521e21078..47e032b19 100644
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -97,9 +97,8 @@ void PartitionFilesystem::PrintDebugInfo() const {
LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
for (u32 i = 0; i < pfs_header.num_entries; i++) {
- LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i,
- pfs_files[i]->GetName(), pfs_files[i]->GetSize(),
- dynamic_cast<OffsetVfsFile*>(pfs_files[i].get())->GetOffset());
+ LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
+ pfs_files[i]->GetName(), pfs_files[i]->GetSize());
}
}
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
new file mode 100644
index 000000000..ff3ddb29c
--- /dev/null
+++ b/src/core/file_sys/romfs.cpp
@@ -0,0 +1,124 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+#include "common/swap.h"
+#include "core/file_sys/romfs.h"
+#include "core/file_sys/vfs.h"
+#include "core/file_sys/vfs_offset.h"
+#include "core/file_sys/vfs_vector.h"
+
+namespace FileSys {
+
+constexpr u32 ROMFS_ENTRY_EMPTY = 0xFFFFFFFF;
+
+struct TableLocation {
+ u64_le offset;
+ u64_le size;
+};
+static_assert(sizeof(TableLocation) == 0x10, "TableLocation has incorrect size.");
+
+struct RomFSHeader {
+ u64_le header_size;
+ TableLocation directory_hash;
+ TableLocation directory_meta;
+ TableLocation file_hash;
+ TableLocation file_meta;
+ u64_le data_offset;
+};
+static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size.");
+
+struct DirectoryEntry {
+ u32_le sibling;
+ u32_le child_dir;
+ u32_le child_file;
+ u32_le hash;
+ u32_le name_length;
+};
+static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size.");
+
+struct FileEntry {
+ u32_le parent;
+ u32_le sibling;
+ u64_le offset;
+ u64_le size;
+ u32_le hash;
+ u32_le name_length;
+};
+static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size.");
+
+template <typename Entry>
+static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t offset) {
+ Entry entry{};
+ if (file->ReadObject(&entry, offset) != sizeof(Entry))
+ return {};
+ std::string string(entry.name_length, '\0');
+ if (file->ReadArray(&string[0], string.size(), offset + sizeof(Entry)) != string.size())
+ return {};
+ return {entry, string};
+}
+
+void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 this_file_offset,
+ std::shared_ptr<VectorVfsDirectory> parent) {
+ while (true) {
+ auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
+
+ parent->AddFile(std::make_shared<OffsetVfsFile>(
+ file, entry.first.size, entry.first.offset + data_offset, entry.second, parent));
+
+ if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
+ break;
+
+ this_file_offset = entry.first.sibling;
+ }
+}
+
+void ProcessDirectory(VirtualFile file, size_t dir_offset, size_t file_offset, size_t data_offset,
+ u32 this_dir_offset, std::shared_ptr<VectorVfsDirectory> parent) {
+ while (true) {
+ auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
+ auto current = std::make_shared<VectorVfsDirectory>(
+ std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parent, entry.second);
+
+ if (entry.first.child_file != ROMFS_ENTRY_EMPTY) {
+ ProcessFile(file, file_offset, data_offset, entry.first.child_file, current);
+ }
+
+ if (entry.first.child_dir != ROMFS_ENTRY_EMPTY) {
+ ProcessDirectory(file, dir_offset, file_offset, data_offset, entry.first.child_dir,
+ current);
+ }
+
+ parent->AddDirectory(current);
+ if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
+ break;
+ this_dir_offset = entry.first.sibling;
+ }
+}
+
+VirtualDir ExtractRomFS(VirtualFile file) {
+ RomFSHeader header{};
+ if (file->ReadObject(&header) != sizeof(RomFSHeader))
+ return nullptr;
+
+ if (header.header_size != sizeof(RomFSHeader))
+ return nullptr;
+
+ const u64 file_offset = header.file_meta.offset;
+ const u64 dir_offset = header.directory_meta.offset + 4;
+
+ const auto root =
+ std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{},
+ file->GetContainingDirectory(), file->GetName());
+
+ ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root);
+
+ VirtualDir out = std::move(root);
+
+ while (out->GetSubdirectory("") != nullptr)
+ out = out->GetSubdirectory("");
+
+ return out;
+}
+} // namespace FileSys
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h
new file mode 100644
index 000000000..03a876d22
--- /dev/null
+++ b/src/core/file_sys/romfs.h
@@ -0,0 +1,35 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include "common/common_funcs.h"
+#include "common/swap.h"
+#include "core/file_sys/vfs.h"
+
+namespace FileSys {
+
+struct IVFCLevel {
+ u64_le offset;
+ u64_le size;
+ u32_le block_size;
+ u32_le reserved;
+};
+static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
+
+struct IVFCHeader {
+ u32_le magic;
+ u32_le magic_number;
+ INSERT_PADDING_BYTES(8);
+ std::array<IVFCLevel, 6> levels;
+ INSERT_PADDING_BYTES(64);
+};
+static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
+
+// Converts a RomFS binary blob to VFS Filesystem
+// Returns nullptr on failure
+VirtualDir ExtractRomFS(VirtualFile file);
+
+} // namespace FileSys
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index b99a4fd5b..dae1c16ef 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -46,6 +46,13 @@ size_t VfsFile::WriteBytes(const std::vector<u8>& data, size_t offset) {
return Write(data.data(), data.size(), offset);
}
+std::string VfsFile::GetFullPath() const {
+ if (GetContainingDirectory() == nullptr)
+ return "/" + GetName();
+
+ return GetContainingDirectory()->GetFullPath() + "/" + GetName();
+}
+
std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const {
auto vec = FileUtil::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
@@ -243,6 +250,13 @@ bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize();
}
+std::string VfsDirectory::GetFullPath() const {
+ if (IsRoot())
+ return GetName();
+
+ return GetParentDirectory()->GetFullPath() + "/" + GetName();
+}
+
bool ReadOnlyVfsDirectory::IsWritable() const {
return false;
}
@@ -270,4 +284,33 @@ bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
bool ReadOnlyVfsDirectory::Rename(std::string_view name) {
return false;
}
+
+bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size) {
+ if (file1->GetSize() != file2->GetSize())
+ return false;
+
+ std::vector<u8> f1_v(block_size);
+ std::vector<u8> f2_v(block_size);
+ for (size_t i = 0; i < file1->GetSize(); i += block_size) {
+ auto f1_vs = file1->Read(f1_v.data(), block_size, i);
+ auto f2_vs = file2->Read(f2_v.data(), block_size, i);
+
+ if (f1_vs != f2_vs)
+ return false;
+ auto iters = std::mismatch(f1_v.begin(), f1_v.end(), f2_v.begin(), f2_v.end());
+ if (iters.first != f1_v.end() && iters.second != f2_v.end())
+ return false;
+ }
+
+ return true;
+}
+
+bool VfsRawCopy(VirtualFile src, VirtualFile dest) {
+ if (src == nullptr || dest == nullptr)
+ return false;
+ if (!dest->Resize(src->GetSize()))
+ return false;
+ std::vector<u8> data = src->ReadAllBytes();
+ return dest->WriteBytes(data, 0) == data.size();
+}
} // namespace FileSys
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 4a13b8378..fab9e2b45 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -113,6 +113,9 @@ struct VfsFile : NonCopyable {
// Renames the file to name. Returns whether or not the operation was successsful.
virtual bool Rename(std::string_view name) = 0;
+
+ // Returns the full path of this file as a string, recursively
+ virtual std::string GetFullPath() const;
};
// A class representing a directory in an abstract filesystem.
@@ -213,6 +216,17 @@ struct VfsDirectory : NonCopyable {
return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p));
}
+ bool InterpretAsDirectory(const std::function<VirtualDir(VirtualFile)>& function,
+ const std::string& file) {
+ auto file_p = GetFile(file);
+ if (file_p == nullptr)
+ return false;
+ return ReplaceFileWithSubdirectory(file_p, function(file_p));
+ }
+
+ // Returns the full path of this directory as a string, recursively
+ virtual std::string GetFullPath() const;
+
protected:
// Backend for InterpretAsDirectory.
// Removes all references to file and adds a reference to dir in the directory's implementation.
@@ -230,4 +244,13 @@ struct ReadOnlyVfsDirectory : public VfsDirectory {
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
};
+
+// Compare the two files, byte-for-byte, in increments specificed by block_size
+bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size = 0x200);
+
+// A method that copies the raw data between two different implementations of VirtualFile. If you
+// are using the same implementation, it is probably better to use the Copy method in the parent
+// directory of src/dest.
+bool VfsRawCopy(VirtualFile src, VirtualFile dest);
+
} // namespace FileSys
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp
index a40331cef..847cde2f5 100644
--- a/src/core/file_sys/vfs_offset.cpp
+++ b/src/core/file_sys/vfs_offset.cpp
@@ -10,8 +10,9 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_,
- std::string name_)
- : file(std::move(file_)), offset(offset_), size(size_), name(std::move(name_)) {}
+ std::string name_, VirtualDir parent_)
+ : file(file_), offset(offset_), size(size_), name(std::move(name_)),
+ parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
std::string OffsetVfsFile::GetName() const {
return name.empty() ? file->GetName() : name;
@@ -35,7 +36,7 @@ bool OffsetVfsFile::Resize(size_t new_size) {
}
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
- return file->GetContainingDirectory();
+ return parent;
}
bool OffsetVfsFile::IsWritable() const {
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h
index 4f471e3ba..235970dc5 100644
--- a/src/core/file_sys/vfs_offset.h
+++ b/src/core/file_sys/vfs_offset.h
@@ -17,7 +17,7 @@ namespace FileSys {
// the size of this wrapper.
struct OffsetVfsFile : public VfsFile {
OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0,
- std::string new_name = "");
+ std::string new_name = "", VirtualDir new_parent = nullptr);
std::string GetName() const override;
size_t GetSize() const override;
@@ -44,6 +44,7 @@ private:
size_t offset;
size_t size;
std::string name;
+ VirtualDir parent;
};
} // namespace FileSys
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 9ce2e1efa..82d54da4a 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -195,6 +195,12 @@ bool RealVfsDirectory::Rename(std::string_view name) {
return FileUtil::Rename(path, new_name);
}
+std::string RealVfsDirectory::GetFullPath() const {
+ auto out = path;
+ std::replace(out.begin(), out.end(), '\\', '/');
+ return out;
+}
+
bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
const auto iter = std::find(files.begin(), files.end(), file);
if (iter == files.end())
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h
index 2151211c9..243d58576 100644
--- a/src/core/file_sys/vfs_real.h
+++ b/src/core/file_sys/vfs_real.h
@@ -41,7 +41,7 @@ private:
// An implementation of VfsDirectory that represents a directory on the user's computer.
struct RealVfsDirectory : public VfsDirectory {
- RealVfsDirectory(const std::string& path, Mode perms);
+ RealVfsDirectory(const std::string& path, Mode perms = Mode::Read);
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
@@ -54,6 +54,7 @@ struct RealVfsDirectory : public VfsDirectory {
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
+ std::string GetFullPath() const override;
protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
diff --git a/src/core/file_sys/vfs_vector.cpp b/src/core/file_sys/vfs_vector.cpp
new file mode 100644
index 000000000..fda603960
--- /dev/null
+++ b/src/core/file_sys/vfs_vector.cpp
@@ -0,0 +1,86 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <utility>
+#include "core/file_sys/vfs_vector.h"
+
+namespace FileSys {
+VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_,
+ std::vector<VirtualDir> dirs_, VirtualDir parent_,
+ std::string name_)
+ : files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)),
+ name(std::move(name_)) {}
+
+std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const {
+ return files;
+}
+
+std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const {
+ return dirs;
+}
+
+bool VectorVfsDirectory::IsWritable() const {
+ return false;
+}
+
+bool VectorVfsDirectory::IsReadable() const {
+ return true;
+}
+
+std::string VectorVfsDirectory::GetName() const {
+ return name;
+}
+
+std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
+ return parent;
+}
+
+template <typename T>
+static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) {
+ const auto iter =
+ std::find_if(vec.begin(), vec.end(), [name](const T& e) { return e->GetName() == name; });
+ if (iter == vec.end())
+ return false;
+
+ vec.erase(iter);
+ return true;
+}
+
+bool VectorVfsDirectory::DeleteSubdirectory(std::string_view name) {
+ return FindAndRemoveVectorElement(dirs, name);
+}
+
+bool VectorVfsDirectory::DeleteFile(std::string_view name) {
+ return FindAndRemoveVectorElement(files, name);
+}
+
+bool VectorVfsDirectory::Rename(std::string_view name_) {
+ name = name_;
+ return true;
+}
+
+std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
+ return nullptr;
+}
+
+std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) {
+ return nullptr;
+}
+
+void VectorVfsDirectory::AddFile(VirtualFile file) {
+ files.push_back(std::move(file));
+}
+
+void VectorVfsDirectory::AddDirectory(VirtualDir dir) {
+ dirs.push_back(std::move(dir));
+}
+
+bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
+ if (!DeleteFile(file->GetName()))
+ return false;
+ dirs.emplace_back(std::move(dir));
+ return true;
+}
+} // namespace FileSys
diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h
new file mode 100644
index 000000000..ba469647b
--- /dev/null
+++ b/src/core/file_sys/vfs_vector.h
@@ -0,0 +1,44 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/file_sys/vfs.h"
+
+namespace FileSys {
+
+// An implementation of VfsDirectory that maintains two vectors for subdirectories and files.
+// Vector data is supplied upon construction.
+struct VectorVfsDirectory : public VfsDirectory {
+ explicit VectorVfsDirectory(std::vector<VirtualFile> files = {},
+ std::vector<VirtualDir> dirs = {}, VirtualDir parent = nullptr,
+ std::string name = "");
+
+ std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
+ std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
+ bool IsWritable() const override;
+ bool IsReadable() const override;
+ std::string GetName() const override;
+ std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
+ bool DeleteSubdirectory(std::string_view name) override;
+ bool DeleteFile(std::string_view name) override;
+ bool Rename(std::string_view name) override;
+ std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
+ std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
+
+ virtual void AddFile(VirtualFile file);
+ virtual void AddDirectory(VirtualDir dir);
+
+protected:
+ bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
+
+private:
+ std::vector<VirtualFile> files;
+ std::vector<VirtualDir> dirs;
+
+ VirtualDir parent;
+ std::string name;
+};
+
+} // namespace FileSys
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 5ca573652..332e5c3d0 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -37,45 +37,46 @@
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/gdbstub/gdbstub.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/scheduler.h"
#include "core/loader/loader.h"
#include "core/memory.h"
-const int GDB_BUFFER_SIZE = 10000;
+namespace GDBStub {
+namespace {
+constexpr int GDB_BUFFER_SIZE = 10000;
-const char GDB_STUB_START = '$';
-const char GDB_STUB_END = '#';
-const char GDB_STUB_ACK = '+';
-const char GDB_STUB_NACK = '-';
+constexpr char GDB_STUB_START = '$';
+constexpr char GDB_STUB_END = '#';
+constexpr char GDB_STUB_ACK = '+';
+constexpr char GDB_STUB_NACK = '-';
#ifndef SIGTRAP
-const u32 SIGTRAP = 5;
+constexpr u32 SIGTRAP = 5;
#endif
#ifndef SIGTERM
-const u32 SIGTERM = 15;
+constexpr u32 SIGTERM = 15;
#endif
#ifndef MSG_WAITALL
-const u32 MSG_WAITALL = 8;
+constexpr u32 MSG_WAITALL = 8;
#endif
-const u32 LR_REGISTER = 30;
-const u32 SP_REGISTER = 31;
-const u32 PC_REGISTER = 32;
-const u32 CPSR_REGISTER = 33;
-const u32 UC_ARM64_REG_Q0 = 34;
-const u32 FPSCR_REGISTER = 66;
+constexpr u32 LR_REGISTER = 30;
+constexpr u32 SP_REGISTER = 31;
+constexpr u32 PC_REGISTER = 32;
+constexpr u32 CPSR_REGISTER = 33;
+constexpr u32 UC_ARM64_REG_Q0 = 34;
+constexpr u32 FPSCR_REGISTER = 66;
// TODO/WiP - Used while working on support for FPU
-const u32 TODO_DUMMY_REG_997 = 997;
-const u32 TODO_DUMMY_REG_998 = 998;
+constexpr u32 TODO_DUMMY_REG_997 = 997;
+constexpr u32 TODO_DUMMY_REG_998 = 998;
// For sample XML files see the GDB source /gdb/features
// GDB also wants the l character at the start
// This XML defines what the registers are for this specific ARM device
-static const char* target_xml =
+constexpr char target_xml[] =
R"(l<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
@@ -141,30 +142,28 @@ static const char* target_xml =
</target>
)";
-namespace GDBStub {
-
-static int gdbserver_socket = -1;
+int gdbserver_socket = -1;
-static u8 command_buffer[GDB_BUFFER_SIZE];
-static u32 command_length;
+u8 command_buffer[GDB_BUFFER_SIZE];
+u32 command_length;
-static u32 latest_signal = 0;
-static bool memory_break = false;
+u32 latest_signal = 0;
+bool memory_break = false;
-static Kernel::Thread* current_thread = nullptr;
-static u32 current_core = 0;
+Kernel::Thread* current_thread = nullptr;
+u32 current_core = 0;
// Binding to a port within the reserved ports range (0-1023) requires root permissions,
// so default to a port outside of that range.
-static u16 gdbstub_port = 24689;
+u16 gdbstub_port = 24689;
-static bool halt_loop = true;
-static bool step_loop = false;
-static bool send_trap = false;
+bool halt_loop = true;
+bool step_loop = false;
+bool send_trap = false;
// If set to false, the server will never be started and no
// gdbstub-related functions will be executed.
-static std::atomic<bool> server_enabled(false);
+std::atomic<bool> server_enabled(false);
#ifdef _WIN32
WSADATA InitData;
@@ -172,23 +171,26 @@ WSADATA InitData;
struct Breakpoint {
bool active;
- PAddr addr;
+ VAddr addr;
u64 len;
+ std::array<u8, 4> inst;
};
-static std::map<u64, Breakpoint> breakpoints_execute;
-static std::map<u64, Breakpoint> breakpoints_read;
-static std::map<u64, Breakpoint> breakpoints_write;
+using BreakpointMap = std::map<VAddr, Breakpoint>;
+BreakpointMap breakpoints_execute;
+BreakpointMap breakpoints_read;
+BreakpointMap breakpoints_write;
struct Module {
std::string name;
- PAddr beg;
- PAddr end;
+ VAddr beg;
+ VAddr end;
};
-static std::vector<Module> modules;
+std::vector<Module> modules;
+} // Anonymous namespace
-void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext) {
+void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) {
Module module;
if (add_elf_ext) {
Common::SplitPath(name, nullptr, &module.name, nullptr);
@@ -419,11 +421,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
}
/**
- * Get the list of breakpoints for a given breakpoint type.
+ * Get the map of breakpoints for a given breakpoint type.
*
- * @param type Type of breakpoint list.
+ * @param type Type of breakpoint map.
*/
-static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
+static BreakpointMap& GetBreakpointMap(BreakpointType type) {
switch (type) {
case BreakpointType::Execute:
return breakpoints_execute;
@@ -442,20 +444,24 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
* @param type Type of breakpoint.
* @param addr Address of breakpoint.
*/
-static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
+static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
+ BreakpointMap& p = GetBreakpointMap(type);
- auto bp = p.find(static_cast<u64>(addr));
- if (bp != p.end()) {
- LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
- bp->second.len, bp->second.addr, static_cast<int>(type));
- p.erase(static_cast<u64>(addr));
+ const auto bp = p.find(addr);
+ if (bp == p.end()) {
+ return;
}
+
+ LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
+ bp->second.len, bp->second.addr, static_cast<int>(type));
+ Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
+ p.erase(addr);
}
-BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) {
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
- auto next_breakpoint = p.lower_bound(static_cast<u64>(addr));
+BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
+ const BreakpointMap& p = GetBreakpointMap(type);
+ const auto next_breakpoint = p.lower_bound(addr);
BreakpointAddress breakpoint;
if (next_breakpoint != p.end()) {
@@ -469,36 +475,38 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type)
return breakpoint;
}
-bool CheckBreakpoint(PAddr addr, BreakpointType type) {
+bool CheckBreakpoint(VAddr addr, BreakpointType type) {
if (!IsConnected()) {
return false;
}
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
+ const BreakpointMap& p = GetBreakpointMap(type);
+ const auto bp = p.find(addr);
- auto bp = p.find(static_cast<u64>(addr));
- if (bp != p.end()) {
- u64 len = bp->second.len;
+ if (bp == p.end()) {
+ return false;
+ }
- // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
- // no matter if it's a 4-byte or 2-byte instruction. When you execute a
- // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
- // two instructions instead of the single instruction you placed the breakpoint
- // on. So, as a way to make sure that execution breakpoints are only breaking
- // on the instruction that was specified, set the length of an execution
- // breakpoint to 1. This should be fine since the CPU should never begin executing
- // an instruction anywhere except the beginning of the instruction.
- if (type == BreakpointType::Execute) {
- len = 1;
- }
+ u64 len = bp->second.len;
- if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
- LOG_DEBUG(Debug_GDBStub,
- "Found breakpoint type {} @ {:016X}, range: {:016X}"
- " - {:016X} ({:X} bytes)",
- static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
- return true;
- }
+ // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
+ // no matter if it's a 4-byte or 2-byte instruction. When you execute a
+ // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
+ // two instructions instead of the single instruction you placed the breakpoint
+ // on. So, as a way to make sure that execution breakpoints are only breaking
+ // on the instruction that was specified, set the length of an execution
+ // breakpoint to 1. This should be fine since the CPU should never begin executing
+ // an instruction anywhere except the beginning of the instruction.
+ if (type == BreakpointType::Execute) {
+ len = 1;
+ }
+
+ if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
+ LOG_DEBUG(Debug_GDBStub,
+ "Found breakpoint type {} @ {:016X}, range: {:016X}"
+ " - {:016X} ({:X} bytes)",
+ static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
+ return true;
}
return false;
@@ -932,6 +940,7 @@ static void WriteMemory() {
GdbHexToMem(data.data(), len_pos + 1, len);
Memory::WriteBlock(addr, data.data(), len);
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
SendReply("OK");
}
@@ -951,6 +960,7 @@ static void Step() {
step_loop = true;
halt_loop = true;
send_trap = true;
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
}
/// Tell the CPU if we hit a memory breakpoint.
@@ -967,6 +977,7 @@ static void Continue() {
memory_break = false;
step_loop = false;
halt_loop = false;
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
}
/**
@@ -976,13 +987,17 @@ static void Continue() {
* @param addr Address of breakpoint.
* @param len Length of breakpoint.
*/
-static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) {
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
+static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
+ BreakpointMap& p = GetBreakpointMap(type);
Breakpoint breakpoint;
breakpoint.active = true;
breakpoint.addr = addr;
breakpoint.len = len;
+ Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
+ static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
+ Memory::WriteBlock(addr, btrap.data(), btrap.size());
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
p.insert({addr, breakpoint});
LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
@@ -1016,7 +1031,7 @@ static void AddBreakpoint() {
auto start_offset = command_buffer + 3;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
- PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
+ VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
start_offset = addr_pos + 1;
u64 len =
@@ -1065,7 +1080,7 @@ static void RemoveBreakpoint() {
auto start_offset = command_buffer + 3;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
- PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
+ VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
if (type == BreakpointType::Access) {
// Access is made up of Read and Write types, so add both breakpoints
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h
index a6b50c26c..5a36524b2 100644
--- a/src/core/gdbstub/gdbstub.h
+++ b/src/core/gdbstub/gdbstub.h
@@ -22,7 +22,7 @@ enum class BreakpointType {
};
struct BreakpointAddress {
- PAddr address;
+ VAddr address;
BreakpointType type;
};
@@ -53,7 +53,7 @@ bool IsServerEnabled();
bool IsConnected();
/// Register module.
-void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext = true);
+void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
/**
* Signal to the gdbstub server that it should halt CPU execution.
@@ -74,7 +74,7 @@ void HandlePacket();
* @param addr Address to search from.
* @param type Type of breakpoint.
*/
-BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointType type);
+BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
/**
* Check if a breakpoint of the specified type exists at the given address.
@@ -82,7 +82,7 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointTy
* @param addr Address of breakpoint.
* @param type Type of breakpoint.
*/
-bool CheckBreakpoint(PAddr addr, GDBStub::BreakpointType type);
+bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
/// If set to true, the CPU will halt at the beginning of the next CPU loop.
bool GetCpuHaltFlag();
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 7fb0da408..d3a734831 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -5,15 +5,18 @@
#pragma once
#include <array>
+#include <cstring>
+#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
+#include "common/assert.h"
+#include "common/common_types.h"
#include "core/hle/ipc.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
-#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/server_port.h"
namespace IPC {
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 233fdab25..03a954a9f 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -2,15 +2,17 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <vector>
+
#include "common/assert.h"
-#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
-#include "core/hle/lock.h"
+#include "core/hle/result.h"
#include "core/memory.h"
namespace Kernel {
@@ -30,9 +32,8 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) {
}
// Gets the threads waiting on an address.
-static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads,
- VAddr address) {
- auto RetrieveWaitingThreads =
+static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) {
+ const auto RetrieveWaitingThreads =
[](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) {
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
auto& thread_list = scheduler->GetThreadList();
@@ -43,16 +44,20 @@ static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_t
}
};
- // Retrieve a list of all threads that are waiting for this address.
- RetrieveWaitingThreads(0, waiting_threads, address);
- RetrieveWaitingThreads(1, waiting_threads, address);
- RetrieveWaitingThreads(2, waiting_threads, address);
- RetrieveWaitingThreads(3, waiting_threads, address);
+ // Retrieve all threads that are waiting for this address.
+ std::vector<SharedPtr<Thread>> threads;
+ RetrieveWaitingThreads(0, threads, address);
+ RetrieveWaitingThreads(1, threads, address);
+ RetrieveWaitingThreads(2, threads, address);
+ RetrieveWaitingThreads(3, threads, address);
+
// Sort them by priority, such that the highest priority ones come first.
- std::sort(waiting_threads.begin(), waiting_threads.end(),
+ std::sort(threads.begin(), threads.end(),
[](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
return lhs->current_priority < rhs->current_priority;
});
+
+ return threads;
}
// Wake up num_to_wake (or all) threads in a vector.
@@ -74,9 +79,7 @@ static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num
// Signals an address being waited on.
ResultCode SignalToAddress(VAddr address, s32 num_to_wake) {
- // Get threads waiting on the address.
- std::vector<SharedPtr<Thread>> waiting_threads;
- GetThreadsWaitingOnAddress(waiting_threads, address);
+ std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
WakeThreads(waiting_threads, num_to_wake);
return RESULT_SUCCESS;
@@ -108,12 +111,11 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu
}
// Get threads waiting on the address.
- std::vector<SharedPtr<Thread>> waiting_threads;
- GetThreadsWaitingOnAddress(waiting_threads, address);
+ std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
// Determine the modified value depending on the waiting count.
s32 updated_value;
- if (waiting_threads.size() == 0) {
+ if (waiting_threads.empty()) {
updated_value = value - 1;
} else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) {
updated_value = value + 1;
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index f20f3dbc0..e3657b8e9 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -4,7 +4,9 @@
#pragma once
-#include "core/hle/result.h"
+#include "common/common_types.h"
+
+union ResultCode;
namespace Kernel {
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index fb2b6f7a3..134e41ebc 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -2,19 +2,20 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/assert.h"
+#include <tuple>
+
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/hle_ipc.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/server_session.h"
namespace Kernel {
-ClientPort::ClientPort() {}
-ClientPort::~ClientPort() {}
+ClientPort::ClientPort() = default;
+ClientPort::~ClientPort() = default;
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
// Note: Threads do not wait for the server endpoint to call
@@ -39,4 +40,12 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
}
+void ClientPort::ConnectionClosed() {
+ if (active_sessions == 0) {
+ return;
+ }
+
+ --active_sessions;
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index a829aeb6d..b1269ea5c 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -6,7 +6,7 @@
#include <string>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/result.h"
namespace Kernel {
@@ -37,14 +37,20 @@ public:
*/
ResultVal<SharedPtr<ClientSession>> Connect();
- SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
- u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have
- u32 active_sessions; ///< Number of currently open sessions to this port
- std::string name; ///< Name of client port (optional)
+ /**
+ * Signifies that a previously active connection has been closed,
+ * decreasing the total number of active connections to this port.
+ */
+ void ConnectionClosed();
private:
ClientPort();
~ClientPort() override;
+
+ SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
+ u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
+ u32 active_sessions = 0; ///< Number of currently open sessions to this port
+ std::string name; ///< Name of client port (optional)
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp
index 72773d8b1..fdffc648d 100644
--- a/src/core/hle/kernel/client_session.cpp
+++ b/src/core/hle/kernel/client_session.cpp
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/assert.h"
-
#include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/hle_ipc.h"
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index 2258f95bc..dabd93ed7 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -7,7 +7,7 @@
#include <memory>
#include <string>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/result.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 9cae2369f..5623c4b6a 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -3,11 +3,9 @@
// Refer to the license.txt file included.
#include <algorithm>
-#include <map>
-#include <vector>
#include "common/assert.h"
#include "core/hle/kernel/event.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index e5c924a75..3c20c05e8 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -5,7 +5,7 @@
#pragma once
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
namespace Kernel {
@@ -31,10 +31,9 @@ public:
return HANDLE_TYPE;
}
- ResetType reset_type; ///< Current ResetType
-
- bool signaled; ///< Whether the event has already been signaled
- std::string name; ///< Name of event (optional)
+ ResetType GetResetType() const {
+ return reset_type;
+ }
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
@@ -47,6 +46,11 @@ public:
private:
Event();
~Event() override;
+
+ ResetType reset_type; ///< Current ResetType
+
+ bool signaled; ///< Whether the event has already been signaled
+ std::string name; ///< Name of event (optional)
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 7dd67f80f..28e21428a 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -8,7 +8,6 @@
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h
index ba968c666..22ddda630 100644
--- a/src/core/hle/kernel/handle_table.h
+++ b/src/core/hle/kernel/handle_table.h
@@ -7,7 +7,7 @@
#include <array>
#include <cstddef>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/result.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index f24392520..5dd1b68d7 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -2,17 +2,22 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <array>
+#include <sstream>
#include <utility>
#include <boost/range/algorithm_ext/erase.hpp>
+
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/server_session.h"
#include "core/memory.h"
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 84727f748..9ce52db24 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -5,7 +5,6 @@
#pragma once
#include <array>
-#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
@@ -14,7 +13,7 @@
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/ipc.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/thread.h"
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 1beb98566..1b0cd0abf 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -4,8 +4,6 @@
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/object_address_table.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
@@ -16,9 +14,7 @@ namespace Kernel {
unsigned int Object::next_object_id;
/// Initialize the kernel
-void Init(u32 system_mode) {
- Kernel::MemoryInit(system_mode);
-
+void Init() {
Kernel::ResourceLimitsInit();
Kernel::ThreadingInit();
Kernel::TimersInit();
@@ -33,13 +29,11 @@ void Init(u32 system_mode) {
void Shutdown() {
// Free all kernel objects
g_handle_table.Clear();
- g_object_address_table.Clear();
Kernel::ThreadingShutdown();
Kernel::TimersShutdown();
Kernel::ResourceLimitsShutdown();
- Kernel::MemoryShutdown();
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 402ae900f..131311472 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,122 +4,12 @@
#pragma once
-#include <cstddef>
-#include <string>
-#include <utility>
-#include <boost/smart_ptr/intrusive_ptr.hpp>
-#include "common/assert.h"
#include "common/common_types.h"
namespace Kernel {
-using Handle = u32;
-
-enum class HandleType : u32 {
- Unknown,
- Event,
- SharedMemory,
- Thread,
- Process,
- AddressArbiter,
- Timer,
- ResourceLimit,
- CodeSet,
- ClientPort,
- ServerPort,
- ClientSession,
- ServerSession,
-};
-
-enum class ResetType {
- OneShot,
- Sticky,
- Pulse,
-};
-
-class Object : NonCopyable {
-public:
- virtual ~Object() {}
-
- /// Returns a unique identifier for the object. For debugging purposes only.
- unsigned int GetObjectId() const {
- return object_id;
- }
-
- virtual std::string GetTypeName() const {
- return "[BAD KERNEL OBJECT TYPE]";
- }
- virtual std::string GetName() const {
- return "[UNKNOWN KERNEL OBJECT]";
- }
- virtual Kernel::HandleType GetHandleType() const = 0;
-
- /**
- * Check if a thread can wait on the object
- * @return True if a thread can wait on the object, otherwise false
- */
- bool IsWaitable() const {
- switch (GetHandleType()) {
- case HandleType::Event:
- case HandleType::Thread:
- case HandleType::Timer:
- case HandleType::ServerPort:
- case HandleType::ServerSession:
- return true;
-
- case HandleType::Unknown:
- case HandleType::SharedMemory:
- case HandleType::Process:
- case HandleType::AddressArbiter:
- case HandleType::ResourceLimit:
- case HandleType::CodeSet:
- case HandleType::ClientPort:
- case HandleType::ClientSession:
- return false;
- }
-
- UNREACHABLE();
- }
-
-public:
- static unsigned int next_object_id;
-
-private:
- friend void intrusive_ptr_add_ref(Object*);
- friend void intrusive_ptr_release(Object*);
-
- unsigned int ref_count = 0;
- unsigned int object_id = next_object_id++;
-};
-
-// Special functions used by boost::instrusive_ptr to do automatic ref-counting
-inline void intrusive_ptr_add_ref(Object* object) {
- ++object->ref_count;
-}
-
-inline void intrusive_ptr_release(Object* object) {
- if (--object->ref_count == 0) {
- delete object;
- }
-}
-
-template <typename T>
-using SharedPtr = boost::intrusive_ptr<T>;
-
-/**
- * Attempts to downcast the given Object pointer to a pointer to T.
- * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
- */
-template <typename T>
-inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
- if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
- return boost::static_pointer_cast<T>(std::move(object));
- }
- return nullptr;
-}
-
/// Initialize the kernel with the specified system mode.
-void Init(u32 system_mode);
+void Init();
/// Shutdown the kernel
void Shutdown();
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
deleted file mode 100644
index 94eac677c..000000000
--- a/src/core/hle/kernel/memory.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include <cinttypes>
-#include <map>
-#include <memory>
-#include <utility>
-#include <vector>
-#include "common/assert.h"
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/vm_manager.h"
-#include "core/hle/result.h"
-#include "core/memory.h"
-#include "core/memory_setup.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace Kernel {
-
-MemoryRegionInfo memory_regions[3];
-
-/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
-/// memory configuration type.
-static const u32 memory_region_sizes[8][3] = {
- // Old 3DS layouts
- {0x04000000, 0x02C00000, 0x01400000}, // 0
- {/* This appears to be unused. */}, // 1
- {0x06000000, 0x00C00000, 0x01400000}, // 2
- {0x05000000, 0x01C00000, 0x01400000}, // 3
- {0x04800000, 0x02400000, 0x01400000}, // 4
- {0x02000000, 0x04C00000, 0x01400000}, // 5
-
- // New 3DS layouts
- {0x07C00000, 0x06400000, 0x02000000}, // 6
- {0x0B200000, 0x02E00000, 0x02000000}, // 7
-};
-
-void MemoryInit(u32 mem_type) {
- // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
- ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
- ASSERT(mem_type != 1);
-
- // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
- // the sizes specified in the memory_region_sizes table.
- VAddr base = 0;
- for (int i = 0; i < 3; ++i) {
- memory_regions[i].base = base;
- memory_regions[i].size = memory_region_sizes[mem_type][i];
- memory_regions[i].used = 0;
- memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
- // Reserve enough space for this region of FCRAM.
- // We do not want this block of memory to be relocated when allocating from it.
- memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size);
-
- base += memory_regions[i].size;
- }
-
- // We must've allocated the entire FCRAM by the end
- ASSERT(base == Memory::FCRAM_SIZE);
-}
-
-void MemoryShutdown() {
- for (auto& region : memory_regions) {
- region.base = 0;
- region.size = 0;
- region.used = 0;
- region.linear_heap_memory = nullptr;
- }
-}
-
-MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
- switch (region) {
- case MemoryRegion::APPLICATION:
- return &memory_regions[0];
- case MemoryRegion::SYSTEM:
- return &memory_regions[1];
- case MemoryRegion::BASE:
- return &memory_regions[2];
- default:
- UNREACHABLE();
- }
-}
-
-void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
-
-void MapSharedPages(VMManager& address_space) {}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
deleted file mode 100644
index 61e30c679..000000000
--- a/src/core/hle/kernel/memory.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <memory>
-#include "common/common_types.h"
-#include "core/hle/kernel/process.h"
-
-namespace Kernel {
-
-class VMManager;
-
-struct MemoryRegionInfo {
- u64 base; // Not an address, but offset from start of FCRAM
- u64 size;
- u64 used;
-
- std::shared_ptr<std::vector<u8>> linear_heap_memory;
-};
-
-void MemoryInit(u32 mem_type);
-void MemoryShutdown();
-MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
-
-void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
-void MapSharedPages(VMManager& address_space);
-
-extern MemoryRegionInfo memory_regions[3];
-} // namespace Kernel
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index feb7b88d2..cb7f58b35 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -3,16 +3,19 @@
// Refer to the license.txt file included.
#include <map>
+#include <utility>
#include <vector>
+
#include <boost/range/algorithm_ext/erase.hpp>
+
#include "common/assert.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/mutex.h"
-#include "core/hle/kernel/object_address_table.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h"
+#include "core/hle/result.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index 3117e7c70..45268bbe9 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -4,12 +4,10 @@
#pragma once
-#include <string>
#include "common/common_types.h"
-#include "common/swap.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/wait_object.h"
-#include "core/hle/result.h"
+#include "core/hle/kernel/object.h"
+
+union ResultCode;
namespace Kernel {
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
new file mode 100644
index 000000000..cdba272f5
--- /dev/null
+++ b/src/core/hle/kernel/object.cpp
@@ -0,0 +1,35 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "core/hle/kernel/object.h"
+
+namespace Kernel {
+
+Object::~Object() = default;
+
+bool Object::IsWaitable() const {
+ switch (GetHandleType()) {
+ case HandleType::Event:
+ case HandleType::Thread:
+ case HandleType::Timer:
+ case HandleType::ServerPort:
+ case HandleType::ServerSession:
+ return true;
+
+ case HandleType::Unknown:
+ case HandleType::SharedMemory:
+ case HandleType::Process:
+ case HandleType::AddressArbiter:
+ case HandleType::ResourceLimit:
+ case HandleType::CodeSet:
+ case HandleType::ClientPort:
+ case HandleType::ClientSession:
+ return false;
+ }
+
+ UNREACHABLE();
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
new file mode 100644
index 000000000..83df68dfd
--- /dev/null
+++ b/src/core/hle/kernel/object.h
@@ -0,0 +1,100 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+#include <utility>
+
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+
+#include "common/common_types.h"
+
+namespace Kernel {
+
+using Handle = u32;
+
+enum class HandleType : u32 {
+ Unknown,
+ Event,
+ SharedMemory,
+ Thread,
+ Process,
+ AddressArbiter,
+ Timer,
+ ResourceLimit,
+ CodeSet,
+ ClientPort,
+ ServerPort,
+ ClientSession,
+ ServerSession,
+};
+
+enum class ResetType {
+ OneShot,
+ Sticky,
+ Pulse,
+};
+
+class Object : NonCopyable {
+public:
+ virtual ~Object();
+
+ /// Returns a unique identifier for the object. For debugging purposes only.
+ unsigned int GetObjectId() const {
+ return object_id;
+ }
+
+ virtual std::string GetTypeName() const {
+ return "[BAD KERNEL OBJECT TYPE]";
+ }
+ virtual std::string GetName() const {
+ return "[UNKNOWN KERNEL OBJECT]";
+ }
+ virtual HandleType GetHandleType() const = 0;
+
+ /**
+ * Check if a thread can wait on the object
+ * @return True if a thread can wait on the object, otherwise false
+ */
+ bool IsWaitable() const;
+
+public:
+ static unsigned int next_object_id;
+
+private:
+ friend void intrusive_ptr_add_ref(Object*);
+ friend void intrusive_ptr_release(Object*);
+
+ unsigned int ref_count = 0;
+ unsigned int object_id = next_object_id++;
+};
+
+// Special functions used by boost::instrusive_ptr to do automatic ref-counting
+inline void intrusive_ptr_add_ref(Object* object) {
+ ++object->ref_count;
+}
+
+inline void intrusive_ptr_release(Object* object) {
+ if (--object->ref_count == 0) {
+ delete object;
+ }
+}
+
+template <typename T>
+using SharedPtr = boost::intrusive_ptr<T>;
+
+/**
+ * Attempts to downcast the given Object pointer to a pointer to T.
+ * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
+ */
+template <typename T>
+inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
+ if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
+ return boost::static_pointer_cast<T>(std::move(object));
+ }
+ return nullptr;
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/object_address_table.cpp b/src/core/hle/kernel/object_address_table.cpp
deleted file mode 100644
index ca8a833a1..000000000
--- a/src/core/hle/kernel/object_address_table.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <utility>
-
-#include "common/assert.h"
-#include "core/hle/kernel/object_address_table.h"
-
-namespace Kernel {
-
-ObjectAddressTable g_object_address_table;
-
-void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) {
- ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x{:X}", addr);
- objects[addr] = std::move(obj);
-}
-
-void ObjectAddressTable::Close(VAddr addr) {
- ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x{:X}", addr);
- objects.erase(addr);
-}
-
-SharedPtr<Object> ObjectAddressTable::GetGeneric(VAddr addr) const {
- auto iter = objects.find(addr);
- if (iter != objects.end()) {
- return iter->second;
- }
- return {};
-}
-
-void ObjectAddressTable::Clear() {
- objects.clear();
-}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/object_address_table.h b/src/core/hle/kernel/object_address_table.h
deleted file mode 100644
index a09004b32..000000000
--- a/src/core/hle/kernel/object_address_table.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <map>
-#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
-
-namespace Kernel {
-
-/**
- * This class is used to keep a table of Kernel objects and their respective addresses in emulated
- * memory. For certain Switch SVCs, Kernel objects are referenced by an address to an object the
- * guest application manages, so we use this table to look these kernel objects up. This is similiar
- * to the HandleTable class.
- */
-class ObjectAddressTable final : NonCopyable {
-public:
- ObjectAddressTable() = default;
-
- /**
- * Inserts an object and address pair into the table.
- */
- void Insert(VAddr addr, SharedPtr<Object> obj);
-
- /**
- * Closes an object by its address, removing it from the table and decreasing the object's
- * ref-count.
- * @return `RESULT_SUCCESS` or one of the following errors:
- * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
- */
- void Close(VAddr addr);
-
- /**
- * Looks up an object by its address.
- * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
- */
- SharedPtr<Object> GetGeneric(VAddr addr) const;
-
- /**
- * Looks up an object by its address while verifying its type.
- * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
- * type differs from the requested one.
- */
- template <class T>
- SharedPtr<T> Get(VAddr addr) const {
- return DynamicObjectCast<T>(GetGeneric(addr));
- }
-
- /// Closes all addresses held in this table.
- void Clear();
-
-private:
- /// Stores the Object referenced by the address
- std::map<VAddr, SharedPtr<Object>> objects;
-};
-
-extern ObjectAddressTable g_object_address_table;
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0c0506085..edf34c5a3 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,7 +8,6 @@
#include "common/common_funcs.h"
#include "common/logging/log.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
@@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
MemoryState::Mapped)
.Unwrap();
- misc_memory_used += stack_size;
- memory_region->used += stack_size;
-
- // Map special address mappings
- MapSharedPages(vm_manager);
- for (const auto& mapping : address_mappings) {
- HandleSpecialMapping(vm_manager, mapping);
- }
vm_manager.LogLayout();
status = ProcessStatus::Running;
@@ -141,37 +132,19 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
}
void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
- memory_region = GetMemoryRegion(flags.memory_region);
-
- auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
- MemoryState memory_state) {
+ const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
+ MemoryState memory_state) {
auto vma = vm_manager
.MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
segment.size, memory_state)
.Unwrap();
vm_manager.Reprotect(vma, permissions);
- misc_memory_used += segment.size;
- memory_region->used += segment.size;
};
// Map CodeSet segments
- MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
- MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
- MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
-}
-
-VAddr Process::GetLinearHeapAreaAddress() const {
- // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
- // the extra RAM in the n3DS.
- return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
-}
-
-VAddr Process::GetLinearHeapBase() const {
- return GetLinearHeapAreaAddress() + memory_region->base;
-}
-
-VAddr Process::GetLinearHeapLimit() const {
- return GetLinearHeapBase() + memory_region->size;
+ MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic);
+ MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable);
+ MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable);
}
ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
@@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
vm_manager.Reprotect(vma, perms);
heap_used = size;
- memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
}
@@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
return result;
heap_used -= size;
- memory_region->used -= size;
-
- return RESULT_SUCCESS;
-}
-
-ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
- UNIMPLEMENTED();
- return {};
-}
-
-ResultCode Process::LinearFree(VAddr target, u32 size) {
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
- target + size < target) {
-
- return ERR_INVALID_ADDRESS;
- }
-
- if (size == 0) {
- return RESULT_SUCCESS;
- }
-
- VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size();
- if (target + size > heap_end) {
- return ERR_INVALID_ADDRESS_STATE;
- }
-
- ResultCode result = vm_manager.UnmapRange(target, size);
- if (result.IsError())
- return result;
-
- linear_heap_used -= size;
- memory_region->used -= size;
-
- if (target + size == heap_end) {
- // End of linear heap has been freed, so check what's the last allocated block in it and
- // reduce the size.
- auto vma = vm_manager.FindVMA(target);
- ASSERT(vma != vm_manager.vma_map.end());
- ASSERT(vma->second.type == VMAType::Free);
- VAddr new_end = vma->second.base;
- if (new_end >= GetLinearHeapBase()) {
- linheap_memory->resize(new_end - GetLinearHeapBase());
- }
- }
return RESULT_SUCCESS;
}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 68e77a4d1..992689186 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -4,6 +4,7 @@
#pragma once
+#include <array>
#include <bitset>
#include <cstddef>
#include <memory>
@@ -12,7 +13,7 @@
#include <boost/container/static_vector.hpp>
#include "common/bit_field.h"
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/vm_manager.h"
@@ -53,9 +54,14 @@ union ProcessFlags {
enum class ProcessStatus { Created, Running, Exited };
class ResourceLimit;
-struct MemoryRegionInfo;
struct CodeSet final : public Object {
+ struct Segment {
+ size_t offset = 0;
+ VAddr addr = 0;
+ u32 size = 0;
+ };
+
static SharedPtr<CodeSet> Create(std::string name);
std::string GetTypeName() const override {
@@ -70,24 +76,38 @@ struct CodeSet final : public Object {
return HANDLE_TYPE;
}
- /// Name of the process
- std::string name;
+ Segment& CodeSegment() {
+ return segments[0];
+ }
- std::shared_ptr<std::vector<u8>> memory;
+ const Segment& CodeSegment() const {
+ return segments[0];
+ }
- struct Segment {
- size_t offset = 0;
- VAddr addr = 0;
- u32 size = 0;
- };
+ Segment& RODataSegment() {
+ return segments[1];
+ }
+
+ const Segment& RODataSegment() const {
+ return segments[1];
+ }
+
+ Segment& DataSegment() {
+ return segments[2];
+ }
+
+ const Segment& DataSegment() const {
+ return segments[2];
+ }
- Segment segments[3];
- Segment& code = segments[0];
- Segment& rodata = segments[1];
- Segment& data = segments[2];
+ std::shared_ptr<std::vector<u8>> memory;
+ std::array<Segment, 3> segments;
VAddr entrypoint;
+ /// Name of the process
+ std::string name;
+
private:
CodeSet();
~CodeSet() override;
@@ -163,12 +183,11 @@ public:
// This makes deallocation and reallocation of holes fast and keeps process memory contiguous
// in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
std::shared_ptr<std::vector<u8>> heap_memory;
- // The left/right bounds of the address space covered by heap_memory.
- VAddr heap_start = 0, heap_end = 0;
- u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0;
-
- MemoryRegionInfo* memory_region = nullptr;
+ // The left/right bounds of the address space covered by heap_memory.
+ VAddr heap_start = 0;
+ VAddr heap_end = 0;
+ u64 heap_used = 0;
/// The Thread Local Storage area is allocated as processes create threads,
/// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
@@ -179,16 +198,9 @@ public:
std::string name;
- VAddr GetLinearHeapAreaAddress() const;
- VAddr GetLinearHeapBase() const;
- VAddr GetLinearHeapLimit() const;
-
ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
ResultCode HeapFree(VAddr target, u32 size);
- ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
- ResultCode LinearFree(VAddr target, u32 size);
-
ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size);
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index cc689a27a..0fa141db3 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -5,7 +5,7 @@
#pragma once
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index e307eec98..94065c736 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -2,8 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
#include <utility>
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/process.h"
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index a3b5fb8ca..1a4ee8f36 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -8,9 +8,11 @@
#include <vector>
#include "common/common_types.h"
#include "common/thread_queue_list.h"
-#include "core/arm/arm_interface.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h"
+class ARM_Interface;
+
namespace Kernel {
class Scheduler final {
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index 0b7061403..7b6211fd8 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -6,7 +6,7 @@
#include "common/assert.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/thread.h"
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index 9ef4ecc35..7f6d6b3eb 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -7,8 +7,9 @@
#include <memory>
#include <string>
#include <tuple>
+#include <vector>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 29b163528..93560152f 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -5,6 +5,8 @@
#include <tuple>
#include <utility>
+#include "common/assert.h"
+#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
@@ -25,7 +27,7 @@ ServerSession::~ServerSession() {
// Decrease the port's connection count.
if (parent->port)
- parent->port->active_sessions--;
+ parent->port->ConnectionClosed();
// TODO(Subv): Wake up all the ClientSession's waiting threads and set
// the SendSyncRequest result to 0xC920181A.
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index 2da807042..2bce54fee 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -6,12 +6,12 @@
#include <memory>
#include <string>
-#include "common/assert.h"
+#include <vector>
+
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
#include "core/hle/result.h"
-#include "core/memory.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index e69b034a7..7a551f5e4 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -4,7 +4,7 @@
#pragma once
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 4bf11c7e2..21ddc2f7d 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -3,10 +3,11 @@
// Refer to the license.txt file included.
#include <utility>
+
+#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/memory.h"
@@ -28,35 +29,17 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
shared_memory->other_permissions = other_permissions;
if (address == 0) {
- // We need to allocate a block from the Linear Heap ourselves.
- // We'll manually allocate some memory from the linear heap in the specified region.
- MemoryRegionInfo* memory_region = GetMemoryRegion(region);
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- ASSERT_MSG(linheap_memory->size() + size <= memory_region->size,
- "Not enough space in region to allocate shared memory!");
-
- shared_memory->backing_block = linheap_memory;
- shared_memory->backing_block_offset = linheap_memory->size();
- // Allocate some memory from the end of the linear heap for this region.
- linheap_memory->insert(linheap_memory->end(), size, 0);
- memory_region->used += size;
-
- shared_memory->linear_heap_phys_address =
- Memory::FCRAM_PADDR + memory_region->base +
- static_cast<PAddr>(shared_memory->backing_block_offset);
-
- // Increase the amount of used linear heap memory for the owner process.
- if (shared_memory->owner_process != nullptr) {
- shared_memory->owner_process->linear_heap_used += size;
- }
+ shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
+ shared_memory->backing_block_offset = 0;
// Refresh the address mappings for the current process.
if (Core::CurrentProcess() != nullptr) {
- Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
+ Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
+ shared_memory->backing_block.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;
+
// The memory is already available and mapped in the owner process.
auto vma = vm_manager.FindVMA(address);
ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
@@ -72,6 +55,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
}
shared_memory->base_address = address;
+
return shared_memory;
}
@@ -122,11 +106,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
VAddr target_address = address;
- if (base_address == 0 && target_address == 0) {
- // Calculate the address at which to map the memory block.
- target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value();
- }
-
// Map the memory block into the target process
auto result = target_process->vm_manager.MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 86f818e90..c50fee615 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -4,9 +4,12 @@
#pragma once
+#include <memory>
#include <string>
+#include <vector>
+
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/result.h"
@@ -108,9 +111,6 @@ public:
SharedPtr<Process> owner_process;
/// Address of shared memory block in the owner process if specified.
VAddr base_address;
- /// Physical address of the shared memory block in the linear heap if no address was specified
- /// during creation.
- PAddr linear_heap_phys_address;
/// Backing memory for this shared memory block.
std::shared_ptr<std::vector<u8>> backing_block;
/// Offset into the backing block for this shared memory.
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 0b439401a..5db2db687 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -5,7 +5,10 @@
#include <algorithm>
#include <cinttypes>
#include <iterator>
+#include <mutex>
+#include <vector>
+#include "common/assert.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/string_util.h"
@@ -17,7 +20,6 @@
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/mutex.h"
-#include "core/hle/kernel/object_address_table.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/shared_memory.h"
@@ -265,7 +267,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
info_sub_id, handle);
- auto& vm_manager = Core::CurrentProcess()->vm_manager;
+ const auto& vm_manager = Core::CurrentProcess()->vm_manager;
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 94735c86e..b9022feae 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -4,8 +4,11 @@
#include <algorithm>
#include <cinttypes>
-#include <list>
#include <vector>
+
+#include <boost/optional.hpp>
+#include <boost/range/algorithm_ext/erase.hpp>
+
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
@@ -17,9 +20,7 @@
#include "core/core_timing_util.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/mutex.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/result.h"
@@ -79,8 +80,8 @@ void Thread::Stop() {
wait_objects.clear();
// Mark the TLS slot in the thread's page as free.
- u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
- u64 tls_slot =
+ const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
+ const u64 tls_slot =
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
}
@@ -250,13 +251,14 @@ void Thread::ResumeFromWait() {
* slot: The index of the first free slot in the indicated page.
* alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full).
*/
-std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& tls_slots) {
+static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot(
+ const std::vector<std::bitset<8>>& tls_slots) {
// Iterate over all the allocated pages, and try to find one where not all slots are used.
- for (unsigned page = 0; page < tls_slots.size(); ++page) {
+ for (std::size_t page = 0; page < tls_slots.size(); ++page) {
const auto& page_tls_slots = tls_slots[page];
if (!page_tls_slots.all()) {
// We found a page with at least one free slot, find which slot it is
- for (unsigned slot = 0; slot < page_tls_slots.size(); ++slot) {
+ for (std::size_t slot = 0; slot < page_tls_slots.size(); ++slot) {
if (!page_tls_slots.test(slot)) {
return std::make_tuple(page, slot, false);
}
@@ -331,42 +333,22 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
// Find the next available TLS index, and mark it as used
auto& tls_slots = owner_process->tls_slots;
- bool needs_allocation = true;
- u32 available_page; // Which allocated page has free space
- u32 available_slot; // Which slot within the page is free
-
- std::tie(available_page, available_slot, needs_allocation) = GetFreeThreadLocalSlot(tls_slots);
+ auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
if (needs_allocation) {
- // There are no already-allocated pages with free slots, lets allocate a new one.
- // TLS pages are allocated from the BASE region in the linear heap.
- MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
- auto& linheap_memory = memory_region->linear_heap_memory;
-
- if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
- LOG_ERROR(Kernel_SVC,
- "Not enough space in region to allocate a new TLS page for thread");
- return ERR_OUT_OF_MEMORY;
- }
-
- size_t offset = linheap_memory->size();
-
- // Allocate some memory from the end of the linear heap for this region.
- linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
- memory_region->used += Memory::PAGE_SIZE;
- owner_process->linear_heap_used += Memory::PAGE_SIZE;
-
tls_slots.emplace_back(0); // The page is completely available at the start
- available_page = static_cast<u32>(tls_slots.size() - 1);
+ available_page = tls_slots.size() - 1;
available_slot = 0; // Use the first slot in the new page
+ // Allocate some memory from the end of the linear heap for this region.
+ const size_t offset = thread->tls_memory->size();
+ thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
+
auto& vm_manager = owner_process->vm_manager;
- vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
+ vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get());
- // Map the page to the current process' address space.
- // TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
- linheap_memory, offset, Memory::PAGE_SIZE,
+ thread->tls_memory, 0, Memory::PAGE_SIZE,
MemoryState::ThreadLocal);
}
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 6218960d2..adc804248 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -4,15 +4,14 @@
#pragma once
+#include <functional>
#include <memory>
#include <string>
-#include <unordered_map>
#include <vector>
-#include <boost/container/flat_map.hpp>
-#include <boost/container/flat_set.hpp>
+
#include "common/common_types.h"
#include "core/arm/arm_interface.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
#include "core/hle/result.h"
@@ -266,6 +265,8 @@ public:
private:
Thread();
~Thread() override;
+
+ std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
};
/**
@@ -289,12 +290,6 @@ Thread* GetCurrentThread();
void WaitCurrentThread_Sleep();
/**
- * Waits the current thread from an ArbitrateAddress call
- * @param wait_address Arbitration address used to resume from wait
- */
-void WaitCurrentThread_ArbitrateAddress(VAddr wait_address);
-
-/**
* Stops the current thread and removes it from the thread_list
*/
void ExitCurrentThread();
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 904a3d0a5..282360745 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -8,7 +8,7 @@
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/kernel/handle_table.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index c63f0ed90..4dddc67e0 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -5,7 +5,7 @@
#pragma once
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 9d26fd781..479cacb62 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
#include <iterator>
#include <utility>
#include "common/assert.h"
@@ -175,9 +176,9 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
- VAddr target_end = target + size;
+ const VAddr target_end = target + size;
- VMAIter end = vma_map.end();
+ const VMAIter end = vma_map.end();
// The comparison against the end of the range must be done using addresses since VMAs can be
// merged during this process, causing invalidation of the iterators.
while (vma != end && vma->second.base < target_end) {
@@ -207,9 +208,9 @@ VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission ne
ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) {
CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
- VAddr target_end = target + size;
+ const VAddr target_end = target + size;
- VMAIter end = vma_map.end();
+ const VMAIter end = vma_map.end();
// The comparison against the end of the range must be done using addresses since VMAs can be
// merged during this process, causing invalidation of the iterators.
while (vma != end && vma->second.base < target_end) {
@@ -258,14 +259,14 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u64 size) {
return ERR_INVALID_ADDRESS;
}
- VirtualMemoryArea& vma = vma_handle->second;
+ const VirtualMemoryArea& vma = vma_handle->second;
if (vma.type != VMAType::Free) {
// Region is already allocated
return ERR_INVALID_ADDRESS_STATE;
}
- u64 start_in_vma = base - vma.base;
- u64 end_in_vma = start_in_vma + size;
+ const VAddr start_in_vma = base - vma.base;
+ const VAddr end_in_vma = start_in_vma + size;
if (end_in_vma > vma.size) {
// Requested allocation doesn't fit inside VMA
@@ -288,17 +289,16 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u64 size) {
ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size);
ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target);
- VAddr target_end = target + size;
+ const VAddr target_end = target + size;
ASSERT(target_end >= target);
ASSERT(target_end <= MAX_ADDRESS);
ASSERT(size > 0);
VMAIter begin_vma = StripIterConstness(FindVMA(target));
- VMAIter i_end = vma_map.lower_bound(target_end);
- for (auto i = begin_vma; i != i_end; ++i) {
- if (i->second.type == VMAType::Free) {
- return ERR_INVALID_ADDRESS_STATE;
- }
+ const VMAIter i_end = vma_map.lower_bound(target_end);
+ if (std::any_of(begin_vma, i_end,
+ [](const auto& entry) { return entry.second.type == VMAType::Free; })) {
+ return ERR_INVALID_ADDRESS_STATE;
}
if (target != begin_vma->second.base) {
@@ -346,7 +346,7 @@ VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u64 offset_in_vma) {
}
VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
- VMAIter next_vma = std::next(iter);
+ const VMAIter next_vma = std::next(iter);
if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) {
iter->second.size += next_vma->second.size;
vma_map.erase(next_vma);
@@ -382,22 +382,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
}
}
-u64 VMManager::GetTotalMemoryUsage() {
+u64 VMManager::GetTotalMemoryUsage() const {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0xF8000000;
}
-u64 VMManager::GetTotalHeapUsage() {
+u64 VMManager::GetTotalHeapUsage() const {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x0;
}
-VAddr VMManager::GetAddressSpaceBaseAddr() {
+VAddr VMManager::GetAddressSpaceBaseAddr() const {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;
}
-u64 VMManager::GetAddressSpaceSize() {
+u64 VMManager::GetAddressSpaceSize() const {
LOG_WARNING(Kernel, "(STUBBED) called");
return MAX_ADDRESS;
}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 38e4ebcd3..98bd04bea 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -190,16 +190,16 @@ public:
void LogLayout() const;
/// Gets the total memory usage, used by svcGetInfo
- u64 GetTotalMemoryUsage();
+ u64 GetTotalMemoryUsage() const;
/// Gets the total heap usage, used by svcGetInfo
- u64 GetTotalHeapUsage();
+ u64 GetTotalHeapUsage() const;
/// Gets the total address space base address, used by svcGetInfo
- VAddr GetAddressSpaceBaseAddr();
+ VAddr GetAddressSpaceBaseAddr() const;
/// Gets the total address space address size, used by svcGetInfo
- u64 GetAddressSpaceSize();
+ u64 GetAddressSpaceSize() const;
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 23af346d0..7681cdee7 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -5,11 +5,8 @@
#include <algorithm>
#include "common/assert.h"
#include "common/logging/log.h"
-#include "core/hle/kernel/errors.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/memory.h"
+#include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h"
-#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h
index 78bfd8c6c..b5fbc647b 100644
--- a/src/core/hle/kernel/wait_object.h
+++ b/src/core/hle/kernel/wait_object.h
@@ -7,7 +7,7 @@
#include <vector>
#include <boost/smart_ptr/intrusive_ptr.hpp>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
namespace Kernel {
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 0b158e015..6d15b46ed 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -10,6 +10,7 @@
#include "core/hle/service/acc/acc_su.h"
#include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h"
+#include "core/settings.h"
namespace Service::Account {
@@ -31,13 +32,14 @@ struct ProfileBase {
};
static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
+// TODO(ogniK): Generate a real user id based on username, md5(username) maybe?
static constexpr u128 DEFAULT_USER_ID{1ull, 0ull};
class IProfile final : public ServiceFramework<IProfile> {
public:
explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
static const FunctionInfo functions[] = {
- {0, nullptr, "Get"},
+ {0, &IProfile::Get, "Get"},
{1, &IProfile::GetBase, "GetBase"},
{10, nullptr, "GetImageSize"},
{11, nullptr, "LoadImage"},
@@ -46,14 +48,36 @@ public:
}
private:
+ void Get(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_ACC, "(STUBBED) called");
+ ProfileBase profile_base{};
+ profile_base.user_id = user_id;
+ if (Settings::values.username.size() > profile_base.username.size()) {
+ std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
+ profile_base.username.begin());
+ } else {
+ std::copy(Settings::values.username.begin(), Settings::values.username.end(),
+ profile_base.username.begin());
+ }
+
+ IPC::ResponseBuilder rb{ctx, 16};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw(profile_base);
+ }
+
void GetBase(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
// TODO(Subv): Retrieve this information from somewhere.
ProfileBase profile_base{};
profile_base.user_id = user_id;
- profile_base.username = {'y', 'u', 'z', 'u'};
-
+ if (Settings::values.username.size() > profile_base.username.size()) {
+ std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
+ profile_base.username.begin());
+ } else {
+ std::copy(Settings::values.username.begin(), Settings::values.username.end(),
+ profile_base.username.begin());
+ }
IPC::ResponseBuilder rb{ctx, 16};
rb.Push(RESULT_SUCCESS);
rb.PushRaw(profile_base);
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97ef07bf9..9404d6b8c 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -11,6 +11,9 @@
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
+#include "core/hle/service/am/idle.h"
+#include "core/hle/service/am/omm.h"
+#include "core/hle/service/am/spsm.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/nvflinger/nvflinger.h"
@@ -649,7 +652,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
// TODO(bunnei): This should be configurable
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US));
+ rb.Push(
+ static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index)));
LOG_DEBUG(Service_AM, "called");
}
@@ -689,6 +693,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
+ std::make_shared<IdleSys>()->InstallAsService(service_manager);
+ std::make_shared<OMM>()->InstallAsService(service_manager);
+ std::make_shared<SPSM>()->InstallAsService(service_manager);
}
IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp
new file mode 100644
index 000000000..af46e9494
--- /dev/null
+++ b/src/core/hle/service/am/idle.cpp
@@ -0,0 +1,24 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/idle.h"
+
+namespace Service::AM {
+
+IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetAutoPowerDownEvent"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h
new file mode 100644
index 000000000..1eb68d2c9
--- /dev/null
+++ b/src/core/hle/service/am/idle.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class IdleSys final : public ServiceFramework<IdleSys> {
+public:
+ explicit IdleSys();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp
new file mode 100644
index 000000000..447fe8669
--- /dev/null
+++ b/src/core/hle/service/am/omm.cpp
@@ -0,0 +1,42 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/omm.h"
+
+namespace Service::AM {
+
+OMM::OMM() : ServiceFramework{"omm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetOperationMode"},
+ {1, nullptr, "GetOperationModeChangeEvent"},
+ {2, nullptr, "EnableAudioVisual"},
+ {3, nullptr, "DisableAudioVisual"},
+ {4, nullptr, "EnterSleepAndWait"},
+ {5, nullptr, "GetCradleStatus"},
+ {6, nullptr, "FadeInDisplay"},
+ {7, nullptr, "FadeOutDisplay"},
+ {8, nullptr, "Unknown1"},
+ {9, nullptr, "Unknown2"},
+ {10, nullptr, "Unknown3"},
+ {11, nullptr, "Unknown4"},
+ {12, nullptr, "Unknown5"},
+ {13, nullptr, "Unknown6"},
+ {14, nullptr, "Unknown7"},
+ {15, nullptr, "Unknown8"},
+ {16, nullptr, "Unknown9"},
+ {17, nullptr, "Unknown10"},
+ {18, nullptr, "Unknown11"},
+ {19, nullptr, "Unknown12"},
+ {20, nullptr, "Unknown13"},
+ {21, nullptr, "Unknown14"},
+ {22, nullptr, "Unknown15"},
+ {23, nullptr, "Unknown16"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h
new file mode 100644
index 000000000..49e5d331c
--- /dev/null
+++ b/src/core/hle/service/am/omm.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class OMM final : public ServiceFramework<OMM> {
+public:
+ explicit OMM();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp
new file mode 100644
index 000000000..a05d433d0
--- /dev/null
+++ b/src/core/hle/service/am/spsm.cpp
@@ -0,0 +1,30 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/spsm.h"
+
+namespace Service::AM {
+
+SPSM::SPSM() : ServiceFramework{"spsm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetState"},
+ {1, nullptr, "SleepSystemAndWaitAwake"},
+ {2, nullptr, "Unknown1"},
+ {3, nullptr, "Unknown2"},
+ {4, nullptr, "GetNotificationMessageEventHandle"},
+ {5, nullptr, "Unknown3"},
+ {6, nullptr, "Unknown4"},
+ {7, nullptr, "Unknown5"},
+ {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"},
+ {9, nullptr, "ChangeHomeButtonLongPressingTime"},
+ {10, nullptr, "Unknown6"},
+ {11, nullptr, "Unknown7"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h
new file mode 100644
index 000000000..57dde62e1
--- /dev/null
+++ b/src/core/hle/service/am/spsm.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class SPSM final : public ServiceFramework<SPSM> {
+public:
+ explicit SPSM();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp
index 7a185c6c8..4109cb7f7 100644
--- a/src/core/hle/service/apm/apm.cpp
+++ b/src/core/hle/service/apm/apm.cpp
@@ -13,6 +13,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module_ = std::make_shared<Module>();
std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager);
std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager);
+ std::make_shared<APM_Sys>()->InstallAsService(service_manager);
}
} // namespace Service::APM
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp
index ce943d829..4cd8132f5 100644
--- a/src/core/hle/service/apm/interface.cpp
+++ b/src/core/hle/service/apm/interface.cpp
@@ -74,6 +74,31 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISession>();
+
+ LOG_DEBUG(Service_APM, "called");
+}
+
+APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestPerformanceMode"},
+ {1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"},
+ {2, nullptr, "GetThrottlingState"},
+ {3, nullptr, "GetLastThrottlingState"},
+ {4, nullptr, "ClearLastThrottlingState"},
+ {5, nullptr, "LoadAndApplySettings"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ISession>();
+
+ LOG_DEBUG(Service_APM, "called");
}
} // namespace Service::APM
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h
index fa68c7d93..d14264ad7 100644
--- a/src/core/hle/service/apm/interface.h
+++ b/src/core/hle/service/apm/interface.h
@@ -19,4 +19,12 @@ private:
std::shared_ptr<Module> apm;
};
+class APM_Sys final : public ServiceFramework<APM_Sys> {
+public:
+ explicit APM_Sys();
+
+private:
+ void GetPerformanceEvent(Kernel::HLERequestContext& ctx);
+};
+
} // namespace Service::APM
diff --git a/src/core/hle/service/arp/arp.cpp b/src/core/hle/service/arp/arp.cpp
new file mode 100644
index 000000000..358ef2576
--- /dev/null
+++ b/src/core/hle/service/arp/arp.cpp
@@ -0,0 +1,75 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/arp/arp.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::ARP {
+
+class ARP_R final : public ServiceFramework<ARP_R> {
+public:
+ explicit ARP_R() : ServiceFramework{"arp:r"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetApplicationLaunchProperty"},
+ {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"},
+ {2, nullptr, "GetApplicationControlProperty"},
+ {3, nullptr, "GetApplicationControlPropertyWithApplicationId"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IRegistrar final : public ServiceFramework<IRegistrar> {
+public:
+ explicit IRegistrar() : ServiceFramework{"IRegistrar"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Issue"},
+ {1, nullptr, "SetApplicationLaunchProperty"},
+ {2, nullptr, "SetApplicationControlProperty"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class ARP_W final : public ServiceFramework<ARP_W> {
+public:
+ explicit ARP_W() : ServiceFramework{"arp:w"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
+ {1, nullptr, "DeleteProperties"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void AcquireRegistrar(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IRegistrar>();
+
+ LOG_DEBUG(Service_ARP, "called");
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<ARP_R>()->InstallAsService(sm);
+ std::make_shared<ARP_W>()->InstallAsService(sm);
+}
+
+} // namespace Service::ARP
diff --git a/src/core/hle/service/arp/arp.h b/src/core/hle/service/arp/arp.h
new file mode 100644
index 000000000..9d100187c
--- /dev/null
+++ b/src/core/hle/service/arp/arp.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::ARP {
+
+/// Registers all ARP services with the specified service manager.
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::ARP
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
new file mode 100644
index 000000000..37c3fdcac
--- /dev/null
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -0,0 +1,45 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/audctl.h"
+
+namespace Service::Audio {
+
+AudCtl::AudCtl() : ServiceFramework{"audctl"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetTargetVolume"},
+ {1, nullptr, "SetTargetVolume"},
+ {2, nullptr, "GetTargetVolumeMin"},
+ {3, nullptr, "GetTargetVolumeMax"},
+ {4, nullptr, "IsTargetMute"},
+ {5, nullptr, "SetTargetMute"},
+ {6, nullptr, "IsTargetConnected"},
+ {7, nullptr, "SetDefaultTarget"},
+ {8, nullptr, "GetDefaultTarget"},
+ {9, nullptr, "GetAudioOutputMode"},
+ {10, nullptr, "SetAudioOutputMode"},
+ {11, nullptr, "SetForceMutePolicy"},
+ {12, nullptr, "GetForceMutePolicy"},
+ {13, nullptr, "GetOutputModeSetting"},
+ {14, nullptr, "SetOutputModeSetting"},
+ {15, nullptr, "SetOutputTarget"},
+ {16, nullptr, "SetInputTargetForceEnabled"},
+ {17, nullptr, "SetHeadphoneOutputLevelMode"},
+ {18, nullptr, "GetHeadphoneOutputLevelMode"},
+ {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
+ {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
+ {21, nullptr, "GetAudioOutputTargetForPlayReport"},
+ {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
+ {23, nullptr, "SetSystemOutputMasterVolume"},
+ {24, nullptr, "GetSystemOutputMasterVolume"},
+ {25, nullptr, "GetAudioVolumeDataForPlayReport"},
+ {26, nullptr, "UpdateHeadphoneSettings"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h
new file mode 100644
index 000000000..ed837bdf2
--- /dev/null
+++ b/src/core/hle/service/audio/audctl.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudCtl final : public ServiceFramework<AudCtl> {
+public:
+ explicit AudCtl();
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp
new file mode 100644
index 000000000..b08c21a20
--- /dev/null
+++ b/src/core/hle/service/audio/auddbg.cpp
@@ -0,0 +1,20 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/auddbg.h"
+
+namespace Service::Audio {
+
+AudDbg::AudDbg(const char* name) : ServiceFramework{name} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendForDebug"},
+ {1, nullptr, "RequestResumeForDebug"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h
new file mode 100644
index 000000000..a2f540b75
--- /dev/null
+++ b/src/core/hle/service/audio/auddbg.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudDbg final : public ServiceFramework<AudDbg> {
+public:
+ explicit AudDbg(const char* name);
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp
new file mode 100644
index 000000000..a70d5bca4
--- /dev/null
+++ b/src/core/hle/service/audio/audin_a.cpp
@@ -0,0 +1,22 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/audin_a.h"
+
+namespace Service::Audio {
+
+AudInA::AudInA() : ServiceFramework{"audin:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendAudioIns"},
+ {1, nullptr, "RequestResumeAudioIns"},
+ {2, nullptr, "GetAudioInsProcessMasterVolume"},
+ {3, nullptr, "SetAudioInsProcessMasterVolume"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h
new file mode 100644
index 000000000..e4c75510f
--- /dev/null
+++ b/src/core/hle/service/audio/audin_a.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudInA final : public ServiceFramework<AudInA> {
+public:
+ explicit AudInA();
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index d231e91e1..6b5e15633 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -2,10 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/hle/service/audio/audctl.h"
+#include "core/hle/service/audio/auddbg.h"
+#include "core/hle/service/audio/audin_a.h"
#include "core/hle/service/audio/audin_u.h"
#include "core/hle/service/audio/audio.h"
+#include "core/hle/service/audio/audout_a.h"
#include "core/hle/service/audio/audout_u.h"
+#include "core/hle/service/audio/audrec_a.h"
#include "core/hle/service/audio/audrec_u.h"
+#include "core/hle/service/audio/audren_a.h"
#include "core/hle/service/audio/audren_u.h"
#include "core/hle/service/audio/codecctl.h"
#include "core/hle/service/audio/hwopus.h"
@@ -13,12 +19,22 @@
namespace Service::Audio {
void InstallInterfaces(SM::ServiceManager& service_manager) {
+ std::make_shared<AudCtl>()->InstallAsService(service_manager);
+ std::make_shared<AudOutA>()->InstallAsService(service_manager);
std::make_shared<AudOutU>()->InstallAsService(service_manager);
+ std::make_shared<AudInA>()->InstallAsService(service_manager);
std::make_shared<AudInU>()->InstallAsService(service_manager);
+ std::make_shared<AudRecA>()->InstallAsService(service_manager);
std::make_shared<AudRecU>()->InstallAsService(service_manager);
+ std::make_shared<AudRenA>()->InstallAsService(service_manager);
std::make_shared<AudRenU>()->InstallAsService(service_manager);
std::make_shared<CodecCtl>()->InstallAsService(service_manager);
std::make_shared<HwOpus>()->InstallAsService(service_manager);
+
+ std::make_shared<AudDbg>("audin:d")->InstallAsService(service_manager);
+ std::make_shared<AudDbg>("audout:d")->InstallAsService(service_manager);
+ std::make_shared<AudDbg>("audrec:d")->InstallAsService(service_manager);
+ std::make_shared<AudDbg>("audren:d")->InstallAsService(service_manager);
}
} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp
new file mode 100644
index 000000000..bf8d40157
--- /dev/null
+++ b/src/core/hle/service/audio/audout_a.cpp
@@ -0,0 +1,24 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/audout_a.h"
+
+namespace Service::Audio {
+
+AudOutA::AudOutA() : ServiceFramework{"audout:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendAudioOuts"},
+ {1, nullptr, "RequestResumeAudioOuts"},
+ {2, nullptr, "GetAudioOutsProcessMasterVolume"},
+ {3, nullptr, "SetAudioOutsProcessMasterVolume"},
+ {4, nullptr, "GetAudioOutsProcessRecordVolume"},
+ {5, nullptr, "SetAudioOutsProcessRecordVolume"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h
new file mode 100644
index 000000000..91a069152
--- /dev/null
+++ b/src/core/hle/service/audio/audout_a.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudOutA final : public ServiceFramework<AudOutA> {
+public:
+ explicit AudOutA();
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 1dcd84d98..108a7c6eb 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -4,9 +4,10 @@
#include <array>
#include <vector>
+
+#include "audio_core/codec.h"
#include "common/logging/log.h"
-#include "core/core_timing.h"
-#include "core/core_timing_util.h"
+#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/hle_ipc.h"
@@ -14,17 +15,21 @@
namespace Service::Audio {
-/// Switch sample rate frequency
-constexpr u32 sample_rate{48000};
-/// TODO(st4rk): dynamic number of channels, as I think Switch has support
-/// to more audio channels (probably when Docked I guess)
-constexpr u32 audio_channels{2};
-/// TODO(st4rk): find a proper value for the audio_ticks
-constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 500)};
+namespace ErrCodes {
+enum {
+ ErrorUnknown = 2,
+ BufferCountExceeded = 8,
+};
+}
+
+constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}};
+constexpr int DefaultSampleRate{48000};
class IAudioOut final : public ServiceFramework<IAudioOut> {
public:
- IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) {
+ IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core)
+ : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) {
+
static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
{1, &IAudioOut::StartAudioOut, "StartAudioOut"},
@@ -32,66 +37,65 @@ public:
{3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
- {6, nullptr, "ContainsAudioOutBuffer"},
+ {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
{7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
- {9, nullptr, "GetAudioOutBufferCount"},
+ {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
{10, nullptr, "GetAudioOutPlayedSampleCount"},
{11, nullptr, "FlushAudioOutBuffers"},
};
RegisterHandlers(functions);
// This is the event handle used to check if the audio buffer was released
- buffer_event =
- Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent");
-
- // Register event callback to update the Audio Buffer
- audio_event = CoreTiming::RegisterEvent(
- "IAudioOut::UpdateAudioBuffersCallback", [this](u64 userdata, int cycles_late) {
- UpdateAudioBuffersCallback();
- CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event);
- });
-
- // Start the audio event
- CoreTiming::ScheduleEvent(audio_ticks, audio_event);
- }
+ buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
- ~IAudioOut() {
- CoreTiming::UnscheduleEvent(audio_event, 0);
+ stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
+ "IAudioOut", [=]() { buffer_event->Signal(); });
}
private:
+ struct AudioBuffer {
+ u64_le next;
+ u64_le buffer;
+ u64_le buffer_capacity;
+ u64_le buffer_size;
+ u64_le offset;
+ };
+ static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size");
+
void GetAudioOutState(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u32>(audio_out_state));
+ rb.Push(static_cast<u32>(stream->IsPlaying() ? AudioState::Started : AudioState::Stopped));
}
void StartAudioOut(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "called");
- // Start audio
- audio_out_state = AudioState::Started;
+ if (stream->IsPlaying()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::ErrorUnknown));
+ return;
+ }
+
+ audio_core.StartStream(stream);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void StopAudioOut(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
-
- // Stop audio
- audio_out_state = AudioState::Stopped;
+ LOG_DEBUG(Service_Audio, "called");
- queue_keys.clear();
+ audio_core.StopStream(stream);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
@@ -99,101 +103,107 @@ private:
}
void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "(STUBBED) called {}", ctx.Description());
IPC::RequestParser rp{ctx};
- const u64 key{rp.Pop<u64>()};
- queue_keys.insert(queue_keys.begin(), key);
+ const auto& input_buffer{ctx.ReadBuffer()};
+ ASSERT_MSG(input_buffer.size() == sizeof(AudioBuffer),
+ "AudioBuffer input is an invalid size!");
+ AudioBuffer audio_buffer{};
+ std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer));
+ const u64 tag{rp.Pop<u64>()};
+
+ std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16));
+ Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size);
+
+ if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded));
+ }
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
-
- // TODO(st4rk): This is how libtransistor currently implements the
- // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address
- // is used to know which buffer should be filled with data and send again to the service
- // through AppendAudioOutBuffer. Check if this is the proper way to do it.
- u64 key{0};
-
- if (queue_keys.size()) {
- key = queue_keys.back();
- queue_keys.pop_back();
- }
+ LOG_DEBUG(Service_Audio, "called {}", ctx.Description());
+ IPC::RequestParser rp{ctx};
+ const u64 max_count{ctx.GetWriteBufferSize() / sizeof(u64)};
+ const auto released_buffers{audio_core.GetTagsAndReleaseBuffers(stream, max_count)};
- ctx.WriteBuffer(&key, sizeof(u64));
+ std::vector<u64> tags{released_buffers};
+ tags.resize(max_count);
+ ctx.WriteBuffer(tags);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- // TODO(st4rk): This might be the total of released buffers, needs to be verified on
- // hardware
- rb.Push<u32>(static_cast<u32>(queue_keys.size()));
+ rb.Push<u32>(static_cast<u32>(released_buffers.size()));
}
- void UpdateAudioBuffersCallback() {
- if (audio_out_state != AudioState::Started) {
- return;
- }
-
- if (queue_keys.empty()) {
- return;
- }
+ void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+ IPC::RequestParser rp{ctx};
+ const u64 tag{rp.Pop<u64>()};
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(stream->ContainsBuffer(tag));
+ }
- buffer_event->Signal();
+ void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u32>(stream->GetQueueSize()));
}
- enum class AudioState : u32 {
- Started,
- Stopped,
- };
+ AudioCore::AudioOut& audio_core;
+ AudioCore::StreamPtr stream;
- /// This is used to trigger the audio event callback that is going to read the samples from the
- /// audio_buffer list and enqueue the samples using the sink (audio_core).
- CoreTiming::EventType* audio_event;
+ AudoutParams audio_params{};
/// This is the evend handle used to check if the audio buffer was released
Kernel::SharedPtr<Kernel::Event> buffer_event;
-
- /// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor
- /// uses the key as an address in the App, so we need to return when the
- /// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because
- /// libtransistor uses the key returned as an pointer.
- std::vector<u64> queue_keys;
-
- AudioState audio_out_state;
};
void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "called");
IPC::RequestParser rp{ctx};
- constexpr std::array<char, 15> audio_interface{{"AudioInterface"}};
- ctx.WriteBuffer(audio_interface);
+ ctx.WriteBuffer(DefaultDevice);
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
rb.Push(RESULT_SUCCESS);
- // TODO(st4rk): We're currently returning only one audio interface (stringlist size). However,
- // it's highly possible to have more than one interface (despite that libtransistor requires
- // only one).
- rb.Push<u32>(1);
+ rb.Push<u32>(1); // Amount of audio devices
}
void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "called");
- if (!audio_out_interface) {
- audio_out_interface = std::make_shared<IAudioOut>();
+ ctx.WriteBuffer(DefaultDevice);
+ IPC::RequestParser rp{ctx};
+ auto params{rp.PopRaw<AudoutParams>()};
+ if (params.channel_count <= 2) {
+ // Mono does not exist for audout
+ params.channel_count = 2;
+ } else {
+ params.channel_count = 6;
}
+ if (!params.sample_rate) {
+ params.sample_rate = DefaultSampleRate;
+ }
+
+ // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
+ // will likely need to be updated as well.
+ ASSERT_MSG(!audio_out_interface, "Unimplemented");
+ audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core);
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(sample_rate);
- rb.Push<u32>(audio_channels);
- rb.Push<u32>(static_cast<u32>(PcmFormat::Int16));
- rb.Push<u32>(0); // This field is unknown
+ rb.Push<u32>(DefaultSampleRate);
+ rb.Push<u32>(params.channel_count);
+ rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16));
+ rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);
}
@@ -203,6 +213,7 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") {
{2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"},
{3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}};
RegisterHandlers(functions);
+ audio_core = std::make_unique<AudioCore::AudioOut>();
}
} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h
index 847d86aa6..fd491f65d 100644
--- a/src/core/hle/service/audio/audout_u.h
+++ b/src/core/hle/service/audio/audout_u.h
@@ -4,6 +4,7 @@
#pragma once
+#include "audio_core/audio_out.h"
#include "core/hle/service/service.h"
namespace Kernel {
@@ -12,6 +13,18 @@ class HLERequestContext;
namespace Service::Audio {
+struct AudoutParams {
+ s32_le sample_rate;
+ u16_le channel_count;
+ INSERT_PADDING_BYTES(2);
+};
+static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size");
+
+enum class AudioState : u32 {
+ Started,
+ Stopped,
+};
+
class IAudioOut;
class AudOutU final : public ServiceFramework<AudOutU> {
@@ -21,19 +34,10 @@ public:
private:
std::shared_ptr<IAudioOut> audio_out_interface;
+ std::unique_ptr<AudioCore::AudioOut> audio_core;
void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
void OpenAudioOutImpl(Kernel::HLERequestContext& ctx);
-
- enum class PcmFormat : u32 {
- Invalid = 0,
- Int8 = 1,
- Int16 = 2,
- Int24 = 3,
- Int32 = 4,
- PcmFloat = 5,
- Adpcm = 6,
- };
};
} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp
new file mode 100644
index 000000000..016eabf53
--- /dev/null
+++ b/src/core/hle/service/audio/audrec_a.cpp
@@ -0,0 +1,20 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/audrec_a.h"
+
+namespace Service::Audio {
+
+AudRecA::AudRecA() : ServiceFramework{"audrec:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendFinalOutputRecorders"},
+ {1, nullptr, "RequestResumeFinalOutputRecorders"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/audrec_a.h
new file mode 100644
index 000000000..9685047f2
--- /dev/null
+++ b/src/core/hle/service/audio/audrec_a.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudRecA final : public ServiceFramework<AudRecA> {
+public:
+ explicit AudRecA();
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp
new file mode 100644
index 000000000..616ff3dc4
--- /dev/null
+++ b/src/core/hle/service/audio/audren_a.cpp
@@ -0,0 +1,26 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/audio/audren_a.h"
+
+namespace Service::Audio {
+
+AudRenA::AudRenA() : ServiceFramework{"audren:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendAudioRenderers"},
+ {1, nullptr, "RequestResumeAudioRenderers"},
+ {2, nullptr, "GetAudioRenderersProcessMasterVolume"},
+ {3, nullptr, "SetAudioRenderersProcessMasterVolume"},
+ {4, nullptr, "RegisterAppletResourceUserId"},
+ {5, nullptr, "UnregisterAppletResourceUserId"},
+ {6, nullptr, "GetAudioRenderersProcessRecordVolume"},
+ {7, nullptr, "SetAudioRenderersProcessRecordVolume"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h
new file mode 100644
index 000000000..5ecf2e184
--- /dev/null
+++ b/src/core/hle/service/audio/audren_a.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+class AudRenA final : public ServiceFramework<AudRenA> {
+public:
+ explicit AudRenA();
+};
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 6aed9e2fa..f99304de5 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -15,13 +15,10 @@
namespace Service::Audio {
-/// TODO(bunnei): Find a proper value for the audio_ticks
-constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)};
-
class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
public:
- explicit IAudioRenderer(AudioRendererParameter audren_params)
- : ServiceFramework("IAudioRenderer"), worker_params(audren_params) {
+ explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params)
+ : ServiceFramework("IAudioRenderer") {
static const FunctionInfo functions[] = {
{0, nullptr, "GetAudioRendererSampleRate"},
{1, nullptr, "GetAudioRendererSampleCount"},
@@ -39,21 +36,8 @@ public:
RegisterHandlers(functions);
system_event =
- Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioRenderer:SystemEvent");
-
- // Register event callback to update the Audio Buffer
- audio_event = CoreTiming::RegisterEvent(
- "IAudioRenderer::UpdateAudioCallback", [this](u64 userdata, int cycles_late) {
- UpdateAudioCallback();
- CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event);
- });
-
- // Start the audio event
- CoreTiming::ScheduleEvent(audio_ticks, audio_event);
- voice_status_list.resize(worker_params.voice_count);
- }
- ~IAudioRenderer() {
- CoreTiming::UnscheduleEvent(audio_event, 0);
+ Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent");
+ renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event);
}
private:
@@ -62,60 +46,9 @@ private:
}
void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) {
- UpdateDataHeader config{};
- auto buf = ctx.ReadBuffer();
- std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader));
- u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
-
- std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
- std::memcpy(mem_pool_info.data(),
- buf.data() + sizeof(UpdateDataHeader) + config.behavior_size,
- memory_pool_count * sizeof(MemoryPoolInfo));
-
- std::vector<VoiceInfo> voice_info(worker_params.voice_count);
- std::memcpy(voice_info.data(),
- buf.data() + sizeof(UpdateDataHeader) + config.behavior_size +
- config.memory_pools_size + config.voice_resource_size,
- worker_params.voice_count * sizeof(VoiceInfo));
-
- UpdateDataHeader response_data{worker_params};
-
- ASSERT(ctx.GetWriteBufferSize() == response_data.total_size);
-
- std::vector<u8> output(response_data.total_size);
- std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader));
- std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
- for (unsigned i = 0; i < memory_pool.size(); i++) {
- if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach)
- memory_pool[i].state = MemoryPoolStates::Attached;
- else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach)
- memory_pool[i].state = MemoryPoolStates::Detached;
- }
- std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(),
- response_data.memory_pools_size);
-
- for (unsigned i = 0; i < voice_info.size(); i++) {
- if (voice_info[i].is_new) {
- voice_status_list[i].played_sample_count = 0;
- voice_status_list[i].wave_buffer_consumed = 0;
- } else if (voice_info[i].play_state == (u8)PlayStates::Started) {
- for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) {
- voice_status_list[i].played_sample_count +=
- (voice_info[i].wave_buffer[buff_idx].end_sample_offset -
- voice_info[i].wave_buffer[buff_idx].start_sample_offset) /
- 2;
- voice_status_list[i].wave_buffer_consumed++;
- }
- }
- }
- std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size,
- voice_status_list.data(), response_data.voices_size);
-
- ctx.WriteBuffer(output);
-
+ ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer()));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
-
LOG_WARNING(Service_Audio, "(STUBBED) called");
}
@@ -136,8 +69,6 @@ private:
}
void QuerySystemEvent(Kernel::HLERequestContext& ctx) {
- // system_event->Signal();
-
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(system_event);
@@ -145,131 +76,8 @@ private:
LOG_WARNING(Service_Audio, "(STUBBED) called");
}
- enum class MemoryPoolStates : u32 { // Should be LE
- Invalid = 0x0,
- Unknown = 0x1,
- RequestDetach = 0x2,
- Detached = 0x3,
- RequestAttach = 0x4,
- Attached = 0x5,
- Released = 0x6,
- };
-
- enum class PlayStates : u8 {
- Started = 0,
- Stopped = 1,
- };
-
- struct MemoryPoolEntry {
- MemoryPoolStates state;
- u32_le unknown_4;
- u32_le unknown_8;
- u32_le unknown_c;
- };
- static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
-
- struct MemoryPoolInfo {
- u64_le pool_address;
- u64_le pool_size;
- MemoryPoolStates pool_state;
- INSERT_PADDING_WORDS(3); // Unknown
- };
- static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
-
- struct UpdateDataHeader {
- UpdateDataHeader() {}
-
- explicit UpdateDataHeader(const AudioRendererParameter& config) {
- revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
- behavior_size = 0xb0;
- memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
- voices_size = config.voice_count * 0x10;
- voice_resource_size = 0x0;
- effects_size = config.effect_count * 0x10;
- mixes_size = 0x0;
- sinks_size = config.sink_count * 0x20;
- performance_manager_size = 0x10;
- total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size +
- voices_size + effects_size + sinks_size + performance_manager_size;
- }
-
- u32_le revision;
- u32_le behavior_size;
- u32_le memory_pools_size;
- u32_le voices_size;
- u32_le voice_resource_size;
- u32_le effects_size;
- u32_le mixes_size;
- u32_le sinks_size;
- u32_le performance_manager_size;
- INSERT_PADDING_WORDS(6);
- u32_le total_size;
- };
- static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
-
- struct BiquadFilter {
- u8 enable;
- INSERT_PADDING_BYTES(1);
- s16_le numerator[3];
- s16_le denominator[2];
- };
- static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
-
- struct WaveBuffer {
- u64_le buffer_addr;
- u64_le buffer_sz;
- s32_le start_sample_offset;
- s32_le end_sample_offset;
- u8 loop;
- u8 end_of_stream;
- u8 sent_to_server;
- INSERT_PADDING_BYTES(5);
- u64 context_addr;
- u64 context_sz;
- INSERT_PADDING_BYTES(8);
- };
- static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
-
- struct VoiceInfo {
- u32_le id;
- u32_le node_id;
- u8 is_new;
- u8 is_in_use;
- u8 play_state;
- u8 sample_format;
- u32_le sample_rate;
- u32_le priority;
- u32_le sorting_order;
- u32_le channel_count;
- float_le pitch;
- float_le volume;
- BiquadFilter biquad_filter[2];
- u32_le wave_buffer_count;
- u16_le wave_buffer_head;
- INSERT_PADDING_BYTES(6);
- u64_le additional_params_addr;
- u64_le additional_params_sz;
- u32_le mix_id;
- u32_le splitter_info_id;
- WaveBuffer wave_buffer[4];
- u32_le voice_channel_resource_ids[6];
- INSERT_PADDING_BYTES(24);
- };
- static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
-
- struct VoiceOutStatus {
- u64_le played_sample_count;
- u32_le wave_buffer_consumed;
- INSERT_PADDING_WORDS(1);
- };
- static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
-
- /// This is used to trigger the audio event callback.
- CoreTiming::EventType* audio_event;
-
Kernel::SharedPtr<Kernel::Event> system_event;
- AudioRendererParameter worker_params;
- std::vector<VoiceOutStatus> voice_status_list;
+ std::unique_ptr<AudioCore::AudioRenderer> renderer;
};
class IAudioDevice final : public ServiceFramework<IAudioDevice> {
@@ -368,7 +176,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {
void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto params = rp.PopRaw<AudioRendererParameter>();
+ auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -379,7 +187,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto params = rp.PopRaw<AudioRendererParameter>();
+ auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40);
buffer_sz += params.unknown_c * 1024;
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index b9b81db4f..14907f8ae 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -4,6 +4,7 @@
#pragma once
+#include "audio_core/audio_renderer.h"
#include "core/hle/service/service.h"
namespace Kernel {
@@ -12,24 +13,6 @@ class HLERequestContext;
namespace Service::Audio {
-struct AudioRendererParameter {
- u32_le sample_rate;
- u32_le sample_count;
- u32_le unknown_8;
- u32_le unknown_c;
- u32_le voice_count;
- u32_le sink_count;
- u32_le effect_count;
- u32_le unknown_1c;
- u8 unknown_20;
- INSERT_PADDING_BYTES(3);
- u32_le splitter_count;
- u32_le unknown_2c;
- INSERT_PADDING_WORDS(1);
- u32_le revision;
-};
-static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
-
class AudRenU final : public ServiceFramework<AudRenU> {
public:
explicit AudRenU();
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 844df382c..371cd4997 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstring>
+#include <opus.h>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
@@ -9,19 +11,142 @@
namespace Service::Audio {
+struct OpusDeleter {
+ void operator()(void* ptr) const {
+ operator delete(ptr);
+ }
+};
+
+class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
+public:
+ IHardwareOpusDecoderManager(std::unique_ptr<OpusDecoder, OpusDeleter> decoder, u32 sample_rate,
+ u32 channel_count)
+ : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)),
+ sample_rate(sample_rate), channel_count(channel_count) {
+ static const FunctionInfo functions[] = {
+ {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
+ {1, nullptr, "SetContext"},
+ {2, nullptr, "DecodeInterleavedForMultiStream"},
+ {3, nullptr, "SetContextForMultiStream"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "Unknown7"},
+ };
+ RegisterHandlers(functions);
+ }
+
+private:
+ void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
+ u32 consumed = 0;
+ u32 sample_count = 0;
+ std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
+ if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ // TODO(ogniK): Use correct error code
+ rb.Push(ResultCode(-1));
+ return;
+ }
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u32>(consumed);
+ rb.Push<u32>(sample_count);
+ ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
+ }
+
+ bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input,
+ std::vector<opus_int16>& output) {
+ size_t raw_output_sz = output.size() * sizeof(opus_int16);
+ if (sizeof(OpusHeader) > input.size())
+ return false;
+ OpusHeader hdr{};
+ std::memcpy(&hdr, input.data(), sizeof(OpusHeader));
+ if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) {
+ return false;
+ }
+ auto frame = input.data() + sizeof(OpusHeader);
+ auto decoded_sample_count = opus_packet_get_nb_samples(
+ frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)),
+ static_cast<opus_int32>(sample_rate));
+ if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz)
+ return false;
+ auto out_sample_count =
+ opus_decode(decoder.get(), frame, hdr.sz, output.data(),
+ (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)), 0);
+ if (out_sample_count < 0)
+ return false;
+ sample_count = out_sample_count;
+ consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz);
+ return true;
+ }
+
+ struct OpusHeader {
+ u32_be sz; // Needs to be BE for some odd reason
+ INSERT_PADDING_WORDS(1);
+ };
+ static_assert(sizeof(OpusHeader) == 0x8, "OpusHeader is an invalid size");
+
+ std::unique_ptr<OpusDecoder, OpusDeleter> decoder;
+ u32 sample_rate;
+ u32 channel_count;
+};
+
+static size_t WorkerBufferSize(u32 channel_count) {
+ ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
+ return opus_decoder_get_size(static_cast<int>(channel_count));
+}
+
void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ auto sample_rate = rp.Pop<u32>();
+ auto channel_count = rp.Pop<u32>();
+ ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
+ sample_rate == 12000 || sample_rate == 8000,
+ "Invalid sample rate");
+ ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
+ u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count));
+ LOG_DEBUG(Audio, "called worker_buffer_sz={}", worker_buffer_sz);
+
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(0x4000);
+ rb.Push<u32>(worker_buffer_sz);
+}
+
+void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ auto sample_rate = rp.Pop<u32>();
+ auto channel_count = rp.Pop<u32>();
+ auto buffer_sz = rp.Pop<u32>();
+ LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate,
+ channel_count, buffer_sz);
+ ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
+ sample_rate == 12000 || sample_rate == 8000,
+ "Invalid sample rate");
+ ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
+
+ size_t worker_sz = WorkerBufferSize(channel_count);
+ ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large");
+ std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
+ static_cast<OpusDecoder*>(operator new(worker_sz))};
+ if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ // TODO(ogniK): Use correct error code
+ rb.Push(ResultCode(-1));
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IHardwareOpusDecoderManager>(std::move(decoder), sample_rate,
+ channel_count);
}
HwOpus::HwOpus() : ServiceFramework("hwopus") {
static const FunctionInfo functions[] = {
- {0, nullptr, "Initialize"},
+ {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"},
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
- {2, nullptr, "InitializeMultiStream"},
- {3, nullptr, "GetWorkBufferSizeMultiStream"},
+ {2, nullptr, "OpenOpusDecoderForMultiStream"},
+ {3, nullptr, "GetWorkBufferSizeForMultiStream"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h
index 090b8c825..5258d59f3 100644
--- a/src/core/hle/service/audio/hwopus.h
+++ b/src/core/hle/service/audio/hwopus.h
@@ -14,6 +14,7 @@ public:
~HwOpus() = default;
private:
+ void OpenOpusDecoder(Kernel::HLERequestContext& ctx);
void GetWorkBufferSize(Kernel::HLERequestContext& ctx);
};
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
new file mode 100644
index 000000000..1c1ecdb60
--- /dev/null
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -0,0 +1,57 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/bpc/bpc.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::BPC {
+
+class BPC final : public ServiceFramework<BPC> {
+public:
+ explicit BPC() : ServiceFramework{"bpc"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ShutdownSystem"},
+ {1, nullptr, "RebootSystem"},
+ {2, nullptr, "GetWakeupReason"},
+ {3, nullptr, "GetShutdownReason"},
+ {4, nullptr, "GetAcOk"},
+ {5, nullptr, "GetBoardPowerControlEvent"},
+ {6, nullptr, "GetSleepButtonState"},
+ {7, nullptr, "GetPowerEvent"},
+ {8, nullptr, "Unknown1"},
+ {9, nullptr, "Unknown2"},
+ {10, nullptr, "Unknown3"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class BPC_R final : public ServiceFramework<BPC_R> {
+public:
+ explicit BPC_R() : ServiceFramework{"bpc:r"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetExternalRtcValue"},
+ {1, nullptr, "SetExternalRtcValue"},
+ {2, nullptr, "ReadExternalRtcResetFlag"},
+ {3, nullptr, "ClearExternalRtcResetFlag"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<BPC>()->InstallAsService(sm);
+ std::make_shared<BPC_R>()->InstallAsService(sm);
+}
+
+} // namespace Service::BPC
diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h
new file mode 100644
index 000000000..eaa37be8d
--- /dev/null
+++ b/src/core/hle/service/bpc/bpc.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::BPC {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::BPC
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
new file mode 100644
index 000000000..d0a15cc4c
--- /dev/null
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -0,0 +1,72 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/btdrv/btdrv.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::BtDrv {
+
+class BtDrv final : public ServiceFramework<BtDrv> {
+public:
+ explicit BtDrv() : ServiceFramework{"btdrv"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown"},
+ {1, nullptr, "Init"},
+ {2, nullptr, "Enable"},
+ {3, nullptr, "Disable"},
+ {4, nullptr, "CleanupAndShutdown"},
+ {5, nullptr, "GetAdapterProperties"},
+ {6, nullptr, "GetAdapterProperty"},
+ {7, nullptr, "SetAdapterProperty"},
+ {8, nullptr, "StartDiscovery"},
+ {9, nullptr, "CancelDiscovery"},
+ {10, nullptr, "CreateBond"},
+ {11, nullptr, "RemoveBond"},
+ {12, nullptr, "CancelBond"},
+ {13, nullptr, "PinReply"},
+ {14, nullptr, "SspReply"},
+ {15, nullptr, "Unknown2"},
+ {16, nullptr, "InitInterfaces"},
+ {17, nullptr, "HidHostInterface_Connect"},
+ {18, nullptr, "HidHostInterface_Disconnect"},
+ {19, nullptr, "HidHostInterface_SendData"},
+ {20, nullptr, "HidHostInterface_SendData2"},
+ {21, nullptr, "HidHostInterface_SetReport"},
+ {22, nullptr, "HidHostInterface_GetReport"},
+ {23, nullptr, "HidHostInterface_WakeController"},
+ {24, nullptr, "HidHostInterface_AddPairedDevice"},
+ {25, nullptr, "HidHostInterface_GetPairedDevice"},
+ {26, nullptr, "HidHostInterface_CleanupAndShutdown"},
+ {27, nullptr, "Unknown3"},
+ {28, nullptr, "ExtInterface_SetTSI"},
+ {29, nullptr, "ExtInterface_SetBurstMode"},
+ {30, nullptr, "ExtInterface_SetZeroRetran"},
+ {31, nullptr, "ExtInterface_SetMcMode"},
+ {32, nullptr, "ExtInterface_StartLlrMode"},
+ {33, nullptr, "ExtInterface_ExitLlrMode"},
+ {34, nullptr, "ExtInterface_SetRadio"},
+ {35, nullptr, "ExtInterface_SetVisibility"},
+ {36, nullptr, "Unknown4"},
+ {37, nullptr, "Unknown5"},
+ {38, nullptr, "HidHostInterface_GetLatestPlr"},
+ {39, nullptr, "ExtInterface_GetPendingConnections"},
+ {40, nullptr, "HidHostInterface_GetChannelMap"},
+ {41, nullptr, "SetIsBluetoothBoostEnabled"},
+ {42, nullptr, "GetIsBluetoothBoostEnabled"},
+ {43, nullptr, "SetIsBluetoothAfhEnabled"},
+ {44, nullptr, "GetIsBluetoothAfhEnabled"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<BtDrv>()->InstallAsService(sm);
+}
+
+} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h
new file mode 100644
index 000000000..164e56f43
--- /dev/null
+++ b/src/core/hle/service/btdrv/btdrv.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::BtDrv {
+
+/// Registers all BtDrv services with the specified service manager.
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
new file mode 100644
index 000000000..b949bfabd
--- /dev/null
+++ b/src/core/hle/service/btm/btm.cpp
@@ -0,0 +1,121 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/btm/btm.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::BTM {
+
+class BTM final : public ServiceFramework<BTM> {
+public:
+ explicit BTM() : ServiceFramework{"btm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "Unknown7"},
+ {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"},
+ {9, nullptr, "Unknown8"},
+ {10, nullptr, "Unknown9"},
+ {11, nullptr, "Unknown10"},
+ {12, nullptr, "Unknown11"},
+ {13, nullptr, "Unknown12"},
+ {14, nullptr, "EnableRadioImpl"},
+ {15, nullptr, "DisableRadioImpl"},
+ {16, nullptr, "Unknown13"},
+ {17, nullptr, "Unknown14"},
+ {18, nullptr, "Unknown15"},
+ {19, nullptr, "Unknown16"},
+ {20, nullptr, "Unknown17"},
+ {21, nullptr, "Unknown18"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class BTM_DBG final : public ServiceFramework<BTM_DBG> {
+public:
+ explicit BTM_DBG() : ServiceFramework{"btm:dbg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterSystemEventForDiscoveryImpl"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "Unknown7"},
+ {8, nullptr, "Unknown8"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
+public:
+ explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "StartGamepadPairingImpl"},
+ {1, nullptr, "CancelGamepadPairingImpl"},
+ {2, nullptr, "ClearGamepadPairingDatabaseImpl"},
+ {3, nullptr, "GetPairedGamepadCountImpl"},
+ {4, nullptr, "EnableRadioImpl"},
+ {5, nullptr, "DisableRadioImpl"},
+ {6, nullptr, "GetRadioOnOffImpl"},
+ {7, nullptr, "AcquireRadioEventImpl"},
+ {8, nullptr, "AcquireGamepadPairingEventImpl"},
+ {9, nullptr, "IsGamepadPairingStartedImpl"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class BTM_SYS final : public ServiceFramework<BTM_SYS> {
+public:
+ explicit BTM_SYS() : ServiceFramework{"btm:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetCoreImpl(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IBtmSystemCore>();
+
+ LOG_DEBUG(Service_BTM, "called");
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<BTM>()->InstallAsService(sm);
+ std::make_shared<BTM_DBG>()->InstallAsService(sm);
+ std::make_shared<BTM_SYS>()->InstallAsService(sm);
+}
+
+} // namespace Service::BTM
diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h
new file mode 100644
index 000000000..e6425a7e3
--- /dev/null
+++ b/src/core/hle/service/btm/btm.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::BTM {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::BTM
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
new file mode 100644
index 000000000..ae7b0720b
--- /dev/null
+++ b/src/core/hle/service/caps/caps.cpp
@@ -0,0 +1,152 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/caps/caps.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::Capture {
+
+class CAPS_A final : public ServiceFramework<CAPS_A> {
+public:
+ explicit CAPS_A() : ServiceFramework{"caps:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ {6, nullptr, "Unknown7"},
+ {7, nullptr, "Unknown8"},
+ {8, nullptr, "Unknown9"},
+ {9, nullptr, "Unknown10"},
+ {10, nullptr, "Unknown11"},
+ {11, nullptr, "Unknown12"},
+ {12, nullptr, "Unknown13"},
+ {13, nullptr, "Unknown14"},
+ {14, nullptr, "Unknown15"},
+ {301, nullptr, "Unknown16"},
+ {401, nullptr, "Unknown17"},
+ {501, nullptr, "Unknown18"},
+ {1001, nullptr, "Unknown19"},
+ {1002, nullptr, "Unknown20"},
+ {8001, nullptr, "Unknown21"},
+ {8002, nullptr, "Unknown22"},
+ {8011, nullptr, "Unknown23"},
+ {8012, nullptr, "Unknown24"},
+ {8021, nullptr, "Unknown25"},
+ {10011, nullptr, "Unknown26"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class CAPS_C final : public ServiceFramework<CAPS_C> {
+public:
+ explicit CAPS_C() : ServiceFramework{"caps:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {2001, nullptr, "Unknown1"},
+ {2002, nullptr, "Unknown2"},
+ {2011, nullptr, "Unknown3"},
+ {2012, nullptr, "Unknown4"},
+ {2013, nullptr, "Unknown5"},
+ {2014, nullptr, "Unknown6"},
+ {2101, nullptr, "Unknown7"},
+ {2102, nullptr, "Unknown8"},
+ {2201, nullptr, "Unknown9"},
+ {2301, nullptr, "Unknown10"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class CAPS_SC final : public ServiceFramework<CAPS_SC> {
+public:
+ explicit CAPS_SC() : ServiceFramework{"caps:sc"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {1001, nullptr, "Unknown3"},
+ {1002, nullptr, "Unknown4"},
+ {1003, nullptr, "Unknown5"},
+ {1011, nullptr, "Unknown6"},
+ {1012, nullptr, "Unknown7"},
+ {1201, nullptr, "Unknown8"},
+ {1202, nullptr, "Unknown9"},
+ {1203, nullptr, "Unknown10"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class CAPS_SS final : public ServiceFramework<CAPS_SS> {
+public:
+ explicit CAPS_SS() : ServiceFramework{"caps:ss"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {201, nullptr, "Unknown1"},
+ {202, nullptr, "Unknown2"},
+ {203, nullptr, "Unknown3"},
+ {204, nullptr, "Unknown4"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class CAPS_SU final : public ServiceFramework<CAPS_SU> {
+public:
+ explicit CAPS_SU() : ServiceFramework{"caps:su"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {201, nullptr, "SaveScreenShot"},
+ {203, nullptr, "SaveScreenShotEx0"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class CAPS_U final : public ServiceFramework<CAPS_U> {
+public:
+ explicit CAPS_U() : ServiceFramework{"caps:u"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {102, nullptr, "GetAlbumFileListByAruid"},
+ {103, nullptr, "DeleteAlbumFileByAruid"},
+ {104, nullptr, "GetAlbumFileSizeByAruid"},
+ {110, nullptr, "LoadAlbumScreenShotImageByAruid"},
+ {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"},
+ {60002, nullptr, "OpenAccessorSessionForApplication"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<CAPS_A>()->InstallAsService(sm);
+ std::make_shared<CAPS_C>()->InstallAsService(sm);
+ std::make_shared<CAPS_SC>()->InstallAsService(sm);
+ std::make_shared<CAPS_SS>()->InstallAsService(sm);
+ std::make_shared<CAPS_SU>()->InstallAsService(sm);
+ std::make_shared<CAPS_U>()->InstallAsService(sm);
+}
+
+} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h
new file mode 100644
index 000000000..471185dfa
--- /dev/null
+++ b/src/core/hle/service/caps/caps.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::Capture {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::Capture
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
new file mode 100644
index 000000000..566fbf924
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -0,0 +1,75 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/fgm/fgm.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::FGM {
+
+class IRequest final : public ServiceFramework<IRequest> {
+public:
+ explicit IRequest() : ServiceFramework{"IRequest"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Set"},
+ {2, nullptr, "Get"},
+ {3, nullptr, "Cancel"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class FGM final : public ServiceFramework<FGM> {
+public:
+ explicit FGM(const char* name) : ServiceFramework{name} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &FGM::Initialize, "Initialize"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void Initialize(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IRequest>();
+
+ LOG_DEBUG(Service_FGM, "called");
+ }
+};
+
+class FGM_DBG final : public ServiceFramework<FGM_DBG> {
+public:
+ explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Read"},
+ {2, nullptr, "Cancel"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<FGM>("fgm")->InstallAsService(sm);
+ std::make_shared<FGM>("fgm:0")->InstallAsService(sm);
+ std::make_shared<FGM>("fgm:9")->InstallAsService(sm);
+ std::make_shared<FGM_DBG>()->InstallAsService(sm);
+}
+
+} // namespace Service::FGM
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h
new file mode 100644
index 000000000..e59691264
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::FGM {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::FGM
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index fdd2fda18..e17d637e4 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -14,6 +14,8 @@
#include "core/file_sys/vfs_offset.h"
#include "core/file_sys/vfs_real.h"
#include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/filesystem/fsp_ldr.h"
+#include "core/hle/service/filesystem/fsp_pr.h"
#include "core/hle/service/filesystem/fsp_srv.h"
namespace Service::FileSystem {
@@ -298,6 +300,8 @@ void RegisterFileSystems() {
void InstallInterfaces(SM::ServiceManager& service_manager) {
RegisterFileSystems();
+ std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
+ std::make_shared<FSP_PR>()->InstallAsService(service_manager);
std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
}
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp
new file mode 100644
index 000000000..0ab9c2606
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_ldr.cpp
@@ -0,0 +1,22 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/filesystem/fsp_ldr.h"
+#include "core/hle/service/service.h"
+
+namespace Service::FileSystem {
+
+FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "OpenCodeFileSystem"},
+ {1, nullptr, "IsArchivedProgram"},
+ {2, nullptr, "SetCurrentProcess"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h
new file mode 100644
index 000000000..fa8e11b4c
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_ldr.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::FileSystem {
+
+class FSP_LDR final : public ServiceFramework<FSP_LDR> {
+public:
+ explicit FSP_LDR();
+};
+
+} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp
new file mode 100644
index 000000000..32b0ae454
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_pr.cpp
@@ -0,0 +1,23 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/filesystem/fsp_pr.h"
+#include "core/hle/service/service.h"
+
+namespace Service::FileSystem {
+
+FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterProgram"},
+ {1, nullptr, "UnregisterProgram"},
+ {2, nullptr, "SetCurrentProcess"},
+ {256, nullptr, "SetEnabledProgramVerification"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h
new file mode 100644
index 000000000..62edcd08a
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_pr.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::FileSystem {
+
+class FSP_PR final : public ServiceFramework<FSP_PR> {
+public:
+ explicit FSP_PR();
+};
+
+} // namespace Service::FileSystem
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e4619a547..8f0262e34 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -326,7 +326,7 @@ public:
{79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
{80, nullptr, "GetGyroscopeZeroDriftMode"},
{81, nullptr, "ResetGyroscopeZeroDriftMode"},
- {82, nullptr, "IsSixAxisSensorAtRest"},
+ {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
{91, nullptr, "ActivateGesture"},
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
{101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
@@ -337,13 +337,14 @@ public:
"AcquireNpadStyleSetUpdateEventHandle"},
{107, nullptr, "DisconnectNpad"},
{108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
+ {109, nullptr, "ActivateNpadWithRevision"},
{120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
{122, &Hid::SetNpadJoyAssignmentModeSingleByDefault,
"SetNpadJoyAssignmentModeSingleByDefault"},
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
- {125, nullptr, "MergeSingleJoyAsDualJoy"},
+ {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
{126, nullptr, "StartLrAssignmentMode"},
{127, nullptr, "StopLrAssignmentMode"},
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
@@ -455,6 +456,14 @@ private:
LOG_WARNING(Service_HID, "(STUBBED) called");
}
+ void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
+ rb.Push(true);
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+ }
+
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -530,6 +539,12 @@ private:
LOG_WARNING(Service_HID, "(STUBBED) called");
}
+ void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+ }
+
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp
new file mode 100644
index 000000000..8fc8b1057
--- /dev/null
+++ b/src/core/hle/service/lbl/lbl.cpp
@@ -0,0 +1,90 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/lbl/lbl.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::LBL {
+
+class LBL final : public ServiceFramework<LBL> {
+public:
+ explicit LBL() : ServiceFramework{"lbl"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ {6, nullptr, "TurnOffBacklight"},
+ {7, nullptr, "TurnOnBacklight"},
+ {8, nullptr, "GetBacklightStatus"},
+ {9, nullptr, "Unknown7"},
+ {10, nullptr, "Unknown8"},
+ {11, nullptr, "Unknown9"},
+ {12, nullptr, "Unknown10"},
+ {13, nullptr, "Unknown11"},
+ {14, nullptr, "Unknown12"},
+ {15, nullptr, "Unknown13"},
+ {16, nullptr, "ReadRawLightSensor"},
+ {17, nullptr, "Unknown14"},
+ {18, nullptr, "Unknown15"},
+ {19, nullptr, "Unknown16"},
+ {20, nullptr, "Unknown17"},
+ {21, nullptr, "Unknown18"},
+ {22, nullptr, "Unknown19"},
+ {23, nullptr, "Unknown20"},
+ {24, nullptr, "Unknown21"},
+ {25, nullptr, "Unknown22"},
+ {26, &LBL::EnableVrMode, "EnableVrMode"},
+ {27, &LBL::DisableVrMode, "DisableVrMode"},
+ {28, &LBL::GetVrMode, "GetVrMode"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void EnableVrMode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ vr_mode_enabled = true;
+
+ LOG_DEBUG(Service_LBL, "called");
+ }
+
+ void DisableVrMode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ vr_mode_enabled = false;
+
+ LOG_DEBUG(Service_LBL, "called");
+ }
+
+ void GetVrMode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(vr_mode_enabled);
+
+ LOG_DEBUG(Service_LBL, "called");
+ }
+
+ bool vr_mode_enabled = false;
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<LBL>()->InstallAsService(sm);
+}
+
+} // namespace Service::LBL
diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h
new file mode 100644
index 000000000..bf6f400f8
--- /dev/null
+++ b/src/core/hle/service/lbl/lbl.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::LBL {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::LBL
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index b497376d7..2e99ddf51 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -13,11 +13,11 @@
namespace Service::LM {
-class Logger final : public ServiceFramework<Logger> {
+class ILogger final : public ServiceFramework<ILogger> {
public:
- Logger() : ServiceFramework("Logger") {
+ ILogger() : ServiceFramework("ILogger") {
static const FunctionInfo functions[] = {
- {0x00000000, &Logger::Initialize, "Initialize"},
+ {0x00000000, &ILogger::Initialize, "Initialize"},
{0x00000001, nullptr, "SetDestination"},
};
RegisterHandlers(functions);
@@ -182,7 +182,7 @@ public:
void OpenLogger(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<Logger>();
+ rb.PushIpcInterface<ILogger>();
LOG_DEBUG(Service_LM, "called");
}
diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp
new file mode 100644
index 000000000..d16367f2c
--- /dev/null
+++ b/src/core/hle/service/mig/mig.cpp
@@ -0,0 +1,34 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/mig/mig.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::Migration {
+
+class MIG_USR final : public ServiceFramework<MIG_USR> {
+public:
+ explicit MIG_USR() : ServiceFramework{"mig:usr"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {10, nullptr, "TryGetLastMigrationInfo"},
+ {100, nullptr, "CreateServer"},
+ {101, nullptr, "ResumeServer"},
+ {200, nullptr, "CreateClient"},
+ {201, nullptr, "ResumeClient"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<MIG_USR>()->InstallAsService(sm);
+}
+
+} // namespace Service::Migration
diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h
new file mode 100644
index 000000000..288c1c1b3
--- /dev/null
+++ b/src/core/hle/service/mig/mig.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::Migration {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::Migration
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
new file mode 100644
index 000000000..a6197124a
--- /dev/null
+++ b/src/core/hle/service/mii/mii.cpp
@@ -0,0 +1,107 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/mii/mii.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::Mii {
+
+class IDatabaseService final : public ServiceFramework<IDatabaseService> {
+public:
+ explicit IDatabaseService() : ServiceFramework{"IDatabaseService"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "IsUpdated"},
+ {1, nullptr, "IsFullDatabase"},
+ {2, nullptr, "GetCount"},
+ {3, nullptr, "Get"},
+ {4, nullptr, "Get1"},
+ {5, nullptr, "UpdateLatest"},
+ {6, nullptr, "BuildRandom"},
+ {7, nullptr, "BuildDefault"},
+ {8, nullptr, "Get2"},
+ {9, nullptr, "Get3"},
+ {10, nullptr, "UpdateLatest1"},
+ {11, nullptr, "FindIndex"},
+ {12, nullptr, "Move"},
+ {13, nullptr, "AddOrReplace"},
+ {14, nullptr, "Delete"},
+ {15, nullptr, "DestroyFile"},
+ {16, nullptr, "DeleteFile"},
+ {17, nullptr, "Format"},
+ {18, nullptr, "Import"},
+ {19, nullptr, "Export"},
+ {20, nullptr, "IsBrokenDatabaseWithClearFlag"},
+ {21, nullptr, "GetIndex"},
+ {22, nullptr, "SetInterfaceVersion"},
+ {23, nullptr, "Convert"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class MiiDBModule final : public ServiceFramework<MiiDBModule> {
+public:
+ explicit MiiDBModule(const char* name) : ServiceFramework{name} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetDatabaseService(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IDatabaseService>();
+
+ LOG_DEBUG(Service_Mii, "called");
+ }
+};
+
+class MiiImg final : public ServiceFramework<MiiImg> {
+public:
+ explicit MiiImg() : ServiceFramework{"miiimg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {10, nullptr, "Reload"},
+ {11, nullptr, "GetCount"},
+ {12, nullptr, "IsEmpty"},
+ {13, nullptr, "IsFull"},
+ {14, nullptr, "GetAttribute"},
+ {15, nullptr, "LoadImage"},
+ {16, nullptr, "AddOrUpdateImage"},
+ {17, nullptr, "DeleteImages"},
+ {100, nullptr, "DeleteFile"},
+ {101, nullptr, "DestroyFile"},
+ {102, nullptr, "ImportFile"},
+ {103, nullptr, "ExportFile"},
+ {104, nullptr, "ForceInitialize"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<MiiDBModule>("mii:e")->InstallAsService(sm);
+ std::make_shared<MiiDBModule>("mii:u")->InstallAsService(sm);
+
+ std::make_shared<MiiImg>()->InstallAsService(sm);
+}
+
+} // namespace Service::Mii
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h
new file mode 100644
index 000000000..7ce9be50e
--- /dev/null
+++ b/src/core/hle/service/mii/mii.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::Mii {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::Mii
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
new file mode 100644
index 000000000..0297edca0
--- /dev/null
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -0,0 +1,59 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/ncm/ncm.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::NCM {
+
+class LocationResolver final : public ServiceFramework<LocationResolver> {
+public:
+ explicit LocationResolver() : ServiceFramework{"lr"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "OpenLocationResolver"},
+ {1, nullptr, "OpenRegisteredLocationResolver"},
+ {2, nullptr, "RefreshLocationResolver"},
+ {3, nullptr, "OpenAddOnContentLocationResolver"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NCM final : public ServiceFramework<NCM> {
+public:
+ explicit NCM() : ServiceFramework{"ncm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateContentStorage"},
+ {1, nullptr, "CreateContentMetaDatabase"},
+ {2, nullptr, "VerifyContentStorage"},
+ {3, nullptr, "VerifyContentMetaDatabase"},
+ {4, nullptr, "OpenContentStorage"},
+ {5, nullptr, "OpenContentMetaDatabase"},
+ {6, nullptr, "CloseContentStorageForcibly"},
+ {7, nullptr, "CloseContentMetaDatabaseForcibly"},
+ {8, nullptr, "CleanupContentMetaDatabase"},
+ {9, nullptr, "OpenContentStorage2"},
+ {10, nullptr, "CloseContentStorage"},
+ {11, nullptr, "OpenContentMetaDatabase2"},
+ {12, nullptr, "CloseContentMetaDatabase"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<LocationResolver>()->InstallAsService(sm);
+ std::make_shared<NCM>()->InstallAsService(sm);
+}
+
+} // namespace Service::NCM
diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h
new file mode 100644
index 000000000..7bc8518a6
--- /dev/null
+++ b/src/core/hle/service/ncm/ncm.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::NCM {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::NCM
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
new file mode 100644
index 000000000..8fec97db8
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -0,0 +1,222 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/nfc/nfc.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::NFC {
+
+class IAm final : public ServiceFramework<IAm> {
+public:
+ explicit IAm() : ServiceFramework{"IAm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "NotifyForegroundApplet"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NFC_AM final : public ServiceFramework<NFC_AM> {
+public:
+ explicit NFC_AM() : ServiceFramework{"nfc:am"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void CreateAmInterface(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IAm>();
+
+ LOG_DEBUG(Service_NFC, "called");
+ }
+};
+
+class MFIUser final : public ServiceFramework<MFIUser> {
+public:
+ explicit MFIUser() : ServiceFramework{"IUser"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "ListDevices"},
+ {3, nullptr, "StartDetection"},
+ {4, nullptr, "StopDetection"},
+ {5, nullptr, "Read"},
+ {6, nullptr, "Write"},
+ {7, nullptr, "GetTagInfo"},
+ {8, nullptr, "GetActivateEventHandle"},
+ {9, nullptr, "GetDeactivateEventHandle"},
+ {10, nullptr, "GetState"},
+ {11, nullptr, "GetDeviceState"},
+ {12, nullptr, "GetNpadId"},
+ {13, nullptr, "GetAvailabilityChangeEventHandle"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NFC_MF_U final : public ServiceFramework<NFC_MF_U> {
+public:
+ explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void CreateUserInterface(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<MFIUser>();
+
+ LOG_DEBUG(Service_NFC, "called");
+ }
+};
+
+class IUser final : public ServiceFramework<IUser> {
+public:
+ explicit IUser() : ServiceFramework{"IUser"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "GetState"},
+ {3, nullptr, "IsNfcEnabled"},
+ {400, nullptr, "Initialize"},
+ {401, nullptr, "Finalize"},
+ {402, nullptr, "GetState"},
+ {403, nullptr, "IsNfcEnabled"},
+ {404, nullptr, "ListDevices"},
+ {405, nullptr, "GetDeviceState"},
+ {406, nullptr, "GetNpadId"},
+ {407, nullptr, "AttachAvailabilityChangeEvent"},
+ {408, nullptr, "StartDetection"},
+ {409, nullptr, "StopDetection"},
+ {410, nullptr, "GetTagInfo"},
+ {411, nullptr, "AttachActivateEvent"},
+ {412, nullptr, "AttachDeactivateEvent"},
+ {1000, nullptr, "ReadMifare"},
+ {1001, nullptr, "WriteMifare"},
+ {1300, nullptr, "SendCommandByPassThrough"},
+ {1301, nullptr, "KeepPassThroughSession"},
+ {1302, nullptr, "ReleasePassThroughSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NFC_U final : public ServiceFramework<NFC_U> {
+public:
+ explicit NFC_U() : ServiceFramework{"nfc:u"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &NFC_U::CreateUserInterface, "CreateUserInterface"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void CreateUserInterface(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IUser>();
+
+ LOG_DEBUG(Service_NFC, "called");
+ }
+};
+
+class ISystem final : public ServiceFramework<ISystem> {
+public:
+ explicit ISystem() : ServiceFramework{"ISystem"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "GetState"},
+ {3, nullptr, "IsNfcEnabled"},
+ {100, nullptr, "SetNfcEnabled"},
+ {400, nullptr, "InitializeSystem"},
+ {401, nullptr, "FinalizeSystem"},
+ {402, nullptr, "GetState"},
+ {403, nullptr, "IsNfcEnabled"},
+ {404, nullptr, "ListDevices"},
+ {405, nullptr, "GetDeviceState"},
+ {406, nullptr, "GetNpadId"},
+ {407, nullptr, "AttachAvailabilityChangeEvent"},
+ {408, nullptr, "StartDetection"},
+ {409, nullptr, "StopDetection"},
+ {410, nullptr, "GetTagInfo"},
+ {411, nullptr, "AttachActivateEvent"},
+ {412, nullptr, "AttachDeactivateEvent"},
+ {500, nullptr, "SetNfcEnabled"},
+ {1000, nullptr, "ReadMifare"},
+ {1001, nullptr, "WriteMifare"},
+ {1300, nullptr, "SendCommandByPassThrough"},
+ {1301, nullptr, "KeepPassThroughSession"},
+ {1302, nullptr, "ReleasePassThroughSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NFC_SYS final : public ServiceFramework<NFC_SYS> {
+public:
+ explicit NFC_SYS() : ServiceFramework{"nfc:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void CreateSystemInterface(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ISystem>();
+
+ LOG_DEBUG(Service_NFC, "called");
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<NFC_AM>()->InstallAsService(sm);
+ std::make_shared<NFC_MF_U>()->InstallAsService(sm);
+ std::make_shared<NFC_U>()->InstallAsService(sm);
+ std::make_shared<NFC_SYS>()->InstallAsService(sm);
+}
+
+} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h
new file mode 100644
index 000000000..4d2d815f9
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::NFC {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::NFC
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 89c703310..98017267c 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -2,12 +2,459 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/ns/pl_u.h"
namespace Service::NS {
+class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
+public:
+ explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateUserAccount"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
+public:
+ explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ListApplicationRecord"},
+ {1, nullptr, "GenerateApplicationRecordCount"},
+ {2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
+ {3, nullptr, "GetApplicationViewDeprecated"},
+ {4, nullptr, "DeleteApplicationEntity"},
+ {5, nullptr, "DeleteApplicationCompletely"},
+ {6, nullptr, "IsAnyApplicationEntityRedundant"},
+ {7, nullptr, "DeleteRedundantApplicationEntity"},
+ {8, nullptr, "IsApplicationEntityMovable"},
+ {9, nullptr, "MoveApplicationEntity"},
+ {11, nullptr, "CalculateApplicationOccupiedSize"},
+ {16, nullptr, "PushApplicationRecord"},
+ {17, nullptr, "ListApplicationRecordContentMeta"},
+ {19, nullptr, "LaunchApplication"},
+ {21, nullptr, "GetApplicationContentPath"},
+ {22, nullptr, "TerminateApplication"},
+ {23, nullptr, "ResolveApplicationContentPath"},
+ {26, nullptr, "BeginInstallApplication"},
+ {27, nullptr, "DeleteApplicationRecord"},
+ {30, nullptr, "RequestApplicationUpdateInfo"},
+ {32, nullptr, "CancelApplicationDownload"},
+ {33, nullptr, "ResumeApplicationDownload"},
+ {35, nullptr, "UpdateVersionList"},
+ {36, nullptr, "PushLaunchVersion"},
+ {37, nullptr, "ListRequiredVersion"},
+ {38, nullptr, "CheckApplicationLaunchVersion"},
+ {39, nullptr, "CheckApplicationLaunchRights"},
+ {40, nullptr, "GetApplicationLogoData"},
+ {41, nullptr, "CalculateApplicationDownloadRequiredSize"},
+ {42, nullptr, "CleanupSdCard"},
+ {43, nullptr, "CheckSdCardMountStatus"},
+ {44, nullptr, "GetSdCardMountStatusChangedEvent"},
+ {45, nullptr, "GetGameCardAttachmentEvent"},
+ {46, nullptr, "GetGameCardAttachmentInfo"},
+ {47, nullptr, "GetTotalSpaceSize"},
+ {48, nullptr, "GetFreeSpaceSize"},
+ {49, nullptr, "GetSdCardRemovedEvent"},
+ {52, nullptr, "GetGameCardUpdateDetectionEvent"},
+ {53, nullptr, "DisableApplicationAutoDelete"},
+ {54, nullptr, "EnableApplicationAutoDelete"},
+ {55, nullptr, "GetApplicationDesiredLanguage"},
+ {56, nullptr, "SetApplicationTerminateResult"},
+ {57, nullptr, "ClearApplicationTerminateResult"},
+ {58, nullptr, "GetLastSdCardMountUnexpectedResult"},
+ {59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
+ {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
+ {61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
+ {62, nullptr, "GetGameCardStopper"},
+ {63, nullptr, "IsSystemProgramInstalled"},
+ {64, nullptr, "StartApplyDeltaTask"},
+ {65, nullptr, "GetRequestServerStopper"},
+ {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
+ {67, nullptr, "CancelApplicationApplyDelta"},
+ {68, nullptr, "ResumeApplicationApplyDelta"},
+ {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
+ {70, nullptr, "ResumeAll"},
+ {71, nullptr, "GetStorageSize"},
+ {80, nullptr, "RequestDownloadApplication"},
+ {81, nullptr, "RequestDownloadAddOnContent"},
+ {82, nullptr, "DownloadApplication"},
+ {83, nullptr, "CheckApplicationResumeRights"},
+ {84, nullptr, "GetDynamicCommitEvent"},
+ {85, nullptr, "RequestUpdateApplication2"},
+ {86, nullptr, "EnableApplicationCrashReport"},
+ {87, nullptr, "IsApplicationCrashReportEnabled"},
+ {90, nullptr, "BoostSystemMemoryResourceLimit"},
+ {100, nullptr, "ResetToFactorySettings"},
+ {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
+ {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
+ {200, nullptr, "CalculateUserSaveDataStatistics"},
+ {201, nullptr, "DeleteUserSaveDataAll"},
+ {210, nullptr, "DeleteUserSystemSaveData"},
+ {220, nullptr, "UnregisterNetworkServiceAccount"},
+ {300, nullptr, "GetApplicationShellEvent"},
+ {301, nullptr, "PopApplicationShellEventInfo"},
+ {302, nullptr, "LaunchLibraryApplet"},
+ {303, nullptr, "TerminateLibraryApplet"},
+ {304, nullptr, "LaunchSystemApplet"},
+ {305, nullptr, "TerminateSystemApplet"},
+ {306, nullptr, "LaunchOverlayApplet"},
+ {307, nullptr, "TerminateOverlayApplet"},
+ {400, nullptr, "GetApplicationControlData"},
+ {401, nullptr, "InvalidateAllApplicationControlCache"},
+ {402, nullptr, "RequestDownloadApplicationControlData"},
+ {403, nullptr, "GetMaxApplicationControlCacheCount"},
+ {404, nullptr, "InvalidateApplicationControlCache"},
+ {405, nullptr, "ListApplicationControlCacheEntryInfo"},
+ {502, nullptr, "RequestCheckGameCardRegistration"},
+ {503, nullptr, "RequestGameCardRegistrationGoldPoint"},
+ {504, nullptr, "RequestRegisterGameCard"},
+ {505, nullptr, "GetGameCardMountFailureEvent"},
+ {506, nullptr, "IsGameCardInserted"},
+ {507, nullptr, "EnsureGameCardAccess"},
+ {508, nullptr, "GetLastGameCardMountFailureResult"},
+ {509, nullptr, "ListApplicationIdOnGameCard"},
+ {600, nullptr, "CountApplicationContentMeta"},
+ {601, nullptr, "ListApplicationContentMetaStatus"},
+ {602, nullptr, "ListAvailableAddOnContent"},
+ {603, nullptr, "GetOwnedApplicationContentMetaStatus"},
+ {604, nullptr, "RegisterContentsExternalKey"},
+ {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
+ {606, nullptr, "GetContentMetaStorage"},
+ {700, nullptr, "PushDownloadTaskList"},
+ {701, nullptr, "ClearTaskStatusList"},
+ {702, nullptr, "RequestDownloadTaskList"},
+ {703, nullptr, "RequestEnsureDownloadTask"},
+ {704, nullptr, "ListDownloadTaskStatus"},
+ {705, nullptr, "RequestDownloadTaskListData"},
+ {800, nullptr, "RequestVersionList"},
+ {801, nullptr, "ListVersionList"},
+ {802, nullptr, "RequestVersionListData"},
+ {900, nullptr, "GetApplicationRecord"},
+ {901, nullptr, "GetApplicationRecordProperty"},
+ {902, nullptr, "EnableApplicationAutoUpdate"},
+ {903, nullptr, "DisableApplicationAutoUpdate"},
+ {904, nullptr, "TouchApplication"},
+ {905, nullptr, "RequestApplicationUpdate"},
+ {906, nullptr, "IsApplicationUpdateRequested"},
+ {907, nullptr, "WithdrawApplicationUpdateRequest"},
+ {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
+ {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
+ {1000, nullptr, "RequestVerifyApplicationDeprecated"},
+ {1001, nullptr, "CorruptApplicationForDebug"},
+ {1002, nullptr, "RequestVerifyAddOnContentsRights"},
+ {1003, nullptr, "RequestVerifyApplication"},
+ {1004, nullptr, "CorruptContentForDebug"},
+ {1200, nullptr, "NeedsUpdateVulnerability"},
+ {1300, nullptr, "IsAnyApplicationEntityInstalled"},
+ {1301, nullptr, "DeleteApplicationContentEntities"},
+ {1302, nullptr, "CleanupUnrecordedApplicationEntity"},
+ {1303, nullptr, "CleanupAddOnContentsWithNoRights"},
+ {1304, nullptr, "DeleteApplicationContentEntity"},
+ {1305, nullptr, "TryDeleteRunningApplicationEntity"},
+ {1306, nullptr, "TryDeleteRunningApplicationCompletely"},
+ {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
+ {1400, nullptr, "PrepareShutdown"},
+ {1500, nullptr, "FormatSdCard"},
+ {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
+ {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
+ {1504, nullptr, "InsertSdCard"},
+ {1505, nullptr, "RemoveSdCard"},
+ {1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
+ {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
+ {1700, nullptr, "ListApplicationDownloadingContentMeta"},
+ {1701, nullptr, "GetApplicationView"},
+ {1702, nullptr, "GetApplicationDownloadTaskStatus"},
+ {1703, nullptr, "GetApplicationViewDownloadErrorContext"},
+ {1800, nullptr, "IsNotificationSetupCompleted"},
+ {1801, nullptr, "GetLastNotificationInfoCount"},
+ {1802, nullptr, "ListLastNotificationInfo"},
+ {1803, nullptr, "ListNotificationTask"},
+ {1900, nullptr, "IsActiveAccount"},
+ {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
+ {1902, nullptr, "GetApplicationTicketInfo"},
+ {2000, nullptr, "GetSystemDeliveryInfo"},
+ {2001, nullptr, "SelectLatestSystemDeliveryInfo"},
+ {2002, nullptr, "VerifyDeliveryProtocolVersion"},
+ {2003, nullptr, "GetApplicationDeliveryInfo"},
+ {2004, nullptr, "HasAllContentsToDeliver"},
+ {2005, nullptr, "CompareApplicationDeliveryInfo"},
+ {2006, nullptr, "CanDeliverApplication"},
+ {2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
+ {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
+ {2009, nullptr, "EstimateRequiredSize"},
+ {2010, nullptr, "RequestReceiveApplication"},
+ {2011, nullptr, "CommitReceiveApplication"},
+ {2012, nullptr, "GetReceiveApplicationProgress"},
+ {2013, nullptr, "RequestSendApplication"},
+ {2014, nullptr, "GetSendApplicationProgress"},
+ {2015, nullptr, "CompareSystemDeliveryInfo"},
+ {2016, nullptr, "ListNotCommittedContentMeta"},
+ {2017, nullptr, "CreateDownloadTask"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
+public:
+ explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetLaunchRequiredVersion"},
+ {1, nullptr, "UpgradeLaunchRequiredVersion"},
+ {35, nullptr, "UpdateVersionList"},
+ {36, nullptr, "PushLaunchVersion"},
+ {37, nullptr, "ListRequiredVersion"},
+ {800, nullptr, "RequestVersionList"},
+ {801, nullptr, "ListVersionList"},
+ {802, nullptr, "RequestVersionListData"},
+ {1000, nullptr, "PerformAutoUpdate"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
+public:
+ explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {11, nullptr, "CalculateApplicationOccupiedSize"},
+ {43, nullptr, "CheckSdCardMountStatus"},
+ {47, nullptr, "GetTotalSpaceSize"},
+ {48, nullptr, "GetFreeSpaceSize"},
+ {600, nullptr, "CountApplicationContentMeta"},
+ {601, nullptr, "ListApplicationContentMetaStatus"},
+ {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
+ {607, nullptr, "IsAnyApplicationRunning"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
+public:
+ explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {21, nullptr, "GetApplicationContentPath"},
+ {23, nullptr, "ResolveApplicationContentPath"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
+public:
+ explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {701, nullptr, "ClearTaskStatusList"},
+ {702, nullptr, "RequestDownloadTaskList"},
+ {703, nullptr, "RequestEnsureDownloadTask"},
+ {704, nullptr, "ListDownloadTaskStatus"},
+ {705, nullptr, "RequestDownloadTaskListData"},
+ {706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
+ {707, nullptr, "EnableAutoCommit"},
+ {708, nullptr, "DisableAutoCommit"},
+ {709, nullptr, "TriggerDynamicCommitEvent"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
+public:
+ explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestLinkDevice"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
+public:
+ explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {100, nullptr, "ResetToFactorySettings"},
+ {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
+ {102, nullptr, "ResetToFactorySettingsForRefurbishment "},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NS final : public ServiceFramework<NS> {
+public:
+ explicit NS(const char* name) : ServiceFramework{name} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
+ {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
+ {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
+ {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
+ {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
+ {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
+ {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
+ {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ template <typename T>
+ void PushInterface(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<T>();
+
+ LOG_DEBUG(Service_NS, "called");
+ }
+};
+
+class NS_DEV final : public ServiceFramework<NS_DEV> {
+public:
+ explicit NS_DEV() : ServiceFramework{"ns:dev"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "LaunchProgram"},
+ {1, nullptr, "TerminateProcess"},
+ {2, nullptr, "TerminateProgram"},
+ {3, nullptr, "GetShellEventHandle"},
+ {4, nullptr, "GetShellEventInfo"},
+ {5, nullptr, "TerminateApplication"},
+ {6, nullptr, "PrepareLaunchProgramFromHost"},
+ {7, nullptr, "LaunchApplication"},
+ {8, nullptr, "LaunchApplicationWithStorageId"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
+public:
+ explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "HasDownloaded"},
+ {1, nullptr, "RequestCheckLatestUpdate"},
+ {2, nullptr, "RequestDownloadLatestUpdate"},
+ {3, nullptr, "GetDownloadProgress"},
+ {4, nullptr, "ApplyDownloadedUpdate"},
+ {5, nullptr, "RequestPrepareCardUpdate"},
+ {6, nullptr, "GetPrepareCardUpdateProgress"},
+ {7, nullptr, "HasPreparedCardUpdate"},
+ {8, nullptr, "ApplyCardUpdate"},
+ {9, nullptr, "GetDownloadedEulaDataSize"},
+ {10, nullptr, "GetDownloadedEulaData"},
+ {11, nullptr, "SetupCardUpdate"},
+ {12, nullptr, "GetPreparedCardUpdateEulaDataSize"},
+ {13, nullptr, "GetPreparedCardUpdateEulaData"},
+ {14, nullptr, "SetupCardUpdateViaSystemUpdater"},
+ {15, nullptr, "HasReceived"},
+ {16, nullptr, "RequestReceiveSystemUpdate"},
+ {17, nullptr, "GetReceiveProgress"},
+ {18, nullptr, "ApplyReceivedUpdate"},
+ {19, nullptr, "GetReceivedEulaDataSize"},
+ {20, nullptr, "GetReceivedEulaData"},
+ {21, nullptr, "SetupToReceiveSystemUpdate"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class NS_SU final : public ServiceFramework<NS_SU> {
+public:
+ explicit NS_SU() : ServiceFramework{"ns:su"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetBackgroundNetworkUpdateState"},
+ {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"},
+ {2, nullptr, "NotifyExFatDriverRequired"},
+ {3, nullptr, "ClearExFatDriverStatusForDebug"},
+ {4, nullptr, "RequestBackgroundNetworkUpdate"},
+ {5, nullptr, "NotifyBackgroundNetworkUpdate"},
+ {6, nullptr, "NotifyExFatDriverDownloadedForDebug"},
+ {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"},
+ {10, nullptr, "NotifySystemUpdateForContentDelivery"},
+ {11, nullptr, "PrepareShutdown"},
+ {16, nullptr, "DestroySystemUpdateTask"},
+ {17, nullptr, "RequestSendSystemUpdate"},
+ {18, nullptr, "GetSendSystemUpdateProgress"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ISystemUpdateControl>();
+
+ LOG_DEBUG(Service_NS, "called");
+ }
+};
+
+class NS_VM final : public ServiceFramework<NS_VM> {
+public:
+ explicit NS_VM() : ServiceFramework{"ns:vm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {1200, nullptr, "NeedsUpdateVulnerability"},
+ {1201, nullptr, "UpdateSafeSystemVersionForDebug"},
+ {1202, nullptr, "GetSafeSystemVersion"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
void InstallInterfaces(SM::ServiceManager& service_manager) {
+ std::make_shared<NS>("ns:am2")->InstallAsService(service_manager);
+ std::make_shared<NS>("ns:ec")->InstallAsService(service_manager);
+ std::make_shared<NS>("ns:rid")->InstallAsService(service_manager);
+ std::make_shared<NS>("ns:rt")->InstallAsService(service_manager);
+ std::make_shared<NS>("ns:web")->InstallAsService(service_manager);
+
+ std::make_shared<NS_DEV>()->InstallAsService(service_manager);
+ std::make_shared<NS_SU>()->InstallAsService(service_manager);
+ std::make_shared<NS_VM>()->InstallAsService(service_manager);
+
std::make_shared<PL_U>()->InstallAsService(service_manager);
}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index ed69a4325..8bc49935a 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -7,8 +7,8 @@
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "video_core/gpu.h"
#include "video_core/renderer_base.h"
-#include "video_core/video_core.h"
namespace Service::Nvidia::Devices {
@@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
addr, offset, width, height, stride, static_cast<PixelFormat>(format),
transform, crop_rect};
- Core::System::GetInstance().perf_stats.EndGameFrame();
-
- VideoCore::g_renderer->SwapBuffers(framebuffer);
+ auto& instance = Core::System::GetInstance();
+ instance.perf_stats.EndGameFrame();
+ instance.Renderer().SwapBuffers(framebuffer);
}
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 57b128b40..be2b79256 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -2,14 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "video_core/memory_manager.h"
+#include "video_core/rasterizer_interface.h"
#include "video_core/renderer_base.h"
-#include "video_core/video_core.h"
namespace Service::Nvidia::Devices {
@@ -150,15 +151,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
- auto& gpu = Core::System::GetInstance().GPU();
-
- auto itr = buffer_mappings.find(params.offset);
-
+ const auto itr = buffer_mappings.find(params.offset);
ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping");
+ auto& system_instance = Core::System::GetInstance();
+
// Remove this memory region from the rasterizer cache.
- VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size);
+ system_instance.Renderer().Rasterizer().FlushAndInvalidateRegion(params.offset,
+ itr->second.size);
+ auto& gpu = system_instance.GPU();
params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size);
buffer_mappings.erase(itr->second.offset);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 671b092e1..5685eb2be 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstdlib>
+#include <cstring>
+
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 090261a60..6b496e9fe 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -5,8 +5,6 @@
#pragma once
#include <array>
-#include <cstdlib>
-#include <cstring>
#include <vector>
#include "common/common_types.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 44e062f50..ae421247d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h"
@@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlActiveSlotMask params{};
- std::memcpy(&params, input.data(), input.size());
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
params.slot = 0x07;
params.mask = 0x01;
std::memcpy(output.data(), &params, output.size());
@@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlZcullGetCtxSize params{};
- std::memcpy(&params, input.data(), input.size());
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
params.size = 0x1;
std::memcpy(output.data(), &params, output.size());
return 0;
@@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlNvgpuGpuZcullGetInfoArgs params{};
- std::memcpy(&params, input.data(), input.size());
+
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
+
params.width_align_pixels = 0x20;
params.height_align_pixels = 0x20;
params.pixel_squares_by_aliquots = 0x400;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 126782573..116dabedb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -2,12 +2,14 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
-#include <map>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
+#include "core/memory.h"
+#include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
namespace Service::Nvidia::Devices {
@@ -132,9 +134,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
params.address, params.num_entries, params.flags);
- auto entries = std::vector<IoctlGpfifoEntry>();
- entries.resize(params.num_entries);
- std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)],
+ ASSERT_MSG(input.size() ==
+ sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry),
+ "Incorrect input size");
+
+ std::vector<IoctlGpfifoEntry> entries(params.num_entries);
+ std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)],
params.num_entries * sizeof(IoctlGpfifoEntry));
for (auto entry : entries) {
Tegra::GPUVAddr va_addr = entry.Address();
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index aa8df2e6e..650ed8fbc 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -6,6 +6,7 @@
#include <memory>
#include <vector>
+#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index b51c73ee8..364619e67 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstring>
+
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 0192aecdd..6ad74421b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -4,11 +4,9 @@
#pragma once
-#include <array>
-#include <cstdlib>
-#include <cstring>
#include <vector>
#include "common/common_types.h"
+#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
namespace Service::Nvidia::Devices {
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 724eeb139..e9305bfb3 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -3,7 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 959b5ba29..1c3529bb6 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -5,7 +5,6 @@
#pragma once
#include <memory>
-#include <string>
#include "core/hle/kernel/event.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/service.h"
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 1555ea806..e8b30921a 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -54,7 +54,7 @@ u32 Module::Open(const std::string& device_name) {
return fd;
}
-u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) {
+u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) {
auto itr = open_files.find(fd);
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp
index 9ca6e5512..0e8e21bad 100644
--- a/src/core/hle/service/nvdrv/nvmemp.cpp
+++ b/src/core/hle/service/nvdrv/nvmemp.cpp
@@ -4,8 +4,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
-#include "core/hle/ipc_helpers.h"
-#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvdrv/nvmemp.h"
namespace Service::Nvidia {
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 7132b18ad..adf180509 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -4,9 +4,8 @@
#include <algorithm>
-#include "common/alignment.h"
-#include "common/scope_exit.h"
-#include "core/core_timing.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
#include "core/hle/service/nvflinger/buffer_queue.h"
namespace Service {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 5344441e1..570aa8493 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -3,8 +3,11 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <boost/optional.hpp>
#include "common/alignment.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "core/core.h"
@@ -31,7 +34,7 @@ NVFlinger::NVFlinger() {
// Schedule the screen composition events
composition_event =
- CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) {
+ CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
Compose();
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event);
});
@@ -43,7 +46,7 @@ NVFlinger::~NVFlinger() {
CoreTiming::UnscheduleEvent(composition_event, 0);
}
-u64 NVFlinger::OpenDisplay(const std::string& name) {
+u64 NVFlinger::OpenDisplay(std::string_view name) {
LOG_WARNING(Service, "Opening display {}", name);
// TODO(Subv): Currently we only support the Default display.
@@ -127,9 +130,11 @@ void NVFlinger::Compose() {
MicroProfileFlip();
if (buffer == boost::none) {
+ auto& system_instance = Core::System::GetInstance();
+
// There was no queued buffer to draw, render previous frame
- Core::System::GetInstance().perf_stats.EndGameFrame();
- VideoCore::g_renderer->SwapBuffers({});
+ system_instance.perf_stats.EndGameFrame();
+ system_instance.Renderer().SwapBuffers({});
continue;
}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 2c908297b..5374df175 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -5,7 +5,11 @@
#pragma once
#include <memory>
-#include <boost/optional.hpp>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "common/common_types.h"
#include "core/hle/kernel/event.h"
namespace CoreTiming {
@@ -41,7 +45,7 @@ public:
~NVFlinger();
/// Opens the specified display and returns the id.
- u64 OpenDisplay(const std::string& name);
+ u64 OpenDisplay(std::string_view name);
/// Creates a layer on the specified display and returns the layer id.
u64 CreateLayer(u64 display_id);
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
new file mode 100644
index 000000000..39cf05eba
--- /dev/null
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -0,0 +1,64 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/pcie/pcie.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::PCIe {
+
+class ISession final : public ServiceFramework<ISession> {
+public:
+ explicit ISession() : ServiceFramework{"ISession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "QueryFunctions"},
+ {1, nullptr, "AcquireFunction"},
+ {2, nullptr, "ReleaseFunction"},
+ {3, nullptr, "GetFunctionState"},
+ {4, nullptr, "GetBarProfile"},
+ {5, nullptr, "ReadConfig"},
+ {6, nullptr, "WriteConfig"},
+ {7, nullptr, "ReadBarRegion"},
+ {8, nullptr, "WriteBarRegion"},
+ {9, nullptr, "FindCapability"},
+ {10, nullptr, "FindExtendedCapability"},
+ {11, nullptr, "MapDma"},
+ {12, nullptr, "UnmapDma"},
+ {13, nullptr, "UnmapDmaBusAddress"},
+ {14, nullptr, "GetDmaBusAddress"},
+ {15, nullptr, "GetDmaBusAddressRange"},
+ {16, nullptr, "SetDmaEnable"},
+ {17, nullptr, "AcquireIrq"},
+ {18, nullptr, "ReleaseIrq"},
+ {19, nullptr, "SetIrqEnable"},
+ {20, nullptr, "SetAspmEnable"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class PCIe final : public ServiceFramework<PCIe> {
+public:
+ explicit PCIe() : ServiceFramework{"pcie"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterClassDriver"},
+ {1, nullptr, "QueryFunctionsUnregistered"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<PCIe>()->InstallAsService(sm);
+}
+
+} // namespace Service::PCIe
diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h
new file mode 100644
index 000000000..59c22ca45
--- /dev/null
+++ b/src/core/hle/service/pcie/pcie.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::PCIe {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::PCIe
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
new file mode 100644
index 000000000..d6891a659
--- /dev/null
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -0,0 +1,84 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/pcv/pcv.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::PCV {
+
+class PCV final : public ServiceFramework<PCV> {
+public:
+ explicit PCV() : ServiceFramework{"pcv"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "SetPowerEnabled"},
+ {1, nullptr, "SetClockEnabled"},
+ {2, nullptr, "SetClockRate"},
+ {3, nullptr, "GetClockRate"},
+ {4, nullptr, "GetState"},
+ {5, nullptr, "GetPossibleClockRates"},
+ {6, nullptr, "SetMinVClockRate"},
+ {7, nullptr, "SetReset"},
+ {8, nullptr, "SetVoltageEnabled"},
+ {9, nullptr, "GetVoltageEnabled"},
+ {10, nullptr, "GetVoltageRange"},
+ {11, nullptr, "SetVoltageValue"},
+ {12, nullptr, "GetVoltageValue"},
+ {13, nullptr, "GetTemperatureThresholds"},
+ {14, nullptr, "SetTemperature"},
+ {15, nullptr, "Initialize"},
+ {16, nullptr, "IsInitialized"},
+ {17, nullptr, "Finalize"},
+ {18, nullptr, "PowerOn"},
+ {19, nullptr, "PowerOff"},
+ {20, nullptr, "ChangeVoltage"},
+ {21, nullptr, "GetPowerClockInfoEvent"},
+ {22, nullptr, "GetOscillatorClock"},
+ {23, nullptr, "GetDvfsTable"},
+ {24, nullptr, "GetModuleStateTable"},
+ {25, nullptr, "GetPowerDomainStateTable"},
+ {26, nullptr, "GetFuseInfo"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class PCV_ARB final : public ServiceFramework<PCV_ARB> {
+public:
+ explicit PCV_ARB() : ServiceFramework{"pcv:arb"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ReleaseControl"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class PCV_IMM final : public ServiceFramework<PCV_IMM> {
+public:
+ explicit PCV_IMM() : ServiceFramework{"pcv:imm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "SetClockRate"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<PCV>()->InstallAsService(sm);
+ std::make_shared<PCV_ARB>()->InstallAsService(sm);
+ std::make_shared<PCV_IMM>()->InstallAsService(sm);
+}
+
+} // namespace Service::PCV
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h
new file mode 100644
index 000000000..219a893c3
--- /dev/null
+++ b/src/core/hle/service/pcv/pcv.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::PCV {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::PCV
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
new file mode 100644
index 000000000..bbad870a2
--- /dev/null
+++ b/src/core/hle/service/psc/psc.cpp
@@ -0,0 +1,77 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/psc/psc.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::PSC {
+
+class PSC_C final : public ServiceFramework<PSC_C> {
+public:
+ explicit PSC_C() : ServiceFramework{"psc:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ {6, nullptr, "Unknown7"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IPmModule final : public ServiceFramework<IPmModule> {
+public:
+ explicit IPmModule() : ServiceFramework{"IPmModule"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "GetRequest"},
+ {2, nullptr, "Acknowledge"},
+ {3, nullptr, "Unknown1"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class PSC_M final : public ServiceFramework<PSC_M> {
+public:
+ explicit PSC_M() : ServiceFramework{"psc:m"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &PSC_M::GetPmModule, "GetPmModule"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetPmModule(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IPmModule>();
+
+ LOG_DEBUG(Service_PSC, "called");
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<PSC_C>()->InstallAsService(sm);
+ std::make_shared<PSC_M>()->InstallAsService(sm);
+}
+
+} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h
new file mode 100644
index 000000000..5052eb02c
--- /dev/null
+++ b/src/core/hle/service/psc/psc.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::PSC {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::PSC
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 8b84fd349..889cdd41a 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -19,28 +19,42 @@
#include "core/hle/service/am/am.h"
#include "core/hle/service/aoc/aoc_u.h"
#include "core/hle/service/apm/apm.h"
+#include "core/hle/service/arp/arp.h"
#include "core/hle/service/audio/audio.h"
#include "core/hle/service/bcat/bcat.h"
+#include "core/hle/service/bpc/bpc.h"
+#include "core/hle/service/btdrv/btdrv.h"
+#include "core/hle/service/btm/btm.h"
+#include "core/hle/service/caps/caps.h"
#include "core/hle/service/erpt/erpt.h"
#include "core/hle/service/es/es.h"
#include "core/hle/service/eupld/eupld.h"
#include "core/hle/service/fatal/fatal.h"
+#include "core/hle/service/fgm/fgm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/grc/grc.h"
#include "core/hle/service/hid/hid.h"
+#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/ldn/ldn.h"
#include "core/hle/service/ldr/ldr.h"
#include "core/hle/service/lm/lm.h"
+#include "core/hle/service/mig/mig.h"
+#include "core/hle/service/mii/mii.h"
#include "core/hle/service/mm/mm_u.h"
+#include "core/hle/service/ncm/ncm.h"
+#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nim/nim.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvdrv/nvdrv.h"
+#include "core/hle/service/pcie/pcie.h"
#include "core/hle/service/pctl/pctl.h"
+#include "core/hle/service/pcv/pcv.h"
#include "core/hle/service/pm/pm.h"
#include "core/hle/service/prepo/prepo.h"
+#include "core/hle/service/psc/psc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/set/settings.h"
#include "core/hle/service/sm/controller.h"
@@ -49,7 +63,9 @@
#include "core/hle/service/spl/module.h"
#include "core/hle/service/ssl/ssl.h"
#include "core/hle/service/time/time.h"
+#include "core/hle/service/usb/usb.h"
#include "core/hle/service/vi/vi.h"
+#include "core/hle/service/wlan/wlan.h"
using Kernel::ClientPort;
using Kernel::ServerPort;
@@ -193,34 +209,50 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
AM::InstallInterfaces(*sm, nv_flinger);
AOC::InstallInterfaces(*sm);
APM::InstallInterfaces(*sm);
- BCAT::InstallInterfaces(*sm);
+ ARP::InstallInterfaces(*sm);
Audio::InstallInterfaces(*sm);
+ BCAT::InstallInterfaces(*sm);
+ BPC::InstallInterfaces(*sm);
+ BtDrv::InstallInterfaces(*sm);
+ BTM::InstallInterfaces(*sm);
+ Capture::InstallInterfaces(*sm);
ERPT::InstallInterfaces(*sm);
ES::InstallInterfaces(*sm);
EUPLD::InstallInterfaces(*sm);
Fatal::InstallInterfaces(*sm);
+ FGM::InstallInterfaces(*sm);
FileSystem::InstallInterfaces(*sm);
Friend::InstallInterfaces(*sm);
GRC::InstallInterfaces(*sm);
HID::InstallInterfaces(*sm);
+ LBL::InstallInterfaces(*sm);
LDN::InstallInterfaces(*sm);
LDR::InstallInterfaces(*sm);
LM::InstallInterfaces(*sm);
+ Migration::InstallInterfaces(*sm);
+ Mii::InstallInterfaces(*sm);
MM::InstallInterfaces(*sm);
+ NCM::InstallInterfaces(*sm);
+ NFC::InstallInterfaces(*sm);
NFP::InstallInterfaces(*sm);
NIFM::InstallInterfaces(*sm);
NIM::InstallInterfaces(*sm);
NS::InstallInterfaces(*sm);
Nvidia::InstallInterfaces(*sm);
+ PCIe::InstallInterfaces(*sm);
PCTL::InstallInterfaces(*sm);
+ PCV::InstallInterfaces(*sm);
PlayReport::InstallInterfaces(*sm);
PM::InstallInterfaces(*sm);
+ PSC::InstallInterfaces(*sm);
+ Set::InstallInterfaces(*sm);
Sockets::InstallInterfaces(*sm);
SPL::InstallInterfaces(*sm);
SSL::InstallInterfaces(*sm);
Time::InstallInterfaces(*sm);
+ USB::InstallInterfaces(*sm);
VI::InstallInterfaces(*sm, nv_flinger);
- Set::InstallInterfaces(*sm);
+ WLAN::InstallInterfaces(*sm);
LOG_DEBUG(Service, "initialized OK");
}
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 180f22703..046c5e18d 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -8,10 +8,9 @@
#include <string>
#include <unordered_map>
#include <boost/container/flat_map.hpp>
-#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hle/kernel/hle_ipc.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace Service
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 1651f6122..a461e72ec 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -8,6 +8,7 @@
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/service/set/set.h"
+#include "core/settings.h"
namespace Service::Set {
@@ -31,6 +32,10 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
LanguageCode::ZH_HANT,
}};
+LanguageCode GetLanguageCodeFromIndex(size_t index) {
+ return available_language_codes.at(index);
+}
+
void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
ctx.WriteBuffer(available_language_codes);
@@ -49,9 +54,17 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
}
+void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index]));
+
+ LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index);
+}
+
SET::SET() : ServiceFramework("set") {
static const FunctionInfo functions[] = {
- {0, nullptr, "GetLanguageCode"},
+ {0, &SET::GetLanguageCode, "GetLanguageCode"},
{1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
{2, nullptr, "MakeLanguageCode"},
{3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"},
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h
index a2472ec4c..4232b6162 100644
--- a/src/core/hle/service/set/set.h
+++ b/src/core/hle/service/set/set.h
@@ -28,6 +28,7 @@ enum class LanguageCode : u64 {
ZH_HANS = 0x00736E61482D687A,
ZH_HANT = 0x00746E61482D687A,
};
+LanguageCode GetLanguageCodeFromIndex(size_t idx);
class SET final : public ServiceFramework<SET> {
public:
@@ -35,6 +36,7 @@ public:
~SET() = default;
private:
+ void GetLanguageCode(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx);
};
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index e2a00e4f6..e8ea62f08 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -4,9 +4,11 @@
#pragma once
+#include <memory>
#include <string>
#include <unordered_map>
-#include "core/hle/kernel/kernel.h"
+
+#include "core/hle/kernel/object.h"
#include "core/hle/result.h"
#include "core/hle/service/service.h"
@@ -19,6 +21,8 @@ class SessionRequestHandler;
namespace Service::SM {
+class Controller;
+
/// Interface to "sm:" service
class SM final : public ServiceFramework<SM> {
public:
@@ -32,8 +36,6 @@ private:
std::shared_ptr<ServiceManager> service_manager;
};
-class Controller;
-
constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1);
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
constexpr ResultCode ERR_INVALID_NAME_SIZE(-1);
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 37b58bb77..2172c681b 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -80,8 +80,8 @@ public:
{5, nullptr, "GetTimeZoneRuleVersion"},
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
- {200, nullptr, "ToPosixTime"},
- {201, nullptr, "ToPosixTimeWithMyRule"},
+ {201, nullptr, "ToPosixTime"},
+ {202, nullptr, "ToPosixTimeWithMyRule"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
new file mode 100644
index 000000000..e7fb5a419
--- /dev/null
+++ b/src/core/hle/service/usb/usb.cpp
@@ -0,0 +1,238 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/usb/usb.h"
+
+namespace Service::USB {
+
+class IDsInterface final : public ServiceFramework<IDsInterface> {
+public:
+ explicit IDsInterface() : ServiceFramework{"IDsInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetDsEndpoint"},
+ {1, nullptr, "GetSetupEvent"},
+ {2, nullptr, "Unknown"},
+ {3, nullptr, "EnableInterface"},
+ {4, nullptr, "DisableInterface"},
+ {5, nullptr, "CtrlInPostBufferAsync"},
+ {6, nullptr, "CtrlOutPostBufferAsync"},
+ {7, nullptr, "GetCtrlInCompletionEvent"},
+ {8, nullptr, "GetCtrlInReportData"},
+ {9, nullptr, "GetCtrlOutCompletionEvent"},
+ {10, nullptr, "GetCtrlOutReportData"},
+ {11, nullptr, "StallCtrl"},
+ {12, nullptr, "AppendConfigurationData"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_DS final : public ServiceFramework<USB_DS> {
+public:
+ explicit USB_DS() : ServiceFramework{"usb:ds"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindDevice"},
+ {1, nullptr, "BindClientProcess"},
+ {2, nullptr, "GetDsInterface"},
+ {3, nullptr, "GetStateChangeEvent"},
+ {4, nullptr, "GetState"},
+ {5, nullptr, "ClearDeviceData"},
+ {6, nullptr, "AddUsbStringDescriptor"},
+ {7, nullptr, "DeleteUsbStringDescriptor"},
+ {8, nullptr, "SetUsbDeviceDescriptor"},
+ {9, nullptr, "SetBinaryObjectStore"},
+ {10, nullptr, "Enable"},
+ {11, nullptr, "Disable"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IClientEpSession final : public ServiceFramework<IClientEpSession> {
+public:
+ explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "PostBufferAsync"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "Unknown7"},
+ {8, nullptr, "Unknown8"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IClientIfSession final : public ServiceFramework<IClientIfSession> {
+public:
+ explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "CtrlXferAsync"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "GetCtrlXferReport"},
+ {8, nullptr, "Unknown7"},
+ {9, nullptr, "GetClientEpSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_HS final : public ServiceFramework<USB_HS> {
+public:
+ explicit USB_HS() : ServiceFramework{"usb:hs"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindClientProcess"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "GetInterfaceStateChangeEvent"},
+ {7, nullptr, "GetClientIfSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IPdSession final : public ServiceFramework<IPdSession> {
+public:
+ explicit IPdSession() : ServiceFramework{"IPdSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindNoticeEvent"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "GetStatus"},
+ {3, nullptr, "GetNotice"},
+ {4, nullptr, "Unknown2"},
+ {5, nullptr, "Unknown3"},
+ {6, nullptr, "ReplyPowerRequest"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_PD final : public ServiceFramework<USB_PD> {
+public:
+ explicit USB_PD() : ServiceFramework{"usb:pd"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &USB_PD::GetPdSession, "GetPdSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetPdSession(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IPdSession>();
+
+ LOG_DEBUG(Service_USB, "called");
+ }
+};
+
+class IPdCradleSession final : public ServiceFramework<IPdCradleSession> {
+public:
+ explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "VdmUserWrite"},
+ {1, nullptr, "VdmUserRead"},
+ {2, nullptr, "Vdm20Init"},
+ {3, nullptr, "GetFwType"},
+ {4, nullptr, "GetFwRevision"},
+ {5, nullptr, "GetManufacturerId"},
+ {6, nullptr, "GetDeviceId"},
+ {7, nullptr, "Unknown1"},
+ {8, nullptr, "Unknown2"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_PD_C final : public ServiceFramework<USB_PD_C> {
+public:
+ explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetPdCradleSession(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IPdCradleSession>();
+
+ LOG_DEBUG(Service_USB, "called");
+ }
+};
+
+class USB_PM final : public ServiceFramework<USB_PM> {
+public:
+ explicit USB_PM() : ServiceFramework{"usb:pm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<USB_DS>()->InstallAsService(sm);
+ std::make_shared<USB_HS>()->InstallAsService(sm);
+ std::make_shared<USB_PD>()->InstallAsService(sm);
+ std::make_shared<USB_PD_C>()->InstallAsService(sm);
+ std::make_shared<USB_PM>()->InstallAsService(sm);
+}
+
+} // namespace Service::USB
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h
new file mode 100644
index 000000000..970a11fe8
--- /dev/null
+++ b/src/core/hle/service/usb/usb.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::USB {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::USB
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp
new file mode 100644
index 000000000..2654594c1
--- /dev/null
+++ b/src/core/hle/service/wlan/wlan.cpp
@@ -0,0 +1,172 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/wlan/wlan.h"
+
+namespace Service::WLAN {
+
+class WLANInfra final : public ServiceFramework<WLANInfra> {
+public:
+ explicit WLANInfra() : ServiceFramework{"wlan:inf"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "GetMacAddress"},
+ {3, nullptr, "StartScan"},
+ {4, nullptr, "StopScan"},
+ {5, nullptr, "Connect"},
+ {6, nullptr, "CancelConnect"},
+ {7, nullptr, "Disconnect"},
+ {8, nullptr, "Unknown3"},
+ {9, nullptr, "Unknown4"},
+ {10, nullptr, "GetState"},
+ {11, nullptr, "GetScanResult"},
+ {12, nullptr, "GetRssi"},
+ {13, nullptr, "ChangeRxAntenna"},
+ {14, nullptr, "Unknown5"},
+ {15, nullptr, "Unknown6"},
+ {16, nullptr, "RequestWakeUp"},
+ {17, nullptr, "RequestIfUpDown"},
+ {18, nullptr, "Unknown7"},
+ {19, nullptr, "Unknown8"},
+ {20, nullptr, "Unknown9"},
+ {21, nullptr, "Unknown10"},
+ {22, nullptr, "Unknown11"},
+ {23, nullptr, "Unknown12"},
+ {24, nullptr, "Unknown13"},
+ {25, nullptr, "Unknown14"},
+ {26, nullptr, "Unknown15"},
+ {27, nullptr, "Unknown16"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class WLANLocal final : public ServiceFramework<WLANLocal> {
+public:
+ explicit WLANLocal() : ServiceFramework{"wlan:lcl"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ {6, nullptr, "GetMacAddress"},
+ {7, nullptr, "CreateBss"},
+ {8, nullptr, "DestroyBss"},
+ {9, nullptr, "StartScan"},
+ {10, nullptr, "StopScan"},
+ {11, nullptr, "Connect"},
+ {12, nullptr, "CancelConnect"},
+ {13, nullptr, "Join"},
+ {14, nullptr, "CancelJoin"},
+ {15, nullptr, "Disconnect"},
+ {16, nullptr, "SetBeaconLostCount"},
+ {17, nullptr, "Unknown7"},
+ {18, nullptr, "Unknown8"},
+ {19, nullptr, "Unknown9"},
+ {20, nullptr, "GetBssIndicationEvent"},
+ {21, nullptr, "GetBssIndicationInfo"},
+ {22, nullptr, "GetState"},
+ {23, nullptr, "GetAllowedChannels"},
+ {24, nullptr, "AddIe"},
+ {25, nullptr, "DeleteIe"},
+ {26, nullptr, "Unknown10"},
+ {27, nullptr, "Unknown11"},
+ {28, nullptr, "CreateRxEntry"},
+ {29, nullptr, "DeleteRxEntry"},
+ {30, nullptr, "Unknown12"},
+ {31, nullptr, "Unknown13"},
+ {32, nullptr, "AddMatchingDataToRxEntry"},
+ {33, nullptr, "RemoveMatchingDataFromRxEntry"},
+ {34, nullptr, "GetScanResult"},
+ {35, nullptr, "Unknown14"},
+ {36, nullptr, "SetActionFrameWithBeacon"},
+ {37, nullptr, "CancelActionFrameWithBeacon"},
+ {38, nullptr, "CreateRxEntryForActionFrame"},
+ {39, nullptr, "DeleteRxEntryForActionFrame"},
+ {40, nullptr, "Unknown15"},
+ {41, nullptr, "Unknown16"},
+ {42, nullptr, "CancelGetActionFrame"},
+ {43, nullptr, "GetRssi"},
+ {44, nullptr, "Unknown17"},
+ {45, nullptr, "Unknown18"},
+ {46, nullptr, "Unknown19"},
+ {47, nullptr, "Unknown20"},
+ {48, nullptr, "Unknown21"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> {
+public:
+ explicit WLANLocalGetFrame() : ServiceFramework{"wlan:lg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> {
+public:
+ explicit WLANSocketGetFrame() : ServiceFramework{"wlan:sg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class WLANSocketManager final : public ServiceFramework<WLANSocketManager> {
+public:
+ explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ {6, nullptr, "GetMacAddress"},
+ {7, nullptr, "SwitchTsfTimerFunction"},
+ {8, nullptr, "Unknown7"},
+ {9, nullptr, "Unknown8"},
+ {10, nullptr, "Unknown9"},
+ {11, nullptr, "Unknown10"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<WLANInfra>()->InstallAsService(sm);
+ std::make_shared<WLANLocal>()->InstallAsService(sm);
+ std::make_shared<WLANLocalGetFrame>()->InstallAsService(sm);
+ std::make_shared<WLANSocketGetFrame>()->InstallAsService(sm);
+ std::make_shared<WLANSocketManager>()->InstallAsService(sm);
+}
+
+} // namespace Service::WLAN
diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h
new file mode 100644
index 000000000..054ea928a
--- /dev/null
+++ b/src/core/hle/service/wlan/wlan.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::WLAN {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::WLAN
diff --git a/src/core/hw/aes/ccm.cpp b/src/core/hw/aes/ccm.cpp
deleted file mode 100644
index 1ee37aaa4..000000000
--- a/src/core/hw/aes/ccm.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include "common/alignment.h"
-#include "common/assert.h"
-#include "common/logging/log.h"
-#include "core/hw/aes/ccm.h"
-#include "core/hw/aes/key.h"
-
-namespace HW {
-namespace AES {
-
-std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce,
- size_t slot_id) {
- UNIMPLEMENTED();
- return {};
-}
-
-std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce,
- size_t slot_id) {
- UNIMPLEMENTED();
- return {};
-}
-
-} // namespace AES
-} // namespace HW
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
deleted file mode 100644
index 2f48068c1..000000000
--- a/src/core/hw/hw.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/hw/hw.h"
-#include "core/hw/lcd.h"
-
-namespace HW {
-
-template <typename T>
-inline void Read(T& var, const u32 addr) {
- switch (addr & 0xFFFFF000) {
- case VADDR_GPU:
- case VADDR_GPU + 0x1000:
- case VADDR_GPU + 0x2000:
- case VADDR_GPU + 0x3000:
- case VADDR_GPU + 0x4000:
- case VADDR_GPU + 0x5000:
- case VADDR_GPU + 0x6000:
- case VADDR_GPU + 0x7000:
- case VADDR_GPU + 0x8000:
- case VADDR_GPU + 0x9000:
- case VADDR_GPU + 0xA000:
- case VADDR_GPU + 0xB000:
- case VADDR_GPU + 0xC000:
- case VADDR_GPU + 0xD000:
- case VADDR_GPU + 0xE000:
- case VADDR_GPU + 0xF000:
- break;
- case VADDR_LCD:
- LCD::Read(var, addr);
- break;
- default:
- LOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
- break;
- }
-}
-
-template <typename T>
-inline void Write(u32 addr, const T data) {
- switch (addr & 0xFFFFF000) {
- case VADDR_GPU:
- case VADDR_GPU + 0x1000:
- case VADDR_GPU + 0x2000:
- case VADDR_GPU + 0x3000:
- case VADDR_GPU + 0x4000:
- case VADDR_GPU + 0x5000:
- case VADDR_GPU + 0x6000:
- case VADDR_GPU + 0x7000:
- case VADDR_GPU + 0x8000:
- case VADDR_GPU + 0x9000:
- case VADDR_GPU + 0xA000:
- case VADDR_GPU + 0xB000:
- case VADDR_GPU + 0xC000:
- case VADDR_GPU + 0xD000:
- case VADDR_GPU + 0xE000:
- case VADDR_GPU + 0xF000:
- break;
- case VADDR_LCD:
- LCD::Write(addr, data);
- break;
- default:
- LOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
- break;
- }
-}
-
-// Explicitly instantiate template functions because we aren't defining this in the header:
-
-template void Read<u64>(u64& var, const u32 addr);
-template void Read<u32>(u32& var, const u32 addr);
-template void Read<u16>(u16& var, const u32 addr);
-template void Read<u8>(u8& var, const u32 addr);
-
-template void Write<u64>(u32 addr, const u64 data);
-template void Write<u32>(u32 addr, const u32 data);
-template void Write<u16>(u32 addr, const u16 data);
-template void Write<u8>(u32 addr, const u8 data);
-
-/// Update hardware
-void Update() {}
-
-/// Initialize hardware
-void Init() {
- LCD::Init();
- LOG_DEBUG(HW, "Initialized OK");
-}
-
-/// Shutdown hardware
-void Shutdown() {
- LCD::Shutdown();
- LOG_DEBUG(HW, "Shutdown OK");
-}
-} // namespace HW
diff --git a/src/core/hw/hw.h b/src/core/hw/hw.h
deleted file mode 100644
index 5890d2b5c..000000000
--- a/src/core/hw/hw.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "common/common_types.h"
-
-namespace HW {
-
-/// Beginnings of IO register regions, in the user VA space.
-enum : u32 {
- VADDR_HASH = 0x1EC01000,
- VADDR_CSND = 0x1EC03000,
- VADDR_DSP = 0x1EC40000,
- VADDR_PDN = 0x1EC41000,
- VADDR_CODEC = 0x1EC41000,
- VADDR_SPI = 0x1EC42000,
- VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM?
- VADDR_I2C = 0x1EC44000,
- VADDR_CODEC_2 = 0x1EC45000,
- VADDR_HID = 0x1EC46000,
- VADDR_GPIO = 0x1EC47000,
- VADDR_I2C_2 = 0x1EC48000,
- VADDR_SPI_3 = 0x1EC60000,
- VADDR_I2C_3 = 0x1EC61000,
- VADDR_MIC = 0x1EC62000,
- VADDR_PXI = 0x1EC63000,
- VADDR_LCD = 0x1ED02000,
- VADDR_DSP_2 = 0x1ED03000,
- VADDR_HASH_2 = 0x1EE01000,
- VADDR_GPU = 0x1EF00000,
-};
-
-template <typename T>
-void Read(T& var, const u32 addr);
-
-template <typename T>
-void Write(u32 addr, const T data);
-
-/// Update hardware
-void Update();
-
-/// Initialize hardware
-void Init();
-
-/// Shutdown hardware
-void Shutdown();
-
-} // namespace HW
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
deleted file mode 100644
index 0b62174d5..000000000
--- a/src/core/hw/lcd.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <cstring>
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/hw/hw.h"
-#include "core/hw/lcd.h"
-#include "core/tracer/recorder.h"
-
-namespace LCD {
-
-Regs g_regs;
-
-template <typename T>
-inline void Read(T& var, const u32 raw_addr) {
- u32 addr = raw_addr - HW::VADDR_LCD;
- u32 index = addr / 4;
-
- // Reads other than u32 are untested, so I'd rather have them abort than silently fail
- if (index >= 0x400 || !std::is_same<T, u32>::value) {
- LOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
- return;
- }
-
- var = g_regs[index];
-}
-
-template <typename T>
-inline void Write(u32 addr, const T data) {
- addr -= HW::VADDR_LCD;
- u32 index = addr / 4;
-
- // Writes other than u32 are untested, so I'd rather have them abort than silently fail
- if (index >= 0x400 || !std::is_same<T, u32>::value) {
- LOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
- return;
- }
-
- g_regs[index] = static_cast<u32>(data);
-}
-
-// Explicitly instantiate template functions because we aren't defining this in the header:
-
-template void Read<u64>(u64& var, const u32 addr);
-template void Read<u32>(u32& var, const u32 addr);
-template void Read<u16>(u16& var, const u32 addr);
-template void Read<u8>(u8& var, const u32 addr);
-
-template void Write<u64>(u32 addr, const u64 data);
-template void Write<u32>(u32 addr, const u32 data);
-template void Write<u16>(u32 addr, const u16 data);
-template void Write<u8>(u32 addr, const u8 data);
-
-/// Initialize hardware
-void Init() {
- memset(&g_regs, 0, sizeof(g_regs));
- LOG_DEBUG(HW_LCD, "Initialized OK");
-}
-
-/// Shutdown hardware
-void Shutdown() {
- LOG_DEBUG(HW_LCD, "Shutdown OK");
-}
-
-} // namespace LCD
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
deleted file mode 100644
index d2db9700f..000000000
--- a/src/core/hw/lcd.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2015 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <cstddef>
-#include <type_traits>
-#include "common/bit_field.h"
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-
-#define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32))
-
-namespace LCD {
-
-struct Regs {
-
- union ColorFill {
- u32 raw;
-
- BitField<0, 8, u32> color_r;
- BitField<8, 8, u32> color_g;
- BitField<16, 8, u32> color_b;
- BitField<24, 1, u32> is_enabled;
- };
-
- INSERT_PADDING_WORDS(0x81);
- ColorFill color_fill_top;
- INSERT_PADDING_WORDS(0xE);
- u32 backlight_top;
-
- INSERT_PADDING_WORDS(0x1F0);
-
- ColorFill color_fill_bottom;
- INSERT_PADDING_WORDS(0xE);
- u32 backlight_bottom;
- INSERT_PADDING_WORDS(0x16F);
-
- static constexpr size_t NumIds() {
- return sizeof(Regs) / sizeof(u32);
- }
-
- const u32& operator[](int index) const {
- const u32* content = reinterpret_cast<const u32*>(this);
- return content[index];
- }
-
- u32& operator[](int index) {
- u32* content = reinterpret_cast<u32*>(this);
- return content[index];
- }
-};
-static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout");
-
-// TODO: MSVC does not support using offsetof() on non-static data members even though this
-// is technically allowed since C++11. This macro should be enabled once MSVC adds
-// support for that.
-#ifndef _MSC_VER
-#define ASSERT_REG_POSITION(field_name, position) \
- static_assert(offsetof(Regs, field_name) == position * 4, \
- "Field " #field_name " has invalid position")
-
-ASSERT_REG_POSITION(color_fill_top, 0x81);
-ASSERT_REG_POSITION(backlight_top, 0x90);
-ASSERT_REG_POSITION(color_fill_bottom, 0x281);
-ASSERT_REG_POSITION(backlight_bottom, 0x290);
-
-#undef ASSERT_REG_POSITION
-#endif // !defined(_MSC_VER)
-
-extern Regs g_regs;
-
-template <typename T>
-void Read(T& var, const u32 addr);
-
-template <typename T>
-void Write(u32 addr, const T data);
-
-/// Initialize hardware
-void Init();
-
-/// Shutdown hardware
-void Shutdown();
-
-} // namespace LCD
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index b0277a875..9a8cdd0ff 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -20,6 +20,10 @@ namespace Loader {
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
: AppLoader(std::move(file)) {}
+AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
+ FileSys::VirtualDir directory)
+ : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {}
+
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
return FileType::DeconstructedRomDirectory;
@@ -34,7 +38,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
return ResultStatus::ErrorAlreadyLoaded;
}
- const FileSys::VirtualDir dir = file->GetContainingDirectory();
+ if (dir == nullptr) {
+ if (file == nullptr)
+ return ResultStatus::ErrorInvalidFormat;
+ dir = file->GetContainingDirectory();
+ }
+
const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
if (npdm == nullptr)
return ResultStatus::ErrorInvalidFormat;
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h
index 982a037f7..7d5433563 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -7,7 +7,7 @@
#include <string>
#include "common/common_types.h"
#include "core/file_sys/program_metadata.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/loader/loader.h"
namespace Loader {
@@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public:
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file);
+ // Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
+ explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory);
+
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
@@ -40,6 +43,7 @@ public:
private:
FileSys::ProgramMetadata metadata;
FileSys::VirtualFile romfs;
+ FileSys::VirtualDir dir;
};
} // namespace Loader
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 352938dcb..a7133f5a6 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -311,11 +311,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
CodeSet::Segment* codeset_segment;
u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
if (permission_flags == (PF_R | PF_X)) {
- codeset_segment = &codeset->code;
+ codeset_segment = &codeset->CodeSegment();
} else if (permission_flags == (PF_R)) {
- codeset_segment = &codeset->rodata;
+ codeset_segment = &codeset->RODataSegment();
} else if (permission_flags == (PF_R | PF_W)) {
- codeset_segment = &codeset->data;
+ codeset_segment = &codeset->DataSegment();
} else {
LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
p->p_flags);
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index cbc4177c6..57e6c0365 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -13,6 +13,7 @@
#include "core/loader/nca.h"
#include "core/loader/nro.h"
#include "core/loader/nso.h"
+#include "core/loader/xci.h"
namespace Loader {
@@ -35,6 +36,7 @@ FileType IdentifyFile(FileSys::VirtualFile file) {
CHECK_TYPE(NSO)
CHECK_TYPE(NRO)
CHECK_TYPE(NCA)
+ CHECK_TYPE(XCI)
#undef CHECK_TYPE
@@ -60,6 +62,8 @@ FileType GuessFromFilename(const std::string& name) {
return FileType::NSO;
if (extension == "nca")
return FileType::NCA;
+ if (extension == "xci")
+ return FileType::XCI;
return FileType::Unknown;
}
@@ -74,6 +78,8 @@ const char* GetFileTypeString(FileType type) {
return "NSO";
case FileType::NCA:
return "NCA";
+ case FileType::XCI:
+ return "XCI";
case FileType::DeconstructedRomDirectory:
return "Directory";
case FileType::Error:
@@ -111,6 +117,9 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
case FileType::NCA:
return std::make_unique<AppLoader_NCA>(std::move(file));
+ case FileType::XCI:
+ return std::make_unique<AppLoader_XCI>(std::move(file));
+
// NX deconstructed ROM directory.
case FileType::DeconstructedRomDirectory:
return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file));
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index fbf11e5d0..e69ab85ef 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -14,7 +14,7 @@
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/vfs.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
namespace Kernel {
struct AddressMapping;
@@ -31,6 +31,7 @@ enum class FileType {
NSO,
NRO,
NCA,
+ XCI,
DeconstructedRomDirectory,
};
@@ -72,7 +73,8 @@ enum class ResultStatus {
ErrorNotUsed,
ErrorAlreadyLoaded,
ErrorMemoryAllocationFailed,
- ErrorEncrypted,
+ ErrorMissingKeys,
+ ErrorDecrypting,
ErrorUnsupportedArch,
};
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index c80df23be..dbc67c0b5 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -22,15 +22,14 @@
namespace Loader {
-AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
+AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_)
+ : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {}
FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
- // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support.
- FileSys::NCAHeader header{};
- if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header))
- return FileType::Error;
+ FileSys::NCA nca(file);
- if (IsValidNCA(header) && header.content_type == FileSys::NCAContentType::Program)
+ if (nca.GetStatus() == ResultStatus::Success &&
+ nca.GetType() == FileSys::NCAContentType::Program)
return FileType::NCA;
return FileType::Error;
@@ -41,8 +40,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::ErrorAlreadyLoaded;
}
- nca = std::make_unique<FileSys::NCA>(file);
- ResultStatus result = nca->GetStatus();
+ const auto result = nca->GetStatus();
if (result != ResultStatus::Success) {
return result;
}
@@ -50,44 +48,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
if (nca->GetType() != FileSys::NCAContentType::Program)
return ResultStatus::ErrorInvalidFormat;
- auto exefs = nca->GetExeFS();
+ const auto exefs = nca->GetExeFS();
if (exefs == nullptr)
return ResultStatus::ErrorInvalidFormat;
- result = metadata.Load(exefs->GetFile("main.npdm"));
- if (result != ResultStatus::Success) {
- return result;
- }
- metadata.Print();
-
- const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
- if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
- return ResultStatus::ErrorUnsupportedArch;
- }
+ directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs);
- VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
- for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
- "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
- const VAddr load_addr = next_load_addr;
-
- next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr);
- if (next_load_addr) {
- LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
- // Register module with GDBStub
- GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
- } else {
- next_load_addr = load_addr;
- }
- }
-
- process->program_id = metadata.GetTitleID();
- process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
- process->resource_limit =
- Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
- metadata.GetMainThreadStackSize());
+ const auto load_result = directory_loader->Load(process);
+ if (load_result != ResultStatus::Success)
+ return load_result;
if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0)
Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this));
@@ -98,12 +68,21 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
}
ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
- if (nca == nullptr || nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
+ if (nca == nullptr)
+ return ResultStatus::ErrorNotLoaded;
+ if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
return ResultStatus::ErrorNotUsed;
dir = nca->GetRomFS();
return ResultStatus::Success;
}
+ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
+ if (nca == nullptr)
+ return ResultStatus::ErrorNotLoaded;
+ out_program_id = nca->GetTitleId();
+ return ResultStatus::Success;
+}
+
AppLoader_NCA::~AppLoader_NCA() = default;
} // namespace Loader
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index 52c95953a..0fd2d0417 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -8,8 +8,9 @@
#include "common/common_types.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/program_metadata.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/loader/loader.h"
+#include "deconstructed_rom_directory.h"
namespace Loader {
@@ -33,12 +34,15 @@ public:
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
+ ResultStatus ReadProgramId(u64& out_program_id) override;
+
~AppLoader_NCA();
private:
FileSys::ProgramMetadata metadata;
std::unique_ptr<FileSys::NCA> nca;
+ std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
};
} // namespace Loader
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 7d3ec2a76..dc053cdad 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -159,7 +159,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
// Resize program image to include .bss section and page align each section
bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
}
- codeset->data.size += bss_size;
+ codeset->DataSegment().size += bss_size;
program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
// Load codeset for current process
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h
index 04a0f497e..bb01c9e25 100644
--- a/src/core/loader/nro.h
+++ b/src/core/loader/nro.h
@@ -6,7 +6,7 @@
#include <string>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/loader/linker.h"
#include "core/loader/loader.h"
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 06b1b33f4..fee7d58c6 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -127,7 +127,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
// Resize program image to include .bss section and page align each section
bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
}
- codeset->data.size += bss_size;
+ codeset->DataSegment().size += bss_size;
const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
program_image.resize(image_size);
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h
index 3f7567500..aaeb1f2a9 100644
--- a/src/core/loader/nso.h
+++ b/src/core/loader/nso.h
@@ -6,7 +6,7 @@
#include <string>
#include "common/common_types.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
#include "core/loader/linker.h"
#include "core/loader/loader.h"
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
new file mode 100644
index 000000000..eb4dee2c2
--- /dev/null
+++ b/src/core/loader/xci.cpp
@@ -0,0 +1,74 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <vector>
+
+#include "common/file_util.h"
+#include "common/logging/log.h"
+#include "common/string_util.h"
+#include "common/swap.h"
+#include "core/core.h"
+#include "core/file_sys/content_archive.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/program_metadata.h"
+#include "core/file_sys/romfs.h"
+#include "core/gdbstub/gdbstub.h"
+#include "core/hle/kernel/process.h"
+#include "core/hle/kernel/resource_limit.h"
+#include "core/hle/service/filesystem/filesystem.h"
+#include "core/loader/nso.h"
+#include "core/loader/xci.h"
+#include "core/memory.h"
+
+namespace Loader {
+
+AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
+ : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
+ nca_loader(std::make_unique<AppLoader_NCA>(
+ xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {}
+
+AppLoader_XCI::~AppLoader_XCI() = default;
+
+FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) {
+ FileSys::XCI xci(file);
+
+ if (xci.GetStatus() == ResultStatus::Success &&
+ xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr &&
+ AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) ==
+ FileType::NCA) {
+ return FileType::XCI;
+ }
+
+ return FileType::Error;
+}
+
+ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
+ if (is_loaded) {
+ return ResultStatus::ErrorAlreadyLoaded;
+ }
+
+ if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) {
+ if (!Core::Crypto::KeyManager::KeyFileExists(false))
+ return ResultStatus::ErrorMissingKeys;
+ return ResultStatus::ErrorDecrypting;
+ }
+
+ auto result = nca_loader->Load(process);
+ if (result != ResultStatus::Success)
+ return result;
+
+ is_loaded = true;
+
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) {
+ return nca_loader->ReadRomFS(dir);
+}
+
+ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
+ return nca_loader->ReadProgramId(out_program_id);
+}
+
+} // namespace Loader
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
new file mode 100644
index 000000000..0dbcfbdf8
--- /dev/null
+++ b/src/core/loader/xci.h
@@ -0,0 +1,44 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include "common/common_types.h"
+#include "core/file_sys/card_image.h"
+#include "core/loader/loader.h"
+#include "core/loader/nca.h"
+
+namespace Loader {
+
+/// Loads an XCI file
+class AppLoader_XCI final : public AppLoader {
+public:
+ explicit AppLoader_XCI(FileSys::VirtualFile file);
+ ~AppLoader_XCI();
+
+ /**
+ * Returns the type of the file
+ * @param file std::shared_ptr<VfsFile> open file
+ * @return FileType found, or FileType::Error if this loader doesn't know it
+ */
+ static FileType IdentifyType(const FileSys::VirtualFile& file);
+
+ FileType GetFileType() override {
+ return IdentifyType(file);
+ }
+
+ ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
+
+ ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
+ ResultStatus ReadProgramId(u64& out_program_id) override;
+
+private:
+ FileSys::ProgramMetadata metadata;
+
+ std::unique_ptr<FileSys::XCI> xci;
+ std::unique_ptr<AppLoader_NCA> nca_loader;
+};
+
+} // namespace Loader
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e753e3436..1133bcbaf 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,7 +14,6 @@
#include "common/swap.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
-#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/lock.h"
#include "core/memory.h"
@@ -24,8 +23,6 @@
namespace Memory {
-static std::array<u8, Memory::VRAM_SIZE> vram;
-
static PageTable* current_page_table = nullptr;
void SetCurrentPageTable(PageTable* page_table) {
@@ -102,22 +99,6 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
}
/**
- * This function should only be called for virtual addreses with attribute `PageType::Special`.
- */
-static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_table, VAddr vaddr,
- u64 size) {
- std::set<MemoryHookPointer> result;
- auto interval = boost::icl::discrete_interval<VAddr>::closed(vaddr, vaddr + size - 1);
- auto interval_list = page_table.special_regions.equal_range(interval);
- for (auto it = interval_list.first; it != interval_list.second; ++it) {
- for (const auto& region : it->second) {
- result.insert(region.handler);
- }
- }
- return result;
-}
-
-/**
* Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
* using a VMA from the current process
*/
@@ -242,10 +223,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
}
-bool IsValidPhysicalAddress(const PAddr paddr) {
- return GetPhysicalPointer(paddr) != nullptr;
-}
-
u8* GetPointer(const VAddr vaddr) {
u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
if (page_pointer) {
@@ -274,61 +251,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) {
return string;
}
-u8* GetPhysicalPointer(PAddr address) {
- struct MemoryArea {
- PAddr paddr_base;
- u32 size;
- };
-
- static constexpr MemoryArea memory_areas[] = {
- {VRAM_PADDR, VRAM_SIZE},
- {IO_AREA_PADDR, IO_AREA_SIZE},
- {DSP_RAM_PADDR, DSP_RAM_SIZE},
- {FCRAM_PADDR, FCRAM_N3DS_SIZE},
- };
-
- const auto area =
- std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) {
- return address >= area.paddr_base && address < area.paddr_base + area.size;
- });
-
- if (area == std::end(memory_areas)) {
- LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
- return nullptr;
- }
-
- if (area->paddr_base == IO_AREA_PADDR) {
- LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
- return nullptr;
- }
-
- u64 offset_into_region = address - area->paddr_base;
-
- u8* target_pointer = nullptr;
- switch (area->paddr_base) {
- case VRAM_PADDR:
- target_pointer = vram.data() + offset_into_region;
- break;
- case DSP_RAM_PADDR:
- break;
- case FCRAM_PADDR:
- for (const auto& region : Kernel::memory_regions) {
- if (offset_into_region >= region.base &&
- offset_into_region < region.base + region.size) {
- target_pointer =
- region.linear_heap_memory->data() + offset_into_region - region.base;
- break;
- }
- }
- ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
- break;
- default:
- UNREACHABLE();
- }
-
- return target_pointer;
-}
-
void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
if (gpu_addr == 0) {
return;
@@ -404,43 +326,45 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached)
}
void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
+ auto& system_instance = Core::System::GetInstance();
+
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
- if (VideoCore::g_renderer == nullptr) {
+ if (!system_instance.IsPoweredOn()) {
return;
}
VAddr end = start + size;
- auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
+ const auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
if (start >= region_end || end <= region_start) {
// No overlap with region
return;
}
- VAddr overlap_start = std::max(start, region_start);
- VAddr overlap_end = std::min(end, region_end);
+ const VAddr overlap_start = std::max(start, region_start);
+ const VAddr overlap_end = std::min(end, region_end);
- std::vector<Tegra::GPUVAddr> gpu_addresses =
- Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start);
+ const std::vector<Tegra::GPUVAddr> gpu_addresses =
+ system_instance.GPU().memory_manager->CpuToGpuAddress(overlap_start);
if (gpu_addresses.empty()) {
return;
}
- u64 overlap_size = overlap_end - overlap_start;
+ const u64 overlap_size = overlap_end - overlap_start;
for (const auto& gpu_address : gpu_addresses) {
- auto* rasterizer = VideoCore::g_renderer->Rasterizer();
+ auto& rasterizer = system_instance.Renderer().Rasterizer();
switch (mode) {
case FlushMode::Flush:
- rasterizer->FlushRegion(gpu_address, overlap_size);
+ rasterizer.FlushRegion(gpu_address, overlap_size);
break;
case FlushMode::Invalidate:
- rasterizer->InvalidateRegion(gpu_address, overlap_size);
+ rasterizer.InvalidateRegion(gpu_address, overlap_size);
break;
case FlushMode::FlushAndInvalidate:
- rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size);
+ rasterizer.FlushAndInvalidateRegion(gpu_address, overlap_size);
break;
}
}
@@ -666,48 +590,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
}
-boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
- if (addr == 0) {
- return 0;
- } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) {
- return addr - VRAM_VADDR + VRAM_PADDR;
- } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) {
- return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR;
- } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) {
- return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR;
- } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) {
- return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
- } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
- return addr - IO_AREA_VADDR + IO_AREA_PADDR;
- }
-
- return boost::none;
-}
-
-PAddr VirtualToPhysicalAddress(const VAddr addr) {
- auto paddr = TryVirtualToPhysicalAddress(addr);
- if (!paddr) {
- LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
- // To help with debugging, set bit on address so that it's obviously invalid.
- return addr | 0x80000000;
- }
- return *paddr;
-}
-
-boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
- if (addr == 0) {
- return 0;
- } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
- return addr - VRAM_PADDR + VRAM_VADDR;
- } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
- return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
- } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
- return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
- } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
- return addr - IO_AREA_PADDR + IO_AREA_VADDR;
- }
-
- return boost::none;
-}
-
} // namespace Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 8d5d017a4..b7fb3b9ed 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -6,12 +6,9 @@
#include <array>
#include <cstddef>
-#include <map>
#include <string>
#include <tuple>
-#include <vector>
#include <boost/icl/interval_map.hpp>
-#include <boost/optional.hpp>
#include "common/common_types.h"
#include "core/memory_hook.h"
#include "video_core/memory_manager.h"
@@ -85,40 +82,6 @@ struct PageTable {
std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
};
-/// Physical memory regions as seen from the ARM11
-enum : PAddr {
- /// IO register area
- IO_AREA_PADDR = 0x10100000,
- IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB)
- IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE,
-
- /// MPCore internal memory region
- MPCORE_RAM_PADDR = 0x17E00000,
- MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB)
- MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE,
-
- /// Video memory
- VRAM_PADDR = 0x18000000,
- VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
- VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
-
- /// DSP memory
- DSP_RAM_PADDR = 0x1FF00000,
- DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
- DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE,
-
- /// AXI WRAM
- AXI_WRAM_PADDR = 0x1FF80000,
- AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB)
- AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE,
-
- /// Main FCRAM
- FCRAM_PADDR = 0x20000000,
- FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
- FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
- FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
-};
-
/// Virtual user-space memory regions
enum : VAddr {
/// Where the application text, data and bss reside.
@@ -126,24 +89,6 @@ enum : VAddr {
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
- /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
- /// memory.
- LINEAR_HEAP_VADDR = 0x14000000,
- LINEAR_HEAP_SIZE = 0x08000000,
- LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
-
- /// Maps 1:1 to the IO register area.
- IO_AREA_VADDR = 0x1EC00000,
- IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
-
- /// Maps 1:1 to VRAM.
- VRAM_VADDR = 0x1F000000,
- VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE,
-
- /// Maps 1:1 to DSP memory.
- DSP_RAM_VADDR = 0x1FF00000,
- DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE,
-
/// Read-only page containing kernel and system configuration values.
CONFIG_MEMORY_VADDR = 0x1FF80000,
CONFIG_MEMORY_SIZE = 0x00001000,
@@ -154,13 +99,8 @@ enum : VAddr {
SHARED_PAGE_SIZE = 0x00001000,
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
- /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
- NEW_LINEAR_HEAP_VADDR = 0x30000000,
- NEW_LINEAR_HEAP_SIZE = 0x10000000,
- NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
-
/// Area where TLS (Thread-Local Storage) buffers are allocated.
- TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
+ TLS_AREA_VADDR = 0x40000000,
TLS_ENTRY_SIZE = 0x200,
TLS_AREA_SIZE = 0x10000000,
TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
@@ -200,12 +140,10 @@ void SetCurrentPageTable(PageTable* page_table);
PageTable* GetCurrentPageTable();
/// Determines if the given VAddr is valid for the specified process.
-bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr);
-bool IsValidVirtualAddress(const VAddr addr);
+bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr);
+bool IsValidVirtualAddress(VAddr vaddr);
/// Determines if the given VAddr is a kernel address
-bool IsKernelVirtualAddress(const VAddr addr);
-
-bool IsValidPhysicalAddress(const PAddr addr);
+bool IsKernelVirtualAddress(VAddr vaddr);
u8 Read8(VAddr addr);
u16 Read16(VAddr addr);
@@ -217,42 +155,17 @@ void Write16(VAddr addr, u16 data);
void Write32(VAddr addr, u32 data);
void Write64(VAddr addr, u64 data);
-void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
- size_t size);
-void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size);
-void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
+void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, size_t size);
+void ReadBlock(VAddr src_addr, void* dest_buffer, size_t size);
+void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
size_t size);
-void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size);
-void ZeroBlock(const VAddr dest_addr, const size_t size);
+void WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size);
+void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, size_t size);
void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size);
-u8* GetPointer(VAddr virtual_address);
-
-std::string ReadCString(VAddr virtual_address, std::size_t max_length);
-
-/**
- * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
- * address. This should be used by services to translate addresses for use by the hardware.
- */
-boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr);
-
-/**
- * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
- * address. This should be used by services to translate addresses for use by the hardware.
- *
- * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure.
- */
-PAddr VirtualToPhysicalAddress(VAddr addr);
+u8* GetPointer(VAddr vaddr);
-/**
- * Undoes a mapping performed by VirtualToPhysicalAddress().
- */
-boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
-
-/**
- * Gets a pointer to the memory region beginning at the specified physical address.
- */
-u8* GetPhysicalPointer(PAddr address);
+std::string ReadCString(VAddr vaddr, std::size_t max_length);
enum class FlushMode {
/// Write back modified surfaces to RAM
@@ -266,7 +179,7 @@ enum class FlushMode {
/**
* Mark each page touching the region as cached.
*/
-void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached);
+void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached);
/**
* Flushes and invalidates any externally cached rasterizer resources touching the given virtual
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp
index 5f53b16d3..8e09b9b63 100644
--- a/src/core/perf_stats.cpp
+++ b/src/core/perf_stats.cpp
@@ -40,22 +40,21 @@ void PerfStats::EndGameFrame() {
game_frames += 1;
}
-PerfStats::Results PerfStats::GetAndResetStats(u64 current_system_time_us) {
+PerfStats::Results PerfStats::GetAndResetStats(microseconds current_system_time_us) {
std::lock_guard<std::mutex> lock(object_mutex);
- auto now = Clock::now();
+ const auto now = Clock::now();
// Walltime elapsed since stats were reset
- auto interval = duration_cast<DoubleSecs>(now - reset_point).count();
+ const auto interval = duration_cast<DoubleSecs>(now - reset_point).count();
- auto system_us_per_second =
- static_cast<double>(current_system_time_us - reset_point_system_us) / interval;
+ const auto system_us_per_second = (current_system_time_us - reset_point_system_us) / interval;
Results results{};
results.system_fps = static_cast<double>(system_frames) / interval;
results.game_fps = static_cast<double>(game_frames) / interval;
results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() /
static_cast<double>(system_frames);
- results.emulation_speed = system_us_per_second / 1'000'000.0;
+ results.emulation_speed = system_us_per_second.count() / 1'000'000.0;
// Reset counters
reset_point = now;
@@ -74,10 +73,10 @@ double PerfStats::GetLastFrameTimeScale() {
return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH;
}
-void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) {
+void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) {
// Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher
// values increase the time needed to recover and limit framerate again after spikes.
- constexpr microseconds MAX_LAG_TIME_US = 25ms;
+ constexpr microseconds MAX_LAG_TIME_US = 25us;
if (!Settings::values.toggle_framelimit) {
return;
@@ -85,7 +84,7 @@ void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) {
auto now = Clock::now();
- frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us);
+ frame_limiting_delta_err += current_system_time_us - previous_system_time_us;
frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime);
frame_limiting_delta_err =
std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US);
diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h
index 362b205c8..6e4619701 100644
--- a/src/core/perf_stats.h
+++ b/src/core/perf_stats.h
@@ -33,7 +33,7 @@ public:
void EndSystemFrame();
void EndGameFrame();
- Results GetAndResetStats(u64 current_system_time_us);
+ Results GetAndResetStats(std::chrono::microseconds current_system_time_us);
/**
* Gets the ratio between walltime and the emulated time of the previous system frame. This is
@@ -47,7 +47,7 @@ private:
/// Point when the cumulative counters were reset
Clock::time_point reset_point = Clock::now();
/// System time when the cumulative counters were reset
- u64 reset_point_system_us = 0;
+ std::chrono::microseconds reset_point_system_us{0};
/// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset
Clock::duration accumulated_frametime = Clock::duration::zero();
@@ -68,11 +68,11 @@ class FrameLimiter {
public:
using Clock = std::chrono::high_resolution_clock;
- void DoFrameLimiting(u64 current_system_time_us);
+ void DoFrameLimiting(std::chrono::microseconds current_system_time_us);
private:
/// Emulated system time (in microseconds) at the last limiter invocation
- u64 previous_system_time_us = 0;
+ std::chrono::microseconds previous_system_time_us{0};
/// Walltime at the last limiter invocation
Clock::time_point previous_walltime = Clock::now();
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 444bcc387..a4623223d 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -2,13 +2,13 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/service/hid/hid.h"
#include "core/settings.h"
+#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
-#include "core/frontend/emu_window.h"
-
namespace Settings {
Values values = {};
@@ -20,9 +20,9 @@ void Apply() {
VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit;
- if (VideoCore::g_emu_window) {
- auto layout = VideoCore::g_emu_window->GetFramebufferLayout();
- VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height);
+ auto& system_instance = Core::System::GetInstance();
+ if (system_instance.IsPoweredOn()) {
+ system_instance.Renderer().UpdateCurrentFramebufferLayout();
}
Service::HID::ReloadInputDevices();
diff --git a/src/core/settings.h b/src/core/settings.h
index 7150d9755..73dc3061f 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -112,6 +112,8 @@ static const std::array<const char*, NumAnalogs> mapping = {{
struct Values {
// System
bool use_docked_mode;
+ std::string username;
+ int language_index;
// Controls
std::array<std::string, NativeButton::NumButtons> buttons;
@@ -137,6 +139,13 @@ struct Values {
std::string log_filter;
+ bool use_dev_keys;
+
+ // Audio
+ std::string sink_id;
+ std::string audio_device_id;
+ float volume;
+
// Debugging
bool use_gdbstub;
u16 gdbstub_port;
diff --git a/src/input_common/keyboard.cpp b/src/input_common/keyboard.cpp
index 0f0d10f23..525fe6abc 100644
--- a/src/input_common/keyboard.cpp
+++ b/src/input_common/keyboard.cpp
@@ -5,6 +5,7 @@
#include <atomic>
#include <list>
#include <mutex>
+#include <utility>
#include "input_common/keyboard.h"
namespace InputCommon {
@@ -12,9 +13,9 @@ namespace InputCommon {
class KeyButton final : public Input::ButtonDevice {
public:
explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
- : key_button_list(key_button_list_) {}
+ : key_button_list(std::move(key_button_list_)) {}
- ~KeyButton();
+ ~KeyButton() override;
bool GetStatus() const override {
return status.load();
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp
index caffe48cb..9570c060e 100644
--- a/src/input_common/motion_emu.cpp
+++ b/src/input_common/motion_emu.cpp
@@ -131,7 +131,7 @@ public:
device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
}
- std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const {
+ std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override {
return device->GetStatus();
}
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp
index 8d117c2d4..d1b960fd7 100644
--- a/src/input_common/sdl/sdl.cpp
+++ b/src/input_common/sdl/sdl.cpp
@@ -82,7 +82,7 @@ private:
class SDLButton final : public Input::ButtonDevice {
public:
explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_)
- : joystick(joystick_), button(button_) {}
+ : joystick(std::move(joystick_)), button(button_) {}
bool GetStatus() const override {
return joystick->GetButton(button);
@@ -96,7 +96,7 @@ private:
class SDLDirectionButton final : public Input::ButtonDevice {
public:
explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_)
- : joystick(joystick_), hat(hat_), direction(direction_) {}
+ : joystick(std::move(joystick_)), hat(hat_), direction(direction_) {}
bool GetStatus() const override {
return joystick->GetHatDirection(hat, direction);
@@ -112,7 +112,7 @@ class SDLAxisButton final : public Input::ButtonDevice {
public:
explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_,
bool trigger_if_greater_)
- : joystick(joystick_), axis(axis_), threshold(threshold_),
+ : joystick(std::move(joystick_)), axis(axis_), threshold(threshold_),
trigger_if_greater(trigger_if_greater_) {}
bool GetStatus() const override {
@@ -132,7 +132,7 @@ private:
class SDLAnalog final : public Input::AnalogDevice {
public:
SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_)
- : joystick(joystick_), axis_x(axis_x_), axis_y(axis_y_) {}
+ : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_) {}
std::tuple<float, float> GetStatus() const override {
return joystick->GetAnalog(axis_x, axis_y);
@@ -314,10 +314,6 @@ namespace Polling {
class SDLPoller : public InputCommon::Polling::DevicePoller {
public:
- SDLPoller() = default;
-
- ~SDLPoller() = default;
-
void Start() override {
// SDL joysticks must be opened, otherwise they don't generate events
SDL_JoystickUpdate();
@@ -341,10 +337,6 @@ private:
class SDLButtonPoller final : public SDLPoller {
public:
- SDLButtonPoller() = default;
-
- ~SDLButtonPoller() = default;
-
Common::ParamPackage GetNextInput() override {
SDL_Event event;
while (SDL_PollEvent(&event)) {
@@ -364,10 +356,6 @@ public:
class SDLAnalogPoller final : public SDLPoller {
public:
- SDLAnalogPoller() = default;
-
- ~SDLAnalogPoller() = default;
-
void Start() override {
SDLPoller::Start();
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 6a0a62ecc..4d74bb395 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -3,7 +3,6 @@ add_executable(tests
core/arm/arm_test_common.cpp
core/arm/arm_test_common.h
core/core_timing.cpp
- core/memory/memory.cpp
glad.cpp
tests.cpp
)
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp
deleted file mode 100644
index 165496a54..000000000
--- a/src/tests/core/memory/memory.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <catch.hpp>
-#include "core/hle/kernel/memory.h"
-#include "core/hle/kernel/process.h"
-#include "core/memory.h"
-
-TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
- SECTION("these regions should not be mapped on an empty process") {
- auto process = Kernel::Process::Create("");
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
- }
-
- SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
- auto process = Kernel::Process::Create("");
- Kernel::MapSharedPages(process->vm_manager);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
- }
-
- SECTION("special regions should be valid after mapping them") {
- auto process = Kernel::Process::Create("");
- SECTION("VRAM") {
- Kernel::HandleSpecialMapping(process->vm_manager,
- {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
- }
-
- SECTION("IO (Not yet implemented)") {
- Kernel::HandleSpecialMapping(
- process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
- CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
- }
-
- SECTION("DSP") {
- Kernel::HandleSpecialMapping(
- process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
- }
- }
-
- SECTION("Unmapping a VAddr should make it invalid") {
- auto process = Kernel::Process::Create("");
- Kernel::MapSharedPages(process->vm_manager);
- process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
- CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
- }
-}
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 0e205ed72..5c0ae8009 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -19,8 +19,8 @@ namespace Engines {
/// First register id that is actually a Macro call.
constexpr u32 MacroRegistersStart = 0xE00;
-Maxwell3D::Maxwell3D(MemoryManager& memory_manager)
- : memory_manager(memory_manager), macro_interpreter(*this) {}
+Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
+ : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {}
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
auto macro_code = uploaded_macros.find(method);
@@ -130,7 +130,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
break;
}
- VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method);
+ rasterizer.NotifyMaxwellRegisterChanged(method);
if (debug_context) {
debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr);
@@ -218,7 +218,7 @@ void Maxwell3D::DrawArrays() {
}
const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count};
- VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed);
+ rasterizer.AccelerateDrawBatch(is_indexed);
// TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if
// the game is trying to draw indexed or direct mode. This needs to be verified on HW still -
@@ -285,8 +285,6 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
// TODO(Subv): Different data types for separate components are not supported
ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
- // TODO(Subv): Only UNORM formats are supported for now.
- ASSERT(r_type == Texture::ComponentType::UNORM);
return tic_entry;
}
@@ -393,7 +391,7 @@ void Maxwell3D::ProcessClearBuffers() {
regs.clear_buffers.R == regs.clear_buffers.B &&
regs.clear_buffers.R == regs.clear_buffers.A);
- VideoCore::g_renderer->Rasterizer()->Clear();
+ rasterizer.Clear();
}
} // namespace Engines
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 3c32f1067..4d0ff96a5 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -17,6 +17,10 @@
#include "video_core/memory_manager.h"
#include "video_core/textures/texture.h"
+namespace VideoCore {
+class RasterizerInterface;
+}
+
namespace Tegra::Engines {
#define MAXWELL3D_REG_INDEX(field_name) \
@@ -24,7 +28,7 @@ namespace Tegra::Engines {
class Maxwell3D final {
public:
- explicit Maxwell3D(MemoryManager& memory_manager);
+ explicit Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager);
~Maxwell3D() = default;
/// Register structure of the Maxwell3D engine.
@@ -818,6 +822,8 @@ public:
Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const;
private:
+ VideoCore::RasterizerInterface& rasterizer;
+
std::unordered_map<u32, std::vector<u32>> uploaded_macros;
/// Macro method that is currently being executed / being fed parameters.
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 60c49d672..b2a83ce0b 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -7,12 +7,13 @@
#include "video_core/engines/maxwell_compute.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
+#include "video_core/rasterizer_interface.h"
namespace Tegra {
-GPU::GPU() {
+GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
memory_manager = std::make_unique<MemoryManager>();
- maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager);
+ maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);
maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager);
@@ -40,6 +41,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
case RenderTargetFormat::RGBA8_UNORM:
case RenderTargetFormat::RGB10_A2_UNORM:
case RenderTargetFormat::BGRA8_UNORM:
+ case RenderTargetFormat::R32_FLOAT:
return 4;
default:
UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format));
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index c464fc6d1..440505c9d 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -11,6 +11,10 @@
#include "core/hle/service/nvflinger/buffer_queue.h"
#include "video_core/memory_manager.h"
+namespace VideoCore {
+class RasterizerInterface;
+}
+
namespace Tegra {
enum class RenderTargetFormat : u32 {
@@ -29,6 +33,7 @@ enum class RenderTargetFormat : u32 {
RG16_UINT = 0xDD,
RG16_FLOAT = 0xDE,
R11G11B10_FLOAT = 0xE0,
+ R32_FLOAT = 0xE5,
R16_FLOAT = 0xF2,
R8_UNORM = 0xF3,
};
@@ -97,7 +102,7 @@ enum class EngineID {
class GPU final {
public:
- GPU();
+ explicit GPU(VideoCore::RasterizerInterface& rasterizer);
~GPU();
/// Processes a command list stored at the specified address in GPU memory.
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 44ece01c1..377bd66ab 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
if (taken) {
// Ignore the delay slot if the branch has the annul bit.
if (opcode.branch_annul) {
- pc = base_address + (opcode.immediate << 2);
+ pc = base_address + opcode.GetBranchTarget();
return true;
}
- delayed_pc = base_address + (opcode.immediate << 2);
+ delayed_pc = base_address + opcode.GetBranchTarget();
// Execute one more instruction due to the delay slot.
return Step(code, true);
}
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index a71e359d8..7d836b816 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -91,6 +91,10 @@ private:
u32 GetBitfieldMask() const {
return (1 << bf_size) - 1;
}
+
+ s32 GetBranchTarget() const {
+ return static_cast<s32>(immediate * sizeof(u32));
+ }
};
union MethodAddress {
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 30075b23c..3ca350243 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -2,14 +2,26 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <atomic>
#include <memory>
+#include "core/frontend/emu_window.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_opengl/gl_rasterizer.h"
-#include "video_core/video_core.h"
+
+namespace VideoCore {
+
+RendererBase::RendererBase(EmuWindow& window) : render_window{window} {}
+RendererBase::~RendererBase() = default;
+
+void RendererBase::UpdateCurrentFramebufferLayout() {
+ const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
+
+ render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
+}
void RendererBase::RefreshRasterizerSetting() {
if (rasterizer == nullptr) {
- rasterizer = std::make_unique<RasterizerOpenGL>();
+ rasterizer = std::make_unique<RasterizerOpenGL>(render_window);
}
}
+
+} // namespace VideoCore
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 89a960eaf..235de23a1 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -13,28 +13,28 @@
class EmuWindow;
+namespace VideoCore {
+
class RendererBase : NonCopyable {
public:
/// Used to reference a framebuffer
enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture };
- virtual ~RendererBase() {}
+ explicit RendererBase(EmuWindow& window);
+ virtual ~RendererBase();
/// Swap buffers (render frame)
virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0;
- /**
- * Set the emulator window to use for renderer
- * @param window EmuWindow handle to emulator window to use for rendering
- */
- virtual void SetWindow(EmuWindow* window) = 0;
-
/// Initialize the renderer
virtual bool Init() = 0;
/// Shutdown the renderer
virtual void ShutDown() = 0;
+ /// Updates the framebuffer layout of the contained render window handle.
+ void UpdateCurrentFramebufferLayout();
+
// Getter/setter functions:
// ------------------------
@@ -46,16 +46,21 @@ public:
return m_current_frame;
}
- VideoCore::RasterizerInterface* Rasterizer() const {
- return rasterizer.get();
+ RasterizerInterface& Rasterizer() {
+ return *rasterizer;
+ }
+
+ const RasterizerInterface& Rasterizer() const {
+ return *rasterizer;
}
void RefreshRasterizerSetting();
protected:
- std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
+ EmuWindow& render_window; ///< Reference to the render window handle.
+ std::unique_ptr<RasterizerInterface> rasterizer;
f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
int m_current_frame = 0; ///< Current frame, should be set by the renderer
-
-private:
};
+
+} // namespace VideoCore
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a1c47bae9..c2a931469 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -14,7 +14,6 @@
#include "common/logging/log.h"
#include "common/math_util.h"
#include "common/microprofile.h"
-#include "common/scope_exit.h"
#include "core/core.h"
#include "core/frontend/emu_window.h"
#include "core/hle/kernel/process.h"
@@ -37,7 +36,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
-RasterizerOpenGL::RasterizerOpenGL() {
+RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} {
// Create sampler objects
for (size_t i = 0; i < texture_samplers.size(); ++i) {
texture_samplers[i].Create();
@@ -170,8 +169,14 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
ASSERT(buffer.IsEnabled());
glEnableVertexAttribArray(index);
- glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
- attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+ if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
+ attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
+ glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.offset);
+ } else {
+ glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+ }
glVertexAttribBinding(index, attrib.buffer);
}
@@ -395,7 +400,7 @@ void RasterizerOpenGL::Clear() {
if (clear_mask == 0)
return;
- ScopeAcquireGLContext acquire_context;
+ ScopeAcquireGLContext acquire_context{emu_window};
auto [dirty_color_surface, dirty_depth_surface] =
ConfigureFramebuffers(use_color_fb, use_depth_fb);
@@ -425,7 +430,7 @@ void RasterizerOpenGL::DrawArrays() {
MICROPROFILE_SCOPE(OpenGL_Drawing);
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- ScopeAcquireGLContext acquire_context;
+ ScopeAcquireGLContext acquire_context{emu_window};
auto [dirty_color_surface, dirty_depth_surface] =
ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index e150be58f..6d6d85cc1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -21,11 +21,12 @@
#include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/gl_stream_buffer.h"
+class EmuWindow;
struct ScreenInfo;
class RasterizerOpenGL : public VideoCore::RasterizerInterface {
public:
- RasterizerOpenGL();
+ explicit RasterizerOpenGL(EmuWindow& renderer);
~RasterizerOpenGL() override;
void DrawArrays() override;
@@ -144,6 +145,8 @@ private:
RasterizerCacheOpenGL res_cache;
+ EmuWindow& emu_window;
+
std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
OGLVertexArray sw_vao;
OGLVertexArray hw_vao;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index a4d9707cb..257aa9571 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -46,6 +46,8 @@ struct FormatTuple {
params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
params.unaligned_height = config.tic.Height();
params.size_in_bytes = params.SizeInBytes();
+ params.cache_width = Common::AlignUp(params.width, 16);
+ params.cache_height = Common::AlignUp(params.height, 16);
return params;
}
@@ -63,6 +65,8 @@ struct FormatTuple {
params.height = config.height;
params.unaligned_height = config.height;
params.size_in_bytes = params.SizeInBytes();
+ params.cache_width = Common::AlignUp(params.width, 16);
+ params.cache_height = Common::AlignUp(params.height, 16);
return params;
}
@@ -82,6 +86,8 @@ struct FormatTuple {
params.height = zeta_height;
params.unaligned_height = zeta_height;
params.size_in_bytes = params.SizeInBytes();
+ params.cache_width = Common::AlignUp(params.width, 16);
+ params.cache_height = Common::AlignUp(params.height, 16);
return params;
}
@@ -118,6 +124,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
{GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI
{GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I
{GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S
+ {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8
// DepthStencil formats
@@ -218,9 +225,10 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>,
MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>,
MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>,
- MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::Z24S8>,
- MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>,
- MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>,
+ MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>,
+ MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>,
+ MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>,
+ MortonCopy<true, PixelFormat::Z32FS8>,
};
static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
@@ -253,6 +261,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
MortonCopy<false, PixelFormat::RG16UI>,
MortonCopy<false, PixelFormat::RG16I>,
MortonCopy<false, PixelFormat::RG16S>,
+ MortonCopy<false, PixelFormat::RGB32F>,
MortonCopy<false, PixelFormat::SRGBA8>,
MortonCopy<false, PixelFormat::Z24S8>,
MortonCopy<false, PixelFormat::S8Z24>,
@@ -677,12 +686,12 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
// If use_accurate_framebuffers is enabled, always load from memory
FlushSurface(surface);
UnregisterSurface(surface);
- } else if (surface->GetSurfaceParams() != params) {
- // If surface parameters changed, recreate the surface from the old one
- return RecreateSurface(surface, params);
- } else {
+ } else if (surface->GetSurfaceParams().IsCompatibleSurface(params)) {
// Use the cached surface as-is
return surface;
+ } else {
+ // If surface parameters changed, recreate the surface from the old one
+ return RecreateSurface(surface, params);
}
}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index bf0458b94..0c6652c7a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -9,6 +9,7 @@
#include <memory>
#include <vector>
#include <boost/icl/interval_map.hpp>
+
#include "common/common_types.h"
#include "common/math_util.h"
#include "video_core/engines/maxwell_3d.h"
@@ -48,16 +49,17 @@ struct SurfaceParams {
RG16UI = 23,
RG16I = 24,
RG16S = 25,
- SRGBA8 = 26,
+ RGB32F = 26,
+ SRGBA8 = 27,
MaxColorFormat,
// DepthStencil formats
- Z24S8 = 27,
- S8Z24 = 28,
- Z32F = 29,
- Z16 = 30,
- Z32FS8 = 31,
+ Z24S8 = 28,
+ S8Z24 = 29,
+ Z32F = 30,
+ Z16 = 31,
+ Z32FS8 = 32,
MaxDepthStencilFormat,
@@ -121,6 +123,7 @@ struct SurfaceParams {
1, // RG16UI
1, // RG16I
1, // RG16S
+ 1, // RGB32F
1, // SRGBA8
1, // Z24S8
1, // S8Z24
@@ -164,6 +167,7 @@ struct SurfaceParams {
32, // RG16UI
32, // RG16I
32, // RG16S
+ 96, // RGB32F
32, // SRGBA8
32, // Z24S8
32, // S8Z24
@@ -200,8 +204,9 @@ struct SurfaceParams {
static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
switch (format) {
+ // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
+ // gamma.
case Tegra::RenderTargetFormat::RGBA8_SRGB:
- return PixelFormat::SRGBA8;
case Tegra::RenderTargetFormat::RGBA8_UNORM:
return PixelFormat::ABGR8;
case Tegra::RenderTargetFormat::BGRA8_UNORM:
@@ -232,6 +237,8 @@ struct SurfaceParams {
return PixelFormat::RG16S;
case Tegra::RenderTargetFormat::R16_FLOAT:
return PixelFormat::R16F;
+ case Tegra::RenderTargetFormat::R32_FLOAT:
+ return PixelFormat::R32F;
default:
LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
UNREACHABLE();
@@ -270,6 +277,8 @@ struct SurfaceParams {
UNREACHABLE();
case Tegra::Texture::TextureFormat::R32_G32:
return PixelFormat::RG32F;
+ case Tegra::Texture::TextureFormat::R32_G32_B32:
+ return PixelFormat::RGB32F;
case Tegra::Texture::TextureFormat::R16:
switch (component_type) {
case Tegra::Texture::ComponentType::FLOAT:
@@ -361,6 +370,8 @@ struct SurfaceParams {
return Tegra::Texture::TextureFormat::A8R8G8B8;
case PixelFormat::RGBA32F:
return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
+ case PixelFormat::RGB32F:
+ return Tegra::Texture::TextureFormat::R32_G32_B32;
case PixelFormat::RG32F:
return Tegra::Texture::TextureFormat::R32_G32;
case PixelFormat::R32F:
@@ -439,6 +450,7 @@ struct SurfaceParams {
case Tegra::RenderTargetFormat::RG32_FLOAT:
case Tegra::RenderTargetFormat::RG16_FLOAT:
case Tegra::RenderTargetFormat::R16_FLOAT:
+ case Tegra::RenderTargetFormat::R32_FLOAT:
return ComponentType::Float;
case Tegra::RenderTargetFormat::RGBA32_UINT:
case Tegra::RenderTargetFormat::RG16_UINT:
@@ -536,6 +548,12 @@ struct SurfaceParams {
return !operator==(other);
}
+ /// Checks if surfaces are compatible for caching
+ bool IsCompatibleSurface(const SurfaceParams& other) const {
+ return std::tie(pixel_format, type, cache_width, cache_height) ==
+ std::tie(other.pixel_format, other.type, other.cache_width, other.cache_height);
+ }
+
Tegra::GPUVAddr addr;
bool is_tiled;
u32 block_height;
@@ -546,6 +564,10 @@ struct SurfaceParams {
u32 height;
u32 unaligned_height;
size_t size_in_bytes;
+
+ // Parameters used for caching only
+ u32 cache_width;
+ u32 cache_height;
};
class CachedSurface final {
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index acf067050..e3217db81 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -412,7 +412,6 @@ public:
}
declarations.AddNewLine();
- unsigned const_buffer_layout = 0;
for (const auto& entry : GetConstBuffersDeclarations()) {
declarations.AddLine("layout(std140) uniform " + entry.GetName());
declarations.AddLine('{');
@@ -420,7 +419,6 @@ public:
"[MAX_CONSTBUFFER_ELEMENTS];");
declarations.AddLine("};");
declarations.AddNewLine();
- ++const_buffer_layout;
}
declarations.AddNewLine();
@@ -768,13 +766,16 @@ private:
// goes into gpr28+0 and gpr28+1
size_t texs_offset{};
+ size_t src_elem{};
for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) {
+ size_t dest_elem{};
for (unsigned elem = 0; elem < 2; ++elem) {
- if (!instr.texs.IsComponentEnabled(elem)) {
+ if (!instr.texs.IsComponentEnabled(src_elem++)) {
// Skip disabled components
continue;
}
- regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem);
+ regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false,
+ dest_elem++);
}
if (!instr.texs.HasTwoDestinations()) {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index e81fcbbc4..415d42fda 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -13,15 +13,16 @@ namespace Impl {
static void SetShaderUniformBlockBinding(GLuint shader, const char* name,
Maxwell3D::Regs::ShaderStage binding,
size_t expected_size) {
- GLuint ub_index = glGetUniformBlockIndex(shader, name);
- if (ub_index != GL_INVALID_INDEX) {
- GLint ub_size = 0;
- glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
- ASSERT_MSG(ub_size == expected_size,
- "Uniform block size did not match! Got {}, expected {}",
- static_cast<int>(ub_size), expected_size);
- glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
+ const GLuint ub_index = glGetUniformBlockIndex(shader, name);
+ if (ub_index == GL_INVALID_INDEX) {
+ return;
}
+
+ GLint ub_size = 0;
+ glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
+ ASSERT_MSG(static_cast<size_t>(ub_size) == expected_size,
+ "Uniform block size did not match! Got {}, expected {}", ub_size, expected_size);
+ glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
}
void SetShaderUniformBlockBindings(GLuint shader) {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index e29d551e1..716933a0b 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -105,20 +105,20 @@ public:
}
ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config,
- const ShaderSetup setup) {
+ const ShaderSetup& setup) {
ShaderEntries result;
std::tie(current.vs, result) = vertex_shaders.Get(config, setup);
return result;
}
ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config,
- const ShaderSetup setup) {
+ const ShaderSetup& setup) {
ShaderEntries result;
std::tie(current.fs, result) = fragment_shaders.Get(config, setup);
return result;
}
- GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) {
+ GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) const {
switch (stage) {
case Maxwell3D::Regs::ShaderStage::Vertex:
return current.vs;
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 3398d7c04..24b1d956b 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -82,7 +82,7 @@ public:
GLenum logic_op; // GL_LOGIC_OP_MODE
// 3 texture units - one for each that is used in PICA fragment shader emulation
- struct {
+ struct TextureUnit {
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
GLuint sampler; // GL_SAMPLER_BINDING
struct {
@@ -104,7 +104,8 @@ public:
Unbind();
sampler = 0;
}
- } texture_units[32];
+ };
+ std::array<TextureUnit, 32> texture_units;
struct {
GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 7810b9147..bf9131193 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -92,23 +92,23 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
return matrix;
}
-ScopeAcquireGLContext::ScopeAcquireGLContext() {
+ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} {
if (Settings::values.use_multi_core) {
- VideoCore::g_emu_window->MakeCurrent();
+ emu_window.MakeCurrent();
}
}
ScopeAcquireGLContext::~ScopeAcquireGLContext() {
if (Settings::values.use_multi_core) {
- VideoCore::g_emu_window->DoneCurrent();
+ emu_window.DoneCurrent();
}
}
-RendererOpenGL::RendererOpenGL() = default;
+RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {}
RendererOpenGL::~RendererOpenGL() = default;
/// Swap buffers (render frame)
void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) {
- ScopeAcquireGLContext acquire_context;
+ ScopeAcquireGLContext acquire_context{render_window};
Core::System::GetInstance().perf_stats.EndSystemFrame();
@@ -130,10 +130,10 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
// Load the framebuffer from memory, draw it to the screen, and swap buffers
LoadFBToScreenInfo(*framebuffer, screen_info);
DrawScreen();
- render_window->SwapBuffers();
+ render_window.SwapBuffers();
}
- render_window->PollEvents();
+ render_window.PollEvents();
Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
Core::System::GetInstance().perf_stats.BeginSystemFrame();
@@ -160,8 +160,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
// only allows rows to have a memory alignement of 4.
ASSERT(framebuffer.stride % 4 == 0);
- if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride,
- screen_info)) {
+ if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride,
+ screen_info)) {
// Reset the screen info's display texture to its own permanent texture
screen_info.display_texture = screen_info.texture.resource.handle;
@@ -356,7 +356,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
* Draws the emulated screens to the emulator window.
*/
void RendererOpenGL::DrawScreen() {
- const auto& layout = render_window->GetFramebufferLayout();
+ const auto& layout = render_window.GetFramebufferLayout();
const auto& screen = layout.screen;
glViewport(0, 0, layout.width, layout.height);
@@ -380,14 +380,6 @@ void RendererOpenGL::DrawScreen() {
/// Updates the framerate
void RendererOpenGL::UpdateFramerate() {}
-/**
- * Set the emulator window to use for renderer
- * @param window EmuWindow handle to emulator window to use for rendering
- */
-void RendererOpenGL::SetWindow(EmuWindow* window) {
- render_window = window;
-}
-
static const char* GetSource(GLenum source) {
#define RET(s) \
case GL_DEBUG_SOURCE_##s: \
@@ -445,7 +437,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
/// Initialize the renderer
bool RendererOpenGL::Init() {
- ScopeAcquireGLContext acquire_context;
+ ScopeAcquireGLContext acquire_context{render_window};
if (GLAD_GL_KHR_debug) {
glEnable(GL_DEBUG_OUTPUT);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 59d92a3dc..428afa3b7 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -34,24 +34,21 @@ struct ScreenInfo {
/// Helper class to acquire/release OpenGL context within a given scope
class ScopeAcquireGLContext : NonCopyable {
public:
- ScopeAcquireGLContext();
+ explicit ScopeAcquireGLContext(EmuWindow& window);
~ScopeAcquireGLContext();
+
+private:
+ EmuWindow& emu_window;
};
-class RendererOpenGL : public RendererBase {
+class RendererOpenGL : public VideoCore::RendererBase {
public:
- RendererOpenGL();
+ explicit RendererOpenGL(EmuWindow& window);
~RendererOpenGL() override;
/// Swap buffers (render frame)
void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override;
- /**
- * Set the emulator window to use for renderer
- * @param window EmuWindow handle to emulator window to use for rendering
- */
- void SetWindow(EmuWindow* window) override;
-
/// Initialize the renderer
bool Init() override;
@@ -72,8 +69,6 @@ private:
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
const TextureInfo& texture);
- EmuWindow* render_window; ///< Handle to render window
-
OpenGLState state;
// OpenGL object IDs
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index d794f8402..65db84ad3 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -57,6 +57,8 @@ u32 BytesPerPixel(TextureFormat format) {
case TextureFormat::BC7U:
// In this case a 'pixel' actually refers to a 4x4 tile.
return 16;
+ case TextureFormat::R32_G32_B32:
+ return 12;
case TextureFormat::ASTC_2D_4X4:
case TextureFormat::A8R8G8B8:
case TextureFormat::A2B10G10R10:
@@ -131,6 +133,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
case TextureFormat::R16_G16:
case TextureFormat::BF10GF11RF11:
case TextureFormat::ASTC_2D_4X4:
+ case TextureFormat::R32_G32_B32:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, block_height);
break;
@@ -190,6 +193,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
case TextureFormat::R32:
case TextureFormat::R16:
case TextureFormat::R16_G16:
+ case TextureFormat::R32_G32_B32:
// TODO(Subv): For the time being just forward the same data without any decoding.
rgba_data = texture_data;
break;
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 289140f31..5085ef96b 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -3,40 +3,16 @@
// Refer to the license.txt file included.
#include <memory>
-#include "common/logging/log.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_opengl/renderer_opengl.h"
#include "video_core/video_core.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Video Core namespace
-
namespace VideoCore {
-EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window
-std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
-
std::atomic<bool> g_toggle_framelimit_enabled;
-/// Initialize the video core
-bool Init(EmuWindow* emu_window) {
- g_emu_window = emu_window;
- g_renderer = std::make_unique<RendererOpenGL>();
- g_renderer->SetWindow(g_emu_window);
- if (g_renderer->Init()) {
- LOG_DEBUG(Render, "initialized OK");
- } else {
- LOG_CRITICAL(Render, "initialization failed !");
- return false;
- }
- return true;
-}
-
-/// Shutdown the video core
-void Shutdown() {
- g_renderer.reset();
-
- LOG_DEBUG(Render, "shutdown OK");
+std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) {
+ return std::make_unique<RendererOpenGL>(emu_window);
}
} // namespace VideoCore
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 37da62436..7c01c0b8d 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -8,29 +8,23 @@
#include <memory>
class EmuWindow;
-class RendererBase;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Video Core namespace
namespace VideoCore {
-enum class Renderer { Software, OpenGL };
+class RendererBase;
-extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
-extern EmuWindow* g_emu_window; ///< Emu window
+enum class Renderer { Software, OpenGL };
// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
// qt ui)
extern std::atomic<bool> g_toggle_framelimit_enabled;
-/// Start the video core
-void Start();
-
-/// Initialize the video core
-bool Init(EmuWindow* emu_window);
-
-/// Shutdown the video core
-void Shutdown();
+/**
+ * Creates a renderer instance.
+ *
+ * @note The returned renderer instance is simply allocated. Its Init()
+ * function still needs to be called to fully complete its setup.
+ */
+std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window);
} // namespace VideoCore
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 7de919a8e..475556806 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -11,6 +11,8 @@ add_executable(yuzu
bootmanager.h
configuration/config.cpp
configuration/config.h
+ configuration/configure_audio.cpp
+ configuration/configure_audio.h
configuration/configure_debug.cpp
configuration/configure_debug.h
configuration/configure_dialog.cpp
@@ -55,6 +57,7 @@ add_executable(yuzu
set(UIS
aboutdialog.ui
configuration/configure.ui
+ configuration/configure_audio.ui
configuration/configure_debug.ui
configuration/configure_general.ui
configuration/configure_graphics.ui
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index d6647eeea..a81ad2888 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -10,8 +10,9 @@
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
ui->setupUi(this);
ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200));
- ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg(
- Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
+ ui->labelBuildInfo->setText(
+ ui->labelBuildInfo->text().arg(Common::g_build_name, Common::g_scm_branch,
+ Common::g_scm_desc, QString(Common::g_build_date).left(10)));
}
-AboutDialog::~AboutDialog() {}
+AboutDialog::~AboutDialog() = default;
diff --git a/src/yuzu/about_dialog.h b/src/yuzu/about_dialog.h
index 2eb6e28f5..18e8c11a7 100644
--- a/src/yuzu/about_dialog.h
+++ b/src/yuzu/about_dialog.h
@@ -16,7 +16,7 @@ class AboutDialog : public QDialog {
public:
explicit AboutDialog(QWidget* parent);
- ~AboutDialog();
+ ~AboutDialog() override;
private:
std::unique_ptr<Ui::AboutDialog> ui;
diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui
index 2680480cc..f122ba39d 100644
--- a/src/yuzu/aboutdialog.ui
+++ b/src/yuzu/aboutdialog.ui
@@ -70,7 +70,7 @@
</sizepolicy>
</property>
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 | %2-%3&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 | %2-%3 (%4)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@@ -115,7 +115,7 @@ p, li { white-space: pre-wrap; }
<item>
<widget class="QLabel" name="labelLinks">
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/license.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/license.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 130bc613b..d0f990c64 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -106,7 +106,7 @@ class GRenderWindow : public QWidget, public EmuWindow {
public:
GRenderWindow(QWidget* parent, EmuThread* emu_thread);
- ~GRenderWindow();
+ ~GRenderWindow() override;
// EmuWindow implementation
void SwapBuffers() override;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 98969fe10..bf469ee73 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -92,16 +92,26 @@ void Config::ReadValues() {
Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat();
qt_config->endGroup();
+ qt_config->beginGroup("Audio");
+ Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString();
+ Settings::values.audio_device_id =
+ qt_config->value("output_device", "auto").toString().toStdString();
+ Settings::values.volume = qt_config->value("volume", 1).toFloat();
+ qt_config->endGroup();
+
qt_config->beginGroup("Data Storage");
Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
qt_config->endGroup();
qt_config->beginGroup("System");
Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool();
+ Settings::values.username = qt_config->value("username", "yuzu").toString().toStdString();
+ Settings::values.language_index = qt_config->value("language_index", 1).toInt();
qt_config->endGroup();
qt_config->beginGroup("Miscellaneous");
Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString();
+ Settings::values.use_dev_keys = qt_config->value("use_dev_keys", false).toBool();
qt_config->endGroup();
qt_config->beginGroup("Debugging");
@@ -195,16 +205,25 @@ void Config::SaveValues() {
qt_config->setValue("bg_blue", (double)Settings::values.bg_blue);
qt_config->endGroup();
+ qt_config->beginGroup("Audio");
+ qt_config->setValue("output_engine", QString::fromStdString(Settings::values.sink_id));
+ qt_config->setValue("output_device", QString::fromStdString(Settings::values.audio_device_id));
+ qt_config->setValue("volume", Settings::values.volume);
+ qt_config->endGroup();
+
qt_config->beginGroup("Data Storage");
qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
qt_config->endGroup();
qt_config->beginGroup("System");
qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode);
+ qt_config->setValue("username", QString::fromStdString(Settings::values.username));
+ qt_config->setValue("language_index", Settings::values.language_index);
qt_config->endGroup();
qt_config->beginGroup("Miscellaneous");
qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter));
+ qt_config->setValue("use_dev_keys", Settings::values.use_dev_keys);
qt_config->endGroup();
qt_config->beginGroup("Debugging");
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index c5303851c..c8e0b88af 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -34,11 +34,16 @@
<string>Input</string>
</attribute>
</widget>
- <widget class="ConfigureGraphics" name="graphicsTab">
- <attribute name="title">
- <string>Graphics</string>
- </attribute>
- </widget>
+ <widget class="ConfigureGraphics" name="graphicsTab">
+ <attribute name="title">
+ <string>Graphics</string>
+ </attribute>
+ </widget>
+ <widget class="ConfigureAudio" name="audioTab">
+ <attribute name="title">
+ <string>Audio</string>
+ </attribute>
+ </widget>
<widget class="ConfigureDebug" name="debugTab">
<attribute name="title">
<string>Debug</string>
@@ -69,6 +74,12 @@
<container>1</container>
</customwidget>
<customwidget>
+ <class>ConfigureAudio</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_audio.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>ConfigureDebug</class>
<extends>QWidget</extends>
<header>configuration/configure_debug.h</header>
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
new file mode 100644
index 000000000..fbb813f6c
--- /dev/null
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -0,0 +1,90 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "audio_core/sink.h"
+#include "audio_core/sink_details.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_audio.h"
+#include "yuzu/configuration/configure_audio.h"
+
+ConfigureAudio::ConfigureAudio(QWidget* parent)
+ : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
+ ui->setupUi(this);
+
+ ui->output_sink_combo_box->clear();
+ ui->output_sink_combo_box->addItem("auto");
+ for (const auto& sink_detail : AudioCore::g_sink_details) {
+ ui->output_sink_combo_box->addItem(sink_detail.id);
+ }
+
+ connect(ui->volume_slider, &QSlider::valueChanged, [this] {
+ ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
+ });
+
+ this->setConfiguration();
+ connect(ui->output_sink_combo_box,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &ConfigureAudio::updateAudioDevices);
+
+ ui->output_sink_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->audio_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+}
+
+ConfigureAudio::~ConfigureAudio() = default;
+
+void ConfigureAudio::setConfiguration() {
+ int new_sink_index = 0;
+ for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
+ if (ui->output_sink_combo_box->itemText(index).toStdString() == Settings::values.sink_id) {
+ new_sink_index = index;
+ break;
+ }
+ }
+ ui->output_sink_combo_box->setCurrentIndex(new_sink_index);
+
+ // The device list cannot be pre-populated (nor listed) until the output sink is known.
+ updateAudioDevices(new_sink_index);
+
+ int new_device_index = -1;
+ for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
+ if (ui->audio_device_combo_box->itemText(index).toStdString() ==
+ Settings::values.audio_device_id) {
+ new_device_index = index;
+ break;
+ }
+ }
+ ui->audio_device_combo_box->setCurrentIndex(new_device_index);
+
+ ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum());
+ ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
+}
+
+void ConfigureAudio::applyConfiguration() {
+ Settings::values.sink_id =
+ ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
+ .toStdString();
+ Settings::values.audio_device_id =
+ ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
+ .toStdString();
+ Settings::values.volume =
+ static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
+}
+
+void ConfigureAudio::updateAudioDevices(int sink_index) {
+ ui->audio_device_combo_box->clear();
+ ui->audio_device_combo_box->addItem(AudioCore::auto_device_name);
+
+ std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
+ std::vector<std::string> device_list = AudioCore::GetSinkDetails(sink_id).list_devices();
+ for (const auto& device : device_list) {
+ ui->audio_device_combo_box->addItem(device.c_str());
+ }
+}
+
+void ConfigureAudio::retranslateUi() {
+ ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h
new file mode 100644
index 000000000..4f0af4163
--- /dev/null
+++ b/src/yuzu/configuration/configure_audio.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+
+namespace Ui {
+class ConfigureAudio;
+}
+
+class ConfigureAudio : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit ConfigureAudio(QWidget* parent = nullptr);
+ ~ConfigureAudio();
+
+ void applyConfiguration();
+ void retranslateUi();
+
+public slots:
+ void updateAudioDevices(int sink_index);
+
+private:
+ void setConfiguration();
+
+ std::unique_ptr<Ui::ConfigureAudio> ui;
+};
diff --git a/src/yuzu/configuration/configure_audio.ui b/src/yuzu/configuration/configure_audio.ui
new file mode 100644
index 000000000..ef67890dc
--- /dev/null
+++ b/src/yuzu/configuration/configure_audio.ui
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureAudio</class>
+ <widget class="QWidget" name="ConfigureAudio">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>188</width>
+ <height>246</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Audio</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Output Engine:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="output_sink_combo_box"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Audio Device:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="audio_device_combo_box"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Volume:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSlider" name="volume_slider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="pageStep">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="volume_indicator">
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0 %</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>167</width>
+ <height>55</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 5e66239ff..45d84f19a 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -24,7 +24,7 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::Co
});
}
-ConfigureDebug::~ConfigureDebug() {}
+ConfigureDebug::~ConfigureDebug() = default;
void ConfigureDebug::setConfiguration() {
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub);
@@ -44,5 +44,4 @@ void ConfigureDebug::applyConfiguration() {
Log::Filter filter;
filter.ParseFilterString(Settings::values.log_filter);
Log::SetGlobalFilter(filter);
- Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 118e91cf1..5ae7276bd 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -23,13 +23,6 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QLabel" name="label_1">
- <property name="text">
- <string>The GDB Stub only works correctly when the CPU JIT is off.</string>
- </property>
- </widget>
- </item>
- <item>
<layout class="QHBoxLayout" name="horizontalLayout_1">
<item>
<widget class="QCheckBox" name="toggle_gdbstub">
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 358f33005..cc4b326ae 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -6,13 +6,16 @@
#include "ui_configure.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_dialog.h"
+#include "yuzu/hotkeys.h"
-ConfigureDialog::ConfigureDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ConfigureDialog) {
+ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry)
+ : QDialog(parent), ui(new Ui::ConfigureDialog) {
ui->setupUi(this);
+ ui->generalTab->PopulateHotkeyList(registry);
this->setConfiguration();
}
-ConfigureDialog::~ConfigureDialog() {}
+ConfigureDialog::~ConfigureDialog() = default;
void ConfigureDialog::setConfiguration() {}
@@ -21,6 +24,7 @@ void ConfigureDialog::applyConfiguration() {
ui->systemTab->applyConfiguration();
ui->inputTab->applyConfiguration();
ui->graphicsTab->applyConfiguration();
+ ui->audioTab->applyConfiguration();
ui->debugTab->applyConfiguration();
Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h
index 21fa1f501..bbbdacc29 100644
--- a/src/yuzu/configuration/configure_dialog.h
+++ b/src/yuzu/configuration/configure_dialog.h
@@ -7,6 +7,8 @@
#include <memory>
#include <QDialog>
+class HotkeyRegistry;
+
namespace Ui {
class ConfigureDialog;
}
@@ -15,7 +17,7 @@ class ConfigureDialog : public QDialog {
Q_OBJECT
public:
- explicit ConfigureDialog(QWidget* parent);
+ explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry);
~ConfigureDialog();
void applyConfiguration();
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index baa558667..d8caee1e8 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -24,7 +24,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
-ConfigureGeneral::~ConfigureGeneral() {}
+ConfigureGeneral::~ConfigureGeneral() = default;
void ConfigureGeneral::setConfiguration() {
ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan);
@@ -35,6 +35,10 @@ void ConfigureGeneral::setConfiguration() {
ui->use_docked_mode->setChecked(Settings::values.use_docked_mode);
}
+void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
+ ui->widget->Populate(registry);
+}
+
void ConfigureGeneral::applyConfiguration() {
UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked();
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
@@ -44,5 +48,4 @@ void ConfigureGeneral::applyConfiguration() {
Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
Settings::values.use_multi_core = ui->use_multi_core->isChecked();
Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
- Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index 447552d8c..4770034cc 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -7,6 +7,8 @@
#include <memory>
#include <QWidget>
+class HotkeyRegistry;
+
namespace Ui {
class ConfigureGeneral;
}
@@ -18,11 +20,11 @@ public:
explicit ConfigureGeneral(QWidget* parent = nullptr);
~ConfigureGeneral();
+ void PopulateHotkeyList(const HotkeyRegistry& registry);
void applyConfiguration();
private:
void setConfiguration();
-private:
std::unique_ptr<Ui::ConfigureGeneral> ui;
};
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 7664880d5..4afe0f81b 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -14,7 +14,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
this->setConfiguration();
}
-ConfigureGraphics::~ConfigureGraphics() {}
+ConfigureGraphics::~ConfigureGraphics() = default;
enum class Resolution : int {
Auto,
@@ -67,5 +67,4 @@ void ConfigureGraphics::applyConfiguration() {
ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked();
Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked();
- Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 78559e2bb..5e7badedf 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -191,8 +191,6 @@ void ConfigureInput::applyConfiguration() {
[](const Common::ParamPackage& param) { return param.Serialize(); });
std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(),
[](const Common::ParamPackage& param) { return param.Serialize(); });
-
- Settings::Apply();
}
void ConfigureInput::loadConfiguration() {
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index d09505a0f..e9ed9c38f 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -4,9 +4,10 @@
#include <QMessageBox>
#include "core/core.h"
+#include "core/settings.h"
#include "ui_configure_system.h"
#include "yuzu/configuration/configure_system.h"
-#include "yuzu/ui_settings.h"
+#include "yuzu/main.h"
static const std::array<int, 12> days_in_month = {{
31,
@@ -34,10 +35,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::
this->setConfiguration();
}
-ConfigureSystem::~ConfigureSystem() {}
+ConfigureSystem::~ConfigureSystem() = default;
void ConfigureSystem::setConfiguration() {
enabled = !Core::System::GetInstance().IsPoweredOn();
+ ui->edit_username->setText(QString::fromStdString(Settings::values.username));
+ ui->combo_language->setCurrentIndex(Settings::values.language_index);
}
void ConfigureSystem::ReadSystemSettings() {}
@@ -45,6 +48,9 @@ void ConfigureSystem::ReadSystemSettings() {}
void ConfigureSystem::applyConfiguration() {
if (!enabled)
return;
+ Settings::values.username = ui->edit_username->text().toStdString();
+ Settings::values.language_index = ui->combo_language->currentIndex();
+ Settings::Apply();
}
void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) {
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index 8caf49623..f3f8db038 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -38,7 +38,7 @@
</sizepolicy>
</property>
<property name="maxLength">
- <number>10</number>
+ <number>32</number>
</property>
</widget>
</item>
@@ -164,7 +164,7 @@
</item>
<item>
<property name="text">
- <string>Simplified Chinese (简体中文)</string>
+ <string>Chinese</string>
</property>
</item>
<item>
@@ -187,6 +187,31 @@
<string>Russian (Русский)</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>Taiwanese</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>British English</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Canadian French</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Latin American Spanish</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Simplified Chinese</string>
+ </property>
+ </item>
<item>
<property name="text">
<string>Traditional Chinese (正體中文)</string>
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
index d6d61a739..5f459ccfb 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
@@ -10,12 +10,12 @@ BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Tegra::DebugConte
: QDockWidget(title, parent), BreakPointObserver(debug_context) {
qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
- connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed()));
+ connect(this, &BreakPointObserverDock::Resumed, this, &BreakPointObserverDock::OnResumed);
// NOTE: This signal is emitted from a non-GUI thread, but connect() takes
// care of delaying its handling to the GUI thread.
- connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this,
- SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection);
+ connect(this, &BreakPointObserverDock::BreakPointHit, this,
+ &BreakPointObserverDock::OnBreakPointHit, Qt::BlockingQueuedConnection);
}
void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) {
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
index 9d05493cf..ab32f0115 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
@@ -23,11 +23,11 @@ public:
void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
void OnMaxwellResume() override;
-private slots:
- virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
- virtual void OnResumed() = 0;
-
signals:
void Resumed();
void BreakPointHit(Tegra::DebugContext::Event event, void* data);
+
+private:
+ virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
+ virtual void OnResumed() = 0;
};
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
index f98cc8152..eb16a38a0 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
@@ -144,21 +144,25 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(
qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
- connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), this,
- SLOT(OnItemDoubleClicked(const QModelIndex&)));
+ connect(breakpoint_list, &QTreeView::doubleClicked, this,
+ &GraphicsBreakPointsWidget::OnItemDoubleClicked);
- connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested()));
+ connect(resume_button, &QPushButton::clicked, this,
+ &GraphicsBreakPointsWidget::OnResumeRequested);
- connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this,
- SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection);
- connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed()));
+ connect(this, &GraphicsBreakPointsWidget::BreakPointHit, this,
+ &GraphicsBreakPointsWidget::OnBreakPointHit, Qt::BlockingQueuedConnection);
+ connect(this, &GraphicsBreakPointsWidget::Resumed, this, &GraphicsBreakPointsWidget::OnResumed);
- connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), breakpoint_model,
- SLOT(OnBreakPointHit(Tegra::DebugContext::Event)), Qt::BlockingQueuedConnection);
- connect(this, SIGNAL(Resumed()), breakpoint_model, SLOT(OnResumed()));
+ connect(this, &GraphicsBreakPointsWidget::BreakPointHit, breakpoint_model,
+ &BreakPointModel::OnBreakPointHit, Qt::BlockingQueuedConnection);
+ connect(this, &GraphicsBreakPointsWidget::Resumed, breakpoint_model,
+ &BreakPointModel::OnResumed);
- connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&, const QModelIndex&)),
- breakpoint_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)));
+ connect(this, &GraphicsBreakPointsWidget::BreakPointsChanged,
+ [this](const QModelIndex& top_left, const QModelIndex& bottom_right) {
+ breakpoint_model->dataChanged(top_left, bottom_right);
+ });
QWidget* main_widget = new QWidget;
auto main_layout = new QVBoxLayout;
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.h b/src/yuzu/debugger/graphics/graphics_breakpoints.h
index ae0ede2e8..a920a2ae5 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.h
@@ -26,18 +26,17 @@ public:
void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
void OnMaxwellResume() override;
-public slots:
- void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
- void OnItemDoubleClicked(const QModelIndex&);
- void OnResumeRequested();
- void OnResumed();
-
signals:
void Resumed();
void BreakPointHit(Tegra::DebugContext::Event event, void* data);
void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
private:
+ void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
+ void OnItemDoubleClicked(const QModelIndex&);
+ void OnResumeRequested();
+ void OnResumed();
+
QLabel* status_text;
QPushButton* resume_button;
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
index 35a6876ae..7112b87e6 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
@@ -25,7 +25,6 @@ public:
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
-public slots:
void OnBreakPointHit(Tegra::DebugContext::Event event);
void OnResumed();
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index c41ff693b..3f7103ab9 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -34,7 +34,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat(
SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_)
: QLabel(parent), surface_widget(surface_widget_) {}
-SurfacePicture::~SurfacePicture() {}
+
+SurfacePicture::~SurfacePicture() = default;
void SurfacePicture::mousePressEvent(QMouseEvent* event) {
// Only do something while the left mouse button is held down
@@ -153,22 +154,24 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext
save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save"));
// Connections
- connect(this, SIGNAL(Update()), this, SLOT(OnUpdate()));
- connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this,
- SLOT(OnSurfaceSourceChanged(int)));
- connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this,
- SLOT(OnSurfaceAddressChanged(qint64)));
- connect(surface_width_control, SIGNAL(valueChanged(int)), this,
- SLOT(OnSurfaceWidthChanged(int)));
- connect(surface_height_control, SIGNAL(valueChanged(int)), this,
- SLOT(OnSurfaceHeightChanged(int)));
- connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this,
- SLOT(OnSurfaceFormatChanged(int)));
- connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this,
- SLOT(OnSurfacePickerXChanged(int)));
- connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this,
- SLOT(OnSurfacePickerYChanged(int)));
- connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface()));
+ connect(this, &GraphicsSurfaceWidget::Update, this, &GraphicsSurfaceWidget::OnUpdate);
+ connect(surface_source_list,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &GraphicsSurfaceWidget::OnSurfaceSourceChanged);
+ connect(surface_address_control, &CSpinBox::ValueChanged, this,
+ &GraphicsSurfaceWidget::OnSurfaceAddressChanged);
+ connect(surface_width_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &GraphicsSurfaceWidget::OnSurfaceWidthChanged);
+ connect(surface_height_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &GraphicsSurfaceWidget::OnSurfaceHeightChanged);
+ connect(surface_format_control,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &GraphicsSurfaceWidget::OnSurfaceFormatChanged);
+ connect(surface_picker_x_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &GraphicsSurfaceWidget::OnSurfacePickerXChanged);
+ connect(surface_picker_y_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &GraphicsSurfaceWidget::OnSurfacePickerYChanged);
+ connect(save_surface, &QPushButton::clicked, this, &GraphicsSurfaceWidget::SaveSurface);
auto main_widget = new QWidget;
auto main_layout = new QVBoxLayout;
diff --git a/src/yuzu/debugger/graphics/graphics_surface.h b/src/yuzu/debugger/graphics/graphics_surface.h
index 6a344bdfc..323e39d94 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.h
+++ b/src/yuzu/debugger/graphics/graphics_surface.h
@@ -22,11 +22,11 @@ class SurfacePicture : public QLabel {
public:
explicit SurfacePicture(QWidget* parent = nullptr,
GraphicsSurfaceWidget* surface_widget = nullptr);
- ~SurfacePicture();
+ ~SurfacePicture() override;
protected slots:
- virtual void mouseMoveEvent(QMouseEvent* event);
- virtual void mousePressEvent(QMouseEvent* event);
+ void mouseMoveEvent(QMouseEvent* event) override;
+ void mousePressEvent(QMouseEvent* event) override;
private:
GraphicsSurfaceWidget* surface_widget;
@@ -65,16 +65,15 @@ public slots:
void OnSurfacePickerYChanged(int new_value);
void OnUpdate();
-private slots:
+signals:
+ void Update();
+
+private:
void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
void OnResumed() override;
void SaveSurface();
-signals:
- void Update();
-
-private:
QComboBox* surface_source_list;
CSpinBox* surface_address_control;
QSpinBox* surface_width_control;
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index f5a5697a0..d0926d723 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -14,7 +14,7 @@
#include "core/hle/kernel/timer.h"
#include "core/hle/kernel/wait_object.h"
-WaitTreeItem::~WaitTreeItem() {}
+WaitTreeItem::~WaitTreeItem() = default;
QColor WaitTreeItem::GetColor() const {
return QColor(Qt::GlobalColor::black);
@@ -316,7 +316,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
list.push_back(std::make_unique<WaitTreeText>(
tr("reset type = %1")
- .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).reset_type))));
+ .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType()))));
return list;
}
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 10fc9e968..513b3c45d 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -9,7 +9,7 @@
#include <QTreeView>
#include <boost/container/flat_set.hpp>
#include "core/core.h"
-#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/object.h"
class EmuThread;
@@ -25,11 +25,13 @@ class WaitTreeThread;
class WaitTreeItem : public QObject {
Q_OBJECT
public:
+ ~WaitTreeItem() override;
+
virtual bool IsExpandable() const;
virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const;
virtual QString GetText() const = 0;
virtual QColor GetColor() const;
- virtual ~WaitTreeItem();
+
void Expand();
WaitTreeItem* Parent() const;
const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const;
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 99e6634a1..24f38a3c7 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -162,15 +162,15 @@ void GameList::onTextChanged(const QString& newText) {
}
search_field->setFilterResult(rowCount, rowCount);
} else {
- QStandardItem* child_file;
- QString file_path, file_name, file_title, file_programmid;
int result_count = 0;
for (int i = 0; i < rowCount; ++i) {
- child_file = item_model->item(i, 0);
- file_path = child_file->data(GameListItemPath::FullPathRole).toString().toLower();
- file_name = file_path.mid(file_path.lastIndexOf("/") + 1);
- file_title = child_file->data(GameListItemPath::TitleRole).toString().toLower();
- file_programmid =
+ const QStandardItem* child_file = item_model->item(i, 0);
+ const QString file_path =
+ child_file->data(GameListItemPath::FullPathRole).toString().toLower();
+ QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1);
+ const QString file_title =
+ child_file->data(GameListItemPath::TitleRole).toString().toLower();
+ const QString file_programmid =
child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
// Only items which filename in combination with its title contains all words
@@ -258,18 +258,20 @@ void GameList::AddEntry(const QList<QStandardItem*>& entry_items) {
void GameList::ValidateEntry(const QModelIndex& item) {
// We don't care about the individual QStandardItem that was selected, but its row.
- int row = item_model->itemFromIndex(item)->row();
- QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME);
- QString file_path = child_file->data(GameListItemPath::FullPathRole).toString();
+ const int row = item_model->itemFromIndex(item)->row();
+ const QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME);
+ const QString file_path = child_file->data(GameListItemPath::FullPathRole).toString();
if (file_path.isEmpty())
return;
- std::string std_file_path(file_path.toStdString());
- if (!FileUtil::Exists(std_file_path))
+
+ if (!QFileInfo::exists(file_path))
return;
- if (FileUtil::IsDirectory(std_file_path)) {
- QDir dir(std_file_path.c_str());
- QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+
+ const QFileInfo file_info{file_path};
+ if (file_info.isDir()) {
+ const QDir dir{file_path};
+ const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
if (matching_main.size() == 1) {
emit GameChosen(dir.path() + DIR_SEP + matching_main[0]);
}
@@ -365,24 +367,26 @@ void GameList::LoadInterfaceLayout() {
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
}
-const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca"};
+const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci"};
static bool HasSupportedFileExtension(const std::string& file_name) {
- QFileInfo file = QFileInfo(file_name.c_str());
+ const QFileInfo file = QFileInfo(QString::fromStdString(file_name));
return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive);
}
static bool IsExtractedNCAMain(const std::string& file_name) {
- return QFileInfo(file_name.c_str()).fileName() == "main";
+ return QFileInfo(QString::fromStdString(file_name)).fileName() == "main";
}
static QString FormatGameName(const std::string& physical_name) {
- QFileInfo file_info(physical_name.c_str());
+ const QString physical_name_as_qstring = QString::fromStdString(physical_name);
+ const QFileInfo file_info(physical_name_as_qstring);
+
if (IsExtractedNCAMain(physical_name)) {
return file_info.dir().path();
- } else {
- return QString::fromStdString(physical_name);
}
+
+ return physical_name_as_qstring;
}
void GameList::RefreshGameDirectory() {
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index a758b77aa..aa69a098f 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -5,6 +5,7 @@
#pragma once
#include <atomic>
+#include <utility>
#include <QImage>
#include <QRunnable>
#include <QStandardItem>
@@ -27,9 +28,8 @@ static QPixmap GetDefaultIcon(bool large) {
class GameListItem : public QStandardItem {
public:
- GameListItem() : QStandardItem() {}
- GameListItem(const QString& string) : QStandardItem(string) {}
- virtual ~GameListItem() override {}
+ GameListItem() = default;
+ explicit GameListItem(const QString& string) : QStandardItem(string) {}
};
/**
@@ -45,9 +45,8 @@ public:
static const int TitleRole = Qt::UserRole + 2;
static const int ProgramIdRole = Qt::UserRole + 3;
- GameListItemPath() : GameListItem() {}
- GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id)
- : GameListItem() {
+ GameListItemPath() = default;
+ GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) {
setData(game_path, FullPathRole);
setData(qulonglong(program_id), ProgramIdRole);
}
@@ -75,8 +74,8 @@ class GameListItemSize : public GameListItem {
public:
static const int SizeRole = Qt::UserRole + 1;
- GameListItemSize() : GameListItem() {}
- GameListItemSize(const qulonglong size_bytes) : GameListItem() {
+ GameListItemSize() = default;
+ explicit GameListItemSize(const qulonglong size_bytes) {
setData(size_bytes, SizeRole);
}
@@ -111,7 +110,7 @@ class GameListWorker : public QObject, public QRunnable {
public:
GameListWorker(QString dir_path, bool deep_scan)
- : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {}
+ : dir_path(std::move(dir_path)), deep_scan(deep_scan) {}
public slots:
/// Starts the processing of directory tree information.
diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp
index 61acb38ee..dce399774 100644
--- a/src/yuzu/hotkeys.cpp
+++ b/src/yuzu/hotkeys.cpp
@@ -10,58 +10,53 @@
#include "yuzu/hotkeys.h"
#include "yuzu/ui_settings.h"
-struct Hotkey {
- Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {}
+HotkeyRegistry::HotkeyRegistry() = default;
+HotkeyRegistry::~HotkeyRegistry() = default;
- QKeySequence keyseq;
- QShortcut* shortcut;
- Qt::ShortcutContext context;
-};
-
-typedef std::map<QString, Hotkey> HotkeyMap;
-typedef std::map<QString, HotkeyMap> HotkeyGroupMap;
-
-HotkeyGroupMap hotkey_groups;
-
-void SaveHotkeys() {
- UISettings::values.shortcuts.clear();
- for (auto group : hotkey_groups) {
- for (auto hotkey : group.second) {
- UISettings::values.shortcuts.emplace_back(
- UISettings::Shortcut(group.first + "/" + hotkey.first,
- UISettings::ContextualShortcut(hotkey.second.keyseq.toString(),
- hotkey.second.context)));
- }
- }
-}
-
-void LoadHotkeys() {
+void HotkeyRegistry::LoadHotkeys() {
// Make sure NOT to use a reference here because it would become invalid once we call
// beginGroup()
for (auto shortcut : UISettings::values.shortcuts) {
- QStringList cat = shortcut.first.split("/");
+ const QStringList cat = shortcut.first.split('/');
Q_ASSERT(cat.size() >= 2);
// RegisterHotkey assigns default keybindings, so use old values as default parameters
Hotkey& hk = hotkey_groups[cat[0]][cat[1]];
if (!shortcut.second.first.isEmpty()) {
hk.keyseq = QKeySequence::fromString(shortcut.second.first);
- hk.context = (Qt::ShortcutContext)shortcut.second.second;
+ hk.context = static_cast<Qt::ShortcutContext>(shortcut.second.second);
}
if (hk.shortcut)
hk.shortcut->setKey(hk.keyseq);
}
}
-void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq,
- Qt::ShortcutContext default_context) {
- if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) {
- hotkey_groups[group][action].keyseq = default_keyseq;
- hotkey_groups[group][action].context = default_context;
+void HotkeyRegistry::SaveHotkeys() {
+ UISettings::values.shortcuts.clear();
+ for (const auto& group : hotkey_groups) {
+ for (const auto& hotkey : group.second) {
+ UISettings::values.shortcuts.emplace_back(
+ UISettings::Shortcut(group.first + '/' + hotkey.first,
+ UISettings::ContextualShortcut(hotkey.second.keyseq.toString(),
+ hotkey.second.context)));
+ }
}
}
-QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) {
+void HotkeyRegistry::RegisterHotkey(const QString& group, const QString& action,
+ const QKeySequence& default_keyseq,
+ Qt::ShortcutContext default_context) {
+ auto& hotkey_group = hotkey_groups[group];
+ if (hotkey_group.find(action) != hotkey_group.end()) {
+ return;
+ }
+
+ auto& hotkey_action = hotkey_groups[group][action];
+ hotkey_action.keyseq = default_keyseq;
+ hotkey_action.context = default_context;
+}
+
+QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) {
Hotkey& hk = hotkey_groups[group][action];
if (!hk.shortcut)
@@ -72,10 +67,12 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge
GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) {
ui.setupUi(this);
+}
- for (auto group : hotkey_groups) {
+void GHotkeysDialog::Populate(const HotkeyRegistry& registry) {
+ for (const auto& group : registry.hotkey_groups) {
QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first));
- for (auto hotkey : group.second) {
+ for (const auto& hotkey : group.second) {
QStringList columns;
columns << hotkey.first << hotkey.second.keyseq.toString();
QTreeWidgetItem* item = new QTreeWidgetItem(columns);
diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h
index a4ccc193b..f38e6c002 100644
--- a/src/yuzu/hotkeys.h
+++ b/src/yuzu/hotkeys.h
@@ -4,6 +4,7 @@
#pragma once
+#include <map>
#include "ui_hotkeys.h"
class QDialog;
@@ -11,47 +12,69 @@ class QKeySequence;
class QSettings;
class QShortcut;
-/**
- * Register a hotkey.
- *
- * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger")
- * @param action Name of the action (e.g. "Start Emulation", "Load Image")
- * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings
- * file before
- * @param default_context Default context to assign if the hotkey wasn't present in the settings
- * file before
- * @warning Both the group and action strings will be displayed in the hotkey settings dialog
- */
-void RegisterHotkey(const QString& group, const QString& action,
- const QKeySequence& default_keyseq = QKeySequence(),
- Qt::ShortcutContext default_context = Qt::WindowShortcut);
-
-/**
- * Returns a QShortcut object whose activated() signal can be connected to other QObjects' slots.
- *
- * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger").
- * @param action Name of the action (e.g. "Start Emulation", "Load Image").
- * @param widget Parent widget of the returned QShortcut.
- * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut
- * will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent.
- */
-QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
-
-/**
- * Saves all registered hotkeys to the settings file.
- *
- * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a
- * settings group will be created to store the key sequence and the hotkey context.
- */
-void SaveHotkeys();
-
-/**
- * Loads hotkeys from the settings file.
- *
- * @note Yet unregistered hotkeys which are present in the settings will automatically be
- * registered.
- */
-void LoadHotkeys();
+class HotkeyRegistry final {
+public:
+ friend class GHotkeysDialog;
+
+ explicit HotkeyRegistry();
+ ~HotkeyRegistry();
+
+ /**
+ * Loads hotkeys from the settings file.
+ *
+ * @note Yet unregistered hotkeys which are present in the settings will automatically be
+ * registered.
+ */
+ void LoadHotkeys();
+
+ /**
+ * Saves all registered hotkeys to the settings file.
+ *
+ * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a
+ * settings group will be created to store the key sequence and the hotkey context.
+ */
+ void SaveHotkeys();
+
+ /**
+ * Returns a QShortcut object whose activated() signal can be connected to other QObjects'
+ * slots.
+ *
+ * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger").
+ * @param action Name of the action (e.g. "Start Emulation", "Load Image").
+ * @param widget Parent widget of the returned QShortcut.
+ * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut
+ * will be the same. Thus, you shouldn't rely on the caller really being the
+ * QShortcut's parent.
+ */
+ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
+
+ /**
+ * Register a hotkey.
+ *
+ * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger")
+ * @param action Name of the action (e.g. "Start Emulation", "Load Image")
+ * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the
+ * settings file before
+ * @param default_context Default context to assign if the hotkey wasn't present in the settings
+ * file before
+ * @warning Both the group and action strings will be displayed in the hotkey settings dialog
+ */
+ void RegisterHotkey(const QString& group, const QString& action,
+ const QKeySequence& default_keyseq = {},
+ Qt::ShortcutContext default_context = Qt::WindowShortcut);
+
+private:
+ struct Hotkey {
+ QKeySequence keyseq;
+ QShortcut* shortcut = nullptr;
+ Qt::ShortcutContext context = Qt::WindowShortcut;
+ };
+
+ using HotkeyMap = std::map<QString, Hotkey>;
+ using HotkeyGroupMap = std::map<QString, HotkeyMap>;
+
+ HotkeyGroupMap hotkey_groups;
+};
class GHotkeysDialog : public QWidget {
Q_OBJECT
@@ -59,6 +82,8 @@ class GHotkeysDialog : public QWidget {
public:
explicit GHotkeysDialog(QWidget* parent = nullptr);
+ void Populate(const HotkeyRegistry& registry);
+
private:
Ui::hotkeys ui;
};
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 97273f967..17ed62c72 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -23,6 +23,7 @@
#include "common/scope_exit.h"
#include "common/string_util.h"
#include "core/core.h"
+#include "core/crypto/key_manager.h"
#include "core/gdbstub/gdbstub.h"
#include "core/loader/loader.h"
#include "core/settings.h"
@@ -80,6 +81,8 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) {
void GMainWindow::ShowCallouts() {}
+const int GMainWindow::max_recent_files_item;
+
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
debug_context = Tegra::DebugContext::Construct();
@@ -205,27 +208,46 @@ void GMainWindow::InitializeRecentFileMenuActions() {
}
void GMainWindow::InitializeHotkeys() {
- RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
- RegisterHotkey("Main Window", "Start Emulation");
- RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen);
- RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape),
- Qt::ApplicationShortcut);
- LoadHotkeys();
-
- connect(GetHotkey("Main Window", "Load File", this), &QShortcut::activated, this,
- &GMainWindow::OnMenuLoadFile);
- connect(GetHotkey("Main Window", "Start Emulation", this), &QShortcut::activated, this,
- &GMainWindow::OnStartGame);
- connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activated,
- ui.action_Fullscreen, &QAction::trigger);
- connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activatedAmbiguously,
- ui.action_Fullscreen, &QAction::trigger);
- connect(GetHotkey("Main Window", "Exit Fullscreen", this), &QShortcut::activated, this, [&] {
- if (emulation_running) {
- ui.action_Fullscreen->setChecked(false);
- ToggleFullscreen();
- }
- });
+ hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
+ hotkey_registry.RegisterHotkey("Main Window", "Start Emulation");
+ hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4));
+ hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen);
+ hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape),
+ Qt::ApplicationShortcut);
+ hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"),
+ Qt::ApplicationShortcut);
+ hotkey_registry.LoadHotkeys();
+
+ connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
+ this, &GMainWindow::OnMenuLoadFile);
+ connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this),
+ &QShortcut::activated, this, &GMainWindow::OnStartGame);
+ connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated,
+ this, [&] {
+ if (emulation_running) {
+ if (emu_thread->IsRunning()) {
+ OnPauseGame();
+ } else {
+ OnStartGame();
+ }
+ }
+ });
+ connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ &QShortcut::activated, ui.action_Fullscreen, &QAction::trigger);
+ connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ &QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger);
+ connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this),
+ &QShortcut::activated, this, [&] {
+ if (emulation_running) {
+ ui.action_Fullscreen->setChecked(false);
+ ToggleFullscreen();
+ }
+ });
+ connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),
+ &QShortcut::activated, this, [&] {
+ Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit;
+ UpdateStatusBar();
+ });
}
void GMainWindow::SetDefaultUIGeometry() {
@@ -304,7 +326,8 @@ void GMainWindow::ConnectMenuEvents() {
connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible);
// Fullscreen
- ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key());
+ ui.action_Fullscreen->setShortcut(
+ hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
// Help
@@ -386,7 +409,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
system.SetGPUDebugContext(debug_context);
- const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())};
+ const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
render_window->DoneCurrent();
@@ -408,18 +431,49 @@ bool GMainWindow::LoadROM(const QString& filename) {
tr("Could not determine the system mode."));
break;
- case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: {
+ case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: {
+ const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false);
+ const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true);
+
+ std::string file_text;
+
+ if (!reg_found && !title_found) {
+ file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be "
+ "found. You will need to dump your keys from your switch to continue.";
+ } else if (reg_found && title_found) {
+ file_text =
+ "Both key files were found in your config directory, but the correct key could"
+ "not be found. You may be missing a titlekey or general key, depending on "
+ "the game.";
+ } else if (reg_found) {
+ file_text =
+ "The regular keys file (prod.keys/dev.keys) was found in your config, but the "
+ "titlekeys file (title.keys) was not. You are either missing the correct "
+ "titlekey or missing a general key required to decrypt the game.";
+ } else {
+ file_text = "The title keys file (title.keys) was found in your config, but "
+ "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, "
+ "having the titlekey is not enough, you need additional general keys "
+ "to properly decrypt the game. You should double-check to make sure "
+ "your keys are correct.";
+ }
+
QMessageBox::critical(
this, tr("Error while loading ROM!"),
- tr("The game that you are trying to load must be decrypted before being used with "
- "yuzu. A real Switch is required.<br/><br/>"
- "For more information on dumping and decrypting games, please see the following "
- "wiki pages: <ul>"
- "<li><a href='https://yuzu-emu.org/wiki/dumping-game-cartridges/'>Dumping Game "
- "Cartridges</a></li>"
- "<li><a href='https://yuzu-emu.org/wiki/dumping-installed-titles/'>Dumping "
- "Installed Titles</a></li>"
- "</ul>"));
+ tr(("The game you are trying to load is encrypted and the required keys to load "
+ "the game could not be found in your configuration. " +
+ file_text + " Please refer to the yuzu wiki for help.")
+ .c_str()));
+ break;
+ }
+ case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: {
+ QMessageBox::critical(
+ this, tr("Error while loading ROM!"),
+ tr("There was a general error while decrypting the game. This means that the keys "
+ "necessary were found, but were either incorrect, the game itself was not a "
+ "valid game or the game uses an unhandled cryptographic scheme. Please double "
+ "check that you have the correct "
+ "keys."));
break;
}
case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
@@ -429,7 +483,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
case Core::System::ResultStatus::ErrorVideoCore:
QMessageBox::critical(
- this, tr("An error occured in the video core."),
+ this, tr("An error occurred initializing the video core."),
tr("yuzu has encountered an error while running the video core, please see the "
"log for more details."
"For more information on accessing the log, please see the following page: "
@@ -443,7 +497,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
default:
QMessageBox::critical(
this, tr("Error while loading ROM!"),
- tr("An unknown error occured. Please see the log for more details."));
+ tr("An unknown error occurred. Please see the log for more details."));
break;
}
return false;
@@ -531,11 +585,11 @@ void GMainWindow::StoreRecentFile(const QString& filename) {
}
void GMainWindow::UpdateRecentFiles() {
- unsigned int num_recent_files =
- std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item));
+ const int num_recent_files =
+ std::min(UISettings::values.recent_files.size(), max_recent_files_item);
- for (unsigned int i = 0; i < num_recent_files; i++) {
- QString text = QString("&%1. %2").arg(i + 1).arg(
+ for (int i = 0; i < num_recent_files; i++) {
+ const QString text = QString("&%1. %2").arg(i + 1).arg(
QFileInfo(UISettings::values.recent_files[i]).fileName());
actions_recent_files[i]->setText(text);
actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
@@ -547,12 +601,8 @@ void GMainWindow::UpdateRecentFiles() {
actions_recent_files[j]->setVisible(false);
}
- // Grey out the recent files menu if the list is empty
- if (num_recent_files == 0) {
- ui.menu_recent_files->setEnabled(false);
- } else {
- ui.menu_recent_files->setEnabled(true);
- }
+ // Enable the recent files menu if the list isn't empty
+ ui.menu_recent_files->setEnabled(num_recent_files != 0);
}
void GMainWindow::OnGameListLoadFile(QString game_path) {
@@ -583,9 +633,15 @@ void GMainWindow::OnMenuLoadFile() {
}
void GMainWindow::OnMenuLoadFolder() {
- QDir dir = QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory"));
+ const QString dir_path =
+ QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory"));
+
+ if (dir_path.isNull()) {
+ return;
+ }
- QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+ const QDir dir{dir_path};
+ const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
if (matching_main.size() == 1) {
BootGame(dir.path() + DIR_SEP + matching_main[0]);
} else {
@@ -606,9 +662,8 @@ void GMainWindow::OnMenuRecentFile() {
QAction* action = qobject_cast<QAction*>(sender());
assert(action);
- QString filename = action->data().toString();
- QFileInfo file_info(filename);
- if (file_info.exists()) {
+ const QString filename = action->data().toString();
+ if (QFileInfo::exists(filename)) {
BootGame(filename);
} else {
// Display an error message and remove the file from the list.
@@ -706,11 +761,13 @@ void GMainWindow::ToggleWindowMode() {
}
void GMainWindow::OnConfigure() {
- ConfigureDialog configureDialog(this);
+ ConfigureDialog configureDialog(this, hotkey_registry);
+ auto old_theme = UISettings::values.theme;
auto result = configureDialog.exec();
if (result == QDialog::Accepted) {
configureDialog.applyConfiguration();
- UpdateUITheme();
+ if (UISettings::values.theme != old_theme)
+ UpdateUITheme();
config->Save();
}
}
@@ -843,7 +900,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
UISettings::values.first_start = false;
game_list->SaveInterfaceLayout();
- SaveHotkeys();
+ hotkey_registry.SaveHotkeys();
// Shutdown session if the emu thread is active...
if (emu_thread != nullptr)
@@ -897,15 +954,14 @@ void GMainWindow::UpdateUITheme() {
QStringList theme_paths(default_theme_paths);
if (UISettings::values.theme != UISettings::themes[0].second &&
!UISettings::values.theme.isEmpty()) {
- QString theme_uri(":" + UISettings::values.theme + "/style.qss");
+ const QString theme_uri(":" + UISettings::values.theme + "/style.qss");
QFile f(theme_uri);
- if (!f.exists()) {
- LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
- } else {
- f.open(QFile::ReadOnly | QFile::Text);
+ if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
GMainWindow::setStyleSheet(ts.readAll());
+ } else {
+ LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
}
theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme});
QIcon::setThemeName(":/icons/" + UISettings::values.theme);
@@ -941,7 +997,6 @@ int main(int argc, char* argv[]) {
QCoreApplication::setOrganizationName("yuzu team");
QCoreApplication::setApplicationName("yuzu");
- QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
QApplication app(argc, argv);
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 074bba3f9..6e335b8f8 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -9,6 +9,7 @@
#include <QTimer>
#include "core/core.h"
#include "ui_main.h"
+#include "yuzu/hotkeys.h"
class Config;
class EmuThread;
@@ -43,7 +44,7 @@ public:
void filterBarSetChecked(bool state);
void UpdateUITheme();
GMainWindow();
- ~GMainWindow();
+ ~GMainWindow() override;
signals:
@@ -172,6 +173,8 @@ private:
// stores default icon theme search paths for the platform
QStringList default_theme_paths;
+ HotkeyRegistry hotkey_registry;
+
protected:
void dropEvent(QDropEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index cea1a5e62..9bf26717f 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -105,6 +105,11 @@ void Config::ReadValues() {
Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0);
Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0);
+ // Audio
+ Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
+ Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
+ Settings::values.volume = sdl2_config->GetReal("Audio", "volume", 1);
+
// Data Storage
Settings::values.use_virtual_sd =
sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
@@ -114,6 +119,7 @@ void Config::ReadValues() {
// Miscellaneous
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
+ Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false);
// Debugging
Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 567f23417..9a935a0d5 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -143,19 +143,17 @@ swap_screen =
[Audio]
# Which audio output engine to use.
-# auto (default): Auto-select, null: No audio output, sdl2: SDL2 (if available)
+# auto (default): Auto-select, null: No audio output, cubeb: Cubeb audio engine (if available)
output_engine =
-# Whether or not to enable the audio-stretching post-processing effect.
-# This effect adjusts audio speed to match emulation speed and helps prevent audio stutter,
-# at the cost of increasing audio latency.
-# 0: No, 1 (default): Yes
-enable_audio_stretching =
-
# Which audio device to use.
# auto (default): Auto-select
output_device =
+# Output volume.
+# 1.0 (default): 100%, 0.0; mute
+volume =
+
[Data Storage]
# Whether to create a virtual SD card.
# 1 (default): Yes, 0: No
@@ -166,6 +164,16 @@ use_virtual_sd =
# 1: Yes, 0 (default): No
use_docked_mode =
+# Sets the account username, max length is 32 characters
+# yuzu (default)
+username =
+
+# Sets the systems language index
+# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
+# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
+# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
+language_index =
+
# The system region that yuzu will use during emulation
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
region_value =
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index b5392c499..d637dbd0c 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -23,6 +23,7 @@
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
#include <getopt.h>
+#include "core/crypto/key_manager.h"
#ifndef _MSC_VER
#include <unistd.h>
#endif
@@ -71,6 +72,7 @@ static void InitializeLogging() {
/// Application entry point
int main(int argc, char** argv) {
Config config;
+
int option_index = 0;
bool use_gdbstub = Settings::values.use_gdbstub;
u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port);
@@ -162,7 +164,7 @@ int main(int argc, char** argv) {
SCOPE_EXIT({ system.Shutdown(); });
- const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)};
+ const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)};
switch (load_result) {
case Core::System::ResultStatus::ErrorGetLoader:
@@ -171,11 +173,15 @@ int main(int argc, char** argv) {
case Core::System::ResultStatus::ErrorLoader:
LOG_CRITICAL(Frontend, "Failed to load ROM!");
return -1;
- case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted:
- LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before "
- "being used with yuzu. \n\n For more information on dumping and "
- "decrypting games, please refer to: "
- "https://yuzu-emu.org/wiki/dumping-game-cartridges/");
+ case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys:
+ LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required "
+ "could not be found. Please refer to the yuzu wiki for help");
+ return -1;
+ case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting:
+ LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a "
+ "general error while decrypting. This could mean that the keys are "
+ "incorrect, game is invalid or game uses an unsupported method of "
+ "crypto. Please double-check your keys");
return -1;
case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported.");
@@ -187,7 +193,7 @@ int main(int argc, char** argv) {
LOG_CRITICAL(Frontend, "Failed to determine system mode!");
return -1;
case Core::System::ResultStatus::ErrorVideoCore:
- LOG_CRITICAL(Frontend, "VideoCore not initialized");
+ LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!");
return -1;
case Core::System::ResultStatus::Success:
break; // Expected case