summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
7[submodule "catch"] 7[submodule "catch"]
8 path = externals/catch 8 path = externals/catch
9 url = https://github.com/philsquared/Catch.git 9 url = https://github.com/philsquared/Catch.git
10[submodule "cubeb"]
11 path = externals/cubeb
12 url = https://github.com/kinetiknz/cubeb.git
10[submodule "dynarmic"] 13[submodule "dynarmic"]
11 path = externals/dynarmic 14 path = externals/dynarmic
12 url = https://github.com/MerryMage/dynarmic.git 15 url = https://github.com/MerryMage/dynarmic.git
@@ -22,3 +25,9 @@
22[submodule "unicorn"] 25[submodule "unicorn"]
23 path = externals/unicorn 26 path = externals/unicorn
24 url = https://github.com/yuzu-emu/unicorn 27 url = https://github.com/yuzu-emu/unicorn
28[submodule "mbedtls"]
29 path = externals/mbedtls
30 url = https://github.com/DarkLordZach/mbedtls
31[submodule "opus"]
32 path = externals/opus
33 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
17 17
18option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON) 18option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
19 19
20option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
21
20if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) 22if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
21 message(STATUS "Copying pre-commit hook") 23 message(STATUS "Copying pre-commit hook")
22 file(COPY hooks/pre-commit 24 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 @@
1# License
2
3## The MIT License (MIT) - Code
4
5Copyright (c) 2013-2018 Colin Duquesnoy
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23THE SOFTWARE.
24
25## Creative Commons Attribution International 4.0 - Images
26
27QDarkStyle (c) 2013-2018 Colin Duquesnoy
28
29Creative 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.
30
31### Using Creative Commons Public Licenses
32
33Creative 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.
34
35* __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).
36
37* __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).
38
39## Creative Commons Attribution 4.0 International Public License
40
41By 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.
42
43### Section 1 – Definitions
44
45a. __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.
46
47b. __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.
48
49c. __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.
50
51d. __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.
52
53e. __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.
54
55f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
56
57g. __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.
58
59h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
60
61i. __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.
62
63j. __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.
64
65k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
66
67### Section 2 – Scope
68
69a. ___License grant.___
70
71 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:
72
73 A. reproduce and Share the Licensed Material, in whole or in part; and
74
75 B. produce, reproduce, and Share Adapted Material.
76
77 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.
78
79 3. __Term.__ The term of this Public License is specified in Section 6(a).
80
81 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.
82
83 5. __Downstream recipients.__
84
85 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.
86
87 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.
88
89 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).
90
91b. ___Other rights.___
92
93 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.
94
95 2. Patent and trademark rights are not licensed under this Public License.
96
97 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.
98
99### Section 3 – License Conditions
100
101Your exercise of the Licensed Rights is expressly made subject to the following conditions.
102
103a. ___Attribution.___
104
105 1. If You Share the Licensed Material (including in modified form), You must:
106
107 A. retain the following if it is supplied by the Licensor with the Licensed Material:
108
109 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);
110
111 ii. a copyright notice;
112
113 iii. a notice that refers to this Public License;
114
115 iv. a notice that refers to the disclaimer of warranties;
116
117 v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
118
119 B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
120
121 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.
122
123 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.
124
125 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.
126
127 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.
128
129### Section 4 – Sui Generis Database Rights
130
131Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
132
133a. 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;
134
135b. 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
136
137c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
138
139For 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.
140
141### Section 5 – Disclaimer of Warranties and Limitation of Liability
142
143a. __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.__
144
145b. __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.__
146
147c. 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.
148
149### Section 6 – Term and Termination
150
151a. 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.
152
153b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
154
155 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
156
157 2. upon express reinstatement by the Licensor.
158
159 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.
160
161c. 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.
162
163d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
164
165### Section 7 – Other Terms and Conditions
166
167a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
168
169b. 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.
170
171### Section 8 – Interpretation
172
173a. 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.
174
175b. 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.
176
177c. 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.
178
179d. 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.
180
181> 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.
182>
183> 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 @@
1/* 1QToolTip {
2 * The MIT License (MIT)
3 *
4 * Copyright (c) <2013-2014> <Colin Duquesnoy>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24QToolTip
25{
26 border: 1px solid #76797C; 2 border: 1px solid #76797C;
27 background-color: rgb(90, 102, 117);; 3 background-color: #5A7566;
28 color: white; 4 color: white;
29 padding: 5px; 5 padding: 0px; /*remove padding, for fix combobox tooltip.*/
30 opacity: 200; 6 opacity: 200;
31} 7}
32 8
33QWidget 9QWidget {
34{
35 color: #eff0f1; 10 color: #eff0f1;
36 background-color: #31363b; 11 background-color: #31363b;
37 selection-background-color:#3daee9; 12 selection-background-color: #3daee9;
38 selection-color: #eff0f1; 13 selection-color: #eff0f1;
39 background-clip: border; 14 background-clip: border;
40 border-image: none; 15 border-image: none;
@@ -42,43 +17,38 @@ QWidget
42 outline: 0; 17 outline: 0;
43} 18}
44 19
45QWidget:item:hover 20QWidget:item:hover {
46{
47 background-color: #18465d; 21 background-color: #18465d;
48 color: #eff0f1; 22 color: #eff0f1;
49} 23}
50 24
51QWidget:item:selected 25QWidget:item:selected {
52{
53 background-color: #18465d; 26 background-color: #18465d;
54} 27}
55 28
56QCheckBox 29QCheckBox {
57{
58 spacing: 5px; 30 spacing: 5px;
59 outline: none; 31 outline: none;
60 color: #eff0f1; 32 color: #eff0f1;
61 margin-bottom: 2px; 33 margin-bottom: 2px;
62} 34}
63 35
64QCheckBox:disabled 36QCheckBox:disabled {
65{
66 color: #76797C; 37 color: #76797C;
67} 38}
68 39
69QCheckBox::indicator, 40QCheckBox::indicator,
70QGroupBox::indicator 41QGroupBox::indicator {
71{
72 width: 18px; 42 width: 18px;
73 height: 18px; 43 height: 18px;
74} 44}
75QGroupBox::indicator 45
76{ 46QGroupBox::indicator {
77 margin-left: 2px; 47 margin-left: 2px;
78} 48}
79 49
80QCheckBox::indicator:unchecked 50QCheckBox::indicator:unchecked,
81{ 51QGroupBox::indicator:unchecked {
82 image: url(:/qss_icons/rc/checkbox_unchecked.png); 52 image: url(:/qss_icons/rc/checkbox_unchecked.png);
83} 53}
84 54
@@ -87,14 +57,13 @@ QCheckBox::indicator:unchecked:focus,
87QCheckBox::indicator:unchecked:pressed, 57QCheckBox::indicator:unchecked:pressed,
88QGroupBox::indicator:unchecked:hover, 58QGroupBox::indicator:unchecked:hover,
89QGroupBox::indicator:unchecked:focus, 59QGroupBox::indicator:unchecked:focus,
90QGroupBox::indicator:unchecked:pressed 60QGroupBox::indicator:unchecked:pressed {
91{ 61 border: none;
92 border: none;
93 image: url(:/qss_icons/rc/checkbox_unchecked_focus.png); 62 image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
94} 63}
95 64
96QCheckBox::indicator:checked 65QCheckBox::indicator:checked,
97{ 66QGroupBox::indicator:checked {
98 image: url(:/qss_icons/rc/checkbox_checked.png); 67 image: url(:/qss_icons/rc/checkbox_checked.png);
99} 68}
100 69
@@ -103,72 +72,60 @@ QCheckBox::indicator:checked:focus,
103QCheckBox::indicator:checked:pressed, 72QCheckBox::indicator:checked:pressed,
104QGroupBox::indicator:checked:hover, 73QGroupBox::indicator:checked:hover,
105QGroupBox::indicator:checked:focus, 74QGroupBox::indicator:checked:focus,
106QGroupBox::indicator:checked:pressed 75QGroupBox::indicator:checked:pressed {
107{ 76 border: none;
108 border: none;
109 image: url(:/qss_icons/rc/checkbox_checked_focus.png); 77 image: url(:/qss_icons/rc/checkbox_checked_focus.png);
110} 78}
111 79
112 80QCheckBox::indicator:indeterminate {
113QCheckBox::indicator:indeterminate
114{
115 image: url(:/qss_icons/rc/checkbox_indeterminate.png); 81 image: url(:/qss_icons/rc/checkbox_indeterminate.png);
116} 82}
117 83
118QCheckBox::indicator:indeterminate:focus, 84QCheckBox::indicator:indeterminate:focus,
119QCheckBox::indicator:indeterminate:hover, 85QCheckBox::indicator:indeterminate:hover,
120QCheckBox::indicator:indeterminate:pressed 86QCheckBox::indicator:indeterminate:pressed {
121{
122 image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png); 87 image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
123} 88}
124 89
125QCheckBox::indicator:checked:disabled, 90QCheckBox::indicator:checked:disabled,
126QGroupBox::indicator:checked:disabled 91QGroupBox::indicator:checked:disabled {
127{
128 image: url(:/qss_icons/rc/checkbox_checked_disabled.png); 92 image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
129} 93}
130 94
131QCheckBox::indicator:unchecked:disabled, 95QCheckBox::indicator:unchecked:disabled,
132QGroupBox::indicator:unchecked:disabled 96QGroupBox::indicator:unchecked:disabled {
133{
134 image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png); 97 image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png);
135} 98}
136 99
137QRadioButton 100QRadioButton {
138{
139 spacing: 5px; 101 spacing: 5px;
140 outline: none; 102 outline: none;
141 color: #eff0f1; 103 color: #eff0f1;
142 margin-bottom: 2px; 104 margin-bottom: 2px;
143} 105}
144 106
145QRadioButton:disabled 107QRadioButton:disabled {
146{
147 color: #76797C; 108 color: #76797C;
148} 109}
149QRadioButton::indicator 110
150{ 111QRadioButton::indicator {
151 width: 21px; 112 width: 21px;
152 height: 21px; 113 height: 21px;
153} 114}
154 115
155QRadioButton::indicator:unchecked 116QRadioButton::indicator:unchecked {
156{
157 image: url(:/qss_icons/rc/radio_unchecked.png); 117 image: url(:/qss_icons/rc/radio_unchecked.png);
158} 118}
159 119
160
161QRadioButton::indicator:unchecked:hover, 120QRadioButton::indicator:unchecked:hover,
162QRadioButton::indicator:unchecked:focus, 121QRadioButton::indicator:unchecked:focus,
163QRadioButton::indicator:unchecked:pressed 122QRadioButton::indicator:unchecked:pressed {
164{
165 border: none; 123 border: none;
166 outline: none; 124 outline: none;
167 image: url(:/qss_icons/rc/radio_unchecked_focus.png); 125 image: url(:/qss_icons/rc/radio_unchecked_focus.png);
168} 126}
169 127
170QRadioButton::indicator:checked 128QRadioButton::indicator:checked {
171{
172 border: none; 129 border: none;
173 outline: none; 130 outline: none;
174 image: url(:/qss_icons/rc/radio_checked.png); 131 image: url(:/qss_icons/rc/radio_checked.png);
@@ -176,72 +133,60 @@ QRadioButton::indicator:checked
176 133
177QRadioButton::indicator:checked:hover, 134QRadioButton::indicator:checked:hover,
178QRadioButton::indicator:checked:focus, 135QRadioButton::indicator:checked:focus,
179QRadioButton::indicator:checked:pressed 136QRadioButton::indicator:checked:pressed {
180{
181 border: none; 137 border: none;
182 outline: none; 138 outline: none;
183 image: url(:/qss_icons/rc/radio_checked_focus.png); 139 image: url(:/qss_icons/rc/radio_checked_focus.png);
184} 140}
185 141
186QRadioButton::indicator:checked:disabled 142QRadioButton::indicator:checked:disabled {
187{
188 outline: none; 143 outline: none;
189 image: url(:/qss_icons/rc/radio_checked_disabled.png); 144 image: url(:/qss_icons/rc/radio_checked_disabled.png);
190} 145}
191 146
192QRadioButton::indicator:unchecked:disabled 147QRadioButton::indicator:unchecked:disabled {
193{
194 image: url(:/qss_icons/rc/radio_unchecked_disabled.png); 148 image: url(:/qss_icons/rc/radio_unchecked_disabled.png);
195} 149}
196 150
197 151QMenuBar {
198QMenuBar
199{
200 background-color: #31363b; 152 background-color: #31363b;
201 color: #eff0f1; 153 color: #eff0f1;
202} 154}
203 155
204QMenuBar::item 156QMenuBar::item {
205{
206 background: transparent; 157 background: transparent;
207} 158}
208 159
209QMenuBar::item:selected 160QMenuBar::item:selected {
210{
211 background: transparent; 161 background: transparent;
212 border: 1px solid #76797C; 162 border: 1px solid #76797C;
213} 163}
214 164
215QMenuBar::item:pressed 165QMenuBar::item:pressed {
216{
217 border: 1px solid #76797C; 166 border: 1px solid #76797C;
218 background-color: #3daee9; 167 background-color: #3daee9;
219 color: #eff0f1; 168 color: #eff0f1;
220 margin-bottom:-1px; 169 margin-bottom: -1px;
221 padding-bottom:1px; 170 padding-bottom: 1px;
222} 171}
223 172
224QMenu 173QMenu {
225{
226 border: 1px solid #76797C; 174 border: 1px solid #76797C;
227 color: #eff0f1; 175 color: #eff0f1;
228 margin: 2px; 176 margin: 2px;
229} 177}
230 178
231QMenu::icon 179QMenu::icon {
232{
233 margin: 5px; 180 margin: 5px;
234} 181}
235 182
236QMenu::item 183QMenu::item {
237{
238 padding: 5px 30px 5px 30px; 184 padding: 5px 30px 5px 30px;
239 margin-left: 5px; 185 border: 1px solid transparent;
240 border: 1px solid transparent; /* reserve space for selection border */ 186 /* reserve space for selection border */
241} 187}
242 188
243QMenu::item:selected 189QMenu::item:selected {
244{
245 color: #eff0f1; 190 color: #eff0f1;
246} 191}
247 192
@@ -257,8 +202,10 @@ QMenu::indicator {
257 height: 18px; 202 height: 18px;
258} 203}
259 204
205
260/* non-exclusive indicator = check box style indicator 206/* non-exclusive indicator = check box style indicator
261 (see QActionGroup::setExclusive) */ 207 (see QActionGroup::setExclusive) */
208
262QMenu::indicator:non-exclusive:unchecked { 209QMenu::indicator:non-exclusive:unchecked {
263 image: url(:/qss_icons/rc/checkbox_unchecked.png); 210 image: url(:/qss_icons/rc/checkbox_unchecked.png);
264} 211}
@@ -275,7 +222,9 @@ QMenu::indicator:non-exclusive:checked:selected {
275 image: url(:/qss_icons/rc/checkbox_checked_disabled.png); 222 image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
276} 223}
277 224
225
278/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ 226/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
227
279QMenu::indicator:exclusive:unchecked { 228QMenu::indicator:exclusive:unchecked {
280 image: url(:/qss_icons/rc/radio_unchecked.png); 229 image: url(:/qss_icons/rc/radio_unchecked.png);
281} 230}
@@ -297,33 +246,31 @@ QMenu::right-arrow {
297 image: url(:/qss_icons/rc/right_arrow.png) 246 image: url(:/qss_icons/rc/right_arrow.png)
298} 247}
299 248
300 249QWidget:disabled {
301QWidget:disabled
302{
303 color: #454545; 250 color: #454545;
304 background-color: #31363b; 251 background-color: #31363b;
305} 252}
306 253
307QAbstractItemView 254QAbstractItemView {
308{
309 alternate-background-color: #31363b; 255 alternate-background-color: #31363b;
310 color: #eff0f1; 256 color: #eff0f1;
311 border: 1px solid 3A3939; 257 border: 1px solid #3A3939;
312 border-radius: 2px; 258 border-radius: 2px;
313} 259}
314 260
315QWidget:focus, QMenuBar:focus 261QWidget:focus,
316{ 262QMenuBar:focus {
317 border: 1px solid #3daee9; 263 border: 1px solid #3daee9;
318} 264}
319 265
320QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus 266QTabWidget:focus,
321{ 267QCheckBox:focus,
268QRadioButton:focus,
269QSlider:focus {
322 border: none; 270 border: none;
323} 271}
324 272
325QLineEdit 273QLineEdit {
326{
327 background-color: #232629; 274 background-color: #232629;
328 padding: 5px; 275 padding: 5px;
329 border-style: solid; 276 border-style: solid;
@@ -332,13 +279,12 @@ QLineEdit
332 color: #eff0f1; 279 color: #eff0f1;
333} 280}
334 281
335QAbstractItemView QLineEdit 282QAbstractItemView QLineEdit {
336{
337 padding: 0; 283 padding: 0;
338} 284}
339 285
340QGroupBox { 286QGroupBox {
341 border:1px solid #76797C; 287 border: 1px solid #76797C;
342 border-radius: 2px; 288 border-radius: 2px;
343 margin-top: 20px; 289 margin-top: 20px;
344} 290}
@@ -351,15 +297,13 @@ QGroupBox::title {
351 padding-top: 10px; 297 padding-top: 10px;
352} 298}
353 299
354QAbstractScrollArea 300QAbstractScrollArea {
355{
356 border-radius: 2px; 301 border-radius: 2px;
357 border: 1px solid #76797C; 302 border: 1px solid #76797C;
358 background-color: transparent; 303 background-color: transparent;
359} 304}
360 305
361QScrollBar:horizontal 306QScrollBar:horizontal {
362{
363 height: 15px; 307 height: 15px;
364 margin: 3px 15px 3px 15px; 308 margin: 3px 15px 3px 15px;
365 border: 1px transparent #2A2929; 309 border: 1px transparent #2A2929;
@@ -367,15 +311,13 @@ QScrollBar:horizontal
367 background-color: #2A2929; 311 background-color: #2A2929;
368} 312}
369 313
370QScrollBar::handle:horizontal 314QScrollBar::handle:horizontal {
371{
372 background-color: #605F5F; 315 background-color: #605F5F;
373 min-width: 5px; 316 min-width: 5px;
374 border-radius: 4px; 317 border-radius: 4px;
375} 318}
376 319
377QScrollBar::add-line:horizontal 320QScrollBar::add-line:horizontal {
378{
379 margin: 0px 3px 0px 3px; 321 margin: 0px 3px 0px 3px;
380 border-image: url(:/qss_icons/rc/right_arrow_disabled.png); 322 border-image: url(:/qss_icons/rc/right_arrow_disabled.png);
381 width: 10px; 323 width: 10px;
@@ -384,8 +326,7 @@ QScrollBar::add-line:horizontal
384 subcontrol-origin: margin; 326 subcontrol-origin: margin;
385} 327}
386 328
387QScrollBar::sub-line:horizontal 329QScrollBar::sub-line:horizontal {
388{
389 margin: 0px 3px 0px 3px; 330 margin: 0px 3px 0px 3px;
390 border-image: url(:/qss_icons/rc/left_arrow_disabled.png); 331 border-image: url(:/qss_icons/rc/left_arrow_disabled.png);
391 height: 10px; 332 height: 10px;
@@ -394,8 +335,8 @@ QScrollBar::sub-line:horizontal
394 subcontrol-origin: margin; 335 subcontrol-origin: margin;
395} 336}
396 337
397QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on 338QScrollBar::add-line:horizontal:hover,
398{ 339QScrollBar::add-line:horizontal:on {
399 border-image: url(:/qss_icons/rc/right_arrow.png); 340 border-image: url(:/qss_icons/rc/right_arrow.png);
400 height: 10px; 341 height: 10px;
401 width: 10px; 342 width: 10px;
@@ -403,9 +344,8 @@ QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on
403 subcontrol-origin: margin; 344 subcontrol-origin: margin;
404} 345}
405 346
406 347QScrollBar::sub-line:horizontal:hover,
407QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on 348QScrollBar::sub-line:horizontal:on {
408{
409 border-image: url(:/qss_icons/rc/left_arrow.png); 349 border-image: url(:/qss_icons/rc/left_arrow.png);
410 height: 10px; 350 height: 10px;
411 width: 10px; 351 width: 10px;
@@ -413,19 +353,17 @@ QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on
413 subcontrol-origin: margin; 353 subcontrol-origin: margin;
414} 354}
415 355
416QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal 356QScrollBar::up-arrow:horizontal,
417{ 357QScrollBar::down-arrow:horizontal {
418 background: none; 358 background: none;
419} 359}
420 360
421 361QScrollBar::add-page:horizontal,
422QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal 362QScrollBar::sub-page:horizontal {
423{
424 background: none; 363 background: none;
425} 364}
426 365
427QScrollBar:vertical 366QScrollBar:vertical {
428{
429 background-color: #2A2929; 367 background-color: #2A2929;
430 width: 15px; 368 width: 15px;
431 margin: 15px 3px 15px 3px; 369 margin: 15px 3px 15px 3px;
@@ -433,15 +371,13 @@ QScrollBar:vertical
433 border-radius: 4px; 371 border-radius: 4px;
434} 372}
435 373
436QScrollBar::handle:vertical 374QScrollBar::handle:vertical {
437{
438 background-color: #605F5F; 375 background-color: #605F5F;
439 min-height: 5px; 376 min-height: 5px;
440 border-radius: 4px; 377 border-radius: 4px;
441} 378}
442 379
443QScrollBar::sub-line:vertical 380QScrollBar::sub-line:vertical {
444{
445 margin: 3px 0px 3px 0px; 381 margin: 3px 0px 3px 0px;
446 border-image: url(:/qss_icons/rc/up_arrow_disabled.png); 382 border-image: url(:/qss_icons/rc/up_arrow_disabled.png);
447 height: 10px; 383 height: 10px;
@@ -450,8 +386,7 @@ QScrollBar::sub-line:vertical
450 subcontrol-origin: margin; 386 subcontrol-origin: margin;
451} 387}
452 388
453QScrollBar::add-line:vertical 389QScrollBar::add-line:vertical {
454{
455 margin: 3px 0px 3px 0px; 390 margin: 3px 0px 3px 0px;
456 border-image: url(:/qss_icons/rc/down_arrow_disabled.png); 391 border-image: url(:/qss_icons/rc/down_arrow_disabled.png);
457 height: 10px; 392 height: 10px;
@@ -460,9 +395,8 @@ QScrollBar::add-line:vertical
460 subcontrol-origin: margin; 395 subcontrol-origin: margin;
461} 396}
462 397
463QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on 398QScrollBar::sub-line:vertical:hover,
464{ 399QScrollBar::sub-line:vertical:on {
465
466 border-image: url(:/qss_icons/rc/up_arrow.png); 400 border-image: url(:/qss_icons/rc/up_arrow.png);
467 height: 10px; 401 height: 10px;
468 width: 10px; 402 width: 10px;
@@ -470,9 +404,8 @@ QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on
470 subcontrol-origin: margin; 404 subcontrol-origin: margin;
471} 405}
472 406
473 407QScrollBar::add-line:vertical:hover,
474QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on 408QScrollBar::add-line:vertical:on {
475{
476 border-image: url(:/qss_icons/rc/down_arrow.png); 409 border-image: url(:/qss_icons/rc/down_arrow.png);
477 height: 10px; 410 height: 10px;
478 width: 10px; 411 width: 10px;
@@ -480,34 +413,31 @@ QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on
480 subcontrol-origin: margin; 413 subcontrol-origin: margin;
481} 414}
482 415
483QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical 416QScrollBar::up-arrow:vertical,
484{ 417QScrollBar::down-arrow:vertical {
485 background: none; 418 background: none;
486} 419}
487 420
488 421QScrollBar::add-page:vertical,
489QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical 422QScrollBar::sub-page:vertical {
490{
491 background: none; 423 background: none;
492} 424}
493 425
494QTextEdit 426QTextEdit {
495{
496 background-color: #232629; 427 background-color: #232629;
497 color: #eff0f1; 428 color: #eff0f1;
498 border: 1px solid #76797C; 429 border: 1px solid #76797C;
499} 430}
500 431
501QPlainTextEdit 432QPlainTextEdit {
502{ 433 background-color: #232629;
503 background-color: #232629;; 434 ;
504 color: #eff0f1; 435 color: #eff0f1;
505 border-radius: 2px; 436 border-radius: 2px;
506 border: 1px solid #76797C; 437 border: 1px solid #76797C;
507} 438}
508 439
509QHeaderView::section 440QHeaderView::section {
510{
511 background-color: #76797C; 441 background-color: #76797C;
512 color: #eff0f1; 442 color: #eff0f1;
513 padding: 5px; 443 padding: 5px;
@@ -520,9 +450,7 @@ QSizeGrip {
520 height: 12px; 450 height: 12px;
521} 451}
522 452
523 453QMainWindow::separator {
524QMainWindow::separator
525{
526 background-color: #31363b; 454 background-color: #31363b;
527 color: white; 455 color: white;
528 padding-left: 4px; 456 padding-left: 4px;
@@ -530,9 +458,7 @@ QMainWindow::separator
530 border: 1px dashed #76797C; 458 border: 1px dashed #76797C;
531} 459}
532 460
533QMainWindow::separator:hover 461QMainWindow::separator:hover {
534{
535
536 background-color: #787876; 462 background-color: #787876;
537 color: white; 463 color: white;
538 padding-left: 4px; 464 padding-left: 4px;
@@ -540,9 +466,7 @@ QMainWindow::separator:hover
540 spacing: 2px; 466 spacing: 2px;
541} 467}
542 468
543 469QMenu::separator {
544QMenu::separator
545{
546 height: 1px; 470 height: 1px;
547 background-color: #76797C; 471 background-color: #76797C;
548 color: white; 472 color: white;
@@ -551,21 +475,17 @@ QMenu::separator
551 margin-right: 5px; 475 margin-right: 5px;
552} 476}
553 477
554 478QFrame {
555QFrame
556{
557 border-radius: 2px; 479 border-radius: 2px;
558 border: 1px solid #76797C; 480 border: 1px solid #76797C;
559} 481}
560 482
561QFrame[frameShape="0"] 483QFrame[frameShape="0"] {
562{
563 border-radius: 2px; 484 border-radius: 2px;
564 border: 1px transparent #76797C; 485 border: 1px transparent #76797C;
565} 486}
566 487
567QStackedWidget 488QStackedWidget {
568{
569 border: 1px transparent black; 489 border: 1px transparent black;
570} 490}
571 491
@@ -578,21 +498,24 @@ QToolBar {
578QToolBar::handle:horizontal { 498QToolBar::handle:horizontal {
579 image: url(:/qss_icons/rc/Hmovetoolbar.png); 499 image: url(:/qss_icons/rc/Hmovetoolbar.png);
580} 500}
501
581QToolBar::handle:vertical { 502QToolBar::handle:vertical {
582 image: url(:/qss_icons/rc/Vmovetoolbar.png); 503 image: url(:/qss_icons/rc/Vmovetoolbar.png);
583} 504}
505
584QToolBar::separator:horizontal { 506QToolBar::separator:horizontal {
585 image: url(:/qss_icons/rc/Hsepartoolbar.png); 507 image: url(:/qss_icons/rc/Hsepartoolbar.png);
586} 508}
509
587QToolBar::separator:vertical { 510QToolBar::separator:vertical {
588 image: url(:/qss_icons/rc/Vsepartoolbar.png); 511 image: url(:/qss_icons/rc/Vsepartoolbar.png);
589} 512}
513
590QToolButton#qt_toolbar_ext_button { 514QToolButton#qt_toolbar_ext_button {
591 background: #58595a 515 background: #58595a
592} 516}
593 517
594QPushButton 518QPushButton {
595{
596 color: #eff0f1; 519 color: #eff0f1;
597 background-color: #31363b; 520 background-color: #31363b;
598 border-width: 1px; 521 border-width: 1px;
@@ -603,8 +526,7 @@ QPushButton
603 outline: none; 526 outline: none;
604} 527}
605 528
606QPushButton:disabled 529QPushButton:disabled {
607{
608 background-color: #31363b; 530 background-color: #31363b;
609 border-width: 1px; 531 border-width: 1px;
610 border-color: #454545; 532 border-color: #454545;
@@ -622,15 +544,13 @@ QPushButton:focus {
622 color: white; 544 color: white;
623} 545}
624 546
625QPushButton:pressed 547QPushButton:pressed {
626{
627 background-color: #3daee9; 548 background-color: #3daee9;
628 padding-top: -15px; 549 padding-top: -15px;
629 padding-bottom: -17px; 550 padding-bottom: -17px;
630} 551}
631 552
632QComboBox 553QComboBox {
633{
634 selection-background-color: #3daee9; 554 selection-background-color: #3daee9;
635 border-style: solid; 555 border-style: solid;
636 border: 1px solid #76797C; 556 border: 1px solid #76797C;
@@ -639,38 +559,40 @@ QComboBox
639 min-width: 75px; 559 min-width: 75px;
640} 560}
641 561
642QPushButton:checked{ 562QPushButton:checked {
643 background-color: #76797C; 563 background-color: #76797C;
644 border-color: #6A6969; 564 border-color: #6A6969;
645} 565}
646 566
647QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover 567QComboBox:hover,
648{ 568QPushButton:hover,
569QAbstractSpinBox:hover,
570QLineEdit:hover,
571QTextEdit:hover,
572QPlainTextEdit:hover,
573QAbstractView:hover,
574QTreeView:hover {
649 border: 1px solid #3daee9; 575 border: 1px solid #3daee9;
650 color: #eff0f1; 576 color: #eff0f1;
651} 577}
652 578
653QComboBox:on 579QComboBox:on {
654{
655 padding-top: 3px; 580 padding-top: 3px;
656 padding-left: 4px; 581 padding-left: 4px;
657 selection-background-color: #4a4a4a; 582 selection-background-color: #4a4a4a;
658} 583}
659 584
660QComboBox QAbstractItemView 585QComboBox QAbstractItemView {
661{
662 background-color: #232629; 586 background-color: #232629;
663 border-radius: 2px; 587 border-radius: 2px;
664 border: 1px solid #76797C; 588 border: 1px solid #76797C;
665 selection-background-color: #18465d; 589 selection-background-color: #18465d;
666} 590}
667 591
668QComboBox::drop-down 592QComboBox::drop-down {
669{
670 subcontrol-origin: padding; 593 subcontrol-origin: padding;
671 subcontrol-position: top right; 594 subcontrol-position: top right;
672 width: 15px; 595 width: 15px;
673
674 border-left-width: 0px; 596 border-left-width: 0px;
675 border-left-color: darkgray; 597 border-left-color: darkgray;
676 border-left-style: solid; 598 border-left-style: solid;
@@ -678,14 +600,13 @@ QComboBox::drop-down
678 border-bottom-right-radius: 3px; 600 border-bottom-right-radius: 3px;
679} 601}
680 602
681QComboBox::down-arrow 603QComboBox::down-arrow {
682{
683 image: url(:/qss_icons/rc/down_arrow_disabled.png); 604 image: url(:/qss_icons/rc/down_arrow_disabled.png);
684} 605}
685 606
686QComboBox::down-arrow:on, QComboBox::down-arrow:hover, 607QComboBox::down-arrow:on,
687QComboBox::down-arrow:focus 608QComboBox::down-arrow:hover,
688{ 609QComboBox::down-arrow:focus {
689 image: url(:/qss_icons/rc/down_arrow.png); 610 image: url(:/qss_icons/rc/down_arrow.png);
690} 611}
691 612
@@ -698,49 +619,47 @@ QAbstractSpinBox {
698 min-width: 75px; 619 min-width: 75px;
699} 620}
700 621
701QAbstractSpinBox:up-button 622QAbstractSpinBox:up-button {
702{
703 background-color: transparent; 623 background-color: transparent;
704 subcontrol-origin: border; 624 subcontrol-origin: border;
705 subcontrol-position: center right; 625 subcontrol-position: center right;
706} 626}
707 627
708QAbstractSpinBox:down-button 628QAbstractSpinBox:down-button {
709{
710 background-color: transparent; 629 background-color: transparent;
711 subcontrol-origin: border; 630 subcontrol-origin: border;
712 subcontrol-position: center left; 631 subcontrol-position: center left;
713} 632}
714 633
715QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { 634QAbstractSpinBox::up-arrow,
635QAbstractSpinBox::up-arrow:disabled,
636QAbstractSpinBox::up-arrow:off {
716 image: url(:/qss_icons/rc/up_arrow_disabled.png); 637 image: url(:/qss_icons/rc/up_arrow_disabled.png);
717 width: 10px; 638 width: 10px;
718 height: 10px; 639 height: 10px;
719} 640}
720QAbstractSpinBox::up-arrow:hover 641
721{ 642QAbstractSpinBox::up-arrow:hover {
722 image: url(:/qss_icons/rc/up_arrow.png); 643 image: url(:/qss_icons/rc/up_arrow.png);
723} 644}
724 645
725 646QAbstractSpinBox::down-arrow,
726QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off 647QAbstractSpinBox::down-arrow:disabled,
727{ 648QAbstractSpinBox::down-arrow:off {
728 image: url(:/qss_icons/rc/down_arrow_disabled.png); 649 image: url(:/qss_icons/rc/down_arrow_disabled.png);
729 width: 10px; 650 width: 10px;
730 height: 10px; 651 height: 10px;
731} 652}
732QAbstractSpinBox::down-arrow:hover 653
733{ 654QAbstractSpinBox::down-arrow:hover {
734 image: url(:/qss_icons/rc/down_arrow.png); 655 image: url(:/qss_icons/rc/down_arrow.png);
735} 656}
736 657
737 658QLabel {
738QLabel
739{
740 border: 0px solid black; 659 border: 0px solid black;
741} 660}
742 661
743QTabWidget{ 662QTabWidget {
744 border: 0px transparent black; 663 border: 0px transparent black;
745} 664}
746 665
@@ -751,27 +670,24 @@ QTabWidget::pane {
751} 670}
752 671
753QTabWidget::tab-bar { 672QTabWidget::tab-bar {
754 left: 5px; /* move to the right by 5px */ 673 /* left: 5px; move to the right by 5px */
755} 674}
756 675
757QTabBar 676QTabBar {
758{
759 qproperty-drawBase: 0; 677 qproperty-drawBase: 0;
760 border-radius: 3px; 678 border-radius: 3px;
761} 679}
762 680
763QTabBar:focus 681QTabBar:focus {
764{
765 border: 0px transparent black; 682 border: 0px transparent black;
766} 683}
767 684
768QTabBar::close-button { 685QTabBar::close-button {
769 image: url(:/qss_icons/rc/close.png); 686 image: url(:/qss_icons/rc/close.png);
770 background: transparent; 687 background: transparent;
771} 688}
772 689
773QTabBar::close-button:hover 690QTabBar::close-button:hover {
774{
775 image: url(:/qss_icons/rc/close-hover.png); 691 image: url(:/qss_icons/rc/close-hover.png);
776 background: transparent; 692 background: transparent;
777} 693}
@@ -781,7 +697,9 @@ QTabBar::close-button:pressed {
781 background: transparent; 697 background: transparent;
782} 698}
783 699
700
784/* TOP TABS */ 701/* TOP TABS */
702
785QTabBar::tab:top { 703QTabBar::tab:top {
786 color: #eff0f1; 704 color: #eff0f1;
787 border: 1px solid #76797C; 705 border: 1px solid #76797C;
@@ -793,12 +711,11 @@ QTabBar::tab:top {
793 border-top-right-radius: 2px; 711 border-top-right-radius: 2px;
794} 712}
795 713
796QTabBar::tab:top:!selected 714QTabBar::tab:top:selected {
797{
798 color: #eff0f1; 715 color: #eff0f1;
799 background-color: #54575B; 716 background-color: #54575B;
800 border: 1px solid #76797C; 717 border: 1px solid #76797C;
801 border-bottom: 1px transparent black; 718 border-bottom: 2px solid #3daee9;
802 border-top-left-radius: 2px; 719 border-top-left-radius: 2px;
803 border-top-right-radius: 2px; 720 border-top-right-radius: 2px;
804} 721}
@@ -807,7 +724,9 @@ QTabBar::tab:top:!selected:hover {
807 background-color: #3daee9; 724 background-color: #3daee9;
808} 725}
809 726
727
810/* BOTTOM TABS */ 728/* BOTTOM TABS */
729
811QTabBar::tab:bottom { 730QTabBar::tab:bottom {
812 color: #eff0f1; 731 color: #eff0f1;
813 border: 1px solid #76797C; 732 border: 1px solid #76797C;
@@ -819,12 +738,11 @@ QTabBar::tab:bottom {
819 min-width: 50px; 738 min-width: 50px;
820} 739}
821 740
822QTabBar::tab:bottom:!selected 741QTabBar::tab:bottom:selected {
823{
824 color: #eff0f1; 742 color: #eff0f1;
825 background-color: #54575B; 743 background-color: #54575B;
826 border: 1px solid #76797C; 744 border: 1px solid #76797C;
827 border-top: 1px transparent black; 745 border-top: 2px solid #3daee9;
828 border-bottom-left-radius: 2px; 746 border-bottom-left-radius: 2px;
829 border-bottom-right-radius: 2px; 747 border-bottom-right-radius: 2px;
830} 748}
@@ -833,7 +751,9 @@ QTabBar::tab:bottom:!selected:hover {
833 background-color: #3daee9; 751 background-color: #3daee9;
834} 752}
835 753
754
836/* LEFT TABS */ 755/* LEFT TABS */
756
837QTabBar::tab:left { 757QTabBar::tab:left {
838 color: #eff0f1; 758 color: #eff0f1;
839 border: 1px solid #76797C; 759 border: 1px solid #76797C;
@@ -845,12 +765,11 @@ QTabBar::tab:left {
845 min-height: 50px; 765 min-height: 50px;
846} 766}
847 767
848QTabBar::tab:left:!selected 768QTabBar::tab:left:selected {
849{
850 color: #eff0f1; 769 color: #eff0f1;
851 background-color: #54575B; 770 background-color: #54575B;
852 border: 1px solid #76797C; 771 border: 1px solid #76797C;
853 border-left: 1px transparent black; 772 border-left: 2px solid #3daee9;
854 border-top-right-radius: 2px; 773 border-top-right-radius: 2px;
855 border-bottom-right-radius: 2px; 774 border-bottom-right-radius: 2px;
856} 775}
@@ -861,6 +780,7 @@ QTabBar::tab:left:!selected:hover {
861 780
862 781
863/* RIGHT TABS */ 782/* RIGHT TABS */
783
864QTabBar::tab:right { 784QTabBar::tab:right {
865 color: #eff0f1; 785 color: #eff0f1;
866 border: 1px solid #76797C; 786 border: 1px solid #76797C;
@@ -872,12 +792,11 @@ QTabBar::tab:right {
872 min-height: 50px; 792 min-height: 50px;
873} 793}
874 794
875QTabBar::tab:right:!selected 795QTabBar::tab:right:selected {
876{
877 color: #eff0f1; 796 color: #eff0f1;
878 background-color: #54575B; 797 background-color: #54575B;
879 border: 1px solid #76797C; 798 border: 1px solid #76797C;
880 border-right: 1px transparent black; 799 border-right: 2px solid #3daee9;
881 border-top-left-radius: 2px; 800 border-top-left-radius: 2px;
882 border-bottom-left-radius: 2px; 801 border-bottom-left-radius: 2px;
883} 802}
@@ -887,21 +806,20 @@ QTabBar::tab:right:!selected:hover {
887} 806}
888 807
889QTabBar QToolButton::right-arrow:enabled { 808QTabBar QToolButton::right-arrow:enabled {
890 image: url(:/qss_icons/rc/right_arrow.png); 809 image: url(:/qss_icons/rc/right_arrow.png);
891 } 810}
892 811
893 QTabBar QToolButton::left-arrow:enabled { 812QTabBar QToolButton::left-arrow:enabled {
894 image: url(:/qss_icons/rc/left_arrow.png); 813 image: url(:/qss_icons/rc/left_arrow.png);
895 } 814}
896 815
897QTabBar QToolButton::right-arrow:disabled { 816QTabBar QToolButton::right-arrow:disabled {
898 image: url(:/qss_icons/rc/right_arrow_disabled.png); 817 image: url(:/qss_icons/rc/right_arrow_disabled.png);
899 } 818}
900
901 QTabBar QToolButton::left-arrow:disabled {
902 image: url(:/qss_icons/rc/left_arrow_disabled.png);
903 }
904 819
820QTabBar QToolButton::left-arrow:disabled {
821 image: url(:/qss_icons/rc/left_arrow_disabled.png);
822}
905 823
906QDockWidget { 824QDockWidget {
907 background: #31363b; 825 background: #31363b;
@@ -910,29 +828,32 @@ QDockWidget {
910 titlebar-normal-icon: url(:/qss_icons/rc/undock.png); 828 titlebar-normal-icon: url(:/qss_icons/rc/undock.png);
911} 829}
912 830
913QDockWidget::close-button, QDockWidget::float-button { 831QDockWidget::close-button,
832QDockWidget::float-button {
914 border: 1px solid transparent; 833 border: 1px solid transparent;
915 border-radius: 2px; 834 border-radius: 2px;
916 background: transparent; 835 background: transparent;
917} 836}
918 837
919QDockWidget::close-button:hover, QDockWidget::float-button:hover { 838QDockWidget::close-button:hover,
839QDockWidget::float-button:hover {
920 background: rgba(255, 255, 255, 10); 840 background: rgba(255, 255, 255, 10);
921} 841}
922 842
923QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { 843QDockWidget::close-button:pressed,
844QDockWidget::float-button:pressed {
924 padding: 1px -1px -1px 1px; 845 padding: 1px -1px -1px 1px;
925 background: rgba(255, 255, 255, 10); 846 background: rgba(255, 255, 255, 10);
926} 847}
927 848
928QTreeView, QListView 849QTreeView,
929{ 850QListView {
930 border: 1px solid #76797C; 851 border: 1px solid #76797C;
931 background-color: #232629; 852 background-color: #232629;
932} 853}
933 854
934QTreeView:branch:selected, QTreeView:branch:hover 855QTreeView:branch:selected,
935{ 856QTreeView:branch:hover {
936 background: url(:/qss_icons/rc/transparent.png); 857 background: url(:/qss_icons/rc/transparent.png);
937} 858}
938 859
@@ -954,31 +875,75 @@ QTreeView::branch:closed:has-children:has-siblings {
954} 875}
955 876
956QTreeView::branch:open:has-children:!has-siblings, 877QTreeView::branch:open:has-children:!has-siblings,
957QTreeView::branch:open:has-children:has-siblings { 878QTreeView::branch:open:has-children:has-siblings {
958 image: url(:/qss_icons/rc/branch_open.png); 879 image: url(:/qss_icons/rc/branch_open.png);
959} 880}
960 881
961QTreeView::branch:has-children:!has-siblings:closed:hover, 882QTreeView::branch:has-children:!has-siblings:closed:hover,
962QTreeView::branch:closed:has-children:has-siblings:hover { 883QTreeView::branch:closed:has-children:has-siblings:hover {
963 image: url(:/qss_icons/rc/branch_closed-on.png); 884 image: url(:/qss_icons/rc/branch_closed-on.png);
964 } 885}
965 886
966QTreeView::branch:open:has-children:!has-siblings:hover, 887QTreeView::branch:open:has-children:!has-siblings:hover,
967QTreeView::branch:open:has-children:has-siblings:hover { 888QTreeView::branch:open:has-children:has-siblings:hover {
968 image: url(:/qss_icons/rc/branch_open-on.png); 889 image: url(:/qss_icons/rc/branch_open-on.png);
969 } 890}
970 891
971QListView::item:!selected:hover, QTreeView::item:!selected:hover { 892QListView::item:!selected:hover,
893QTreeView::item:!selected:hover {
972 background: #18465d; 894 background: #18465d;
973 outline: 0; 895 outline: 0;
974 color: #eff0f1 896 color: #eff0f1
975} 897}
976 898
977QListView::item:selected:hover, QTreeView::item:selected:hover { 899QListView::item:selected:hover,
900QTreeView::item:selected:hover {
978 background: #287399; 901 background: #287399;
979 color: #eff0f1; 902 color: #eff0f1;
980} 903}
981 904
905QTreeView::indicator:checked,
906QListView::indicator:checked {
907 image: url(:/qss_icons/rc/checkbox_checked.png);
908}
909
910QTreeView::indicator:unchecked,
911QListView::indicator:unchecked {
912 image: url(:/qss_icons/rc/checkbox_unchecked.png);
913}
914
915QTreeView::indicator:indeterminate,
916QListView::indicator:indeterminate {
917 image: url(:/qss_icons/rc/checkbox_indeterminate.png);
918}
919
920QTreeView::indicator:checked:hover,
921QTreeView::indicator:checked:focus,
922QTreeView::indicator:checked:pressed,
923QListView::indicator:checked:hover,
924QListView::indicator:checked:focus,
925QListView::indicator:checked:pressed {
926 image: url(:/qss_icons/rc/checkbox_checked_focus.png);
927}
928
929QTreeView::indicator:unchecked:hover,
930QTreeView::indicator:unchecked:focus,
931QTreeView::indicator:unchecked:pressed,
932QListView::indicator:unchecked:hover,
933QListView::indicator:unchecked:focus,
934QListView::indicator:unchecked:pressed {
935 image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
936}
937
938QTreeView::indicator:indeterminate:hover,
939QTreeView::indicator:indeterminate:focus,
940QTreeView::indicator:indeterminate:pressed,
941QListView::indicator:indeterminate:hover,
942QListView::indicator:indeterminate:focus,
943QListView::indicator:indeterminate:pressed {
944 image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
945}
946
982QSlider::groove:horizontal { 947QSlider::groove:horizontal {
983 border: 1px solid #565a5e; 948 border: 1px solid #565a5e;
984 height: 4px; 949 height: 4px;
@@ -1021,38 +986,49 @@ QToolButton {
1021 padding: 5px; 986 padding: 5px;
1022} 987}
1023 988
1024QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ 989QToolButton[popupMode="1"] {
1025 padding-right: 20px; /* make way for the popup button */ 990 /* only for MenuButtonPopup */
1026 border: 1px #76797C; 991 padding-right: 20px;
1027 border-radius: 5px; 992 /* make way for the popup button */
993 border: 1px #76797C;
994 border-radius: 5px;
1028} 995}
1029 996
1030QToolButton[popupMode="2"] { /* only for InstantPopup */ 997QToolButton[popupMode="2"] {
1031 padding-right: 10px; /* make way for the popup button */ 998 /* only for InstantPopup */
1032 border: 1px #76797C; 999 padding-right: 10px;
1000 /* make way for the popup button */
1001 border: 1px #76797C;
1033} 1002}
1034 1003
1035 1004QToolButton:hover,
1036QToolButton:hover, QToolButton::menu-button:hover { 1005QToolButton::menu-button:hover {
1037 background-color: transparent; 1006 background-color: transparent;
1038 border: 1px solid #3daee9; 1007 border: 1px solid #3daee9;
1039 padding: 5px; 1008 padding: 5px;
1040} 1009}
1041 1010
1042QToolButton:checked, QToolButton:pressed, 1011QToolButton:checked,
1043 QToolButton::menu-button:pressed { 1012QToolButton:pressed,
1013QToolButton::menu-button:pressed {
1044 background-color: #3daee9; 1014 background-color: #3daee9;
1045 border: 1px solid #3daee9; 1015 border: 1px solid #3daee9;
1046 padding: 5px; 1016 padding: 5px;
1047} 1017}
1048 1018
1019
1049/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ 1020/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */
1021
1050QToolButton::menu-indicator { 1022QToolButton::menu-indicator {
1051 image: url(:/qss_icons/rc/down_arrow.png); 1023 image: url(:/qss_icons/rc/down_arrow.png);
1052 top: -7px; left: -2px; /* shift it a bit */ 1024 top: -7px;
1025 left: -2px;
1026 /* shift it a bit */
1053} 1027}
1054 1028
1029
1055/* the subcontrols below are used only in the MenuButtonPopup mode */ 1030/* the subcontrols below are used only in the MenuButtonPopup mode */
1031
1056QToolButton::menu-button { 1032QToolButton::menu-button {
1057 border: 1px transparent #76797C; 1033 border: 1px transparent #76797C;
1058 border-top-right-radius: 6px; 1034 border-top-right-radius: 6px;
@@ -1070,47 +1046,46 @@ QToolButton::menu-arrow:open {
1070 border: 1px solid #76797C; 1046 border: 1px solid #76797C;
1071} 1047}
1072 1048
1073QPushButton::menu-indicator { 1049QPushButton::menu-indicator {
1074 subcontrol-origin: padding; 1050 subcontrol-origin: padding;
1075 subcontrol-position: bottom right; 1051 subcontrol-position: bottom right;
1076 left: 8px; 1052 left: 8px;
1077} 1053}
1078 1054
1079QTableView 1055QTableView {
1080{
1081 border: 1px solid #76797C; 1056 border: 1px solid #76797C;
1082 gridline-color: #31363b; 1057 gridline-color: #31363b;
1083 background-color: #232629; 1058 background-color: #232629;
1084} 1059}
1085 1060
1086 1061QTableView,
1087QTableView, QHeaderView 1062QHeaderView {
1088{
1089 border-radius: 0px; 1063 border-radius: 0px;
1090} 1064}
1091 1065
1092QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed { 1066QTableView::item:pressed,
1067QListView::item:pressed,
1068QTreeView::item:pressed {
1093 background: #18465d; 1069 background: #18465d;
1094 color: #eff0f1; 1070 color: #eff0f1;
1095} 1071}
1096 1072
1097QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active { 1073QTableView::item:selected:active,
1074QTreeView::item:selected:active,
1075QListView::item:selected:active {
1098 background: #287399; 1076 background: #287399;
1099 color: #eff0f1; 1077 color: #eff0f1;
1100} 1078}
1101 1079
1102 1080QHeaderView {
1103QHeaderView
1104{
1105 background-color: #31363b; 1081 background-color: #31363b;
1106 border: 1px transparent; 1082 border: 1px transparent;
1107 border-radius: 0px; 1083 border-radius: 0px;
1108 margin: 0px; 1084 margin: 0px;
1109 padding: 0px; 1085 padding: 0px;
1110
1111} 1086}
1112 1087
1113QHeaderView::section { 1088QHeaderView::section {
1114 background-color: #31363b; 1089 background-color: #31363b;
1115 color: #eff0f1; 1090 color: #eff0f1;
1116 padding: 5px; 1091 padding: 5px;
@@ -1119,34 +1094,32 @@ QHeaderView::section {
1119 text-align: center; 1094 text-align: center;
1120} 1095}
1121 1096
1122QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one 1097QHeaderView::section::vertical::first,
1123{ 1098QHeaderView::section::vertical::only-one {
1124 border-top: 1px solid #76797C; 1099 border-top: 1px solid #76797C;
1125} 1100}
1126 1101
1127QHeaderView::section::vertical 1102QHeaderView::section::vertical {
1128{
1129 border-top: transparent; 1103 border-top: transparent;
1130} 1104}
1131 1105
1132QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one 1106QHeaderView::section::horizontal::first,
1133{ 1107QHeaderView::section::horizontal::only-one {
1134 border-left: 1px solid #76797C; 1108 border-left: 1px solid #76797C;
1135} 1109}
1136 1110
1137QHeaderView::section::horizontal 1111QHeaderView::section::horizontal {
1138{
1139 border-left: transparent; 1112 border-left: transparent;
1140} 1113}
1141 1114
1142 1115QHeaderView::section:checked {
1143QHeaderView::section:checked
1144 {
1145 color: white; 1116 color: white;
1146 background-color: #334e5e; 1117 background-color: #334e5e;
1147 } 1118}
1119
1120
1121/* style the sort indicator */
1148 1122
1149 /* style the sort indicator */
1150QHeaderView::down-arrow { 1123QHeaderView::down-arrow {
1151 image: url(:/qss_icons/rc/down_arrow.png); 1124 image: url(:/qss_icons/rc/down_arrow.png);
1152} 1125}
@@ -1155,14 +1128,13 @@ QHeaderView::up-arrow {
1155 image: url(:/qss_icons/rc/up_arrow.png); 1128 image: url(:/qss_icons/rc/up_arrow.png);
1156} 1129}
1157 1130
1158
1159QTableCornerButton::section { 1131QTableCornerButton::section {
1160 background-color: #31363b; 1132 background-color: #31363b;
1161 border: 1px transparent #76797C; 1133 border: 1px transparent #76797C;
1162 border-radius: 0px; 1134 border-radius: 0px;
1163} 1135}
1164 1136
1165QToolBox { 1137QToolBox {
1166 padding: 5px; 1138 padding: 5px;
1167 border: 1px transparent black; 1139 border: 1px transparent black;
1168} 1140}
@@ -1176,22 +1148,22 @@ QToolBox::tab {
1176 border-top-right-radius: 5px; 1148 border-top-right-radius: 5px;
1177} 1149}
1178 1150
1179QToolBox::tab:selected { /* italicize selected tabs */ 1151QToolBox::tab:selected {
1152 /* italicize selected tabs */
1180 font: italic; 1153 font: italic;
1181 background-color: #31363b; 1154 background-color: #31363b;
1182 border-color: #3daee9; 1155 border-color: #3daee9;
1183 } 1156}
1184 1157
1185QStatusBar::item { 1158QStatusBar::item {
1186 border: 0px transparent dark; 1159 border: 0px transparent dark;
1187 } 1160}
1188
1189 1161
1190QFrame[height="3"], QFrame[width="3"] { 1162QFrame[height="3"],
1163QFrame[width="3"] {
1191 background-color: #76797C; 1164 background-color: #76797C;
1192} 1165}
1193 1166
1194
1195QSplitter::handle { 1167QSplitter::handle {
1196 border: 1px dashed #76797C; 1168 border: 1px dashed #76797C;
1197} 1169}
@@ -1219,8 +1191,7 @@ QProgressBar::chunk {
1219 background-color: #05B8CC; 1191 background-color: #05B8CC;
1220} 1192}
1221 1193
1222QDateEdit 1194QDateEdit {
1223{
1224 selection-background-color: #3daee9; 1195 selection-background-color: #3daee9;
1225 border-style: solid; 1196 border-style: solid;
1226 border: 1px solid #3375A3; 1197 border: 1px solid #3375A3;
@@ -1229,23 +1200,20 @@ QDateEdit
1229 min-width: 75px; 1200 min-width: 75px;
1230} 1201}
1231 1202
1232QDateEdit:on 1203QDateEdit:on {
1233{
1234 padding-top: 3px; 1204 padding-top: 3px;
1235 padding-left: 4px; 1205 padding-left: 4px;
1236 selection-background-color: #4a4a4a; 1206 selection-background-color: #4a4a4a;
1237} 1207}
1238 1208
1239QDateEdit QAbstractItemView 1209QDateEdit QAbstractItemView {
1240{
1241 background-color: #232629; 1210 background-color: #232629;
1242 border-radius: 2px; 1211 border-radius: 2px;
1243 border: 1px solid #3375A3; 1212 border: 1px solid #3375A3;
1244 selection-background-color: #3daee9; 1213 selection-background-color: #3daee9;
1245} 1214}
1246 1215
1247QDateEdit::drop-down 1216QDateEdit::drop-down {
1248{
1249 subcontrol-origin: padding; 1217 subcontrol-origin: padding;
1250 subcontrol-position: top right; 1218 subcontrol-position: top right;
1251 width: 15px; 1219 width: 15px;
@@ -1256,13 +1224,12 @@ QDateEdit::drop-down
1256 border-bottom-right-radius: 3px; 1224 border-bottom-right-radius: 3px;
1257} 1225}
1258 1226
1259QDateEdit::down-arrow 1227QDateEdit::down-arrow {
1260{
1261 image: url(:/qss_icons/rc/down_arrow_disabled.png); 1228 image: url(:/qss_icons/rc/down_arrow_disabled.png);
1262} 1229}
1263 1230
1264QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, 1231QDateEdit::down-arrow:on,
1265QDateEdit::down-arrow:focus 1232QDateEdit::down-arrow:hover,
1266{ 1233QDateEdit::down-arrow:focus {
1267 image: url(:/qss_icons/rc/down_arrow.png); 1234 image: url(:/qss_icons/rc/down_arrow.png);
1268} 1235}
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)
35add_subdirectory(lz4/contrib/cmake_unofficial) 35add_subdirectory(lz4/contrib/cmake_unofficial)
36target_include_directories(lz4_static INTERFACE ./lz4/lib) 36target_include_directories(lz4_static INTERFACE ./lz4/lib)
37 37
38# mbedtls
39add_subdirectory(mbedtls EXCLUDE_FROM_ALL)
40target_include_directories(mbedtls PUBLIC ./mbedtls/include)
41
38# MicroProfile 42# MicroProfile
39add_library(microprofile INTERFACE) 43add_library(microprofile INTERFACE)
40target_include_directories(microprofile INTERFACE ./microprofile) 44target_include_directories(microprofile INTERFACE ./microprofile)
@@ -50,3 +54,13 @@ if (ARCHITECTURE_x86_64)
50 target_include_directories(xbyak INTERFACE ./xbyak/xbyak) 54 target_include_directories(xbyak INTERFACE ./xbyak/xbyak)
51 target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES) 55 target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
52endif() 56endif()
57
58# Opus
59add_subdirectory(opus)
60target_include_directories(opus INTERFACE ./opus/include)
61
62# Cubeb
63if(ENABLE_CUBEB)
64 set(BUILD_TESTS OFF CACHE BOOL "")
65 add_subdirectory(cubeb EXCLUDE_FROM_ALL)
66endif()
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 @@
1/* 1/*
2 2
3 OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. 3 OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018.
4 4
5 Language/Generator: C/C++ 5 Language/Generator: C/C++
6 Specification: gl 6 Specification: gl
@@ -15,6 +15,7 @@
15 GL_AMD_debug_output, 15 GL_AMD_debug_output,
16 GL_AMD_depth_clamp_separate, 16 GL_AMD_depth_clamp_separate,
17 GL_AMD_draw_buffers_blend, 17 GL_AMD_draw_buffers_blend,
18 GL_AMD_framebuffer_multisample_advanced,
18 GL_AMD_framebuffer_sample_positions, 19 GL_AMD_framebuffer_sample_positions,
19 GL_AMD_gcn_shader, 20 GL_AMD_gcn_shader,
20 GL_AMD_gpu_shader_half_float, 21 GL_AMD_gpu_shader_half_float,
@@ -600,7 +601,7 @@
600 Omit khrplatform: False 601 Omit khrplatform: False
601 602
602 Commandline: 603 Commandline:
603 --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" 604 --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"
604 Online: 605 Online:
605 Too many extensions 606 Too many extensions
606*/ 607*/
@@ -1409,7 +1410,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void);
1409#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 1410#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
1410#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 1411#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
1411#define GL_MAX_SAMPLES 0x8D57 1412#define GL_MAX_SAMPLES 0x8D57
1412#define GL_INDEX 0x8222
1413#define GL_FRAMEBUFFER_SRGB 0x8DB9 1413#define GL_FRAMEBUFFER_SRGB 0x8DB9
1414#define GL_HALF_FLOAT 0x140B 1414#define GL_HALF_FLOAT 0x140B
1415#define GL_MAP_READ_BIT 0x0001 1415#define GL_MAP_READ_BIT 0x0001
@@ -2780,6 +2780,12 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
2780#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 2780#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
2781#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E 2781#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
2782#define GL_DEPTH_CLAMP_FAR_AMD 0x901F 2782#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
2783#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
2784#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
2785#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
2786#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
2787#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
2788#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
2783#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F 2789#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
2784#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE 2790#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE
2785#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF 2791#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF
@@ -3157,6 +3163,7 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
3157#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 3163#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
3158#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 3164#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
3159#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 3165#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
3166#define GL_INDEX 0x8222
3160#define GL_LINES_ADJACENCY_ARB 0x000A 3167#define GL_LINES_ADJACENCY_ARB 0x000A
3161#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B 3168#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
3162#define GL_TRIANGLES_ADJACENCY_ARB 0x000C 3169#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
@@ -6433,6 +6440,16 @@ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)(GLuint buf, GL
6433GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; 6440GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD;
6434#define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD 6441#define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD
6435#endif 6442#endif
6443#ifndef GL_AMD_framebuffer_multisample_advanced
6444#define GL_AMD_framebuffer_multisample_advanced 1
6445GLAPI int GLAD_GL_AMD_framebuffer_multisample_advanced;
6446typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
6447GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD;
6448#define glRenderbufferStorageMultisampleAdvancedAMD glad_glRenderbufferStorageMultisampleAdvancedAMD
6449typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
6450GLAPI PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD;
6451#define glNamedRenderbufferStorageMultisampleAdvancedAMD glad_glNamedRenderbufferStorageMultisampleAdvancedAMD
6452#endif
6436#ifndef GL_AMD_framebuffer_sample_positions 6453#ifndef GL_AMD_framebuffer_sample_positions
6437#define GL_AMD_framebuffer_sample_positions 1 6454#define GL_AMD_framebuffer_sample_positions 1
6438GLAPI int GLAD_GL_AMD_framebuffer_sample_positions; 6455GLAPI 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 @@
1/* 1/*
2 2
3 OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. 3 OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018.
4 4
5 Language/Generator: C/C++ 5 Language/Generator: C/C++
6 Specification: gl 6 Specification: gl
@@ -15,6 +15,7 @@
15 GL_AMD_debug_output, 15 GL_AMD_debug_output,
16 GL_AMD_depth_clamp_separate, 16 GL_AMD_depth_clamp_separate,
17 GL_AMD_draw_buffers_blend, 17 GL_AMD_draw_buffers_blend,
18 GL_AMD_framebuffer_multisample_advanced,
18 GL_AMD_framebuffer_sample_positions, 19 GL_AMD_framebuffer_sample_positions,
19 GL_AMD_gcn_shader, 20 GL_AMD_gcn_shader,
20 GL_AMD_gpu_shader_half_float, 21 GL_AMD_gpu_shader_half_float,
@@ -600,7 +601,7 @@
600 Omit khrplatform: False 601 Omit khrplatform: False
601 602
602 Commandline: 603 Commandline:
603 --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" 604 --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"
604 Online: 605 Online:
605 Too many extensions 606 Too many extensions
606*/ 607*/
@@ -739,7 +740,7 @@ int gladLoadGL(void) {
739 return status; 740 return status;
740} 741}
741 742
742struct gladGLversionStruct GLVersion; 743struct gladGLversionStruct GLVersion = { 0, 0 };
743 744
744#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) 745#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
745#define _GLAD_IS_SOME_NEW_VERSION 1 746#define _GLAD_IS_SOME_NEW_VERSION 1
@@ -838,3190 +839,3193 @@ static int has_ext(const char *ext) {
838 839
839 return 0; 840 return 0;
840} 841}
841int GLAD_GL_VERSION_1_0; 842int GLAD_GL_VERSION_1_0 = 0;
842int GLAD_GL_VERSION_1_1; 843int GLAD_GL_VERSION_1_1 = 0;
843int GLAD_GL_VERSION_1_2; 844int GLAD_GL_VERSION_1_2 = 0;
844int GLAD_GL_VERSION_1_3; 845int GLAD_GL_VERSION_1_3 = 0;
845int GLAD_GL_VERSION_1_4; 846int GLAD_GL_VERSION_1_4 = 0;
846int GLAD_GL_VERSION_1_5; 847int GLAD_GL_VERSION_1_5 = 0;
847int GLAD_GL_VERSION_2_0; 848int GLAD_GL_VERSION_2_0 = 0;
848int GLAD_GL_VERSION_2_1; 849int GLAD_GL_VERSION_2_1 = 0;
849int GLAD_GL_VERSION_3_0; 850int GLAD_GL_VERSION_3_0 = 0;
850int GLAD_GL_VERSION_3_1; 851int GLAD_GL_VERSION_3_1 = 0;
851int GLAD_GL_VERSION_3_2; 852int GLAD_GL_VERSION_3_2 = 0;
852int GLAD_GL_VERSION_3_3; 853int GLAD_GL_VERSION_3_3 = 0;
853PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; 854PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL;
854PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; 855PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL;
855PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; 856PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
856PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; 857PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
857PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; 858PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL;
858PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; 859PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL;
859PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; 860PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL;
860PFNGLBINDSAMPLERPROC glad_glBindSampler; 861PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
861PFNGLLINEWIDTHPROC glad_glLineWidth; 862PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
862PFNGLCOLORP3UIVPROC glad_glColorP3uiv; 863PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL;
863PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; 864PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
864PFNGLCOMPILESHADERPROC glad_glCompileShader; 865PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
865PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; 866PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
866PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; 867PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
867PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; 868PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL;
868PFNGLVERTEXP4UIPROC glad_glVertexP4ui; 869PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL;
869PFNGLENABLEIPROC glad_glEnablei; 870PFNGLENABLEIPROC glad_glEnablei = NULL;
870PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; 871PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL;
871PFNGLCREATESHADERPROC glad_glCreateShader; 872PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
872PFNGLISBUFFERPROC glad_glIsBuffer; 873PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
873PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; 874PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL;
874PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; 875PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
875PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; 876PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
876PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; 877PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
877PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; 878PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
878PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; 879PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
879PFNGLHINTPROC glad_glHint; 880PFNGLHINTPROC glad_glHint = NULL;
880PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; 881PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL;
881PFNGLSAMPLEMASKIPROC glad_glSampleMaski; 882PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL;
882PFNGLVERTEXP2UIPROC glad_glVertexP2ui; 883PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL;
883PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; 884PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
884PFNGLPOINTSIZEPROC glad_glPointSize; 885PFNGLPOINTSIZEPROC glad_glPointSize = NULL;
885PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; 886PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL;
886PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; 887PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
887PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; 888PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL;
888PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; 889PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
889PFNGLWAITSYNCPROC glad_glWaitSync; 890PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
890PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; 891PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
891PFNGLUNIFORM3IPROC glad_glUniform3i; 892PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
892PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; 893PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL;
893PFNGLUNIFORM3FPROC glad_glUniform3f; 894PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
894PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; 895PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL;
895PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; 896PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
896PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; 897PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL;
897PFNGLCOLORMASKIPROC glad_glColorMaski; 898PFNGLCOLORMASKIPROC glad_glColorMaski = NULL;
898PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; 899PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL;
899PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; 900PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
900PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; 901PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL;
901PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; 902PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL;
902PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; 903PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL;
903PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; 904PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL;
904PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; 905PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
905PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; 906PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL;
906PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; 907PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
907PFNGLDRAWARRAYSPROC glad_glDrawArrays; 908PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
908PFNGLUNIFORM1UIPROC glad_glUniform1ui; 909PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL;
909PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; 910PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL;
910PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; 911PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL;
911PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; 912PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL;
912PFNGLCLEARPROC glad_glClear; 913PFNGLCLEARPROC glad_glClear = NULL;
913PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; 914PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL;
914PFNGLISENABLEDPROC glad_glIsEnabled; 915PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
915PFNGLSTENCILOPPROC glad_glStencilOp; 916PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
916PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; 917PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
917PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; 918PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
918PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; 919PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL;
919PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; 920PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
920PFNGLTEXIMAGE1DPROC glad_glTexImage1D; 921PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL;
921PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; 922PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
922PFNGLGETTEXIMAGEPROC glad_glGetTexImage; 923PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL;
923PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; 924PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL;
924PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; 925PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
925PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; 926PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
926PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; 927PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
927PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; 928PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
928PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; 929PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL;
929PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; 930PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
930PFNGLGETQUERYIVPROC glad_glGetQueryiv; 931PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL;
931PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; 932PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL;
932PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; 933PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
933PFNGLISSHADERPROC glad_glIsShader; 934PFNGLISSHADERPROC glad_glIsShader = NULL;
934PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; 935PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL;
935PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; 936PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL;
936PFNGLENABLEPROC glad_glEnable; 937PFNGLENABLEPROC glad_glEnable = NULL;
937PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; 938PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL;
938PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; 939PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
939PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; 940PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL;
940PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; 941PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL;
941PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; 942PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL;
942PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; 943PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
943PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; 944PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
944PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; 945PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
945PFNGLDRAWBUFFERPROC glad_glDrawBuffer; 946PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
946PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; 947PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL;
947PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; 948PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
948PFNGLFLUSHPROC glad_glFlush; 949PFNGLFLUSHPROC glad_glFlush = NULL;
949PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; 950PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
950PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; 951PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
951PFNGLFENCESYNCPROC glad_glFenceSync; 952PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
952PFNGLCOLORP3UIPROC glad_glColorP3ui; 953PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL;
953PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; 954PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL;
954PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; 955PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL;
955PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; 956PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL;
956PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; 957PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL;
957PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; 958PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
958PFNGLGENSAMPLERSPROC glad_glGenSamplers; 959PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
959PFNGLCLAMPCOLORPROC glad_glClampColor; 960PFNGLCLAMPCOLORPROC glad_glClampColor = NULL;
960PFNGLUNIFORM4IVPROC glad_glUniform4iv; 961PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
961PFNGLCLEARSTENCILPROC glad_glClearStencil; 962PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
962PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; 963PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL;
963PFNGLGENTEXTURESPROC glad_glGenTextures; 964PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
964PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; 965PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL;
965PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; 966PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL;
966PFNGLISSYNCPROC glad_glIsSync; 967PFNGLISSYNCPROC glad_glIsSync = NULL;
967PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; 968PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL;
968PFNGLUNIFORM2IPROC glad_glUniform2i; 969PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
969PFNGLUNIFORM2FPROC glad_glUniform2f; 970PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
970PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; 971PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL;
971PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; 972PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
972PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; 973PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
973PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; 974PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL;
974PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; 975PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
975PFNGLGENQUERIESPROC glad_glGenQueries; 976PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
976PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; 977PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL;
977PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; 978PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
978PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; 979PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
979PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; 980PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL;
980PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; 981PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
981PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; 982PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
982PFNGLISENABLEDIPROC glad_glIsEnabledi; 983PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL;
983PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; 984PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL;
984PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; 985PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL;
985PFNGLUNIFORM2IVPROC glad_glUniform2iv; 986PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
986PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; 987PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
987PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; 988PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL;
988PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; 989PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL;
989PFNGLGETSHADERIVPROC glad_glGetShaderiv; 990PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
990PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; 991PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL;
991PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; 992PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
992PFNGLGETDOUBLEVPROC glad_glGetDoublev; 993PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL;
993PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; 994PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL;
994PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; 995PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
995PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; 996PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL;
996PFNGLUNIFORM3FVPROC glad_glUniform3fv; 997PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
997PFNGLDEPTHRANGEPROC glad_glDepthRange; 998PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
998PFNGLMAPBUFFERPROC glad_glMapBuffer; 999PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL;
999PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; 1000PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL;
1000PFNGLDELETESYNCPROC glad_glDeleteSync; 1001PFNGLDELETESYNCPROC glad_glDeleteSync = NULL;
1001PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; 1002PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
1002PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; 1003PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
1003PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; 1004PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL;
1004PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; 1005PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
1005PFNGLUNIFORM3IVPROC glad_glUniform3iv; 1006PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
1006PFNGLPOLYGONMODEPROC glad_glPolygonMode; 1007PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL;
1007PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; 1008PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
1008PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; 1009PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL;
1009PFNGLUSEPROGRAMPROC glad_glUseProgram; 1010PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
1010PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; 1011PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
1011PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; 1012PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
1012PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; 1013PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
1013PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; 1014PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL;
1014PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; 1015PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL;
1015PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; 1016PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL;
1016PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; 1017PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL;
1017PFNGLFINISHPROC glad_glFinish; 1018PFNGLFINISHPROC glad_glFinish = NULL;
1018PFNGLDELETESHADERPROC glad_glDeleteShader; 1019PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
1019PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; 1020PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL;
1020PFNGLVIEWPORTPROC glad_glViewport; 1021PFNGLVIEWPORTPROC glad_glViewport = NULL;
1021PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; 1022PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL;
1022PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; 1023PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
1023PFNGLUNIFORM2UIPROC glad_glUniform2ui; 1024PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL;
1024PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; 1025PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL;
1025PFNGLCLEARDEPTHPROC glad_glClearDepth; 1026PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL;
1026PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; 1027PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL;
1027PFNGLTEXPARAMETERFPROC glad_glTexParameterf; 1028PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
1028PFNGLTEXPARAMETERIPROC glad_glTexParameteri; 1029PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
1029PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; 1030PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
1030PFNGLTEXBUFFERPROC glad_glTexBuffer; 1031PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL;
1031PFNGLPIXELSTOREIPROC glad_glPixelStorei; 1032PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
1032PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; 1033PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
1033PFNGLPIXELSTOREFPROC glad_glPixelStoref; 1034PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL;
1034PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; 1035PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL;
1035PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; 1036PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL;
1036PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; 1037PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL;
1037PFNGLLINKPROGRAMPROC glad_glLinkProgram; 1038PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
1038PFNGLBINDTEXTUREPROC glad_glBindTexture; 1039PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
1039PFNGLGETSTRINGPROC glad_glGetString; 1040PFNGLGETSTRINGPROC glad_glGetString = NULL;
1040PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; 1041PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL;
1041PFNGLDETACHSHADERPROC glad_glDetachShader; 1042PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
1042PFNGLENDQUERYPROC glad_glEndQuery; 1043PFNGLENDQUERYPROC glad_glEndQuery = NULL;
1043PFNGLNORMALP3UIPROC glad_glNormalP3ui; 1044PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL;
1044PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; 1045PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL;
1045PFNGLDELETETEXTURESPROC glad_glDeleteTextures; 1046PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
1046PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; 1047PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
1047PFNGLDELETEQUERIESPROC glad_glDeleteQueries; 1048PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL;
1048PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; 1049PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL;
1049PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; 1050PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
1050PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; 1051PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL;
1051PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; 1052PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
1052PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; 1053PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL;
1053PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; 1054PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL;
1054PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; 1055PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
1055PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; 1056PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL;
1056PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; 1057PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL;
1057PFNGLUNIFORM1FPROC glad_glUniform1f; 1058PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
1058PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; 1059PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
1059PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; 1060PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL;
1060PFNGLUNIFORM1IPROC glad_glUniform1i; 1061PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
1061PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; 1062PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
1062PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; 1063PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
1063PFNGLDISABLEPROC glad_glDisable; 1064PFNGLDISABLEPROC glad_glDisable = NULL;
1064PFNGLLOGICOPPROC glad_glLogicOp; 1065PFNGLLOGICOPPROC glad_glLogicOp = NULL;
1065PFNGLUNIFORM4UIPROC glad_glUniform4ui; 1066PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL;
1066PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; 1067PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
1067PFNGLCULLFACEPROC glad_glCullFace; 1068PFNGLCULLFACEPROC glad_glCullFace = NULL;
1068PFNGLGETSTRINGIPROC glad_glGetStringi; 1069PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
1069PFNGLATTACHSHADERPROC glad_glAttachShader; 1070PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
1070PFNGLQUERYCOUNTERPROC glad_glQueryCounter; 1071PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL;
1071PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; 1072PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL;
1072PFNGLDRAWELEMENTSPROC glad_glDrawElements; 1073PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
1073PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; 1074PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL;
1074PFNGLUNIFORM1IVPROC glad_glUniform1iv; 1075PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
1075PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; 1076PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL;
1076PFNGLREADBUFFERPROC glad_glReadBuffer; 1077PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
1077PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; 1078PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL;
1078PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; 1079PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
1079PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; 1080PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
1080PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; 1081PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL;
1081PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; 1082PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
1082PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; 1083PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL;
1083PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; 1084PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL;
1084PFNGLBLENDCOLORPROC glad_glBlendColor; 1085PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
1085PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; 1086PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL;
1086PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; 1087PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
1087PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; 1088PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL;
1088PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; 1089PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL;
1089PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; 1090PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
1090PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; 1091PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL;
1091PFNGLISPROGRAMPROC glad_glIsProgram; 1092PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
1092PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; 1093PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL;
1093PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; 1094PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
1094PFNGLUNIFORM4IPROC glad_glUniform4i; 1095PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
1095PFNGLACTIVETEXTUREPROC glad_glActiveTexture; 1096PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
1096PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; 1097PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
1097PFNGLREADPIXELSPROC glad_glReadPixels; 1098PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
1098PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; 1099PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL;
1099PFNGLUNIFORM4FPROC glad_glUniform4f; 1100PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
1100PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; 1101PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
1101PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; 1102PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
1102PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; 1103PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
1103PFNGLSTENCILFUNCPROC glad_glStencilFunc; 1104PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
1104PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; 1105PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL;
1105PFNGLCOLORP4UIPROC glad_glColorP4ui; 1106PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL;
1106PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; 1107PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL;
1107PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; 1108PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
1108PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; 1109PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL;
1109PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; 1110PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL;
1110PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; 1111PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
1111PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; 1112PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL;
1112PFNGLGENBUFFERSPROC glad_glGenBuffers; 1113PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
1113PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; 1114PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL;
1114PFNGLBLENDFUNCPROC glad_glBlendFunc; 1115PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
1115PFNGLCREATEPROGRAMPROC glad_glCreateProgram; 1116PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
1116PFNGLTEXIMAGE3DPROC glad_glTexImage3D; 1117PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL;
1117PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; 1118PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
1118PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; 1119PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL;
1119PFNGLGETINTEGER64VPROC glad_glGetInteger64v; 1120PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
1120PFNGLSCISSORPROC glad_glScissor; 1121PFNGLSCISSORPROC glad_glScissor = NULL;
1121PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; 1122PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL;
1122PFNGLGETBOOLEANVPROC glad_glGetBooleanv; 1123PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
1123PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; 1124PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL;
1124PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; 1125PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL;
1125PFNGLCLEARCOLORPROC glad_glClearColor; 1126PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
1126PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; 1127PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL;
1127PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; 1128PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL;
1128PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; 1129PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL;
1129PFNGLCOLORP4UIVPROC glad_glColorP4uiv; 1130PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL;
1130PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; 1131PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL;
1131PFNGLUNIFORM3UIPROC glad_glUniform3ui; 1132PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL;
1132PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; 1133PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL;
1133PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; 1134PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL;
1134PFNGLUNIFORM2FVPROC glad_glUniform2fv; 1135PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
1135PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; 1136PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL;
1136PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; 1137PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
1137PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; 1138PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
1138PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; 1139PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
1139PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; 1140PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL;
1140PFNGLDEPTHFUNCPROC glad_glDepthFunc; 1141PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
1141PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; 1142PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
1142PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; 1143PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL;
1143PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; 1144PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
1144PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; 1145PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL;
1145PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; 1146PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
1146PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; 1147PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL;
1147PFNGLCOLORMASKPROC glad_glColorMask; 1148PFNGLCOLORMASKPROC glad_glColorMask = NULL;
1148PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; 1149PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL;
1149PFNGLBLENDEQUATIONPROC glad_glBlendEquation; 1150PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
1150PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; 1151PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
1151PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; 1152PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
1152PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; 1153PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL;
1153PFNGLUNIFORM4FVPROC glad_glUniform4fv; 1154PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
1154PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; 1155PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
1155PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; 1156PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL;
1156PFNGLISSAMPLERPROC glad_glIsSampler; 1157PFNGLISSAMPLERPROC glad_glIsSampler = NULL;
1157PFNGLVERTEXP3UIPROC glad_glVertexP3ui; 1158PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL;
1158PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; 1159PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
1159PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; 1160PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL;
1160PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; 1161PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL;
1161PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; 1162PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
1162PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; 1163PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
1163PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; 1164PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL;
1164PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; 1165PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL;
1165PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; 1166PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
1166PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; 1167PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
1167PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; 1168PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL;
1168PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; 1169PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
1169PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; 1170PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL;
1170PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; 1171PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
1171PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; 1172PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
1172PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; 1173PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL;
1173PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; 1174PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL;
1174PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; 1175PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL;
1175PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; 1176PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL;
1176PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; 1177PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL;
1177PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; 1178PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL;
1178PFNGLDISABLEIPROC glad_glDisablei; 1179PFNGLDISABLEIPROC glad_glDisablei = NULL;
1179PFNGLSHADERSOURCEPROC glad_glShaderSource; 1180PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
1180PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; 1181PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
1181PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; 1182PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL;
1182PFNGLGETSYNCIVPROC glad_glGetSynciv; 1183PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
1183PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; 1184PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL;
1184PFNGLBEGINQUERYPROC glad_glBeginQuery; 1185PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
1185PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; 1186PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
1186PFNGLBINDBUFFERPROC glad_glBindBuffer; 1187PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
1187PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; 1188PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
1188PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; 1189PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
1189PFNGLBUFFERDATAPROC glad_glBufferData; 1190PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
1190PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; 1191PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL;
1191PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; 1192PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL;
1192PFNGLGETERRORPROC glad_glGetError; 1193PFNGLGETERRORPROC glad_glGetError = NULL;
1193PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; 1194PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL;
1194PFNGLGETFLOATVPROC glad_glGetFloatv; 1195PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
1195PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; 1196PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL;
1196PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; 1197PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
1197PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; 1198PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL;
1198PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; 1199PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL;
1199PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; 1200PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL;
1200PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; 1201PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL;
1201PFNGLGETINTEGERVPROC glad_glGetIntegerv; 1202PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
1202PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; 1203PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL;
1203PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; 1204PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL;
1204PFNGLISQUERYPROC glad_glIsQuery; 1205PFNGLISQUERYPROC glad_glIsQuery = NULL;
1205PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; 1206PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL;
1206PFNGLTEXIMAGE2DPROC glad_glTexImage2D; 1207PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
1207PFNGLSTENCILMASKPROC glad_glStencilMask; 1208PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
1208PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; 1209PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL;
1209PFNGLISTEXTUREPROC glad_glIsTexture; 1210PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
1210PFNGLUNIFORM1FVPROC glad_glUniform1fv; 1211PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
1211PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; 1212PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL;
1212PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; 1213PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
1213PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; 1214PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL;
1214PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; 1215PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
1215PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; 1216PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL;
1216PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; 1217PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL;
1217PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; 1218PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
1218PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; 1219PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL;
1219PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; 1220PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL;
1220PFNGLDEPTHMASKPROC glad_glDepthMask; 1221PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
1221PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; 1222PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL;
1222PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; 1223PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL;
1223PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; 1224PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
1224PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; 1225PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL;
1225PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; 1226PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
1226PFNGLFRONTFACEPROC glad_glFrontFace; 1227PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
1227int GLAD_GL_SGIX_pixel_tiles; 1228int GLAD_GL_SGIX_pixel_tiles = 0;
1228int GLAD_GL_EXT_post_depth_coverage; 1229int GLAD_GL_EXT_post_depth_coverage = 0;
1229int GLAD_GL_APPLE_element_array; 1230int GLAD_GL_APPLE_element_array = 0;
1230int GLAD_GL_AMD_multi_draw_indirect; 1231int GLAD_GL_AMD_multi_draw_indirect = 0;
1231int GLAD_GL_EXT_blend_subtract; 1232int GLAD_GL_EXT_blend_subtract = 0;
1232int GLAD_GL_SGIX_tag_sample_buffer; 1233int GLAD_GL_SGIX_tag_sample_buffer = 0;
1233int GLAD_GL_NV_point_sprite; 1234int GLAD_GL_NV_point_sprite = 0;
1234int GLAD_GL_IBM_texture_mirrored_repeat; 1235int GLAD_GL_IBM_texture_mirrored_repeat = 0;
1235int GLAD_GL_APPLE_transform_hint; 1236int GLAD_GL_APPLE_transform_hint = 0;
1236int GLAD_GL_ATI_separate_stencil; 1237int GLAD_GL_ATI_separate_stencil = 0;
1237int GLAD_GL_NV_shader_atomic_int64; 1238int GLAD_GL_NV_shader_atomic_int64 = 0;
1238int GLAD_GL_EXT_semaphore_win32; 1239int GLAD_GL_EXT_semaphore_win32 = 0;
1239int GLAD_GL_NV_vertex_program2_option; 1240int GLAD_GL_NV_vertex_program2_option = 0;
1240int GLAD_GL_EXT_texture_buffer_object; 1241int GLAD_GL_EXT_texture_buffer_object = 0;
1241int GLAD_GL_ARB_vertex_blend; 1242int GLAD_GL_ARB_vertex_blend = 0;
1242int GLAD_GL_OVR_multiview; 1243int GLAD_GL_OVR_multiview = 0;
1243int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch; 1244int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = 0;
1244int GLAD_GL_NV_vertex_program2; 1245int GLAD_GL_NV_vertex_program2 = 0;
1245int GLAD_GL_ARB_program_interface_query; 1246int GLAD_GL_ARB_program_interface_query = 0;
1246int GLAD_GL_EXT_misc_attribute; 1247int GLAD_GL_EXT_misc_attribute = 0;
1247int GLAD_GL_NV_multisample_coverage; 1248int GLAD_GL_NV_multisample_coverage = 0;
1248int GLAD_GL_ARB_shading_language_packing; 1249int GLAD_GL_ARB_shading_language_packing = 0;
1249int GLAD_GL_EXT_texture_cube_map; 1250int GLAD_GL_EXT_texture_cube_map = 0;
1250int GLAD_GL_NV_viewport_array2; 1251int GLAD_GL_NV_viewport_array2 = 0;
1251int GLAD_GL_ARB_texture_stencil8; 1252int GLAD_GL_ARB_texture_stencil8 = 0;
1252int GLAD_GL_EXT_index_func; 1253int GLAD_GL_EXT_index_func = 0;
1253int GLAD_GL_EXT_memory_object_fd; 1254int GLAD_GL_EXT_memory_object_fd = 0;
1254int GLAD_GL_OES_compressed_paletted_texture; 1255int GLAD_GL_OES_compressed_paletted_texture = 0;
1255int GLAD_GL_MESA_shader_integer_functions; 1256int GLAD_GL_MESA_shader_integer_functions = 0;
1256int GLAD_GL_NV_shader_buffer_load; 1257int GLAD_GL_NV_shader_buffer_load = 0;
1257int GLAD_GL_EXT_color_subtable; 1258int GLAD_GL_EXT_color_subtable = 0;
1258int GLAD_GL_SUNX_constant_data; 1259int GLAD_GL_SUNX_constant_data = 0;
1259int GLAD_GL_EXT_texture_compression_s3tc; 1260int GLAD_GL_EXT_texture_compression_s3tc = 0;
1260int GLAD_GL_EXT_multi_draw_arrays; 1261int GLAD_GL_EXT_multi_draw_arrays = 0;
1261int GLAD_GL_ARB_shader_atomic_counters; 1262int GLAD_GL_ARB_shader_atomic_counters = 0;
1262int GLAD_GL_ARB_arrays_of_arrays; 1263int GLAD_GL_ARB_arrays_of_arrays = 0;
1263int GLAD_GL_NV_conditional_render; 1264int GLAD_GL_NV_conditional_render = 0;
1264int GLAD_GL_EXT_texture_env_combine; 1265int GLAD_GL_EXT_texture_env_combine = 0;
1265int GLAD_GL_NV_fog_distance; 1266int GLAD_GL_NV_fog_distance = 0;
1266int GLAD_GL_SGIX_async_histogram; 1267int GLAD_GL_SGIX_async_histogram = 0;
1267int GLAD_GL_MESA_resize_buffers; 1268int GLAD_GL_MESA_resize_buffers = 0;
1268int GLAD_GL_NV_light_max_exponent; 1269int GLAD_GL_NV_light_max_exponent = 0;
1269int GLAD_GL_NV_texture_env_combine4; 1270int GLAD_GL_NV_texture_env_combine4 = 0;
1270int GLAD_GL_ARB_spirv_extensions; 1271int GLAD_GL_ARB_spirv_extensions = 0;
1271int GLAD_GL_ARB_texture_view; 1272int GLAD_GL_ARB_texture_view = 0;
1272int GLAD_GL_ARB_texture_env_combine; 1273int GLAD_GL_ARB_texture_env_combine = 0;
1273int GLAD_GL_ARB_map_buffer_range; 1274int GLAD_GL_ARB_map_buffer_range = 0;
1274int GLAD_GL_EXT_convolution; 1275int GLAD_GL_EXT_convolution = 0;
1275int GLAD_GL_NV_compute_program5; 1276int GLAD_GL_NV_compute_program5 = 0;
1276int GLAD_GL_NV_vertex_attrib_integer_64bit; 1277int GLAD_GL_NV_vertex_attrib_integer_64bit = 0;
1277int GLAD_GL_EXT_paletted_texture; 1278int GLAD_GL_EXT_paletted_texture = 0;
1278int GLAD_GL_ARB_texture_buffer_object; 1279int GLAD_GL_ARB_texture_buffer_object = 0;
1279int GLAD_GL_ATI_pn_triangles; 1280int GLAD_GL_ATI_pn_triangles = 0;
1280int GLAD_GL_SGIX_resample; 1281int GLAD_GL_SGIX_resample = 0;
1281int GLAD_GL_SGIX_flush_raster; 1282int GLAD_GL_SGIX_flush_raster = 0;
1282int GLAD_GL_EXT_light_texture; 1283int GLAD_GL_EXT_light_texture = 0;
1283int GLAD_GL_ARB_point_sprite; 1284int GLAD_GL_ARB_point_sprite = 0;
1284int GLAD_GL_SUN_convolution_border_modes; 1285int GLAD_GL_SUN_convolution_border_modes = 0;
1285int GLAD_GL_EXT_semaphore_fd; 1286int GLAD_GL_EXT_semaphore_fd = 0;
1286int GLAD_GL_NV_parameter_buffer_object2; 1287int GLAD_GL_NV_parameter_buffer_object2 = 0;
1287int GLAD_GL_ARB_half_float_pixel; 1288int GLAD_GL_ARB_half_float_pixel = 0;
1288int GLAD_GL_NV_tessellation_program5; 1289int GLAD_GL_NV_tessellation_program5 = 0;
1289int GLAD_GL_REND_screen_coordinates; 1290int GLAD_GL_REND_screen_coordinates = 0;
1290int GLAD_GL_EXT_shared_texture_palette; 1291int GLAD_GL_EXT_shared_texture_palette = 0;
1291int GLAD_GL_EXT_packed_float; 1292int GLAD_GL_EXT_packed_float = 0;
1292int GLAD_GL_OML_subsample; 1293int GLAD_GL_OML_subsample = 0;
1293int GLAD_GL_SGIX_vertex_preclip; 1294int GLAD_GL_SGIX_vertex_preclip = 0;
1294int GLAD_GL_SGIX_texture_scale_bias; 1295int GLAD_GL_SGIX_texture_scale_bias = 0;
1295int GLAD_GL_AMD_draw_buffers_blend; 1296int GLAD_GL_AMD_draw_buffers_blend = 0;
1296int GLAD_GL_APPLE_texture_range; 1297int GLAD_GL_APPLE_texture_range = 0;
1297int GLAD_GL_EXT_texture_array; 1298int GLAD_GL_EXT_texture_array = 0;
1298int GLAD_GL_NV_texture_barrier; 1299int GLAD_GL_NV_texture_barrier = 0;
1299int GLAD_GL_ARB_texture_query_levels; 1300int GLAD_GL_ARB_texture_query_levels = 0;
1300int GLAD_GL_NV_texgen_emboss; 1301int GLAD_GL_NV_texgen_emboss = 0;
1301int GLAD_GL_EXT_texture_swizzle; 1302int GLAD_GL_EXT_texture_swizzle = 0;
1302int GLAD_GL_ARB_texture_rg; 1303int GLAD_GL_ARB_texture_rg = 0;
1303int GLAD_GL_ARB_vertex_type_2_10_10_10_rev; 1304int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0;
1304int GLAD_GL_ARB_fragment_shader; 1305int GLAD_GL_ARB_fragment_shader = 0;
1305int GLAD_GL_3DFX_tbuffer; 1306int GLAD_GL_3DFX_tbuffer = 0;
1306int GLAD_GL_GREMEDY_frame_terminator; 1307int GLAD_GL_GREMEDY_frame_terminator = 0;
1307int GLAD_GL_IBM_cull_vertex; 1308int GLAD_GL_IBM_cull_vertex = 0;
1308int GLAD_GL_EXT_separate_shader_objects; 1309int GLAD_GL_EXT_separate_shader_objects = 0;
1309int GLAD_GL_NV_texture_multisample; 1310int GLAD_GL_NV_texture_multisample = 0;
1310int GLAD_GL_ARB_shader_objects; 1311int GLAD_GL_ARB_shader_objects = 0;
1311int GLAD_GL_ARB_framebuffer_object; 1312int GLAD_GL_ARB_framebuffer_object = 0;
1312int GLAD_GL_EXT_external_buffer; 1313int GLAD_GL_EXT_external_buffer = 0;
1313int GLAD_GL_ATI_envmap_bumpmap; 1314int GLAD_GL_ATI_envmap_bumpmap = 0;
1314int GLAD_GL_AMD_shader_explicit_vertex_parameter; 1315int GLAD_GL_AMD_shader_explicit_vertex_parameter = 0;
1315int GLAD_GL_ARB_robust_buffer_access_behavior; 1316int GLAD_GL_ARB_robust_buffer_access_behavior = 0;
1316int GLAD_GL_ARB_shader_stencil_export; 1317int GLAD_GL_ARB_shader_stencil_export = 0;
1317int GLAD_GL_NV_texture_rectangle; 1318int GLAD_GL_NV_texture_rectangle = 0;
1318int GLAD_GL_ARB_enhanced_layouts; 1319int GLAD_GL_ARB_enhanced_layouts = 0;
1319int GLAD_GL_ARB_texture_rectangle; 1320int GLAD_GL_ARB_texture_rectangle = 0;
1320int GLAD_GL_SGI_texture_color_table; 1321int GLAD_GL_SGI_texture_color_table = 0;
1321int GLAD_GL_NV_viewport_swizzle; 1322int GLAD_GL_NV_viewport_swizzle = 0;
1322int GLAD_GL_ATI_map_object_buffer; 1323int GLAD_GL_ATI_map_object_buffer = 0;
1323int GLAD_GL_ARB_robustness; 1324int GLAD_GL_ARB_robustness = 0;
1324int GLAD_GL_NV_pixel_data_range; 1325int GLAD_GL_NV_pixel_data_range = 0;
1325int GLAD_GL_EXT_framebuffer_blit; 1326int GLAD_GL_EXT_framebuffer_blit = 0;
1326int GLAD_GL_ARB_gpu_shader_fp64; 1327int GLAD_GL_ARB_gpu_shader_fp64 = 0;
1327int GLAD_GL_NV_command_list; 1328int GLAD_GL_NV_command_list = 0;
1328int GLAD_GL_SGIX_depth_texture; 1329int GLAD_GL_SGIX_depth_texture = 0;
1329int GLAD_GL_AMD_framebuffer_sample_positions; 1330int GLAD_GL_AMD_framebuffer_sample_positions = 0;
1330int GLAD_GL_GREMEDY_string_marker; 1331int GLAD_GL_GREMEDY_string_marker = 0;
1331int GLAD_GL_ARB_texture_compression_bptc; 1332int GLAD_GL_ARB_texture_compression_bptc = 0;
1332int GLAD_GL_EXT_subtexture; 1333int GLAD_GL_EXT_subtexture = 0;
1333int GLAD_GL_EXT_pixel_transform_color_table; 1334int GLAD_GL_EXT_pixel_transform_color_table = 0;
1334int GLAD_GL_EXT_texture_compression_rgtc; 1335int GLAD_GL_EXT_texture_compression_rgtc = 0;
1335int GLAD_GL_ARB_shader_atomic_counter_ops; 1336int GLAD_GL_ARB_shader_atomic_counter_ops = 0;
1336int GLAD_GL_SGIX_depth_pass_instrument; 1337int GLAD_GL_SGIX_depth_pass_instrument = 0;
1337int GLAD_GL_EXT_gpu_program_parameters; 1338int GLAD_GL_EXT_gpu_program_parameters = 0;
1338int GLAD_GL_NV_evaluators; 1339int GLAD_GL_NV_evaluators = 0;
1339int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent; 1340int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = 0;
1340int GLAD_GL_SGIS_texture_filter4; 1341int GLAD_GL_SGIS_texture_filter4 = 0;
1341int GLAD_GL_AMD_performance_monitor; 1342int GLAD_GL_AMD_performance_monitor = 0;
1342int GLAD_GL_NV_geometry_shader4; 1343int GLAD_GL_NV_geometry_shader4 = 0;
1343int GLAD_GL_EXT_stencil_clear_tag; 1344int GLAD_GL_EXT_stencil_clear_tag = 0;
1344int GLAD_GL_NV_vertex_program1_1; 1345int GLAD_GL_NV_vertex_program1_1 = 0;
1345int GLAD_GL_NV_present_video; 1346int GLAD_GL_NV_present_video = 0;
1346int GLAD_GL_ARB_texture_compression_rgtc; 1347int GLAD_GL_ARB_texture_compression_rgtc = 0;
1347int GLAD_GL_HP_convolution_border_modes; 1348int GLAD_GL_HP_convolution_border_modes = 0;
1348int GLAD_GL_EXT_shader_integer_mix; 1349int GLAD_GL_EXT_shader_integer_mix = 0;
1349int GLAD_GL_SGIX_framezoom; 1350int GLAD_GL_SGIX_framezoom = 0;
1350int GLAD_GL_ARB_stencil_texturing; 1351int GLAD_GL_ARB_stencil_texturing = 0;
1351int GLAD_GL_ARB_shader_clock; 1352int GLAD_GL_ARB_shader_clock = 0;
1352int GLAD_GL_NV_shader_atomic_fp16_vector; 1353int GLAD_GL_NV_shader_atomic_fp16_vector = 0;
1353int GLAD_GL_SGIX_fog_offset; 1354int GLAD_GL_SGIX_fog_offset = 0;
1354int GLAD_GL_ARB_draw_elements_base_vertex; 1355int GLAD_GL_ARB_draw_elements_base_vertex = 0;
1355int GLAD_GL_INGR_interlace_read; 1356int GLAD_GL_INGR_interlace_read = 0;
1356int GLAD_GL_NV_transform_feedback; 1357int GLAD_GL_NV_transform_feedback = 0;
1357int GLAD_GL_NV_fragment_program; 1358int GLAD_GL_NV_fragment_program = 0;
1358int GLAD_GL_AMD_stencil_operation_extended; 1359int GLAD_GL_AMD_stencil_operation_extended = 0;
1359int GLAD_GL_ARB_seamless_cubemap_per_texture; 1360int GLAD_GL_ARB_seamless_cubemap_per_texture = 0;
1360int GLAD_GL_ARB_instanced_arrays; 1361int GLAD_GL_ARB_instanced_arrays = 0;
1361int GLAD_GL_ARB_get_texture_sub_image; 1362int GLAD_GL_ARB_get_texture_sub_image = 0;
1362int GLAD_GL_NV_vertex_array_range2; 1363int GLAD_GL_NV_vertex_array_range2 = 0;
1363int GLAD_GL_KHR_robustness; 1364int GLAD_GL_KHR_robustness = 0;
1364int GLAD_GL_AMD_sparse_texture; 1365int GLAD_GL_AMD_sparse_texture = 0;
1365int GLAD_GL_ARB_clip_control; 1366int GLAD_GL_ARB_clip_control = 0;
1366int GLAD_GL_NV_fragment_coverage_to_color; 1367int GLAD_GL_NV_fragment_coverage_to_color = 0;
1367int GLAD_GL_NV_fence; 1368int GLAD_GL_NV_fence = 0;
1368int GLAD_GL_ARB_texture_buffer_range; 1369int GLAD_GL_ARB_texture_buffer_range = 0;
1369int GLAD_GL_SUN_mesh_array; 1370int GLAD_GL_SUN_mesh_array = 0;
1370int GLAD_GL_ARB_vertex_attrib_binding; 1371int GLAD_GL_ARB_vertex_attrib_binding = 0;
1371int GLAD_GL_ARB_framebuffer_no_attachments; 1372int GLAD_GL_ARB_framebuffer_no_attachments = 0;
1372int GLAD_GL_ARB_cl_event; 1373int GLAD_GL_ARB_cl_event = 0;
1373int GLAD_GL_EXT_vertex_weighting; 1374int GLAD_GL_EXT_vertex_weighting = 0;
1374int GLAD_GL_ARB_derivative_control; 1375int GLAD_GL_ARB_derivative_control = 0;
1375int GLAD_GL_NV_packed_depth_stencil; 1376int GLAD_GL_NV_packed_depth_stencil = 0;
1376int GLAD_GL_OES_single_precision; 1377int GLAD_GL_OES_single_precision = 0;
1377int GLAD_GL_NV_primitive_restart; 1378int GLAD_GL_NV_primitive_restart = 0;
1378int GLAD_GL_SUN_global_alpha; 1379int GLAD_GL_SUN_global_alpha = 0;
1379int GLAD_GL_ARB_fragment_shader_interlock; 1380int GLAD_GL_ARB_fragment_shader_interlock = 0;
1380int GLAD_GL_EXT_texture_object; 1381int GLAD_GL_EXT_texture_object = 0;
1381int GLAD_GL_AMD_name_gen_delete; 1382int GLAD_GL_AMD_name_gen_delete = 0;
1382int GLAD_GL_NV_texture_compression_vtc; 1383int GLAD_GL_NV_texture_compression_vtc = 0;
1383int GLAD_GL_NV_sample_mask_override_coverage; 1384int GLAD_GL_NV_sample_mask_override_coverage = 0;
1384int GLAD_GL_NV_texture_shader3; 1385int GLAD_GL_NV_texture_shader3 = 0;
1385int GLAD_GL_MESA_tile_raster_order; 1386int GLAD_GL_MESA_tile_raster_order = 0;
1386int GLAD_GL_ARB_texture_filter_anisotropic; 1387int GLAD_GL_ARB_texture_filter_anisotropic = 0;
1387int GLAD_GL_EXT_texture; 1388int GLAD_GL_EXT_texture = 0;
1388int GLAD_GL_ARB_buffer_storage; 1389int GLAD_GL_ARB_buffer_storage = 0;
1389int GLAD_GL_AMD_shader_atomic_counter_ops; 1390int GLAD_GL_AMD_shader_atomic_counter_ops = 0;
1390int GLAD_GL_APPLE_vertex_program_evaluators; 1391int GLAD_GL_APPLE_vertex_program_evaluators = 0;
1391int GLAD_GL_AMD_texture_gather_bias_lod; 1392int GLAD_GL_AMD_texture_gather_bias_lod = 0;
1392int GLAD_GL_NV_texgen_reflection; 1393int GLAD_GL_NV_texgen_reflection = 0;
1393int GLAD_GL_ARB_explicit_uniform_location; 1394int GLAD_GL_ARB_explicit_uniform_location = 0;
1394int GLAD_GL_ARB_depth_buffer_float; 1395int GLAD_GL_ARB_depth_buffer_float = 0;
1395int GLAD_GL_NV_path_rendering_shared_edge; 1396int GLAD_GL_NV_path_rendering_shared_edge = 0;
1396int GLAD_GL_SGIX_shadow_ambient; 1397int GLAD_GL_SGIX_shadow_ambient = 0;
1397int GLAD_GL_ARB_texture_cube_map; 1398int GLAD_GL_ARB_texture_cube_map = 0;
1398int GLAD_GL_AMD_vertex_shader_viewport_index; 1399int GLAD_GL_AMD_vertex_shader_viewport_index = 0;
1399int GLAD_GL_SGIX_list_priority; 1400int GLAD_GL_SGIX_list_priority = 0;
1400int GLAD_GL_NV_vertex_buffer_unified_memory; 1401int GLAD_GL_NV_vertex_buffer_unified_memory = 0;
1401int GLAD_GL_NV_uniform_buffer_unified_memory; 1402int GLAD_GL_NV_uniform_buffer_unified_memory = 0;
1402int GLAD_GL_ARB_clear_texture; 1403int GLAD_GL_ARB_clear_texture = 0;
1403int GLAD_GL_ATI_texture_env_combine3; 1404int GLAD_GL_ATI_texture_env_combine3 = 0;
1404int GLAD_GL_NV_depth_clamp; 1405int GLAD_GL_NV_depth_clamp = 0;
1405int GLAD_GL_ARB_map_buffer_alignment; 1406int GLAD_GL_ARB_map_buffer_alignment = 0;
1406int GLAD_GL_EXT_memory_object; 1407int GLAD_GL_EXT_memory_object = 0;
1407int GLAD_GL_NV_blend_equation_advanced; 1408int GLAD_GL_NV_blend_equation_advanced = 0;
1408int GLAD_GL_SGIS_sharpen_texture; 1409int GLAD_GL_SGIS_sharpen_texture = 0;
1409int GLAD_GL_KHR_robust_buffer_access_behavior; 1410int GLAD_GL_KHR_robust_buffer_access_behavior = 0;
1410int GLAD_GL_ARB_pipeline_statistics_query; 1411int GLAD_GL_ARB_pipeline_statistics_query = 0;
1411int GLAD_GL_ARB_vertex_program; 1412int GLAD_GL_ARB_vertex_program = 0;
1412int GLAD_GL_ARB_texture_rgb10_a2ui; 1413int GLAD_GL_ARB_texture_rgb10_a2ui = 0;
1413int GLAD_GL_OML_interlace; 1414int GLAD_GL_OML_interlace = 0;
1414int GLAD_GL_ATI_pixel_format_float; 1415int GLAD_GL_ATI_pixel_format_float = 0;
1415int GLAD_GL_NV_clip_space_w_scaling; 1416int GLAD_GL_NV_clip_space_w_scaling = 0;
1416int GLAD_GL_ARB_vertex_buffer_object; 1417int GLAD_GL_ARB_vertex_buffer_object = 0;
1417int GLAD_GL_EXT_shadow_funcs; 1418int GLAD_GL_EXT_shadow_funcs = 0;
1418int GLAD_GL_ATI_text_fragment_shader; 1419int GLAD_GL_ATI_text_fragment_shader = 0;
1419int GLAD_GL_NV_vertex_array_range; 1420int GLAD_GL_NV_vertex_array_range = 0;
1420int GLAD_GL_SGIX_fragment_lighting; 1421int GLAD_GL_SGIX_fragment_lighting = 0;
1421int GLAD_GL_AMD_shader_ballot; 1422int GLAD_GL_AMD_shader_ballot = 0;
1422int GLAD_GL_NV_texture_expand_normal; 1423int GLAD_GL_NV_texture_expand_normal = 0;
1423int GLAD_GL_NV_framebuffer_multisample_coverage; 1424int GLAD_GL_NV_framebuffer_multisample_coverage = 0;
1424int GLAD_GL_EXT_timer_query; 1425int GLAD_GL_EXT_timer_query = 0;
1425int GLAD_GL_EXT_vertex_array_bgra; 1426int GLAD_GL_EXT_vertex_array_bgra = 0;
1426int GLAD_GL_NV_bindless_texture; 1427int GLAD_GL_NV_bindless_texture = 0;
1427int GLAD_GL_KHR_debug; 1428int GLAD_GL_KHR_debug = 0;
1428int GLAD_GL_SGIS_texture_border_clamp; 1429int GLAD_GL_SGIS_texture_border_clamp = 0;
1429int GLAD_GL_ATI_vertex_attrib_array_object; 1430int GLAD_GL_ATI_vertex_attrib_array_object = 0;
1430int GLAD_GL_SGIX_clipmap; 1431int GLAD_GL_SGIX_clipmap = 0;
1431int GLAD_GL_EXT_geometry_shader4; 1432int GLAD_GL_EXT_geometry_shader4 = 0;
1432int GLAD_GL_ARB_shader_texture_image_samples; 1433int GLAD_GL_ARB_shader_texture_image_samples = 0;
1433int GLAD_GL_MESA_ycbcr_texture; 1434int GLAD_GL_MESA_ycbcr_texture = 0;
1434int GLAD_GL_MESAX_texture_stack; 1435int GLAD_GL_MESAX_texture_stack = 0;
1435int GLAD_GL_AMD_seamless_cubemap_per_texture; 1436int GLAD_GL_AMD_seamless_cubemap_per_texture = 0;
1436int GLAD_GL_EXT_bindable_uniform; 1437int GLAD_GL_EXT_bindable_uniform = 0;
1437int GLAD_GL_KHR_texture_compression_astc_hdr; 1438int GLAD_GL_KHR_texture_compression_astc_hdr = 0;
1438int GLAD_GL_ARB_shader_ballot; 1439int GLAD_GL_ARB_shader_ballot = 0;
1439int GLAD_GL_KHR_blend_equation_advanced; 1440int GLAD_GL_KHR_blend_equation_advanced = 0;
1440int GLAD_GL_ARB_fragment_program_shadow; 1441int GLAD_GL_ARB_fragment_program_shadow = 0;
1441int GLAD_GL_ATI_element_array; 1442int GLAD_GL_ATI_element_array = 0;
1442int GLAD_GL_AMD_texture_texture4; 1443int GLAD_GL_AMD_texture_texture4 = 0;
1443int GLAD_GL_SGIX_reference_plane; 1444int GLAD_GL_SGIX_reference_plane = 0;
1444int GLAD_GL_EXT_stencil_two_side; 1445int GLAD_GL_EXT_stencil_two_side = 0;
1445int GLAD_GL_ARB_transform_feedback_overflow_query; 1446int GLAD_GL_ARB_transform_feedback_overflow_query = 0;
1446int GLAD_GL_SGIX_texture_lod_bias; 1447int GLAD_GL_SGIX_texture_lod_bias = 0;
1447int GLAD_GL_KHR_no_error; 1448int GLAD_GL_KHR_no_error = 0;
1448int GLAD_GL_NV_explicit_multisample; 1449int GLAD_GL_NV_explicit_multisample = 0;
1449int GLAD_GL_NV_stereo_view_rendering; 1450int GLAD_GL_NV_stereo_view_rendering = 0;
1450int GLAD_GL_IBM_static_data; 1451int GLAD_GL_IBM_static_data = 0;
1451int GLAD_GL_EXT_clip_volume_hint; 1452int GLAD_GL_EXT_clip_volume_hint = 0;
1452int GLAD_GL_EXT_texture_perturb_normal; 1453int GLAD_GL_EXT_texture_perturb_normal = 0;
1453int GLAD_GL_NV_fragment_program2; 1454int GLAD_GL_NV_fragment_program2 = 0;
1454int GLAD_GL_NV_fragment_program4; 1455int GLAD_GL_NV_fragment_program4 = 0;
1455int GLAD_GL_EXT_point_parameters; 1456int GLAD_GL_EXT_point_parameters = 0;
1456int GLAD_GL_PGI_misc_hints; 1457int GLAD_GL_PGI_misc_hints = 0;
1457int GLAD_GL_EXT_EGL_image_storage; 1458int GLAD_GL_EXT_EGL_image_storage = 0;
1458int GLAD_GL_SGIX_subsample; 1459int GLAD_GL_SGIX_subsample = 0;
1459int GLAD_GL_AMD_shader_stencil_export; 1460int GLAD_GL_AMD_shader_stencil_export = 0;
1460int GLAD_GL_ARB_shader_texture_lod; 1461int GLAD_GL_ARB_shader_texture_lod = 0;
1461int GLAD_GL_ARB_vertex_shader; 1462int GLAD_GL_ARB_vertex_shader = 0;
1462int GLAD_GL_ARB_depth_clamp; 1463int GLAD_GL_ARB_depth_clamp = 0;
1463int GLAD_GL_SGIS_texture_select; 1464int GLAD_GL_SGIS_texture_select = 0;
1464int GLAD_GL_NV_texture_shader; 1465int GLAD_GL_NV_texture_shader = 0;
1465int GLAD_GL_ARB_tessellation_shader; 1466int GLAD_GL_ARB_tessellation_shader = 0;
1466int GLAD_GL_EXT_draw_buffers2; 1467int GLAD_GL_EXT_draw_buffers2 = 0;
1467int GLAD_GL_ARB_vertex_attrib_64bit; 1468int GLAD_GL_ARB_vertex_attrib_64bit = 0;
1468int GLAD_GL_EXT_texture_filter_minmax; 1469int GLAD_GL_EXT_texture_filter_minmax = 0;
1469int GLAD_GL_NV_query_resource; 1470int GLAD_GL_NV_query_resource = 0;
1470int GLAD_GL_AMD_interleaved_elements; 1471int GLAD_GL_AMD_interleaved_elements = 0;
1471int GLAD_GL_ARB_fragment_program; 1472int GLAD_GL_ARB_fragment_program = 0;
1472int GLAD_GL_OML_resample; 1473int GLAD_GL_OML_resample = 0;
1473int GLAD_GL_APPLE_ycbcr_422; 1474int GLAD_GL_APPLE_ycbcr_422 = 0;
1474int GLAD_GL_SGIX_texture_add_env; 1475int GLAD_GL_SGIX_texture_add_env = 0;
1475int GLAD_GL_ARB_shadow_ambient; 1476int GLAD_GL_ARB_shadow_ambient = 0;
1476int GLAD_GL_ARB_texture_storage; 1477int GLAD_GL_ARB_texture_storage = 0;
1477int GLAD_GL_EXT_pixel_buffer_object; 1478int GLAD_GL_EXT_pixel_buffer_object = 0;
1478int GLAD_GL_ARB_copy_image; 1479int GLAD_GL_ARB_copy_image = 0;
1479int GLAD_GL_SGIS_pixel_texture; 1480int GLAD_GL_SGIS_pixel_texture = 0;
1480int GLAD_GL_SGIS_generate_mipmap; 1481int GLAD_GL_SGIS_generate_mipmap = 0;
1481int GLAD_GL_SGIX_instruments; 1482int GLAD_GL_SGIX_instruments = 0;
1482int GLAD_GL_ARB_fragment_layer_viewport; 1483int GLAD_GL_ARB_fragment_layer_viewport = 0;
1483int GLAD_GL_ARB_shader_storage_buffer_object; 1484int GLAD_GL_ARB_shader_storage_buffer_object = 0;
1484int GLAD_GL_EXT_sparse_texture2; 1485int GLAD_GL_EXT_sparse_texture2 = 0;
1485int GLAD_GL_EXT_blend_minmax; 1486int GLAD_GL_EXT_blend_minmax = 0;
1486int GLAD_GL_MESA_pack_invert; 1487int GLAD_GL_MESA_pack_invert = 0;
1487int GLAD_GL_ARB_base_instance; 1488int GLAD_GL_ARB_base_instance = 0;
1488int GLAD_GL_SGIX_convolution_accuracy; 1489int GLAD_GL_SGIX_convolution_accuracy = 0;
1489int GLAD_GL_PGI_vertex_hints; 1490int GLAD_GL_PGI_vertex_hints = 0;
1490int GLAD_GL_AMD_transform_feedback4; 1491int GLAD_GL_AMD_transform_feedback4 = 0;
1491int GLAD_GL_ARB_ES3_1_compatibility; 1492int GLAD_GL_ARB_ES3_1_compatibility = 0;
1492int GLAD_GL_EXT_memory_object_win32; 1493int GLAD_GL_EXT_memory_object_win32 = 0;
1493int GLAD_GL_EXT_texture_integer; 1494int GLAD_GL_EXT_texture_integer = 0;
1494int GLAD_GL_ARB_texture_multisample; 1495int GLAD_GL_ARB_texture_multisample = 0;
1495int GLAD_GL_ATI_vertex_streams; 1496int GLAD_GL_ATI_vertex_streams = 0;
1496int GLAD_GL_AMD_gpu_shader_int64; 1497int GLAD_GL_AMD_gpu_shader_int64 = 0;
1497int GLAD_GL_S3_s3tc; 1498int GLAD_GL_S3_s3tc = 0;
1498int GLAD_GL_ARB_query_buffer_object; 1499int GLAD_GL_ARB_query_buffer_object = 0;
1499int GLAD_GL_AMD_vertex_shader_tessellator; 1500int GLAD_GL_AMD_vertex_shader_tessellator = 0;
1500int GLAD_GL_ARB_invalidate_subdata; 1501int GLAD_GL_ARB_invalidate_subdata = 0;
1501int GLAD_GL_NV_draw_vulkan_image; 1502int GLAD_GL_NV_draw_vulkan_image = 0;
1502int GLAD_GL_EXT_index_material; 1503int GLAD_GL_EXT_index_material = 0;
1503int GLAD_GL_NVX_linked_gpu_multicast; 1504int GLAD_GL_NVX_linked_gpu_multicast = 0;
1504int GLAD_GL_NV_blend_equation_advanced_coherent; 1505int GLAD_GL_NV_blend_equation_advanced_coherent = 0;
1505int GLAD_GL_KHR_texture_compression_astc_sliced_3d; 1506int GLAD_GL_KHR_texture_compression_astc_sliced_3d = 0;
1506int GLAD_GL_INTEL_parallel_arrays; 1507int GLAD_GL_INTEL_parallel_arrays = 0;
1507int GLAD_GL_ATI_draw_buffers; 1508int GLAD_GL_ATI_draw_buffers = 0;
1508int GLAD_GL_WIN_specular_fog; 1509int GLAD_GL_WIN_specular_fog = 0;
1509int GLAD_GL_EXT_cmyka; 1510int GLAD_GL_EXT_cmyka = 0;
1510int GLAD_GL_SGIX_pixel_texture; 1511int GLAD_GL_SGIX_pixel_texture = 0;
1511int GLAD_GL_APPLE_specular_vector; 1512int GLAD_GL_APPLE_specular_vector = 0;
1512int GLAD_GL_ARB_compatibility; 1513int GLAD_GL_ARB_compatibility = 0;
1513int GLAD_GL_ARB_timer_query; 1514int GLAD_GL_ARB_timer_query = 0;
1514int GLAD_GL_SGIX_interlace; 1515int GLAD_GL_SGIX_interlace = 0;
1515int GLAD_GL_NV_parameter_buffer_object; 1516int GLAD_GL_NV_parameter_buffer_object = 0;
1516int GLAD_GL_AMD_shader_trinary_minmax; 1517int GLAD_GL_AMD_shader_trinary_minmax = 0;
1517int GLAD_GL_ARB_direct_state_access; 1518int GLAD_GL_ARB_direct_state_access = 0;
1518int GLAD_GL_EXT_rescale_normal; 1519int GLAD_GL_EXT_rescale_normal = 0;
1519int GLAD_GL_ARB_pixel_buffer_object; 1520int GLAD_GL_ARB_pixel_buffer_object = 0;
1520int GLAD_GL_ARB_uniform_buffer_object; 1521int GLAD_GL_ARB_uniform_buffer_object = 0;
1521int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev; 1522int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = 0;
1522int GLAD_GL_ARB_texture_swizzle; 1523int GLAD_GL_ARB_texture_swizzle = 0;
1523int GLAD_GL_NV_transform_feedback2; 1524int GLAD_GL_NV_transform_feedback2 = 0;
1524int GLAD_GL_SGIX_async_pixel; 1525int GLAD_GL_SGIX_async_pixel = 0;
1525int GLAD_GL_NV_fragment_program_option; 1526int GLAD_GL_NV_fragment_program_option = 0;
1526int GLAD_GL_ARB_explicit_attrib_location; 1527int GLAD_GL_ARB_explicit_attrib_location = 0;
1527int GLAD_GL_EXT_blend_color; 1528int GLAD_GL_EXT_blend_color = 0;
1528int GLAD_GL_NV_shader_thread_group; 1529int GLAD_GL_NV_shader_thread_group = 0;
1529int GLAD_GL_EXT_stencil_wrap; 1530int GLAD_GL_EXT_stencil_wrap = 0;
1530int GLAD_GL_EXT_index_array_formats; 1531int GLAD_GL_EXT_index_array_formats = 0;
1531int GLAD_GL_OVR_multiview2; 1532int GLAD_GL_OVR_multiview2 = 0;
1532int GLAD_GL_EXT_histogram; 1533int GLAD_GL_EXT_histogram = 0;
1533int GLAD_GL_EXT_polygon_offset; 1534int GLAD_GL_EXT_polygon_offset = 0;
1534int GLAD_GL_SGIS_point_parameters; 1535int GLAD_GL_SGIS_point_parameters = 0;
1535int GLAD_GL_SGIX_ycrcb; 1536int GLAD_GL_SGIX_ycrcb = 0;
1536int GLAD_GL_EXT_direct_state_access; 1537int GLAD_GL_EXT_direct_state_access = 0;
1537int GLAD_GL_ARB_cull_distance; 1538int GLAD_GL_ARB_cull_distance = 0;
1538int GLAD_GL_AMD_sample_positions; 1539int GLAD_GL_AMD_sample_positions = 0;
1539int GLAD_GL_NV_vertex_program; 1540int GLAD_GL_NV_vertex_program = 0;
1540int GLAD_GL_NV_shader_thread_shuffle; 1541int GLAD_GL_NV_shader_thread_shuffle = 0;
1541int GLAD_GL_ARB_shader_precision; 1542int GLAD_GL_ARB_shader_precision = 0;
1542int GLAD_GL_EXT_vertex_shader; 1543int GLAD_GL_EXT_vertex_shader = 0;
1543int GLAD_GL_EXT_blend_func_separate; 1544int GLAD_GL_EXT_blend_func_separate = 0;
1544int GLAD_GL_APPLE_fence; 1545int GLAD_GL_APPLE_fence = 0;
1545int GLAD_GL_NV_query_resource_tag; 1546int GLAD_GL_NV_query_resource_tag = 0;
1546int GLAD_GL_OES_byte_coordinates; 1547int GLAD_GL_OES_byte_coordinates = 0;
1547int GLAD_GL_ARB_transpose_matrix; 1548int GLAD_GL_ARB_transpose_matrix = 0;
1548int GLAD_GL_ARB_provoking_vertex; 1549int GLAD_GL_ARB_provoking_vertex = 0;
1549int GLAD_GL_EXT_fog_coord; 1550int GLAD_GL_EXT_fog_coord = 0;
1550int GLAD_GL_EXT_vertex_array; 1551int GLAD_GL_EXT_vertex_array = 0;
1551int GLAD_GL_ARB_half_float_vertex; 1552int GLAD_GL_ARB_half_float_vertex = 0;
1552int GLAD_GL_EXT_blend_equation_separate; 1553int GLAD_GL_EXT_blend_equation_separate = 0;
1553int GLAD_GL_NV_framebuffer_mixed_samples; 1554int GLAD_GL_NV_framebuffer_mixed_samples = 0;
1554int GLAD_GL_NVX_conditional_render; 1555int GLAD_GL_NVX_conditional_render = 0;
1555int GLAD_GL_ARB_multi_draw_indirect; 1556int GLAD_GL_ARB_multi_draw_indirect = 0;
1556int GLAD_GL_EXT_raster_multisample; 1557int GLAD_GL_EXT_raster_multisample = 0;
1557int GLAD_GL_NV_copy_image; 1558int GLAD_GL_NV_copy_image = 0;
1558int GLAD_GL_HP_texture_lighting; 1559int GLAD_GL_HP_texture_lighting = 0;
1559int GLAD_GL_INTEL_framebuffer_CMAA; 1560int GLAD_GL_INTEL_framebuffer_CMAA = 0;
1560int GLAD_GL_ARB_transform_feedback2; 1561int GLAD_GL_ARB_transform_feedback2 = 0;
1561int GLAD_GL_ARB_transform_feedback3; 1562int GLAD_GL_ARB_transform_feedback3 = 0;
1562int GLAD_GL_SGIX_ycrcba; 1563int GLAD_GL_SGIX_ycrcba = 0;
1563int GLAD_GL_EXT_debug_marker; 1564int GLAD_GL_EXT_debug_marker = 0;
1564int GLAD_GL_EXT_bgra; 1565int GLAD_GL_EXT_bgra = 0;
1565int GLAD_GL_ARB_sparse_texture_clamp; 1566int GLAD_GL_ARB_sparse_texture_clamp = 0;
1566int GLAD_GL_EXT_pixel_transform; 1567int GLAD_GL_EXT_pixel_transform = 0;
1567int GLAD_GL_ARB_conservative_depth; 1568int GLAD_GL_ARB_conservative_depth = 0;
1568int GLAD_GL_ATI_fragment_shader; 1569int GLAD_GL_ATI_fragment_shader = 0;
1569int GLAD_GL_ARB_vertex_array_object; 1570int GLAD_GL_ARB_vertex_array_object = 0;
1570int GLAD_GL_SUN_triangle_list; 1571int GLAD_GL_SUN_triangle_list = 0;
1571int GLAD_GL_EXT_texture_env_add; 1572int GLAD_GL_EXT_texture_env_add = 0;
1572int GLAD_GL_EXT_packed_depth_stencil; 1573int GLAD_GL_EXT_packed_depth_stencil = 0;
1573int GLAD_GL_EXT_texture_mirror_clamp; 1574int GLAD_GL_EXT_texture_mirror_clamp = 0;
1574int GLAD_GL_NV_multisample_filter_hint; 1575int GLAD_GL_NV_multisample_filter_hint = 0;
1575int GLAD_GL_APPLE_float_pixels; 1576int GLAD_GL_APPLE_float_pixels = 0;
1576int GLAD_GL_ARB_transform_feedback_instanced; 1577int GLAD_GL_ARB_transform_feedback_instanced = 0;
1577int GLAD_GL_SGIX_async; 1578int GLAD_GL_SGIX_async = 0;
1578int GLAD_GL_EXT_texture_compression_latc; 1579int GLAD_GL_EXT_texture_compression_latc = 0;
1579int GLAD_GL_NV_robustness_video_memory_purge; 1580int GLAD_GL_NV_robustness_video_memory_purge = 0;
1580int GLAD_GL_ARB_shading_language_100; 1581int GLAD_GL_ARB_shading_language_100 = 0;
1581int GLAD_GL_INTEL_performance_query; 1582int GLAD_GL_INTEL_performance_query = 0;
1582int GLAD_GL_ARB_texture_mirror_clamp_to_edge; 1583int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0;
1583int GLAD_GL_NV_gpu_shader5; 1584int GLAD_GL_NV_gpu_shader5 = 0;
1584int GLAD_GL_NV_bindless_multi_draw_indirect_count; 1585int GLAD_GL_NV_bindless_multi_draw_indirect_count = 0;
1585int GLAD_GL_ARB_ES2_compatibility; 1586int GLAD_GL_ARB_ES2_compatibility = 0;
1586int GLAD_GL_ARB_indirect_parameters; 1587int GLAD_GL_ARB_indirect_parameters = 0;
1587int GLAD_GL_EXT_window_rectangles; 1588int GLAD_GL_EXT_window_rectangles = 0;
1588int GLAD_GL_NV_half_float; 1589int GLAD_GL_NV_half_float = 0;
1589int GLAD_GL_ARB_ES3_2_compatibility; 1590int GLAD_GL_ARB_ES3_2_compatibility = 0;
1590int GLAD_GL_ATI_texture_mirror_once; 1591int GLAD_GL_ATI_texture_mirror_once = 0;
1591int GLAD_GL_IBM_rasterpos_clip; 1592int GLAD_GL_IBM_rasterpos_clip = 0;
1592int GLAD_GL_EXT_semaphore; 1593int GLAD_GL_EXT_semaphore = 0;
1593int GLAD_GL_SGIX_shadow; 1594int GLAD_GL_SGIX_shadow = 0;
1594int GLAD_GL_EXT_polygon_offset_clamp; 1595int GLAD_GL_EXT_polygon_offset_clamp = 0;
1595int GLAD_GL_NV_deep_texture3D; 1596int GLAD_GL_NV_deep_texture3D = 0;
1596int GLAD_GL_ARB_shader_draw_parameters; 1597int GLAD_GL_ARB_shader_draw_parameters = 0;
1597int GLAD_GL_SGIX_calligraphic_fragment; 1598int GLAD_GL_SGIX_calligraphic_fragment = 0;
1598int GLAD_GL_ARB_shader_bit_encoding; 1599int GLAD_GL_ARB_shader_bit_encoding = 0;
1599int GLAD_GL_EXT_compiled_vertex_array; 1600int GLAD_GL_EXT_compiled_vertex_array = 0;
1600int GLAD_GL_NV_depth_buffer_float; 1601int GLAD_GL_NV_depth_buffer_float = 0;
1601int GLAD_GL_NV_occlusion_query; 1602int GLAD_GL_NV_occlusion_query = 0;
1602int GLAD_GL_APPLE_flush_buffer_range; 1603int GLAD_GL_APPLE_flush_buffer_range = 0;
1603int GLAD_GL_ARB_imaging; 1604int GLAD_GL_ARB_imaging = 0;
1604int GLAD_GL_NV_shader_atomic_float; 1605int GLAD_GL_NV_shader_atomic_float = 0;
1605int GLAD_GL_ARB_draw_buffers_blend; 1606int GLAD_GL_ARB_draw_buffers_blend = 0;
1606int GLAD_GL_AMD_gcn_shader; 1607int GLAD_GL_AMD_gcn_shader = 0;
1607int GLAD_GL_AMD_blend_minmax_factor; 1608int GLAD_GL_AMD_blend_minmax_factor = 0;
1608int GLAD_GL_EXT_texture_sRGB_decode; 1609int GLAD_GL_EXT_texture_sRGB_decode = 0;
1609int GLAD_GL_ARB_shading_language_420pack; 1610int GLAD_GL_ARB_shading_language_420pack = 0;
1610int GLAD_GL_ARB_shader_viewport_layer_array; 1611int GLAD_GL_ARB_shader_viewport_layer_array = 0;
1611int GLAD_GL_ATI_meminfo; 1612int GLAD_GL_ATI_meminfo = 0;
1612int GLAD_GL_EXT_abgr; 1613int GLAD_GL_EXT_abgr = 0;
1613int GLAD_GL_AMD_pinned_memory; 1614int GLAD_GL_AMD_pinned_memory = 0;
1614int GLAD_GL_EXT_texture_snorm; 1615int GLAD_GL_EXT_texture_snorm = 0;
1615int GLAD_GL_SGIX_texture_coordinate_clamp; 1616int GLAD_GL_SGIX_texture_coordinate_clamp = 0;
1616int GLAD_GL_ARB_clear_buffer_object; 1617int GLAD_GL_ARB_clear_buffer_object = 0;
1617int GLAD_GL_ARB_multisample; 1618int GLAD_GL_ARB_multisample = 0;
1618int GLAD_GL_EXT_debug_label; 1619int GLAD_GL_EXT_debug_label = 0;
1619int GLAD_GL_ARB_sample_shading; 1620int GLAD_GL_ARB_sample_shading = 0;
1620int GLAD_GL_NV_internalformat_sample_query; 1621int GLAD_GL_NV_internalformat_sample_query = 0;
1621int GLAD_GL_INTEL_map_texture; 1622int GLAD_GL_INTEL_map_texture = 0;
1622int GLAD_GL_ARB_texture_env_crossbar; 1623int GLAD_GL_ARB_texture_env_crossbar = 0;
1623int GLAD_GL_EXT_422_pixels; 1624int GLAD_GL_EXT_422_pixels = 0;
1624int GLAD_GL_NV_blend_minmax_factor; 1625int GLAD_GL_NV_blend_minmax_factor = 0;
1625int GLAD_GL_NV_conservative_raster_pre_snap_triangles; 1626int GLAD_GL_NV_conservative_raster_pre_snap_triangles = 0;
1626int GLAD_GL_ARB_compute_shader; 1627int GLAD_GL_ARB_compute_shader = 0;
1627int GLAD_GL_EXT_blend_logic_op; 1628int GLAD_GL_EXT_blend_logic_op = 0;
1628int GLAD_GL_ARB_blend_func_extended; 1629int GLAD_GL_ARB_blend_func_extended = 0;
1629int GLAD_GL_IBM_vertex_array_lists; 1630int GLAD_GL_IBM_vertex_array_lists = 0;
1630int GLAD_GL_ARB_color_buffer_float; 1631int GLAD_GL_ARB_color_buffer_float = 0;
1631int GLAD_GL_ARB_bindless_texture; 1632int GLAD_GL_ARB_bindless_texture = 0;
1632int GLAD_GL_ARB_window_pos; 1633int GLAD_GL_ARB_window_pos = 0;
1633int GLAD_GL_ARB_internalformat_query; 1634int GLAD_GL_ARB_internalformat_query = 0;
1634int GLAD_GL_ARB_shadow; 1635int GLAD_GL_ARB_shadow = 0;
1635int GLAD_GL_ARB_texture_mirrored_repeat; 1636int GLAD_GL_ARB_texture_mirrored_repeat = 0;
1636int GLAD_GL_EXT_shader_image_load_store; 1637int GLAD_GL_EXT_shader_image_load_store = 0;
1637int GLAD_GL_EXT_copy_texture; 1638int GLAD_GL_EXT_copy_texture = 0;
1638int GLAD_GL_NV_register_combiners2; 1639int GLAD_GL_NV_register_combiners2 = 0;
1639int GLAD_GL_SGIX_ycrcb_subsample; 1640int GLAD_GL_SGIX_ycrcb_subsample = 0;
1640int GLAD_GL_NV_alpha_to_coverage_dither_control; 1641int GLAD_GL_NV_alpha_to_coverage_dither_control = 0;
1641int GLAD_GL_SGIX_ir_instrument1; 1642int GLAD_GL_SGIX_ir_instrument1 = 0;
1642int GLAD_GL_NV_draw_texture; 1643int GLAD_GL_NV_draw_texture = 0;
1643int GLAD_GL_EXT_texture_shared_exponent; 1644int GLAD_GL_EXT_texture_shared_exponent = 0;
1644int GLAD_GL_NV_texture_shader2; 1645int GLAD_GL_NV_texture_shader2 = 0;
1645int GLAD_GL_EXT_draw_instanced; 1646int GLAD_GL_EXT_draw_instanced = 0;
1646int GLAD_GL_NV_copy_depth_to_color; 1647int GLAD_GL_NV_copy_depth_to_color = 0;
1647int GLAD_GL_ARB_viewport_array; 1648int GLAD_GL_ARB_viewport_array = 0;
1648int GLAD_GL_ARB_separate_shader_objects; 1649int GLAD_GL_ARB_separate_shader_objects = 0;
1649int GLAD_GL_NV_conservative_raster_pre_snap; 1650int GLAD_GL_NV_conservative_raster_pre_snap = 0;
1650int GLAD_GL_EXT_depth_bounds_test; 1651int GLAD_GL_EXT_depth_bounds_test = 0;
1651int GLAD_GL_HP_image_transform; 1652int GLAD_GL_HP_image_transform = 0;
1652int GLAD_GL_ARB_texture_env_add; 1653int GLAD_GL_ARB_texture_env_add = 0;
1653int GLAD_GL_NV_video_capture; 1654int GLAD_GL_NV_video_capture = 0;
1654int GLAD_GL_ARB_sampler_objects; 1655int GLAD_GL_ARB_sampler_objects = 0;
1655int GLAD_GL_ARB_matrix_palette; 1656int GLAD_GL_ARB_matrix_palette = 0;
1656int GLAD_GL_SGIS_texture_color_mask; 1657int GLAD_GL_SGIS_texture_color_mask = 0;
1657int GLAD_GL_EXT_packed_pixels; 1658int GLAD_GL_EXT_packed_pixels = 0;
1658int GLAD_GL_EXT_coordinate_frame; 1659int GLAD_GL_EXT_coordinate_frame = 0;
1659int GLAD_GL_ARB_texture_compression; 1660int GLAD_GL_ARB_texture_compression = 0;
1660int GLAD_GL_ARB_multi_bind; 1661int GLAD_GL_ARB_multi_bind = 0;
1661int GLAD_GL_APPLE_aux_depth_stencil; 1662int GLAD_GL_APPLE_aux_depth_stencil = 0;
1662int GLAD_GL_ARB_shader_subroutine; 1663int GLAD_GL_ARB_shader_subroutine = 0;
1663int GLAD_GL_EXT_framebuffer_sRGB; 1664int GLAD_GL_EXT_framebuffer_sRGB = 0;
1664int GLAD_GL_ARB_texture_storage_multisample; 1665int GLAD_GL_ARB_texture_storage_multisample = 0;
1665int GLAD_GL_KHR_blend_equation_advanced_coherent; 1666int GLAD_GL_KHR_blend_equation_advanced_coherent = 0;
1666int GLAD_GL_EXT_vertex_attrib_64bit; 1667int GLAD_GL_EXT_vertex_attrib_64bit = 0;
1667int GLAD_GL_NV_shader_atomic_float64; 1668int GLAD_GL_NV_shader_atomic_float64 = 0;
1668int GLAD_GL_ARB_depth_texture; 1669int GLAD_GL_ARB_depth_texture = 0;
1669int GLAD_GL_NV_shader_buffer_store; 1670int GLAD_GL_NV_shader_buffer_store = 0;
1670int GLAD_GL_OES_query_matrix; 1671int GLAD_GL_OES_query_matrix = 0;
1671int GLAD_GL_MESA_window_pos; 1672int GLAD_GL_MESA_window_pos = 0;
1672int GLAD_GL_NV_fill_rectangle; 1673int GLAD_GL_NV_fill_rectangle = 0;
1673int GLAD_GL_NV_shader_storage_buffer_object; 1674int GLAD_GL_NV_shader_storage_buffer_object = 0;
1674int GLAD_GL_ARB_texture_query_lod; 1675int GLAD_GL_ARB_texture_query_lod = 0;
1675int GLAD_GL_ARB_copy_buffer; 1676int GLAD_GL_ARB_copy_buffer = 0;
1676int GLAD_GL_ARB_shader_image_size; 1677int GLAD_GL_ARB_shader_image_size = 0;
1677int GLAD_GL_NV_shader_atomic_counters; 1678int GLAD_GL_NV_shader_atomic_counters = 0;
1678int GLAD_GL_APPLE_object_purgeable; 1679int GLAD_GL_APPLE_object_purgeable = 0;
1679int GLAD_GL_ARB_occlusion_query; 1680int GLAD_GL_ARB_occlusion_query = 0;
1680int GLAD_GL_INGR_color_clamp; 1681int GLAD_GL_INGR_color_clamp = 0;
1681int GLAD_GL_SGI_color_table; 1682int GLAD_GL_SGI_color_table = 0;
1682int GLAD_GL_NV_gpu_program5_mem_extended; 1683int GLAD_GL_NV_gpu_program5_mem_extended = 0;
1683int GLAD_GL_ARB_texture_cube_map_array; 1684int GLAD_GL_ARB_texture_cube_map_array = 0;
1684int GLAD_GL_SGIX_scalebias_hint; 1685int GLAD_GL_SGIX_scalebias_hint = 0;
1685int GLAD_GL_EXT_gpu_shader4; 1686int GLAD_GL_EXT_gpu_shader4 = 0;
1686int GLAD_GL_NV_geometry_program4; 1687int GLAD_GL_NV_geometry_program4 = 0;
1687int GLAD_GL_EXT_framebuffer_multisample_blit_scaled; 1688int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0;
1688int GLAD_GL_AMD_debug_output; 1689int GLAD_GL_AMD_debug_output = 0;
1689int GLAD_GL_ARB_texture_border_clamp; 1690int GLAD_GL_ARB_texture_border_clamp = 0;
1690int GLAD_GL_EXT_win32_keyed_mutex; 1691int GLAD_GL_EXT_win32_keyed_mutex = 0;
1691int GLAD_GL_ARB_fragment_coord_conventions; 1692int GLAD_GL_ARB_fragment_coord_conventions = 0;
1692int GLAD_GL_ARB_multitexture; 1693int GLAD_GL_ARB_multitexture = 0;
1693int GLAD_GL_SGIX_polynomial_ffd; 1694int GLAD_GL_SGIX_polynomial_ffd = 0;
1694int GLAD_GL_EXT_texture_env_dot3; 1695int GLAD_GL_EXT_texture_env_dot3 = 0;
1695int GLAD_GL_EXT_provoking_vertex; 1696int GLAD_GL_EXT_provoking_vertex = 0;
1696int GLAD_GL_ARB_point_parameters; 1697int GLAD_GL_ARB_point_parameters = 0;
1697int GLAD_GL_ARB_shader_image_load_store; 1698int GLAD_GL_ARB_shader_image_load_store = 0;
1698int GLAD_GL_ARB_conditional_render_inverted; 1699int GLAD_GL_ARB_conditional_render_inverted = 0;
1699int GLAD_GL_HP_occlusion_test; 1700int GLAD_GL_HP_occlusion_test = 0;
1700int GLAD_GL_ARB_ES3_compatibility; 1701int GLAD_GL_ARB_ES3_compatibility = 0;
1701int GLAD_GL_ARB_texture_barrier; 1702int GLAD_GL_ARB_texture_barrier = 0;
1702int GLAD_GL_ARB_texture_buffer_object_rgb32; 1703int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0;
1703int GLAD_GL_NV_bindless_multi_draw_indirect; 1704int GLAD_GL_NV_bindless_multi_draw_indirect = 0;
1704int GLAD_GL_SGIX_texture_multi_buffer; 1705int GLAD_GL_SGIX_texture_multi_buffer = 0;
1705int GLAD_GL_INTEL_blackhole_render; 1706int GLAD_GL_INTEL_blackhole_render = 0;
1706int GLAD_GL_AMD_shader_image_load_store_lod; 1707int GLAD_GL_AMD_shader_image_load_store_lod = 0;
1707int GLAD_GL_KHR_texture_compression_astc_ldr; 1708int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
1708int GLAD_GL_3DFX_multisample; 1709int GLAD_GL_3DFX_multisample = 0;
1709int GLAD_GL_INTEL_fragment_shader_ordering; 1710int GLAD_GL_INTEL_fragment_shader_ordering = 0;
1710int GLAD_GL_ARB_texture_env_dot3; 1711int GLAD_GL_ARB_texture_env_dot3 = 0;
1711int GLAD_GL_NV_gpu_program4; 1712int GLAD_GL_NV_gpu_program4 = 0;
1712int GLAD_GL_NV_gpu_program5; 1713int GLAD_GL_NV_gpu_program5 = 0;
1713int GLAD_GL_NV_float_buffer; 1714int GLAD_GL_NV_float_buffer = 0;
1714int GLAD_GL_SGIS_texture_edge_clamp; 1715int GLAD_GL_SGIS_texture_edge_clamp = 0;
1715int GLAD_GL_ARB_framebuffer_sRGB; 1716int GLAD_GL_ARB_framebuffer_sRGB = 0;
1716int GLAD_GL_SUN_slice_accum; 1717int GLAD_GL_SUN_slice_accum = 0;
1717int GLAD_GL_EXT_index_texture; 1718int GLAD_GL_EXT_index_texture = 0;
1718int GLAD_GL_EXT_shader_image_load_formatted; 1719int GLAD_GL_EXT_shader_image_load_formatted = 0;
1719int GLAD_GL_ARB_geometry_shader4; 1720int GLAD_GL_ARB_geometry_shader4 = 0;
1720int GLAD_GL_EXT_separate_specular_color; 1721int GLAD_GL_EXT_separate_specular_color = 0;
1721int GLAD_GL_AMD_depth_clamp_separate; 1722int GLAD_GL_AMD_depth_clamp_separate = 0;
1722int GLAD_GL_NV_conservative_raster; 1723int GLAD_GL_NV_conservative_raster = 0;
1723int GLAD_GL_ARB_sparse_texture2; 1724int GLAD_GL_ARB_sparse_texture2 = 0;
1724int GLAD_GL_SGIX_sprite; 1725int GLAD_GL_SGIX_sprite = 0;
1725int GLAD_GL_ARB_get_program_binary; 1726int GLAD_GL_ARB_get_program_binary = 0;
1726int GLAD_GL_AMD_occlusion_query_event; 1727int GLAD_GL_AMD_occlusion_query_event = 0;
1727int GLAD_GL_SGIS_multisample; 1728int GLAD_GL_SGIS_multisample = 0;
1728int GLAD_GL_EXT_framebuffer_object; 1729int GLAD_GL_EXT_framebuffer_object = 0;
1729int GLAD_GL_ARB_robustness_isolation; 1730int GLAD_GL_ARB_robustness_isolation = 0;
1730int GLAD_GL_ARB_vertex_array_bgra; 1731int GLAD_GL_ARB_vertex_array_bgra = 0;
1731int GLAD_GL_APPLE_vertex_array_range; 1732int GLAD_GL_APPLE_vertex_array_range = 0;
1732int GLAD_GL_AMD_query_buffer_object; 1733int GLAD_GL_AMD_query_buffer_object = 0;
1733int GLAD_GL_NV_register_combiners; 1734int GLAD_GL_NV_register_combiners = 0;
1734int GLAD_GL_ARB_draw_buffers; 1735int GLAD_GL_ARB_draw_buffers = 0;
1735int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers; 1736int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = 0;
1736int GLAD_GL_AMD_gpu_shader_int16; 1737int GLAD_GL_AMD_gpu_shader_int16 = 0;
1737int GLAD_GL_ARB_debug_output; 1738int GLAD_GL_ARB_debug_output = 0;
1738int GLAD_GL_EXT_shader_framebuffer_fetch; 1739int GLAD_GL_EXT_shader_framebuffer_fetch = 0;
1739int GLAD_GL_SGI_color_matrix; 1740int GLAD_GL_SGI_color_matrix = 0;
1740int GLAD_GL_EXT_cull_vertex; 1741int GLAD_GL_EXT_cull_vertex = 0;
1741int GLAD_GL_EXT_texture_sRGB; 1742int GLAD_GL_AMD_framebuffer_multisample_advanced = 0;
1742int GLAD_GL_APPLE_row_bytes; 1743int GLAD_GL_EXT_texture_sRGB = 0;
1743int GLAD_GL_NV_conservative_raster_underestimation; 1744int GLAD_GL_APPLE_row_bytes = 0;
1744int GLAD_GL_IBM_multimode_draw_arrays; 1745int GLAD_GL_NV_conservative_raster_underestimation = 0;
1745int GLAD_GL_KHR_parallel_shader_compile; 1746int GLAD_GL_IBM_multimode_draw_arrays = 0;
1746int GLAD_GL_APPLE_vertex_array_object; 1747int GLAD_GL_KHR_parallel_shader_compile = 0;
1747int GLAD_GL_3DFX_texture_compression_FXT1; 1748int GLAD_GL_APPLE_vertex_array_object = 0;
1748int GLAD_GL_NV_fragment_shader_interlock; 1749int GLAD_GL_3DFX_texture_compression_FXT1 = 0;
1749int GLAD_GL_AMD_conservative_depth; 1750int GLAD_GL_NV_fragment_shader_interlock = 0;
1750int GLAD_GL_ARB_texture_float; 1751int GLAD_GL_AMD_conservative_depth = 0;
1751int GLAD_GL_ARB_compressed_texture_pixel_storage; 1752int GLAD_GL_ARB_texture_float = 0;
1752int GLAD_GL_SGIS_detail_texture; 1753int GLAD_GL_ARB_compressed_texture_pixel_storage = 0;
1753int GLAD_GL_NV_geometry_shader_passthrough; 1754int GLAD_GL_SGIS_detail_texture = 0;
1754int GLAD_GL_ARB_draw_instanced; 1755int GLAD_GL_NV_geometry_shader_passthrough = 0;
1755int GLAD_GL_OES_read_format; 1756int GLAD_GL_ARB_draw_instanced = 0;
1756int GLAD_GL_ATI_texture_float; 1757int GLAD_GL_OES_read_format = 0;
1757int GLAD_GL_ARB_texture_gather; 1758int GLAD_GL_ATI_texture_float = 0;
1758int GLAD_GL_AMD_vertex_shader_layer; 1759int GLAD_GL_ARB_texture_gather = 0;
1759int GLAD_GL_ARB_shading_language_include; 1760int GLAD_GL_AMD_vertex_shader_layer = 0;
1760int GLAD_GL_APPLE_client_storage; 1761int GLAD_GL_ARB_shading_language_include = 0;
1761int GLAD_GL_WIN_phong_shading; 1762int GLAD_GL_APPLE_client_storage = 0;
1762int GLAD_GL_INGR_blend_func_separate; 1763int GLAD_GL_WIN_phong_shading = 0;
1763int GLAD_GL_NV_path_rendering; 1764int GLAD_GL_INGR_blend_func_separate = 0;
1764int GLAD_GL_NV_conservative_raster_dilate; 1765int GLAD_GL_NV_path_rendering = 0;
1765int GLAD_GL_AMD_gpu_shader_half_float; 1766int GLAD_GL_NV_conservative_raster_dilate = 0;
1766int GLAD_GL_ARB_post_depth_coverage; 1767int GLAD_GL_AMD_gpu_shader_half_float = 0;
1767int GLAD_GL_ARB_texture_non_power_of_two; 1768int GLAD_GL_ARB_post_depth_coverage = 0;
1768int GLAD_GL_APPLE_rgb_422; 1769int GLAD_GL_ARB_texture_non_power_of_two = 0;
1769int GLAD_GL_EXT_texture_lod_bias; 1770int GLAD_GL_APPLE_rgb_422 = 0;
1770int GLAD_GL_ARB_gpu_shader_int64; 1771int GLAD_GL_EXT_texture_lod_bias = 0;
1771int GLAD_GL_ARB_seamless_cube_map; 1772int GLAD_GL_ARB_gpu_shader_int64 = 0;
1772int GLAD_GL_ARB_shader_group_vote; 1773int GLAD_GL_ARB_seamless_cube_map = 0;
1773int GLAD_GL_NV_vdpau_interop; 1774int GLAD_GL_ARB_shader_group_vote = 0;
1774int GLAD_GL_ARB_occlusion_query2; 1775int GLAD_GL_NV_vdpau_interop = 0;
1775int GLAD_GL_ARB_internalformat_query2; 1776int GLAD_GL_ARB_occlusion_query2 = 0;
1776int GLAD_GL_EXT_texture_filter_anisotropic; 1777int GLAD_GL_ARB_internalformat_query2 = 0;
1777int GLAD_GL_SUN_vertex; 1778int GLAD_GL_EXT_texture_filter_anisotropic = 0;
1778int GLAD_GL_EXT_transform_feedback; 1779int GLAD_GL_SUN_vertex = 0;
1779int GLAD_GL_SGIX_igloo_interface; 1780int GLAD_GL_EXT_transform_feedback = 0;
1780int GLAD_GL_SGIS_texture_lod; 1781int GLAD_GL_SGIX_igloo_interface = 0;
1781int GLAD_GL_NV_vertex_program3; 1782int GLAD_GL_SGIS_texture_lod = 0;
1782int GLAD_GL_ARB_draw_indirect; 1783int GLAD_GL_NV_vertex_program3 = 0;
1783int GLAD_GL_NV_vertex_program4; 1784int GLAD_GL_ARB_draw_indirect = 0;
1784int GLAD_GL_AMD_transform_feedback3_lines_triangles; 1785int GLAD_GL_NV_vertex_program4 = 0;
1785int GLAD_GL_SGIS_fog_function; 1786int GLAD_GL_AMD_transform_feedback3_lines_triangles = 0;
1786int GLAD_GL_EXT_x11_sync_object; 1787int GLAD_GL_SGIS_fog_function = 0;
1787int GLAD_GL_ARB_sync; 1788int GLAD_GL_EXT_x11_sync_object = 0;
1788int GLAD_GL_NV_texture_rectangle_compressed; 1789int GLAD_GL_ARB_sync = 0;
1789int GLAD_GL_NV_sample_locations; 1790int GLAD_GL_NV_texture_rectangle_compressed = 0;
1790int GLAD_GL_NV_gpu_multicast; 1791int GLAD_GL_NV_sample_locations = 0;
1791int GLAD_GL_ARB_gl_spirv; 1792int GLAD_GL_NV_gpu_multicast = 0;
1792int GLAD_GL_ARB_compute_variable_group_size; 1793int GLAD_GL_ARB_gl_spirv = 0;
1793int GLAD_GL_OES_fixed_point; 1794int GLAD_GL_ARB_compute_variable_group_size = 0;
1794int GLAD_GL_MESA_program_binary_formats; 1795int GLAD_GL_OES_fixed_point = 0;
1795int GLAD_GL_NV_blend_square; 1796int GLAD_GL_MESA_program_binary_formats = 0;
1796int GLAD_GL_EXT_framebuffer_multisample; 1797int GLAD_GL_NV_blend_square = 0;
1797int GLAD_GL_ARB_gpu_shader5; 1798int GLAD_GL_EXT_framebuffer_multisample = 0;
1798int GLAD_GL_SGIS_texture4D; 1799int GLAD_GL_ARB_gpu_shader5 = 0;
1799int GLAD_GL_EXT_texture3D; 1800int GLAD_GL_SGIS_texture4D = 0;
1800int GLAD_GL_EXT_multisample; 1801int GLAD_GL_EXT_texture3D = 0;
1801int GLAD_GL_EXT_secondary_color; 1802int GLAD_GL_EXT_multisample = 0;
1802int GLAD_GL_INTEL_conservative_rasterization; 1803int GLAD_GL_EXT_secondary_color = 0;
1803int GLAD_GL_ARB_texture_filter_minmax; 1804int GLAD_GL_INTEL_conservative_rasterization = 0;
1804int GLAD_GL_ATI_vertex_array_object; 1805int GLAD_GL_ARB_texture_filter_minmax = 0;
1805int GLAD_GL_ARB_parallel_shader_compile; 1806int GLAD_GL_ATI_vertex_array_object = 0;
1806int GLAD_GL_NVX_gpu_memory_info; 1807int GLAD_GL_ARB_parallel_shader_compile = 0;
1807int GLAD_GL_ARB_sparse_texture; 1808int GLAD_GL_NVX_gpu_memory_info = 0;
1808int GLAD_GL_SGIS_point_line_texgen; 1809int GLAD_GL_ARB_sparse_texture = 0;
1809int GLAD_GL_ARB_sample_locations; 1810int GLAD_GL_SGIS_point_line_texgen = 0;
1810int GLAD_GL_ARB_sparse_buffer; 1811int GLAD_GL_ARB_sample_locations = 0;
1811int GLAD_GL_ARB_polygon_offset_clamp; 1812int GLAD_GL_ARB_sparse_buffer = 0;
1812int GLAD_GL_EXT_draw_range_elements; 1813int GLAD_GL_ARB_polygon_offset_clamp = 0;
1813int GLAD_GL_SGIX_blend_alpha_minmax; 1814int GLAD_GL_EXT_draw_range_elements = 0;
1814int GLAD_GL_KHR_context_flush_control; 1815int GLAD_GL_SGIX_blend_alpha_minmax = 0;
1815PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX; 1816int GLAD_GL_KHR_context_flush_control = 0;
1816PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD; 1817PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX = NULL;
1817PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD; 1818PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD = NULL;
1818PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD; 1819PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD = NULL;
1819PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD; 1820PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD = NULL;
1820PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD; 1821PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD = NULL;
1821PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD; 1822PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD = NULL;
1822PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD; 1823PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD = NULL;
1823PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; 1824PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD = NULL;
1824PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD; 1825PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD = NULL;
1825PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD; 1826PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD = NULL;
1826PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD; 1827PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = NULL;
1827PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD; 1828PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD = NULL;
1828PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV; 1829PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD = NULL;
1829PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV; 1830PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD = NULL;
1830PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV; 1831PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD = NULL;
1831PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV; 1832PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV = NULL;
1832PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV; 1833PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV = NULL;
1833PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV; 1834PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV = NULL;
1834PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV; 1835PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV = NULL;
1835PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV; 1836PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV = NULL;
1836PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV; 1837PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV = NULL;
1837PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV; 1838PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV = NULL;
1838PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV; 1839PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV = NULL;
1839PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV; 1840PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV = NULL;
1840PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV; 1841PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV = NULL;
1841PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV; 1842PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV = NULL;
1842PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV; 1843PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV = NULL;
1843PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV; 1844PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV = NULL;
1844PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV; 1845PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV = NULL;
1845PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV; 1846PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV = NULL;
1846PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV; 1847PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV = NULL;
1847PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV; 1848PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV = NULL;
1848PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV; 1849PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV = NULL;
1849PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV; 1850PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV = NULL;
1850PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV; 1851PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV = NULL;
1851PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV; 1852PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV = NULL;
1852PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV; 1853PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV = NULL;
1853PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV; 1854PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV = NULL;
1854PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV; 1855PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV = NULL;
1855PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV; 1856PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV = NULL;
1856PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV; 1857PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV = NULL;
1857PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV; 1858PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV = NULL;
1858PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV; 1859PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV = NULL;
1859PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV; 1860PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV = NULL;
1860PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV; 1861PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV = NULL;
1861PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV; 1862PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV = NULL;
1862PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD; 1863PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV = NULL;
1863PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD; 1864PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV = NULL;
1864PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD; 1865PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV = NULL;
1865PFNGLGENNAMESAMDPROC glad_glGenNamesAMD; 1866PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD = NULL;
1866PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD; 1867PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD = NULL;
1867PFNGLISNAMEAMDPROC glad_glIsNameAMD; 1868PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD = NULL;
1868PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD; 1869PFNGLGENNAMESAMDPROC glad_glGenNamesAMD = NULL;
1869PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD; 1870PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD = NULL;
1870PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD; 1871PFNGLISNAMEAMDPROC glad_glIsNameAMD = NULL;
1871PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD; 1872PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD = NULL;
1872PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD; 1873PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD = NULL;
1873PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD; 1874PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD = NULL;
1874PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD; 1875PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD = NULL;
1875PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD; 1876PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD = NULL;
1876PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD; 1877PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD = NULL;
1877PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD; 1878PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD = NULL;
1878PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD; 1879PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD = NULL;
1879PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD; 1880PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD = NULL;
1880PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD; 1881PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD = NULL;
1881PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD; 1882PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD = NULL;
1882PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD; 1883PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD = NULL;
1883PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD; 1884PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD = NULL;
1884PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD; 1885PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD = NULL;
1885PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD; 1886PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD = NULL;
1886PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE; 1887PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD = NULL;
1887PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE; 1888PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD = NULL;
1888PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE; 1889PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD = NULL;
1889PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE; 1890PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE = NULL;
1890PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE; 1891PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE = NULL;
1891PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE; 1892PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE = NULL;
1892PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE; 1893PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE = NULL;
1893PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE; 1894PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE = NULL;
1894PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE; 1895PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE = NULL;
1895PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE; 1896PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE = NULL;
1896PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE; 1897PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE = NULL;
1897PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE; 1898PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE = NULL;
1898PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE; 1899PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE = NULL;
1899PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE; 1900PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE = NULL;
1900PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE; 1901PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE = NULL;
1901PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE; 1902PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE = NULL;
1902PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE; 1903PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE = NULL;
1903PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE; 1904PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE = NULL;
1904PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE; 1905PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE = NULL;
1905PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE; 1906PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE = NULL;
1906PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE; 1907PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE = NULL;
1907PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE; 1908PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE = NULL;
1908PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE; 1909PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE = NULL;
1909PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE; 1910PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE = NULL;
1910PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE; 1911PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE = NULL;
1911PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE; 1912PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE = NULL;
1912PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE; 1913PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE = NULL;
1913PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE; 1914PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE = NULL;
1914PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE; 1915PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE = NULL;
1915PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE; 1916PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE = NULL;
1916PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE; 1917PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE = NULL;
1917PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE; 1918PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE = NULL;
1918PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE; 1919PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE = NULL;
1919PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE; 1920PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE = NULL;
1920PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; 1921PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE = NULL;
1921PFNGLSHADERBINARYPROC glad_glShaderBinary; 1922PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE = NULL;
1922PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; 1923PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE = NULL;
1923PFNGLDEPTHRANGEFPROC glad_glDepthRangef; 1924PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
1924PFNGLCLEARDEPTHFPROC glad_glClearDepthf; 1925PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
1925PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; 1926PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
1926PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB; 1927PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
1927PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; 1928PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
1928PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; 1929PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL;
1929PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; 1930PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB = NULL;
1930PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB; 1931PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
1931PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB; 1932PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
1932PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB; 1933PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
1933PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB; 1934PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB = NULL;
1934PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB; 1935PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB = NULL;
1935PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB; 1936PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB = NULL;
1936PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB; 1937PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB = NULL;
1937PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB; 1938PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB = NULL;
1938PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB; 1939PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB = NULL;
1939PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB; 1940PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB = NULL;
1940PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB; 1941PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB = NULL;
1941PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB; 1942PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB = NULL;
1942PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB; 1943PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB = NULL;
1943PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB; 1944PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB = NULL;
1944PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB; 1945PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB = NULL;
1945PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB; 1946PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB = NULL;
1946PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; 1947PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB = NULL;
1947PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB; 1948PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB = NULL;
1948PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; 1949PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB = NULL;
1949PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; 1950PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
1950PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; 1951PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB = NULL;
1951PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; 1952PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL;
1952PFNGLCLIPCONTROLPROC glad_glClipControl; 1953PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL;
1953PFNGLCLAMPCOLORARBPROC glad_glClampColorARB; 1954PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
1954PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; 1955PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
1955PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; 1956PFNGLCLIPCONTROLPROC glad_glClipControl = NULL;
1956PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB; 1957PFNGLCLAMPCOLORARBPROC glad_glClampColorARB = NULL;
1957PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; 1958PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL;
1958PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; 1959PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL;
1959PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; 1960PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB = NULL;
1960PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; 1961PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL;
1961PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; 1962PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL;
1962PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; 1963PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL;
1963PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; 1964PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL;
1964PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; 1965PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL;
1965PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; 1966PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL;
1966PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; 1967PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL;
1967PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; 1968PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL;
1968PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; 1969PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL;
1969PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; 1970PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL;
1970PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; 1971PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL;
1971PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; 1972PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL;
1972PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; 1973PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL;
1973PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; 1974PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL;
1974PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; 1975PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL;
1975PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; 1976PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL;
1976PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; 1977PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL;
1977PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; 1978PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL;
1978PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; 1979PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL;
1979PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; 1980PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL;
1980PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; 1981PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL;
1981PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; 1982PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL;
1982PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; 1983PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL;
1983PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; 1984PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL;
1984PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; 1985PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL;
1985PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; 1986PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL;
1986PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; 1987PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL;
1987PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; 1988PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL;
1988PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; 1989PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL;
1989PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; 1990PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL;
1990PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; 1991PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL;
1991PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; 1992PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL;
1992PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; 1993PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL;
1993PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; 1994PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL;
1994PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; 1995PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL;
1995PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; 1996PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL;
1996PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; 1997PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL;
1997PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; 1998PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL;
1998PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; 1999PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL;
1999PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; 2000PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL;
2000PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; 2001PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL;
2001PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; 2002PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL;
2002PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; 2003PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL;
2003PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; 2004PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL;
2004PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; 2005PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL;
2005PFNGLCREATETEXTURESPROC glad_glCreateTextures; 2006PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL;
2006PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; 2007PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL;
2007PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; 2008PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL;
2008PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; 2009PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL;
2009PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; 2010PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL;
2010PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; 2011PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL;
2011PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; 2012PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL;
2012PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; 2013PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL;
2013PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; 2014PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL;
2014PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; 2015PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL;
2015PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; 2016PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL;
2016PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; 2017PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL;
2017PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; 2018PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL;
2018PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; 2019PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL;
2019PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; 2020PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL;
2020PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; 2021PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL;
2021PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; 2022PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL;
2022PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; 2023PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL;
2023PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; 2024PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL;
2024PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; 2025PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL;
2025PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; 2026PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL;
2026PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; 2027PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL;
2027PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; 2028PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL;
2028PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; 2029PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL;
2029PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; 2030PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL;
2030PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; 2031PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL;
2031PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; 2032PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL;
2032PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; 2033PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL;
2033PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; 2034PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL;
2034PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; 2035PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL;
2035PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; 2036PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL;
2036PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; 2037PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL;
2037PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; 2038PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL;
2038PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; 2039PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL;
2039PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; 2040PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL;
2040PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; 2041PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL;
2041PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; 2042PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL;
2042PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; 2043PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL;
2043PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; 2044PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL;
2044PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; 2045PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL;
2045PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; 2046PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL;
2046PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; 2047PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL;
2047PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; 2048PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL;
2048PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; 2049PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL;
2049PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; 2050PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL;
2050PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; 2051PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL;
2051PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; 2052PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL;
2052PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; 2053PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL;
2053PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; 2054PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL;
2054PFNGLCREATEQUERIESPROC glad_glCreateQueries; 2055PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL;
2055PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; 2056PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL;
2056PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; 2057PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL;
2057PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; 2058PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL;
2058PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; 2059PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL;
2059PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB; 2060PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL;
2060PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB; 2061PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL;
2061PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB; 2062PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL;
2062PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB; 2063PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL;
2063PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB; 2064PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB = NULL;
2064PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; 2065PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB = NULL;
2065PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; 2066PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB = NULL;
2066PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB; 2067PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB = NULL;
2067PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB; 2068PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
2068PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB; 2069PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL;
2069PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB; 2070PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL;
2070PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB; 2071PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL;
2071PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB; 2072PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB = NULL;
2072PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB; 2073PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB = NULL;
2073PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB; 2074PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB = NULL;
2074PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB; 2075PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB = NULL;
2075PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB; 2076PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB = NULL;
2076PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB; 2077PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB = NULL;
2077PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB; 2078PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB = NULL;
2078PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB; 2079PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB = NULL;
2079PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB; 2080PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB = NULL;
2080PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB; 2081PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB = NULL;
2081PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB; 2082PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB = NULL;
2082PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB; 2083PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB = NULL;
2083PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB; 2084PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB = NULL;
2084PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB; 2085PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB = NULL;
2085PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB; 2086PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB = NULL;
2086PFNGLISPROGRAMARBPROC glad_glIsProgramARB; 2087PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB = NULL;
2087PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; 2088PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB = NULL;
2088PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; 2089PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB = NULL;
2089PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB; 2090PFNGLISPROGRAMARBPROC glad_glIsProgramARB = NULL;
2090PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB; 2091PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL;
2091PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB; 2092PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL;
2092PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB; 2093PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB = NULL;
2093PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; 2094PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB = NULL;
2094PFNGLPROGRAMBINARYPROC glad_glProgramBinary; 2095PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB = NULL;
2095PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; 2096PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB = NULL;
2096PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; 2097PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
2097PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; 2098PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
2098PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB; 2099PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
2099PFNGLUNIFORM1DPROC glad_glUniform1d; 2100PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL;
2100PFNGLUNIFORM2DPROC glad_glUniform2d; 2101PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL;
2101PFNGLUNIFORM3DPROC glad_glUniform3d; 2102PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB = NULL;
2102PFNGLUNIFORM4DPROC glad_glUniform4d; 2103PFNGLUNIFORM1DPROC glad_glUniform1d = NULL;
2103PFNGLUNIFORM1DVPROC glad_glUniform1dv; 2104PFNGLUNIFORM2DPROC glad_glUniform2d = NULL;
2104PFNGLUNIFORM2DVPROC glad_glUniform2dv; 2105PFNGLUNIFORM3DPROC glad_glUniform3d = NULL;
2105PFNGLUNIFORM3DVPROC glad_glUniform3dv; 2106PFNGLUNIFORM4DPROC glad_glUniform4d = NULL;
2106PFNGLUNIFORM4DVPROC glad_glUniform4dv; 2107PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL;
2107PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; 2108PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL;
2108PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; 2109PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL;
2109PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; 2110PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL;
2110PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; 2111PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL;
2111PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; 2112PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL;
2112PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; 2113PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL;
2113PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; 2114PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL;
2114PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; 2115PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL;
2115PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; 2116PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL;
2116PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; 2117PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL;
2117PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB; 2118PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL;
2118PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB; 2119PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL;
2119PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB; 2120PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL;
2120PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB; 2121PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB = NULL;
2121PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB; 2122PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB = NULL;
2122PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB; 2123PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB = NULL;
2123PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB; 2124PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB = NULL;
2124PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB; 2125PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB = NULL;
2125PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB; 2126PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB = NULL;
2126PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB; 2127PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB = NULL;
2127PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB; 2128PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB = NULL;
2128PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB; 2129PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB = NULL;
2129PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB; 2130PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB = NULL;
2130PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB; 2131PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB = NULL;
2131PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB; 2132PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB = NULL;
2132PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB; 2133PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB = NULL;
2133PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB; 2134PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB = NULL;
2134PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB; 2135PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB = NULL;
2135PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB; 2136PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB = NULL;
2136PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB; 2137PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB = NULL;
2137PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB; 2138PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB = NULL;
2138PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB; 2139PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB = NULL;
2139PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB; 2140PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB = NULL;
2140PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB; 2141PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB = NULL;
2141PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB; 2142PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB = NULL;
2142PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB; 2143PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB = NULL;
2143PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB; 2144PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB = NULL;
2144PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB; 2145PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB = NULL;
2145PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB; 2146PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB = NULL;
2146PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB; 2147PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB = NULL;
2147PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB; 2148PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB = NULL;
2148PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB; 2149PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB = NULL;
2149PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB; 2150PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB = NULL;
2150PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB; 2151PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB = NULL;
2151PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB; 2152PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB = NULL;
2152PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB; 2153PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB = NULL;
2153PFNGLCOLORTABLEPROC glad_glColorTable; 2154PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB = NULL;
2154PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv; 2155PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB = NULL;
2155PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv; 2156PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB = NULL;
2156PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable; 2157PFNGLCOLORTABLEPROC glad_glColorTable = NULL;
2157PFNGLGETCOLORTABLEPROC glad_glGetColorTable; 2158PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv = NULL;
2158PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv; 2159PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv = NULL;
2159PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv; 2160PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable = NULL;
2160PFNGLCOLORSUBTABLEPROC glad_glColorSubTable; 2161PFNGLGETCOLORTABLEPROC glad_glGetColorTable = NULL;
2161PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable; 2162PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv = NULL;
2162PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D; 2163PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv = NULL;
2163PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D; 2164PFNGLCOLORSUBTABLEPROC glad_glColorSubTable = NULL;
2164PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf; 2165PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable = NULL;
2165PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv; 2166PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D = NULL;
2166PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri; 2167PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D = NULL;
2167PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv; 2168PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf = NULL;
2168PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D; 2169PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv = NULL;
2169PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D; 2170PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri = NULL;
2170PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter; 2171PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv = NULL;
2171PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv; 2172PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D = NULL;
2172PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv; 2173PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D = NULL;
2173PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter; 2174PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter = NULL;
2174PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D; 2175PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv = NULL;
2175PFNGLGETHISTOGRAMPROC glad_glGetHistogram; 2176PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv = NULL;
2176PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv; 2177PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter = NULL;
2177PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv; 2178PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D = NULL;
2178PFNGLGETMINMAXPROC glad_glGetMinmax; 2179PFNGLGETHISTOGRAMPROC glad_glGetHistogram = NULL;
2179PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv; 2180PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv = NULL;
2180PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv; 2181PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv = NULL;
2181PFNGLHISTOGRAMPROC glad_glHistogram; 2182PFNGLGETMINMAXPROC glad_glGetMinmax = NULL;
2182PFNGLMINMAXPROC glad_glMinmax; 2183PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv = NULL;
2183PFNGLRESETHISTOGRAMPROC glad_glResetHistogram; 2184PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv = NULL;
2184PFNGLRESETMINMAXPROC glad_glResetMinmax; 2185PFNGLHISTOGRAMPROC glad_glHistogram = NULL;
2185PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB; 2186PFNGLMINMAXPROC glad_glMinmax = NULL;
2186PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB; 2187PFNGLRESETHISTOGRAMPROC glad_glResetHistogram = NULL;
2187PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB; 2188PFNGLRESETMINMAXPROC glad_glResetMinmax = NULL;
2188PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; 2189PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB = NULL;
2189PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; 2190PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB = NULL;
2190PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; 2191PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB = NULL;
2191PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; 2192PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
2192PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; 2193PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL;
2193PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; 2194PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL;
2194PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; 2195PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL;
2195PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; 2196PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL;
2196PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB; 2197PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL;
2197PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB; 2198PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
2198PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB; 2199PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
2199PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB; 2200PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB = NULL;
2200PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB; 2201PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB = NULL;
2201PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; 2202PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB = NULL;
2202PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; 2203PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB = NULL;
2203PFNGLBINDTEXTURESPROC glad_glBindTextures; 2204PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB = NULL;
2204PFNGLBINDSAMPLERSPROC glad_glBindSamplers; 2205PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL;
2205PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; 2206PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL;
2206PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; 2207PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL;
2207PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; 2208PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL;
2208PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; 2209PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL;
2209PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; 2210PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL;
2210PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB; 2211PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL;
2211PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB; 2212PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL;
2212PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB; 2213PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL;
2213PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB; 2214PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB = NULL;
2214PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB; 2215PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB = NULL;
2215PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB; 2216PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB = NULL;
2216PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB; 2217PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB = NULL;
2217PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB; 2218PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB = NULL;
2218PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB; 2219PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB = NULL;
2219PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB; 2220PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB = NULL;
2220PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB; 2221PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB = NULL;
2221PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB; 2222PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB = NULL;
2222PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB; 2223PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB = NULL;
2223PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB; 2224PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB = NULL;
2224PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB; 2225PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB = NULL;
2225PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB; 2226PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB = NULL;
2226PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB; 2227PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB = NULL;
2227PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB; 2228PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB = NULL;
2228PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB; 2229PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB = NULL;
2229PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB; 2230PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB = NULL;
2230PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB; 2231PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB = NULL;
2231PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB; 2232PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB = NULL;
2232PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB; 2233PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB = NULL;
2233PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB; 2234PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB = NULL;
2234PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB; 2235PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB = NULL;
2235PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB; 2236PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB = NULL;
2236PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB; 2237PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB = NULL;
2237PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB; 2238PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB = NULL;
2238PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB; 2239PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB = NULL;
2239PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB; 2240PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB = NULL;
2240PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB; 2241PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB = NULL;
2241PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB; 2242PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB = NULL;
2242PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB; 2243PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB = NULL;
2243PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB; 2244PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB = NULL;
2244PFNGLGENQUERIESARBPROC glad_glGenQueriesARB; 2245PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB = NULL;
2245PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB; 2246PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB = NULL;
2246PFNGLISQUERYARBPROC glad_glIsQueryARB; 2247PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB = NULL;
2247PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB; 2248PFNGLGENQUERIESARBPROC glad_glGenQueriesARB = NULL;
2248PFNGLENDQUERYARBPROC glad_glEndQueryARB; 2249PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB = NULL;
2249PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB; 2250PFNGLISQUERYARBPROC glad_glIsQueryARB = NULL;
2250PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB; 2251PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB = NULL;
2251PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB; 2252PFNGLENDQUERYARBPROC glad_glEndQueryARB = NULL;
2252PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB; 2253PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB = NULL;
2253PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB; 2254PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB = NULL;
2254PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB; 2255PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB = NULL;
2255PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; 2256PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB = NULL;
2256PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; 2257PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB = NULL;
2257PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; 2258PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB = NULL;
2258PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; 2259PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL;
2259PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; 2260PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL;
2260PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; 2261PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL;
2261PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; 2262PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL;
2262PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; 2263PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL;
2263PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; 2264PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL;
2264PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; 2265PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL;
2265PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; 2266PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL;
2266PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; 2267PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL;
2267PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; 2268PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL;
2268PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; 2269PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL;
2269PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; 2270PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL;
2270PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; 2271PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL;
2271PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; 2272PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL;
2272PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; 2273PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL;
2273PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; 2274PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL;
2274PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; 2275PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL;
2275PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; 2276PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL;
2276PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; 2277PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL;
2277PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; 2278PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL;
2278PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; 2279PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL;
2279PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; 2280PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL;
2280PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; 2281PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL;
2281PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; 2282PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL;
2282PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB; 2283PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL;
2283PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB; 2284PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL;
2284PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB; 2285PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL;
2285PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB; 2286PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB = NULL;
2286PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; 2287PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB = NULL;
2287PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; 2288PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB = NULL;
2288PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; 2289PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB = NULL;
2289PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; 2290PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL;
2290PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; 2291PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL;
2291PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; 2292PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL;
2292PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; 2293PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL;
2293PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; 2294PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL;
2294PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; 2295PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL;
2295PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; 2296PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL;
2296PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; 2297PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL;
2297PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; 2298PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL;
2298PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; 2299PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL;
2299PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; 2300PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL;
2300PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; 2301PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL;
2301PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; 2302PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL;
2302PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; 2303PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL;
2303PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; 2304PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL;
2304PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; 2305PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL;
2305PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; 2306PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL;
2306PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; 2307PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL;
2307PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; 2308PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL;
2308PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; 2309PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL;
2309PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; 2310PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL;
2310PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; 2311PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL;
2311PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; 2312PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL;
2312PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; 2313PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL;
2313PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; 2314PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL;
2314PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; 2315PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL;
2315PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; 2316PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL;
2316PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; 2317PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL;
2317PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; 2318PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL;
2318PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; 2319PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL;
2319PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; 2320PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL;
2320PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; 2321PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL;
2321PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; 2322PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL;
2322PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; 2323PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL;
2323PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; 2324PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL;
2324PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; 2325PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL;
2325PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; 2326PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL;
2326PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; 2327PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL;
2327PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; 2328PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL;
2328PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; 2329PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL;
2329PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; 2330PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL;
2330PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; 2331PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL;
2331PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; 2332PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL;
2332PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; 2333PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL;
2333PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; 2334PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL;
2334PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; 2335PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL;
2335PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; 2336PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL;
2336PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; 2337PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL;
2337PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; 2338PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL;
2338PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; 2339PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL;
2339PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; 2340PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL;
2340PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; 2341PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL;
2341PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; 2342PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL;
2342PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; 2343PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL;
2343PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; 2344PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL;
2344PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; 2345PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL;
2345PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; 2346PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL;
2346PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; 2347PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL;
2347PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; 2348PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL;
2348PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; 2349PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL;
2349PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB; 2350PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL;
2350PFNGLGETHANDLEARBPROC glad_glGetHandleARB; 2351PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL;
2351PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB; 2352PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL;
2352PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB; 2353PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB = NULL;
2353PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB; 2354PFNGLGETHANDLEARBPROC glad_glGetHandleARB = NULL;
2354PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB; 2355PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB = NULL;
2355PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB; 2356PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB = NULL;
2356PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB; 2357PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB = NULL;
2357PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB; 2358PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB = NULL;
2358PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB; 2359PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB = NULL;
2359PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB; 2360PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB = NULL;
2360PFNGLUNIFORM1FARBPROC glad_glUniform1fARB; 2361PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB = NULL;
2361PFNGLUNIFORM2FARBPROC glad_glUniform2fARB; 2362PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB = NULL;
2362PFNGLUNIFORM3FARBPROC glad_glUniform3fARB; 2363PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB = NULL;
2363PFNGLUNIFORM4FARBPROC glad_glUniform4fARB; 2364PFNGLUNIFORM1FARBPROC glad_glUniform1fARB = NULL;
2364PFNGLUNIFORM1IARBPROC glad_glUniform1iARB; 2365PFNGLUNIFORM2FARBPROC glad_glUniform2fARB = NULL;
2365PFNGLUNIFORM2IARBPROC glad_glUniform2iARB; 2366PFNGLUNIFORM3FARBPROC glad_glUniform3fARB = NULL;
2366PFNGLUNIFORM3IARBPROC glad_glUniform3iARB; 2367PFNGLUNIFORM4FARBPROC glad_glUniform4fARB = NULL;
2367PFNGLUNIFORM4IARBPROC glad_glUniform4iARB; 2368PFNGLUNIFORM1IARBPROC glad_glUniform1iARB = NULL;
2368PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB; 2369PFNGLUNIFORM2IARBPROC glad_glUniform2iARB = NULL;
2369PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB; 2370PFNGLUNIFORM3IARBPROC glad_glUniform3iARB = NULL;
2370PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB; 2371PFNGLUNIFORM4IARBPROC glad_glUniform4iARB = NULL;
2371PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB; 2372PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB = NULL;
2372PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB; 2373PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB = NULL;
2373PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB; 2374PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB = NULL;
2374PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB; 2375PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB = NULL;
2375PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB; 2376PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB = NULL;
2376PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB; 2377PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB = NULL;
2377PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB; 2378PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB = NULL;
2378PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB; 2379PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB = NULL;
2379PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB; 2380PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB = NULL;
2380PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB; 2381PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB = NULL;
2381PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB; 2382PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB = NULL;
2382PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB; 2383PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB = NULL;
2383PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB; 2384PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB = NULL;
2384PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB; 2385PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB = NULL;
2385PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB; 2386PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB = NULL;
2386PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB; 2387PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB = NULL;
2387PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB; 2388PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB = NULL;
2388PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; 2389PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB = NULL;
2389PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; 2390PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB = NULL;
2390PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; 2391PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB = NULL;
2391PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; 2392PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL;
2392PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; 2393PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL;
2393PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; 2394PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL;
2394PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; 2395PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL;
2395PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; 2396PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL;
2396PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; 2397PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL;
2397PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB; 2398PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL;
2398PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB; 2399PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL;
2399PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB; 2400PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL;
2400PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB; 2401PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB = NULL;
2401PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB; 2402PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB = NULL;
2402PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB; 2403PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB = NULL;
2403PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB; 2404PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB = NULL;
2404PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT; 2405PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB = NULL;
2405PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB; 2406PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB = NULL;
2406PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB; 2407PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB = NULL;
2407PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; 2408PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT = NULL;
2408PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; 2409PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB = NULL;
2409PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; 2410PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB = NULL;
2410PFNGLTEXBUFFERARBPROC glad_glTexBufferARB; 2411PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL;
2411PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; 2412PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL;
2412PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB; 2413PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL;
2413PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB; 2414PFNGLTEXBUFFERARBPROC glad_glTexBufferARB = NULL;
2414PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB; 2415PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL;
2415PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB; 2416PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB = NULL;
2416PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB; 2417PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB = NULL;
2417PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB; 2418PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB = NULL;
2418PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB; 2419PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB = NULL;
2419PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; 2420PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB = NULL;
2420PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; 2421PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB = NULL;
2421PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; 2422PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB = NULL;
2422PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; 2423PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL;
2423PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; 2424PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
2424PFNGLTEXTUREVIEWPROC glad_glTextureView; 2425PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
2425PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; 2426PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL;
2426PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; 2427PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL;
2427PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; 2428PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL;
2428PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; 2429PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
2429PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; 2430PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
2430PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; 2431PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
2431PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; 2432PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL;
2432PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; 2433PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL;
2433PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; 2434PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
2434PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; 2435PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
2435PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; 2436PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL;
2436PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; 2437PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL;
2437PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; 2438PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL;
2438PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB; 2439PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL;
2439PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB; 2440PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL;
2440PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB; 2441PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL;
2441PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB; 2442PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB = NULL;
2442PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; 2443PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB = NULL;
2443PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; 2444PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB = NULL;
2444PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; 2445PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB = NULL;
2445PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; 2446PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL;
2446PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; 2447PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL;
2447PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; 2448PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL;
2448PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; 2449PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL;
2449PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; 2450PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL;
2450PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; 2451PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL;
2451PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; 2452PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL;
2452PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; 2453PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL;
2453PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; 2454PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL;
2454PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; 2455PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL;
2455PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; 2456PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL;
2456PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; 2457PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL;
2457PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; 2458PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL;
2458PFNGLWEIGHTBVARBPROC glad_glWeightbvARB; 2459PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL;
2459PFNGLWEIGHTSVARBPROC glad_glWeightsvARB; 2460PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL;
2460PFNGLWEIGHTIVARBPROC glad_glWeightivARB; 2461PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL;
2461PFNGLWEIGHTFVARBPROC glad_glWeightfvARB; 2462PFNGLWEIGHTBVARBPROC glad_glWeightbvARB = NULL;
2462PFNGLWEIGHTDVARBPROC glad_glWeightdvARB; 2463PFNGLWEIGHTSVARBPROC glad_glWeightsvARB = NULL;
2463PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB; 2464PFNGLWEIGHTIVARBPROC glad_glWeightivARB = NULL;
2464PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB; 2465PFNGLWEIGHTFVARBPROC glad_glWeightfvARB = NULL;
2465PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB; 2466PFNGLWEIGHTDVARBPROC glad_glWeightdvARB = NULL;
2466PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB; 2467PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB = NULL;
2467PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB; 2468PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB = NULL;
2468PFNGLBINDBUFFERARBPROC glad_glBindBufferARB; 2469PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB = NULL;
2469PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB; 2470PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB = NULL;
2470PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB; 2471PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB = NULL;
2471PFNGLISBUFFERARBPROC glad_glIsBufferARB; 2472PFNGLBINDBUFFERARBPROC glad_glBindBufferARB = NULL;
2472PFNGLBUFFERDATAARBPROC glad_glBufferDataARB; 2473PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB = NULL;
2473PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB; 2474PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB = NULL;
2474PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB; 2475PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL;
2475PFNGLMAPBUFFERARBPROC glad_glMapBufferARB; 2476PFNGLBUFFERDATAARBPROC glad_glBufferDataARB = NULL;
2476PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB; 2477PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB = NULL;
2477PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB; 2478PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB = NULL;
2478PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB; 2479PFNGLMAPBUFFERARBPROC glad_glMapBufferARB = NULL;
2479PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB; 2480PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB = NULL;
2480PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB; 2481PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB = NULL;
2481PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB; 2482PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB = NULL;
2482PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB; 2483PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB = NULL;
2483PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB; 2484PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB = NULL;
2484PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB; 2485PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB = NULL;
2485PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB; 2486PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB = NULL;
2486PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB; 2487PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB = NULL;
2487PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB; 2488PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB = NULL;
2488PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB; 2489PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB = NULL;
2489PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB; 2490PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB = NULL;
2490PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB; 2491PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB = NULL;
2491PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB; 2492PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB = NULL;
2492PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB; 2493PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB = NULL;
2493PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB; 2494PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB = NULL;
2494PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB; 2495PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB = NULL;
2495PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB; 2496PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB = NULL;
2496PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB; 2497PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB = NULL;
2497PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB; 2498PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB = NULL;
2498PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB; 2499PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB = NULL;
2499PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB; 2500PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB = NULL;
2500PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB; 2501PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB = NULL;
2501PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB; 2502PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB = NULL;
2502PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB; 2503PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB = NULL;
2503PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB; 2504PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB = NULL;
2504PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB; 2505PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB = NULL;
2505PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB; 2506PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB = NULL;
2506PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB; 2507PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB = NULL;
2507PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB; 2508PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB = NULL;
2508PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB; 2509PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB = NULL;
2509PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB; 2510PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB = NULL;
2510PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB; 2511PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB = NULL;
2511PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB; 2512PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB = NULL;
2512PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB; 2513PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB = NULL;
2513PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB; 2514PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB = NULL;
2514PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB; 2515PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB = NULL;
2515PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB; 2516PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB = NULL;
2516PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB; 2517PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB = NULL;
2517PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB; 2518PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB = NULL;
2518PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB; 2519PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB = NULL;
2519PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB; 2520PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB = NULL;
2520PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB; 2521PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB = NULL;
2521PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB; 2522PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB = NULL;
2522PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB; 2523PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB = NULL;
2523PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB; 2524PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB = NULL;
2524PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB; 2525PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB = NULL;
2525PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; 2526PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB = NULL;
2526PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; 2527PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB = NULL;
2527PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; 2528PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB = NULL;
2528PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; 2529PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
2529PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; 2530PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
2530PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; 2531PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
2531PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; 2532PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL;
2532PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; 2533PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL;
2533PFNGLGETFLOATI_VPROC glad_glGetFloati_v; 2534PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL;
2534PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; 2535PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
2535PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB; 2536PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
2536PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB; 2537PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL;
2537PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB; 2538PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL;
2538PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB; 2539PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB = NULL;
2539PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB; 2540PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB = NULL;
2540PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB; 2541PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB = NULL;
2541PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB; 2542PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB = NULL;
2542PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB; 2543PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB = NULL;
2543PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB; 2544PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB = NULL;
2544PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB; 2545PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB = NULL;
2545PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB; 2546PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB = NULL;
2546PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB; 2547PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB = NULL;
2547PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB; 2548PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB = NULL;
2548PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB; 2549PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB = NULL;
2549PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB; 2550PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB = NULL;
2550PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB; 2551PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB = NULL;
2551PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI; 2552PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB = NULL;
2552PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI; 2553PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB = NULL;
2553PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI; 2554PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB = NULL;
2554PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI; 2555PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI = NULL;
2555PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI; 2556PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI = NULL;
2556PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI; 2557PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI = NULL;
2557PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI; 2558PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI = NULL;
2558PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI; 2559PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI = NULL;
2559PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI; 2560PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI = NULL;
2560PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI; 2561PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI = NULL;
2561PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI; 2562PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI = NULL;
2562PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI; 2563PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI = NULL;
2563PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI; 2564PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI = NULL;
2564PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI; 2565PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI = NULL;
2565PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI; 2566PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI = NULL;
2566PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI; 2567PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI = NULL;
2567PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI; 2568PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI = NULL;
2568PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI; 2569PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI = NULL;
2569PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI; 2570PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI = NULL;
2570PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI; 2571PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI = NULL;
2571PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI; 2572PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI = NULL;
2572PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI; 2573PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI = NULL;
2573PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI; 2574PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI = NULL;
2574PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI; 2575PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI = NULL;
2575PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI; 2576PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI = NULL;
2576PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI; 2577PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI = NULL;
2577PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI; 2578PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI = NULL;
2578PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI; 2579PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI = NULL;
2579PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI; 2580PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI = NULL;
2580PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI; 2581PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI = NULL;
2581PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI; 2582PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI = NULL;
2582PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI; 2583PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI = NULL;
2583PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI; 2584PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI = NULL;
2584PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI; 2585PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI = NULL;
2585PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI; 2586PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI = NULL;
2586PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI; 2587PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI = NULL;
2587PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI; 2588PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI = NULL;
2588PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI; 2589PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI = NULL;
2589PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI; 2590PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI = NULL;
2590PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI; 2591PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI = NULL;
2591PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI; 2592PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI = NULL;
2592PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI; 2593PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI = NULL;
2593PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI; 2594PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI = NULL;
2594PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI; 2595PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI = NULL;
2595PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI; 2596PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI = NULL;
2596PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI; 2597PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI = NULL;
2597PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI; 2598PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI = NULL;
2598PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI; 2599PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI = NULL;
2599PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI; 2600PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI = NULL;
2600PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI; 2601PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI = NULL;
2601PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI; 2602PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI = NULL;
2602PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI; 2603PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI = NULL;
2603PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI; 2604PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI = NULL;
2604PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI; 2605PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI = NULL;
2605PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI; 2606PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI = NULL;
2606PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI; 2607PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI = NULL;
2607PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI; 2608PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI = NULL;
2608PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI; 2609PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI = NULL;
2609PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI; 2610PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI = NULL;
2610PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI; 2611PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI = NULL;
2611PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI; 2612PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI = NULL;
2612PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI; 2613PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI = NULL;
2613PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI; 2614PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI = NULL;
2614PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI; 2615PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI = NULL;
2615PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI; 2616PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI = NULL;
2616PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI; 2617PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI = NULL;
2617PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI; 2618PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI = NULL;
2618PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI; 2619PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI = NULL;
2619PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI; 2620PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI = NULL;
2620PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI; 2621PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI = NULL;
2621PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI; 2622PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI = NULL;
2622PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI; 2623PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI = NULL;
2623PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI; 2624PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI = NULL;
2624PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI; 2625PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI = NULL;
2625PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI; 2626PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI = NULL;
2626PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI; 2627PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI = NULL;
2627PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI; 2628PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI = NULL;
2628PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI; 2629PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI = NULL;
2629PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI; 2630PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI = NULL;
2630PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI; 2631PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI = NULL;
2631PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI; 2632PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI = NULL;
2632PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI; 2633PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI = NULL;
2633PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI; 2634PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI = NULL;
2634PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI; 2635PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI = NULL;
2635PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI; 2636PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI = NULL;
2636PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI; 2637PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI = NULL;
2637PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI; 2638PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI = NULL;
2638PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI; 2639PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI = NULL;
2639PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT; 2640PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI = NULL;
2640PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT; 2641PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI = NULL;
2641PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT; 2642PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI = NULL;
2642PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT; 2643PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT = NULL;
2643PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT; 2644PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT = NULL;
2644PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT; 2645PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT = NULL;
2645PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT; 2646PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT = NULL;
2646PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT; 2647PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT = NULL;
2647PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT; 2648PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT = NULL;
2648PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT; 2649PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT = NULL;
2649PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT; 2650PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT = NULL;
2650PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT; 2651PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT = NULL;
2651PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT; 2652PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT = NULL;
2652PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT; 2653PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT = NULL;
2653PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT; 2654PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT = NULL;
2654PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT; 2655PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT = NULL;
2655PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT; 2656PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT = NULL;
2656PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT; 2657PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT = NULL;
2657PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT; 2658PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT = NULL;
2658PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT; 2659PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT = NULL;
2659PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT; 2660PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT = NULL;
2660PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT; 2661PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT = NULL;
2661PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT; 2662PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT = NULL;
2662PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT; 2663PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT = NULL;
2663PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT; 2664PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT = NULL;
2664PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT; 2665PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT = NULL;
2665PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT; 2666PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT = NULL;
2666PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT; 2667PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT = NULL;
2667PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT; 2668PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT = NULL;
2668PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT; 2669PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT = NULL;
2669PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT; 2670PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT = NULL;
2670PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT; 2671PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT = NULL;
2671PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT; 2672PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT = NULL;
2672PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT; 2673PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT = NULL;
2673PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT; 2674PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT = NULL;
2674PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT; 2675PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT = NULL;
2675PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT; 2676PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT = NULL;
2676PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT; 2677PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT = NULL;
2677PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT; 2678PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT = NULL;
2678PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT; 2679PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT = NULL;
2679PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT; 2680PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT = NULL;
2680PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT; 2681PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT = NULL;
2681PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT; 2682PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT = NULL;
2682PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT; 2683PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT = NULL;
2683PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT; 2684PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT = NULL;
2684PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT; 2685PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT = NULL;
2685PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT; 2686PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT = NULL;
2686PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT; 2687PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT = NULL;
2687PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT; 2688PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT = NULL;
2688PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT; 2689PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT = NULL;
2689PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT; 2690PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT = NULL;
2690PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT; 2691PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT = NULL;
2691PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT; 2692PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT = NULL;
2692PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT; 2693PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT = NULL;
2693PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT; 2694PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT = NULL;
2694PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT; 2695PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT = NULL;
2695PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT; 2696PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT = NULL;
2696PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT; 2697PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT = NULL;
2697PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT; 2698PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT = NULL;
2698PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT; 2699PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT = NULL;
2699PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT; 2700PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT = NULL;
2700PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT; 2701PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT = NULL;
2701PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT; 2702PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT = NULL;
2702PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT; 2703PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT = NULL;
2703PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT; 2704PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT = NULL;
2704PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT; 2705PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT = NULL;
2705PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT; 2706PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT = NULL;
2706PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT; 2707PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT = NULL;
2707PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT; 2708PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT = NULL;
2708PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT; 2709PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT = NULL;
2709PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT; 2710PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT = NULL;
2710PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT; 2711PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT = NULL;
2711PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT; 2712PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT = NULL;
2712PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT; 2713PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT = NULL;
2713PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT; 2714PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT = NULL;
2714PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT; 2715PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT = NULL;
2715PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT; 2716PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT = NULL;
2716PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT; 2717PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT = NULL;
2717PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT; 2718PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT = NULL;
2718PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT; 2719PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT = NULL;
2719PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT; 2720PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT = NULL;
2720PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT; 2721PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT = NULL;
2721PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT; 2722PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT = NULL;
2722PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT; 2723PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT = NULL;
2723PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT; 2724PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT = NULL;
2724PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT; 2725PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT = NULL;
2725PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT; 2726PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT = NULL;
2726PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT; 2727PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT = NULL;
2727PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT; 2728PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT = NULL;
2728PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT; 2729PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT = NULL;
2729PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT; 2730PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT = NULL;
2730PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT; 2731PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT = NULL;
2731PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT; 2732PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT = NULL;
2732PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT; 2733PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT = NULL;
2733PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT; 2734PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT = NULL;
2734PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT; 2735PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT = NULL;
2735PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT; 2736PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT = NULL;
2736PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT; 2737PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT = NULL;
2737PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT; 2738PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT = NULL;
2738PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT; 2739PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT = NULL;
2739PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT; 2740PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT = NULL;
2740PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT; 2741PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT = NULL;
2741PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT; 2742PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT = NULL;
2742PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT; 2743PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT = NULL;
2743PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT; 2744PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT = NULL;
2744PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT; 2745PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT = NULL;
2745PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT; 2746PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT = NULL;
2746PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT; 2747PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT = NULL;
2747PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT; 2748PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT = NULL;
2748PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT; 2749PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT = NULL;
2749PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT; 2750PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT = NULL;
2750PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT; 2751PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT = NULL;
2751PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT; 2752PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT = NULL;
2752PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT; 2753PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT = NULL;
2753PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT; 2754PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT = NULL;
2754PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT; 2755PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT = NULL;
2755PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT; 2756PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT = NULL;
2756PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT; 2757PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT = NULL;
2757PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT; 2758PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT = NULL;
2758PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT; 2759PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT = NULL;
2759PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT; 2760PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT = NULL;
2760PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT; 2761PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT = NULL;
2761PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT; 2762PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT = NULL;
2762PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT; 2763PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT = NULL;
2763PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT; 2764PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT = NULL;
2764PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT; 2765PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT = NULL;
2765PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT; 2766PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT = NULL;
2766PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT; 2767PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT = NULL;
2767PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT; 2768PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT = NULL;
2768PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT; 2769PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT = NULL;
2769PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT; 2770PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT = NULL;
2770PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT; 2771PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT = NULL;
2771PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT; 2772PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT = NULL;
2772PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT; 2773PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT = NULL;
2773PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT; 2774PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT = NULL;
2774PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT; 2775PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT = NULL;
2775PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT; 2776PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT = NULL;
2776PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT; 2777PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT = NULL;
2777PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT; 2778PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT = NULL;
2778PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT; 2779PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT = NULL;
2779PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT; 2780PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT = NULL;
2780PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT; 2781PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT = NULL;
2781PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT; 2782PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT = NULL;
2782PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT; 2783PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT = NULL;
2783PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT; 2784PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT = NULL;
2784PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT; 2785PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT = NULL;
2785PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT; 2786PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT = NULL;
2786PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT; 2787PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT = NULL;
2787PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT; 2788PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT = NULL;
2788PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT; 2789PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT = NULL;
2789PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT; 2790PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT = NULL;
2790PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT; 2791PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT = NULL;
2791PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT; 2792PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT = NULL;
2792PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT; 2793PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT = NULL;
2793PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT; 2794PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT = NULL;
2794PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT; 2795PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT = NULL;
2795PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT; 2796PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT = NULL;
2796PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT; 2797PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT = NULL;
2797PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT; 2798PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT = NULL;
2798PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT; 2799PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT = NULL;
2799PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT; 2800PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT = NULL;
2800PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT; 2801PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT = NULL;
2801PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT; 2802PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT = NULL;
2802PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT; 2803PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT = NULL;
2803PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT; 2804PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT = NULL;
2804PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT; 2805PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT = NULL;
2805PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT; 2806PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT = NULL;
2806PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT; 2807PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT = NULL;
2807PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT; 2808PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT = NULL;
2808PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT; 2809PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT = NULL;
2809PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT; 2810PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT = NULL;
2810PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT; 2811PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT = NULL;
2811PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT; 2812PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT = NULL;
2812PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT; 2813PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT = NULL;
2813PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT; 2814PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT = NULL;
2814PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT; 2815PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT = NULL;
2815PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT; 2816PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT = NULL;
2816PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT; 2817PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT = NULL;
2817PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT; 2818PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT = NULL;
2818PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT; 2819PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT = NULL;
2819PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT; 2820PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT = NULL;
2820PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT; 2821PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT = NULL;
2821PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT; 2822PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT = NULL;
2822PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT; 2823PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT = NULL;
2823PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT; 2824PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT = NULL;
2824PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT; 2825PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT = NULL;
2825PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT; 2826PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT = NULL;
2826PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT; 2827PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT = NULL;
2827PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT; 2828PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT = NULL;
2828PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT; 2829PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT = NULL;
2829PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT; 2830PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT = NULL;
2830PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT; 2831PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT = NULL;
2831PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT; 2832PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT = NULL;
2832PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT; 2833PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT = NULL;
2833PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT; 2834PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT = NULL;
2834PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT; 2835PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT = NULL;
2835PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT; 2836PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT = NULL;
2836PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT; 2837PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT = NULL;
2837PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT; 2838PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT = NULL;
2838PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT; 2839PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT = NULL;
2839PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT; 2840PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT = NULL;
2840PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT; 2841PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT = NULL;
2841PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT; 2842PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT = NULL;
2842PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT; 2843PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT = NULL;
2843PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT; 2844PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT = NULL;
2844PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT; 2845PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT = NULL;
2845PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT; 2846PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT = NULL;
2846PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT; 2847PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT = NULL;
2847PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT; 2848PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT = NULL;
2848PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT; 2849PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT = NULL;
2849PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT; 2850PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT = NULL;
2850PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT; 2851PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT = NULL;
2851PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT; 2852PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT = NULL;
2852PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT; 2853PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT = NULL;
2853PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT; 2854PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT = NULL;
2854PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT; 2855PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT = NULL;
2855PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT; 2856PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT = NULL;
2856PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT; 2857PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT = NULL;
2857PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT; 2858PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT = NULL;
2858PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT; 2859PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT = NULL;
2859PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT; 2860PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT = NULL;
2860PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT; 2861PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT = NULL;
2861PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT; 2862PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT = NULL;
2862PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT; 2863PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT = NULL;
2863PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT; 2864PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT = NULL;
2864PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT; 2865PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT = NULL;
2865PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT; 2866PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT = NULL;
2866PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT; 2867PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT = NULL;
2867PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT; 2868PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT = NULL;
2868PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT; 2869PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT = NULL;
2869PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT; 2870PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT = NULL;
2870PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT; 2871PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT = NULL;
2871PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT; 2872PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT = NULL;
2872PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT; 2873PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT = NULL;
2873PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT; 2874PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT = NULL;
2874PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT; 2875PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT = NULL;
2875PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT; 2876PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT = NULL;
2876PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT; 2877PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT = NULL;
2877PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT; 2878PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT = NULL;
2878PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT; 2879PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT = NULL;
2879PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT; 2880PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT = NULL;
2880PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT; 2881PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT = NULL;
2881PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT; 2882PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT = NULL;
2882PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT; 2883PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT = NULL;
2883PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT; 2884PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT = NULL;
2884PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT; 2885PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT = NULL;
2885PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT; 2886PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT = NULL;
2886PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT; 2887PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT = NULL;
2887PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT; 2888PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT = NULL;
2888PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT; 2889PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT = NULL;
2889PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT; 2890PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT = NULL;
2890PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT; 2891PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT = NULL;
2891PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT; 2892PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT = NULL;
2892PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT; 2893PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT = NULL;
2893PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT; 2894PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT = NULL;
2894PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT; 2895PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT = NULL;
2895PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT; 2896PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT = NULL;
2896PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT; 2897PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT = NULL;
2897PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT; 2898PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT = NULL;
2898PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT; 2899PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT = NULL;
2899PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT; 2900PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT = NULL;
2900PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT; 2901PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT = NULL;
2901PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT; 2902PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT = NULL;
2902PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT; 2903PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT = NULL;
2903PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT; 2904PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT = NULL;
2904PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT; 2905PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT = NULL;
2905PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT; 2906PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT = NULL;
2906PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT; 2907PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT = NULL;
2907PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT; 2908PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT = NULL;
2908PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT; 2909PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT = NULL;
2909PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT; 2910PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT = NULL;
2910PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT; 2911PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT = NULL;
2911PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT; 2912PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT = NULL;
2912PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT; 2913PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT = NULL;
2913PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT; 2914PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT = NULL;
2914PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT; 2915PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT = NULL;
2915PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT; 2916PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT = NULL;
2916PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT; 2917PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT = NULL;
2917PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT; 2918PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT = NULL;
2918PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT; 2919PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT = NULL;
2919PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT; 2920PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT = NULL;
2920PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT; 2921PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT = NULL;
2921PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT; 2922PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT = NULL;
2922PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT; 2923PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT = NULL;
2923PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT; 2924PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT = NULL;
2924PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT; 2925PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT = NULL;
2925PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT; 2926PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT = NULL;
2926PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT; 2927PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT = NULL;
2927PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT; 2928PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT = NULL;
2928PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT; 2929PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT = NULL;
2929PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT; 2930PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT = NULL;
2930PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT; 2931PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT = NULL;
2931PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT; 2932PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT = NULL;
2932PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT; 2933PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT = NULL;
2933PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT; 2934PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT = NULL;
2934PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT; 2935PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT = NULL;
2935PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT; 2936PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT = NULL;
2936PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT; 2937PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT = NULL;
2937PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT; 2938PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT = NULL;
2938PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT; 2939PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT = NULL;
2939PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT; 2940PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT = NULL;
2940PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT; 2941PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT = NULL;
2941PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT; 2942PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT = NULL;
2942PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT; 2943PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT = NULL;
2943PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT; 2944PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT = NULL;
2944PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT; 2945PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL;
2945PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT; 2946PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL;
2946PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT; 2947PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL;
2947PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT; 2948PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT = NULL;
2948PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT; 2949PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT = NULL;
2949PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT; 2950PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT = NULL;
2950PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT; 2951PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT = NULL;
2951PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT; 2952PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT = NULL;
2952PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT; 2953PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT = NULL;
2953PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT; 2954PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT = NULL;
2954PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT; 2955PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT = NULL;
2955PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT; 2956PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT = NULL;
2956PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT; 2957PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT = NULL;
2957PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT; 2958PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT = NULL;
2958PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT; 2959PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT = NULL;
2959PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT; 2960PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL;
2960PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT; 2961PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL;
2961PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT; 2962PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT = NULL;
2962PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT; 2963PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT = NULL;
2963PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT; 2964PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT = NULL;
2964PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT; 2965PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT = NULL;
2965PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT; 2966PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT = NULL;
2966PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; 2967PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT = NULL;
2967PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; 2968PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT = NULL;
2968PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; 2969PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT = NULL;
2969PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; 2970PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL;
2970PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; 2971PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL;
2971PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; 2972PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL;
2972PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; 2973PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL;
2973PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; 2974PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL;
2974PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; 2975PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL;
2975PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; 2976PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL;
2976PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; 2977PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL;
2977PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; 2978PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL;
2978PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; 2979PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL;
2979PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; 2980PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL;
2980PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; 2981PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL;
2981PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; 2982PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL;
2982PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; 2983PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL;
2983PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; 2984PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL;
2984PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; 2985PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL;
2985PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT; 2986PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL;
2986PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT; 2987PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL;
2987PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT; 2988PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL;
2988PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT; 2989PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT = NULL;
2989PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT; 2990PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT = NULL;
2990PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT; 2991PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT = NULL;
2991PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT; 2992PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT = NULL;
2992PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT; 2993PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT = NULL;
2993PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT; 2994PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT = NULL;
2994PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT; 2995PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT = NULL;
2995PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT; 2996PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT = NULL;
2996PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT; 2997PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT = NULL;
2997PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT; 2998PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT = NULL;
2998PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT; 2999PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT = NULL;
2999PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT; 3000PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT = NULL;
3000PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT; 3001PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT = NULL;
3001PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT; 3002PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT = NULL;
3002PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT; 3003PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT = NULL;
3003PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT; 3004PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT = NULL;
3004PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT; 3005PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT = NULL;
3005PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT; 3006PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT = NULL;
3006PFNGLMINMAXEXTPROC glad_glMinmaxEXT; 3007PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT = NULL;
3007PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT; 3008PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT = NULL;
3008PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT; 3009PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT = NULL;
3009PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT; 3010PFNGLMINMAXEXTPROC glad_glMinmaxEXT = NULL;
3010PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT; 3011PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT = NULL;
3011PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT; 3012PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT = NULL;
3012PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT; 3013PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT = NULL;
3013PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT; 3014PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT = NULL;
3014PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT; 3015PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT = NULL;
3015PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT; 3016PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT = NULL;
3016PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT; 3017PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT = NULL;
3017PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT; 3018PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL;
3018PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT; 3019PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL;
3019PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT; 3020PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL;
3020PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT; 3021PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL;
3021PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT; 3022PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL;
3022PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT; 3023PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL;
3023PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT; 3024PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL;
3024PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT; 3025PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL;
3025PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT; 3026PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL;
3026PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT; 3027PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL;
3027PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT; 3028PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL;
3028PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT; 3029PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL;
3029PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT; 3030PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL;
3030PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT; 3031PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL;
3031PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT; 3032PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL;
3032PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT; 3033PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL;
3033PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT; 3034PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL;
3034PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT; 3035PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL;
3035PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT; 3036PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL;
3036PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT; 3037PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL;
3037PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT; 3038PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT = NULL;
3038PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT; 3039PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT = NULL;
3039PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT; 3040PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT = NULL;
3040PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT; 3041PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT = NULL;
3041PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT; 3042PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT = NULL;
3042PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT; 3043PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT = NULL;
3043PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT; 3044PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT = NULL;
3044PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT; 3045PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT = NULL;
3045PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT; 3046PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT = NULL;
3046PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT; 3047PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT = NULL;
3047PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT; 3048PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT = NULL;
3048PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT; 3049PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT = NULL;
3049PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT; 3050PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT = NULL;
3050PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT; 3051PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT = NULL;
3051PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT; 3052PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT = NULL;
3052PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT; 3053PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT = NULL;
3053PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT; 3054PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT = NULL;
3054PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT; 3055PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT = NULL;
3055PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT; 3056PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT = NULL;
3056PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT; 3057PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT = NULL;
3057PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT; 3058PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT = NULL;
3058PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT; 3059PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT = NULL;
3059PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT; 3060PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT = NULL;
3060PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT; 3061PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT = NULL;
3061PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT; 3062PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT = NULL;
3062PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT; 3063PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT = NULL;
3063PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT; 3064PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT = NULL;
3064PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT; 3065PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT = NULL;
3065PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT; 3066PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT = NULL;
3066PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT; 3067PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT = NULL;
3067PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT; 3068PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT = NULL;
3068PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT; 3069PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT = NULL;
3069PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT; 3070PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT = NULL;
3070PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT; 3071PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT = NULL;
3071PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT; 3072PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT = NULL;
3072PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT; 3073PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT = NULL;
3073PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT; 3074PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT = NULL;
3074PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT; 3075PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT = NULL;
3075PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT; 3076PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT = NULL;
3076PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT; 3077PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT = NULL;
3077PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT; 3078PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT = NULL;
3078PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT; 3079PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT = NULL;
3079PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT; 3080PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT = NULL;
3080PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT; 3081PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT = NULL;
3081PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT; 3082PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT = NULL;
3082PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT; 3083PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT = NULL;
3083PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT; 3084PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT = NULL;
3084PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT; 3085PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT = NULL;
3085PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT; 3086PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT = NULL;
3086PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT; 3087PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT = NULL;
3087PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT; 3088PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT = NULL;
3088PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT; 3089PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT = NULL;
3089PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT; 3090PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT = NULL;
3090PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT; 3091PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT = NULL;
3091PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT; 3092PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT = NULL;
3092PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT; 3093PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT = NULL;
3093PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT; 3094PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT = NULL;
3094PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT; 3095PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT = NULL;
3095PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT; 3096PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT = NULL;
3096PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT; 3097PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT = NULL;
3097PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT; 3098PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT = NULL;
3098PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT; 3099PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT = NULL;
3099PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT; 3100PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT = NULL;
3100PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT; 3101PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT = NULL;
3101PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT; 3102PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT = NULL;
3102PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT; 3103PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT = NULL;
3103PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT; 3104PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT = NULL;
3104PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT; 3105PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT = NULL;
3105PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT; 3106PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT = NULL;
3106PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT; 3107PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT = NULL;
3107PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT; 3108PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT = NULL;
3108PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT; 3109PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT = NULL;
3109PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT; 3110PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT = NULL;
3110PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT; 3111PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT = NULL;
3111PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT; 3112PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT = NULL;
3112PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT; 3113PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT = NULL;
3113PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT; 3114PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT = NULL;
3114PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT; 3115PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT = NULL;
3115PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT; 3116PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT = NULL;
3116PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT; 3117PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT = NULL;
3117PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT; 3118PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT = NULL;
3118PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT; 3119PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT = NULL;
3119PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT; 3120PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT = NULL;
3120PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT; 3121PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT = NULL;
3121PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT; 3122PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT = NULL;
3122PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT; 3123PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT = NULL;
3123PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT; 3124PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT = NULL;
3124PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT; 3125PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT = NULL;
3125PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT; 3126PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT = NULL;
3126PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT; 3127PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT = NULL;
3127PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT; 3128PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT = NULL;
3128PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT; 3129PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT = NULL;
3129PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT; 3130PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT = NULL;
3130PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT; 3131PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT = NULL;
3131PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT; 3132PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT = NULL;
3132PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT; 3133PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT = NULL;
3133PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT; 3134PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT = NULL;
3134PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT; 3135PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT = NULL;
3135PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT; 3136PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT = NULL;
3136PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT; 3137PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT = NULL;
3137PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT; 3138PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT = NULL;
3138PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT; 3139PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT = NULL;
3139PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT; 3140PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT = NULL;
3140PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT; 3141PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT = NULL;
3141PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT; 3142PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT = NULL;
3142PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT; 3143PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT = NULL;
3143PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT; 3144PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT = NULL;
3144PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT; 3145PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT = NULL;
3145PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT; 3146PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT = NULL;
3146PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT; 3147PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT = NULL;
3147PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT; 3148PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT = NULL;
3148PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT; 3149PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT = NULL;
3149PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT; 3150PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT = NULL;
3150PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT; 3151PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT = NULL;
3151PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT; 3152PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT = NULL;
3152PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT; 3153PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT = NULL;
3153PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT; 3154PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT = NULL;
3154PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT; 3155PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT = NULL;
3155PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT; 3156PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT = NULL;
3156PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT; 3157PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT = NULL;
3157PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT; 3158PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT = NULL;
3158PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT; 3159PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT = NULL;
3159PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT; 3160PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT = NULL;
3160PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT; 3161PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT = NULL;
3161PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT; 3162PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT = NULL;
3162PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT; 3163PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT = NULL;
3163PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT; 3164PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT = NULL;
3164PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT; 3165PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT = NULL;
3165PFNGLVARIANTIVEXTPROC glad_glVariantivEXT; 3166PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT = NULL;
3166PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT; 3167PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT = NULL;
3167PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT; 3168PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT = NULL;
3168PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT; 3169PFNGLVARIANTIVEXTPROC glad_glVariantivEXT = NULL;
3169PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT; 3170PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT = NULL;
3170PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT; 3171PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT = NULL;
3171PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT; 3172PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT = NULL;
3172PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT; 3173PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT = NULL;
3173PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT; 3174PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT = NULL;
3174PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT; 3175PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT = NULL;
3175PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT; 3176PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT = NULL;
3176PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT; 3177PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT = NULL;
3177PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT; 3178PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT = NULL;
3178PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT; 3179PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT = NULL;
3179PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT; 3180PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT = NULL;
3180PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT; 3181PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT = NULL;
3181PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT; 3182PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT = NULL;
3182PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT; 3183PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT = NULL;
3183PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT; 3184PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT = NULL;
3184PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT; 3185PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT = NULL;
3185PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT; 3186PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT = NULL;
3186PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT; 3187PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT = NULL;
3187PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT; 3188PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT = NULL;
3188PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT; 3189PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT = NULL;
3189PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT; 3190PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT = NULL;
3190PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT; 3191PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT = NULL;
3191PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT; 3192PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT = NULL;
3192PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT; 3193PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT = NULL;
3193PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT; 3194PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT = NULL;
3194PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT; 3195PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT = NULL;
3195PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT; 3196PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT = NULL;
3196PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT; 3197PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT = NULL;
3197PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY; 3198PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT = NULL;
3198PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY; 3199PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT = NULL;
3199PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP; 3200PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT = NULL;
3200PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP; 3201PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY = NULL;
3201PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP; 3202PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY = NULL;
3202PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP; 3203PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP = NULL;
3203PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP; 3204PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP = NULL;
3204PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP; 3205PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP = NULL;
3205PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM; 3206PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP = NULL;
3206PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM; 3207PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP = NULL;
3207PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM; 3208PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP = NULL;
3208PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM; 3209PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM = NULL;
3209PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM; 3210PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM = NULL;
3210PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM; 3211PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM = NULL;
3211PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM; 3212PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM = NULL;
3212PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM; 3213PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM = NULL;
3213PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM; 3214PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM = NULL;
3214PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM; 3215PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM = NULL;
3215PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM; 3216PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM = NULL;
3216PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR; 3217PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM = NULL;
3217PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL; 3218PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM = NULL;
3218PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL; 3219PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM = NULL;
3219PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL; 3220PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR = NULL;
3220PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL; 3221PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL = NULL;
3221PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL; 3222PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL = NULL;
3222PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL; 3223PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL = NULL;
3223PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL; 3224PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL = NULL;
3224PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL; 3225PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL = NULL;
3225PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL; 3226PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL = NULL;
3226PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL; 3227PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL = NULL;
3227PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL; 3228PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL = NULL;
3228PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL; 3229PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL = NULL;
3229PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL; 3230PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL = NULL;
3230PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL; 3231PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL = NULL;
3231PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL; 3232PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL = NULL;
3232PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL; 3233PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL = NULL;
3233PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL; 3234PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL = NULL;
3234PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL; 3235PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL = NULL;
3235PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; 3236PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL = NULL;
3236PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; 3237PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL = NULL;
3237PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; 3238PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL = NULL;
3238PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; 3239PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL;
3239PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; 3240PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL;
3240PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; 3241PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL;
3241PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; 3242PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL;
3242PFNGLOBJECTLABELPROC glad_glObjectLabel; 3243PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL;
3243PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; 3244PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL;
3244PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; 3245PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL;
3245PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; 3246PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL;
3246PFNGLGETPOINTERVPROC glad_glGetPointerv; 3247PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL;
3247PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; 3248PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL;
3248PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; 3249PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL;
3249PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; 3250PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL;
3250PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; 3251PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL;
3251PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; 3252PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL;
3252PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; 3253PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL;
3253PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; 3254PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL;
3254PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; 3255PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL;
3255PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; 3256PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL;
3256PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; 3257PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL;
3257PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; 3258PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL;
3258PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR; 3259PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL;
3259PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; 3260PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL;
3260PFNGLREADNPIXELSPROC glad_glReadnPixels; 3261PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL;
3261PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; 3262PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL;
3262PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; 3263PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL;
3263PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; 3264PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL;
3264PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR; 3265PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL;
3265PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR; 3266PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL;
3266PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR; 3267PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL;
3267PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR; 3268PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR = NULL;
3268PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR; 3269PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR = NULL;
3269PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA; 3270PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR = NULL;
3270PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA; 3271PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR = NULL;
3271PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA; 3272PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR = NULL;
3272PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA; 3273PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA = NULL;
3273PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA; 3274PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA = NULL;
3274PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA; 3275PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA = NULL;
3275PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA; 3276PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA = NULL;
3276PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA; 3277PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA = NULL;
3277PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA; 3278PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA = NULL;
3278PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA; 3279PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA = NULL;
3279PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA; 3280PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA = NULL;
3280PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA; 3281PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA = NULL;
3281PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA; 3282PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA = NULL;
3282PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA; 3283PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA = NULL;
3283PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA; 3284PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA = NULL;
3284PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA; 3285PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA = NULL;
3285PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA; 3286PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA = NULL;
3286PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA; 3287PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA = NULL;
3287PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA; 3288PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA = NULL;
3288PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA; 3289PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA = NULL;
3289PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA; 3290PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA = NULL;
3290PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA; 3291PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA = NULL;
3291PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA; 3292PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA = NULL;
3292PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA; 3293PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA = NULL;
3293PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA; 3294PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA = NULL;
3294PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX; 3295PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA = NULL;
3295PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX; 3296PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA = NULL;
3296PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX; 3297PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA = NULL;
3297PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX; 3298PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX = NULL;
3298PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX; 3299PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX = NULL;
3299PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV; 3300PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX = NULL;
3300PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV; 3301PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX = NULL;
3301PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV; 3302PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX = NULL;
3302PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV; 3303PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV = NULL;
3303PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV; 3304PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV = NULL;
3304PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV; 3305PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV = NULL;
3305PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV; 3306PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV = NULL;
3306PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV; 3307PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV = NULL;
3307PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV; 3308PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV = NULL;
3308PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV; 3309PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV = NULL;
3309PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV; 3310PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV = NULL;
3310PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV; 3311PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV = NULL;
3311PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV; 3312PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV = NULL;
3312PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV; 3313PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV = NULL;
3313PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV; 3314PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV = NULL;
3314PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV; 3315PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV = NULL;
3315PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV; 3316PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV = NULL;
3316PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV; 3317PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV = NULL;
3317PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV; 3318PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV = NULL;
3318PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV; 3319PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV = NULL;
3319PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV; 3320PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV = NULL;
3320PFNGLCREATESTATESNVPROC glad_glCreateStatesNV; 3321PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV = NULL;
3321PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV; 3322PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV = NULL;
3322PFNGLISSTATENVPROC glad_glIsStateNV; 3323PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV = NULL;
3323PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV; 3324PFNGLCREATESTATESNVPROC glad_glCreateStatesNV = NULL;
3324PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV; 3325PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV = NULL;
3325PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV; 3326PFNGLISSTATENVPROC glad_glIsStateNV = NULL;
3326PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV; 3327PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV = NULL;
3327PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV; 3328PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV = NULL;
3328PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV; 3329PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV = NULL;
3329PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV; 3330PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV = NULL;
3330PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV; 3331PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV = NULL;
3331PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV; 3332PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV = NULL;
3332PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV; 3333PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV = NULL;
3333PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV; 3334PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV = NULL;
3334PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV; 3335PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV = NULL;
3335PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV; 3336PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV = NULL;
3336PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV; 3337PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV = NULL;
3337PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV; 3338PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV = NULL;
3338PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV; 3339PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV = NULL;
3339PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV; 3340PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV = NULL;
3340PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV; 3341PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV = NULL;
3341PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV; 3342PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV = NULL;
3342PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV; 3343PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV = NULL;
3343PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV; 3344PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV = NULL;
3344PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV; 3345PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV = NULL;
3345PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV; 3346PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV = NULL;
3346PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV; 3347PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV = NULL;
3347PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV; 3348PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV = NULL;
3348PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV; 3349PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV = NULL;
3349PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV; 3350PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV = NULL;
3350PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV; 3351PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV = NULL;
3351PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV; 3352PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV = NULL;
3352PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV; 3353PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV = NULL;
3353PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV; 3354PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV = NULL;
3354PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV; 3355PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV = NULL;
3355PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV; 3356PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV = NULL;
3356PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV; 3357PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV = NULL;
3357PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV; 3358PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV = NULL;
3358PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV; 3359PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV = NULL;
3359PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV; 3360PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV = NULL;
3360PFNGLEVALMAPSNVPROC glad_glEvalMapsNV; 3361PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV = NULL;
3361PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV; 3362PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV = NULL;
3362PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV; 3363PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV = NULL;
3363PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV; 3364PFNGLEVALMAPSNVPROC glad_glEvalMapsNV = NULL;
3364PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV; 3365PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV = NULL;
3365PFNGLGENFENCESNVPROC glad_glGenFencesNV; 3366PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV = NULL;
3366PFNGLISFENCENVPROC glad_glIsFenceNV; 3367PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV = NULL;
3367PFNGLTESTFENCENVPROC glad_glTestFenceNV; 3368PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV = NULL;
3368PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV; 3369PFNGLGENFENCESNVPROC glad_glGenFencesNV = NULL;
3369PFNGLFINISHFENCENVPROC glad_glFinishFenceNV; 3370PFNGLISFENCENVPROC glad_glIsFenceNV = NULL;
3370PFNGLSETFENCENVPROC glad_glSetFenceNV; 3371PFNGLTESTFENCENVPROC glad_glTestFenceNV = NULL;
3371PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV; 3372PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV = NULL;
3372PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV; 3373PFNGLFINISHFENCENVPROC glad_glFinishFenceNV = NULL;
3373PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV; 3374PFNGLSETFENCENVPROC glad_glSetFenceNV = NULL;
3374PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV; 3375PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV = NULL;
3375PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV; 3376PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV = NULL;
3376PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV; 3377PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV = NULL;
3377PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV; 3378PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV = NULL;
3378PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV; 3379PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV = NULL;
3379PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV; 3380PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV = NULL;
3380PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV; 3381PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV = NULL;
3381PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV; 3382PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV = NULL;
3382PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV; 3383PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV = NULL;
3383PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT; 3384PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV = NULL;
3384PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT; 3385PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV = NULL;
3385PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV; 3386PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV = NULL;
3386PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV; 3387PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT = NULL;
3387PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV; 3388PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT = NULL;
3388PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV; 3389PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV = NULL;
3389PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV; 3390PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV = NULL;
3390PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV; 3391PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV = NULL;
3391PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV; 3392PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV = NULL;
3392PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV; 3393PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV = NULL;
3393PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV; 3394PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV = NULL;
3394PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV; 3395PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV = NULL;
3395PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV; 3396PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV = NULL;
3396PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV; 3397PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV = NULL;
3397PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV; 3398PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV = NULL;
3398PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV; 3399PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV = NULL;
3399PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV; 3400PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV = NULL;
3400PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV; 3401PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV = NULL;
3401PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV; 3402PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV = NULL;
3402PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV; 3403PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV = NULL;
3403PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV; 3404PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV = NULL;
3404PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV; 3405PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV = NULL;
3405PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV; 3406PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV = NULL;
3406PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV; 3407PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV = NULL;
3407PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV; 3408PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV = NULL;
3408PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV; 3409PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV = NULL;
3409PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV; 3410PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV = NULL;
3410PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV; 3411PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV = NULL;
3411PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV; 3412PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV = NULL;
3412PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV; 3413PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV = NULL;
3413PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV; 3414PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV = NULL;
3414PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV; 3415PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV = NULL;
3415PFNGLVERTEX2HNVPROC glad_glVertex2hNV; 3416PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV = NULL;
3416PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV; 3417PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV = NULL;
3417PFNGLVERTEX3HNVPROC glad_glVertex3hNV; 3418PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV = NULL;
3418PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV; 3419PFNGLVERTEX2HNVPROC glad_glVertex2hNV = NULL;
3419PFNGLVERTEX4HNVPROC glad_glVertex4hNV; 3420PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV = NULL;
3420PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV; 3421PFNGLVERTEX3HNVPROC glad_glVertex3hNV = NULL;
3421PFNGLNORMAL3HNVPROC glad_glNormal3hNV; 3422PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV = NULL;
3422PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV; 3423PFNGLVERTEX4HNVPROC glad_glVertex4hNV = NULL;
3423PFNGLCOLOR3HNVPROC glad_glColor3hNV; 3424PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV = NULL;
3424PFNGLCOLOR3HVNVPROC glad_glColor3hvNV; 3425PFNGLNORMAL3HNVPROC glad_glNormal3hNV = NULL;
3425PFNGLCOLOR4HNVPROC glad_glColor4hNV; 3426PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV = NULL;
3426PFNGLCOLOR4HVNVPROC glad_glColor4hvNV; 3427PFNGLCOLOR3HNVPROC glad_glColor3hNV = NULL;
3427PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV; 3428PFNGLCOLOR3HVNVPROC glad_glColor3hvNV = NULL;
3428PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV; 3429PFNGLCOLOR4HNVPROC glad_glColor4hNV = NULL;
3429PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV; 3430PFNGLCOLOR4HVNVPROC glad_glColor4hvNV = NULL;
3430PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV; 3431PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV = NULL;
3431PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV; 3432PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV = NULL;
3432PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV; 3433PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV = NULL;
3433PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV; 3434PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV = NULL;
3434PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV; 3435PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV = NULL;
3435PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV; 3436PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV = NULL;
3436PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV; 3437PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV = NULL;
3437PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV; 3438PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV = NULL;
3438PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV; 3439PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV = NULL;
3439PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV; 3440PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV = NULL;
3440PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV; 3441PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV = NULL;
3441PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV; 3442PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV = NULL;
3442PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV; 3443PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV = NULL;
3443PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV; 3444PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV = NULL;
3444PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV; 3445PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV = NULL;
3445PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV; 3446PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV = NULL;
3446PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV; 3447PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV = NULL;
3447PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV; 3448PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV = NULL;
3448PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV; 3449PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV = NULL;
3449PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV; 3450PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV = NULL;
3450PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV; 3451PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV = NULL;
3451PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV; 3452PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV = NULL;
3452PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV; 3453PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV = NULL;
3453PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV; 3454PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV = NULL;
3454PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV; 3455PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV = NULL;
3455PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV; 3456PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV = NULL;
3456PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV; 3457PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV = NULL;
3457PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV; 3458PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV = NULL;
3458PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV; 3459PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV = NULL;
3459PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV; 3460PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV = NULL;
3460PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV; 3461PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV = NULL;
3461PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV; 3462PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV = NULL;
3462PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV; 3463PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV = NULL;
3463PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV; 3464PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV = NULL;
3464PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV; 3465PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV = NULL;
3465PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV; 3466PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV = NULL;
3466PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV; 3467PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV = NULL;
3467PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV; 3468PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV = NULL;
3468PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV; 3469PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV = NULL;
3469PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV; 3470PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV = NULL;
3470PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV; 3471PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV = NULL;
3471PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV; 3472PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV = NULL;
3472PFNGLGENPATHSNVPROC glad_glGenPathsNV; 3473PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV = NULL;
3473PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV; 3474PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV = NULL;
3474PFNGLISPATHNVPROC glad_glIsPathNV; 3475PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV = NULL;
3475PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV; 3476PFNGLGENPATHSNVPROC glad_glGenPathsNV = NULL;
3476PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV; 3477PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV = NULL;
3477PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV; 3478PFNGLISPATHNVPROC glad_glIsPathNV = NULL;
3478PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV; 3479PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV = NULL;
3479PFNGLPATHSTRINGNVPROC glad_glPathStringNV; 3480PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV = NULL;
3480PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV; 3481PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV = NULL;
3481PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV; 3482PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV = NULL;
3482PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV; 3483PFNGLPATHSTRINGNVPROC glad_glPathStringNV = NULL;
3483PFNGLCOPYPATHNVPROC glad_glCopyPathNV; 3484PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV = NULL;
3484PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV; 3485PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV = NULL;
3485PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV; 3486PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV = NULL;
3486PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV; 3487PFNGLCOPYPATHNVPROC glad_glCopyPathNV = NULL;
3487PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV; 3488PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV = NULL;
3488PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV; 3489PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV = NULL;
3489PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV; 3490PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV = NULL;
3490PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV; 3491PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV = NULL;
3491PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV; 3492PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV = NULL;
3492PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV; 3493PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV = NULL;
3493PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV; 3494PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV = NULL;
3494PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV; 3495PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV = NULL;
3495PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV; 3496PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV = NULL;
3496PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV; 3497PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV = NULL;
3497PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV; 3498PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV = NULL;
3498PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV; 3499PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV = NULL;
3499PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV; 3500PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV = NULL;
3500PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV; 3501PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV = NULL;
3501PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV; 3502PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV = NULL;
3502PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV; 3503PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV = NULL;
3503PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV; 3504PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV = NULL;
3504PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV; 3505PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV = NULL;
3505PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV; 3506PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV = NULL;
3506PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV; 3507PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV = NULL;
3507PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV; 3508PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV = NULL;
3508PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV; 3509PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV = NULL;
3509PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV; 3510PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV = NULL;
3510PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV; 3511PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV = NULL;
3511PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV; 3512PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV = NULL;
3512PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV; 3513PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV = NULL;
3513PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV; 3514PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV = NULL;
3514PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV; 3515PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV = NULL;
3515PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV; 3516PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV = NULL;
3516PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV; 3517PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV = NULL;
3517PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV; 3518PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV = NULL;
3518PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV; 3519PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV = NULL;
3519PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV; 3520PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV = NULL;
3520PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV; 3521PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV = NULL;
3521PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV; 3522PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV = NULL;
3522PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV; 3523PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV = NULL;
3523PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV; 3524PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV = NULL;
3524PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV; 3525PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV = NULL;
3525PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV; 3526PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV = NULL;
3526PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV; 3527PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV = NULL;
3527PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV; 3528PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV = NULL;
3528PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV; 3529PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV = NULL;
3529PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV; 3530PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV = NULL;
3530PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV; 3531PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV = NULL;
3531PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV; 3532PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV = NULL;
3532PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV; 3533PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV = NULL;
3533PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV; 3534PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV = NULL;
3534PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV; 3535PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV = NULL;
3535PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV; 3536PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV = NULL;
3536PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV; 3537PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV = NULL;
3537PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV; 3538PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV = NULL;
3538PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV; 3539PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV = NULL;
3539PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV; 3540PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV = NULL;
3540PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV; 3541PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV = NULL;
3541PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV; 3542PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV = NULL;
3542PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV; 3543PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV = NULL;
3543PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV; 3544PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV = NULL;
3544PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV; 3545PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV = NULL;
3545PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV; 3546PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV = NULL;
3546PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV; 3547PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV = NULL;
3547PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV; 3548PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV = NULL;
3548PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV; 3549PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV = NULL;
3549PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV; 3550PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV = NULL;
3550PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV; 3551PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV = NULL;
3551PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV; 3552PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV = NULL;
3552PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV; 3553PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV = NULL;
3553PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV; 3554PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV = NULL;
3554PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV; 3555PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV = NULL;
3555PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV; 3556PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV = NULL;
3556PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV; 3557PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV = NULL;
3557PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV; 3558PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV = NULL;
3558PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV; 3559PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV = NULL;
3559PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV; 3560PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV = NULL;
3560PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV; 3561PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV = NULL;
3561PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV; 3562PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV = NULL;
3562PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV; 3563PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV = NULL;
3563PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV; 3564PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV = NULL;
3564PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV; 3565PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV = NULL;
3565PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV; 3566PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV = NULL;
3566PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV; 3567PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV = NULL;
3567PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV; 3568PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV = NULL;
3568PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV; 3569PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV = NULL;
3569PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV; 3570PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV = NULL;
3570PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV; 3571PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV = NULL;
3571PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV; 3572PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV = NULL;
3572PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV; 3573PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV = NULL;
3573PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV; 3574PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV = NULL;
3574PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV; 3575PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV = NULL;
3575PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV; 3576PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV = NULL;
3576PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV; 3577PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV = NULL;
3577PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV; 3578PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV = NULL;
3578PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV; 3579PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV = NULL;
3579PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV; 3580PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV = NULL;
3580PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV; 3581PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV = NULL;
3581PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV; 3582PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV = NULL;
3582PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV; 3583PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV = NULL;
3583PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV; 3584PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV = NULL;
3584PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV; 3585PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV = NULL;
3585PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV; 3586PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV = NULL;
3586PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV; 3587PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV = NULL;
3587PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV; 3588PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV = NULL;
3588PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV; 3589PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV = NULL;
3589PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV; 3590PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV = NULL;
3590PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV; 3591PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV = NULL;
3591PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV; 3592PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV = NULL;
3592PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV; 3593PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV = NULL;
3593PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV; 3594PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV = NULL;
3594PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV; 3595PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV = NULL;
3595PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV; 3596PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV = NULL;
3596PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV; 3597PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV = NULL;
3597PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV; 3598PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV = NULL;
3598PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV; 3599PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV = NULL;
3599PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV; 3600PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV = NULL;
3600PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV; 3601PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV = NULL;
3601PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV; 3602PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV = NULL;
3602PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV; 3603PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV = NULL;
3603PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV; 3604PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV = NULL;
3604PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV; 3605PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV = NULL;
3605PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV; 3606PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV = NULL;
3606PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV; 3607PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV = NULL;
3607PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV; 3608PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV = NULL;
3608PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV; 3609PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV = NULL;
3609PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV; 3610PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV = NULL;
3610PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV; 3611PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV = NULL;
3611PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV; 3612PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV = NULL;
3612PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV; 3613PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV = NULL;
3613PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV; 3614PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV = NULL;
3614PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV; 3615PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV = NULL;
3615PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV; 3616PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV = NULL;
3616PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV; 3617PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV = NULL;
3617PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV; 3618PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV = NULL;
3618PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV; 3619PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV = NULL;
3619PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV; 3620PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV = NULL;
3620PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV; 3621PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV = NULL;
3621PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV; 3622PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV = NULL;
3622PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV; 3623PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV = NULL;
3623PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV; 3624PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV = NULL;
3624PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV; 3625PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV = NULL;
3625PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV; 3626PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV = NULL;
3626PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV; 3627PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV = NULL;
3627PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV; 3628PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV = NULL;
3628PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV; 3629PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV = NULL;
3629PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV; 3630PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV = NULL;
3630PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV; 3631PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV = NULL;
3631PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV; 3632PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV = NULL;
3632PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV; 3633PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV = NULL;
3633PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV; 3634PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV = NULL;
3634PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV; 3635PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV = NULL;
3635PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV; 3636PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV = NULL;
3636PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV; 3637PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV = NULL;
3637PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV; 3638PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV = NULL;
3638PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV; 3639PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV = NULL;
3639PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV; 3640PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV = NULL;
3640PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV; 3641PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV = NULL;
3641PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV; 3642PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV = NULL;
3642PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV; 3643PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV = NULL;
3643PFNGLCOLORFORMATNVPROC glad_glColorFormatNV; 3644PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV = NULL;
3644PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV; 3645PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV = NULL;
3645PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV; 3646PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV = NULL;
3646PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV; 3647PFNGLCOLORFORMATNVPROC glad_glColorFormatNV = NULL;
3647PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV; 3648PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV = NULL;
3648PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV; 3649PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV = NULL;
3649PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV; 3650PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV = NULL;
3650PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV; 3651PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV = NULL;
3651PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV; 3652PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV = NULL;
3652PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV; 3653PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV = NULL;
3653PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV; 3654PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV = NULL;
3654PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV; 3655PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV = NULL;
3655PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV; 3656PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV = NULL;
3656PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV; 3657PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV = NULL;
3657PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV; 3658PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV = NULL;
3658PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV; 3659PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV = NULL;
3659PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV; 3660PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV = NULL;
3660PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV; 3661PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV = NULL;
3661PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV; 3662PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV = NULL;
3662PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV; 3663PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV = NULL;
3663PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV; 3664PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV = NULL;
3664PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV; 3665PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV = NULL;
3665PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV; 3666PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV = NULL;
3666PFNGLISPROGRAMNVPROC glad_glIsProgramNV; 3667PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV = NULL;
3667PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV; 3668PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV = NULL;
3668PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV; 3669PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV = NULL;
3669PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV; 3670PFNGLISPROGRAMNVPROC glad_glIsProgramNV = NULL;
3670PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV; 3671PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV = NULL;
3671PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV; 3672PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV = NULL;
3672PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV; 3673PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV = NULL;
3673PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV; 3674PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV = NULL;
3674PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV; 3675PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV = NULL;
3675PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV; 3676PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV = NULL;
3676PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV; 3677PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV = NULL;
3677PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV; 3678PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV = NULL;
3678PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV; 3679PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV = NULL;
3679PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV; 3680PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV = NULL;
3680PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV; 3681PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV = NULL;
3681PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV; 3682PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV = NULL;
3682PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV; 3683PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV = NULL;
3683PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV; 3684PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV = NULL;
3684PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV; 3685PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV = NULL;
3685PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV; 3686PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV = NULL;
3686PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV; 3687PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV = NULL;
3687PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV; 3688PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV = NULL;
3688PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV; 3689PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV = NULL;
3689PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV; 3690PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV = NULL;
3690PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV; 3691PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV = NULL;
3691PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV; 3692PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV = NULL;
3692PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV; 3693PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV = NULL;
3693PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV; 3694PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV = NULL;
3694PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV; 3695PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV = NULL;
3695PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV; 3696PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV = NULL;
3696PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV; 3697PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV = NULL;
3697PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV; 3698PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV = NULL;
3698PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV; 3699PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV = NULL;
3699PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV; 3700PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV = NULL;
3700PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV; 3701PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV = NULL;
3701PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV; 3702PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV = NULL;
3702PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV; 3703PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV = NULL;
3703PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV; 3704PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV = NULL;
3704PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV; 3705PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV = NULL;
3705PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV; 3706PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV = NULL;
3706PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV; 3707PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV = NULL;
3707PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV; 3708PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV = NULL;
3708PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV; 3709PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV = NULL;
3709PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV; 3710PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV = NULL;
3710PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV; 3711PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV = NULL;
3711PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV; 3712PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV = NULL;
3712PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV; 3713PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV = NULL;
3713PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV; 3714PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV = NULL;
3714PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV; 3715PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV = NULL;
3715PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV; 3716PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV = NULL;
3716PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT; 3717PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV = NULL;
3717PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT; 3718PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV = NULL;
3718PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT; 3719PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV = NULL;
3719PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT; 3720PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT = NULL;
3720PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT; 3721PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT = NULL;
3721PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT; 3722PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT = NULL;
3722PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT; 3723PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT = NULL;
3723PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT; 3724PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT = NULL;
3724PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT; 3725PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT = NULL;
3725PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT; 3726PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT = NULL;
3726PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT; 3727PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT = NULL;
3727PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT; 3728PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT = NULL;
3728PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT; 3729PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT = NULL;
3729PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT; 3730PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT = NULL;
3730PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT; 3731PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT = NULL;
3731PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT; 3732PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT = NULL;
3732PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT; 3733PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT = NULL;
3733PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT; 3734PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT = NULL;
3734PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT; 3735PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT = NULL;
3735PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT; 3736PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT = NULL;
3736PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT; 3737PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT = NULL;
3737PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT; 3738PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT = NULL;
3738PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT; 3739PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT = NULL;
3739PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV; 3740PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT = NULL;
3740PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV; 3741PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT = NULL;
3741PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV; 3742PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT = NULL;
3742PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV; 3743PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV = NULL;
3743PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV; 3744PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV = NULL;
3744PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV; 3745PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV = NULL;
3745PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV; 3746PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV = NULL;
3746PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV; 3747PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV = NULL;
3747PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV; 3748PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV = NULL;
3748PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV; 3749PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV = NULL;
3749PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV; 3750PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV = NULL;
3750PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV; 3751PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV = NULL;
3751PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV; 3752PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV = NULL;
3752PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES; 3753PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV = NULL;
3753PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES; 3754PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV = NULL;
3754PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES; 3755PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV = NULL;
3755PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES; 3756PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES = NULL;
3756PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES; 3757PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES = NULL;
3757PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES; 3758PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES = NULL;
3758PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES; 3759PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES = NULL;
3759PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES; 3760PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES = NULL;
3760PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES; 3761PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES = NULL;
3761PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES; 3762PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES = NULL;
3762PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES; 3763PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES = NULL;
3763PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES; 3764PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES = NULL;
3764PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES; 3765PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES = NULL;
3765PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES; 3766PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES = NULL;
3766PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES; 3767PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES = NULL;
3767PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES; 3768PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES = NULL;
3768PFNGLVERTEX2BOESPROC glad_glVertex2bOES; 3769PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES = NULL;
3769PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES; 3770PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES = NULL;
3770PFNGLVERTEX3BOESPROC glad_glVertex3bOES; 3771PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES = NULL;
3771PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES; 3772PFNGLVERTEX2BOESPROC glad_glVertex2bOES = NULL;
3772PFNGLVERTEX4BOESPROC glad_glVertex4bOES; 3773PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES = NULL;
3773PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES; 3774PFNGLVERTEX3BOESPROC glad_glVertex3bOES = NULL;
3774PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES; 3775PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES = NULL;
3775PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES; 3776PFNGLVERTEX4BOESPROC glad_glVertex4bOES = NULL;
3776PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES; 3777PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES = NULL;
3777PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES; 3778PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES = NULL;
3778PFNGLCOLOR4XOESPROC glad_glColor4xOES; 3779PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES = NULL;
3779PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES; 3780PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES = NULL;
3780PFNGLFOGXOESPROC glad_glFogxOES; 3781PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES = NULL;
3781PFNGLFOGXVOESPROC glad_glFogxvOES; 3782PFNGLCOLOR4XOESPROC glad_glColor4xOES = NULL;
3782PFNGLFRUSTUMXOESPROC glad_glFrustumxOES; 3783PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES = NULL;
3783PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES; 3784PFNGLFOGXOESPROC glad_glFogxOES = NULL;
3784PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES; 3785PFNGLFOGXVOESPROC glad_glFogxvOES = NULL;
3785PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES; 3786PFNGLFRUSTUMXOESPROC glad_glFrustumxOES = NULL;
3786PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES; 3787PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES = NULL;
3787PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES; 3788PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES = NULL;
3788PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES; 3789PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES = NULL;
3789PFNGLLIGHTXOESPROC glad_glLightxOES; 3790PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES = NULL;
3790PFNGLLIGHTXVOESPROC glad_glLightxvOES; 3791PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES = NULL;
3791PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES; 3792PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES = NULL;
3792PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES; 3793PFNGLLIGHTXOESPROC glad_glLightxOES = NULL;
3793PFNGLMATERIALXOESPROC glad_glMaterialxOES; 3794PFNGLLIGHTXVOESPROC glad_glLightxvOES = NULL;
3794PFNGLMATERIALXVOESPROC glad_glMaterialxvOES; 3795PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES = NULL;
3795PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES; 3796PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES = NULL;
3796PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES; 3797PFNGLMATERIALXOESPROC glad_glMaterialxOES = NULL;
3797PFNGLNORMAL3XOESPROC glad_glNormal3xOES; 3798PFNGLMATERIALXVOESPROC glad_glMaterialxvOES = NULL;
3798PFNGLORTHOXOESPROC glad_glOrthoxOES; 3799PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES = NULL;
3799PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES; 3800PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES = NULL;
3800PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES; 3801PFNGLNORMAL3XOESPROC glad_glNormal3xOES = NULL;
3801PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES; 3802PFNGLORTHOXOESPROC glad_glOrthoxOES = NULL;
3802PFNGLROTATEXOESPROC glad_glRotatexOES; 3803PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES = NULL;
3803PFNGLSCALEXOESPROC glad_glScalexOES; 3804PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES = NULL;
3804PFNGLTEXENVXOESPROC glad_glTexEnvxOES; 3805PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES = NULL;
3805PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES; 3806PFNGLROTATEXOESPROC glad_glRotatexOES = NULL;
3806PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES; 3807PFNGLSCALEXOESPROC glad_glScalexOES = NULL;
3807PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES; 3808PFNGLTEXENVXOESPROC glad_glTexEnvxOES = NULL;
3808PFNGLTRANSLATEXOESPROC glad_glTranslatexOES; 3809PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES = NULL;
3809PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES; 3810PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES = NULL;
3810PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES; 3811PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES = NULL;
3811PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES; 3812PFNGLTRANSLATEXOESPROC glad_glTranslatexOES = NULL;
3812PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES; 3813PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES = NULL;
3813PFNGLACCUMXOESPROC glad_glAccumxOES; 3814PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES = NULL;
3814PFNGLBITMAPXOESPROC glad_glBitmapxOES; 3815PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES = NULL;
3815PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES; 3816PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES = NULL;
3816PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES; 3817PFNGLACCUMXOESPROC glad_glAccumxOES = NULL;
3817PFNGLCOLOR3XOESPROC glad_glColor3xOES; 3818PFNGLBITMAPXOESPROC glad_glBitmapxOES = NULL;
3818PFNGLCOLOR3XVOESPROC glad_glColor3xvOES; 3819PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES = NULL;
3819PFNGLCOLOR4XVOESPROC glad_glColor4xvOES; 3820PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES = NULL;
3820PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES; 3821PFNGLCOLOR3XOESPROC glad_glColor3xOES = NULL;
3821PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES; 3822PFNGLCOLOR3XVOESPROC glad_glColor3xvOES = NULL;
3822PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES; 3823PFNGLCOLOR4XVOESPROC glad_glColor4xvOES = NULL;
3823PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES; 3824PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES = NULL;
3824PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES; 3825PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES = NULL;
3825PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES; 3826PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES = NULL;
3826PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES; 3827PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES = NULL;
3827PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES; 3828PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES = NULL;
3828PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES; 3829PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES = NULL;
3829PFNGLGETLIGHTXOESPROC glad_glGetLightxOES; 3830PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES = NULL;
3830PFNGLGETMAPXVOESPROC glad_glGetMapxvOES; 3831PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES = NULL;
3831PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES; 3832PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES = NULL;
3832PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv; 3833PFNGLGETLIGHTXOESPROC glad_glGetLightxOES = NULL;
3833PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES; 3834PFNGLGETMAPXVOESPROC glad_glGetMapxvOES = NULL;
3834PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES; 3835PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES = NULL;
3835PFNGLINDEXXOESPROC glad_glIndexxOES; 3836PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv = NULL;
3836PFNGLINDEXXVOESPROC glad_glIndexxvOES; 3837PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES = NULL;
3837PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES; 3838PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES = NULL;
3838PFNGLMAP1XOESPROC glad_glMap1xOES; 3839PFNGLINDEXXOESPROC glad_glIndexxOES = NULL;
3839PFNGLMAP2XOESPROC glad_glMap2xOES; 3840PFNGLINDEXXVOESPROC glad_glIndexxvOES = NULL;
3840PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES; 3841PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES = NULL;
3841PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES; 3842PFNGLMAP1XOESPROC glad_glMap1xOES = NULL;
3842PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES; 3843PFNGLMAP2XOESPROC glad_glMap2xOES = NULL;
3843PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES; 3844PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES = NULL;
3844PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES; 3845PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES = NULL;
3845PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES; 3846PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES = NULL;
3846PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES; 3847PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES = NULL;
3847PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES; 3848PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES = NULL;
3848PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES; 3849PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES = NULL;
3849PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES; 3850PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES = NULL;
3850PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES; 3851PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES = NULL;
3851PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES; 3852PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES = NULL;
3852PFNGLPIXELMAPXPROC glad_glPixelMapx; 3853PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES = NULL;
3853PFNGLPIXELSTOREXPROC glad_glPixelStorex; 3854PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES = NULL;
3854PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES; 3855PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES = NULL;
3855PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES; 3856PFNGLPIXELMAPXPROC glad_glPixelMapx = NULL;
3856PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES; 3857PFNGLPIXELSTOREXPROC glad_glPixelStorex = NULL;
3857PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES; 3858PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES = NULL;
3858PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES; 3859PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES = NULL;
3859PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES; 3860PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES = NULL;
3860PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES; 3861PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES = NULL;
3861PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES; 3862PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES = NULL;
3862PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES; 3863PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES = NULL;
3863PFNGLRECTXOESPROC glad_glRectxOES; 3864PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES = NULL;
3864PFNGLRECTXVOESPROC glad_glRectxvOES; 3865PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES = NULL;
3865PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES; 3866PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES = NULL;
3866PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES; 3867PFNGLRECTXOESPROC glad_glRectxOES = NULL;
3867PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES; 3868PFNGLRECTXVOESPROC glad_glRectxvOES = NULL;
3868PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES; 3869PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES = NULL;
3869PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES; 3870PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES = NULL;
3870PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES; 3871PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES = NULL;
3871PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES; 3872PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES = NULL;
3872PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES; 3873PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES = NULL;
3873PFNGLTEXGENXOESPROC glad_glTexGenxOES; 3874PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES = NULL;
3874PFNGLTEXGENXVOESPROC glad_glTexGenxvOES; 3875PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES = NULL;
3875PFNGLVERTEX2XOESPROC glad_glVertex2xOES; 3876PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES = NULL;
3876PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES; 3877PFNGLTEXGENXOESPROC glad_glTexGenxOES = NULL;
3877PFNGLVERTEX3XOESPROC glad_glVertex3xOES; 3878PFNGLTEXGENXVOESPROC glad_glTexGenxvOES = NULL;
3878PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES; 3879PFNGLVERTEX2XOESPROC glad_glVertex2xOES = NULL;
3879PFNGLVERTEX4XOESPROC glad_glVertex4xOES; 3880PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES = NULL;
3880PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES; 3881PFNGLVERTEX3XOESPROC glad_glVertex3xOES = NULL;
3881PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES; 3882PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES = NULL;
3882PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES; 3883PFNGLVERTEX4XOESPROC glad_glVertex4xOES = NULL;
3883PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES; 3884PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES = NULL;
3884PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES; 3885PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES = NULL;
3885PFNGLFRUSTUMFOESPROC glad_glFrustumfOES; 3886PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES = NULL;
3886PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES; 3887PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES = NULL;
3887PFNGLORTHOFOESPROC glad_glOrthofOES; 3888PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES = NULL;
3888PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; 3889PFNGLFRUSTUMFOESPROC glad_glFrustumfOES = NULL;
3889PFNGLHINTPGIPROC glad_glHintPGI; 3890PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES = NULL;
3890PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS; 3891PFNGLORTHOFOESPROC glad_glOrthofOES = NULL;
3891PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS; 3892PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL;
3892PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS; 3893PFNGLHINTPGIPROC glad_glHintPGI = NULL;
3893PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS; 3894PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS = NULL;
3894PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS; 3895PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS = NULL;
3895PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS; 3896PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS = NULL;
3896PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS; 3897PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS = NULL;
3897PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS; 3898PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS = NULL;
3898PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS; 3899PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS = NULL;
3899PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS; 3900PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS = NULL;
3900PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS; 3901PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS = NULL;
3901PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS; 3902PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS = NULL;
3902PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS; 3903PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS = NULL;
3903PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS; 3904PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS = NULL;
3904PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS; 3905PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS = NULL;
3905PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS; 3906PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS = NULL;
3906PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS; 3907PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS = NULL;
3907PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS; 3908PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS = NULL;
3908PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS; 3909PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS = NULL;
3909PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS; 3910PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS = NULL;
3910PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS; 3911PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS = NULL;
3911PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX; 3912PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS = NULL;
3912PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX; 3913PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS = NULL;
3913PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX; 3914PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS = NULL;
3914PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX; 3915PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX = NULL;
3915PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX; 3916PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX = NULL;
3916PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX; 3917PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX = NULL;
3917PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX; 3918PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX = NULL;
3918PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX; 3919PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX = NULL;
3919PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX; 3920PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX = NULL;
3920PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX; 3921PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX = NULL;
3921PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX; 3922PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX = NULL;
3922PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX; 3923PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX = NULL;
3923PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX; 3924PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX = NULL;
3924PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX; 3925PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX = NULL;
3925PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX; 3926PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX = NULL;
3926PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX; 3927PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX = NULL;
3927PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX; 3928PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX = NULL;
3928PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX; 3929PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX = NULL;
3929PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX; 3930PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX = NULL;
3930PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX; 3931PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX = NULL;
3931PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX; 3932PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX = NULL;
3932PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX; 3933PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX = NULL;
3933PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX; 3934PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX = NULL;
3934PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX; 3935PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX = NULL;
3935PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX; 3936PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX = NULL;
3936PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX; 3937PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX = NULL;
3937PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX; 3938PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX = NULL;
3938PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX; 3939PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX = NULL;
3939PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX; 3940PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX = NULL;
3940PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX; 3941PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX = NULL;
3941PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX; 3942PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX = NULL;
3942PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX; 3943PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX = NULL;
3943PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX; 3944PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX = NULL;
3944PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX; 3945PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX = NULL;
3945PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX; 3946PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX = NULL;
3946PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX; 3947PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX = NULL;
3947PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX; 3948PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX = NULL;
3948PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX; 3949PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX = NULL;
3949PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX; 3950PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX = NULL;
3950PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX; 3951PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX = NULL;
3951PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX; 3952PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX = NULL;
3952PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX; 3953PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX = NULL;
3953PFNGLDEFORMSGIXPROC glad_glDeformSGIX; 3954PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX = NULL;
3954PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX; 3955PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX = NULL;
3955PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX; 3956PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX = NULL;
3956PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX; 3957PFNGLDEFORMSGIXPROC glad_glDeformSGIX = NULL;
3957PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX; 3958PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX = NULL;
3958PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX; 3959PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX = NULL;
3959PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX; 3960PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX = NULL;
3960PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX; 3961PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX = NULL;
3961PFNGLCOLORTABLESGIPROC glad_glColorTableSGI; 3962PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX = NULL;
3962PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI; 3963PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX = NULL;
3963PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI; 3964PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX = NULL;
3964PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI; 3965PFNGLCOLORTABLESGIPROC glad_glColorTableSGI = NULL;
3965PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI; 3966PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI = NULL;
3966PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI; 3967PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI = NULL;
3967PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI; 3968PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI = NULL;
3968PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX; 3969PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI = NULL;
3969PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN; 3970PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI = NULL;
3970PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN; 3971PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI = NULL;
3971PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN; 3972PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX = NULL;
3972PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN; 3973PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN = NULL;
3973PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN; 3974PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN = NULL;
3974PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN; 3975PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN = NULL;
3975PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN; 3976PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN = NULL;
3976PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN; 3977PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN = NULL;
3977PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN; 3978PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN = NULL;
3978PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN; 3979PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN = NULL;
3979PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN; 3980PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN = NULL;
3980PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN; 3981PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN = NULL;
3981PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN; 3982PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN = NULL;
3982PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN; 3983PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN = NULL;
3983PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN; 3984PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN = NULL;
3984PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN; 3985PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN = NULL;
3985PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN; 3986PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN = NULL;
3986PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN; 3987PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN = NULL;
3987PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN; 3988PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN = NULL;
3988PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN; 3989PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN = NULL;
3989PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN; 3990PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN = NULL;
3990PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN; 3991PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN = NULL;
3991PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN; 3992PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN = NULL;
3992PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN; 3993PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN = NULL;
3993PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN; 3994PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN = NULL;
3994PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN; 3995PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN = NULL;
3995PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN; 3996PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN = NULL;
3996PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN; 3997PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN = NULL;
3997PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN; 3998PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN = NULL;
3998PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN; 3999PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN = NULL;
3999PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN; 4000PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN = NULL;
4000PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN; 4001PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN = NULL;
4001PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN; 4002PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN = NULL;
4002PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN; 4003PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN = NULL;
4003PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN; 4004PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN = NULL;
4004PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN; 4005PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN = NULL;
4005PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN; 4006PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN = NULL;
4006PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN; 4007PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN = NULL;
4007PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN; 4008PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN = NULL;
4008PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN; 4009PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
4009PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN; 4010PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
4010PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN; 4011PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN = NULL;
4011PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN; 4012PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = NULL;
4012PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN; 4013PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN = NULL;
4013PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN; 4014PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN = NULL;
4014PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN; 4015PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN = NULL;
4015PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN; 4016PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN = NULL;
4016PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN; 4017PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN = NULL;
4017PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN; 4018PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN = NULL;
4018PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; 4019PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN = NULL;
4019PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN; 4020PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN = NULL;
4020PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN; 4021PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL;
4021PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; 4022PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL;
4022PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; 4023PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN = NULL;
4023PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; 4024PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = NULL;
4024PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; 4025PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL;
4026PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL;
4027PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
4028PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
4025static void load_GL_VERSION_1_0(GLADloadproc load) { 4029static void load_GL_VERSION_1_0(GLADloadproc load) {
4026 if(!GLAD_GL_VERSION_1_0) return; 4030 if(!GLAD_GL_VERSION_1_0) return;
4027 glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); 4031 glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
@@ -4453,6 +4457,11 @@ static void load_GL_AMD_draw_buffers_blend(GLADloadproc load) {
4453 glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD"); 4457 glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD");
4454 glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD"); 4458 glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD");
4455} 4459}
4460static void load_GL_AMD_framebuffer_multisample_advanced(GLADloadproc load) {
4461 if(!GLAD_GL_AMD_framebuffer_multisample_advanced) return;
4462 glad_glRenderbufferStorageMultisampleAdvancedAMD = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glRenderbufferStorageMultisampleAdvancedAMD");
4463 glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glNamedRenderbufferStorageMultisampleAdvancedAMD");
4464}
4456static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) { 4465static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) {
4457 if(!GLAD_GL_AMD_framebuffer_sample_positions) return; 4466 if(!GLAD_GL_AMD_framebuffer_sample_positions) return;
4458 glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD"); 4467 glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD");
@@ -7812,6 +7821,7 @@ static int find_extensionsGL(void) {
7812 GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output"); 7821 GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output");
7813 GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate"); 7822 GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate");
7814 GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend"); 7823 GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend");
7824 GLAD_GL_AMD_framebuffer_multisample_advanced = has_ext("GL_AMD_framebuffer_multisample_advanced");
7815 GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions"); 7825 GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions");
7816 GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader"); 7826 GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader");
7817 GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float"); 7827 GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float");
@@ -8473,6 +8483,7 @@ int gladLoadGLLoader(GLADloadproc load) {
8473 load_GL_3DFX_tbuffer(load); 8483 load_GL_3DFX_tbuffer(load);
8474 load_GL_AMD_debug_output(load); 8484 load_GL_AMD_debug_output(load);
8475 load_GL_AMD_draw_buffers_blend(load); 8485 load_GL_AMD_draw_buffers_blend(load);
8486 load_GL_AMD_framebuffer_multisample_advanced(load);
8476 load_GL_AMD_framebuffer_sample_positions(load); 8487 load_GL_AMD_framebuffer_sample_positions(load);
8477 load_GL_AMD_gpu_shader_int64(load); 8488 load_GL_AMD_gpu_shader_int64(load);
8478 load_GL_AMD_interleaved_elements(load); 8489 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(.)
3 3
4add_subdirectory(common) 4add_subdirectory(common)
5add_subdirectory(core) 5add_subdirectory(core)
6add_subdirectory(audio_core)
6add_subdirectory(video_core) 7add_subdirectory(video_core)
7add_subdirectory(input_common) 8add_subdirectory(input_common)
8add_subdirectory(tests) 9add_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 @@
1add_library(audio_core STATIC
2 audio_out.cpp
3 audio_out.h
4 audio_renderer.cpp
5 audio_renderer.h
6 buffer.h
7 codec.cpp
8 codec.h
9 null_sink.h
10 stream.cpp
11 stream.h
12 sink.h
13 sink_details.cpp
14 sink_details.h
15 sink_stream.h
16
17 $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h>
18)
19
20create_target_directory_groups(audio_core)
21
22target_link_libraries(audio_core PUBLIC common core)
23
24if(ENABLE_CUBEB)
25 target_link_libraries(audio_core PRIVATE cubeb)
26 target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
27endif()
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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "audio_core/audio_out.h"
6#include "audio_core/sink.h"
7#include "audio_core/sink_details.h"
8#include "common/assert.h"
9#include "common/logging/log.h"
10#include "core/settings.h"
11
12namespace AudioCore {
13
14/// Returns the stream format from the specified number of channels
15static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
16 switch (num_channels) {
17 case 1:
18 return Stream::Format::Mono16;
19 case 2:
20 return Stream::Format::Stereo16;
21 case 6:
22 return Stream::Format::Multi51Channel16;
23 }
24
25 LOG_CRITICAL(Audio, "Unimplemented num_channels={}", num_channels);
26 UNREACHABLE();
27 return {};
28}
29
30StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name,
31 Stream::ReleaseCallback&& release_callback) {
32 if (!sink) {
33 const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id);
34 sink = sink_details.factory(Settings::values.audio_device_id);
35 }
36
37 return std::make_shared<Stream>(
38 sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback),
39 sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name));
40}
41
42std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) {
43 return stream->GetTagsAndReleaseBuffers(max_count);
44}
45
46void AudioOut::StartStream(StreamPtr stream) {
47 stream->Play();
48}
49
50void AudioOut::StopStream(StreamPtr stream) {
51 stream->Stop();
52}
53
54bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data) {
55 return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data)));
56}
57
58} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <string>
9#include <vector>
10
11#include "audio_core/buffer.h"
12#include "audio_core/sink.h"
13#include "audio_core/stream.h"
14#include "common/common_types.h"
15
16namespace AudioCore {
17
18/**
19 * Represents an audio playback interface, used to open and play audio streams
20 */
21class AudioOut {
22public:
23 /// Opens a new audio stream
24 StreamPtr OpenStream(u32 sample_rate, u32 num_channels, std::string&& name,
25 Stream::ReleaseCallback&& release_callback);
26
27 /// Returns a vector of recently released buffers specified by tag for the specified stream
28 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count);
29
30 /// Starts an audio stream for playback
31 void StartStream(StreamPtr stream);
32
33 /// Stops an audio stream that is currently playing
34 void StopStream(StreamPtr stream);
35
36 /// Queues a buffer into the specified audio stream, returns true on success
37 bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data);
38
39private:
40 SinkPtr sink;
41};
42
43} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "audio_core/audio_renderer.h"
6#include "common/assert.h"
7#include "common/logging/log.h"
8#include "core/memory.h"
9
10namespace AudioCore {
11
12constexpr u32 STREAM_SAMPLE_RATE{48000};
13constexpr u32 STREAM_NUM_CHANNELS{2};
14
15AudioRenderer::AudioRenderer(AudioRendererParameter params,
16 Kernel::SharedPtr<Kernel::Event> buffer_event)
17 : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) {
18
19 audio_core = std::make_unique<AudioCore::AudioOut>();
20 stream = audio_core->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer",
21 [=]() { buffer_event->Signal(); });
22 audio_core->StartStream(stream);
23
24 QueueMixedBuffer(0);
25 QueueMixedBuffer(1);
26 QueueMixedBuffer(2);
27}
28
29std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) {
30 // Copy UpdateDataHeader struct
31 UpdateDataHeader config{};
32 std::memcpy(&config, input_params.data(), sizeof(UpdateDataHeader));
33 u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
34
35 // Copy MemoryPoolInfo structs
36 std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
37 std::memcpy(mem_pool_info.data(),
38 input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size,
39 memory_pool_count * sizeof(MemoryPoolInfo));
40
41 // Copy VoiceInfo structs
42 size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
43 config.voice_resource_size};
44 for (auto& voice : voices) {
45 std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo));
46 offset += sizeof(VoiceInfo);
47 }
48
49 // Update voices
50 for (auto& voice : voices) {
51 voice.UpdateState();
52 if (!voice.GetInfo().is_in_use) {
53 continue;
54 }
55 if (voice.GetInfo().is_new) {
56 voice.SetWaveIndex(voice.GetInfo().wave_buffer_head);
57 }
58 }
59
60 // Update memory pool state
61 std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
62 for (size_t index = 0; index < memory_pool.size(); ++index) {
63 if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
64 memory_pool[index].state = MemoryPoolStates::Attached;
65 } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
66 memory_pool[index].state = MemoryPoolStates::Detached;
67 }
68 }
69
70 // Release previous buffers and queue next ones for playback
71 ReleaseAndQueueBuffers();
72
73 // Copy output header
74 UpdateDataHeader response_data{worker_params};
75 std::vector<u8> output_params(response_data.total_size);
76 std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader));
77
78 // Copy output memory pool entries
79 std::memcpy(output_params.data() + sizeof(UpdateDataHeader), memory_pool.data(),
80 response_data.memory_pools_size);
81
82 // Copy output voice status
83 size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
84 for (const auto& voice : voices) {
85 std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
86 sizeof(VoiceOutStatus));
87 voice_out_status_offset += sizeof(VoiceOutStatus);
88 }
89
90 return output_params;
91}
92
93void AudioRenderer::VoiceState::SetWaveIndex(size_t index) {
94 wave_index = index & 3;
95 is_refresh_pending = true;
96}
97
98std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) {
99 if (!IsPlaying()) {
100 return {};
101 }
102
103 if (is_refresh_pending) {
104 RefreshBuffer();
105 }
106
107 const size_t max_size{samples.size() - offset};
108 const size_t dequeue_offset{offset};
109 size_t size{sample_count * STREAM_NUM_CHANNELS};
110 if (size > max_size) {
111 size = max_size;
112 }
113
114 out_status.played_sample_count += size / STREAM_NUM_CHANNELS;
115 offset += size;
116
117 const auto& wave_buffer{info.wave_buffer[wave_index]};
118 if (offset == samples.size()) {
119 offset = 0;
120
121 if (!wave_buffer.is_looping) {
122 SetWaveIndex(wave_index + 1);
123 }
124
125 out_status.wave_buffer_consumed++;
126
127 if (wave_buffer.end_of_stream) {
128 info.play_state = PlayState::Paused;
129 }
130 }
131
132 return {samples.begin() + dequeue_offset, samples.begin() + dequeue_offset + size};
133}
134
135void AudioRenderer::VoiceState::UpdateState() {
136 if (is_in_use && !info.is_in_use) {
137 // No longer in use, reset state
138 is_refresh_pending = true;
139 wave_index = 0;
140 offset = 0;
141 out_status = {};
142 }
143 is_in_use = info.is_in_use;
144}
145
146void AudioRenderer::VoiceState::RefreshBuffer() {
147 std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16));
148 Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(),
149 info.wave_buffer[wave_index].buffer_sz);
150
151 switch (static_cast<Codec::PcmFormat>(info.sample_format)) {
152 case Codec::PcmFormat::Int16: {
153 // PCM16 is played as-is
154 break;
155 }
156 case Codec::PcmFormat::Adpcm: {
157 // Decode ADPCM to PCM16
158 Codec::ADPCM_Coeff coeffs;
159 Memory::ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff));
160 new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()),
161 new_samples.size() * sizeof(s16), coeffs, adpcm_state);
162 break;
163 }
164 default:
165 LOG_CRITICAL(Audio, "Unimplemented sample_format={}", info.sample_format);
166 UNREACHABLE();
167 break;
168 }
169
170 switch (info.channel_count) {
171 case 1:
172 // 1 channel is upsampled to 2 channel
173 samples.resize(new_samples.size() * 2);
174 for (size_t index = 0; index < new_samples.size(); ++index) {
175 samples[index * 2] = new_samples[index];
176 samples[index * 2 + 1] = new_samples[index];
177 }
178 break;
179 case 2: {
180 // 2 channel is played as is
181 samples = std::move(new_samples);
182 break;
183 }
184 default:
185 LOG_CRITICAL(Audio, "Unimplemented channel_count={}", info.channel_count);
186 UNREACHABLE();
187 break;
188 }
189
190 is_refresh_pending = false;
191}
192
193static constexpr s16 ClampToS16(s32 value) {
194 return static_cast<s16>(std::clamp(value, -32768, 32767));
195}
196
197void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
198 constexpr size_t BUFFER_SIZE{512};
199 std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
200
201 for (auto& voice : voices) {
202 if (!voice.IsPlaying()) {
203 continue;
204 }
205
206 size_t offset{};
207 s64 samples_remaining{BUFFER_SIZE};
208 while (samples_remaining > 0) {
209 const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};
210
211 if (samples.empty()) {
212 break;
213 }
214
215 samples_remaining -= samples.size();
216
217 for (const auto& sample : samples) {
218 const s32 buffer_sample{buffer[offset]};
219 buffer[offset++] =
220 ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume));
221 }
222 }
223 }
224 audio_core->QueueBuffer(stream, tag, std::move(buffer));
225}
226
227void AudioRenderer::ReleaseAndQueueBuffers() {
228 const auto released_buffers{audio_core->GetTagsAndReleaseBuffers(stream, 2)};
229 for (const auto& tag : released_buffers) {
230 QueueMixedBuffer(tag);
231 }
232}
233
234} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <memory>
9#include <vector>
10
11#include "audio_core/audio_out.h"
12#include "audio_core/codec.h"
13#include "audio_core/stream.h"
14#include "common/common_types.h"
15#include "common/swap.h"
16#include "core/hle/kernel/event.h"
17
18namespace AudioCore {
19
20enum class PlayState : u8 {
21 Started = 0,
22 Stopped = 1,
23 Paused = 2,
24};
25
26struct AudioRendererParameter {
27 u32_le sample_rate;
28 u32_le sample_count;
29 u32_le unknown_8;
30 u32_le unknown_c;
31 u32_le voice_count;
32 u32_le sink_count;
33 u32_le effect_count;
34 u32_le unknown_1c;
35 u8 unknown_20;
36 INSERT_PADDING_BYTES(3);
37 u32_le splitter_count;
38 u32_le unknown_2c;
39 INSERT_PADDING_WORDS(1);
40 u32_le revision;
41};
42static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
43
44enum class MemoryPoolStates : u32 { // Should be LE
45 Invalid = 0x0,
46 Unknown = 0x1,
47 RequestDetach = 0x2,
48 Detached = 0x3,
49 RequestAttach = 0x4,
50 Attached = 0x5,
51 Released = 0x6,
52};
53
54struct MemoryPoolEntry {
55 MemoryPoolStates state;
56 u32_le unknown_4;
57 u32_le unknown_8;
58 u32_le unknown_c;
59};
60static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
61
62struct MemoryPoolInfo {
63 u64_le pool_address;
64 u64_le pool_size;
65 MemoryPoolStates pool_state;
66 INSERT_PADDING_WORDS(3); // Unknown
67};
68static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
69struct BiquadFilter {
70 u8 enable;
71 INSERT_PADDING_BYTES(1);
72 std::array<s16_le, 3> numerator;
73 std::array<s16_le, 2> denominator;
74};
75static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
76
77struct WaveBuffer {
78 u64_le buffer_addr;
79 u64_le buffer_sz;
80 s32_le start_sample_offset;
81 s32_le end_sample_offset;
82 u8 is_looping;
83 u8 end_of_stream;
84 u8 sent_to_server;
85 INSERT_PADDING_BYTES(5);
86 u64 context_addr;
87 u64 context_sz;
88 INSERT_PADDING_BYTES(8);
89};
90static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
91
92struct VoiceInfo {
93 u32_le id;
94 u32_le node_id;
95 u8 is_new;
96 u8 is_in_use;
97 PlayState play_state;
98 u8 sample_format;
99 u32_le sample_rate;
100 u32_le priority;
101 u32_le sorting_order;
102 u32_le channel_count;
103 float_le pitch;
104 float_le volume;
105 std::array<BiquadFilter, 2> biquad_filter;
106 u32_le wave_buffer_count;
107 u32_le wave_buffer_head;
108 INSERT_PADDING_WORDS(1);
109 u64_le additional_params_addr;
110 u64_le additional_params_sz;
111 u32_le mix_id;
112 u32_le splitter_info_id;
113 std::array<WaveBuffer, 4> wave_buffer;
114 std::array<u32_le, 6> voice_channel_resource_ids;
115 INSERT_PADDING_BYTES(24);
116};
117static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
118
119struct VoiceOutStatus {
120 u64_le played_sample_count;
121 u32_le wave_buffer_consumed;
122 u32_le voice_drops_count;
123};
124static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
125
126struct UpdateDataHeader {
127 UpdateDataHeader() {}
128
129 explicit UpdateDataHeader(const AudioRendererParameter& config) {
130 revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
131 behavior_size = 0xb0;
132 memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
133 voices_size = config.voice_count * 0x10;
134 voice_resource_size = 0x0;
135 effects_size = config.effect_count * 0x10;
136 mixes_size = 0x0;
137 sinks_size = config.sink_count * 0x20;
138 performance_manager_size = 0x10;
139 total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
140 effects_size + sinks_size + performance_manager_size;
141 }
142
143 u32_le revision;
144 u32_le behavior_size;
145 u32_le memory_pools_size;
146 u32_le voices_size;
147 u32_le voice_resource_size;
148 u32_le effects_size;
149 u32_le mixes_size;
150 u32_le sinks_size;
151 u32_le performance_manager_size;
152 INSERT_PADDING_WORDS(6);
153 u32_le total_size;
154};
155static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
156
157class AudioRenderer {
158public:
159 AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
160 std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
161 void QueueMixedBuffer(Buffer::Tag tag);
162 void ReleaseAndQueueBuffers();
163
164private:
165 class VoiceState {
166 public:
167 bool IsPlaying() const {
168 return is_in_use && info.play_state == PlayState::Started;
169 }
170
171 const VoiceOutStatus& GetOutStatus() const {
172 return out_status;
173 }
174
175 const VoiceInfo& GetInfo() const {
176 return info;
177 }
178
179 VoiceInfo& Info() {
180 return info;
181 }
182
183 void SetWaveIndex(size_t index);
184 std::vector<s16> DequeueSamples(size_t sample_count);
185 void UpdateState();
186 void RefreshBuffer();
187
188 private:
189 bool is_in_use{};
190 bool is_refresh_pending{};
191 size_t wave_index{};
192 size_t offset{};
193 Codec::ADPCMState adpcm_state{};
194 std::vector<s16> samples;
195 VoiceOutStatus out_status{};
196 VoiceInfo info{};
197 };
198
199 AudioRendererParameter worker_params;
200 Kernel::SharedPtr<Kernel::Event> buffer_event;
201 std::vector<VoiceState> voices;
202 std::unique_ptr<AudioCore::AudioOut> audio_core;
203 AudioCore::StreamPtr stream;
204};
205
206} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace AudioCore {
13
14/**
15 * Represents a buffer of audio samples to be played in an audio stream
16 */
17class Buffer {
18public:
19 using Tag = u64;
20
21 Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
22
23 /// Returns the raw audio data for the buffer
24 std::vector<s16>& Samples() {
25 return samples;
26 }
27
28 /// Returns the raw audio data for the buffer
29 const std::vector<s16>& GetSamples() const {
30 return samples;
31 }
32
33 /// Returns the buffer tag, this is provided by the game to the audout service
34 Tag GetTag() const {
35 return tag;
36 }
37
38private:
39 Tag tag;
40 std::vector<s16> samples;
41};
42
43using BufferPtr = std::shared_ptr<Buffer>;
44
45} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6
7#include "audio_core/codec.h"
8
9namespace AudioCore::Codec {
10
11std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff,
12 ADPCMState& state) {
13 // GC-ADPCM with scale factor and variable coefficients.
14 // Frames are 8 bytes long containing 14 samples each.
15 // Samples are 4 bits (one nibble) long.
16
17 constexpr size_t FRAME_LEN = 8;
18 constexpr size_t SAMPLES_PER_FRAME = 14;
19 constexpr std::array<int, 16> SIGNED_NIBBLES = {
20 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
21
22 const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
23 const size_t ret_size =
24 sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
25 std::vector<s16> ret(ret_size);
26
27 int yn1 = state.yn1, yn2 = state.yn2;
28
29 const size_t NUM_FRAMES =
30 (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
31 for (size_t framei = 0; framei < NUM_FRAMES; framei++) {
32 const int frame_header = data[framei * FRAME_LEN];
33 const int scale = 1 << (frame_header & 0xF);
34 const int idx = (frame_header >> 4) & 0x7;
35
36 // Coefficients are fixed point with 11 bits fractional part.
37 const int coef1 = coeff[idx * 2 + 0];
38 const int coef2 = coeff[idx * 2 + 1];
39
40 // Decodes an audio sample. One nibble produces one sample.
41 const auto decode_sample = [&](const int nibble) -> s16 {
42 const int xn = nibble * scale;
43 // We first transform everything into 11 bit fixed point, perform the second order
44 // digital filter, then transform back.
45 // 0x400 == 0.5 in 11 bit fixed point.
46 // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2]
47 int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11;
48 // Clamp to output range.
49 val = std::clamp<s32>(val, -32768, 32767);
50 // Advance output feedback.
51 yn2 = yn1;
52 yn1 = val;
53 return static_cast<s16>(val);
54 };
55
56 size_t outputi = framei * SAMPLES_PER_FRAME;
57 size_t datai = framei * FRAME_LEN + 1;
58 for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
59 const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
60 ret[outputi] = sample1;
61 outputi++;
62
63 const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]);
64 ret[outputi] = sample2;
65 outputi++;
66
67 datai++;
68 }
69 }
70
71 state.yn1 = yn1;
72 state.yn2 = yn2;
73
74 return ret;
75}
76
77} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace AudioCore::Codec {
13
14enum class PcmFormat : u32 {
15 Invalid = 0,
16 Int8 = 1,
17 Int16 = 2,
18 Int24 = 3,
19 Int32 = 4,
20 PcmFloat = 5,
21 Adpcm = 6,
22};
23
24/// See: Codec::DecodeADPCM
25struct ADPCMState {
26 // Two historical samples from previous processed buffer,
27 // required for ADPCM decoding
28 s16 yn1; ///< y[n-1]
29 s16 yn2; ///< y[n-2]
30};
31
32using ADPCM_Coeff = std::array<s16, 16>;
33
34/**
35 * @param data Pointer to buffer that contains ADPCM data to decode
36 * @param size Size of buffer in bytes
37 * @param coeff ADPCM coefficients
38 * @param state ADPCM state, this is updated with new state
39 * @return Decoded stereo signed PCM16 data, sample_count in length
40 */
41std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff,
42 ADPCMState& state);
43
44}; // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cstring>
7
8#include "audio_core/cubeb_sink.h"
9#include "audio_core/stream.h"
10#include "common/logging/log.h"
11
12namespace AudioCore {
13
14class SinkStreamImpl final : public SinkStream {
15public:
16 SinkStreamImpl(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
17 const std::string& name)
18 : ctx{ctx}, num_channels{num_channels_} {
19
20 if (num_channels == 6) {
21 // 6-channel audio does not seem to work with cubeb + SDL, so we downsample this to 2
22 // channel for now
23 is_6_channel = true;
24 num_channels = 2;
25 }
26
27 cubeb_stream_params params{};
28 params.rate = sample_rate;
29 params.channels = num_channels;
30 params.format = CUBEB_SAMPLE_S16NE;
31 params.layout = num_channels == 1 ? CUBEB_LAYOUT_MONO : CUBEB_LAYOUT_STEREO;
32
33 u32 minimum_latency{};
34 if (cubeb_get_min_latency(ctx, &params, &minimum_latency) != CUBEB_OK) {
35 LOG_CRITICAL(Audio_Sink, "Error getting minimum latency");
36 }
37
38 if (cubeb_stream_init(ctx, &stream_backend, name.c_str(), nullptr, nullptr, output_device,
39 &params, std::max(512u, minimum_latency),
40 &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback,
41 this) != CUBEB_OK) {
42 LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream");
43 return;
44 }
45
46 if (cubeb_stream_start(stream_backend) != CUBEB_OK) {
47 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream");
48 return;
49 }
50 }
51
52 ~SinkStreamImpl() {
53 if (!ctx) {
54 return;
55 }
56
57 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
58 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
59 }
60
61 cubeb_stream_destroy(stream_backend);
62 }
63
64 void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) override {
65 if (!ctx) {
66 return;
67 }
68
69 queue.reserve(queue.size() + samples.size() * GetNumChannels());
70
71 if (is_6_channel) {
72 // Downsample 6 channels to 2
73 const size_t sample_count_copy_size = samples.size() * 2;
74 queue.reserve(sample_count_copy_size);
75 for (size_t i = 0; i < samples.size(); i += num_channels) {
76 queue.push_back(samples[i]);
77 queue.push_back(samples[i + 1]);
78 }
79 } else {
80 // Copy as-is
81 std::copy(samples.begin(), samples.end(), std::back_inserter(queue));
82 }
83 }
84
85 u32 GetNumChannels() const {
86 return num_channels;
87 }
88
89private:
90 std::vector<std::string> device_list;
91
92 cubeb* ctx{};
93 cubeb_stream* stream_backend{};
94 u32 num_channels{};
95 bool is_6_channel{};
96
97 std::vector<s16> queue;
98
99 static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
100 void* output_buffer, long num_frames);
101 static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state);
102};
103
104CubebSink::CubebSink(std::string target_device_name) {
105 if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) {
106 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
107 return;
108 }
109
110 if (target_device_name != auto_device_name && !target_device_name.empty()) {
111 cubeb_device_collection collection;
112 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
113 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
114 } else {
115 const auto collection_end{collection.device + collection.count};
116 const auto device{std::find_if(collection.device, collection_end,
117 [&](const cubeb_device_info& device) {
118 return target_device_name == device.friendly_name;
119 })};
120 if (device != collection_end) {
121 output_device = device->devid;
122 }
123 cubeb_device_collection_destroy(ctx, &collection);
124 }
125 }
126}
127
128CubebSink::~CubebSink() {
129 if (!ctx) {
130 return;
131 }
132
133 for (auto& sink_stream : sink_streams) {
134 sink_stream.reset();
135 }
136
137 cubeb_destroy(ctx);
138}
139
140SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
141 const std::string& name) {
142 sink_streams.push_back(
143 std::make_unique<SinkStreamImpl>(ctx, sample_rate, num_channels, output_device, name));
144 return *sink_streams.back();
145}
146
147long SinkStreamImpl::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
148 void* output_buffer, long num_frames) {
149 SinkStreamImpl* impl = static_cast<SinkStreamImpl*>(user_data);
150 u8* buffer = reinterpret_cast<u8*>(output_buffer);
151
152 if (!impl) {
153 return {};
154 }
155
156 const size_t frames_to_write{
157 std::min(impl->queue.size() / impl->GetNumChannels(), static_cast<size_t>(num_frames))};
158
159 memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * impl->GetNumChannels());
160 impl->queue.erase(impl->queue.begin(),
161 impl->queue.begin() + frames_to_write * impl->GetNumChannels());
162
163 if (frames_to_write < num_frames) {
164 // Fill the rest of the frames with silence
165 memset(buffer + frames_to_write * sizeof(s16) * impl->GetNumChannels(), 0,
166 (num_frames - frames_to_write) * sizeof(s16) * impl->GetNumChannels());
167 }
168
169 return num_frames;
170}
171
172void SinkStreamImpl::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
173
174std::vector<std::string> ListCubebSinkDevices() {
175 std::vector<std::string> device_list;
176 cubeb* ctx;
177
178 if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) {
179 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
180 return {};
181 }
182
183 cubeb_device_collection collection;
184 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
185 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
186 } else {
187 for (size_t i = 0; i < collection.count; i++) {
188 const cubeb_device_info& device = collection.device[i];
189 if (device.friendly_name) {
190 device_list.emplace_back(device.friendly_name);
191 }
192 }
193 cubeb_device_collection_destroy(ctx, &collection);
194 }
195
196 cubeb_destroy(ctx);
197 return device_list;
198}
199
200} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <string>
8#include <vector>
9
10#include <cubeb/cubeb.h>
11
12#include "audio_core/sink.h"
13
14namespace AudioCore {
15
16class CubebSink final : public Sink {
17public:
18 explicit CubebSink(std::string device_id);
19 ~CubebSink() override;
20
21 SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
22 const std::string& name) override;
23
24private:
25 cubeb* ctx{};
26 cubeb_devid output_device{};
27 std::vector<SinkStreamPtr> sink_streams;
28};
29
30std::vector<std::string> ListCubebSinkDevices();
31
32} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "audio_core/sink.h"
8
9namespace AudioCore {
10
11class NullSink final : public Sink {
12public:
13 explicit NullSink(std::string){};
14 ~NullSink() override = default;
15
16 SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/,
17 const std::string& /*name*/) override {
18 return null_sink_stream;
19 }
20
21private:
22 struct NullSinkStreamImpl final : SinkStream {
23 void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {}
24 } null_sink_stream;
25};
26
27} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <string>
9
10#include "audio_core/sink_stream.h"
11#include "common/common_types.h"
12
13namespace AudioCore {
14
15constexpr char auto_device_name[] = "auto";
16
17/**
18 * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed
19 * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate.
20 * They are dumb outputs.
21 */
22class Sink {
23public:
24 virtual ~Sink() = default;
25 virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
26 const std::string& name) = 0;
27};
28
29using SinkPtr = std::unique_ptr<Sink>;
30
31} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <memory>
7#include <string>
8#include <vector>
9#include "audio_core/null_sink.h"
10#include "audio_core/sink_details.h"
11#ifdef HAVE_CUBEB
12#include "audio_core/cubeb_sink.h"
13#endif
14#include "common/logging/log.h"
15
16namespace AudioCore {
17
18// g_sink_details is ordered in terms of desirability, with the best choice at the top.
19const std::vector<SinkDetails> g_sink_details = {
20#ifdef HAVE_CUBEB
21 SinkDetails{"cubeb", &std::make_unique<CubebSink, std::string>, &ListCubebSinkDevices},
22#endif
23 SinkDetails{"null", &std::make_unique<NullSink, std::string>,
24 [] { return std::vector<std::string>{"null"}; }},
25};
26
27const SinkDetails& GetSinkDetails(std::string sink_id) {
28 auto iter =
29 std::find_if(g_sink_details.begin(), g_sink_details.end(),
30 [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
31
32 if (sink_id == "auto" || iter == g_sink_details.end()) {
33 if (sink_id != "auto") {
34 LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id);
35 }
36 // Auto-select.
37 // g_sink_details is ordered in terms of desirability, with the best choice at the front.
38 iter = g_sink_details.begin();
39 }
40
41 return *iter;
42}
43
44} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <functional>
8#include <memory>
9#include <utility>
10#include <vector>
11
12namespace AudioCore {
13
14class Sink;
15
16struct SinkDetails {
17 using FactoryFn = std::function<std::unique_ptr<Sink>(std::string)>;
18 using ListDevicesFn = std::function<std::vector<std::string>()>;
19
20 SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_)
21 : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {}
22
23 /// Name for this sink.
24 const char* id;
25 /// A method to call to construct an instance of this type of sink.
26 FactoryFn factory;
27 /// A method to call to list available devices.
28 ListDevicesFn list_devices;
29};
30
31extern const std::vector<SinkDetails> g_sink_details;
32
33const SinkDetails& GetSinkDetails(std::string sink_id);
34
35} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace AudioCore {
13
14/**
15 * Accepts samples in stereo signed PCM16 format to be output. Sinks *do not* handle resampling and
16 * expect the correct sample rate. They are dumb outputs.
17 */
18class SinkStream {
19public:
20 virtual ~SinkStream() = default;
21
22 /**
23 * Feed stereo samples to sink.
24 * @param num_channels Number of channels used.
25 * @param samples Samples in interleaved stereo PCM16 format.
26 */
27 virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0;
28};
29
30using SinkStreamPtr = std::unique_ptr<SinkStream>;
31
32} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cmath>
7
8#include "audio_core/sink.h"
9#include "audio_core/sink_details.h"
10#include "audio_core/stream.h"
11#include "common/assert.h"
12#include "common/logging/log.h"
13#include "core/core_timing.h"
14#include "core/core_timing_util.h"
15#include "core/settings.h"
16
17namespace AudioCore {
18
19constexpr size_t MaxAudioBufferCount{32};
20
21u32 Stream::GetNumChannels() const {
22 switch (format) {
23 case Format::Mono16:
24 return 1;
25 case Format::Stereo16:
26 return 2;
27 case Format::Multi51Channel16:
28 return 6;
29 }
30 LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format));
31 UNREACHABLE();
32 return {};
33}
34
35Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
36 SinkStream& sink_stream, std::string&& name_)
37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
38 sink_stream{sink_stream}, name{std::move(name_)} {
39
40 release_event = CoreTiming::RegisterEvent(
41 name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
42}
43
44void Stream::Play() {
45 state = State::Playing;
46 PlayNextBuffer();
47}
48
49void Stream::Stop() {
50 ASSERT_MSG(false, "Unimplemented");
51}
52
53s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
54 const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
55 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
56}
57
58static void VolumeAdjustSamples(std::vector<s16>& samples) {
59 const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)};
60
61 if (volume == 1.0f) {
62 return;
63 }
64
65 // Implementation of a volume slider with a dynamic range of 60 dB
66 const float volume_scale_factor{std::exp(6.90775f * volume) * 0.001f};
67 for (auto& sample : samples) {
68 sample = static_cast<s16>(sample * volume_scale_factor);
69 }
70}
71
72void Stream::PlayNextBuffer() {
73 if (!IsPlaying()) {
74 // Ensure we are in playing state before playing the next buffer
75 return;
76 }
77
78 if (active_buffer) {
79 // Do not queue a new buffer if we are already playing a buffer
80 return;
81 }
82
83 if (queued_buffers.empty()) {
84 // No queued buffers - we are effectively paused
85 return;
86 }
87
88 active_buffer = queued_buffers.front();
89 queued_buffers.pop();
90
91 VolumeAdjustSamples(active_buffer->Samples());
92 sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
93
94 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
95}
96
97void Stream::ReleaseActiveBuffer() {
98 ASSERT(active_buffer);
99 released_buffers.push(std::move(active_buffer));
100 release_callback();
101 PlayNextBuffer();
102}
103
104bool Stream::QueueBuffer(BufferPtr&& buffer) {
105 if (queued_buffers.size() < MaxAudioBufferCount) {
106 queued_buffers.push(std::move(buffer));
107 PlayNextBuffer();
108 return true;
109 }
110 return false;
111}
112
113bool Stream::ContainsBuffer(Buffer::Tag tag) const {
114 ASSERT_MSG(false, "Unimplemented");
115 return {};
116}
117
118std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) {
119 std::vector<Buffer::Tag> tags;
120 for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) {
121 tags.push_back(released_buffers.front()->GetTag());
122 released_buffers.pop();
123 }
124 return tags;
125}
126
127} // 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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <functional>
8#include <memory>
9#include <string>
10#include <vector>
11#include <queue>
12
13#include "audio_core/buffer.h"
14#include "audio_core/sink_stream.h"
15#include "common/assert.h"
16#include "common/common_types.h"
17#include "core/core_timing.h"
18
19namespace AudioCore {
20
21/**
22 * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
23 */
24class Stream {
25public:
26 /// Audio format of the stream
27 enum class Format {
28 Mono16,
29 Stereo16,
30 Multi51Channel16,
31 };
32
33 /// Callback function type, used to change guest state on a buffer being released
34 using ReleaseCallback = std::function<void()>;
35
36 Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
37 SinkStream& sink_stream, std::string&& name_);
38
39 /// Plays the audio stream
40 void Play();
41
42 /// Stops the audio stream
43 void Stop();
44
45 /// Queues a buffer into the audio stream, returns true on success
46 bool QueueBuffer(BufferPtr&& buffer);
47
48 /// Returns true if the audio stream contains a buffer with the specified tag
49 bool ContainsBuffer(Buffer::Tag tag) const;
50
51 /// Returns a vector of recently released buffers specified by tag
52 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count);
53
54 /// Returns true if the stream is currently playing
55 bool IsPlaying() const {
56 return state == State::Playing;
57 }
58
59 /// Returns the number of queued buffers
60 size_t GetQueueSize() const {
61 return queued_buffers.size();
62 }
63
64 /// Gets the sample rate
65 u32 GetSampleRate() const {
66 return sample_rate;
67 }
68
69 /// Gets the number of channels
70 u32 GetNumChannels() const;
71
72private:
73 /// Current state of the stream
74 enum class State {
75 Stopped,
76 Playing,
77 };
78
79 /// Plays the next queued buffer in the audio stream, starting playback if necessary
80 void PlayNextBuffer();
81
82 /// Releases the actively playing buffer, signalling that it has been completed
83 void ReleaseActiveBuffer();
84
85 /// Gets the number of core cycles when the specified buffer will be released
86 s64 GetBufferReleaseCycles(const Buffer& buffer) const;
87
88 u32 sample_rate; ///< Sample rate of the stream
89 Format format; ///< Format of the stream
90 ReleaseCallback release_callback; ///< Buffer release callback for the stream
91 State state{State::Stopped}; ///< Playback state of the stream
92 CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream
93 BufferPtr active_buffer; ///< Actively playing buffer in the stream
94 std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
95 std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
96 SinkStream& sink_stream; ///< Output sink for the stream
97 std::string name; ///< Name of the stream, must be unique
98};
99
100using StreamPtr = std::shared_ptr<Stream>;
101
102} // 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 @@
6 6
7#include <string> 7#include <string>
8 8
9#if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM) 9#if !defined(ARCHITECTURE_x86_64)
10#include <cstdlib> // for exit 10#include <cstdlib> // for exit
11#endif 11#endif
12#include "common/common_types.h" 12#include "common/common_types.h"
@@ -32,8 +32,6 @@
32 32
33#ifdef ARCHITECTURE_x86_64 33#ifdef ARCHITECTURE_x86_64
34#define Crash() __asm__ __volatile__("int $3") 34#define Crash() __asm__ __volatile__("int $3")
35#elif defined(ARCHITECTURE_ARM)
36#define Crash() __asm__ __volatile__("trap")
37#else 35#else
38#define Crash() exit(1) 36#define Crash() exit(1)
39#endif 37#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 @@
32#define SDMC_DIR "sdmc" 32#define SDMC_DIR "sdmc"
33#define NAND_DIR "nand" 33#define NAND_DIR "nand"
34#define SYSDATA_DIR "sysdata" 34#define SYSDATA_DIR "sysdata"
35#define KEYS_DIR "keys"
35#define LOG_DIR "log" 36#define LOG_DIR "log"
36 37
37// Filenames 38// 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) {
706 paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); 706 paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP);
707 paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); 707 paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP);
708 paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); 708 paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP);
709 paths.emplace(UserPath::KeysDir, user_path + KEYS_DIR DIR_SEP);
709 // TODO: Put the logs in a better location for each OS 710 // TODO: Put the logs in a better location for each OS
710 paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); 711 paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP);
711 } 712 }
@@ -736,6 +737,19 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) {
736 return paths[path]; 737 return paths[path];
737} 738}
738 739
740std::string GetHactoolConfigurationPath() {
741#ifdef _WIN32
742 PWSTR pw_local_path = nullptr;
743 if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pw_local_path) != S_OK)
744 return "";
745 std::string local_path = Common::UTF16ToUTF8(pw_local_path);
746 CoTaskMemFree(pw_local_path);
747 return local_path + "\\.switch";
748#else
749 return GetHomeDirectory() + "/.switch";
750#endif
751}
752
739size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { 753size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) {
740 return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); 754 return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size());
741} 755}
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 {
23enum class UserPath { 23enum class UserPath {
24 CacheDir, 24 CacheDir,
25 ConfigDir, 25 ConfigDir,
26 KeysDir,
26 LogDir, 27 LogDir,
27 NANDDir, 28 NANDDir,
28 RootDir, 29 RootDir,
@@ -125,6 +126,8 @@ bool SetCurrentDir(const std::string& directory);
125// directory. To be used in "multi-user" mode (that is, installed). 126// directory. To be used in "multi-user" mode (that is, installed).
126const std::string& GetUserPath(UserPath path, const std::string& new_path = ""); 127const std::string& GetUserPath(UserPath path, const std::string& new_path = "");
127 128
129std::string GetHactoolConfigurationPath();
130
128// Returns the path to where the sys file are 131// Returns the path to where the sys file are
129std::string GetSysDirectory(); 132std::string GetSysDirectory();
130 133
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) {
168 SUB(Service, AM) \ 168 SUB(Service, AM) \
169 SUB(Service, AOC) \ 169 SUB(Service, AOC) \
170 SUB(Service, APM) \ 170 SUB(Service, APM) \
171 SUB(Service, ARP) \
171 SUB(Service, BCAT) \ 172 SUB(Service, BCAT) \
173 SUB(Service, BPC) \
174 SUB(Service, BTM) \
175 SUB(Service, Capture) \
172 SUB(Service, Fatal) \ 176 SUB(Service, Fatal) \
177 SUB(Service, FGM) \
173 SUB(Service, Friend) \ 178 SUB(Service, Friend) \
174 SUB(Service, FS) \ 179 SUB(Service, FS) \
175 SUB(Service, HID) \ 180 SUB(Service, HID) \
181 SUB(Service, LBL) \
176 SUB(Service, LDN) \ 182 SUB(Service, LDN) \
177 SUB(Service, LM) \ 183 SUB(Service, LM) \
184 SUB(Service, Migration) \
185 SUB(Service, Mii) \
178 SUB(Service, MM) \ 186 SUB(Service, MM) \
187 SUB(Service, NCM) \
188 SUB(Service, NFC) \
179 SUB(Service, NFP) \ 189 SUB(Service, NFP) \
180 SUB(Service, NIFM) \ 190 SUB(Service, NIFM) \
181 SUB(Service, NS) \ 191 SUB(Service, NS) \
182 SUB(Service, NVDRV) \ 192 SUB(Service, NVDRV) \
193 SUB(Service, PCIE) \
183 SUB(Service, PCTL) \ 194 SUB(Service, PCTL) \
195 SUB(Service, PCV) \
184 SUB(Service, PREPO) \ 196 SUB(Service, PREPO) \
197 SUB(Service, PSC) \
185 SUB(Service, SET) \ 198 SUB(Service, SET) \
186 SUB(Service, SM) \ 199 SUB(Service, SM) \
187 SUB(Service, SPL) \ 200 SUB(Service, SPL) \
188 SUB(Service, SSL) \ 201 SUB(Service, SSL) \
189 SUB(Service, Time) \ 202 SUB(Service, Time) \
203 SUB(Service, USB) \
190 SUB(Service, VI) \ 204 SUB(Service, VI) \
205 SUB(Service, WLAN) \
191 CLS(HW) \ 206 CLS(HW) \
192 SUB(HW, Memory) \ 207 SUB(HW, Memory) \
193 SUB(HW, LCD) \ 208 SUB(HW, LCD) \
@@ -204,6 +219,7 @@ void FileBackend::Write(const Entry& entry) {
204 CLS(Input) \ 219 CLS(Input) \
205 CLS(Network) \ 220 CLS(Network) \
206 CLS(Loader) \ 221 CLS(Loader) \
222 CLS(Crypto) \
207 CLS(WebService) 223 CLS(WebService)
208 224
209// GetClassName is a macro defined by Windows.h, grrr... 225// 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 {
54 Service_AM, ///< The AM (Applet manager) service 54 Service_AM, ///< The AM (Applet manager) service
55 Service_AOC, ///< The AOC (AddOn Content) service 55 Service_AOC, ///< The AOC (AddOn Content) service
56 Service_APM, ///< The APM (Performance) service 56 Service_APM, ///< The APM (Performance) service
57 Service_ARP, ///< The ARP service
57 Service_Audio, ///< The Audio (Audio control) service 58 Service_Audio, ///< The Audio (Audio control) service
58 Service_BCAT, ///< The BCAT service 59 Service_BCAT, ///< The BCAT service
60 Service_BPC, ///< The BPC service
61 Service_BTM, ///< The BTM service
62 Service_Capture, ///< The capture service
59 Service_Fatal, ///< The Fatal service 63 Service_Fatal, ///< The Fatal service
64 Service_FGM, ///< The FGM service
60 Service_Friend, ///< The friend service 65 Service_Friend, ///< The friend service
61 Service_FS, ///< The FS (Filesystem) service 66 Service_FS, ///< The FS (Filesystem) service
62 Service_HID, ///< The HID (Human interface device) service 67 Service_HID, ///< The HID (Human interface device) service
68 Service_LBL, ///< The LBL (LCD backlight) service
63 Service_LDN, ///< The LDN (Local domain network) service 69 Service_LDN, ///< The LDN (Local domain network) service
64 Service_LM, ///< The LM (Logger) service 70 Service_LM, ///< The LM (Logger) service
71 Service_Migration, ///< The migration service
72 Service_Mii, ///< The Mii service
65 Service_MM, ///< The MM (Multimedia) service 73 Service_MM, ///< The MM (Multimedia) service
74 Service_NCM, ///< The NCM service
75 Service_NFC, ///< The NFC (Near-field communication) service
66 Service_NFP, ///< The NFP service 76 Service_NFP, ///< The NFP service
67 Service_NIFM, ///< The NIFM (Network interface) service 77 Service_NIFM, ///< The NIFM (Network interface) service
68 Service_NS, ///< The NS services 78 Service_NS, ///< The NS services
69 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 79 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
80 Service_PCIE, ///< The PCIe service
70 Service_PCTL, ///< The PCTL (Parental control) service 81 Service_PCTL, ///< The PCTL (Parental control) service
82 Service_PCV, ///< The PCV service
71 Service_PREPO, ///< The PREPO (Play report) service 83 Service_PREPO, ///< The PREPO (Play report) service
84 Service_PSC, ///< The PSC service
72 Service_SET, ///< The SET (Settings) service 85 Service_SET, ///< The SET (Settings) service
73 Service_SM, ///< The SM (Service manager) service 86 Service_SM, ///< The SM (Service manager) service
74 Service_SPL, ///< The SPL service 87 Service_SPL, ///< The SPL service
75 Service_SSL, ///< The SSL service 88 Service_SSL, ///< The SSL service
76 Service_Time, ///< The time service 89 Service_Time, ///< The time service
90 Service_USB, ///< The USB (Universal Serial Bus) service
77 Service_VI, ///< The VI (Video interface) service 91 Service_VI, ///< The VI (Video interface) service
92 Service_WLAN, ///< The WLAN (Wireless local area network) service
78 HW, ///< Low-level hardware emulation 93 HW, ///< Low-level hardware emulation
79 HW_Memory, ///< Memory-map and address translation 94 HW_Memory, ///< Memory-map and address translation
80 HW_LCD, ///< LCD register emulation 95 HW_LCD, ///< LCD register emulation
@@ -89,6 +104,7 @@ enum class Class : ClassType {
89 Audio_DSP, ///< The HLE implementation of the DSP 104 Audio_DSP, ///< The HLE implementation of the DSP
90 Audio_Sink, ///< Emulator audio output backend 105 Audio_Sink, ///< Emulator audio output backend
91 Loader, ///< ROM loader 106 Loader, ///< ROM loader
107 Crypto, ///< Cryptographic engine/functions
92 Input, ///< Input emulation 108 Input, ///< Input emulation
93 Network, ///< Network emulation 109 Network, ///< Network emulation
94 WebService, ///< Interface to yuzu Web Services 110 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 @@
5#pragma once 5#pragma once
6 6
7#include <cstddef> 7#include <cstddef>
8#include <string>
8 9
9namespace Log { 10namespace Log {
10 11
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
19 19
20template <class T> 20template <class T>
21struct Rectangle { 21struct Rectangle {
22 T left; 22 T left{};
23 T top; 23 T top{};
24 T right; 24 T right{};
25 T bottom; 25 T bottom{};
26 26
27 Rectangle() {} 27 Rectangle() = default;
28 28
29 Rectangle(T left, T top, T right, T bottom) 29 Rectangle(T left, T top, T right, T bottom)
30 : left(left), top(top), right(right), bottom(bottom) {} 30 : 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <cctype> 6#include <cctype>
6#include <cerrno> 7#include <cerrno>
7#include <cstdio> 8#include <cstdio>
8#include <cstdlib> 9#include <cstdlib>
9#include <cstring> 10#include <cstring>
10#include <boost/range/algorithm/transform.hpp>
11#include "common/common_paths.h" 11#include "common/common_paths.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/string_util.h" 13#include "common/string_util.h"
@@ -24,13 +24,15 @@ namespace Common {
24 24
25/// Make a string lowercase 25/// Make a string lowercase
26std::string ToLower(std::string str) { 26std::string ToLower(std::string str) {
27 boost::transform(str, str.begin(), ::tolower); 27 std::transform(str.begin(), str.end(), str.begin(),
28 [](unsigned char c) { return std::tolower(c); });
28 return str; 29 return str;
29} 30}
30 31
31/// Make a string uppercase 32/// Make a string uppercase
32std::string ToUpper(std::string str) { 33std::string ToUpper(std::string str) {
33 boost::transform(str, str.begin(), ::toupper); 34 std::transform(str.begin(), str.end(), str.begin(),
35 [](unsigned char c) { return std::toupper(c); });
34 return str; 36 return str;
35} 37}
36 38
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) {
69inline u64 swap64(u64 _data) { 69inline u64 swap64(u64 _data) {
70 return _byteswap_uint64(_data); 70 return _byteswap_uint64(_data);
71} 71}
72#elif ARCHITECTURE_ARM 72#elif defined(ARCHITECTURE_ARM) && (__ARM_ARCH >= 6)
73inline u16 swap16(u16 _data) { 73inline u16 swap16(u16 _data) {
74 u32 data = _data; 74 u32 data = _data;
75 __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); 75 __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:
33 bool Empty() const { 33 bool Empty() const {
34 return !read_ptr->next.load(); 34 return !read_ptr->next.load();
35 } 35 }
36
36 T& Front() const { 37 T& Front() const {
37 return read_ptr->current; 38 return read_ptr->current;
38 } 39 }
40
39 template <typename Arg> 41 template <typename Arg>
40 void Push(Arg&& t) { 42 void Push(Arg&& t) {
41 // create the element, add it to the queue 43 // create the element, add it to the queue
@@ -108,15 +110,41 @@ private:
108// single reader, multiple writer queue 110// single reader, multiple writer queue
109 111
110template <typename T, bool NeedSize = true> 112template <typename T, bool NeedSize = true>
111class MPSCQueue : public SPSCQueue<T, NeedSize> { 113class MPSCQueue {
112public: 114public:
115 u32 Size() const {
116 return spsc_queue.Size();
117 }
118
119 bool Empty() const {
120 return spsc_queue.Empty();
121 }
122
123 T& Front() const {
124 return spsc_queue.Front();
125 }
126
113 template <typename Arg> 127 template <typename Arg>
114 void Push(Arg&& t) { 128 void Push(Arg&& t) {
115 std::lock_guard<std::mutex> lock(write_lock); 129 std::lock_guard<std::mutex> lock(write_lock);
116 SPSCQueue<T, NeedSize>::Push(t); 130 spsc_queue.Push(t);
131 }
132
133 void Pop() {
134 return spsc_queue.Pop();
135 }
136
137 bool Pop(T& t) {
138 return spsc_queue.Pop(t);
139 }
140
141 // not thread-safe
142 void Clear() {
143 spsc_queue.Clear();
117 } 144 }
118 145
119private: 146private:
147 SPSCQueue<T, NeedSize> spsc_queue;
120 std::mutex write_lock; 148 std::mutex write_lock;
121}; 149};
122} // namespace Common 150} // 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <ctime> 5#include <ctime>
6
7#include <fmt/format.h> 6#include <fmt/format.h>
8
9#ifdef _WIN32
10#include <windows.h>
11// windows.h needs to be included before other windows headers
12#include <mmsystem.h>
13#include <sys/timeb.h>
14#else
15#include <sys/time.h>
16#endif
17#include "common/common_types.h" 7#include "common/common_types.h"
18#include "common/string_util.h" 8#include "common/string_util.h"
19#include "common/timer.h" 9#include "common/timer.h"
20 10
21namespace Common { 11namespace Common {
22 12
23u32 Timer::GetTimeMs() { 13std::chrono::milliseconds Timer::GetTimeMs() {
24#ifdef _WIN32 14 return std::chrono::duration_cast<std::chrono::milliseconds>(
25 return timeGetTime(); 15 std::chrono::system_clock::now().time_since_epoch());
26#else
27 struct timeval t;
28 (void)gettimeofday(&t, nullptr);
29 return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000));
30#endif
31} 16}
32 17
33// -------------------------------------------- 18// --------------------------------------------
@@ -63,7 +48,7 @@ void Timer::Update() {
63// ------------------------------------- 48// -------------------------------------
64 49
65// Get the number of milliseconds since the last Update() 50// Get the number of milliseconds since the last Update()
66u64 Timer::GetTimeDifference() { 51std::chrono::milliseconds Timer::GetTimeDifference() {
67 return GetTimeMs() - m_LastTime; 52 return GetTimeMs() - m_LastTime;
68} 53}
69 54
@@ -74,11 +59,11 @@ void Timer::AddTimeDifference() {
74} 59}
75 60
76// Get the time elapsed since the Start() 61// Get the time elapsed since the Start()
77u64 Timer::GetTimeElapsed() { 62std::chrono::milliseconds Timer::GetTimeElapsed() {
78 // If we have not started yet, return 1 (because then I don't 63 // If we have not started yet, return 1 (because then I don't
79 // have to change the FPS calculation in CoreRerecording.cpp . 64 // have to change the FPS calculation in CoreRerecording.cpp .
80 if (m_StartTime == 0) 65 if (m_StartTime.count() == 0)
81 return 1; 66 return std::chrono::milliseconds(1);
82 67
83 // Return the final timer time if the timer is stopped 68 // Return the final timer time if the timer is stopped
84 if (!m_Running) 69 if (!m_Running)
@@ -90,49 +75,34 @@ u64 Timer::GetTimeElapsed() {
90// Get the formatted time elapsed since the Start() 75// Get the formatted time elapsed since the Start()
91std::string Timer::GetTimeElapsedFormatted() const { 76std::string Timer::GetTimeElapsedFormatted() const {
92 // If we have not started yet, return zero 77 // If we have not started yet, return zero
93 if (m_StartTime == 0) 78 if (m_StartTime.count() == 0)
94 return "00:00:00:000"; 79 return "00:00:00:000";
95 80
96 // The number of milliseconds since the start. 81 // The number of milliseconds since the start.
97 // Use a different value if the timer is stopped. 82 // Use a different value if the timer is stopped.
98 u64 Milliseconds; 83 std::chrono::milliseconds Milliseconds;
99 if (m_Running) 84 if (m_Running)
100 Milliseconds = GetTimeMs() - m_StartTime; 85 Milliseconds = GetTimeMs() - m_StartTime;
101 else 86 else
102 Milliseconds = m_LastTime - m_StartTime; 87 Milliseconds = m_LastTime - m_StartTime;
103 // Seconds 88 // Seconds
104 u32 Seconds = (u32)(Milliseconds / 1000); 89 std::chrono::seconds Seconds = std::chrono::duration_cast<std::chrono::seconds>(Milliseconds);
105 // Minutes 90 // Minutes
106 u32 Minutes = Seconds / 60; 91 std::chrono::minutes Minutes = std::chrono::duration_cast<std::chrono::minutes>(Milliseconds);
107 // Hours 92 // Hours
108 u32 Hours = Minutes / 60; 93 std::chrono::hours Hours = std::chrono::duration_cast<std::chrono::hours>(Milliseconds);
109 94
110 std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours, Minutes % 60, Seconds % 60, 95 std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours.count(), Minutes.count() % 60,
111 Milliseconds % 1000); 96 Seconds.count() % 60, Milliseconds.count() % 1000);
112 return TmpStr; 97 return TmpStr;
113} 98}
114 99
115// Get current time
116void Timer::IncreaseResolution() {
117#ifdef _WIN32
118 timeBeginPeriod(1);
119#endif
120}
121
122void Timer::RestoreResolution() {
123#ifdef _WIN32
124 timeEndPeriod(1);
125#endif
126}
127
128// Get the number of seconds since January 1 1970 100// Get the number of seconds since January 1 1970
129u64 Timer::GetTimeSinceJan1970() { 101std::chrono::seconds Timer::GetTimeSinceJan1970() {
130 time_t ltime; 102 return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs());
131 time(&ltime);
132 return ((u64)ltime);
133} 103}
134 104
135u64 Timer::GetLocalTimeSinceJan1970() { 105std::chrono::seconds Timer::GetLocalTimeSinceJan1970() {
136 time_t sysTime, tzDiff, tzDST; 106 time_t sysTime, tzDiff, tzDST;
137 struct tm* gmTime; 107 struct tm* gmTime;
138 108
@@ -149,7 +119,7 @@ u64 Timer::GetLocalTimeSinceJan1970() {
149 gmTime = gmtime(&sysTime); 119 gmTime = gmtime(&sysTime);
150 tzDiff = sysTime - mktime(gmTime); 120 tzDiff = sysTime - mktime(gmTime);
151 121
152 return (u64)(sysTime + tzDiff + tzDST); 122 return std::chrono::seconds(sysTime + tzDiff + tzDST);
153} 123}
154 124
155// Return the current time formatted as Minutes:Seconds:Milliseconds 125// Return the current time formatted as Minutes:Seconds:Milliseconds
@@ -164,30 +134,16 @@ std::string Timer::GetTimeFormatted() {
164 134
165 strftime(tmp, 6, "%M:%S", gmTime); 135 strftime(tmp, 6, "%M:%S", gmTime);
166 136
167// Now tack on the milliseconds 137 u64 milliseconds = static_cast<u64>(GetTimeMs().count()) % 1000;
168#ifdef _WIN32 138 return fmt::format("{}:{:03}", tmp, milliseconds);
169 struct timeb tp;
170 (void)::ftime(&tp);
171 return fmt::format("{}:{:03}", tmp, tp.millitm);
172#else
173 struct timeval t;
174 (void)gettimeofday(&t, nullptr);
175 return fmt::format("{}:{:03}", tmp, static_cast<int>(t.tv_usec / 1000));
176#endif
177} 139}
178 140
179// Returns a timestamp with decimals for precise time comparisons 141// Returns a timestamp with decimals for precise time comparisons
180// ---------------- 142// ----------------
181double Timer::GetDoubleTime() { 143double Timer::GetDoubleTime() {
182#ifdef _WIN32
183 struct timeb tp;
184 (void)::ftime(&tp);
185#else
186 struct timeval t;
187 (void)gettimeofday(&t, nullptr);
188#endif
189 // Get continuous timestamp 144 // Get continuous timestamp
190 u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); 145 u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count());
146 double ms = static_cast<u64>(GetTimeMs().count()) % 1000;
191 147
192 // Remove a few years. We only really want enough seconds to make 148 // Remove a few years. We only really want enough seconds to make
193 // sure that we are detecting actual actions, perhaps 60 seconds is 149 // sure that we are detecting actual actions, perhaps 60 seconds is
@@ -196,12 +152,7 @@ double Timer::GetDoubleTime() {
196 TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); 152 TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
197 153
198 // Make a smaller integer that fits in the double 154 // Make a smaller integer that fits in the double
199 u32 Seconds = (u32)TmpSeconds; 155 u32 Seconds = static_cast<u32>(TmpSeconds);
200#ifdef _WIN32
201 double ms = tp.millitm / 1000.0 / 1000.0;
202#else
203 double ms = t.tv_usec / 1000000.0;
204#endif
205 double TmpTime = Seconds + ms; 156 double TmpTime = Seconds + ms;
206 157
207 return TmpTime; 158 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <chrono>
7#include <string> 8#include <string>
8#include "common/common_types.h" 9#include "common/common_types.h"
9 10
@@ -18,24 +19,22 @@ public:
18 19
19 // The time difference is always returned in milliseconds, regardless of alternative internal 20 // The time difference is always returned in milliseconds, regardless of alternative internal
20 // representation 21 // representation
21 u64 GetTimeDifference(); 22 std::chrono::milliseconds GetTimeDifference();
22 void AddTimeDifference(); 23 void AddTimeDifference();
23 24
24 static void IncreaseResolution(); 25 static std::chrono::seconds GetTimeSinceJan1970();
25 static void RestoreResolution(); 26 static std::chrono::seconds GetLocalTimeSinceJan1970();
26 static u64 GetTimeSinceJan1970();
27 static u64 GetLocalTimeSinceJan1970();
28 static double GetDoubleTime(); 27 static double GetDoubleTime();
29 28
30 static std::string GetTimeFormatted(); 29 static std::string GetTimeFormatted();
31 std::string GetTimeElapsedFormatted() const; 30 std::string GetTimeElapsedFormatted() const;
32 u64 GetTimeElapsed(); 31 std::chrono::milliseconds GetTimeElapsed();
33 32
34 static u32 GetTimeMs(); 33 static std::chrono::milliseconds GetTimeMs();
35 34
36private: 35private:
37 u64 m_LastTime; 36 std::chrono::milliseconds m_LastTime;
38 u64 m_StartTime; 37 std::chrono::milliseconds m_StartTime;
39 bool m_Running; 38 bool m_Running;
40}; 39};
41 40
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
12 core_timing.h 12 core_timing.h
13 core_timing_util.cpp 13 core_timing_util.cpp
14 core_timing_util.h 14 core_timing_util.h
15 crypto/aes_util.cpp
16 crypto/aes_util.h
17 crypto/encryption_layer.cpp
18 crypto/encryption_layer.h
19 crypto/key_manager.cpp
20 crypto/key_manager.h
21 crypto/ctr_encryption_layer.cpp
22 crypto/ctr_encryption_layer.h
23 file_sys/card_image.cpp
24 file_sys/card_image.h
15 file_sys/content_archive.cpp 25 file_sys/content_archive.cpp
16 file_sys/content_archive.h 26 file_sys/content_archive.h
17 file_sys/control_metadata.cpp 27 file_sys/control_metadata.cpp
@@ -23,6 +33,8 @@ add_library(core STATIC
23 file_sys/partition_filesystem.h 33 file_sys/partition_filesystem.h
24 file_sys/program_metadata.cpp 34 file_sys/program_metadata.cpp
25 file_sys/program_metadata.h 35 file_sys/program_metadata.h
36 file_sys/romfs.cpp
37 file_sys/romfs.h
26 file_sys/romfs_factory.cpp 38 file_sys/romfs_factory.cpp
27 file_sys/romfs_factory.h 39 file_sys/romfs_factory.h
28 file_sys/savedata_factory.cpp 40 file_sys/savedata_factory.cpp
@@ -35,6 +47,8 @@ add_library(core STATIC
35 file_sys/vfs_offset.h 47 file_sys/vfs_offset.h
36 file_sys/vfs_real.cpp 48 file_sys/vfs_real.cpp
37 file_sys/vfs_real.h 49 file_sys/vfs_real.h
50 file_sys/vfs_vector.cpp
51 file_sys/vfs_vector.h
38 frontend/emu_window.cpp 52 frontend/emu_window.cpp
39 frontend/emu_window.h 53 frontend/emu_window.h
40 frontend/framebuffer_layout.cpp 54 frontend/framebuffer_layout.cpp
@@ -59,12 +73,10 @@ add_library(core STATIC
59 hle/kernel/hle_ipc.h 73 hle/kernel/hle_ipc.h
60 hle/kernel/kernel.cpp 74 hle/kernel/kernel.cpp
61 hle/kernel/kernel.h 75 hle/kernel/kernel.h
62 hle/kernel/memory.cpp
63 hle/kernel/memory.h
64 hle/kernel/mutex.cpp 76 hle/kernel/mutex.cpp
65 hle/kernel/mutex.h 77 hle/kernel/mutex.h
66 hle/kernel/object_address_table.cpp 78 hle/kernel/object.cpp
67 hle/kernel/object_address_table.h 79 hle/kernel/object.h
68 hle/kernel/process.cpp 80 hle/kernel/process.cpp
69 hle/kernel/process.h 81 hle/kernel/process.h
70 hle/kernel/resource_limit.cpp 82 hle/kernel/resource_limit.cpp
@@ -110,23 +122,41 @@ add_library(core STATIC
110 hle/service/am/applet_ae.h 122 hle/service/am/applet_ae.h
111 hle/service/am/applet_oe.cpp 123 hle/service/am/applet_oe.cpp
112 hle/service/am/applet_oe.h 124 hle/service/am/applet_oe.h
125 hle/service/am/idle.cpp
126 hle/service/am/idle.h
127 hle/service/am/omm.cpp
128 hle/service/am/omm.h
129 hle/service/am/spsm.cpp
130 hle/service/am/spsm.h
113 hle/service/aoc/aoc_u.cpp 131 hle/service/aoc/aoc_u.cpp
114 hle/service/aoc/aoc_u.h 132 hle/service/aoc/aoc_u.h
115 hle/service/apm/apm.cpp 133 hle/service/apm/apm.cpp
116 hle/service/apm/apm.h 134 hle/service/apm/apm.h
117 hle/service/apm/interface.cpp 135 hle/service/apm/interface.cpp
118 hle/service/apm/interface.h 136 hle/service/apm/interface.h
137 hle/service/arp/arp.cpp
138 hle/service/arp/arp.h
139 hle/service/audio/audctl.cpp
140 hle/service/audio/audctl.h
141 hle/service/audio/auddbg.cpp
142 hle/service/audio/auddbg.h
143 hle/service/audio/audin_a.cpp
144 hle/service/audio/audin_a.h
119 hle/service/audio/audin_u.cpp 145 hle/service/audio/audin_u.cpp
120 hle/service/audio/audin_u.h 146 hle/service/audio/audin_u.h
121 hle/service/audio/audio.cpp 147 hle/service/audio/audio.cpp
122 hle/service/audio/audio.h 148 hle/service/audio/audio.h
149 hle/service/audio/audout_a.cpp
150 hle/service/audio/audout_a.h
123 hle/service/audio/audout_u.cpp 151 hle/service/audio/audout_u.cpp
124 hle/service/audio/audout_u.h 152 hle/service/audio/audout_u.h
153 hle/service/audio/audrec_a.cpp
154 hle/service/audio/audrec_a.h
125 hle/service/audio/audrec_u.cpp 155 hle/service/audio/audrec_u.cpp
126 hle/service/audio/audrec_u.h 156 hle/service/audio/audrec_u.h
157 hle/service/audio/audren_a.cpp
158 hle/service/audio/audren_a.h
127 hle/service/audio/audren_u.cpp 159 hle/service/audio/audren_u.cpp
128 hle/service/audio/audren_u.cpp
129 hle/service/audio/audren_u.h
130 hle/service/audio/audren_u.h 160 hle/service/audio/audren_u.h
131 hle/service/audio/codecctl.cpp 161 hle/service/audio/codecctl.cpp
132 hle/service/audio/codecctl.h 162 hle/service/audio/codecctl.h
@@ -136,6 +166,14 @@ add_library(core STATIC
136 hle/service/bcat/bcat.h 166 hle/service/bcat/bcat.h
137 hle/service/bcat/module.cpp 167 hle/service/bcat/module.cpp
138 hle/service/bcat/module.h 168 hle/service/bcat/module.h
169 hle/service/bpc/bpc.cpp
170 hle/service/bpc/bpc.h
171 hle/service/btdrv/btdrv.cpp
172 hle/service/btdrv/btdrv.h
173 hle/service/btm/btm.cpp
174 hle/service/btm/btm.h
175 hle/service/caps/caps.cpp
176 hle/service/caps/caps.h
139 hle/service/erpt/erpt.cpp 177 hle/service/erpt/erpt.cpp
140 hle/service/erpt/erpt.h 178 hle/service/erpt/erpt.h
141 hle/service/es/es.cpp 179 hle/service/es/es.cpp
@@ -150,8 +188,14 @@ add_library(core STATIC
150 hle/service/fatal/fatal_u.h 188 hle/service/fatal/fatal_u.h
151 hle/service/filesystem/filesystem.cpp 189 hle/service/filesystem/filesystem.cpp
152 hle/service/filesystem/filesystem.h 190 hle/service/filesystem/filesystem.h
191 hle/service/filesystem/fsp_ldr.cpp
192 hle/service/filesystem/fsp_ldr.h
193 hle/service/filesystem/fsp_pr.cpp
194 hle/service/filesystem/fsp_pr.h
153 hle/service/filesystem/fsp_srv.cpp 195 hle/service/filesystem/fsp_srv.cpp
154 hle/service/filesystem/fsp_srv.h 196 hle/service/filesystem/fsp_srv.h
197 hle/service/fgm/fgm.cpp
198 hle/service/fgm/fgm.h
155 hle/service/friend/friend.cpp 199 hle/service/friend/friend.cpp
156 hle/service/friend/friend.h 200 hle/service/friend/friend.h
157 hle/service/friend/interface.cpp 201 hle/service/friend/interface.cpp
@@ -164,14 +208,24 @@ add_library(core STATIC
164 hle/service/hid/irs.h 208 hle/service/hid/irs.h
165 hle/service/hid/xcd.cpp 209 hle/service/hid/xcd.cpp
166 hle/service/hid/xcd.h 210 hle/service/hid/xcd.h
211 hle/service/lbl/lbl.cpp
212 hle/service/lbl/lbl.h
167 hle/service/ldn/ldn.cpp 213 hle/service/ldn/ldn.cpp
168 hle/service/ldn/ldn.h 214 hle/service/ldn/ldn.h
169 hle/service/ldr/ldr.cpp 215 hle/service/ldr/ldr.cpp
170 hle/service/ldr/ldr.h 216 hle/service/ldr/ldr.h
171 hle/service/lm/lm.cpp 217 hle/service/lm/lm.cpp
172 hle/service/lm/lm.h 218 hle/service/lm/lm.h
219 hle/service/mig/mig.cpp
220 hle/service/mig/mig.h
221 hle/service/mii/mii.cpp
222 hle/service/mii/mii.h
173 hle/service/mm/mm_u.cpp 223 hle/service/mm/mm_u.cpp
174 hle/service/mm/mm_u.h 224 hle/service/mm/mm_u.h
225 hle/service/ncm/ncm.cpp
226 hle/service/ncm/ncm.h
227 hle/service/nfc/nfc.cpp
228 hle/service/nfc/nfc.h
175 hle/service/nfp/nfp.cpp 229 hle/service/nfp/nfp.cpp
176 hle/service/nfp/nfp.h 230 hle/service/nfp/nfp.h
177 hle/service/nfp/nfp_user.cpp 231 hle/service/nfp/nfp_user.cpp
@@ -209,14 +263,20 @@ add_library(core STATIC
209 hle/service/nvflinger/buffer_queue.h 263 hle/service/nvflinger/buffer_queue.h
210 hle/service/nvflinger/nvflinger.cpp 264 hle/service/nvflinger/nvflinger.cpp
211 hle/service/nvflinger/nvflinger.h 265 hle/service/nvflinger/nvflinger.h
266 hle/service/pcie/pcie.cpp
267 hle/service/pcie/pcie.h
212 hle/service/pctl/module.cpp 268 hle/service/pctl/module.cpp
213 hle/service/pctl/module.h 269 hle/service/pctl/module.h
214 hle/service/pctl/pctl.cpp 270 hle/service/pctl/pctl.cpp
215 hle/service/pctl/pctl.h 271 hle/service/pctl/pctl.h
272 hle/service/pcv/pcv.cpp
273 hle/service/pcv/pcv.h
216 hle/service/pm/pm.cpp 274 hle/service/pm/pm.cpp
217 hle/service/pm/pm.h 275 hle/service/pm/pm.h
218 hle/service/prepo/prepo.cpp 276 hle/service/prepo/prepo.cpp
219 hle/service/prepo/prepo.h 277 hle/service/prepo/prepo.h
278 hle/service/psc/psc.cpp
279 hle/service/psc/psc.h
220 hle/service/service.cpp 280 hle/service/service.cpp
221 hle/service/service.h 281 hle/service/service.h
222 hle/service/set/set.cpp 282 hle/service/set/set.cpp
@@ -255,6 +315,8 @@ add_library(core STATIC
255 hle/service/time/interface.h 315 hle/service/time/interface.h
256 hle/service/time/time.cpp 316 hle/service/time/time.cpp
257 hle/service/time/time.h 317 hle/service/time/time.h
318 hle/service/usb/usb.cpp
319 hle/service/usb/usb.h
258 hle/service/vi/vi.cpp 320 hle/service/vi/vi.cpp
259 hle/service/vi/vi.h 321 hle/service/vi/vi.h
260 hle/service/vi/vi_m.cpp 322 hle/service/vi/vi_m.cpp
@@ -263,10 +325,8 @@ add_library(core STATIC
263 hle/service/vi/vi_s.h 325 hle/service/vi/vi_s.h
264 hle/service/vi/vi_u.cpp 326 hle/service/vi/vi_u.cpp
265 hle/service/vi/vi_u.h 327 hle/service/vi/vi_u.h
266 hw/hw.cpp 328 hle/service/wlan/wlan.cpp
267 hw/hw.h 329 hle/service/wlan/wlan.h
268 hw/lcd.cpp
269 hw/lcd.h
270 loader/deconstructed_rom_directory.cpp 330 loader/deconstructed_rom_directory.cpp
271 loader/deconstructed_rom_directory.h 331 loader/deconstructed_rom_directory.h
272 loader/elf.cpp 332 loader/elf.cpp
@@ -281,6 +341,8 @@ add_library(core STATIC
281 loader/nro.h 341 loader/nro.h
282 loader/nso.cpp 342 loader/nso.cpp
283 loader/nso.h 343 loader/nso.h
344 loader/xci.cpp
345 loader/xci.h
284 memory.cpp 346 memory.cpp
285 memory.h 347 memory.h
286 memory_hook.cpp 348 memory_hook.cpp
@@ -299,8 +361,8 @@ add_library(core STATIC
299 361
300create_target_directory_groups(core) 362create_target_directory_groups(core)
301 363
302target_link_libraries(core PUBLIC common PRIVATE video_core) 364target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
303target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn) 365target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn)
304 366
305if (ARCHITECTURE_x86_64) 367if (ARCHITECTURE_x86_64)
306 target_sources(core PRIVATE 368 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 @@
10#include "core/arm/dynarmic/arm_dynarmic.h" 10#include "core/arm/dynarmic/arm_dynarmic.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/core_timing.h" 12#include "core/core_timing.h"
13#include "core/hle/kernel/memory.h" 13#include "core/hle/kernel/process.h"
14#include "core/hle/kernel/svc.h" 14#include "core/hle/kernel/svc.h"
15#include "core/memory.h" 15#include "core/memory.h"
16 16
@@ -139,14 +139,12 @@ void ARM_Dynarmic::Step() {
139} 139}
140 140
141ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) 141ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index)
142 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), 142 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index},
143 jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>( 143 exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} {
144 exclusive_monitor)}, 144 ThreadContext ctx;
145 core_index{core_index} {
146 ARM_Interface::ThreadContext ctx;
147 inner_unicorn.SaveContext(ctx); 145 inner_unicorn.SaveContext(ctx);
148 LoadContext(ctx);
149 PageTableChanged(); 146 PageTableChanged();
147 LoadContext(ctx);
150} 148}
151 149
152ARM_Dynarmic::~ARM_Dynarmic() = default; 150ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -205,7 +203,7 @@ u64 ARM_Dynarmic::GetTlsAddress() const {
205 return cb->tpidrro_el0; 203 return cb->tpidrro_el0;
206} 204}
207 205
208void ARM_Dynarmic::SetTlsAddress(u64 address) { 206void ARM_Dynarmic::SetTlsAddress(VAddr address) {
209 cb->tpidrro_el0 = address; 207 cb->tpidrro_el0 = address;
210} 208}
211 209
@@ -217,7 +215,7 @@ void ARM_Dynarmic::SetTPIDR_EL0(u64 value) {
217 cb->tpidr_el0 = value; 215 cb->tpidr_el0 = value;
218} 216}
219 217
220void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { 218void ARM_Dynarmic::SaveContext(ThreadContext& ctx) {
221 ctx.cpu_registers = jit->GetRegisters(); 219 ctx.cpu_registers = jit->GetRegisters();
222 ctx.sp = jit->GetSP(); 220 ctx.sp = jit->GetSP();
223 ctx.pc = jit->GetPC(); 221 ctx.pc = jit->GetPC();
@@ -226,7 +224,7 @@ void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
226 ctx.fpscr = jit->GetFpcr(); 224 ctx.fpscr = jit->GetFpcr();
227} 225}
228 226
229void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { 227void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
230 jit->SetRegisters(ctx.cpu_registers); 228 jit->SetRegisters(ctx.cpu_registers);
231 jit->SetSP(ctx.sp); 229 jit->SetSP(ctx.sp);
232 jit->SetPC(ctx.pc); 230 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) {
203 } 203 }
204 Kernel::Thread* thread = Kernel::GetCurrentThread(); 204 Kernel::Thread* thread = Kernel::GetCurrentThread();
205 SaveContext(thread->context); 205 SaveContext(thread->context);
206 if (last_bkpt_hit || (num_instructions == 1)) { 206 if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
207 last_bkpt_hit = false; 207 last_bkpt_hit = false;
208 GDBStub::Break(); 208 GDBStub::Break();
209 GDBStub::SendTrap(thread, 5); 209 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 @@
15#include "core/hle/service/service.h" 15#include "core/hle/service/service.h"
16#include "core/hle/service/sm/controller.h" 16#include "core/hle/service/sm/controller.h"
17#include "core/hle/service/sm/sm.h" 17#include "core/hle/service/sm/sm.h"
18#include "core/hw/hw.h"
19#include "core/loader/loader.h" 18#include "core/loader/loader.h"
20#include "core/memory_setup.h"
21#include "core/settings.h" 19#include "core/settings.h"
22#include "file_sys/vfs_real.h" 20#include "file_sys/vfs_real.h"
21#include "video_core/renderer_base.h"
23#include "video_core/video_core.h" 22#include "video_core/video_core.h"
24 23
25namespace Core { 24namespace Core {
@@ -63,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
63 // execute. Otherwise, get out of the loop function. 62 // execute. Otherwise, get out of the loop function.
64 if (GDBStub::GetCpuHaltFlag()) { 63 if (GDBStub::GetCpuHaltFlag()) {
65 if (GDBStub::GetCpuStepFlag()) { 64 if (GDBStub::GetCpuStepFlag()) {
66 GDBStub::SetCpuStepFlag(false);
67 tight_loop = false; 65 tight_loop = false;
68 } else { 66 } else {
69 return ResultStatus::Success; 67 return ResultStatus::Success;
@@ -79,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
79 } 77 }
80 } 78 }
81 79
80 if (GDBStub::IsServerEnabled()) {
81 GDBStub::SetCpuStepFlag(false);
82 }
83
82 return status; 84 return status;
83} 85}
84 86
@@ -86,7 +88,7 @@ System::ResultStatus System::SingleStep() {
86 return RunLoop(false); 88 return RunLoop(false);
87} 89}
88 90
89System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { 91System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) {
90 app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); 92 app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath));
91 93
92 if (!app_loader) { 94 if (!app_loader) {
@@ -101,8 +103,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
101 static_cast<int>(system_mode.second)); 103 static_cast<int>(system_mode.second));
102 104
103 switch (system_mode.second) { 105 switch (system_mode.second) {
104 case Loader::ResultStatus::ErrorEncrypted: 106 case Loader::ResultStatus::ErrorMissingKeys:
105 return ResultStatus::ErrorLoader_ErrorEncrypted; 107 return ResultStatus::ErrorLoader_ErrorMissingKeys;
108 case Loader::ResultStatus::ErrorDecrypting:
109 return ResultStatus::ErrorLoader_ErrorDecrypting;
106 case Loader::ResultStatus::ErrorInvalidFormat: 110 case Loader::ResultStatus::ErrorInvalidFormat:
107 return ResultStatus::ErrorLoader_ErrorInvalidFormat; 111 return ResultStatus::ErrorLoader_ErrorInvalidFormat;
108 case Loader::ResultStatus::ErrorUnsupportedArch: 112 case Loader::ResultStatus::ErrorUnsupportedArch:
@@ -112,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
112 } 116 }
113 } 117 }
114 118
115 ResultStatus init_result{Init(emu_window, system_mode.first.get())}; 119 ResultStatus init_result{Init(emu_window)};
116 if (init_result != ResultStatus::Success) { 120 if (init_result != ResultStatus::Success) {
117 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 121 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
118 static_cast<int>(init_result)); 122 static_cast<int>(init_result));
@@ -126,8 +130,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
126 System::Shutdown(); 130 System::Shutdown();
127 131
128 switch (load_result) { 132 switch (load_result) {
129 case Loader::ResultStatus::ErrorEncrypted: 133 case Loader::ResultStatus::ErrorMissingKeys:
130 return ResultStatus::ErrorLoader_ErrorEncrypted; 134 return ResultStatus::ErrorLoader_ErrorMissingKeys;
135 case Loader::ResultStatus::ErrorDecrypting:
136 return ResultStatus::ErrorLoader_ErrorDecrypting;
131 case Loader::ResultStatus::ErrorInvalidFormat: 137 case Loader::ResultStatus::ErrorInvalidFormat:
132 return ResultStatus::ErrorLoader_ErrorInvalidFormat; 138 return ResultStatus::ErrorLoader_ErrorInvalidFormat;
133 case Loader::ResultStatus::ErrorUnsupportedArch: 139 case Loader::ResultStatus::ErrorUnsupportedArch:
@@ -163,7 +169,7 @@ Cpu& System::CpuCore(size_t core_index) {
163 return *cpu_cores[core_index]; 169 return *cpu_cores[core_index];
164} 170}
165 171
166System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { 172System::ResultStatus System::Init(EmuWindow& emu_window) {
167 LOG_DEBUG(HW_Memory, "initialized OK"); 173 LOG_DEBUG(HW_Memory, "initialized OK");
168 174
169 CoreTiming::Init(); 175 CoreTiming::Init();
@@ -176,19 +182,20 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
176 cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); 182 cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index);
177 } 183 }
178 184
179 gpu_core = std::make_unique<Tegra::GPU>();
180 telemetry_session = std::make_unique<Core::TelemetrySession>(); 185 telemetry_session = std::make_unique<Core::TelemetrySession>();
181 service_manager = std::make_shared<Service::SM::ServiceManager>(); 186 service_manager = std::make_shared<Service::SM::ServiceManager>();
182 187
183 HW::Init(); 188 Kernel::Init();
184 Kernel::Init(system_mode);
185 Service::Init(service_manager); 189 Service::Init(service_manager);
186 GDBStub::Init(); 190 GDBStub::Init();
187 191
188 if (!VideoCore::Init(emu_window)) { 192 renderer = VideoCore::CreateRenderer(emu_window);
193 if (!renderer->Init()) {
189 return ResultStatus::ErrorVideoCore; 194 return ResultStatus::ErrorVideoCore;
190 } 195 }
191 196
197 gpu_core = std::make_unique<Tegra::GPU>(renderer->Rasterizer());
198
192 // Create threads for CPU cores 1-3, and build thread_to_cpu map 199 // Create threads for CPU cores 1-3, and build thread_to_cpu map
193 // CPU core 0 is run on the main thread 200 // CPU core 0 is run on the main thread
194 thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; 201 thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
@@ -220,11 +227,10 @@ void System::Shutdown() {
220 perf_results.frametime * 1000.0); 227 perf_results.frametime * 1000.0);
221 228
222 // Shutdown emulation session 229 // Shutdown emulation session
223 VideoCore::Shutdown(); 230 renderer.reset();
224 GDBStub::Shutdown(); 231 GDBStub::Shutdown();
225 Service::Shutdown(); 232 Service::Shutdown();
226 Kernel::Shutdown(); 233 Kernel::Shutdown();
227 HW::Shutdown();
228 service_manager.reset(); 234 service_manager.reset();
229 telemetry_session.reset(); 235 telemetry_session.reset();
230 gpu_core.reset(); 236 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 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/arm/exclusive_monitor.h" 12#include "core/arm/exclusive_monitor.h"
13#include "core/core_cpu.h" 13#include "core/core_cpu.h"
14#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/scheduler.h" 15#include "core/hle/kernel/scheduler.h"
16#include "core/loader/loader.h" 16#include "core/loader/loader.h"
17#include "core/memory.h" 17#include "core/memory.h"
@@ -27,6 +27,10 @@ namespace Service::SM {
27class ServiceManager; 27class ServiceManager;
28} 28}
29 29
30namespace VideoCore {
31class RendererBase;
32}
33
30namespace Core { 34namespace Core {
31 35
32class System { 36class System {
@@ -43,12 +47,14 @@ public:
43 47
44 /// Enumeration representing the return values of the System Initialize and Load process. 48 /// Enumeration representing the return values of the System Initialize and Load process.
45 enum class ResultStatus : u32 { 49 enum class ResultStatus : u32 {
46 Success, ///< Succeeded 50 Success, ///< Succeeded
47 ErrorNotInitialized, ///< Error trying to use core prior to initialization 51 ErrorNotInitialized, ///< Error trying to use core prior to initialization
48 ErrorGetLoader, ///< Error finding the correct application loader 52 ErrorGetLoader, ///< Error finding the correct application loader
49 ErrorSystemMode, ///< Error determining the system mode 53 ErrorSystemMode, ///< Error determining the system mode
50 ErrorLoader, ///< Error loading the specified application 54 ErrorLoader, ///< Error loading the specified application
51 ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption 55 ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be
56 ///< found.
57 ErrorLoader_ErrorDecrypting, ///< Error loading the specified application due to encryption
52 ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an 58 ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
53 /// invalid format 59 /// invalid format
54 ErrorSystemFiles, ///< Error in finding system files 60 ErrorSystemFiles, ///< Error in finding system files
@@ -76,16 +82,28 @@ public:
76 */ 82 */
77 ResultStatus SingleStep(); 83 ResultStatus SingleStep();
78 84
85 /**
86 * Invalidate the CPU instruction caches
87 * This function should only be used by GDB Stub to support breakpoints, memory updates and
88 * step/continue commands.
89 */
90 void InvalidateCpuInstructionCaches() {
91 for (auto& cpu : cpu_cores) {
92 cpu->ArmInterface().ClearInstructionCache();
93 }
94 }
95
79 /// Shutdown the emulated system. 96 /// Shutdown the emulated system.
80 void Shutdown(); 97 void Shutdown();
81 98
82 /** 99 /**
83 * Load an executable application. 100 * Load an executable application.
84 * @param emu_window Pointer to the host-system window used for video output and keyboard input. 101 * @param emu_window Reference to the host-system window used for video output and keyboard
102 * input.
85 * @param filepath String path to the executable application to load on the host file system. 103 * @param filepath String path to the executable application to load on the host file system.
86 * @returns ResultStatus code, indicating if the operation succeeded. 104 * @returns ResultStatus code, indicating if the operation succeeded.
87 */ 105 */
88 ResultStatus Load(EmuWindow* emu_window, const std::string& filepath); 106 ResultStatus Load(EmuWindow& emu_window, const std::string& filepath);
89 107
90 /** 108 /**
91 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an 109 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -126,11 +144,26 @@ public:
126 /// Gets a CPU interface to the CPU core with the specified index 144 /// Gets a CPU interface to the CPU core with the specified index
127 Cpu& CpuCore(size_t core_index); 145 Cpu& CpuCore(size_t core_index);
128 146
129 /// Gets the GPU interface 147 /// Gets a mutable reference to the GPU interface
130 Tegra::GPU& GPU() { 148 Tegra::GPU& GPU() {
131 return *gpu_core; 149 return *gpu_core;
132 } 150 }
133 151
152 /// Gets an immutable reference to the GPU interface.
153 const Tegra::GPU& GPU() const {
154 return *gpu_core;
155 }
156
157 /// Gets a mutable reference to the renderer.
158 VideoCore::RendererBase& Renderer() {
159 return *renderer;
160 }
161
162 /// Gets an immutable reference to the renderer.
163 const VideoCore::RendererBase& Renderer() const {
164 return *renderer;
165 }
166
134 /// Gets the scheduler for the CPU core that is currently running 167 /// Gets the scheduler for the CPU core that is currently running
135 Kernel::Scheduler& CurrentScheduler() { 168 Kernel::Scheduler& CurrentScheduler() {
136 return *CurrentCpuCore().Scheduler(); 169 return *CurrentCpuCore().Scheduler();
@@ -186,14 +219,15 @@ private:
186 219
187 /** 220 /**
188 * Initialize the emulated system. 221 * Initialize the emulated system.
189 * @param emu_window Pointer to the host-system window used for video output and keyboard input. 222 * @param emu_window Reference to the host-system window used for video output and keyboard
190 * @param system_mode The system mode. 223 * input.
191 * @return ResultStatus code, indicating if the operation succeeded. 224 * @return ResultStatus code, indicating if the operation succeeded.
192 */ 225 */
193 ResultStatus Init(EmuWindow* emu_window, u32 system_mode); 226 ResultStatus Init(EmuWindow& emu_window);
194 227
195 /// AppLoader used to load the current executing application 228 /// AppLoader used to load the current executing application
196 std::unique_ptr<Loader::AppLoader> app_loader; 229 std::unique_ptr<Loader::AppLoader> app_loader;
230 std::unique_ptr<VideoCore::RendererBase> renderer;
197 std::unique_ptr<Tegra::GPU> gpu_core; 231 std::unique_ptr<Tegra::GPU> gpu_core;
198 std::shared_ptr<Tegra::DebugContext> debug_context; 232 std::shared_ptr<Tegra::DebugContext> debug_context;
199 Kernel::SharedPtr<Kernel::Process> current_process; 233 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 @@
12#include "core/arm/unicorn/arm_unicorn.h" 12#include "core/arm/unicorn/arm_unicorn.h"
13#include "core/core_cpu.h" 13#include "core/core_cpu.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/scheduler.h" 15#include "core/hle/kernel/scheduler.h"
17#include "core/hle/kernel/thread.h" 16#include "core/hle/kernel/thread.h"
18#include "core/settings.h" 17#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
141 ForceExceptionCheck(cycles_into_future); 141 ForceExceptionCheck(cycles_into_future);
142 142
143 event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); 143 event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type});
144 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); 144 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
145} 145}
146 146
147void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) { 147void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) {
@@ -156,7 +156,7 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) {
156 // Removing random items breaks the invariant so we have to re-establish it. 156 // Removing random items breaks the invariant so we have to re-establish it.
157 if (itr != event_queue.end()) { 157 if (itr != event_queue.end()) {
158 event_queue.erase(itr, event_queue.end()); 158 event_queue.erase(itr, event_queue.end());
159 std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); 159 std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
160 } 160 }
161} 161}
162 162
@@ -167,7 +167,7 @@ void RemoveEvent(const EventType* event_type) {
167 // Removing random items breaks the invariant so we have to re-establish it. 167 // Removing random items breaks the invariant so we have to re-establish it.
168 if (itr != event_queue.end()) { 168 if (itr != event_queue.end()) {
169 event_queue.erase(itr, event_queue.end()); 169 event_queue.erase(itr, event_queue.end());
170 std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); 170 std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
171 } 171 }
172} 172}
173 173
@@ -190,7 +190,7 @@ void MoveEvents() {
190 for (Event ev; ts_queue.Pop(ev);) { 190 for (Event ev; ts_queue.Pop(ev);) {
191 ev.fifo_order = event_fifo_id++; 191 ev.fifo_order = event_fifo_id++;
192 event_queue.emplace_back(std::move(ev)); 192 event_queue.emplace_back(std::move(ev));
193 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); 193 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
194 } 194 }
195} 195}
196 196
@@ -205,7 +205,7 @@ void Advance() {
205 205
206 while (!event_queue.empty() && event_queue.front().time <= global_timer) { 206 while (!event_queue.empty() && event_queue.front().time <= global_timer) {
207 Event evt = std::move(event_queue.front()); 207 Event evt = std::move(event_queue.front());
208 std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); 208 std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
209 event_queue.pop_back(); 209 event_queue.pop_back();
210 evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time)); 210 evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time));
211 } 211 }
@@ -226,8 +226,8 @@ void Idle() {
226 downcount = 0; 226 downcount = 0;
227} 227}
228 228
229u64 GetGlobalTimeUs() { 229std::chrono::microseconds GetGlobalTimeUs() {
230 return GetTicks() * 1000000 / BASE_CLOCK_RATE; 230 return std::chrono::microseconds{GetTicks() * 1000000 / BASE_CLOCK_RATE};
231} 231}
232 232
233int GetDowncount() { 233int 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 @@
17 * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") 17 * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever")
18 */ 18 */
19 19
20#include <chrono>
20#include <functional> 21#include <functional>
21#include <string> 22#include <string>
22#include "common/common_types.h" 23#include "common/common_types.h"
23 24
24namespace CoreTiming { 25namespace CoreTiming {
25 26
27struct EventType;
28
29using TimedCallback = std::function<void(u64 userdata, int cycles_late)>;
30
26/** 31/**
27 * CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is 32 * CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is
28 * required to end slice -1 and start slice 0 before the first cycle of code is executed. 33 * required to end slice -1 and start slice 0 before the first cycle of code is executed.
@@ -30,8 +35,6 @@ namespace CoreTiming {
30void Init(); 35void Init();
31void Shutdown(); 36void Shutdown();
32 37
33typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback;
34
35/** 38/**
36 * This should only be called from the emu thread, if you are calling it any other thread, you are 39 * This should only be called from the emu thread, if you are calling it any other thread, you are
37 * doing something evil 40 * doing something evil
@@ -40,8 +43,6 @@ u64 GetTicks();
40u64 GetIdleTicks(); 43u64 GetIdleTicks();
41void AddTicks(u64 ticks); 44void AddTicks(u64 ticks);
42 45
43struct EventType;
44
45/** 46/**
46 * Returns the event_type identifier. if name is not unique, it will assert. 47 * Returns the event_type identifier. if name is not unique, it will assert.
47 */ 48 */
@@ -86,7 +87,7 @@ void ClearPendingEvents();
86 87
87void ForceExceptionCheck(s64 cycles); 88void ForceExceptionCheck(s64 cycles);
88 89
89u64 GetGlobalTimeUs(); 90std::chrono::microseconds GetGlobalTimeUs();
90 91
91int GetDowncount(); 92int GetDowncount();
92 93
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <mbedtls/cipher.h>
6#include "common/assert.h"
7#include "common/logging/log.h"
8#include "core/crypto/aes_util.h"
9#include "core/crypto/key_manager.h"
10
11namespace Core::Crypto {
12namespace {
13std::vector<u8> CalculateNintendoTweak(size_t sector_id) {
14 std::vector<u8> out(0x10);
15 for (size_t i = 0xF; i <= 0xF; --i) {
16 out[i] = sector_id & 0xFF;
17 sector_id >>= 8;
18 }
19 return out;
20}
21} // Anonymous namespace
22
23static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR),
24 "CTR has incorrect value.");
25static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB),
26 "ECB has incorrect value.");
27static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS),
28 "XTS has incorrect value.");
29
30// Structure to hide mbedtls types from header file
31struct CipherContext {
32 mbedtls_cipher_context_t encryption_context;
33 mbedtls_cipher_context_t decryption_context;
34};
35
36template <typename Key, size_t KeySize>
37Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
38 : ctx(std::make_unique<CipherContext>()) {
39 mbedtls_cipher_init(&ctx->encryption_context);
40 mbedtls_cipher_init(&ctx->decryption_context);
41
42 ASSERT_MSG((mbedtls_cipher_setup(
43 &ctx->encryption_context,
44 mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode))) ||
45 mbedtls_cipher_setup(
46 &ctx->decryption_context,
47 mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode)))) == 0,
48 "Failed to initialize mbedtls ciphers.");
49
50 ASSERT(
51 !mbedtls_cipher_setkey(&ctx->encryption_context, key.data(), KeySize * 8, MBEDTLS_ENCRYPT));
52 ASSERT(
53 !mbedtls_cipher_setkey(&ctx->decryption_context, key.data(), KeySize * 8, MBEDTLS_DECRYPT));
54 //"Failed to set key on mbedtls ciphers.");
55}
56
57template <typename Key, size_t KeySize>
58AESCipher<Key, KeySize>::~AESCipher() {
59 mbedtls_cipher_free(&ctx->encryption_context);
60 mbedtls_cipher_free(&ctx->decryption_context);
61}
62
63template <typename Key, size_t KeySize>
64void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) {
65 ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) ||
66 mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0,
67 "Failed to set IV on mbedtls ciphers.");
68}
69
70template <typename Key, size_t KeySize>
71void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) const {
72 auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context;
73
74 mbedtls_cipher_reset(context);
75
76 size_t written = 0;
77 if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) {
78 mbedtls_cipher_update(context, src, size, dest, &written);
79 if (written != size) {
80 LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.",
81 size, written);
82 }
83 } else {
84 const auto block_size = mbedtls_cipher_get_block_size(context);
85
86 for (size_t offset = 0; offset < size; offset += block_size) {
87 auto length = std::min<size_t>(block_size, size - offset);
88 mbedtls_cipher_update(context, src + offset, length, dest + offset, &written);
89 if (written != length) {
90 LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.",
91 length, written);
92 }
93 }
94 }
95
96 mbedtls_cipher_finish(context, nullptr, nullptr);
97}
98
99template <typename Key, size_t KeySize>
100void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id,
101 size_t sector_size, Op op) {
102 if (size % sector_size > 0) {
103 LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size.");
104 return;
105 }
106
107 for (size_t i = 0; i < size; i += sector_size) {
108 SetIV(CalculateNintendoTweak(sector_id++));
109 Transcode<u8, u8>(src + i, sector_size, dest + i, op);
110 }
111}
112
113template class AESCipher<Key128>;
114template class AESCipher<Key256>;
115} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <type_traits>
9#include <vector>
10#include "common/common_types.h"
11#include "core/file_sys/vfs.h"
12
13namespace Core::Crypto {
14
15struct CipherContext;
16
17enum class Mode {
18 CTR = 11,
19 ECB = 2,
20 XTS = 70,
21};
22
23enum class Op {
24 Encrypt,
25 Decrypt,
26};
27
28template <typename Key, size_t KeySize = sizeof(Key)>
29class AESCipher {
30 static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8.");
31 static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256.");
32
33public:
34 AESCipher(Key key, Mode mode);
35
36 ~AESCipher();
37
38 void SetIV(std::vector<u8> iv);
39
40 template <typename Source, typename Dest>
41 void Transcode(const Source* src, size_t size, Dest* dest, Op op) const {
42 static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
43 "Transcode source and destination types must be trivially copyable.");
44 Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op);
45 }
46
47 void Transcode(const u8* src, size_t size, u8* dest, Op op) const;
48
49 template <typename Source, typename Dest>
50 void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id,
51 size_t sector_size, Op op) {
52 static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
53 "XTSTranscode source and destination types must be trivially copyable.");
54 XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id,
55 sector_size, op);
56 }
57
58 void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size,
59 Op op);
60
61private:
62 std::unique_ptr<CipherContext> ctx;
63};
64} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include "common/assert.h"
7#include "core/crypto/ctr_encryption_layer.h"
8
9namespace Core::Crypto {
10
11CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, size_t base_offset)
12 : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR),
13 iv(16, 0) {}
14
15size_t CTREncryptionLayer::Read(u8* data, size_t length, size_t offset) const {
16 if (length == 0)
17 return 0;
18
19 const auto sector_offset = offset & 0xF;
20 if (sector_offset == 0) {
21 UpdateIV(base_offset + offset);
22 std::vector<u8> raw = base->ReadBytes(length, offset);
23 if (raw.size() != length)
24 return Read(data, raw.size(), offset);
25 cipher.Transcode(raw.data(), length, data, Op::Decrypt);
26 return length;
27 }
28
29 // offset does not fall on block boundary (0x10)
30 std::vector<u8> block = base->ReadBytes(0x10, offset - sector_offset);
31 UpdateIV(base_offset + offset - sector_offset);
32 cipher.Transcode(block.data(), block.size(), block.data(), Op::Decrypt);
33 size_t read = 0x10 - sector_offset;
34
35 if (length + sector_offset < 0x10) {
36 std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read));
37 return read;
38 }
39 std::memcpy(data, block.data() + sector_offset, read);
40 return read + Read(data + read, length - read, offset + read);
41}
42
43void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) {
44 const auto length = std::min(iv_.size(), iv.size());
45 iv.assign(iv_.cbegin(), iv_.cbegin() + length);
46}
47
48void CTREncryptionLayer::UpdateIV(size_t offset) const {
49 offset >>= 4;
50 for (size_t i = 0; i < 8; ++i) {
51 iv[16 - i - 1] = offset & 0xFF;
52 offset >>= 8;
53 }
54 cipher.SetIV(iv);
55}
56} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <vector>
8#include "core/crypto/aes_util.h"
9#include "core/crypto/encryption_layer.h"
10#include "core/crypto/key_manager.h"
11
12namespace Core::Crypto {
13
14// Sits on top of a VirtualFile and provides CTR-mode AES decription.
15class CTREncryptionLayer : public EncryptionLayer {
16public:
17 CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, size_t base_offset);
18
19 size_t Read(u8* data, size_t length, size_t offset) const override;
20
21 void SetIV(const std::vector<u8>& iv);
22
23private:
24 size_t base_offset;
25
26 // Must be mutable as operations modify cipher contexts.
27 mutable AESCipher<Key128> cipher;
28 mutable std::vector<u8> iv;
29
30 void UpdateIV(size_t offset) const;
31};
32
33} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/crypto/encryption_layer.h"
6
7namespace Core::Crypto {
8
9EncryptionLayer::EncryptionLayer(FileSys::VirtualFile base_) : base(std::move(base_)) {}
10
11std::string EncryptionLayer::GetName() const {
12 return base->GetName();
13}
14
15size_t EncryptionLayer::GetSize() const {
16 return base->GetSize();
17}
18
19bool EncryptionLayer::Resize(size_t new_size) {
20 return false;
21}
22
23std::shared_ptr<FileSys::VfsDirectory> EncryptionLayer::GetContainingDirectory() const {
24 return base->GetContainingDirectory();
25}
26
27bool EncryptionLayer::IsWritable() const {
28 return false;
29}
30
31bool EncryptionLayer::IsReadable() const {
32 return true;
33}
34
35size_t EncryptionLayer::Write(const u8* data, size_t length, size_t offset) {
36 return 0;
37}
38
39bool EncryptionLayer::Rename(std::string_view name) {
40 return base->Rename(name);
41}
42} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "core/file_sys/vfs.h"
9
10namespace Core::Crypto {
11
12// Basically non-functional class that implements all of the methods that are irrelevant to an
13// EncryptionLayer. Reduces duplicate code.
14class EncryptionLayer : public FileSys::VfsFile {
15public:
16 explicit EncryptionLayer(FileSys::VirtualFile base);
17
18 size_t Read(u8* data, size_t length, size_t offset) const override = 0;
19
20 std::string GetName() const override;
21 size_t GetSize() const override;
22 bool Resize(size_t new_size) override;
23 std::shared_ptr<FileSys::VfsDirectory> GetContainingDirectory() const override;
24 bool IsWritable() const override;
25 bool IsReadable() const override;
26 size_t Write(const u8* data, size_t length, size_t offset) override;
27 bool Rename(std::string_view name) override;
28
29protected:
30 FileSys::VirtualFile base;
31};
32
33} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <array>
7#include <fstream>
8#include <locale>
9#include <sstream>
10#include <string_view>
11#include "common/common_paths.h"
12#include "common/file_util.h"
13#include "core/crypto/key_manager.h"
14#include "core/settings.h"
15
16namespace Core::Crypto {
17
18static u8 ToHexNibble(char c1) {
19 if (c1 >= 65 && c1 <= 70)
20 return c1 - 55;
21 if (c1 >= 97 && c1 <= 102)
22 return c1 - 87;
23 if (c1 >= 48 && c1 <= 57)
24 return c1 - 48;
25 throw std::logic_error("Invalid hex digit");
26}
27
28template <size_t Size>
29static std::array<u8, Size> HexStringToArray(std::string_view str) {
30 std::array<u8, Size> out{};
31 for (size_t i = 0; i < 2 * Size; i += 2) {
32 auto d1 = str[i];
33 auto d2 = str[i + 1];
34 out[i / 2] = (ToHexNibble(d1) << 4) | ToHexNibble(d2);
35 }
36 return out;
37}
38
39std::array<u8, 16> operator""_array16(const char* str, size_t len) {
40 if (len != 32)
41 throw std::logic_error("Not of correct size.");
42 return HexStringToArray<16>(str);
43}
44
45std::array<u8, 32> operator""_array32(const char* str, size_t len) {
46 if (len != 64)
47 throw std::logic_error("Not of correct size.");
48 return HexStringToArray<32>(str);
49}
50
51KeyManager::KeyManager() {
52 // Initialize keys
53 const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
54 const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
55 if (Settings::values.use_dev_keys) {
56 dev_mode = true;
57 AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false);
58 } else {
59 dev_mode = false;
60 AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false);
61 }
62
63 AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true);
64}
65
66void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
67 std::ifstream file(filename);
68 if (!file.is_open())
69 return;
70
71 std::string line;
72 while (std::getline(file, line)) {
73 std::vector<std::string> out;
74 std::stringstream stream(line);
75 std::string item;
76 while (std::getline(stream, item, '='))
77 out.push_back(std::move(item));
78
79 if (out.size() != 2)
80 continue;
81
82 out[0].erase(std::remove(out[0].begin(), out[0].end(), ' '), out[0].end());
83 out[1].erase(std::remove(out[1].begin(), out[1].end(), ' '), out[1].end());
84
85 if (is_title_keys) {
86 auto rights_id_raw = HexStringToArray<16>(out[0]);
87 u128 rights_id{};
88 std::memcpy(rights_id.data(), rights_id_raw.data(), rights_id_raw.size());
89 Key128 key = HexStringToArray<16>(out[1]);
90 SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
91 } else {
92 std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower);
93 if (s128_file_id.find(out[0]) != s128_file_id.end()) {
94 const auto index = s128_file_id.at(out[0]);
95 Key128 key = HexStringToArray<16>(out[1]);
96 SetKey(index.type, key, index.field1, index.field2);
97 } else if (s256_file_id.find(out[0]) != s256_file_id.end()) {
98 const auto index = s256_file_id.at(out[0]);
99 Key256 key = HexStringToArray<32>(out[1]);
100 SetKey(index.type, key, index.field1, index.field2);
101 }
102 }
103 }
104}
105
106void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
107 const std::string& filename, bool title) {
108 if (FileUtil::Exists(dir1 + DIR_SEP + filename))
109 LoadFromFile(dir1 + DIR_SEP + filename, title);
110 else if (FileUtil::Exists(dir2 + DIR_SEP + filename))
111 LoadFromFile(dir2 + DIR_SEP + filename, title);
112}
113
114bool KeyManager::HasKey(S128KeyType id, u64 field1, u64 field2) const {
115 return s128_keys.find({id, field1, field2}) != s128_keys.end();
116}
117
118bool KeyManager::HasKey(S256KeyType id, u64 field1, u64 field2) const {
119 return s256_keys.find({id, field1, field2}) != s256_keys.end();
120}
121
122Key128 KeyManager::GetKey(S128KeyType id, u64 field1, u64 field2) const {
123 if (!HasKey(id, field1, field2))
124 return {};
125 return s128_keys.at({id, field1, field2});
126}
127
128Key256 KeyManager::GetKey(S256KeyType id, u64 field1, u64 field2) const {
129 if (!HasKey(id, field1, field2))
130 return {};
131 return s256_keys.at({id, field1, field2});
132}
133
134void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
135 s128_keys[{id, field1, field2}] = key;
136}
137
138void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
139 s256_keys[{id, field1, field2}] = key;
140}
141
142bool KeyManager::KeyFileExists(bool title) {
143 const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
144 const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
145 if (title) {
146 return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") ||
147 FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys");
148 }
149
150 if (Settings::values.use_dev_keys) {
151 return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") ||
152 FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys");
153 }
154
155 return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") ||
156 FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys");
157}
158
159const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = {
160 {"master_key_00", {S128KeyType::Master, 0, 0}},
161 {"master_key_01", {S128KeyType::Master, 1, 0}},
162 {"master_key_02", {S128KeyType::Master, 2, 0}},
163 {"master_key_03", {S128KeyType::Master, 3, 0}},
164 {"master_key_04", {S128KeyType::Master, 4, 0}},
165 {"package1_key_00", {S128KeyType::Package1, 0, 0}},
166 {"package1_key_01", {S128KeyType::Package1, 1, 0}},
167 {"package1_key_02", {S128KeyType::Package1, 2, 0}},
168 {"package1_key_03", {S128KeyType::Package1, 3, 0}},
169 {"package1_key_04", {S128KeyType::Package1, 4, 0}},
170 {"package2_key_00", {S128KeyType::Package2, 0, 0}},
171 {"package2_key_01", {S128KeyType::Package2, 1, 0}},
172 {"package2_key_02", {S128KeyType::Package2, 2, 0}},
173 {"package2_key_03", {S128KeyType::Package2, 3, 0}},
174 {"package2_key_04", {S128KeyType::Package2, 4, 0}},
175 {"titlekek_00", {S128KeyType::Titlekek, 0, 0}},
176 {"titlekek_01", {S128KeyType::Titlekek, 1, 0}},
177 {"titlekek_02", {S128KeyType::Titlekek, 2, 0}},
178 {"titlekek_03", {S128KeyType::Titlekek, 3, 0}},
179 {"titlekek_04", {S128KeyType::Titlekek, 4, 0}},
180 {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}},
181 {"key_area_key_application_00",
182 {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Application)}},
183 {"key_area_key_application_01",
184 {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Application)}},
185 {"key_area_key_application_02",
186 {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Application)}},
187 {"key_area_key_application_03",
188 {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Application)}},
189 {"key_area_key_application_04",
190 {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Application)}},
191 {"key_area_key_ocean_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Ocean)}},
192 {"key_area_key_ocean_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Ocean)}},
193 {"key_area_key_ocean_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Ocean)}},
194 {"key_area_key_ocean_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Ocean)}},
195 {"key_area_key_ocean_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Ocean)}},
196 {"key_area_key_system_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::System)}},
197 {"key_area_key_system_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::System)}},
198 {"key_area_key_system_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::System)}},
199 {"key_area_key_system_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::System)}},
200 {"key_area_key_system_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::System)}},
201};
202
203const std::unordered_map<std::string, KeyIndex<S256KeyType>> KeyManager::s256_file_id = {
204 {"header_key", {S256KeyType::Header, 0, 0}},
205 {"sd_card_save_key", {S256KeyType::SDSave, 0, 0}},
206 {"sd_card_nca_key", {S256KeyType::SDNCA, 0, 0}},
207};
208} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <string>
9#include <type_traits>
10#include <unordered_map>
11#include <vector>
12#include <fmt/format.h>
13#include "common/common_types.h"
14
15namespace Core::Crypto {
16
17using Key128 = std::array<u8, 0x10>;
18using Key256 = std::array<u8, 0x20>;
19using SHA256Hash = std::array<u8, 0x20>;
20
21static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
22static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big.");
23
24enum class S256KeyType : u64 {
25 Header, //
26 SDSave, //
27 SDNCA, //
28};
29
30enum class S128KeyType : u64 {
31 Master, // f1=crypto revision
32 Package1, // f1=crypto revision
33 Package2, // f1=crypto revision
34 Titlekek, // f1=crypto revision
35 ETicketRSAKek, //
36 KeyArea, // f1=crypto revision f2=type {app, ocean, system}
37 SDSeed, //
38 Titlekey, // f1=rights id LSB f2=rights id MSB
39};
40
41enum class KeyAreaKeyType : u8 {
42 Application,
43 Ocean,
44 System,
45};
46
47template <typename KeyType>
48struct KeyIndex {
49 KeyType type;
50 u64 field1;
51 u64 field2;
52
53 std::string DebugInfo() const {
54 u8 key_size = 16;
55 if constexpr (std::is_same_v<KeyType, S256KeyType>)
56 key_size = 32;
57 return fmt::format("key_size={:02X}, key={:02X}, field1={:016X}, field2={:016X}", key_size,
58 static_cast<u8>(type), field1, field2);
59 }
60};
61
62// The following two (== and hash) are so KeyIndex can be a key in unordered_map
63
64template <typename KeyType>
65bool operator==(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
66 return std::tie(lhs.type, lhs.field1, lhs.field2) == std::tie(rhs.type, rhs.field1, rhs.field2);
67}
68
69template <typename KeyType>
70bool operator!=(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
71 return !operator==(lhs, rhs);
72}
73
74} // namespace Core::Crypto
75
76namespace std {
77template <typename KeyType>
78struct hash<Core::Crypto::KeyIndex<KeyType>> {
79 size_t operator()(const Core::Crypto::KeyIndex<KeyType>& k) const {
80 using std::hash;
81
82 return ((hash<u64>()(static_cast<u64>(k.type)) ^ (hash<u64>()(k.field1) << 1)) >> 1) ^
83 (hash<u64>()(k.field2) << 1);
84 }
85};
86} // namespace std
87
88namespace Core::Crypto {
89
90std::array<u8, 0x10> operator"" _array16(const char* str, size_t len);
91std::array<u8, 0x20> operator"" _array32(const char* str, size_t len);
92
93class KeyManager {
94public:
95 KeyManager();
96
97 bool HasKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
98 bool HasKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
99
100 Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
101 Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
102
103 void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
104 void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
105
106 static bool KeyFileExists(bool title);
107
108private:
109 std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys;
110 std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys;
111
112 bool dev_mode;
113 void LoadFromFile(const std::string& filename, bool is_title_keys);
114 void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
115 const std::string& filename, bool title);
116
117 static const std::unordered_map<std::string, KeyIndex<S128KeyType>> s128_file_id;
118 static const std::unordered_map<std::string, KeyIndex<S256KeyType>> s256_file_id;
119};
120} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5namespace 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/assert.h"
8#include "core/file_sys/vfs.h"
9#include "key_manager.h"
10#include "mbedtls/cipher.h"
11
12namespace Crypto {
13typedef std::array<u8, 0x20> SHA256Hash;
14
15inline SHA256Hash operator"" _HASH(const char* data, size_t len) {
16 if (len != 0x40)
17 return {};
18}
19
20} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6#include <string>
7#include <core/loader/loader.h>
8#include "core/file_sys/card_image.h"
9#include "core/file_sys/partition_filesystem.h"
10#include "core/file_sys/vfs_offset.h"
11
12namespace FileSys {
13
14XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {
15 if (file->ReadObject(&header) != sizeof(GamecardHeader)) {
16 status = Loader::ResultStatus::ErrorInvalidFormat;
17 return;
18 }
19
20 if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) {
21 status = Loader::ResultStatus::ErrorInvalidFormat;
22 return;
23 }
24
25 PartitionFilesystem main_hfs(
26 std::make_shared<OffsetVfsFile>(file, header.hfs_size, header.hfs_offset));
27
28 if (main_hfs.GetStatus() != Loader::ResultStatus::Success) {
29 status = main_hfs.GetStatus();
30 return;
31 }
32
33 static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure",
34 "logo"};
35
36 for (XCIPartition partition :
37 {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) {
38 auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]);
39 if (raw != nullptr)
40 partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw);
41 }
42
43 auto result = AddNCAFromPartition(XCIPartition::Secure);
44 if (result != Loader::ResultStatus::Success) {
45 status = result;
46 return;
47 }
48
49 result = AddNCAFromPartition(XCIPartition::Update);
50 if (result != Loader::ResultStatus::Success) {
51 status = result;
52 return;
53 }
54
55 result = AddNCAFromPartition(XCIPartition::Normal);
56 if (result != Loader::ResultStatus::Success) {
57 status = result;
58 return;
59 }
60
61 if (GetFormatVersion() >= 0x2) {
62 result = AddNCAFromPartition(XCIPartition::Logo);
63 if (result != Loader::ResultStatus::Success) {
64 status = result;
65 return;
66 }
67 }
68
69 status = Loader::ResultStatus::Success;
70}
71
72Loader::ResultStatus XCI::GetStatus() const {
73 return status;
74}
75
76VirtualDir XCI::GetPartition(XCIPartition partition) const {
77 return partitions[static_cast<size_t>(partition)];
78}
79
80VirtualDir XCI::GetSecurePartition() const {
81 return GetPartition(XCIPartition::Secure);
82}
83
84VirtualDir XCI::GetNormalPartition() const {
85 return GetPartition(XCIPartition::Normal);
86}
87
88VirtualDir XCI::GetUpdatePartition() const {
89 return GetPartition(XCIPartition::Update);
90}
91
92VirtualDir XCI::GetLogoPartition() const {
93 return GetPartition(XCIPartition::Logo);
94}
95
96std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const {
97 const auto iter =
98 std::find_if(ncas.begin(), ncas.end(),
99 [type](const std::shared_ptr<NCA>& nca) { return nca->GetType() == type; });
100 return iter == ncas.end() ? nullptr : *iter;
101}
102
103VirtualFile XCI::GetNCAFileByType(NCAContentType type) const {
104 auto nca = GetNCAByType(type);
105 if (nca != nullptr)
106 return nca->GetBaseFile();
107 return nullptr;
108}
109
110std::vector<std::shared_ptr<VfsFile>> XCI::GetFiles() const {
111 return {};
112}
113
114std::vector<std::shared_ptr<VfsDirectory>> XCI::GetSubdirectories() const {
115 return std::vector<std::shared_ptr<VfsDirectory>>();
116}
117
118std::string XCI::GetName() const {
119 return file->GetName();
120}
121
122std::shared_ptr<VfsDirectory> XCI::GetParentDirectory() const {
123 return file->GetContainingDirectory();
124}
125
126bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
127 return false;
128}
129
130Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
131 if (partitions[static_cast<size_t>(part)] == nullptr) {
132 return Loader::ResultStatus::ErrorInvalidFormat;
133 }
134
135 for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) {
136 if (file->GetExtension() != "nca")
137 continue;
138 auto nca = std::make_shared<NCA>(file);
139 if (nca->GetStatus() == Loader::ResultStatus::Success)
140 ncas.push_back(std::move(nca));
141 }
142
143 return Loader::ResultStatus::Success;
144}
145
146u8 XCI::GetFormatVersion() const {
147 return GetLogoPartition() == nullptr ? 0x1 : 0x2;
148}
149} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <vector>
9#include "common/common_types.h"
10#include "common/swap.h"
11#include "core/file_sys/content_archive.h"
12#include "core/file_sys/vfs.h"
13#include "core/loader/loader.h"
14
15namespace FileSys {
16
17enum class GamecardSize : u8 {
18 S_1GB = 0xFA,
19 S_2GB = 0xF8,
20 S_4GB = 0xF0,
21 S_8GB = 0xE0,
22 S_16GB = 0xE1,
23 S_32GB = 0xE2,
24};
25
26struct GamecardInfo {
27 std::array<u8, 0x70> data;
28};
29static_assert(sizeof(GamecardInfo) == 0x70, "GamecardInfo has incorrect size.");
30
31struct GamecardHeader {
32 std::array<u8, 0x100> signature;
33 u32_le magic;
34 u32_le secure_area_start;
35 u32_le backup_area_start;
36 u8 kek_index;
37 GamecardSize size;
38 u8 header_version;
39 u8 flags;
40 u64_le package_id;
41 u64_le valid_data_end;
42 u128 info_iv;
43 u64_le hfs_offset;
44 u64_le hfs_size;
45 std::array<u8, 0x20> hfs_header_hash;
46 std::array<u8, 0x20> initial_data_hash;
47 u32_le secure_mode_flag;
48 u32_le title_key_flag;
49 u32_le key_flag;
50 u32_le normal_area_end;
51 GamecardInfo info;
52};
53static_assert(sizeof(GamecardHeader) == 0x200, "GamecardHeader has incorrect size.");
54
55enum class XCIPartition : u8 { Update, Normal, Secure, Logo };
56
57class XCI : public ReadOnlyVfsDirectory {
58public:
59 explicit XCI(VirtualFile file);
60
61 Loader::ResultStatus GetStatus() const;
62
63 u8 GetFormatVersion() const;
64
65 VirtualDir GetPartition(XCIPartition partition) const;
66 VirtualDir GetSecurePartition() const;
67 VirtualDir GetNormalPartition() const;
68 VirtualDir GetUpdatePartition() const;
69 VirtualDir GetLogoPartition() const;
70
71 std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
72 VirtualFile GetNCAFileByType(NCAContentType type) const;
73
74 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
75
76 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
77
78 std::string GetName() const override;
79
80 std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
81
82protected:
83 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
84
85private:
86 Loader::ResultStatus AddNCAFromPartition(XCIPartition part);
87
88 VirtualFile file;
89 GamecardHeader header{};
90
91 Loader::ResultStatus status;
92
93 std::vector<VirtualDir> partitions;
94 std::vector<std::shared_ptr<NCA>> ncas;
95};
96} // 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 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <utility> 6#include <utility>
7 7#include <boost/optional.hpp>
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/crypto/aes_util.h"
10#include "core/crypto/ctr_encryption_layer.h"
9#include "core/file_sys/content_archive.h" 11#include "core/file_sys/content_archive.h"
12#include "core/file_sys/romfs.h"
10#include "core/file_sys/vfs_offset.h" 13#include "core/file_sys/vfs_offset.h"
11#include "core/loader/loader.h" 14#include "core/loader/loader.h"
12 15
@@ -28,11 +31,19 @@ enum class NCASectionFilesystemType : u8 {
28struct NCASectionHeaderBlock { 31struct NCASectionHeaderBlock {
29 INSERT_PADDING_BYTES(3); 32 INSERT_PADDING_BYTES(3);
30 NCASectionFilesystemType filesystem_type; 33 NCASectionFilesystemType filesystem_type;
31 u8 crypto_type; 34 NCASectionCryptoType crypto_type;
32 INSERT_PADDING_BYTES(3); 35 INSERT_PADDING_BYTES(3);
33}; 36};
34static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); 37static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size.");
35 38
39struct NCASectionRaw {
40 NCASectionHeaderBlock header;
41 std::array<u8, 0x138> block_data;
42 std::array<u8, 0x8> section_ctr;
43 INSERT_PADDING_BYTES(0xB8);
44};
45static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size.");
46
36struct PFS0Superblock { 47struct PFS0Superblock {
37 NCASectionHeaderBlock header_block; 48 NCASectionHeaderBlock header_block;
38 std::array<u8, 0x20> hash; 49 std::array<u8, 0x20> hash;
@@ -42,79 +53,200 @@ struct PFS0Superblock {
42 u64_le hash_table_size; 53 u64_le hash_table_size;
43 u64_le pfs0_header_offset; 54 u64_le pfs0_header_offset;
44 u64_le pfs0_size; 55 u64_le pfs0_size;
45 INSERT_PADDING_BYTES(432); 56 INSERT_PADDING_BYTES(0x1B0);
46}; 57};
47static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); 58static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size.");
48 59
49struct IVFCLevel {
50 u64_le offset;
51 u64_le size;
52 u32_le block_size;
53 u32_le reserved;
54};
55static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
56
57struct RomFSSuperblock { 60struct RomFSSuperblock {
58 NCASectionHeaderBlock header_block; 61 NCASectionHeaderBlock header_block;
59 u32_le magic; 62 IVFCHeader ivfc;
60 u32_le magic_number; 63 INSERT_PADDING_BYTES(0x118);
61 INSERT_PADDING_BYTES(8);
62 std::array<IVFCLevel, 6> levels;
63 INSERT_PADDING_BYTES(64);
64}; 64};
65static_assert(sizeof(RomFSSuperblock) == 0xE8, "RomFSSuperblock has incorrect size."); 65static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size.");
66
67union NCASectionHeader {
68 NCASectionRaw raw;
69 PFS0Superblock pfs0;
70 RomFSSuperblock romfs;
71};
72static_assert(sizeof(NCASectionHeader) == 0x200, "NCASectionHeader has incorrect size.");
73
74bool IsValidNCA(const NCAHeader& header) {
75 // TODO(DarkLordZach): Add NCA2/NCA0 support.
76 return header.magic == Common::MakeMagic('N', 'C', 'A', '3');
77}
78
79u8 NCA::GetCryptoRevision() const {
80 u8 master_key_id = header.crypto_type;
81 if (header.crypto_type_2 > master_key_id)
82 master_key_id = header.crypto_type_2;
83 if (master_key_id > 0)
84 --master_key_id;
85 return master_key_id;
86}
87
88boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
89 const auto master_key_id = GetCryptoRevision();
90
91 if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index))
92 return boost::none;
93
94 std::vector<u8> key_area(header.key_area.begin(), header.key_area.end());
95 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
96 keys.GetKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index),
97 Core::Crypto::Mode::ECB);
98 cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt);
99
100 Core::Crypto::Key128 out;
101 if (type == NCASectionCryptoType::XTS)
102 std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin());
103 else if (type == NCASectionCryptoType::CTR)
104 std::copy(key_area.begin() + 0x20, key_area.begin() + 0x30, out.begin());
105 else
106 LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}",
107 static_cast<u8>(type));
108 u128 out_128{};
109 memcpy(out_128.data(), out.data(), 16);
110 LOG_DEBUG(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}",
111 master_key_id, header.key_index, out_128[1], out_128[0]);
112
113 return out;
114}
115
116boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() const {
117 const auto master_key_id = GetCryptoRevision();
118
119 u128 rights_id{};
120 memcpy(rights_id.data(), header.rights_id.data(), 16);
121 if (rights_id == u128{})
122 return boost::none;
123
124 auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]);
125 if (titlekey == Core::Crypto::Key128{})
126 return boost::none;
127 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
128 keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB);
129 cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt);
130
131 return titlekey;
132}
133
134VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) const {
135 if (!encrypted)
136 return in;
137
138 switch (s_header.raw.header.crypto_type) {
139 case NCASectionCryptoType::NONE:
140 LOG_DEBUG(Crypto, "called with mode=NONE");
141 return in;
142 case NCASectionCryptoType::CTR:
143 LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset);
144 {
145 boost::optional<Core::Crypto::Key128> key = boost::none;
146 if (std::find_if_not(header.rights_id.begin(), header.rights_id.end(),
147 [](char c) { return c == 0; }) == header.rights_id.end()) {
148 key = GetKeyAreaKey(NCASectionCryptoType::CTR);
149 } else {
150 key = GetTitlekey();
151 }
152
153 if (key == boost::none)
154 return nullptr;
155 auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(
156 std::move(in), key.value(), starting_offset);
157 std::vector<u8> iv(16);
158 for (u8 i = 0; i < 8; ++i)
159 iv[i] = s_header.raw.section_ctr[0x8 - i - 1];
160 out->SetIV(iv);
161 return std::static_pointer_cast<VfsFile>(out);
162 }
163 case NCASectionCryptoType::XTS:
164 // TODO(DarkLordZach): Implement XTSEncryptionLayer.
165 default:
166 LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}",
167 static_cast<u8>(s_header.raw.header.crypto_type));
168 return nullptr;
169 }
170}
66 171
67NCA::NCA(VirtualFile file_) : file(std::move(file_)) { 172NCA::NCA(VirtualFile file_) : file(std::move(file_)) {
68 if (sizeof(NCAHeader) != file->ReadObject(&header)) 173 if (sizeof(NCAHeader) != file->ReadObject(&header))
69 LOG_CRITICAL(Loader, "File reader errored out during header read."); 174 LOG_ERROR(Loader, "File reader errored out during header read.");
175
176 encrypted = false;
70 177
71 if (!IsValidNCA(header)) { 178 if (!IsValidNCA(header)) {
72 status = Loader::ResultStatus::ErrorInvalidFormat; 179 NCAHeader dec_header{};
73 return; 180 Core::Crypto::AESCipher<Core::Crypto::Key256> cipher(
181 keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS);
182 cipher.XTSTranscode(&header, sizeof(NCAHeader), &dec_header, 0, 0x200,
183 Core::Crypto::Op::Decrypt);
184 if (IsValidNCA(dec_header)) {
185 header = dec_header;
186 encrypted = true;
187 } else {
188 if (!keys.HasKey(Core::Crypto::S256KeyType::Header))
189 status = Loader::ResultStatus::ErrorMissingKeys;
190 else
191 status = Loader::ResultStatus::ErrorDecrypting;
192 return;
193 }
74 } 194 }
75 195
76 std::ptrdiff_t number_sections = 196 const std::ptrdiff_t number_sections =
77 std::count_if(std::begin(header.section_tables), std::end(header.section_tables), 197 std::count_if(std::begin(header.section_tables), std::end(header.section_tables),
78 [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); 198 [](NCASectionTableEntry entry) { return entry.media_offset > 0; });
79 199
200 std::vector<NCASectionHeader> sections(number_sections);
201 const auto length_sections = SECTION_HEADER_SIZE * number_sections;
202
203 if (encrypted) {
204 auto raw = file->ReadBytes(length_sections, SECTION_HEADER_OFFSET);
205 Core::Crypto::AESCipher<Core::Crypto::Key256> cipher(
206 keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS);
207 cipher.XTSTranscode(raw.data(), length_sections, sections.data(), 2, SECTION_HEADER_SIZE,
208 Core::Crypto::Op::Decrypt);
209 } else {
210 file->ReadBytes(sections.data(), length_sections, SECTION_HEADER_OFFSET);
211 }
212
80 for (std::ptrdiff_t i = 0; i < number_sections; ++i) { 213 for (std::ptrdiff_t i = 0; i < number_sections; ++i) {
81 // Seek to beginning of this section. 214 auto section = sections[i];
82 NCASectionHeaderBlock block{};
83 if (sizeof(NCASectionHeaderBlock) !=
84 file->ReadObject(&block, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE))
85 LOG_CRITICAL(Loader, "File reader errored out during header read.");
86
87 if (block.filesystem_type == NCASectionFilesystemType::ROMFS) {
88 RomFSSuperblock sb{};
89 if (sizeof(RomFSSuperblock) !=
90 file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE))
91 LOG_CRITICAL(Loader, "File reader errored out during header read.");
92 215
216 if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) {
93 const size_t romfs_offset = 217 const size_t romfs_offset =
94 header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER + 218 header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER +
95 sb.levels[IVFC_MAX_LEVEL - 1].offset; 219 section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
96 const size_t romfs_size = sb.levels[IVFC_MAX_LEVEL - 1].size; 220 const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
97 files.emplace_back(std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset)); 221 auto dec =
98 romfs = files.back(); 222 Decrypt(section, std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset),
99 } else if (block.filesystem_type == NCASectionFilesystemType::PFS0) { 223 romfs_offset);
100 PFS0Superblock sb{}; 224 if (dec != nullptr) {
101 // Seek back to beginning of this section. 225 files.push_back(std::move(dec));
102 if (sizeof(PFS0Superblock) != 226 romfs = files.back();
103 file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE)) 227 } else {
104 LOG_CRITICAL(Loader, "File reader errored out during header read."); 228 status = Loader::ResultStatus::ErrorMissingKeys;
105 229 return;
230 }
231 } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) {
106 u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * 232 u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) *
107 MEDIA_OFFSET_MULTIPLIER) + 233 MEDIA_OFFSET_MULTIPLIER) +
108 sb.pfs0_header_offset; 234 section.pfs0.pfs0_header_offset;
109 u64 size = MEDIA_OFFSET_MULTIPLIER * (header.section_tables[i].media_end_offset - 235 u64 size = MEDIA_OFFSET_MULTIPLIER * (header.section_tables[i].media_end_offset -
110 header.section_tables[i].media_offset); 236 header.section_tables[i].media_offset);
111 auto npfs = std::make_shared<PartitionFilesystem>( 237 auto dec =
112 std::make_shared<OffsetVfsFile>(file, size, offset)); 238 Decrypt(section, std::make_shared<OffsetVfsFile>(file, size, offset), offset);
239 if (dec != nullptr) {
240 auto npfs = std::make_shared<PartitionFilesystem>(std::move(dec));
113 241
114 if (npfs->GetStatus() == Loader::ResultStatus::Success) { 242 if (npfs->GetStatus() == Loader::ResultStatus::Success) {
115 dirs.emplace_back(npfs); 243 dirs.push_back(std::move(npfs));
116 if (IsDirectoryExeFS(dirs.back())) 244 if (IsDirectoryExeFS(dirs.back()))
117 exefs = dirs.back(); 245 exefs = dirs.back();
246 }
247 } else {
248 status = Loader::ResultStatus::ErrorMissingKeys;
249 return;
118 } 250 }
119 } 251 }
120 } 252 }
@@ -164,6 +296,10 @@ VirtualDir NCA::GetExeFS() const {
164 return exefs; 296 return exefs;
165} 297}
166 298
299VirtualFile NCA::GetBaseFile() const {
300 return file;
301}
302
167bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { 303bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
168 return false; 304 return false;
169} 305}
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 @@
8#include <memory> 8#include <memory>
9#include <string> 9#include <string>
10#include <vector> 10#include <vector>
11 11#include <boost/optional.hpp>
12#include "common/common_funcs.h" 12#include "common/common_funcs.h"
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/crypto/key_manager.h"
15#include "core/file_sys/partition_filesystem.h" 16#include "core/file_sys/partition_filesystem.h"
17#include "core/loader/loader.h"
16 18
17namespace FileSys { 19namespace FileSys {
18 20
21union NCASectionHeader;
22
19enum class NCAContentType : u8 { 23enum class NCAContentType : u8 {
20 Program = 0, 24 Program = 0,
21 Meta = 1, 25 Meta = 1,
@@ -24,6 +28,13 @@ enum class NCAContentType : u8 {
24 Data = 4, 28 Data = 4,
25}; 29};
26 30
31enum class NCASectionCryptoType : u8 {
32 NONE = 1,
33 XTS = 2,
34 CTR = 3,
35 BKTR = 4,
36};
37
27struct NCASectionTableEntry { 38struct NCASectionTableEntry {
28 u32_le media_offset; 39 u32_le media_offset;
29 u32_le media_end_offset; 40 u32_le media_end_offset;
@@ -48,7 +59,7 @@ struct NCAHeader {
48 std::array<u8, 0x10> rights_id; 59 std::array<u8, 0x10> rights_id;
49 std::array<NCASectionTableEntry, 0x4> section_tables; 60 std::array<NCASectionTableEntry, 0x4> section_tables;
50 std::array<std::array<u8, 0x20>, 0x4> hash_tables; 61 std::array<std::array<u8, 0x20>, 0x4> hash_tables;
51 std::array<std::array<u8, 0x10>, 0x4> key_area; 62 std::array<u8, 0x40> key_area;
52 INSERT_PADDING_BYTES(0xC0); 63 INSERT_PADDING_BYTES(0xC0);
53}; 64};
54static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size."); 65static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
@@ -58,10 +69,7 @@ inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) {
58 return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; 69 return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
59} 70}
60 71
61inline bool IsValidNCA(const NCAHeader& header) { 72bool IsValidNCA(const NCAHeader& header);
62 return header.magic == Common::MakeMagic('N', 'C', 'A', '2') ||
63 header.magic == Common::MakeMagic('N', 'C', 'A', '3');
64}
65 73
66// An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. 74// An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner.
67// After construction, use GetStatus to determine if the file is valid and ready to be used. 75// After construction, use GetStatus to determine if the file is valid and ready to be used.
@@ -81,10 +89,17 @@ public:
81 VirtualFile GetRomFS() const; 89 VirtualFile GetRomFS() const;
82 VirtualDir GetExeFS() const; 90 VirtualDir GetExeFS() const;
83 91
92 VirtualFile GetBaseFile() const;
93
84protected: 94protected:
85 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; 95 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
86 96
87private: 97private:
98 u8 GetCryptoRevision() const;
99 boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const;
100 boost::optional<Core::Crypto::Key128> GetTitlekey() const;
101 VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const;
102
88 std::vector<VirtualDir> dirs; 103 std::vector<VirtualDir> dirs;
89 std::vector<VirtualFile> files; 104 std::vector<VirtualFile> files;
90 105
@@ -95,6 +110,10 @@ private:
95 NCAHeader header{}; 110 NCAHeader header{};
96 111
97 Loader::ResultStatus status{}; 112 Loader::ResultStatus status{};
113
114 bool encrypted;
115
116 Core::Crypto::KeyManager keys;
98}; 117};
99 118
100} // namespace FileSys 119} // 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 {
97 LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic); 97 LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
98 LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries); 98 LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
99 for (u32 i = 0; i < pfs_header.num_entries; i++) { 99 for (u32 i = 0; i < pfs_header.num_entries; i++) {
100 LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i, 100 LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
101 pfs_files[i]->GetName(), pfs_files[i]->GetSize(), 101 pfs_files[i]->GetName(), pfs_files[i]->GetSize());
102 dynamic_cast<OffsetVfsFile*>(pfs_files[i].get())->GetOffset());
103 } 102 }
104} 103}
105 104
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/swap.h"
7#include "core/file_sys/romfs.h"
8#include "core/file_sys/vfs.h"
9#include "core/file_sys/vfs_offset.h"
10#include "core/file_sys/vfs_vector.h"
11
12namespace FileSys {
13
14constexpr u32 ROMFS_ENTRY_EMPTY = 0xFFFFFFFF;
15
16struct TableLocation {
17 u64_le offset;
18 u64_le size;
19};
20static_assert(sizeof(TableLocation) == 0x10, "TableLocation has incorrect size.");
21
22struct RomFSHeader {
23 u64_le header_size;
24 TableLocation directory_hash;
25 TableLocation directory_meta;
26 TableLocation file_hash;
27 TableLocation file_meta;
28 u64_le data_offset;
29};
30static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size.");
31
32struct DirectoryEntry {
33 u32_le sibling;
34 u32_le child_dir;
35 u32_le child_file;
36 u32_le hash;
37 u32_le name_length;
38};
39static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size.");
40
41struct FileEntry {
42 u32_le parent;
43 u32_le sibling;
44 u64_le offset;
45 u64_le size;
46 u32_le hash;
47 u32_le name_length;
48};
49static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size.");
50
51template <typename Entry>
52static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t offset) {
53 Entry entry{};
54 if (file->ReadObject(&entry, offset) != sizeof(Entry))
55 return {};
56 std::string string(entry.name_length, '\0');
57 if (file->ReadArray(&string[0], string.size(), offset + sizeof(Entry)) != string.size())
58 return {};
59 return {entry, string};
60}
61
62void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 this_file_offset,
63 std::shared_ptr<VectorVfsDirectory> parent) {
64 while (true) {
65 auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
66
67 parent->AddFile(std::make_shared<OffsetVfsFile>(
68 file, entry.first.size, entry.first.offset + data_offset, entry.second, parent));
69
70 if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
71 break;
72
73 this_file_offset = entry.first.sibling;
74 }
75}
76
77void ProcessDirectory(VirtualFile file, size_t dir_offset, size_t file_offset, size_t data_offset,
78 u32 this_dir_offset, std::shared_ptr<VectorVfsDirectory> parent) {
79 while (true) {
80 auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
81 auto current = std::make_shared<VectorVfsDirectory>(
82 std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parent, entry.second);
83
84 if (entry.first.child_file != ROMFS_ENTRY_EMPTY) {
85 ProcessFile(file, file_offset, data_offset, entry.first.child_file, current);
86 }
87
88 if (entry.first.child_dir != ROMFS_ENTRY_EMPTY) {
89 ProcessDirectory(file, dir_offset, file_offset, data_offset, entry.first.child_dir,
90 current);
91 }
92
93 parent->AddDirectory(current);
94 if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
95 break;
96 this_dir_offset = entry.first.sibling;
97 }
98}
99
100VirtualDir ExtractRomFS(VirtualFile file) {
101 RomFSHeader header{};
102 if (file->ReadObject(&header) != sizeof(RomFSHeader))
103 return nullptr;
104
105 if (header.header_size != sizeof(RomFSHeader))
106 return nullptr;
107
108 const u64 file_offset = header.file_meta.offset;
109 const u64 dir_offset = header.directory_meta.offset + 4;
110
111 const auto root =
112 std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{},
113 file->GetContainingDirectory(), file->GetName());
114
115 ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root);
116
117 VirtualDir out = std::move(root);
118
119 while (out->GetSubdirectory("") != nullptr)
120 out = out->GetSubdirectory("");
121
122 return out;
123}
124} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include "common/common_funcs.h"
9#include "common/swap.h"
10#include "core/file_sys/vfs.h"
11
12namespace FileSys {
13
14struct IVFCLevel {
15 u64_le offset;
16 u64_le size;
17 u32_le block_size;
18 u32_le reserved;
19};
20static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
21
22struct IVFCHeader {
23 u32_le magic;
24 u32_le magic_number;
25 INSERT_PADDING_BYTES(8);
26 std::array<IVFCLevel, 6> levels;
27 INSERT_PADDING_BYTES(64);
28};
29static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
30
31// Converts a RomFS binary blob to VFS Filesystem
32// Returns nullptr on failure
33VirtualDir ExtractRomFS(VirtualFile file);
34
35} // 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) {
46 return Write(data.data(), data.size(), offset); 46 return Write(data.data(), data.size(), offset);
47} 47}
48 48
49std::string VfsFile::GetFullPath() const {
50 if (GetContainingDirectory() == nullptr)
51 return "/" + GetName();
52
53 return GetContainingDirectory()->GetFullPath() + "/" + GetName();
54}
55
49std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const { 56std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const {
50 auto vec = FileUtil::SplitPathComponents(path); 57 auto vec = FileUtil::SplitPathComponents(path);
51 vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), 58 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) {
243 return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize(); 250 return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize();
244} 251}
245 252
253std::string VfsDirectory::GetFullPath() const {
254 if (IsRoot())
255 return GetName();
256
257 return GetParentDirectory()->GetFullPath() + "/" + GetName();
258}
259
246bool ReadOnlyVfsDirectory::IsWritable() const { 260bool ReadOnlyVfsDirectory::IsWritable() const {
247 return false; 261 return false;
248} 262}
@@ -270,4 +284,33 @@ bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
270bool ReadOnlyVfsDirectory::Rename(std::string_view name) { 284bool ReadOnlyVfsDirectory::Rename(std::string_view name) {
271 return false; 285 return false;
272} 286}
287
288bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size) {
289 if (file1->GetSize() != file2->GetSize())
290 return false;
291
292 std::vector<u8> f1_v(block_size);
293 std::vector<u8> f2_v(block_size);
294 for (size_t i = 0; i < file1->GetSize(); i += block_size) {
295 auto f1_vs = file1->Read(f1_v.data(), block_size, i);
296 auto f2_vs = file2->Read(f2_v.data(), block_size, i);
297
298 if (f1_vs != f2_vs)
299 return false;
300 auto iters = std::mismatch(f1_v.begin(), f1_v.end(), f2_v.begin(), f2_v.end());
301 if (iters.first != f1_v.end() && iters.second != f2_v.end())
302 return false;
303 }
304
305 return true;
306}
307
308bool VfsRawCopy(VirtualFile src, VirtualFile dest) {
309 if (src == nullptr || dest == nullptr)
310 return false;
311 if (!dest->Resize(src->GetSize()))
312 return false;
313 std::vector<u8> data = src->ReadAllBytes();
314 return dest->WriteBytes(data, 0) == data.size();
315}
273} // namespace FileSys 316} // 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 {
113 113
114 // Renames the file to name. Returns whether or not the operation was successsful. 114 // Renames the file to name. Returns whether or not the operation was successsful.
115 virtual bool Rename(std::string_view name) = 0; 115 virtual bool Rename(std::string_view name) = 0;
116
117 // Returns the full path of this file as a string, recursively
118 virtual std::string GetFullPath() const;
116}; 119};
117 120
118// A class representing a directory in an abstract filesystem. 121// A class representing a directory in an abstract filesystem.
@@ -213,6 +216,17 @@ struct VfsDirectory : NonCopyable {
213 return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p)); 216 return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p));
214 } 217 }
215 218
219 bool InterpretAsDirectory(const std::function<VirtualDir(VirtualFile)>& function,
220 const std::string& file) {
221 auto file_p = GetFile(file);
222 if (file_p == nullptr)
223 return false;
224 return ReplaceFileWithSubdirectory(file_p, function(file_p));
225 }
226
227 // Returns the full path of this directory as a string, recursively
228 virtual std::string GetFullPath() const;
229
216protected: 230protected:
217 // Backend for InterpretAsDirectory. 231 // Backend for InterpretAsDirectory.
218 // Removes all references to file and adds a reference to dir in the directory's implementation. 232 // Removes all references to file and adds a reference to dir in the directory's implementation.
@@ -230,4 +244,13 @@ struct ReadOnlyVfsDirectory : public VfsDirectory {
230 bool DeleteFile(std::string_view name) override; 244 bool DeleteFile(std::string_view name) override;
231 bool Rename(std::string_view name) override; 245 bool Rename(std::string_view name) override;
232}; 246};
247
248// Compare the two files, byte-for-byte, in increments specificed by block_size
249bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size = 0x200);
250
251// A method that copies the raw data between two different implementations of VirtualFile. If you
252// are using the same implementation, it is probably better to use the Copy method in the parent
253// directory of src/dest.
254bool VfsRawCopy(VirtualFile src, VirtualFile dest);
255
233} // namespace FileSys 256} // 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 @@
10namespace FileSys { 10namespace FileSys {
11 11
12OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, 12OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_,
13 std::string name_) 13 std::string name_, VirtualDir parent_)
14 : file(std::move(file_)), offset(offset_), size(size_), name(std::move(name_)) {} 14 : file(file_), offset(offset_), size(size_), name(std::move(name_)),
15 parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
15 16
16std::string OffsetVfsFile::GetName() const { 17std::string OffsetVfsFile::GetName() const {
17 return name.empty() ? file->GetName() : name; 18 return name.empty() ? file->GetName() : name;
@@ -35,7 +36,7 @@ bool OffsetVfsFile::Resize(size_t new_size) {
35} 36}
36 37
37std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const { 38std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
38 return file->GetContainingDirectory(); 39 return parent;
39} 40}
40 41
41bool OffsetVfsFile::IsWritable() const { 42bool 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 {
17// the size of this wrapper. 17// the size of this wrapper.
18struct OffsetVfsFile : public VfsFile { 18struct OffsetVfsFile : public VfsFile {
19 OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, 19 OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0,
20 std::string new_name = ""); 20 std::string new_name = "", VirtualDir new_parent = nullptr);
21 21
22 std::string GetName() const override; 22 std::string GetName() const override;
23 size_t GetSize() const override; 23 size_t GetSize() const override;
@@ -44,6 +44,7 @@ private:
44 size_t offset; 44 size_t offset;
45 size_t size; 45 size_t size;
46 std::string name; 46 std::string name;
47 VirtualDir parent;
47}; 48};
48 49
49} // namespace FileSys 50} // 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) {
195 return FileUtil::Rename(path, new_name); 195 return FileUtil::Rename(path, new_name);
196} 196}
197 197
198std::string RealVfsDirectory::GetFullPath() const {
199 auto out = path;
200 std::replace(out.begin(), out.end(), '\\', '/');
201 return out;
202}
203
198bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { 204bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
199 const auto iter = std::find(files.begin(), files.end(), file); 205 const auto iter = std::find(files.begin(), files.end(), file);
200 if (iter == files.end()) 206 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:
41 41
42// An implementation of VfsDirectory that represents a directory on the user's computer. 42// An implementation of VfsDirectory that represents a directory on the user's computer.
43struct RealVfsDirectory : public VfsDirectory { 43struct RealVfsDirectory : public VfsDirectory {
44 RealVfsDirectory(const std::string& path, Mode perms); 44 RealVfsDirectory(const std::string& path, Mode perms = Mode::Read);
45 45
46 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; 46 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
47 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; 47 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
@@ -54,6 +54,7 @@ struct RealVfsDirectory : public VfsDirectory {
54 bool DeleteSubdirectory(std::string_view name) override; 54 bool DeleteSubdirectory(std::string_view name) override;
55 bool DeleteFile(std::string_view name) override; 55 bool DeleteFile(std::string_view name) override;
56 bool Rename(std::string_view name) override; 56 bool Rename(std::string_view name) override;
57 std::string GetFullPath() const override;
57 58
58protected: 59protected:
59 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; 60 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <utility>
7#include "core/file_sys/vfs_vector.h"
8
9namespace FileSys {
10VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_,
11 std::vector<VirtualDir> dirs_, VirtualDir parent_,
12 std::string name_)
13 : files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)),
14 name(std::move(name_)) {}
15
16std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const {
17 return files;
18}
19
20std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const {
21 return dirs;
22}
23
24bool VectorVfsDirectory::IsWritable() const {
25 return false;
26}
27
28bool VectorVfsDirectory::IsReadable() const {
29 return true;
30}
31
32std::string VectorVfsDirectory::GetName() const {
33 return name;
34}
35
36std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
37 return parent;
38}
39
40template <typename T>
41static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) {
42 const auto iter =
43 std::find_if(vec.begin(), vec.end(), [name](const T& e) { return e->GetName() == name; });
44 if (iter == vec.end())
45 return false;
46
47 vec.erase(iter);
48 return true;
49}
50
51bool VectorVfsDirectory::DeleteSubdirectory(std::string_view name) {
52 return FindAndRemoveVectorElement(dirs, name);
53}
54
55bool VectorVfsDirectory::DeleteFile(std::string_view name) {
56 return FindAndRemoveVectorElement(files, name);
57}
58
59bool VectorVfsDirectory::Rename(std::string_view name_) {
60 name = name_;
61 return true;
62}
63
64std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
65 return nullptr;
66}
67
68std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) {
69 return nullptr;
70}
71
72void VectorVfsDirectory::AddFile(VirtualFile file) {
73 files.push_back(std::move(file));
74}
75
76void VectorVfsDirectory::AddDirectory(VirtualDir dir) {
77 dirs.push_back(std::move(dir));
78}
79
80bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
81 if (!DeleteFile(file->GetName()))
82 return false;
83 dirs.emplace_back(std::move(dir));
84 return true;
85}
86} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/file_sys/vfs.h"
8
9namespace FileSys {
10
11// An implementation of VfsDirectory that maintains two vectors for subdirectories and files.
12// Vector data is supplied upon construction.
13struct VectorVfsDirectory : public VfsDirectory {
14 explicit VectorVfsDirectory(std::vector<VirtualFile> files = {},
15 std::vector<VirtualDir> dirs = {}, VirtualDir parent = nullptr,
16 std::string name = "");
17
18 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
19 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
20 bool IsWritable() const override;
21 bool IsReadable() const override;
22 std::string GetName() const override;
23 std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
24 bool DeleteSubdirectory(std::string_view name) override;
25 bool DeleteFile(std::string_view name) override;
26 bool Rename(std::string_view name) override;
27 std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
28 std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
29
30 virtual void AddFile(VirtualFile file);
31 virtual void AddDirectory(VirtualDir dir);
32
33protected:
34 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
35
36private:
37 std::vector<VirtualFile> files;
38 std::vector<VirtualDir> dirs;
39
40 VirtualDir parent;
41 std::string name;
42};
43
44} // 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 @@
37#include "core/core.h" 37#include "core/core.h"
38#include "core/core_cpu.h" 38#include "core/core_cpu.h"
39#include "core/gdbstub/gdbstub.h" 39#include "core/gdbstub/gdbstub.h"
40#include "core/hle/kernel/kernel.h"
41#include "core/hle/kernel/scheduler.h" 40#include "core/hle/kernel/scheduler.h"
42#include "core/loader/loader.h" 41#include "core/loader/loader.h"
43#include "core/memory.h" 42#include "core/memory.h"
44 43
45const int GDB_BUFFER_SIZE = 10000; 44namespace GDBStub {
45namespace {
46constexpr int GDB_BUFFER_SIZE = 10000;
46 47
47const char GDB_STUB_START = '$'; 48constexpr char GDB_STUB_START = '$';
48const char GDB_STUB_END = '#'; 49constexpr char GDB_STUB_END = '#';
49const char GDB_STUB_ACK = '+'; 50constexpr char GDB_STUB_ACK = '+';
50const char GDB_STUB_NACK = '-'; 51constexpr char GDB_STUB_NACK = '-';
51 52
52#ifndef SIGTRAP 53#ifndef SIGTRAP
53const u32 SIGTRAP = 5; 54constexpr u32 SIGTRAP = 5;
54#endif 55#endif
55 56
56#ifndef SIGTERM 57#ifndef SIGTERM
57const u32 SIGTERM = 15; 58constexpr u32 SIGTERM = 15;
58#endif 59#endif
59 60
60#ifndef MSG_WAITALL 61#ifndef MSG_WAITALL
61const u32 MSG_WAITALL = 8; 62constexpr u32 MSG_WAITALL = 8;
62#endif 63#endif
63 64
64const u32 LR_REGISTER = 30; 65constexpr u32 LR_REGISTER = 30;
65const u32 SP_REGISTER = 31; 66constexpr u32 SP_REGISTER = 31;
66const u32 PC_REGISTER = 32; 67constexpr u32 PC_REGISTER = 32;
67const u32 CPSR_REGISTER = 33; 68constexpr u32 CPSR_REGISTER = 33;
68const u32 UC_ARM64_REG_Q0 = 34; 69constexpr u32 UC_ARM64_REG_Q0 = 34;
69const u32 FPSCR_REGISTER = 66; 70constexpr u32 FPSCR_REGISTER = 66;
70 71
71// TODO/WiP - Used while working on support for FPU 72// TODO/WiP - Used while working on support for FPU
72const u32 TODO_DUMMY_REG_997 = 997; 73constexpr u32 TODO_DUMMY_REG_997 = 997;
73const u32 TODO_DUMMY_REG_998 = 998; 74constexpr u32 TODO_DUMMY_REG_998 = 998;
74 75
75// For sample XML files see the GDB source /gdb/features 76// For sample XML files see the GDB source /gdb/features
76// GDB also wants the l character at the start 77// GDB also wants the l character at the start
77// This XML defines what the registers are for this specific ARM device 78// This XML defines what the registers are for this specific ARM device
78static const char* target_xml = 79constexpr char target_xml[] =
79 R"(l<?xml version="1.0"?> 80 R"(l<?xml version="1.0"?>
80<!DOCTYPE target SYSTEM "gdb-target.dtd"> 81<!DOCTYPE target SYSTEM "gdb-target.dtd">
81<target version="1.0"> 82<target version="1.0">
@@ -141,30 +142,28 @@ static const char* target_xml =
141</target> 142</target>
142)"; 143)";
143 144
144namespace GDBStub { 145int gdbserver_socket = -1;
145
146static int gdbserver_socket = -1;
147 146
148static u8 command_buffer[GDB_BUFFER_SIZE]; 147u8 command_buffer[GDB_BUFFER_SIZE];
149static u32 command_length; 148u32 command_length;
150 149
151static u32 latest_signal = 0; 150u32 latest_signal = 0;
152static bool memory_break = false; 151bool memory_break = false;
153 152
154static Kernel::Thread* current_thread = nullptr; 153Kernel::Thread* current_thread = nullptr;
155static u32 current_core = 0; 154u32 current_core = 0;
156 155
157// Binding to a port within the reserved ports range (0-1023) requires root permissions, 156// Binding to a port within the reserved ports range (0-1023) requires root permissions,
158// so default to a port outside of that range. 157// so default to a port outside of that range.
159static u16 gdbstub_port = 24689; 158u16 gdbstub_port = 24689;
160 159
161static bool halt_loop = true; 160bool halt_loop = true;
162static bool step_loop = false; 161bool step_loop = false;
163static bool send_trap = false; 162bool send_trap = false;
164 163
165// If set to false, the server will never be started and no 164// If set to false, the server will never be started and no
166// gdbstub-related functions will be executed. 165// gdbstub-related functions will be executed.
167static std::atomic<bool> server_enabled(false); 166std::atomic<bool> server_enabled(false);
168 167
169#ifdef _WIN32 168#ifdef _WIN32
170WSADATA InitData; 169WSADATA InitData;
@@ -172,23 +171,26 @@ WSADATA InitData;
172 171
173struct Breakpoint { 172struct Breakpoint {
174 bool active; 173 bool active;
175 PAddr addr; 174 VAddr addr;
176 u64 len; 175 u64 len;
176 std::array<u8, 4> inst;
177}; 177};
178 178
179static std::map<u64, Breakpoint> breakpoints_execute; 179using BreakpointMap = std::map<VAddr, Breakpoint>;
180static std::map<u64, Breakpoint> breakpoints_read; 180BreakpointMap breakpoints_execute;
181static std::map<u64, Breakpoint> breakpoints_write; 181BreakpointMap breakpoints_read;
182BreakpointMap breakpoints_write;
182 183
183struct Module { 184struct Module {
184 std::string name; 185 std::string name;
185 PAddr beg; 186 VAddr beg;
186 PAddr end; 187 VAddr end;
187}; 188};
188 189
189static std::vector<Module> modules; 190std::vector<Module> modules;
191} // Anonymous namespace
190 192
191void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext) { 193void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) {
192 Module module; 194 Module module;
193 if (add_elf_ext) { 195 if (add_elf_ext) {
194 Common::SplitPath(name, nullptr, &module.name, nullptr); 196 Common::SplitPath(name, nullptr, &module.name, nullptr);
@@ -419,11 +421,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
419} 421}
420 422
421/** 423/**
422 * Get the list of breakpoints for a given breakpoint type. 424 * Get the map of breakpoints for a given breakpoint type.
423 * 425 *
424 * @param type Type of breakpoint list. 426 * @param type Type of breakpoint map.
425 */ 427 */
426static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { 428static BreakpointMap& GetBreakpointMap(BreakpointType type) {
427 switch (type) { 429 switch (type) {
428 case BreakpointType::Execute: 430 case BreakpointType::Execute:
429 return breakpoints_execute; 431 return breakpoints_execute;
@@ -442,20 +444,24 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
442 * @param type Type of breakpoint. 444 * @param type Type of breakpoint.
443 * @param addr Address of breakpoint. 445 * @param addr Address of breakpoint.
444 */ 446 */
445static void RemoveBreakpoint(BreakpointType type, PAddr addr) { 447static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
446 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 448 BreakpointMap& p = GetBreakpointMap(type);
447 449
448 auto bp = p.find(static_cast<u64>(addr)); 450 const auto bp = p.find(addr);
449 if (bp != p.end()) { 451 if (bp == p.end()) {
450 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", 452 return;
451 bp->second.len, bp->second.addr, static_cast<int>(type));
452 p.erase(static_cast<u64>(addr));
453 } 453 }
454
455 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
456 bp->second.len, bp->second.addr, static_cast<int>(type));
457 Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
458 Core::System::GetInstance().InvalidateCpuInstructionCaches();
459 p.erase(addr);
454} 460}
455 461
456BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) { 462BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
457 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 463 const BreakpointMap& p = GetBreakpointMap(type);
458 auto next_breakpoint = p.lower_bound(static_cast<u64>(addr)); 464 const auto next_breakpoint = p.lower_bound(addr);
459 BreakpointAddress breakpoint; 465 BreakpointAddress breakpoint;
460 466
461 if (next_breakpoint != p.end()) { 467 if (next_breakpoint != p.end()) {
@@ -469,36 +475,38 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type)
469 return breakpoint; 475 return breakpoint;
470} 476}
471 477
472bool CheckBreakpoint(PAddr addr, BreakpointType type) { 478bool CheckBreakpoint(VAddr addr, BreakpointType type) {
473 if (!IsConnected()) { 479 if (!IsConnected()) {
474 return false; 480 return false;
475 } 481 }
476 482
477 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 483 const BreakpointMap& p = GetBreakpointMap(type);
484 const auto bp = p.find(addr);
478 485
479 auto bp = p.find(static_cast<u64>(addr)); 486 if (bp == p.end()) {
480 if (bp != p.end()) { 487 return false;
481 u64 len = bp->second.len; 488 }
482 489
483 // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints 490 u64 len = bp->second.len;
484 // no matter if it's a 4-byte or 2-byte instruction. When you execute a
485 // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
486 // two instructions instead of the single instruction you placed the breakpoint
487 // on. So, as a way to make sure that execution breakpoints are only breaking
488 // on the instruction that was specified, set the length of an execution
489 // breakpoint to 1. This should be fine since the CPU should never begin executing
490 // an instruction anywhere except the beginning of the instruction.
491 if (type == BreakpointType::Execute) {
492 len = 1;
493 }
494 491
495 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { 492 // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
496 LOG_DEBUG(Debug_GDBStub, 493 // no matter if it's a 4-byte or 2-byte instruction. When you execute a
497 "Found breakpoint type {} @ {:016X}, range: {:016X}" 494 // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
498 " - {:016X} ({:X} bytes)", 495 // two instructions instead of the single instruction you placed the breakpoint
499 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); 496 // on. So, as a way to make sure that execution breakpoints are only breaking
500 return true; 497 // on the instruction that was specified, set the length of an execution
501 } 498 // breakpoint to 1. This should be fine since the CPU should never begin executing
499 // an instruction anywhere except the beginning of the instruction.
500 if (type == BreakpointType::Execute) {
501 len = 1;
502 }
503
504 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
505 LOG_DEBUG(Debug_GDBStub,
506 "Found breakpoint type {} @ {:016X}, range: {:016X}"
507 " - {:016X} ({:X} bytes)",
508 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
509 return true;
502 } 510 }
503 511
504 return false; 512 return false;
@@ -932,6 +940,7 @@ static void WriteMemory() {
932 940
933 GdbHexToMem(data.data(), len_pos + 1, len); 941 GdbHexToMem(data.data(), len_pos + 1, len);
934 Memory::WriteBlock(addr, data.data(), len); 942 Memory::WriteBlock(addr, data.data(), len);
943 Core::System::GetInstance().InvalidateCpuInstructionCaches();
935 SendReply("OK"); 944 SendReply("OK");
936} 945}
937 946
@@ -951,6 +960,7 @@ static void Step() {
951 step_loop = true; 960 step_loop = true;
952 halt_loop = true; 961 halt_loop = true;
953 send_trap = true; 962 send_trap = true;
963 Core::System::GetInstance().InvalidateCpuInstructionCaches();
954} 964}
955 965
956/// Tell the CPU if we hit a memory breakpoint. 966/// Tell the CPU if we hit a memory breakpoint.
@@ -967,6 +977,7 @@ static void Continue() {
967 memory_break = false; 977 memory_break = false;
968 step_loop = false; 978 step_loop = false;
969 halt_loop = false; 979 halt_loop = false;
980 Core::System::GetInstance().InvalidateCpuInstructionCaches();
970} 981}
971 982
972/** 983/**
@@ -976,13 +987,17 @@ static void Continue() {
976 * @param addr Address of breakpoint. 987 * @param addr Address of breakpoint.
977 * @param len Length of breakpoint. 988 * @param len Length of breakpoint.
978 */ 989 */
979static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { 990static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
980 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 991 BreakpointMap& p = GetBreakpointMap(type);
981 992
982 Breakpoint breakpoint; 993 Breakpoint breakpoint;
983 breakpoint.active = true; 994 breakpoint.active = true;
984 breakpoint.addr = addr; 995 breakpoint.addr = addr;
985 breakpoint.len = len; 996 breakpoint.len = len;
997 Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
998 static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
999 Memory::WriteBlock(addr, btrap.data(), btrap.size());
1000 Core::System::GetInstance().InvalidateCpuInstructionCaches();
986 p.insert({addr, breakpoint}); 1001 p.insert({addr, breakpoint});
987 1002
988 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", 1003 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
@@ -1016,7 +1031,7 @@ static void AddBreakpoint() {
1016 1031
1017 auto start_offset = command_buffer + 3; 1032 auto start_offset = command_buffer + 3;
1018 auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); 1033 auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
1019 PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); 1034 VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
1020 1035
1021 start_offset = addr_pos + 1; 1036 start_offset = addr_pos + 1;
1022 u64 len = 1037 u64 len =
@@ -1065,7 +1080,7 @@ static void RemoveBreakpoint() {
1065 1080
1066 auto start_offset = command_buffer + 3; 1081 auto start_offset = command_buffer + 3;
1067 auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); 1082 auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
1068 PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); 1083 VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
1069 1084
1070 if (type == BreakpointType::Access) { 1085 if (type == BreakpointType::Access) {
1071 // Access is made up of Read and Write types, so add both breakpoints 1086 // 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 {
22}; 22};
23 23
24struct BreakpointAddress { 24struct BreakpointAddress {
25 PAddr address; 25 VAddr address;
26 BreakpointType type; 26 BreakpointType type;
27}; 27};
28 28
@@ -53,7 +53,7 @@ bool IsServerEnabled();
53bool IsConnected(); 53bool IsConnected();
54 54
55/// Register module. 55/// Register module.
56void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext = true); 56void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
57 57
58/** 58/**
59 * Signal to the gdbstub server that it should halt CPU execution. 59 * Signal to the gdbstub server that it should halt CPU execution.
@@ -74,7 +74,7 @@ void HandlePacket();
74 * @param addr Address to search from. 74 * @param addr Address to search from.
75 * @param type Type of breakpoint. 75 * @param type Type of breakpoint.
76 */ 76 */
77BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointType type); 77BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
78 78
79/** 79/**
80 * Check if a breakpoint of the specified type exists at the given address. 80 * Check if a breakpoint of the specified type exists at the given address.
@@ -82,7 +82,7 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointTy
82 * @param addr Address of breakpoint. 82 * @param addr Address of breakpoint.
83 * @param type Type of breakpoint. 83 * @param type Type of breakpoint.
84 */ 84 */
85bool CheckBreakpoint(PAddr addr, GDBStub::BreakpointType type); 85bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
86 86
87/// If set to true, the CPU will halt at the beginning of the next CPU loop. 87/// If set to true, the CPU will halt at the beginning of the next CPU loop.
88bool GetCpuHaltFlag(); 88bool 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 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <cstring>
9#include <memory>
8#include <tuple> 10#include <tuple>
9#include <type_traits> 11#include <type_traits>
10#include <utility> 12#include <utility>
13#include "common/assert.h"
14#include "common/common_types.h"
11#include "core/hle/ipc.h" 15#include "core/hle/ipc.h"
12#include "core/hle/kernel/client_port.h" 16#include "core/hle/kernel/client_port.h"
13#include "core/hle/kernel/client_session.h" 17#include "core/hle/kernel/client_session.h"
14#include "core/hle/kernel/handle_table.h"
15#include "core/hle/kernel/hle_ipc.h" 18#include "core/hle/kernel/hle_ipc.h"
16#include "core/hle/kernel/kernel.h" 19#include "core/hle/kernel/object.h"
17#include "core/hle/kernel/server_port.h" 20#include "core/hle/kernel/server_port.h"
18 21
19namespace IPC { 22namespace 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <vector>
7
5#include "common/assert.h" 8#include "common/assert.h"
6#include "common/common_funcs.h"
7#include "common/common_types.h" 9#include "common/common_types.h"
8#include "core/core.h" 10#include "core/core.h"
9#include "core/hle/kernel/errors.h" 11#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
12#include "core/hle/kernel/thread.h" 14#include "core/hle/kernel/thread.h"
13#include "core/hle/lock.h" 15#include "core/hle/result.h"
14#include "core/memory.h" 16#include "core/memory.h"
15 17
16namespace Kernel { 18namespace Kernel {
@@ -30,9 +32,8 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) {
30} 32}
31 33
32// Gets the threads waiting on an address. 34// Gets the threads waiting on an address.
33static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, 35static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) {
34 VAddr address) { 36 const auto RetrieveWaitingThreads =
35 auto RetrieveWaitingThreads =
36 [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { 37 [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) {
37 const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); 38 const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
38 auto& thread_list = scheduler->GetThreadList(); 39 auto& thread_list = scheduler->GetThreadList();
@@ -43,16 +44,20 @@ static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_t
43 } 44 }
44 }; 45 };
45 46
46 // Retrieve a list of all threads that are waiting for this address. 47 // Retrieve all threads that are waiting for this address.
47 RetrieveWaitingThreads(0, waiting_threads, address); 48 std::vector<SharedPtr<Thread>> threads;
48 RetrieveWaitingThreads(1, waiting_threads, address); 49 RetrieveWaitingThreads(0, threads, address);
49 RetrieveWaitingThreads(2, waiting_threads, address); 50 RetrieveWaitingThreads(1, threads, address);
50 RetrieveWaitingThreads(3, waiting_threads, address); 51 RetrieveWaitingThreads(2, threads, address);
52 RetrieveWaitingThreads(3, threads, address);
53
51 // Sort them by priority, such that the highest priority ones come first. 54 // Sort them by priority, such that the highest priority ones come first.
52 std::sort(waiting_threads.begin(), waiting_threads.end(), 55 std::sort(threads.begin(), threads.end(),
53 [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { 56 [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
54 return lhs->current_priority < rhs->current_priority; 57 return lhs->current_priority < rhs->current_priority;
55 }); 58 });
59
60 return threads;
56} 61}
57 62
58// Wake up num_to_wake (or all) threads in a vector. 63// 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
74 79
75// Signals an address being waited on. 80// Signals an address being waited on.
76ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { 81ResultCode SignalToAddress(VAddr address, s32 num_to_wake) {
77 // Get threads waiting on the address. 82 std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
78 std::vector<SharedPtr<Thread>> waiting_threads;
79 GetThreadsWaitingOnAddress(waiting_threads, address);
80 83
81 WakeThreads(waiting_threads, num_to_wake); 84 WakeThreads(waiting_threads, num_to_wake);
82 return RESULT_SUCCESS; 85 return RESULT_SUCCESS;
@@ -108,12 +111,11 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu
108 } 111 }
109 112
110 // Get threads waiting on the address. 113 // Get threads waiting on the address.
111 std::vector<SharedPtr<Thread>> waiting_threads; 114 std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
112 GetThreadsWaitingOnAddress(waiting_threads, address);
113 115
114 // Determine the modified value depending on the waiting count. 116 // Determine the modified value depending on the waiting count.
115 s32 updated_value; 117 s32 updated_value;
116 if (waiting_threads.size() == 0) { 118 if (waiting_threads.empty()) {
117 updated_value = value - 1; 119 updated_value = value - 1;
118 } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { 120 } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) {
119 updated_value = value + 1; 121 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/result.h" 7#include "common/common_types.h"
8
9union ResultCode;
8 10
9namespace Kernel { 11namespace Kernel {
10 12
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include <tuple>
6
6#include "core/hle/kernel/client_port.h" 7#include "core/hle/kernel/client_port.h"
7#include "core/hle/kernel/client_session.h" 8#include "core/hle/kernel/client_session.h"
8#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/hle_ipc.h" 10#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/server_port.h" 12#include "core/hle/kernel/server_port.h"
12#include "core/hle/kernel/server_session.h" 13#include "core/hle/kernel/server_session.h"
13 14
14namespace Kernel { 15namespace Kernel {
15 16
16ClientPort::ClientPort() {} 17ClientPort::ClientPort() = default;
17ClientPort::~ClientPort() {} 18ClientPort::~ClientPort() = default;
18 19
19ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { 20ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
20 // Note: Threads do not wait for the server endpoint to call 21 // Note: Threads do not wait for the server endpoint to call
@@ -39,4 +40,12 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
39 return MakeResult(std::get<SharedPtr<ClientSession>>(sessions)); 40 return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
40} 41}
41 42
43void ClientPort::ConnectionClosed() {
44 if (active_sessions == 0) {
45 return;
46 }
47
48 --active_sessions;
49}
50
42} // namespace Kernel 51} // 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 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
11 11
12namespace Kernel { 12namespace Kernel {
@@ -37,14 +37,20 @@ public:
37 */ 37 */
38 ResultVal<SharedPtr<ClientSession>> Connect(); 38 ResultVal<SharedPtr<ClientSession>> Connect();
39 39
40 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. 40 /**
41 u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have 41 * Signifies that a previously active connection has been closed,
42 u32 active_sessions; ///< Number of currently open sessions to this port 42 * decreasing the total number of active connections to this port.
43 std::string name; ///< Name of client port (optional) 43 */
44 void ConnectionClosed();
44 45
45private: 46private:
46 ClientPort(); 47 ClientPort();
47 ~ClientPort() override; 48 ~ClientPort() override;
49
50 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
51 u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
52 u32 active_sessions = 0; ///< Number of currently open sessions to this port
53 std::string name; ///< Name of client port (optional)
48}; 54};
49 55
50} // namespace Kernel 56} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h"
6
7#include "core/hle/kernel/client_session.h" 5#include "core/hle/kernel/client_session.h"
8#include "core/hle/kernel/errors.h" 6#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/hle_ipc.h" 7#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 @@
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/result.h" 11#include "core/hle/result.h"
12 12
13namespace Kernel { 13namespace 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <map>
7#include <vector>
8#include "common/assert.h" 6#include "common/assert.h"
9#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
12 10
13namespace Kernel { 11namespace 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 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/wait_object.h" 9#include "core/hle/kernel/wait_object.h"
10 10
11namespace Kernel { 11namespace Kernel {
@@ -31,10 +31,9 @@ public:
31 return HANDLE_TYPE; 31 return HANDLE_TYPE;
32 } 32 }
33 33
34 ResetType reset_type; ///< Current ResetType 34 ResetType GetResetType() const {
35 35 return reset_type;
36 bool signaled; ///< Whether the event has already been signaled 36 }
37 std::string name; ///< Name of event (optional)
38 37
39 bool ShouldWait(Thread* thread) const override; 38 bool ShouldWait(Thread* thread) const override;
40 void Acquire(Thread* thread) override; 39 void Acquire(Thread* thread) override;
@@ -47,6 +46,11 @@ public:
47private: 46private:
48 Event(); 47 Event();
49 ~Event() override; 48 ~Event() override;
49
50 ResetType reset_type; ///< Current ResetType
51
52 bool signaled; ///< Whether the event has already been signaled
53 std::string name; ///< Name of event (optional)
50}; 54};
51 55
52} // namespace Kernel 56} // 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 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
14 13
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 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/result.h" 11#include "core/hle/result.h"
12 12
13namespace Kernel { 13namespace 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <array>
7#include <sstream>
5#include <utility> 8#include <utility>
6 9
7#include <boost/range/algorithm_ext/erase.hpp> 10#include <boost/range/algorithm_ext/erase.hpp>
11
8#include "common/assert.h" 12#include "common/assert.h"
9#include "common/common_funcs.h" 13#include "common/common_funcs.h"
10#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/logging/log.h"
11#include "core/hle/ipc_helpers.h" 16#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/event.h" 17#include "core/hle/kernel/event.h"
13#include "core/hle/kernel/handle_table.h" 18#include "core/hle/kernel/handle_table.h"
14#include "core/hle/kernel/hle_ipc.h" 19#include "core/hle/kernel/hle_ipc.h"
15#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
17#include "core/hle/kernel/server_session.h" 22#include "core/hle/kernel/server_session.h"
18#include "core/memory.h" 23#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 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <iterator>
9#include <memory> 8#include <memory>
10#include <string> 9#include <string>
11#include <type_traits> 10#include <type_traits>
@@ -14,7 +13,7 @@
14#include "common/common_types.h" 13#include "common/common_types.h"
15#include "common/swap.h" 14#include "common/swap.h"
16#include "core/hle/ipc.h" 15#include "core/hle/ipc.h"
17#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/object.h"
18#include "core/hle/kernel/server_session.h" 17#include "core/hle/kernel/server_session.h"
19#include "core/hle/kernel/thread.h" 18#include "core/hle/kernel/thread.h"
20 19
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 @@
4 4
5#include "core/hle/kernel/handle_table.h" 5#include "core/hle/kernel/handle_table.h"
6#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/memory.h"
8#include "core/hle/kernel/object_address_table.h"
9#include "core/hle/kernel/process.h" 7#include "core/hle/kernel/process.h"
10#include "core/hle/kernel/resource_limit.h" 8#include "core/hle/kernel/resource_limit.h"
11#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
@@ -16,9 +14,7 @@ namespace Kernel {
16unsigned int Object::next_object_id; 14unsigned int Object::next_object_id;
17 15
18/// Initialize the kernel 16/// Initialize the kernel
19void Init(u32 system_mode) { 17void Init() {
20 Kernel::MemoryInit(system_mode);
21
22 Kernel::ResourceLimitsInit(); 18 Kernel::ResourceLimitsInit();
23 Kernel::ThreadingInit(); 19 Kernel::ThreadingInit();
24 Kernel::TimersInit(); 20 Kernel::TimersInit();
@@ -33,13 +29,11 @@ void Init(u32 system_mode) {
33void Shutdown() { 29void Shutdown() {
34 // Free all kernel objects 30 // Free all kernel objects
35 g_handle_table.Clear(); 31 g_handle_table.Clear();
36 g_object_address_table.Clear();
37 32
38 Kernel::ThreadingShutdown(); 33 Kernel::ThreadingShutdown();
39 34
40 Kernel::TimersShutdown(); 35 Kernel::TimersShutdown();
41 Kernel::ResourceLimitsShutdown(); 36 Kernel::ResourceLimitsShutdown();
42 Kernel::MemoryShutdown();
43} 37}
44 38
45} // namespace Kernel 39} // 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstddef>
8#include <string>
9#include <utility>
10#include <boost/smart_ptr/intrusive_ptr.hpp>
11#include "common/assert.h"
12#include "common/common_types.h" 7#include "common/common_types.h"
13 8
14namespace Kernel { 9namespace Kernel {
15 10
16using Handle = u32;
17
18enum class HandleType : u32 {
19 Unknown,
20 Event,
21 SharedMemory,
22 Thread,
23 Process,
24 AddressArbiter,
25 Timer,
26 ResourceLimit,
27 CodeSet,
28 ClientPort,
29 ServerPort,
30 ClientSession,
31 ServerSession,
32};
33
34enum class ResetType {
35 OneShot,
36 Sticky,
37 Pulse,
38};
39
40class Object : NonCopyable {
41public:
42 virtual ~Object() {}
43
44 /// Returns a unique identifier for the object. For debugging purposes only.
45 unsigned int GetObjectId() const {
46 return object_id;
47 }
48
49 virtual std::string GetTypeName() const {
50 return "[BAD KERNEL OBJECT TYPE]";
51 }
52 virtual std::string GetName() const {
53 return "[UNKNOWN KERNEL OBJECT]";
54 }
55 virtual Kernel::HandleType GetHandleType() const = 0;
56
57 /**
58 * Check if a thread can wait on the object
59 * @return True if a thread can wait on the object, otherwise false
60 */
61 bool IsWaitable() const {
62 switch (GetHandleType()) {
63 case HandleType::Event:
64 case HandleType::Thread:
65 case HandleType::Timer:
66 case HandleType::ServerPort:
67 case HandleType::ServerSession:
68 return true;
69
70 case HandleType::Unknown:
71 case HandleType::SharedMemory:
72 case HandleType::Process:
73 case HandleType::AddressArbiter:
74 case HandleType::ResourceLimit:
75 case HandleType::CodeSet:
76 case HandleType::ClientPort:
77 case HandleType::ClientSession:
78 return false;
79 }
80
81 UNREACHABLE();
82 }
83
84public:
85 static unsigned int next_object_id;
86
87private:
88 friend void intrusive_ptr_add_ref(Object*);
89 friend void intrusive_ptr_release(Object*);
90
91 unsigned int ref_count = 0;
92 unsigned int object_id = next_object_id++;
93};
94
95// Special functions used by boost::instrusive_ptr to do automatic ref-counting
96inline void intrusive_ptr_add_ref(Object* object) {
97 ++object->ref_count;
98}
99
100inline void intrusive_ptr_release(Object* object) {
101 if (--object->ref_count == 0) {
102 delete object;
103 }
104}
105
106template <typename T>
107using SharedPtr = boost::intrusive_ptr<T>;
108
109/**
110 * Attempts to downcast the given Object pointer to a pointer to T.
111 * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
112 */
113template <typename T>
114inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
115 if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
116 return boost::static_pointer_cast<T>(std::move(object));
117 }
118 return nullptr;
119}
120
121/// Initialize the kernel with the specified system mode. 11/// Initialize the kernel with the specified system mode.
122void Init(u32 system_mode); 12void Init();
123 13
124/// Shutdown the kernel 14/// Shutdown the kernel
125void Shutdown(); 15void 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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cinttypes>
7#include <map>
8#include <memory>
9#include <utility>
10#include <vector>
11#include "common/assert.h"
12#include "common/common_types.h"
13#include "common/logging/log.h"
14#include "core/hle/kernel/memory.h"
15#include "core/hle/kernel/vm_manager.h"
16#include "core/hle/result.h"
17#include "core/memory.h"
18#include "core/memory_setup.h"
19
20////////////////////////////////////////////////////////////////////////////////////////////////////
21
22namespace Kernel {
23
24MemoryRegionInfo memory_regions[3];
25
26/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
27/// memory configuration type.
28static const u32 memory_region_sizes[8][3] = {
29 // Old 3DS layouts
30 {0x04000000, 0x02C00000, 0x01400000}, // 0
31 {/* This appears to be unused. */}, // 1
32 {0x06000000, 0x00C00000, 0x01400000}, // 2
33 {0x05000000, 0x01C00000, 0x01400000}, // 3
34 {0x04800000, 0x02400000, 0x01400000}, // 4
35 {0x02000000, 0x04C00000, 0x01400000}, // 5
36
37 // New 3DS layouts
38 {0x07C00000, 0x06400000, 0x02000000}, // 6
39 {0x0B200000, 0x02E00000, 0x02000000}, // 7
40};
41
42void MemoryInit(u32 mem_type) {
43 // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
44 ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
45 ASSERT(mem_type != 1);
46
47 // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
48 // the sizes specified in the memory_region_sizes table.
49 VAddr base = 0;
50 for (int i = 0; i < 3; ++i) {
51 memory_regions[i].base = base;
52 memory_regions[i].size = memory_region_sizes[mem_type][i];
53 memory_regions[i].used = 0;
54 memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
55 // Reserve enough space for this region of FCRAM.
56 // We do not want this block of memory to be relocated when allocating from it.
57 memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size);
58
59 base += memory_regions[i].size;
60 }
61
62 // We must've allocated the entire FCRAM by the end
63 ASSERT(base == Memory::FCRAM_SIZE);
64}
65
66void MemoryShutdown() {
67 for (auto& region : memory_regions) {
68 region.base = 0;
69 region.size = 0;
70 region.used = 0;
71 region.linear_heap_memory = nullptr;
72 }
73}
74
75MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
76 switch (region) {
77 case MemoryRegion::APPLICATION:
78 return &memory_regions[0];
79 case MemoryRegion::SYSTEM:
80 return &memory_regions[1];
81 case MemoryRegion::BASE:
82 return &memory_regions[2];
83 default:
84 UNREACHABLE();
85 }
86}
87
88void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
89
90void MapSharedPages(VMManager& address_space) {}
91
92} // 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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "common/common_types.h"
9#include "core/hle/kernel/process.h"
10
11namespace Kernel {
12
13class VMManager;
14
15struct MemoryRegionInfo {
16 u64 base; // Not an address, but offset from start of FCRAM
17 u64 size;
18 u64 used;
19
20 std::shared_ptr<std::vector<u8>> linear_heap_memory;
21};
22
23void MemoryInit(u32 mem_type);
24void MemoryShutdown();
25MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
26
27void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
28void MapSharedPages(VMManager& address_space);
29
30extern MemoryRegionInfo memory_regions[3];
31} // 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map> 5#include <map>
6#include <utility>
6#include <vector> 7#include <vector>
8
7#include <boost/range/algorithm_ext/erase.hpp> 9#include <boost/range/algorithm_ext/erase.hpp>
10
8#include "common/assert.h" 11#include "common/assert.h"
9#include "core/core.h" 12#include "core/core.h"
10#include "core/hle/kernel/errors.h" 13#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/handle_table.h" 14#include "core/hle/kernel/handle_table.h"
12#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/mutex.h" 15#include "core/hle/kernel/mutex.h"
14#include "core/hle/kernel/object_address_table.h" 16#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
18#include "core/hle/result.h"
16 19
17namespace Kernel { 20namespace Kernel {
18 21
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <string>
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "common/swap.h" 8#include "core/hle/kernel/object.h"
10#include "core/hle/kernel/kernel.h" 9
11#include "core/hle/kernel/wait_object.h" 10union ResultCode;
12#include "core/hle/result.h"
13 11
14namespace Kernel { 12namespace Kernel {
15 13
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 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "core/hle/kernel/object.h"
7
8namespace Kernel {
9
10Object::~Object() = default;
11
12bool Object::IsWaitable() const {
13 switch (GetHandleType()) {
14 case HandleType::Event:
15 case HandleType::Thread:
16 case HandleType::Timer:
17 case HandleType::ServerPort:
18 case HandleType::ServerSession:
19 return true;
20
21 case HandleType::Unknown:
22 case HandleType::SharedMemory:
23 case HandleType::Process:
24 case HandleType::AddressArbiter:
25 case HandleType::ResourceLimit:
26 case HandleType::CodeSet:
27 case HandleType::ClientPort:
28 case HandleType::ClientSession:
29 return false;
30 }
31
32 UNREACHABLE();
33}
34
35} // 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 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <string>
8#include <utility>
9
10#include <boost/smart_ptr/intrusive_ptr.hpp>
11
12#include "common/common_types.h"
13
14namespace Kernel {
15
16using Handle = u32;
17
18enum class HandleType : u32 {
19 Unknown,
20 Event,
21 SharedMemory,
22 Thread,
23 Process,
24 AddressArbiter,
25 Timer,
26 ResourceLimit,
27 CodeSet,
28 ClientPort,
29 ServerPort,
30 ClientSession,
31 ServerSession,
32};
33
34enum class ResetType {
35 OneShot,
36 Sticky,
37 Pulse,
38};
39
40class Object : NonCopyable {
41public:
42 virtual ~Object();
43
44 /// Returns a unique identifier for the object. For debugging purposes only.
45 unsigned int GetObjectId() const {
46 return object_id;
47 }
48
49 virtual std::string GetTypeName() const {
50 return "[BAD KERNEL OBJECT TYPE]";
51 }
52 virtual std::string GetName() const {
53 return "[UNKNOWN KERNEL OBJECT]";
54 }
55 virtual HandleType GetHandleType() const = 0;
56
57 /**
58 * Check if a thread can wait on the object
59 * @return True if a thread can wait on the object, otherwise false
60 */
61 bool IsWaitable() const;
62
63public:
64 static unsigned int next_object_id;
65
66private:
67 friend void intrusive_ptr_add_ref(Object*);
68 friend void intrusive_ptr_release(Object*);
69
70 unsigned int ref_count = 0;
71 unsigned int object_id = next_object_id++;
72};
73
74// Special functions used by boost::instrusive_ptr to do automatic ref-counting
75inline void intrusive_ptr_add_ref(Object* object) {
76 ++object->ref_count;
77}
78
79inline void intrusive_ptr_release(Object* object) {
80 if (--object->ref_count == 0) {
81 delete object;
82 }
83}
84
85template <typename T>
86using SharedPtr = boost::intrusive_ptr<T>;
87
88/**
89 * Attempts to downcast the given Object pointer to a pointer to T.
90 * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
91 */
92template <typename T>
93inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
94 if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
95 return boost::static_pointer_cast<T>(std::move(object));
96 }
97 return nullptr;
98}
99
100} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <utility>
6
7#include "common/assert.h"
8#include "core/hle/kernel/object_address_table.h"
9
10namespace Kernel {
11
12ObjectAddressTable g_object_address_table;
13
14void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) {
15 ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x{:X}", addr);
16 objects[addr] = std::move(obj);
17}
18
19void ObjectAddressTable::Close(VAddr addr) {
20 ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x{:X}", addr);
21 objects.erase(addr);
22}
23
24SharedPtr<Object> ObjectAddressTable::GetGeneric(VAddr addr) const {
25 auto iter = objects.find(addr);
26 if (iter != objects.end()) {
27 return iter->second;
28 }
29 return {};
30}
31
32void ObjectAddressTable::Clear() {
33 objects.clear();
34}
35
36} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <map>
8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h"
10
11namespace Kernel {
12
13/**
14 * This class is used to keep a table of Kernel objects and their respective addresses in emulated
15 * memory. For certain Switch SVCs, Kernel objects are referenced by an address to an object the
16 * guest application manages, so we use this table to look these kernel objects up. This is similiar
17 * to the HandleTable class.
18 */
19class ObjectAddressTable final : NonCopyable {
20public:
21 ObjectAddressTable() = default;
22
23 /**
24 * Inserts an object and address pair into the table.
25 */
26 void Insert(VAddr addr, SharedPtr<Object> obj);
27
28 /**
29 * Closes an object by its address, removing it from the table and decreasing the object's
30 * ref-count.
31 * @return `RESULT_SUCCESS` or one of the following errors:
32 * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
33 */
34 void Close(VAddr addr);
35
36 /**
37 * Looks up an object by its address.
38 * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
39 */
40 SharedPtr<Object> GetGeneric(VAddr addr) const;
41
42 /**
43 * Looks up an object by its address while verifying its type.
44 * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
45 * type differs from the requested one.
46 */
47 template <class T>
48 SharedPtr<T> Get(VAddr addr) const {
49 return DynamicObjectCast<T>(GetGeneric(addr));
50 }
51
52 /// Closes all addresses held in this table.
53 void Clear();
54
55private:
56 /// Stores the Object referenced by the address
57 std::map<VAddr, SharedPtr<Object>> objects;
58};
59
60extern ObjectAddressTable g_object_address_table;
61
62} // 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 @@
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 12#include "core/hle/kernel/resource_limit.h"
14#include "core/hle/kernel/thread.h" 13#include "core/hle/kernel/thread.h"
@@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
125 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, 124 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
126 MemoryState::Mapped) 125 MemoryState::Mapped)
127 .Unwrap(); 126 .Unwrap();
128 misc_memory_used += stack_size;
129 memory_region->used += stack_size;
130
131 // Map special address mappings
132 MapSharedPages(vm_manager);
133 for (const auto& mapping : address_mappings) {
134 HandleSpecialMapping(vm_manager, mapping);
135 }
136 127
137 vm_manager.LogLayout(); 128 vm_manager.LogLayout();
138 status = ProcessStatus::Running; 129 status = ProcessStatus::Running;
@@ -141,37 +132,19 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
141} 132}
142 133
143void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { 134void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
144 memory_region = GetMemoryRegion(flags.memory_region); 135 const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
145 136 MemoryState memory_state) {
146 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
147 MemoryState memory_state) {
148 auto vma = vm_manager 137 auto vma = vm_manager
149 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, 138 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
150 segment.size, memory_state) 139 segment.size, memory_state)
151 .Unwrap(); 140 .Unwrap();
152 vm_manager.Reprotect(vma, permissions); 141 vm_manager.Reprotect(vma, permissions);
153 misc_memory_used += segment.size;
154 memory_region->used += segment.size;
155 }; 142 };
156 143
157 // Map CodeSet segments 144 // Map CodeSet segments
158 MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic); 145 MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic);
159 MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable); 146 MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable);
160 MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); 147 MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable);
161}
162
163VAddr Process::GetLinearHeapAreaAddress() const {
164 // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
165 // the extra RAM in the n3DS.
166 return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
167}
168
169VAddr Process::GetLinearHeapBase() const {
170 return GetLinearHeapAreaAddress() + memory_region->base;
171}
172
173VAddr Process::GetLinearHeapLimit() const {
174 return GetLinearHeapBase() + memory_region->size;
175} 148}
176 149
177ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { 150ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
@@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
206 vm_manager.Reprotect(vma, perms); 179 vm_manager.Reprotect(vma, perms);
207 180
208 heap_used = size; 181 heap_used = size;
209 memory_region->used += size;
210 182
211 return MakeResult<VAddr>(heap_end - size); 183 return MakeResult<VAddr>(heap_end - size);
212} 184}
@@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
226 return result; 198 return result;
227 199
228 heap_used -= size; 200 heap_used -= size;
229 memory_region->used -= size;
230
231 return RESULT_SUCCESS;
232}
233
234ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
235 UNIMPLEMENTED();
236 return {};
237}
238
239ResultCode Process::LinearFree(VAddr target, u32 size) {
240 auto& linheap_memory = memory_region->linear_heap_memory;
241
242 if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
243 target + size < target) {
244
245 return ERR_INVALID_ADDRESS;
246 }
247
248 if (size == 0) {
249 return RESULT_SUCCESS;
250 }
251
252 VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size();
253 if (target + size > heap_end) {
254 return ERR_INVALID_ADDRESS_STATE;
255 }
256
257 ResultCode result = vm_manager.UnmapRange(target, size);
258 if (result.IsError())
259 return result;
260
261 linear_heap_used -= size;
262 memory_region->used -= size;
263
264 if (target + size == heap_end) {
265 // End of linear heap has been freed, so check what's the last allocated block in it and
266 // reduce the size.
267 auto vma = vm_manager.FindVMA(target);
268 ASSERT(vma != vm_manager.vma_map.end());
269 ASSERT(vma->second.type == VMAType::Free);
270 VAddr new_end = vma->second.base;
271 if (new_end >= GetLinearHeapBase()) {
272 linheap_memory->resize(new_end - GetLinearHeapBase());
273 }
274 }
275 201
276 return RESULT_SUCCESS; 202 return RESULT_SUCCESS;
277} 203}
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <bitset> 8#include <bitset>
8#include <cstddef> 9#include <cstddef>
9#include <memory> 10#include <memory>
@@ -12,7 +13,7 @@
12#include <boost/container/static_vector.hpp> 13#include <boost/container/static_vector.hpp>
13#include "common/bit_field.h" 14#include "common/bit_field.h"
14#include "common/common_types.h" 15#include "common/common_types.h"
15#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
17#include "core/hle/kernel/vm_manager.h" 18#include "core/hle/kernel/vm_manager.h"
18 19
@@ -53,9 +54,14 @@ union ProcessFlags {
53enum class ProcessStatus { Created, Running, Exited }; 54enum class ProcessStatus { Created, Running, Exited };
54 55
55class ResourceLimit; 56class ResourceLimit;
56struct MemoryRegionInfo;
57 57
58struct CodeSet final : public Object { 58struct CodeSet final : public Object {
59 struct Segment {
60 size_t offset = 0;
61 VAddr addr = 0;
62 u32 size = 0;
63 };
64
59 static SharedPtr<CodeSet> Create(std::string name); 65 static SharedPtr<CodeSet> Create(std::string name);
60 66
61 std::string GetTypeName() const override { 67 std::string GetTypeName() const override {
@@ -70,24 +76,38 @@ struct CodeSet final : public Object {
70 return HANDLE_TYPE; 76 return HANDLE_TYPE;
71 } 77 }
72 78
73 /// Name of the process 79 Segment& CodeSegment() {
74 std::string name; 80 return segments[0];
81 }
75 82
76 std::shared_ptr<std::vector<u8>> memory; 83 const Segment& CodeSegment() const {
84 return segments[0];
85 }
77 86
78 struct Segment { 87 Segment& RODataSegment() {
79 size_t offset = 0; 88 return segments[1];
80 VAddr addr = 0; 89 }
81 u32 size = 0; 90
82 }; 91 const Segment& RODataSegment() const {
92 return segments[1];
93 }
94
95 Segment& DataSegment() {
96 return segments[2];
97 }
98
99 const Segment& DataSegment() const {
100 return segments[2];
101 }
83 102
84 Segment segments[3]; 103 std::shared_ptr<std::vector<u8>> memory;
85 Segment& code = segments[0];
86 Segment& rodata = segments[1];
87 Segment& data = segments[2];
88 104
105 std::array<Segment, 3> segments;
89 VAddr entrypoint; 106 VAddr entrypoint;
90 107
108 /// Name of the process
109 std::string name;
110
91private: 111private:
92 CodeSet(); 112 CodeSet();
93 ~CodeSet() override; 113 ~CodeSet() override;
@@ -163,12 +183,11 @@ public:
163 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous 183 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
164 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. 184 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
165 std::shared_ptr<std::vector<u8>> heap_memory; 185 std::shared_ptr<std::vector<u8>> heap_memory;
166 // The left/right bounds of the address space covered by heap_memory.
167 VAddr heap_start = 0, heap_end = 0;
168 186
169 u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0; 187 // The left/right bounds of the address space covered by heap_memory.
170 188 VAddr heap_start = 0;
171 MemoryRegionInfo* memory_region = nullptr; 189 VAddr heap_end = 0;
190 u64 heap_used = 0;
172 191
173 /// The Thread Local Storage area is allocated as processes create threads, 192 /// The Thread Local Storage area is allocated as processes create threads,
174 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part 193 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
@@ -179,16 +198,9 @@ public:
179 198
180 std::string name; 199 std::string name;
181 200
182 VAddr GetLinearHeapAreaAddress() const;
183 VAddr GetLinearHeapBase() const;
184 VAddr GetLinearHeapLimit() const;
185
186 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); 201 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
187 ResultCode HeapFree(VAddr target, u32 size); 202 ResultCode HeapFree(VAddr target, u32 size);
188 203
189 ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
190 ResultCode LinearFree(VAddr target, u32 size);
191
192 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); 204 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size);
193 205
194 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 206 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 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9 9
10namespace Kernel { 10namespace Kernel {
11 11
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <utility> 6#include <utility>
6 7
8#include "common/assert.h"
9#include "common/logging/log.h"
10#include "core/arm/arm_interface.h"
7#include "core/core.h" 11#include "core/core.h"
8#include "core/core_timing.h" 12#include "core/core_timing.h"
9#include "core/hle/kernel/process.h" 13#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 @@
8#include <vector> 8#include <vector>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/thread_queue_list.h" 10#include "common/thread_queue_list.h"
11#include "core/arm/arm_interface.h" 11#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
13 13
14class ARM_Interface;
15
14namespace Kernel { 16namespace Kernel {
15 17
16class Scheduler final { 18class 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 @@
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/hle/kernel/client_port.h" 7#include "core/hle/kernel/client_port.h"
8#include "core/hle/kernel/errors.h" 8#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/hle/kernel/server_port.h" 10#include "core/hle/kernel/server_port.h"
11#include "core/hle/kernel/server_session.h" 11#include "core/hle/kernel/server_session.h"
12#include "core/hle/kernel/thread.h" 12#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 @@
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include <tuple> 9#include <tuple>
10#include <vector>
10#include "common/common_types.h" 11#include "common/common_types.h"
11#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/wait_object.h" 13#include "core/hle/kernel/wait_object.h"
13 14
14namespace Kernel { 15namespace 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 @@
5#include <tuple> 5#include <tuple>
6#include <utility> 6#include <utility>
7 7
8#include "common/assert.h"
9#include "common/logging/log.h"
8#include "core/core.h" 10#include "core/core.h"
9#include "core/hle/ipc_helpers.h" 11#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/client_port.h" 12#include "core/hle/kernel/client_port.h"
@@ -25,7 +27,7 @@ ServerSession::~ServerSession() {
25 27
26 // Decrease the port's connection count. 28 // Decrease the port's connection count.
27 if (parent->port) 29 if (parent->port)
28 parent->port->active_sessions--; 30 parent->port->ConnectionClosed();
29 31
30 // TODO(Subv): Wake up all the ClientSession's waiting threads and set 32 // TODO(Subv): Wake up all the ClientSession's waiting threads and set
31 // the SendSyncRequest result to 0xC920181A. 33 // 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 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include "common/assert.h" 9#include <vector>
10
10#include "common/common_types.h" 11#include "common/common_types.h"
11#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/wait_object.h" 13#include "core/hle/kernel/wait_object.h"
13#include "core/hle/result.h" 14#include "core/hle/result.h"
14#include "core/memory.h"
15 15
16namespace Kernel { 16namespace Kernel {
17 17
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/object.h"
8 8
9namespace Kernel { 9namespace Kernel {
10 10
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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <utility> 5#include <utility>
6
7#include "common/assert.h"
6#include "common/logging/log.h" 8#include "common/logging/log.h"
7#include "core/core.h" 9#include "core/core.h"
8#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/memory.h"
10#include "core/hle/kernel/shared_memory.h" 11#include "core/hle/kernel/shared_memory.h"
11#include "core/memory.h" 12#include "core/memory.h"
12 13
@@ -28,35 +29,17 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
28 shared_memory->other_permissions = other_permissions; 29 shared_memory->other_permissions = other_permissions;
29 30
30 if (address == 0) { 31 if (address == 0) {
31 // We need to allocate a block from the Linear Heap ourselves. 32 shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
32 // We'll manually allocate some memory from the linear heap in the specified region. 33 shared_memory->backing_block_offset = 0;
33 MemoryRegionInfo* memory_region = GetMemoryRegion(region);
34 auto& linheap_memory = memory_region->linear_heap_memory;
35
36 ASSERT_MSG(linheap_memory->size() + size <= memory_region->size,
37 "Not enough space in region to allocate shared memory!");
38
39 shared_memory->backing_block = linheap_memory;
40 shared_memory->backing_block_offset = linheap_memory->size();
41 // Allocate some memory from the end of the linear heap for this region.
42 linheap_memory->insert(linheap_memory->end(), size, 0);
43 memory_region->used += size;
44
45 shared_memory->linear_heap_phys_address =
46 Memory::FCRAM_PADDR + memory_region->base +
47 static_cast<PAddr>(shared_memory->backing_block_offset);
48
49 // Increase the amount of used linear heap memory for the owner process.
50 if (shared_memory->owner_process != nullptr) {
51 shared_memory->owner_process->linear_heap_used += size;
52 }
53 34
54 // Refresh the address mappings for the current process. 35 // Refresh the address mappings for the current process.
55 if (Core::CurrentProcess() != nullptr) { 36 if (Core::CurrentProcess() != nullptr) {
56 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 37 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
38 shared_memory->backing_block.get());
57 } 39 }
58 } else { 40 } else {
59 auto& vm_manager = shared_memory->owner_process->vm_manager; 41 auto& vm_manager = shared_memory->owner_process->vm_manager;
42
60 // The memory is already available and mapped in the owner process. 43 // The memory is already available and mapped in the owner process.
61 auto vma = vm_manager.FindVMA(address); 44 auto vma = vm_manager.FindVMA(address);
62 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); 45 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
@@ -72,6 +55,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
72 } 55 }
73 56
74 shared_memory->base_address = address; 57 shared_memory->base_address = address;
58
75 return shared_memory; 59 return shared_memory;
76} 60}
77 61
@@ -122,11 +106,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
122 106
123 VAddr target_address = address; 107 VAddr target_address = address;
124 108
125 if (base_address == 0 && target_address == 0) {
126 // Calculate the address at which to map the memory block.
127 target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value();
128 }
129
130 // Map the memory block into the target process 109 // Map the memory block into the target process
131 auto result = target_process->vm_manager.MapMemoryBlock( 110 auto result = target_process->vm_manager.MapMemoryBlock(
132 target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 111 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <string> 8#include <string>
9#include <vector>
10
8#include "common/common_types.h" 11#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
10#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
11#include "core/hle/result.h" 14#include "core/hle/result.h"
12 15
@@ -108,9 +111,6 @@ public:
108 SharedPtr<Process> owner_process; 111 SharedPtr<Process> owner_process;
109 /// Address of shared memory block in the owner process if specified. 112 /// Address of shared memory block in the owner process if specified.
110 VAddr base_address; 113 VAddr base_address;
111 /// Physical address of the shared memory block in the linear heap if no address was specified
112 /// during creation.
113 PAddr linear_heap_phys_address;
114 /// Backing memory for this shared memory block. 114 /// Backing memory for this shared memory block.
115 std::shared_ptr<std::vector<u8>> backing_block; 115 std::shared_ptr<std::vector<u8>> backing_block;
116 /// Offset into the backing block for this shared memory. 116 /// 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 @@
5#include <algorithm> 5#include <algorithm>
6#include <cinttypes> 6#include <cinttypes>
7#include <iterator> 7#include <iterator>
8#include <mutex>
9#include <vector>
8 10
11#include "common/assert.h"
9#include "common/logging/log.h" 12#include "common/logging/log.h"
10#include "common/microprofile.h" 13#include "common/microprofile.h"
11#include "common/string_util.h" 14#include "common/string_util.h"
@@ -17,7 +20,6 @@
17#include "core/hle/kernel/event.h" 20#include "core/hle/kernel/event.h"
18#include "core/hle/kernel/handle_table.h" 21#include "core/hle/kernel/handle_table.h"
19#include "core/hle/kernel/mutex.h" 22#include "core/hle/kernel/mutex.h"
20#include "core/hle/kernel/object_address_table.h"
21#include "core/hle/kernel/process.h" 23#include "core/hle/kernel/process.h"
22#include "core/hle/kernel/resource_limit.h" 24#include "core/hle/kernel/resource_limit.h"
23#include "core/hle/kernel/shared_memory.h" 25#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)
265 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 267 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
266 info_sub_id, handle); 268 info_sub_id, handle);
267 269
268 auto& vm_manager = Core::CurrentProcess()->vm_manager; 270 const auto& vm_manager = Core::CurrentProcess()->vm_manager;
269 271
270 switch (static_cast<GetInfoType>(info_id)) { 272 switch (static_cast<GetInfoType>(info_id)) {
271 case GetInfoType::AllowedCpuIdBitmask: 273 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 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cinttypes> 6#include <cinttypes>
7#include <list>
8#include <vector> 7#include <vector>
8
9#include <boost/optional.hpp>
10#include <boost/range/algorithm_ext/erase.hpp>
11
9#include "common/assert.h" 12#include "common/assert.h"
10#include "common/common_types.h" 13#include "common/common_types.h"
11#include "common/logging/log.h" 14#include "common/logging/log.h"
@@ -17,9 +20,7 @@
17#include "core/core_timing_util.h" 20#include "core/core_timing_util.h"
18#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
19#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
20#include "core/hle/kernel/kernel.h" 23#include "core/hle/kernel/object.h"
21#include "core/hle/kernel/memory.h"
22#include "core/hle/kernel/mutex.h"
23#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
24#include "core/hle/kernel/thread.h" 25#include "core/hle/kernel/thread.h"
25#include "core/hle/result.h" 26#include "core/hle/result.h"
@@ -79,8 +80,8 @@ void Thread::Stop() {
79 wait_objects.clear(); 80 wait_objects.clear();
80 81
81 // Mark the TLS slot in the thread's page as free. 82 // Mark the TLS slot in the thread's page as free.
82 u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; 83 const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
83 u64 tls_slot = 84 const u64 tls_slot =
84 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; 85 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
85 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); 86 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
86} 87}
@@ -250,13 +251,14 @@ void Thread::ResumeFromWait() {
250 * slot: The index of the first free slot in the indicated page. 251 * slot: The index of the first free slot in the indicated page.
251 * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full). 252 * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full).
252 */ 253 */
253std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& tls_slots) { 254static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot(
255 const std::vector<std::bitset<8>>& tls_slots) {
254 // Iterate over all the allocated pages, and try to find one where not all slots are used. 256 // Iterate over all the allocated pages, and try to find one where not all slots are used.
255 for (unsigned page = 0; page < tls_slots.size(); ++page) { 257 for (std::size_t page = 0; page < tls_slots.size(); ++page) {
256 const auto& page_tls_slots = tls_slots[page]; 258 const auto& page_tls_slots = tls_slots[page];
257 if (!page_tls_slots.all()) { 259 if (!page_tls_slots.all()) {
258 // We found a page with at least one free slot, find which slot it is 260 // We found a page with at least one free slot, find which slot it is
259 for (unsigned slot = 0; slot < page_tls_slots.size(); ++slot) { 261 for (std::size_t slot = 0; slot < page_tls_slots.size(); ++slot) {
260 if (!page_tls_slots.test(slot)) { 262 if (!page_tls_slots.test(slot)) {
261 return std::make_tuple(page, slot, false); 263 return std::make_tuple(page, slot, false);
262 } 264 }
@@ -331,42 +333,22 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
331 333
332 // Find the next available TLS index, and mark it as used 334 // Find the next available TLS index, and mark it as used
333 auto& tls_slots = owner_process->tls_slots; 335 auto& tls_slots = owner_process->tls_slots;
334 bool needs_allocation = true;
335 u32 available_page; // Which allocated page has free space
336 u32 available_slot; // Which slot within the page is free
337
338 std::tie(available_page, available_slot, needs_allocation) = GetFreeThreadLocalSlot(tls_slots);
339 336
337 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
340 if (needs_allocation) { 338 if (needs_allocation) {
341 // There are no already-allocated pages with free slots, lets allocate a new one.
342 // TLS pages are allocated from the BASE region in the linear heap.
343 MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
344 auto& linheap_memory = memory_region->linear_heap_memory;
345
346 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
347 LOG_ERROR(Kernel_SVC,
348 "Not enough space in region to allocate a new TLS page for thread");
349 return ERR_OUT_OF_MEMORY;
350 }
351
352 size_t offset = linheap_memory->size();
353
354 // Allocate some memory from the end of the linear heap for this region.
355 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
356 memory_region->used += Memory::PAGE_SIZE;
357 owner_process->linear_heap_used += Memory::PAGE_SIZE;
358
359 tls_slots.emplace_back(0); // The page is completely available at the start 339 tls_slots.emplace_back(0); // The page is completely available at the start
360 available_page = static_cast<u32>(tls_slots.size() - 1); 340 available_page = tls_slots.size() - 1;
361 available_slot = 0; // Use the first slot in the new page 341 available_slot = 0; // Use the first slot in the new page
362 342
343 // Allocate some memory from the end of the linear heap for this region.
344 const size_t offset = thread->tls_memory->size();
345 thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
346
363 auto& vm_manager = owner_process->vm_manager; 347 auto& vm_manager = owner_process->vm_manager;
364 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 348 vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get());
365 349
366 // Map the page to the current process' address space.
367 // TODO(Subv): Find the correct MemoryState for this region.
368 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, 350 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
369 linheap_memory, offset, Memory::PAGE_SIZE, 351 thread->tls_memory, 0, Memory::PAGE_SIZE,
370 MemoryState::ThreadLocal); 352 MemoryState::ThreadLocal);
371 } 353 }
372 354
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <functional>
7#include <memory> 8#include <memory>
8#include <string> 9#include <string>
9#include <unordered_map>
10#include <vector> 10#include <vector>
11#include <boost/container/flat_map.hpp> 11
12#include <boost/container/flat_set.hpp>
13#include "common/common_types.h" 12#include "common/common_types.h"
14#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
15#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/wait_object.h" 15#include "core/hle/kernel/wait_object.h"
17#include "core/hle/result.h" 16#include "core/hle/result.h"
18 17
@@ -266,6 +265,8 @@ public:
266private: 265private:
267 Thread(); 266 Thread();
268 ~Thread() override; 267 ~Thread() override;
268
269 std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
269}; 270};
270 271
271/** 272/**
@@ -289,12 +290,6 @@ Thread* GetCurrentThread();
289void WaitCurrentThread_Sleep(); 290void WaitCurrentThread_Sleep();
290 291
291/** 292/**
292 * Waits the current thread from an ArbitrateAddress call
293 * @param wait_address Arbitration address used to resume from wait
294 */
295void WaitCurrentThread_ArbitrateAddress(VAddr wait_address);
296
297/**
298 * Stops the current thread and removes it from the thread_list 293 * Stops the current thread and removes it from the thread_list
299 */ 294 */
300void ExitCurrentThread(); 295void 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 @@
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/core_timing_util.h" 9#include "core/core_timing_util.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
13#include "core/hle/kernel/timer.h" 13#include "core/hle/kernel/timer.h"
14 14
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 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/wait_object.h" 9#include "core/hle/kernel/wait_object.h"
10 10
11namespace Kernel { 11namespace 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <iterator> 6#include <iterator>
6#include <utility> 7#include <utility>
7#include "common/assert.h" 8#include "common/assert.h"
@@ -175,9 +176,9 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
175 176
176ResultCode VMManager::UnmapRange(VAddr target, u64 size) { 177ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
177 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); 178 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
178 VAddr target_end = target + size; 179 const VAddr target_end = target + size;
179 180
180 VMAIter end = vma_map.end(); 181 const VMAIter end = vma_map.end();
181 // The comparison against the end of the range must be done using addresses since VMAs can be 182 // The comparison against the end of the range must be done using addresses since VMAs can be
182 // merged during this process, causing invalidation of the iterators. 183 // merged during this process, causing invalidation of the iterators.
183 while (vma != end && vma->second.base < target_end) { 184 while (vma != end && vma->second.base < target_end) {
@@ -207,9 +208,9 @@ VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission ne
207 208
208ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) { 209ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) {
209 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); 210 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
210 VAddr target_end = target + size; 211 const VAddr target_end = target + size;
211 212
212 VMAIter end = vma_map.end(); 213 const VMAIter end = vma_map.end();
213 // The comparison against the end of the range must be done using addresses since VMAs can be 214 // The comparison against the end of the range must be done using addresses since VMAs can be
214 // merged during this process, causing invalidation of the iterators. 215 // merged during this process, causing invalidation of the iterators.
215 while (vma != end && vma->second.base < target_end) { 216 while (vma != end && vma->second.base < target_end) {
@@ -258,14 +259,14 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u64 size) {
258 return ERR_INVALID_ADDRESS; 259 return ERR_INVALID_ADDRESS;
259 } 260 }
260 261
261 VirtualMemoryArea& vma = vma_handle->second; 262 const VirtualMemoryArea& vma = vma_handle->second;
262 if (vma.type != VMAType::Free) { 263 if (vma.type != VMAType::Free) {
263 // Region is already allocated 264 // Region is already allocated
264 return ERR_INVALID_ADDRESS_STATE; 265 return ERR_INVALID_ADDRESS_STATE;
265 } 266 }
266 267
267 u64 start_in_vma = base - vma.base; 268 const VAddr start_in_vma = base - vma.base;
268 u64 end_in_vma = start_in_vma + size; 269 const VAddr end_in_vma = start_in_vma + size;
269 270
270 if (end_in_vma > vma.size) { 271 if (end_in_vma > vma.size) {
271 // Requested allocation doesn't fit inside VMA 272 // Requested allocation doesn't fit inside VMA
@@ -288,17 +289,16 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u64 size) {
288 ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size); 289 ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size);
289 ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target); 290 ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target);
290 291
291 VAddr target_end = target + size; 292 const VAddr target_end = target + size;
292 ASSERT(target_end >= target); 293 ASSERT(target_end >= target);
293 ASSERT(target_end <= MAX_ADDRESS); 294 ASSERT(target_end <= MAX_ADDRESS);
294 ASSERT(size > 0); 295 ASSERT(size > 0);
295 296
296 VMAIter begin_vma = StripIterConstness(FindVMA(target)); 297 VMAIter begin_vma = StripIterConstness(FindVMA(target));
297 VMAIter i_end = vma_map.lower_bound(target_end); 298 const VMAIter i_end = vma_map.lower_bound(target_end);
298 for (auto i = begin_vma; i != i_end; ++i) { 299 if (std::any_of(begin_vma, i_end,
299 if (i->second.type == VMAType::Free) { 300 [](const auto& entry) { return entry.second.type == VMAType::Free; })) {
300 return ERR_INVALID_ADDRESS_STATE; 301 return ERR_INVALID_ADDRESS_STATE;
301 }
302 } 302 }
303 303
304 if (target != begin_vma->second.base) { 304 if (target != begin_vma->second.base) {
@@ -346,7 +346,7 @@ VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u64 offset_in_vma) {
346} 346}
347 347
348VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { 348VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
349 VMAIter next_vma = std::next(iter); 349 const VMAIter next_vma = std::next(iter);
350 if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) { 350 if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) {
351 iter->second.size += next_vma->second.size; 351 iter->second.size += next_vma->second.size;
352 vma_map.erase(next_vma); 352 vma_map.erase(next_vma);
@@ -382,22 +382,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
382 } 382 }
383} 383}
384 384
385u64 VMManager::GetTotalMemoryUsage() { 385u64 VMManager::GetTotalMemoryUsage() const {
386 LOG_WARNING(Kernel, "(STUBBED) called"); 386 LOG_WARNING(Kernel, "(STUBBED) called");
387 return 0xF8000000; 387 return 0xF8000000;
388} 388}
389 389
390u64 VMManager::GetTotalHeapUsage() { 390u64 VMManager::GetTotalHeapUsage() const {
391 LOG_WARNING(Kernel, "(STUBBED) called"); 391 LOG_WARNING(Kernel, "(STUBBED) called");
392 return 0x0; 392 return 0x0;
393} 393}
394 394
395VAddr VMManager::GetAddressSpaceBaseAddr() { 395VAddr VMManager::GetAddressSpaceBaseAddr() const {
396 LOG_WARNING(Kernel, "(STUBBED) called"); 396 LOG_WARNING(Kernel, "(STUBBED) called");
397 return 0x8000000; 397 return 0x8000000;
398} 398}
399 399
400u64 VMManager::GetAddressSpaceSize() { 400u64 VMManager::GetAddressSpaceSize() const {
401 LOG_WARNING(Kernel, "(STUBBED) called"); 401 LOG_WARNING(Kernel, "(STUBBED) called");
402 return MAX_ADDRESS; 402 return MAX_ADDRESS;
403} 403}
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:
190 void LogLayout() const; 190 void LogLayout() const;
191 191
192 /// Gets the total memory usage, used by svcGetInfo 192 /// Gets the total memory usage, used by svcGetInfo
193 u64 GetTotalMemoryUsage(); 193 u64 GetTotalMemoryUsage() const;
194 194
195 /// Gets the total heap usage, used by svcGetInfo 195 /// Gets the total heap usage, used by svcGetInfo
196 u64 GetTotalHeapUsage(); 196 u64 GetTotalHeapUsage() const;
197 197
198 /// Gets the total address space base address, used by svcGetInfo 198 /// Gets the total address space base address, used by svcGetInfo
199 VAddr GetAddressSpaceBaseAddr(); 199 VAddr GetAddressSpaceBaseAddr() const;
200 200
201 /// Gets the total address space address size, used by svcGetInfo 201 /// Gets the total address space address size, used by svcGetInfo
202 u64 GetAddressSpaceSize(); 202 u64 GetAddressSpaceSize() const;
203 203
204 /// Each VMManager has its own page table, which is set as the main one when the owning process 204 /// Each VMManager has its own page table, which is set as the main one when the owning process
205 /// is scheduled. 205 /// 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 @@
5#include <algorithm> 5#include <algorithm>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/kernel/errors.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/kernel.h"
10#include "core/hle/kernel/memory.h"
11#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
12#include "core/hle/kernel/resource_limit.h"
13#include "core/hle/kernel/thread.h" 10#include "core/hle/kernel/thread.h"
14#include "core/hle/kernel/timer.h" 11#include "core/hle/kernel/timer.h"
15 12
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 @@
7#include <vector> 7#include <vector>
8#include <boost/smart_ptr/intrusive_ptr.hpp> 8#include <boost/smart_ptr/intrusive_ptr.hpp>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11 11
12namespace Kernel { 12namespace Kernel {
13 13
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 @@
10#include "core/hle/service/acc/acc_su.h" 10#include "core/hle/service/acc/acc_su.h"
11#include "core/hle/service/acc/acc_u0.h" 11#include "core/hle/service/acc/acc_u0.h"
12#include "core/hle/service/acc/acc_u1.h" 12#include "core/hle/service/acc/acc_u1.h"
13#include "core/settings.h"
13 14
14namespace Service::Account { 15namespace Service::Account {
15 16
@@ -31,13 +32,14 @@ struct ProfileBase {
31}; 32};
32static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); 33static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
33 34
35// TODO(ogniK): Generate a real user id based on username, md5(username) maybe?
34static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; 36static constexpr u128 DEFAULT_USER_ID{1ull, 0ull};
35 37
36class IProfile final : public ServiceFramework<IProfile> { 38class IProfile final : public ServiceFramework<IProfile> {
37public: 39public:
38 explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { 40 explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
39 static const FunctionInfo functions[] = { 41 static const FunctionInfo functions[] = {
40 {0, nullptr, "Get"}, 42 {0, &IProfile::Get, "Get"},
41 {1, &IProfile::GetBase, "GetBase"}, 43 {1, &IProfile::GetBase, "GetBase"},
42 {10, nullptr, "GetImageSize"}, 44 {10, nullptr, "GetImageSize"},
43 {11, nullptr, "LoadImage"}, 45 {11, nullptr, "LoadImage"},
@@ -46,14 +48,36 @@ public:
46 } 48 }
47 49
48private: 50private:
51 void Get(Kernel::HLERequestContext& ctx) {
52 LOG_WARNING(Service_ACC, "(STUBBED) called");
53 ProfileBase profile_base{};
54 profile_base.user_id = user_id;
55 if (Settings::values.username.size() > profile_base.username.size()) {
56 std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
57 profile_base.username.begin());
58 } else {
59 std::copy(Settings::values.username.begin(), Settings::values.username.end(),
60 profile_base.username.begin());
61 }
62
63 IPC::ResponseBuilder rb{ctx, 16};
64 rb.Push(RESULT_SUCCESS);
65 rb.PushRaw(profile_base);
66 }
67
49 void GetBase(Kernel::HLERequestContext& ctx) { 68 void GetBase(Kernel::HLERequestContext& ctx) {
50 LOG_WARNING(Service_ACC, "(STUBBED) called"); 69 LOG_WARNING(Service_ACC, "(STUBBED) called");
51 70
52 // TODO(Subv): Retrieve this information from somewhere. 71 // TODO(Subv): Retrieve this information from somewhere.
53 ProfileBase profile_base{}; 72 ProfileBase profile_base{};
54 profile_base.user_id = user_id; 73 profile_base.user_id = user_id;
55 profile_base.username = {'y', 'u', 'z', 'u'}; 74 if (Settings::values.username.size() > profile_base.username.size()) {
56 75 std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
76 profile_base.username.begin());
77 } else {
78 std::copy(Settings::values.username.begin(), Settings::values.username.end(),
79 profile_base.username.begin());
80 }
57 IPC::ResponseBuilder rb{ctx, 16}; 81 IPC::ResponseBuilder rb{ctx, 16};
58 rb.Push(RESULT_SUCCESS); 82 rb.Push(RESULT_SUCCESS);
59 rb.PushRaw(profile_base); 83 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 @@
11#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applet_ae.h" 12#include "core/hle/service/am/applet_ae.h"
13#include "core/hle/service/am/applet_oe.h" 13#include "core/hle/service/am/applet_oe.h"
14#include "core/hle/service/am/idle.h"
15#include "core/hle/service/am/omm.h"
16#include "core/hle/service/am/spsm.h"
14#include "core/hle/service/apm/apm.h" 17#include "core/hle/service/apm/apm.h"
15#include "core/hle/service/filesystem/filesystem.h" 18#include "core/hle/service/filesystem/filesystem.h"
16#include "core/hle/service/nvflinger/nvflinger.h" 19#include "core/hle/service/nvflinger/nvflinger.h"
@@ -649,7 +652,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
649 // TODO(bunnei): This should be configurable 652 // TODO(bunnei): This should be configurable
650 IPC::ResponseBuilder rb{ctx, 4}; 653 IPC::ResponseBuilder rb{ctx, 4};
651 rb.Push(RESULT_SUCCESS); 654 rb.Push(RESULT_SUCCESS);
652 rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US)); 655 rb.Push(
656 static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index)));
653 LOG_DEBUG(Service_AM, "called"); 657 LOG_DEBUG(Service_AM, "called");
654} 658}
655 659
@@ -689,6 +693,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
689 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { 693 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
690 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); 694 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
691 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); 695 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
696 std::make_shared<IdleSys>()->InstallAsService(service_manager);
697 std::make_shared<OMM>()->InstallAsService(service_manager);
698 std::make_shared<SPSM>()->InstallAsService(service_manager);
692} 699}
693 700
694IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { 701IHomeMenuFunctions::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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/am/idle.h"
6
7namespace Service::AM {
8
9IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetAutoPowerDownEvent"},
13 {1, nullptr, "Unknown1"},
14 {2, nullptr, "Unknown2"},
15 {3, nullptr, "Unknown3"},
16 {4, nullptr, "Unknown4"},
17 {5, nullptr, "Unknown5"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::AM {
10
11class IdleSys final : public ServiceFramework<IdleSys> {
12public:
13 explicit IdleSys();
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/am/omm.h"
6
7namespace Service::AM {
8
9OMM::OMM() : ServiceFramework{"omm"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetOperationMode"},
13 {1, nullptr, "GetOperationModeChangeEvent"},
14 {2, nullptr, "EnableAudioVisual"},
15 {3, nullptr, "DisableAudioVisual"},
16 {4, nullptr, "EnterSleepAndWait"},
17 {5, nullptr, "GetCradleStatus"},
18 {6, nullptr, "FadeInDisplay"},
19 {7, nullptr, "FadeOutDisplay"},
20 {8, nullptr, "Unknown1"},
21 {9, nullptr, "Unknown2"},
22 {10, nullptr, "Unknown3"},
23 {11, nullptr, "Unknown4"},
24 {12, nullptr, "Unknown5"},
25 {13, nullptr, "Unknown6"},
26 {14, nullptr, "Unknown7"},
27 {15, nullptr, "Unknown8"},
28 {16, nullptr, "Unknown9"},
29 {17, nullptr, "Unknown10"},
30 {18, nullptr, "Unknown11"},
31 {19, nullptr, "Unknown12"},
32 {20, nullptr, "Unknown13"},
33 {21, nullptr, "Unknown14"},
34 {22, nullptr, "Unknown15"},
35 {23, nullptr, "Unknown16"},
36 };
37 // clang-format on
38
39 RegisterHandlers(functions);
40}
41
42} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::AM {
10
11class OMM final : public ServiceFramework<OMM> {
12public:
13 explicit OMM();
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/am/spsm.h"
6
7namespace Service::AM {
8
9SPSM::SPSM() : ServiceFramework{"spsm"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetState"},
13 {1, nullptr, "SleepSystemAndWaitAwake"},
14 {2, nullptr, "Unknown1"},
15 {3, nullptr, "Unknown2"},
16 {4, nullptr, "GetNotificationMessageEventHandle"},
17 {5, nullptr, "Unknown3"},
18 {6, nullptr, "Unknown4"},
19 {7, nullptr, "Unknown5"},
20 {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"},
21 {9, nullptr, "ChangeHomeButtonLongPressingTime"},
22 {10, nullptr, "Unknown6"},
23 {11, nullptr, "Unknown7"},
24 };
25 // clang-format on
26
27 RegisterHandlers(functions);
28}
29
30} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::AM {
10
11class SPSM final : public ServiceFramework<SPSM> {
12public:
13 explicit SPSM();
14};
15
16} // 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) {
13 auto module_ = std::make_shared<Module>(); 13 auto module_ = std::make_shared<Module>();
14 std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); 14 std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager);
15 std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager); 15 std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager);
16 std::make_shared<APM_Sys>()->InstallAsService(service_manager);
16} 17}
17 18
18} // namespace Service::APM 19} // 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) {
74 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 74 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
75 rb.Push(RESULT_SUCCESS); 75 rb.Push(RESULT_SUCCESS);
76 rb.PushIpcInterface<ISession>(); 76 rb.PushIpcInterface<ISession>();
77
78 LOG_DEBUG(Service_APM, "called");
79}
80
81APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
82 // clang-format off
83 static const FunctionInfo functions[] = {
84 {0, nullptr, "RequestPerformanceMode"},
85 {1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"},
86 {2, nullptr, "GetThrottlingState"},
87 {3, nullptr, "GetLastThrottlingState"},
88 {4, nullptr, "ClearLastThrottlingState"},
89 {5, nullptr, "LoadAndApplySettings"},
90 };
91 // clang-format on
92
93 RegisterHandlers(functions);
94}
95
96void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
97 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
98 rb.Push(RESULT_SUCCESS);
99 rb.PushIpcInterface<ISession>();
100
101 LOG_DEBUG(Service_APM, "called");
77} 102}
78 103
79} // namespace Service::APM 104} // 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:
19 std::shared_ptr<Module> apm; 19 std::shared_ptr<Module> apm;
20}; 20};
21 21
22class APM_Sys final : public ServiceFramework<APM_Sys> {
23public:
24 explicit APM_Sys();
25
26private:
27 void GetPerformanceEvent(Kernel::HLERequestContext& ctx);
28};
29
22} // namespace Service::APM 30} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/arp/arp.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::ARP {
15
16class ARP_R final : public ServiceFramework<ARP_R> {
17public:
18 explicit ARP_R() : ServiceFramework{"arp:r"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "GetApplicationLaunchProperty"},
22 {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"},
23 {2, nullptr, "GetApplicationControlProperty"},
24 {3, nullptr, "GetApplicationControlPropertyWithApplicationId"},
25 };
26 // clang-format on
27
28 RegisterHandlers(functions);
29 }
30};
31
32class IRegistrar final : public ServiceFramework<IRegistrar> {
33public:
34 explicit IRegistrar() : ServiceFramework{"IRegistrar"} {
35 // clang-format off
36 static const FunctionInfo functions[] = {
37 {0, nullptr, "Issue"},
38 {1, nullptr, "SetApplicationLaunchProperty"},
39 {2, nullptr, "SetApplicationControlProperty"},
40 };
41 // clang-format on
42
43 RegisterHandlers(functions);
44 }
45};
46
47class ARP_W final : public ServiceFramework<ARP_W> {
48public:
49 explicit ARP_W() : ServiceFramework{"arp:w"} {
50 // clang-format off
51 static const FunctionInfo functions[] = {
52 {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
53 {1, nullptr, "DeleteProperties"},
54 };
55 // clang-format on
56
57 RegisterHandlers(functions);
58 }
59
60private:
61 void AcquireRegistrar(Kernel::HLERequestContext& ctx) {
62 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
63 rb.Push(RESULT_SUCCESS);
64 rb.PushIpcInterface<IRegistrar>();
65
66 LOG_DEBUG(Service_ARP, "called");
67 }
68};
69
70void InstallInterfaces(SM::ServiceManager& sm) {
71 std::make_shared<ARP_R>()->InstallAsService(sm);
72 std::make_shared<ARP_W>()->InstallAsService(sm);
73}
74
75} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::ARP {
12
13/// Registers all ARP services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm);
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/audctl.h"
6
7namespace Service::Audio {
8
9AudCtl::AudCtl() : ServiceFramework{"audctl"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetTargetVolume"},
13 {1, nullptr, "SetTargetVolume"},
14 {2, nullptr, "GetTargetVolumeMin"},
15 {3, nullptr, "GetTargetVolumeMax"},
16 {4, nullptr, "IsTargetMute"},
17 {5, nullptr, "SetTargetMute"},
18 {6, nullptr, "IsTargetConnected"},
19 {7, nullptr, "SetDefaultTarget"},
20 {8, nullptr, "GetDefaultTarget"},
21 {9, nullptr, "GetAudioOutputMode"},
22 {10, nullptr, "SetAudioOutputMode"},
23 {11, nullptr, "SetForceMutePolicy"},
24 {12, nullptr, "GetForceMutePolicy"},
25 {13, nullptr, "GetOutputModeSetting"},
26 {14, nullptr, "SetOutputModeSetting"},
27 {15, nullptr, "SetOutputTarget"},
28 {16, nullptr, "SetInputTargetForceEnabled"},
29 {17, nullptr, "SetHeadphoneOutputLevelMode"},
30 {18, nullptr, "GetHeadphoneOutputLevelMode"},
31 {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
32 {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
33 {21, nullptr, "GetAudioOutputTargetForPlayReport"},
34 {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
35 {23, nullptr, "SetSystemOutputMasterVolume"},
36 {24, nullptr, "GetSystemOutputMasterVolume"},
37 {25, nullptr, "GetAudioVolumeDataForPlayReport"},
38 {26, nullptr, "UpdateHeadphoneSettings"},
39 };
40 // clang-format on
41
42 RegisterHandlers(functions);
43}
44
45} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudCtl final : public ServiceFramework<AudCtl> {
12public:
13 explicit AudCtl();
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/auddbg.h"
6
7namespace Service::Audio {
8
9AudDbg::AudDbg(const char* name) : ServiceFramework{name} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendForDebug"},
13 {1, nullptr, "RequestResumeForDebug"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudDbg final : public ServiceFramework<AudDbg> {
12public:
13 explicit AudDbg(const char* name);
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/audin_a.h"
6
7namespace Service::Audio {
8
9AudInA::AudInA() : ServiceFramework{"audin:a"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioIns"},
13 {1, nullptr, "RequestResumeAudioIns"},
14 {2, nullptr, "GetAudioInsProcessMasterVolume"},
15 {3, nullptr, "SetAudioInsProcessMasterVolume"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20}
21
22} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudInA final : public ServiceFramework<AudInA> {
12public:
13 explicit AudInA();
14};
15
16} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/audio/audctl.h"
6#include "core/hle/service/audio/auddbg.h"
7#include "core/hle/service/audio/audin_a.h"
5#include "core/hle/service/audio/audin_u.h" 8#include "core/hle/service/audio/audin_u.h"
6#include "core/hle/service/audio/audio.h" 9#include "core/hle/service/audio/audio.h"
10#include "core/hle/service/audio/audout_a.h"
7#include "core/hle/service/audio/audout_u.h" 11#include "core/hle/service/audio/audout_u.h"
12#include "core/hle/service/audio/audrec_a.h"
8#include "core/hle/service/audio/audrec_u.h" 13#include "core/hle/service/audio/audrec_u.h"
14#include "core/hle/service/audio/audren_a.h"
9#include "core/hle/service/audio/audren_u.h" 15#include "core/hle/service/audio/audren_u.h"
10#include "core/hle/service/audio/codecctl.h" 16#include "core/hle/service/audio/codecctl.h"
11#include "core/hle/service/audio/hwopus.h" 17#include "core/hle/service/audio/hwopus.h"
@@ -13,12 +19,22 @@
13namespace Service::Audio { 19namespace Service::Audio {
14 20
15void InstallInterfaces(SM::ServiceManager& service_manager) { 21void InstallInterfaces(SM::ServiceManager& service_manager) {
22 std::make_shared<AudCtl>()->InstallAsService(service_manager);
23 std::make_shared<AudOutA>()->InstallAsService(service_manager);
16 std::make_shared<AudOutU>()->InstallAsService(service_manager); 24 std::make_shared<AudOutU>()->InstallAsService(service_manager);
25 std::make_shared<AudInA>()->InstallAsService(service_manager);
17 std::make_shared<AudInU>()->InstallAsService(service_manager); 26 std::make_shared<AudInU>()->InstallAsService(service_manager);
27 std::make_shared<AudRecA>()->InstallAsService(service_manager);
18 std::make_shared<AudRecU>()->InstallAsService(service_manager); 28 std::make_shared<AudRecU>()->InstallAsService(service_manager);
29 std::make_shared<AudRenA>()->InstallAsService(service_manager);
19 std::make_shared<AudRenU>()->InstallAsService(service_manager); 30 std::make_shared<AudRenU>()->InstallAsService(service_manager);
20 std::make_shared<CodecCtl>()->InstallAsService(service_manager); 31 std::make_shared<CodecCtl>()->InstallAsService(service_manager);
21 std::make_shared<HwOpus>()->InstallAsService(service_manager); 32 std::make_shared<HwOpus>()->InstallAsService(service_manager);
33
34 std::make_shared<AudDbg>("audin:d")->InstallAsService(service_manager);
35 std::make_shared<AudDbg>("audout:d")->InstallAsService(service_manager);
36 std::make_shared<AudDbg>("audrec:d")->InstallAsService(service_manager);
37 std::make_shared<AudDbg>("audren:d")->InstallAsService(service_manager);
22} 38}
23 39
24} // namespace Service::Audio 40} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/audout_a.h"
6
7namespace Service::Audio {
8
9AudOutA::AudOutA() : ServiceFramework{"audout:a"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioOuts"},
13 {1, nullptr, "RequestResumeAudioOuts"},
14 {2, nullptr, "GetAudioOutsProcessMasterVolume"},
15 {3, nullptr, "SetAudioOutsProcessMasterVolume"},
16 {4, nullptr, "GetAudioOutsProcessRecordVolume"},
17 {5, nullptr, "SetAudioOutsProcessRecordVolume"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudOutA final : public ServiceFramework<AudOutA> {
12public:
13 explicit AudOutA();
14};
15
16} // 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 @@
4 4
5#include <array> 5#include <array>
6#include <vector> 6#include <vector>
7
8#include "audio_core/codec.h"
7#include "common/logging/log.h" 9#include "common/logging/log.h"
8#include "core/core_timing.h" 10#include "core/core.h"
9#include "core/core_timing_util.h"
10#include "core/hle/ipc_helpers.h" 11#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/event.h" 12#include "core/hle/kernel/event.h"
12#include "core/hle/kernel/hle_ipc.h" 13#include "core/hle/kernel/hle_ipc.h"
@@ -14,17 +15,21 @@
14 15
15namespace Service::Audio { 16namespace Service::Audio {
16 17
17/// Switch sample rate frequency 18namespace ErrCodes {
18constexpr u32 sample_rate{48000}; 19enum {
19/// TODO(st4rk): dynamic number of channels, as I think Switch has support 20 ErrorUnknown = 2,
20/// to more audio channels (probably when Docked I guess) 21 BufferCountExceeded = 8,
21constexpr u32 audio_channels{2}; 22};
22/// TODO(st4rk): find a proper value for the audio_ticks 23}
23constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 500)}; 24
25constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}};
26constexpr int DefaultSampleRate{48000};
24 27
25class IAudioOut final : public ServiceFramework<IAudioOut> { 28class IAudioOut final : public ServiceFramework<IAudioOut> {
26public: 29public:
27 IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) { 30 IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core)
31 : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) {
32
28 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
29 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, 34 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
30 {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, 35 {1, &IAudioOut::StartAudioOut, "StartAudioOut"},
@@ -32,66 +37,65 @@ public:
32 {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, 37 {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
33 {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, 38 {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
34 {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"}, 39 {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
35 {6, nullptr, "ContainsAudioOutBuffer"}, 40 {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
36 {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, 41 {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
37 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, 42 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
38 {9, nullptr, "GetAudioOutBufferCount"}, 43 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
39 {10, nullptr, "GetAudioOutPlayedSampleCount"}, 44 {10, nullptr, "GetAudioOutPlayedSampleCount"},
40 {11, nullptr, "FlushAudioOutBuffers"}, 45 {11, nullptr, "FlushAudioOutBuffers"},
41 }; 46 };
42 RegisterHandlers(functions); 47 RegisterHandlers(functions);
43 48
44 // This is the event handle used to check if the audio buffer was released 49 // This is the event handle used to check if the audio buffer was released
45 buffer_event = 50 buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
46 Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent");
47
48 // Register event callback to update the Audio Buffer
49 audio_event = CoreTiming::RegisterEvent(
50 "IAudioOut::UpdateAudioBuffersCallback", [this](u64 userdata, int cycles_late) {
51 UpdateAudioBuffersCallback();
52 CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event);
53 });
54
55 // Start the audio event
56 CoreTiming::ScheduleEvent(audio_ticks, audio_event);
57 }
58 51
59 ~IAudioOut() { 52 stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
60 CoreTiming::UnscheduleEvent(audio_event, 0); 53 "IAudioOut", [=]() { buffer_event->Signal(); });
61 } 54 }
62 55
63private: 56private:
57 struct AudioBuffer {
58 u64_le next;
59 u64_le buffer;
60 u64_le buffer_capacity;
61 u64_le buffer_size;
62 u64_le offset;
63 };
64 static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size");
65
64 void GetAudioOutState(Kernel::HLERequestContext& ctx) { 66 void GetAudioOutState(Kernel::HLERequestContext& ctx) {
65 LOG_DEBUG(Service_Audio, "called"); 67 LOG_DEBUG(Service_Audio, "called");
66 IPC::ResponseBuilder rb{ctx, 3}; 68 IPC::ResponseBuilder rb{ctx, 3};
67 rb.Push(RESULT_SUCCESS); 69 rb.Push(RESULT_SUCCESS);
68 rb.Push(static_cast<u32>(audio_out_state)); 70 rb.Push(static_cast<u32>(stream->IsPlaying() ? AudioState::Started : AudioState::Stopped));
69 } 71 }
70 72
71 void StartAudioOut(Kernel::HLERequestContext& ctx) { 73 void StartAudioOut(Kernel::HLERequestContext& ctx) {
72 LOG_WARNING(Service_Audio, "(STUBBED) called"); 74 LOG_DEBUG(Service_Audio, "called");
73 75
74 // Start audio 76 if (stream->IsPlaying()) {
75 audio_out_state = AudioState::Started; 77 IPC::ResponseBuilder rb{ctx, 2};
78 rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::ErrorUnknown));
79 return;
80 }
81
82 audio_core.StartStream(stream);
76 83
77 IPC::ResponseBuilder rb{ctx, 2}; 84 IPC::ResponseBuilder rb{ctx, 2};
78 rb.Push(RESULT_SUCCESS); 85 rb.Push(RESULT_SUCCESS);
79 } 86 }
80 87
81 void StopAudioOut(Kernel::HLERequestContext& ctx) { 88 void StopAudioOut(Kernel::HLERequestContext& ctx) {
82 LOG_WARNING(Service_Audio, "(STUBBED) called"); 89 LOG_DEBUG(Service_Audio, "called");
83
84 // Stop audio
85 audio_out_state = AudioState::Stopped;
86 90
87 queue_keys.clear(); 91 audio_core.StopStream(stream);
88 92
89 IPC::ResponseBuilder rb{ctx, 2}; 93 IPC::ResponseBuilder rb{ctx, 2};
90 rb.Push(RESULT_SUCCESS); 94 rb.Push(RESULT_SUCCESS);
91 } 95 }
92 96
93 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { 97 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
94 LOG_WARNING(Service_Audio, "(STUBBED) called"); 98 LOG_DEBUG(Service_Audio, "called");
95 99
96 IPC::ResponseBuilder rb{ctx, 2, 1}; 100 IPC::ResponseBuilder rb{ctx, 2, 1};
97 rb.Push(RESULT_SUCCESS); 101 rb.Push(RESULT_SUCCESS);
@@ -99,101 +103,107 @@ private:
99 } 103 }
100 104
101 void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { 105 void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
102 LOG_WARNING(Service_Audio, "(STUBBED) called"); 106 LOG_DEBUG(Service_Audio, "(STUBBED) called {}", ctx.Description());
103 IPC::RequestParser rp{ctx}; 107 IPC::RequestParser rp{ctx};
104 108
105 const u64 key{rp.Pop<u64>()}; 109 const auto& input_buffer{ctx.ReadBuffer()};
106 queue_keys.insert(queue_keys.begin(), key); 110 ASSERT_MSG(input_buffer.size() == sizeof(AudioBuffer),
111 "AudioBuffer input is an invalid size!");
112 AudioBuffer audio_buffer{};
113 std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer));
114 const u64 tag{rp.Pop<u64>()};
115
116 std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16));
117 Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size);
118
119 if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) {
120 IPC::ResponseBuilder rb{ctx, 2};
121 rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded));
122 }
107 123
108 IPC::ResponseBuilder rb{ctx, 2}; 124 IPC::ResponseBuilder rb{ctx, 2};
109 rb.Push(RESULT_SUCCESS); 125 rb.Push(RESULT_SUCCESS);
110 } 126 }
111 127
112 void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { 128 void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
113 LOG_WARNING(Service_Audio, "(STUBBED) called"); 129 LOG_DEBUG(Service_Audio, "called {}", ctx.Description());
114 130 IPC::RequestParser rp{ctx};
115 // TODO(st4rk): This is how libtransistor currently implements the 131 const u64 max_count{ctx.GetWriteBufferSize() / sizeof(u64)};
116 // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address 132 const auto released_buffers{audio_core.GetTagsAndReleaseBuffers(stream, max_count)};
117 // is used to know which buffer should be filled with data and send again to the service
118 // through AppendAudioOutBuffer. Check if this is the proper way to do it.
119 u64 key{0};
120
121 if (queue_keys.size()) {
122 key = queue_keys.back();
123 queue_keys.pop_back();
124 }
125 133
126 ctx.WriteBuffer(&key, sizeof(u64)); 134 std::vector<u64> tags{released_buffers};
135 tags.resize(max_count);
136 ctx.WriteBuffer(tags);
127 137
128 IPC::ResponseBuilder rb{ctx, 3}; 138 IPC::ResponseBuilder rb{ctx, 3};
129 rb.Push(RESULT_SUCCESS); 139 rb.Push(RESULT_SUCCESS);
130 // TODO(st4rk): This might be the total of released buffers, needs to be verified on 140 rb.Push<u32>(static_cast<u32>(released_buffers.size()));
131 // hardware
132 rb.Push<u32>(static_cast<u32>(queue_keys.size()));
133 } 141 }
134 142
135 void UpdateAudioBuffersCallback() { 143 void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) {
136 if (audio_out_state != AudioState::Started) { 144 LOG_DEBUG(Service_Audio, "called");
137 return; 145 IPC::RequestParser rp{ctx};
138 } 146 const u64 tag{rp.Pop<u64>()};
139 147 IPC::ResponseBuilder rb{ctx, 3};
140 if (queue_keys.empty()) { 148 rb.Push(RESULT_SUCCESS);
141 return; 149 rb.Push(stream->ContainsBuffer(tag));
142 } 150 }
143 151
144 buffer_event->Signal(); 152 void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) {
153 LOG_DEBUG(Service_Audio, "called");
154 IPC::ResponseBuilder rb{ctx, 3};
155 rb.Push(RESULT_SUCCESS);
156 rb.Push(static_cast<u32>(stream->GetQueueSize()));
145 } 157 }
146 158
147 enum class AudioState : u32 { 159 AudioCore::AudioOut& audio_core;
148 Started, 160 AudioCore::StreamPtr stream;
149 Stopped,
150 };
151 161
152 /// This is used to trigger the audio event callback that is going to read the samples from the 162 AudoutParams audio_params{};
153 /// audio_buffer list and enqueue the samples using the sink (audio_core).
154 CoreTiming::EventType* audio_event;
155 163
156 /// This is the evend handle used to check if the audio buffer was released 164 /// This is the evend handle used to check if the audio buffer was released
157 Kernel::SharedPtr<Kernel::Event> buffer_event; 165 Kernel::SharedPtr<Kernel::Event> buffer_event;
158
159 /// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor
160 /// uses the key as an address in the App, so we need to return when the
161 /// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because
162 /// libtransistor uses the key returned as an pointer.
163 std::vector<u64> queue_keys;
164
165 AudioState audio_out_state;
166}; 166};
167 167
168void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { 168void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
169 LOG_WARNING(Service_Audio, "(STUBBED) called"); 169 LOG_DEBUG(Service_Audio, "called");
170 IPC::RequestParser rp{ctx}; 170 IPC::RequestParser rp{ctx};
171 171
172 constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; 172 ctx.WriteBuffer(DefaultDevice);
173 ctx.WriteBuffer(audio_interface);
174 173
175 IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); 174 IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
176 175
177 rb.Push(RESULT_SUCCESS); 176 rb.Push(RESULT_SUCCESS);
178 // TODO(st4rk): We're currently returning only one audio interface (stringlist size). However, 177 rb.Push<u32>(1); // Amount of audio devices
179 // it's highly possible to have more than one interface (despite that libtransistor requires
180 // only one).
181 rb.Push<u32>(1);
182} 178}
183 179
184void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) { 180void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
185 LOG_WARNING(Service_Audio, "(STUBBED) called"); 181 LOG_DEBUG(Service_Audio, "called");
186 182
187 if (!audio_out_interface) { 183 ctx.WriteBuffer(DefaultDevice);
188 audio_out_interface = std::make_shared<IAudioOut>(); 184 IPC::RequestParser rp{ctx};
185 auto params{rp.PopRaw<AudoutParams>()};
186 if (params.channel_count <= 2) {
187 // Mono does not exist for audout
188 params.channel_count = 2;
189 } else {
190 params.channel_count = 6;
189 } 191 }
192 if (!params.sample_rate) {
193 params.sample_rate = DefaultSampleRate;
194 }
195
196 // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
197 // will likely need to be updated as well.
198 ASSERT_MSG(!audio_out_interface, "Unimplemented");
199 audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core);
190 200
191 IPC::ResponseBuilder rb{ctx, 6, 0, 1}; 201 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
192 rb.Push(RESULT_SUCCESS); 202 rb.Push(RESULT_SUCCESS);
193 rb.Push<u32>(sample_rate); 203 rb.Push<u32>(DefaultSampleRate);
194 rb.Push<u32>(audio_channels); 204 rb.Push<u32>(params.channel_count);
195 rb.Push<u32>(static_cast<u32>(PcmFormat::Int16)); 205 rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16));
196 rb.Push<u32>(0); // This field is unknown 206 rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
197 rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); 207 rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);
198} 208}
199 209
@@ -203,6 +213,7 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") {
203 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"}, 213 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"},
204 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}}; 214 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}};
205 RegisterHandlers(functions); 215 RegisterHandlers(functions);
216 audio_core = std::make_unique<AudioCore::AudioOut>();
206} 217}
207 218
208} // namespace Service::Audio 219} // 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "audio_core/audio_out.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Kernel { 10namespace Kernel {
@@ -12,6 +13,18 @@ class HLERequestContext;
12 13
13namespace Service::Audio { 14namespace Service::Audio {
14 15
16struct AudoutParams {
17 s32_le sample_rate;
18 u16_le channel_count;
19 INSERT_PADDING_BYTES(2);
20};
21static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size");
22
23enum class AudioState : u32 {
24 Started,
25 Stopped,
26};
27
15class IAudioOut; 28class IAudioOut;
16 29
17class AudOutU final : public ServiceFramework<AudOutU> { 30class AudOutU final : public ServiceFramework<AudOutU> {
@@ -21,19 +34,10 @@ public:
21 34
22private: 35private:
23 std::shared_ptr<IAudioOut> audio_out_interface; 36 std::shared_ptr<IAudioOut> audio_out_interface;
37 std::unique_ptr<AudioCore::AudioOut> audio_core;
24 38
25 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); 39 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
26 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); 40 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx);
27
28 enum class PcmFormat : u32 {
29 Invalid = 0,
30 Int8 = 1,
31 Int16 = 2,
32 Int24 = 3,
33 Int32 = 4,
34 PcmFloat = 5,
35 Adpcm = 6,
36 };
37}; 41};
38 42
39} // namespace Service::Audio 43} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/audrec_a.h"
6
7namespace Service::Audio {
8
9AudRecA::AudRecA() : ServiceFramework{"audrec:a"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendFinalOutputRecorders"},
13 {1, nullptr, "RequestResumeFinalOutputRecorders"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudRecA final : public ServiceFramework<AudRecA> {
12public:
13 explicit AudRecA();
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/audio/audren_a.h"
6
7namespace Service::Audio {
8
9AudRenA::AudRenA() : ServiceFramework{"audren:a"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioRenderers"},
13 {1, nullptr, "RequestResumeAudioRenderers"},
14 {2, nullptr, "GetAudioRenderersProcessMasterVolume"},
15 {3, nullptr, "SetAudioRenderersProcessMasterVolume"},
16 {4, nullptr, "RegisterAppletResourceUserId"},
17 {5, nullptr, "UnregisterAppletResourceUserId"},
18 {6, nullptr, "GetAudioRenderersProcessRecordVolume"},
19 {7, nullptr, "SetAudioRenderersProcessRecordVolume"},
20 };
21 // clang-format on
22
23 RegisterHandlers(functions);
24}
25
26} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class AudRenA final : public ServiceFramework<AudRenA> {
12public:
13 explicit AudRenA();
14};
15
16} // 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 @@
15 15
16namespace Service::Audio { 16namespace Service::Audio {
17 17
18/// TODO(bunnei): Find a proper value for the audio_ticks
19constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)};
20
21class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { 18class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
22public: 19public:
23 explicit IAudioRenderer(AudioRendererParameter audren_params) 20 explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params)
24 : ServiceFramework("IAudioRenderer"), worker_params(audren_params) { 21 : ServiceFramework("IAudioRenderer") {
25 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
26 {0, nullptr, "GetAudioRendererSampleRate"}, 23 {0, nullptr, "GetAudioRendererSampleRate"},
27 {1, nullptr, "GetAudioRendererSampleCount"}, 24 {1, nullptr, "GetAudioRendererSampleCount"},
@@ -39,21 +36,8 @@ public:
39 RegisterHandlers(functions); 36 RegisterHandlers(functions);
40 37
41 system_event = 38 system_event =
42 Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioRenderer:SystemEvent"); 39 Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent");
43 40 renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event);
44 // Register event callback to update the Audio Buffer
45 audio_event = CoreTiming::RegisterEvent(
46 "IAudioRenderer::UpdateAudioCallback", [this](u64 userdata, int cycles_late) {
47 UpdateAudioCallback();
48 CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event);
49 });
50
51 // Start the audio event
52 CoreTiming::ScheduleEvent(audio_ticks, audio_event);
53 voice_status_list.resize(worker_params.voice_count);
54 }
55 ~IAudioRenderer() {
56 CoreTiming::UnscheduleEvent(audio_event, 0);
57 } 41 }
58 42
59private: 43private:
@@ -62,60 +46,9 @@ private:
62 } 46 }
63 47
64 void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { 48 void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) {
65 UpdateDataHeader config{}; 49 ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer()));
66 auto buf = ctx.ReadBuffer();
67 std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader));
68 u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
69
70 std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
71 std::memcpy(mem_pool_info.data(),
72 buf.data() + sizeof(UpdateDataHeader) + config.behavior_size,
73 memory_pool_count * sizeof(MemoryPoolInfo));
74
75 std::vector<VoiceInfo> voice_info(worker_params.voice_count);
76 std::memcpy(voice_info.data(),
77 buf.data() + sizeof(UpdateDataHeader) + config.behavior_size +
78 config.memory_pools_size + config.voice_resource_size,
79 worker_params.voice_count * sizeof(VoiceInfo));
80
81 UpdateDataHeader response_data{worker_params};
82
83 ASSERT(ctx.GetWriteBufferSize() == response_data.total_size);
84
85 std::vector<u8> output(response_data.total_size);
86 std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader));
87 std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
88 for (unsigned i = 0; i < memory_pool.size(); i++) {
89 if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach)
90 memory_pool[i].state = MemoryPoolStates::Attached;
91 else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach)
92 memory_pool[i].state = MemoryPoolStates::Detached;
93 }
94 std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(),
95 response_data.memory_pools_size);
96
97 for (unsigned i = 0; i < voice_info.size(); i++) {
98 if (voice_info[i].is_new) {
99 voice_status_list[i].played_sample_count = 0;
100 voice_status_list[i].wave_buffer_consumed = 0;
101 } else if (voice_info[i].play_state == (u8)PlayStates::Started) {
102 for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) {
103 voice_status_list[i].played_sample_count +=
104 (voice_info[i].wave_buffer[buff_idx].end_sample_offset -
105 voice_info[i].wave_buffer[buff_idx].start_sample_offset) /
106 2;
107 voice_status_list[i].wave_buffer_consumed++;
108 }
109 }
110 }
111 std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size,
112 voice_status_list.data(), response_data.voices_size);
113
114 ctx.WriteBuffer(output);
115
116 IPC::ResponseBuilder rb{ctx, 2}; 50 IPC::ResponseBuilder rb{ctx, 2};
117 rb.Push(RESULT_SUCCESS); 51 rb.Push(RESULT_SUCCESS);
118
119 LOG_WARNING(Service_Audio, "(STUBBED) called"); 52 LOG_WARNING(Service_Audio, "(STUBBED) called");
120 } 53 }
121 54
@@ -136,8 +69,6 @@ private:
136 } 69 }
137 70
138 void QuerySystemEvent(Kernel::HLERequestContext& ctx) { 71 void QuerySystemEvent(Kernel::HLERequestContext& ctx) {
139 // system_event->Signal();
140
141 IPC::ResponseBuilder rb{ctx, 2, 1}; 72 IPC::ResponseBuilder rb{ctx, 2, 1};
142 rb.Push(RESULT_SUCCESS); 73 rb.Push(RESULT_SUCCESS);
143 rb.PushCopyObjects(system_event); 74 rb.PushCopyObjects(system_event);
@@ -145,131 +76,8 @@ private:
145 LOG_WARNING(Service_Audio, "(STUBBED) called"); 76 LOG_WARNING(Service_Audio, "(STUBBED) called");
146 } 77 }
147 78
148 enum class MemoryPoolStates : u32 { // Should be LE
149 Invalid = 0x0,
150 Unknown = 0x1,
151 RequestDetach = 0x2,
152 Detached = 0x3,
153 RequestAttach = 0x4,
154 Attached = 0x5,
155 Released = 0x6,
156 };
157
158 enum class PlayStates : u8 {
159 Started = 0,
160 Stopped = 1,
161 };
162
163 struct MemoryPoolEntry {
164 MemoryPoolStates state;
165 u32_le unknown_4;
166 u32_le unknown_8;
167 u32_le unknown_c;
168 };
169 static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
170
171 struct MemoryPoolInfo {
172 u64_le pool_address;
173 u64_le pool_size;
174 MemoryPoolStates pool_state;
175 INSERT_PADDING_WORDS(3); // Unknown
176 };
177 static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
178
179 struct UpdateDataHeader {
180 UpdateDataHeader() {}
181
182 explicit UpdateDataHeader(const AudioRendererParameter& config) {
183 revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
184 behavior_size = 0xb0;
185 memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
186 voices_size = config.voice_count * 0x10;
187 voice_resource_size = 0x0;
188 effects_size = config.effect_count * 0x10;
189 mixes_size = 0x0;
190 sinks_size = config.sink_count * 0x20;
191 performance_manager_size = 0x10;
192 total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size +
193 voices_size + effects_size + sinks_size + performance_manager_size;
194 }
195
196 u32_le revision;
197 u32_le behavior_size;
198 u32_le memory_pools_size;
199 u32_le voices_size;
200 u32_le voice_resource_size;
201 u32_le effects_size;
202 u32_le mixes_size;
203 u32_le sinks_size;
204 u32_le performance_manager_size;
205 INSERT_PADDING_WORDS(6);
206 u32_le total_size;
207 };
208 static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
209
210 struct BiquadFilter {
211 u8 enable;
212 INSERT_PADDING_BYTES(1);
213 s16_le numerator[3];
214 s16_le denominator[2];
215 };
216 static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
217
218 struct WaveBuffer {
219 u64_le buffer_addr;
220 u64_le buffer_sz;
221 s32_le start_sample_offset;
222 s32_le end_sample_offset;
223 u8 loop;
224 u8 end_of_stream;
225 u8 sent_to_server;
226 INSERT_PADDING_BYTES(5);
227 u64 context_addr;
228 u64 context_sz;
229 INSERT_PADDING_BYTES(8);
230 };
231 static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
232
233 struct VoiceInfo {
234 u32_le id;
235 u32_le node_id;
236 u8 is_new;
237 u8 is_in_use;
238 u8 play_state;
239 u8 sample_format;
240 u32_le sample_rate;
241 u32_le priority;
242 u32_le sorting_order;
243 u32_le channel_count;
244 float_le pitch;
245 float_le volume;
246 BiquadFilter biquad_filter[2];
247 u32_le wave_buffer_count;
248 u16_le wave_buffer_head;
249 INSERT_PADDING_BYTES(6);
250 u64_le additional_params_addr;
251 u64_le additional_params_sz;
252 u32_le mix_id;
253 u32_le splitter_info_id;
254 WaveBuffer wave_buffer[4];
255 u32_le voice_channel_resource_ids[6];
256 INSERT_PADDING_BYTES(24);
257 };
258 static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
259
260 struct VoiceOutStatus {
261 u64_le played_sample_count;
262 u32_le wave_buffer_consumed;
263 INSERT_PADDING_WORDS(1);
264 };
265 static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
266
267 /// This is used to trigger the audio event callback.
268 CoreTiming::EventType* audio_event;
269
270 Kernel::SharedPtr<Kernel::Event> system_event; 79 Kernel::SharedPtr<Kernel::Event> system_event;
271 AudioRendererParameter worker_params; 80 std::unique_ptr<AudioCore::AudioRenderer> renderer;
272 std::vector<VoiceOutStatus> voice_status_list;
273}; 81};
274 82
275class IAudioDevice final : public ServiceFramework<IAudioDevice> { 83class IAudioDevice final : public ServiceFramework<IAudioDevice> {
@@ -368,7 +176,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {
368 176
369void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { 177void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
370 IPC::RequestParser rp{ctx}; 178 IPC::RequestParser rp{ctx};
371 auto params = rp.PopRaw<AudioRendererParameter>(); 179 auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
372 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 180 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
373 181
374 rb.Push(RESULT_SUCCESS); 182 rb.Push(RESULT_SUCCESS);
@@ -379,7 +187,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
379 187
380void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { 188void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
381 IPC::RequestParser rp{ctx}; 189 IPC::RequestParser rp{ctx};
382 auto params = rp.PopRaw<AudioRendererParameter>(); 190 auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
383 191
384 u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); 192 u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40);
385 buffer_sz += params.unknown_c * 1024; 193 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "audio_core/audio_renderer.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Kernel { 10namespace Kernel {
@@ -12,24 +13,6 @@ class HLERequestContext;
12 13
13namespace Service::Audio { 14namespace Service::Audio {
14 15
15struct AudioRendererParameter {
16 u32_le sample_rate;
17 u32_le sample_count;
18 u32_le unknown_8;
19 u32_le unknown_c;
20 u32_le voice_count;
21 u32_le sink_count;
22 u32_le effect_count;
23 u32_le unknown_1c;
24 u8 unknown_20;
25 INSERT_PADDING_BYTES(3);
26 u32_le splitter_count;
27 u32_le unknown_2c;
28 INSERT_PADDING_WORDS(1);
29 u32_le revision;
30};
31static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
32
33class AudRenU final : public ServiceFramework<AudRenU> { 16class AudRenU final : public ServiceFramework<AudRenU> {
34public: 17public:
35 explicit AudRenU(); 18 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
6#include <opus.h>
5#include "common/logging/log.h" 7#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/hle_ipc.h" 9#include "core/hle/kernel/hle_ipc.h"
@@ -9,19 +11,142 @@
9 11
10namespace Service::Audio { 12namespace Service::Audio {
11 13
14struct OpusDeleter {
15 void operator()(void* ptr) const {
16 operator delete(ptr);
17 }
18};
19
20class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
21public:
22 IHardwareOpusDecoderManager(std::unique_ptr<OpusDecoder, OpusDeleter> decoder, u32 sample_rate,
23 u32 channel_count)
24 : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)),
25 sample_rate(sample_rate), channel_count(channel_count) {
26 static const FunctionInfo functions[] = {
27 {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
28 {1, nullptr, "SetContext"},
29 {2, nullptr, "DecodeInterleavedForMultiStream"},
30 {3, nullptr, "SetContextForMultiStream"},
31 {4, nullptr, "Unknown4"},
32 {5, nullptr, "Unknown5"},
33 {6, nullptr, "Unknown6"},
34 {7, nullptr, "Unknown7"},
35 };
36 RegisterHandlers(functions);
37 }
38
39private:
40 void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
41 u32 consumed = 0;
42 u32 sample_count = 0;
43 std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
44 if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) {
45 IPC::ResponseBuilder rb{ctx, 2};
46 // TODO(ogniK): Use correct error code
47 rb.Push(ResultCode(-1));
48 return;
49 }
50 IPC::ResponseBuilder rb{ctx, 4};
51 rb.Push(RESULT_SUCCESS);
52 rb.Push<u32>(consumed);
53 rb.Push<u32>(sample_count);
54 ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16));
55 }
56
57 bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input,
58 std::vector<opus_int16>& output) {
59 size_t raw_output_sz = output.size() * sizeof(opus_int16);
60 if (sizeof(OpusHeader) > input.size())
61 return false;
62 OpusHeader hdr{};
63 std::memcpy(&hdr, input.data(), sizeof(OpusHeader));
64 if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) {
65 return false;
66 }
67 auto frame = input.data() + sizeof(OpusHeader);
68 auto decoded_sample_count = opus_packet_get_nb_samples(
69 frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)),
70 static_cast<opus_int32>(sample_rate));
71 if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz)
72 return false;
73 auto out_sample_count =
74 opus_decode(decoder.get(), frame, hdr.sz, output.data(),
75 (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)), 0);
76 if (out_sample_count < 0)
77 return false;
78 sample_count = out_sample_count;
79 consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz);
80 return true;
81 }
82
83 struct OpusHeader {
84 u32_be sz; // Needs to be BE for some odd reason
85 INSERT_PADDING_WORDS(1);
86 };
87 static_assert(sizeof(OpusHeader) == 0x8, "OpusHeader is an invalid size");
88
89 std::unique_ptr<OpusDecoder, OpusDeleter> decoder;
90 u32 sample_rate;
91 u32 channel_count;
92};
93
94static size_t WorkerBufferSize(u32 channel_count) {
95 ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
96 return opus_decoder_get_size(static_cast<int>(channel_count));
97}
98
12void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { 99void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
13 LOG_WARNING(Service_Audio, "(STUBBED) called"); 100 IPC::RequestParser rp{ctx};
101 auto sample_rate = rp.Pop<u32>();
102 auto channel_count = rp.Pop<u32>();
103 ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
104 sample_rate == 12000 || sample_rate == 8000,
105 "Invalid sample rate");
106 ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
107 u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count));
108 LOG_DEBUG(Audio, "called worker_buffer_sz={}", worker_buffer_sz);
109
14 IPC::ResponseBuilder rb{ctx, 3}; 110 IPC::ResponseBuilder rb{ctx, 3};
15 rb.Push(RESULT_SUCCESS); 111 rb.Push(RESULT_SUCCESS);
16 rb.Push<u32>(0x4000); 112 rb.Push<u32>(worker_buffer_sz);
113}
114
115void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
116 IPC::RequestParser rp{ctx};
117 auto sample_rate = rp.Pop<u32>();
118 auto channel_count = rp.Pop<u32>();
119 auto buffer_sz = rp.Pop<u32>();
120 LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate,
121 channel_count, buffer_sz);
122 ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
123 sample_rate == 12000 || sample_rate == 8000,
124 "Invalid sample rate");
125 ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
126
127 size_t worker_sz = WorkerBufferSize(channel_count);
128 ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large");
129 std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
130 static_cast<OpusDecoder*>(operator new(worker_sz))};
131 if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
132 IPC::ResponseBuilder rb{ctx, 2};
133 // TODO(ogniK): Use correct error code
134 rb.Push(ResultCode(-1));
135 return;
136 }
137
138 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
139 rb.Push(RESULT_SUCCESS);
140 rb.PushIpcInterface<IHardwareOpusDecoderManager>(std::move(decoder), sample_rate,
141 channel_count);
17} 142}
18 143
19HwOpus::HwOpus() : ServiceFramework("hwopus") { 144HwOpus::HwOpus() : ServiceFramework("hwopus") {
20 static const FunctionInfo functions[] = { 145 static const FunctionInfo functions[] = {
21 {0, nullptr, "Initialize"}, 146 {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"},
22 {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, 147 {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
23 {2, nullptr, "InitializeMultiStream"}, 148 {2, nullptr, "OpenOpusDecoderForMultiStream"},
24 {3, nullptr, "GetWorkBufferSizeMultiStream"}, 149 {3, nullptr, "GetWorkBufferSizeForMultiStream"},
25 }; 150 };
26 RegisterHandlers(functions); 151 RegisterHandlers(functions);
27} 152}
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:
14 ~HwOpus() = default; 14 ~HwOpus() = default;
15 15
16private: 16private:
17 void OpenOpusDecoder(Kernel::HLERequestContext& ctx);
17 void GetWorkBufferSize(Kernel::HLERequestContext& ctx); 18 void GetWorkBufferSize(Kernel::HLERequestContext& ctx);
18}; 19};
19 20
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/bpc/bpc.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::BPC {
12
13class BPC final : public ServiceFramework<BPC> {
14public:
15 explicit BPC() : ServiceFramework{"bpc"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "ShutdownSystem"},
19 {1, nullptr, "RebootSystem"},
20 {2, nullptr, "GetWakeupReason"},
21 {3, nullptr, "GetShutdownReason"},
22 {4, nullptr, "GetAcOk"},
23 {5, nullptr, "GetBoardPowerControlEvent"},
24 {6, nullptr, "GetSleepButtonState"},
25 {7, nullptr, "GetPowerEvent"},
26 {8, nullptr, "Unknown1"},
27 {9, nullptr, "Unknown2"},
28 {10, nullptr, "Unknown3"},
29 };
30 // clang-format on
31
32 RegisterHandlers(functions);
33 }
34};
35
36class BPC_R final : public ServiceFramework<BPC_R> {
37public:
38 explicit BPC_R() : ServiceFramework{"bpc:r"} {
39 // clang-format off
40 static const FunctionInfo functions[] = {
41 {0, nullptr, "GetExternalRtcValue"},
42 {1, nullptr, "SetExternalRtcValue"},
43 {2, nullptr, "ReadExternalRtcResetFlag"},
44 {3, nullptr, "ClearExternalRtcResetFlag"},
45 };
46 // clang-format on
47
48 RegisterHandlers(functions);
49 }
50};
51
52void InstallInterfaces(SM::ServiceManager& sm) {
53 std::make_shared<BPC>()->InstallAsService(sm);
54 std::make_shared<BPC_R>()->InstallAsService(sm);
55}
56
57} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::BPC {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/btdrv/btdrv.h"
6#include "core/hle/service/service.h"
7#include "core/hle/service/sm/sm.h"
8
9namespace Service::BtDrv {
10
11class BtDrv final : public ServiceFramework<BtDrv> {
12public:
13 explicit BtDrv() : ServiceFramework{"btdrv"} {
14 // clang-format off
15 static const FunctionInfo functions[] = {
16 {0, nullptr, "Unknown"},
17 {1, nullptr, "Init"},
18 {2, nullptr, "Enable"},
19 {3, nullptr, "Disable"},
20 {4, nullptr, "CleanupAndShutdown"},
21 {5, nullptr, "GetAdapterProperties"},
22 {6, nullptr, "GetAdapterProperty"},
23 {7, nullptr, "SetAdapterProperty"},
24 {8, nullptr, "StartDiscovery"},
25 {9, nullptr, "CancelDiscovery"},
26 {10, nullptr, "CreateBond"},
27 {11, nullptr, "RemoveBond"},
28 {12, nullptr, "CancelBond"},
29 {13, nullptr, "PinReply"},
30 {14, nullptr, "SspReply"},
31 {15, nullptr, "Unknown2"},
32 {16, nullptr, "InitInterfaces"},
33 {17, nullptr, "HidHostInterface_Connect"},
34 {18, nullptr, "HidHostInterface_Disconnect"},
35 {19, nullptr, "HidHostInterface_SendData"},
36 {20, nullptr, "HidHostInterface_SendData2"},
37 {21, nullptr, "HidHostInterface_SetReport"},
38 {22, nullptr, "HidHostInterface_GetReport"},
39 {23, nullptr, "HidHostInterface_WakeController"},
40 {24, nullptr, "HidHostInterface_AddPairedDevice"},
41 {25, nullptr, "HidHostInterface_GetPairedDevice"},
42 {26, nullptr, "HidHostInterface_CleanupAndShutdown"},
43 {27, nullptr, "Unknown3"},
44 {28, nullptr, "ExtInterface_SetTSI"},
45 {29, nullptr, "ExtInterface_SetBurstMode"},
46 {30, nullptr, "ExtInterface_SetZeroRetran"},
47 {31, nullptr, "ExtInterface_SetMcMode"},
48 {32, nullptr, "ExtInterface_StartLlrMode"},
49 {33, nullptr, "ExtInterface_ExitLlrMode"},
50 {34, nullptr, "ExtInterface_SetRadio"},
51 {35, nullptr, "ExtInterface_SetVisibility"},
52 {36, nullptr, "Unknown4"},
53 {37, nullptr, "Unknown5"},
54 {38, nullptr, "HidHostInterface_GetLatestPlr"},
55 {39, nullptr, "ExtInterface_GetPendingConnections"},
56 {40, nullptr, "HidHostInterface_GetChannelMap"},
57 {41, nullptr, "SetIsBluetoothBoostEnabled"},
58 {42, nullptr, "GetIsBluetoothBoostEnabled"},
59 {43, nullptr, "SetIsBluetoothAfhEnabled"},
60 {44, nullptr, "GetIsBluetoothAfhEnabled"},
61 };
62 // clang-format on
63
64 RegisterHandlers(functions);
65 }
66};
67
68void InstallInterfaces(SM::ServiceManager& sm) {
69 std::make_shared<BtDrv>()->InstallAsService(sm);
70}
71
72} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::BtDrv {
12
13/// Registers all BtDrv services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm);
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/btm/btm.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::BTM {
15
16class BTM final : public ServiceFramework<BTM> {
17public:
18 explicit BTM() : ServiceFramework{"btm"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "Unknown1"},
22 {1, nullptr, "Unknown2"},
23 {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"},
24 {3, nullptr, "Unknown3"},
25 {4, nullptr, "Unknown4"},
26 {5, nullptr, "Unknown5"},
27 {6, nullptr, "Unknown6"},
28 {7, nullptr, "Unknown7"},
29 {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"},
30 {9, nullptr, "Unknown8"},
31 {10, nullptr, "Unknown9"},
32 {11, nullptr, "Unknown10"},
33 {12, nullptr, "Unknown11"},
34 {13, nullptr, "Unknown12"},
35 {14, nullptr, "EnableRadioImpl"},
36 {15, nullptr, "DisableRadioImpl"},
37 {16, nullptr, "Unknown13"},
38 {17, nullptr, "Unknown14"},
39 {18, nullptr, "Unknown15"},
40 {19, nullptr, "Unknown16"},
41 {20, nullptr, "Unknown17"},
42 {21, nullptr, "Unknown18"},
43 };
44 // clang-format on
45
46 RegisterHandlers(functions);
47 }
48};
49
50class BTM_DBG final : public ServiceFramework<BTM_DBG> {
51public:
52 explicit BTM_DBG() : ServiceFramework{"btm:dbg"} {
53 // clang-format off
54 static const FunctionInfo functions[] = {
55 {0, nullptr, "RegisterSystemEventForDiscoveryImpl"},
56 {1, nullptr, "Unknown1"},
57 {2, nullptr, "Unknown2"},
58 {3, nullptr, "Unknown3"},
59 {4, nullptr, "Unknown4"},
60 {5, nullptr, "Unknown5"},
61 {6, nullptr, "Unknown6"},
62 {7, nullptr, "Unknown7"},
63 {8, nullptr, "Unknown8"},
64 };
65 // clang-format on
66
67 RegisterHandlers(functions);
68 }
69};
70
71class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
72public:
73 explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} {
74 // clang-format off
75 static const FunctionInfo functions[] = {
76 {0, nullptr, "StartGamepadPairingImpl"},
77 {1, nullptr, "CancelGamepadPairingImpl"},
78 {2, nullptr, "ClearGamepadPairingDatabaseImpl"},
79 {3, nullptr, "GetPairedGamepadCountImpl"},
80 {4, nullptr, "EnableRadioImpl"},
81 {5, nullptr, "DisableRadioImpl"},
82 {6, nullptr, "GetRadioOnOffImpl"},
83 {7, nullptr, "AcquireRadioEventImpl"},
84 {8, nullptr, "AcquireGamepadPairingEventImpl"},
85 {9, nullptr, "IsGamepadPairingStartedImpl"},
86 };
87 // clang-format on
88
89 RegisterHandlers(functions);
90 }
91};
92
93class BTM_SYS final : public ServiceFramework<BTM_SYS> {
94public:
95 explicit BTM_SYS() : ServiceFramework{"btm:sys"} {
96 // clang-format off
97 static const FunctionInfo functions[] = {
98 {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"},
99 };
100 // clang-format on
101
102 RegisterHandlers(functions);
103 }
104
105private:
106 void GetCoreImpl(Kernel::HLERequestContext& ctx) {
107 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
108 rb.Push(RESULT_SUCCESS);
109 rb.PushIpcInterface<IBtmSystemCore>();
110
111 LOG_DEBUG(Service_BTM, "called");
112 }
113};
114
115void InstallInterfaces(SM::ServiceManager& sm) {
116 std::make_shared<BTM>()->InstallAsService(sm);
117 std::make_shared<BTM_DBG>()->InstallAsService(sm);
118 std::make_shared<BTM_SYS>()->InstallAsService(sm);
119}
120
121} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::BTM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/caps/caps.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::Capture {
12
13class CAPS_A final : public ServiceFramework<CAPS_A> {
14public:
15 explicit CAPS_A() : ServiceFramework{"caps:a"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "Unknown1"},
19 {1, nullptr, "Unknown2"},
20 {2, nullptr, "Unknown3"},
21 {3, nullptr, "Unknown4"},
22 {4, nullptr, "Unknown5"},
23 {5, nullptr, "Unknown6"},
24 {6, nullptr, "Unknown7"},
25 {7, nullptr, "Unknown8"},
26 {8, nullptr, "Unknown9"},
27 {9, nullptr, "Unknown10"},
28 {10, nullptr, "Unknown11"},
29 {11, nullptr, "Unknown12"},
30 {12, nullptr, "Unknown13"},
31 {13, nullptr, "Unknown14"},
32 {14, nullptr, "Unknown15"},
33 {301, nullptr, "Unknown16"},
34 {401, nullptr, "Unknown17"},
35 {501, nullptr, "Unknown18"},
36 {1001, nullptr, "Unknown19"},
37 {1002, nullptr, "Unknown20"},
38 {8001, nullptr, "Unknown21"},
39 {8002, nullptr, "Unknown22"},
40 {8011, nullptr, "Unknown23"},
41 {8012, nullptr, "Unknown24"},
42 {8021, nullptr, "Unknown25"},
43 {10011, nullptr, "Unknown26"},
44 };
45 // clang-format on
46
47 RegisterHandlers(functions);
48 }
49};
50
51class CAPS_C final : public ServiceFramework<CAPS_C> {
52public:
53 explicit CAPS_C() : ServiceFramework{"caps:c"} {
54 // clang-format off
55 static const FunctionInfo functions[] = {
56 {2001, nullptr, "Unknown1"},
57 {2002, nullptr, "Unknown2"},
58 {2011, nullptr, "Unknown3"},
59 {2012, nullptr, "Unknown4"},
60 {2013, nullptr, "Unknown5"},
61 {2014, nullptr, "Unknown6"},
62 {2101, nullptr, "Unknown7"},
63 {2102, nullptr, "Unknown8"},
64 {2201, nullptr, "Unknown9"},
65 {2301, nullptr, "Unknown10"},
66 };
67 // clang-format on
68
69 RegisterHandlers(functions);
70 }
71};
72
73class CAPS_SC final : public ServiceFramework<CAPS_SC> {
74public:
75 explicit CAPS_SC() : ServiceFramework{"caps:sc"} {
76 // clang-format off
77 static const FunctionInfo functions[] = {
78 {1, nullptr, "Unknown1"},
79 {2, nullptr, "Unknown2"},
80 {1001, nullptr, "Unknown3"},
81 {1002, nullptr, "Unknown4"},
82 {1003, nullptr, "Unknown5"},
83 {1011, nullptr, "Unknown6"},
84 {1012, nullptr, "Unknown7"},
85 {1201, nullptr, "Unknown8"},
86 {1202, nullptr, "Unknown9"},
87 {1203, nullptr, "Unknown10"},
88 };
89 // clang-format on
90
91 RegisterHandlers(functions);
92 }
93};
94
95class CAPS_SS final : public ServiceFramework<CAPS_SS> {
96public:
97 explicit CAPS_SS() : ServiceFramework{"caps:ss"} {
98 // clang-format off
99 static const FunctionInfo functions[] = {
100 {201, nullptr, "Unknown1"},
101 {202, nullptr, "Unknown2"},
102 {203, nullptr, "Unknown3"},
103 {204, nullptr, "Unknown4"},
104 };
105 // clang-format on
106
107 RegisterHandlers(functions);
108 }
109};
110
111class CAPS_SU final : public ServiceFramework<CAPS_SU> {
112public:
113 explicit CAPS_SU() : ServiceFramework{"caps:su"} {
114 // clang-format off
115 static const FunctionInfo functions[] = {
116 {201, nullptr, "SaveScreenShot"},
117 {203, nullptr, "SaveScreenShotEx0"},
118 };
119 // clang-format on
120
121 RegisterHandlers(functions);
122 }
123};
124
125class CAPS_U final : public ServiceFramework<CAPS_U> {
126public:
127 explicit CAPS_U() : ServiceFramework{"caps:u"} {
128 // clang-format off
129 static const FunctionInfo functions[] = {
130 {102, nullptr, "GetAlbumFileListByAruid"},
131 {103, nullptr, "DeleteAlbumFileByAruid"},
132 {104, nullptr, "GetAlbumFileSizeByAruid"},
133 {110, nullptr, "LoadAlbumScreenShotImageByAruid"},
134 {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"},
135 {60002, nullptr, "OpenAccessorSessionForApplication"},
136 };
137 // clang-format on
138
139 RegisterHandlers(functions);
140 }
141};
142
143void InstallInterfaces(SM::ServiceManager& sm) {
144 std::make_shared<CAPS_A>()->InstallAsService(sm);
145 std::make_shared<CAPS_C>()->InstallAsService(sm);
146 std::make_shared<CAPS_SC>()->InstallAsService(sm);
147 std::make_shared<CAPS_SS>()->InstallAsService(sm);
148 std::make_shared<CAPS_SU>()->InstallAsService(sm);
149 std::make_shared<CAPS_U>()->InstallAsService(sm);
150}
151
152} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::Capture {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/hle_ipc.h"
9#include "core/hle/service/fgm/fgm.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12
13namespace Service::FGM {
14
15class IRequest final : public ServiceFramework<IRequest> {
16public:
17 explicit IRequest() : ServiceFramework{"IRequest"} {
18 // clang-format off
19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Initialize"},
21 {1, nullptr, "Set"},
22 {2, nullptr, "Get"},
23 {3, nullptr, "Cancel"},
24 };
25 // clang-format on
26
27 RegisterHandlers(functions);
28 }
29};
30
31class FGM final : public ServiceFramework<FGM> {
32public:
33 explicit FGM(const char* name) : ServiceFramework{name} {
34 // clang-format off
35 static const FunctionInfo functions[] = {
36 {0, &FGM::Initialize, "Initialize"},
37 };
38 // clang-format on
39
40 RegisterHandlers(functions);
41 }
42
43private:
44 void Initialize(Kernel::HLERequestContext& ctx) {
45 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
46 rb.Push(RESULT_SUCCESS);
47 rb.PushIpcInterface<IRequest>();
48
49 LOG_DEBUG(Service_FGM, "called");
50 }
51};
52
53class FGM_DBG final : public ServiceFramework<FGM_DBG> {
54public:
55 explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} {
56 // clang-format off
57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Initialize"},
59 {1, nullptr, "Read"},
60 {2, nullptr, "Cancel"},
61 };
62 // clang-format on
63
64 RegisterHandlers(functions);
65 }
66};
67
68void InstallInterfaces(SM::ServiceManager& sm) {
69 std::make_shared<FGM>("fgm")->InstallAsService(sm);
70 std::make_shared<FGM>("fgm:0")->InstallAsService(sm);
71 std::make_shared<FGM>("fgm:9")->InstallAsService(sm);
72 std::make_shared<FGM_DBG>()->InstallAsService(sm);
73}
74
75} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::FGM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
14#include "core/file_sys/vfs_offset.h" 14#include "core/file_sys/vfs_offset.h"
15#include "core/file_sys/vfs_real.h" 15#include "core/file_sys/vfs_real.h"
16#include "core/hle/service/filesystem/filesystem.h" 16#include "core/hle/service/filesystem/filesystem.h"
17#include "core/hle/service/filesystem/fsp_ldr.h"
18#include "core/hle/service/filesystem/fsp_pr.h"
17#include "core/hle/service/filesystem/fsp_srv.h" 19#include "core/hle/service/filesystem/fsp_srv.h"
18 20
19namespace Service::FileSystem { 21namespace Service::FileSystem {
@@ -298,6 +300,8 @@ void RegisterFileSystems() {
298 300
299void InstallInterfaces(SM::ServiceManager& service_manager) { 301void InstallInterfaces(SM::ServiceManager& service_manager) {
300 RegisterFileSystems(); 302 RegisterFileSystems();
303 std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
304 std::make_shared<FSP_PR>()->InstallAsService(service_manager);
301 std::make_shared<FSP_SRV>()->InstallAsService(service_manager); 305 std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
302} 306}
303 307
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/filesystem/fsp_ldr.h"
6#include "core/hle/service/service.h"
7
8namespace Service::FileSystem {
9
10FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, nullptr, "OpenCodeFileSystem"},
14 {1, nullptr, "IsArchivedProgram"},
15 {2, nullptr, "SetCurrentProcess"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20}
21
22} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::FileSystem {
10
11class FSP_LDR final : public ServiceFramework<FSP_LDR> {
12public:
13 explicit FSP_LDR();
14};
15
16} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/filesystem/fsp_pr.h"
6#include "core/hle/service/service.h"
7
8namespace Service::FileSystem {
9
10FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} {
11 // clang-format off
12 static const FunctionInfo functions[] = {
13 {0, nullptr, "RegisterProgram"},
14 {1, nullptr, "UnregisterProgram"},
15 {2, nullptr, "SetCurrentProcess"},
16 {256, nullptr, "SetEnabledProgramVerification"},
17 };
18 // clang-format on
19
20 RegisterHandlers(functions);
21}
22
23} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::FileSystem {
10
11class FSP_PR final : public ServiceFramework<FSP_PR> {
12public:
13 explicit FSP_PR();
14};
15
16} // 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:
326 {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, 326 {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
327 {80, nullptr, "GetGyroscopeZeroDriftMode"}, 327 {80, nullptr, "GetGyroscopeZeroDriftMode"},
328 {81, nullptr, "ResetGyroscopeZeroDriftMode"}, 328 {81, nullptr, "ResetGyroscopeZeroDriftMode"},
329 {82, nullptr, "IsSixAxisSensorAtRest"}, 329 {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
330 {91, nullptr, "ActivateGesture"}, 330 {91, nullptr, "ActivateGesture"},
331 {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, 331 {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
332 {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, 332 {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
@@ -337,13 +337,14 @@ public:
337 "AcquireNpadStyleSetUpdateEventHandle"}, 337 "AcquireNpadStyleSetUpdateEventHandle"},
338 {107, nullptr, "DisconnectNpad"}, 338 {107, nullptr, "DisconnectNpad"},
339 {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, 339 {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
340 {109, nullptr, "ActivateNpadWithRevision"},
340 {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, 341 {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
341 {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, 342 {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
342 {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, 343 {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault,
343 "SetNpadJoyAssignmentModeSingleByDefault"}, 344 "SetNpadJoyAssignmentModeSingleByDefault"},
344 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, 345 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
345 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, 346 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
346 {125, nullptr, "MergeSingleJoyAsDualJoy"}, 347 {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
347 {126, nullptr, "StartLrAssignmentMode"}, 348 {126, nullptr, "StartLrAssignmentMode"},
348 {127, nullptr, "StopLrAssignmentMode"}, 349 {127, nullptr, "StopLrAssignmentMode"},
349 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, 350 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
@@ -455,6 +456,14 @@ private:
455 LOG_WARNING(Service_HID, "(STUBBED) called"); 456 LOG_WARNING(Service_HID, "(STUBBED) called");
456 } 457 }
457 458
459 void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
460 IPC::ResponseBuilder rb{ctx, 2};
461 rb.Push(RESULT_SUCCESS);
462 // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
463 rb.Push(true);
464 LOG_WARNING(Service_HID, "(STUBBED) called");
465 }
466
458 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 467 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
459 IPC::ResponseBuilder rb{ctx, 2}; 468 IPC::ResponseBuilder rb{ctx, 2};
460 rb.Push(RESULT_SUCCESS); 469 rb.Push(RESULT_SUCCESS);
@@ -530,6 +539,12 @@ private:
530 LOG_WARNING(Service_HID, "(STUBBED) called"); 539 LOG_WARNING(Service_HID, "(STUBBED) called");
531 } 540 }
532 541
542 void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
543 IPC::ResponseBuilder rb{ctx, 2};
544 rb.Push(RESULT_SUCCESS);
545 LOG_WARNING(Service_HID, "(STUBBED) called");
546 }
547
533 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 548 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
534 IPC::ResponseBuilder rb{ctx, 2}; 549 IPC::ResponseBuilder rb{ctx, 2};
535 rb.Push(RESULT_SUCCESS); 550 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/lbl/lbl.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::LBL {
15
16class LBL final : public ServiceFramework<LBL> {
17public:
18 explicit LBL() : ServiceFramework{"lbl"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "Unknown1"},
22 {1, nullptr, "Unknown2"},
23 {2, nullptr, "Unknown3"},
24 {3, nullptr, "Unknown4"},
25 {4, nullptr, "Unknown5"},
26 {5, nullptr, "Unknown6"},
27 {6, nullptr, "TurnOffBacklight"},
28 {7, nullptr, "TurnOnBacklight"},
29 {8, nullptr, "GetBacklightStatus"},
30 {9, nullptr, "Unknown7"},
31 {10, nullptr, "Unknown8"},
32 {11, nullptr, "Unknown9"},
33 {12, nullptr, "Unknown10"},
34 {13, nullptr, "Unknown11"},
35 {14, nullptr, "Unknown12"},
36 {15, nullptr, "Unknown13"},
37 {16, nullptr, "ReadRawLightSensor"},
38 {17, nullptr, "Unknown14"},
39 {18, nullptr, "Unknown15"},
40 {19, nullptr, "Unknown16"},
41 {20, nullptr, "Unknown17"},
42 {21, nullptr, "Unknown18"},
43 {22, nullptr, "Unknown19"},
44 {23, nullptr, "Unknown20"},
45 {24, nullptr, "Unknown21"},
46 {25, nullptr, "Unknown22"},
47 {26, &LBL::EnableVrMode, "EnableVrMode"},
48 {27, &LBL::DisableVrMode, "DisableVrMode"},
49 {28, &LBL::GetVrMode, "GetVrMode"},
50 };
51 // clang-format on
52
53 RegisterHandlers(functions);
54 }
55
56private:
57 void EnableVrMode(Kernel::HLERequestContext& ctx) {
58 IPC::ResponseBuilder rb{ctx, 2};
59 rb.Push(RESULT_SUCCESS);
60
61 vr_mode_enabled = true;
62
63 LOG_DEBUG(Service_LBL, "called");
64 }
65
66 void DisableVrMode(Kernel::HLERequestContext& ctx) {
67 IPC::ResponseBuilder rb{ctx, 2};
68 rb.Push(RESULT_SUCCESS);
69
70 vr_mode_enabled = false;
71
72 LOG_DEBUG(Service_LBL, "called");
73 }
74
75 void GetVrMode(Kernel::HLERequestContext& ctx) {
76 IPC::ResponseBuilder rb{ctx, 3};
77 rb.Push(RESULT_SUCCESS);
78 rb.Push(vr_mode_enabled);
79
80 LOG_DEBUG(Service_LBL, "called");
81 }
82
83 bool vr_mode_enabled = false;
84};
85
86void InstallInterfaces(SM::ServiceManager& sm) {
87 std::make_shared<LBL>()->InstallAsService(sm);
88}
89
90} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::LBL {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
13 13
14namespace Service::LM { 14namespace Service::LM {
15 15
16class Logger final : public ServiceFramework<Logger> { 16class ILogger final : public ServiceFramework<ILogger> {
17public: 17public:
18 Logger() : ServiceFramework("Logger") { 18 ILogger() : ServiceFramework("ILogger") {
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0x00000000, &Logger::Initialize, "Initialize"}, 20 {0x00000000, &ILogger::Initialize, "Initialize"},
21 {0x00000001, nullptr, "SetDestination"}, 21 {0x00000001, nullptr, "SetDestination"},
22 }; 22 };
23 RegisterHandlers(functions); 23 RegisterHandlers(functions);
@@ -182,7 +182,7 @@ public:
182 void OpenLogger(Kernel::HLERequestContext& ctx) { 182 void OpenLogger(Kernel::HLERequestContext& ctx) {
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
184 rb.Push(RESULT_SUCCESS); 184 rb.Push(RESULT_SUCCESS);
185 rb.PushIpcInterface<Logger>(); 185 rb.PushIpcInterface<ILogger>();
186 186
187 LOG_DEBUG(Service_LM, "called"); 187 LOG_DEBUG(Service_LM, "called");
188 } 188 }
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/mig/mig.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::Migration {
12
13class MIG_USR final : public ServiceFramework<MIG_USR> {
14public:
15 explicit MIG_USR() : ServiceFramework{"mig:usr"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {10, nullptr, "TryGetLastMigrationInfo"},
19 {100, nullptr, "CreateServer"},
20 {101, nullptr, "ResumeServer"},
21 {200, nullptr, "CreateClient"},
22 {201, nullptr, "ResumeClient"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27 }
28};
29
30void InstallInterfaces(SM::ServiceManager& sm) {
31 std::make_shared<MIG_USR>()->InstallAsService(sm);
32}
33
34} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::Migration {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/mii/mii.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::Mii {
15
16class IDatabaseService final : public ServiceFramework<IDatabaseService> {
17public:
18 explicit IDatabaseService() : ServiceFramework{"IDatabaseService"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "IsUpdated"},
22 {1, nullptr, "IsFullDatabase"},
23 {2, nullptr, "GetCount"},
24 {3, nullptr, "Get"},
25 {4, nullptr, "Get1"},
26 {5, nullptr, "UpdateLatest"},
27 {6, nullptr, "BuildRandom"},
28 {7, nullptr, "BuildDefault"},
29 {8, nullptr, "Get2"},
30 {9, nullptr, "Get3"},
31 {10, nullptr, "UpdateLatest1"},
32 {11, nullptr, "FindIndex"},
33 {12, nullptr, "Move"},
34 {13, nullptr, "AddOrReplace"},
35 {14, nullptr, "Delete"},
36 {15, nullptr, "DestroyFile"},
37 {16, nullptr, "DeleteFile"},
38 {17, nullptr, "Format"},
39 {18, nullptr, "Import"},
40 {19, nullptr, "Export"},
41 {20, nullptr, "IsBrokenDatabaseWithClearFlag"},
42 {21, nullptr, "GetIndex"},
43 {22, nullptr, "SetInterfaceVersion"},
44 {23, nullptr, "Convert"},
45 };
46 // clang-format on
47
48 RegisterHandlers(functions);
49 }
50};
51
52class MiiDBModule final : public ServiceFramework<MiiDBModule> {
53public:
54 explicit MiiDBModule(const char* name) : ServiceFramework{name} {
55 // clang-format off
56 static const FunctionInfo functions[] = {
57 {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"},
58 };
59 // clang-format on
60
61 RegisterHandlers(functions);
62 }
63
64private:
65 void GetDatabaseService(Kernel::HLERequestContext& ctx) {
66 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
67 rb.Push(RESULT_SUCCESS);
68 rb.PushIpcInterface<IDatabaseService>();
69
70 LOG_DEBUG(Service_Mii, "called");
71 }
72};
73
74class MiiImg final : public ServiceFramework<MiiImg> {
75public:
76 explicit MiiImg() : ServiceFramework{"miiimg"} {
77 // clang-format off
78 static const FunctionInfo functions[] = {
79 {0, nullptr, "Initialize"},
80 {10, nullptr, "Reload"},
81 {11, nullptr, "GetCount"},
82 {12, nullptr, "IsEmpty"},
83 {13, nullptr, "IsFull"},
84 {14, nullptr, "GetAttribute"},
85 {15, nullptr, "LoadImage"},
86 {16, nullptr, "AddOrUpdateImage"},
87 {17, nullptr, "DeleteImages"},
88 {100, nullptr, "DeleteFile"},
89 {101, nullptr, "DestroyFile"},
90 {102, nullptr, "ImportFile"},
91 {103, nullptr, "ExportFile"},
92 {104, nullptr, "ForceInitialize"},
93 };
94 // clang-format on
95
96 RegisterHandlers(functions);
97 }
98};
99
100void InstallInterfaces(SM::ServiceManager& sm) {
101 std::make_shared<MiiDBModule>("mii:e")->InstallAsService(sm);
102 std::make_shared<MiiDBModule>("mii:u")->InstallAsService(sm);
103
104 std::make_shared<MiiImg>()->InstallAsService(sm);
105}
106
107} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::Mii {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/ncm/ncm.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::NCM {
12
13class LocationResolver final : public ServiceFramework<LocationResolver> {
14public:
15 explicit LocationResolver() : ServiceFramework{"lr"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "OpenLocationResolver"},
19 {1, nullptr, "OpenRegisteredLocationResolver"},
20 {2, nullptr, "RefreshLocationResolver"},
21 {3, nullptr, "OpenAddOnContentLocationResolver"},
22 };
23 // clang-format on
24
25 RegisterHandlers(functions);
26 }
27};
28
29class NCM final : public ServiceFramework<NCM> {
30public:
31 explicit NCM() : ServiceFramework{"ncm"} {
32 // clang-format off
33 static const FunctionInfo functions[] = {
34 {0, nullptr, "CreateContentStorage"},
35 {1, nullptr, "CreateContentMetaDatabase"},
36 {2, nullptr, "VerifyContentStorage"},
37 {3, nullptr, "VerifyContentMetaDatabase"},
38 {4, nullptr, "OpenContentStorage"},
39 {5, nullptr, "OpenContentMetaDatabase"},
40 {6, nullptr, "CloseContentStorageForcibly"},
41 {7, nullptr, "CloseContentMetaDatabaseForcibly"},
42 {8, nullptr, "CleanupContentMetaDatabase"},
43 {9, nullptr, "OpenContentStorage2"},
44 {10, nullptr, "CloseContentStorage"},
45 {11, nullptr, "OpenContentMetaDatabase2"},
46 {12, nullptr, "CloseContentMetaDatabase"},
47 };
48 // clang-format on
49
50 RegisterHandlers(functions);
51 }
52};
53
54void InstallInterfaces(SM::ServiceManager& sm) {
55 std::make_shared<LocationResolver>()->InstallAsService(sm);
56 std::make_shared<NCM>()->InstallAsService(sm);
57}
58
59} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::NCM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/nfc/nfc.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::NFC {
15
16class IAm final : public ServiceFramework<IAm> {
17public:
18 explicit IAm() : ServiceFramework{"IAm"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "Initialize"},
22 {1, nullptr, "Finalize"},
23 {2, nullptr, "NotifyForegroundApplet"},
24 };
25 // clang-format on
26
27 RegisterHandlers(functions);
28 }
29};
30
31class NFC_AM final : public ServiceFramework<NFC_AM> {
32public:
33 explicit NFC_AM() : ServiceFramework{"nfc:am"} {
34 // clang-format off
35 static const FunctionInfo functions[] = {
36 {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"},
37 };
38 // clang-format on
39
40 RegisterHandlers(functions);
41 }
42
43private:
44 void CreateAmInterface(Kernel::HLERequestContext& ctx) {
45 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
46 rb.Push(RESULT_SUCCESS);
47 rb.PushIpcInterface<IAm>();
48
49 LOG_DEBUG(Service_NFC, "called");
50 }
51};
52
53class MFIUser final : public ServiceFramework<MFIUser> {
54public:
55 explicit MFIUser() : ServiceFramework{"IUser"} {
56 // clang-format off
57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Initialize"},
59 {1, nullptr, "Finalize"},
60 {2, nullptr, "ListDevices"},
61 {3, nullptr, "StartDetection"},
62 {4, nullptr, "StopDetection"},
63 {5, nullptr, "Read"},
64 {6, nullptr, "Write"},
65 {7, nullptr, "GetTagInfo"},
66 {8, nullptr, "GetActivateEventHandle"},
67 {9, nullptr, "GetDeactivateEventHandle"},
68 {10, nullptr, "GetState"},
69 {11, nullptr, "GetDeviceState"},
70 {12, nullptr, "GetNpadId"},
71 {13, nullptr, "GetAvailabilityChangeEventHandle"},
72 };
73 // clang-format on
74
75 RegisterHandlers(functions);
76 }
77};
78
79class NFC_MF_U final : public ServiceFramework<NFC_MF_U> {
80public:
81 explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} {
82 // clang-format off
83 static const FunctionInfo functions[] = {
84 {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"},
85 };
86 // clang-format on
87
88 RegisterHandlers(functions);
89 }
90
91private:
92 void CreateUserInterface(Kernel::HLERequestContext& ctx) {
93 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
94 rb.Push(RESULT_SUCCESS);
95 rb.PushIpcInterface<MFIUser>();
96
97 LOG_DEBUG(Service_NFC, "called");
98 }
99};
100
101class IUser final : public ServiceFramework<IUser> {
102public:
103 explicit IUser() : ServiceFramework{"IUser"} {
104 // clang-format off
105 static const FunctionInfo functions[] = {
106 {0, nullptr, "Initialize"},
107 {1, nullptr, "Finalize"},
108 {2, nullptr, "GetState"},
109 {3, nullptr, "IsNfcEnabled"},
110 {400, nullptr, "Initialize"},
111 {401, nullptr, "Finalize"},
112 {402, nullptr, "GetState"},
113 {403, nullptr, "IsNfcEnabled"},
114 {404, nullptr, "ListDevices"},
115 {405, nullptr, "GetDeviceState"},
116 {406, nullptr, "GetNpadId"},
117 {407, nullptr, "AttachAvailabilityChangeEvent"},
118 {408, nullptr, "StartDetection"},
119 {409, nullptr, "StopDetection"},
120 {410, nullptr, "GetTagInfo"},
121 {411, nullptr, "AttachActivateEvent"},
122 {412, nullptr, "AttachDeactivateEvent"},
123 {1000, nullptr, "ReadMifare"},
124 {1001, nullptr, "WriteMifare"},
125 {1300, nullptr, "SendCommandByPassThrough"},
126 {1301, nullptr, "KeepPassThroughSession"},
127 {1302, nullptr, "ReleasePassThroughSession"},
128 };
129 // clang-format on
130
131 RegisterHandlers(functions);
132 }
133};
134
135class NFC_U final : public ServiceFramework<NFC_U> {
136public:
137 explicit NFC_U() : ServiceFramework{"nfc:u"} {
138 // clang-format off
139 static const FunctionInfo functions[] = {
140 {0, &NFC_U::CreateUserInterface, "CreateUserInterface"},
141 };
142 // clang-format on
143
144 RegisterHandlers(functions);
145 }
146
147private:
148 void CreateUserInterface(Kernel::HLERequestContext& ctx) {
149 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
150 rb.Push(RESULT_SUCCESS);
151 rb.PushIpcInterface<IUser>();
152
153 LOG_DEBUG(Service_NFC, "called");
154 }
155};
156
157class ISystem final : public ServiceFramework<ISystem> {
158public:
159 explicit ISystem() : ServiceFramework{"ISystem"} {
160 // clang-format off
161 static const FunctionInfo functions[] = {
162 {0, nullptr, "Initialize"},
163 {1, nullptr, "Finalize"},
164 {2, nullptr, "GetState"},
165 {3, nullptr, "IsNfcEnabled"},
166 {100, nullptr, "SetNfcEnabled"},
167 {400, nullptr, "InitializeSystem"},
168 {401, nullptr, "FinalizeSystem"},
169 {402, nullptr, "GetState"},
170 {403, nullptr, "IsNfcEnabled"},
171 {404, nullptr, "ListDevices"},
172 {405, nullptr, "GetDeviceState"},
173 {406, nullptr, "GetNpadId"},
174 {407, nullptr, "AttachAvailabilityChangeEvent"},
175 {408, nullptr, "StartDetection"},
176 {409, nullptr, "StopDetection"},
177 {410, nullptr, "GetTagInfo"},
178 {411, nullptr, "AttachActivateEvent"},
179 {412, nullptr, "AttachDeactivateEvent"},
180 {500, nullptr, "SetNfcEnabled"},
181 {1000, nullptr, "ReadMifare"},
182 {1001, nullptr, "WriteMifare"},
183 {1300, nullptr, "SendCommandByPassThrough"},
184 {1301, nullptr, "KeepPassThroughSession"},
185 {1302, nullptr, "ReleasePassThroughSession"},
186 };
187 // clang-format on
188
189 RegisterHandlers(functions);
190 }
191};
192
193class NFC_SYS final : public ServiceFramework<NFC_SYS> {
194public:
195 explicit NFC_SYS() : ServiceFramework{"nfc:sys"} {
196 // clang-format off
197 static const FunctionInfo functions[] = {
198 {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"},
199 };
200 // clang-format on
201
202 RegisterHandlers(functions);
203 }
204
205private:
206 void CreateSystemInterface(Kernel::HLERequestContext& ctx) {
207 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
208 rb.Push(RESULT_SUCCESS);
209 rb.PushIpcInterface<ISystem>();
210
211 LOG_DEBUG(Service_NFC, "called");
212 }
213};
214
215void InstallInterfaces(SM::ServiceManager& sm) {
216 std::make_shared<NFC_AM>()->InstallAsService(sm);
217 std::make_shared<NFC_MF_U>()->InstallAsService(sm);
218 std::make_shared<NFC_U>()->InstallAsService(sm);
219 std::make_shared<NFC_SYS>()->InstallAsService(sm);
220}
221
222} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::NFC {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/hle_ipc.h"
5#include "core/hle/service/ns/ns.h" 7#include "core/hle/service/ns/ns.h"
6#include "core/hle/service/ns/pl_u.h" 8#include "core/hle/service/ns/pl_u.h"
7 9
8namespace Service::NS { 10namespace Service::NS {
9 11
12class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
13public:
14 explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, nullptr, "CreateUserAccount"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22 }
23};
24
25class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
26public:
27 explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
28 // clang-format off
29 static const FunctionInfo functions[] = {
30 {0, nullptr, "ListApplicationRecord"},
31 {1, nullptr, "GenerateApplicationRecordCount"},
32 {2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
33 {3, nullptr, "GetApplicationViewDeprecated"},
34 {4, nullptr, "DeleteApplicationEntity"},
35 {5, nullptr, "DeleteApplicationCompletely"},
36 {6, nullptr, "IsAnyApplicationEntityRedundant"},
37 {7, nullptr, "DeleteRedundantApplicationEntity"},
38 {8, nullptr, "IsApplicationEntityMovable"},
39 {9, nullptr, "MoveApplicationEntity"},
40 {11, nullptr, "CalculateApplicationOccupiedSize"},
41 {16, nullptr, "PushApplicationRecord"},
42 {17, nullptr, "ListApplicationRecordContentMeta"},
43 {19, nullptr, "LaunchApplication"},
44 {21, nullptr, "GetApplicationContentPath"},
45 {22, nullptr, "TerminateApplication"},
46 {23, nullptr, "ResolveApplicationContentPath"},
47 {26, nullptr, "BeginInstallApplication"},
48 {27, nullptr, "DeleteApplicationRecord"},
49 {30, nullptr, "RequestApplicationUpdateInfo"},
50 {32, nullptr, "CancelApplicationDownload"},
51 {33, nullptr, "ResumeApplicationDownload"},
52 {35, nullptr, "UpdateVersionList"},
53 {36, nullptr, "PushLaunchVersion"},
54 {37, nullptr, "ListRequiredVersion"},
55 {38, nullptr, "CheckApplicationLaunchVersion"},
56 {39, nullptr, "CheckApplicationLaunchRights"},
57 {40, nullptr, "GetApplicationLogoData"},
58 {41, nullptr, "CalculateApplicationDownloadRequiredSize"},
59 {42, nullptr, "CleanupSdCard"},
60 {43, nullptr, "CheckSdCardMountStatus"},
61 {44, nullptr, "GetSdCardMountStatusChangedEvent"},
62 {45, nullptr, "GetGameCardAttachmentEvent"},
63 {46, nullptr, "GetGameCardAttachmentInfo"},
64 {47, nullptr, "GetTotalSpaceSize"},
65 {48, nullptr, "GetFreeSpaceSize"},
66 {49, nullptr, "GetSdCardRemovedEvent"},
67 {52, nullptr, "GetGameCardUpdateDetectionEvent"},
68 {53, nullptr, "DisableApplicationAutoDelete"},
69 {54, nullptr, "EnableApplicationAutoDelete"},
70 {55, nullptr, "GetApplicationDesiredLanguage"},
71 {56, nullptr, "SetApplicationTerminateResult"},
72 {57, nullptr, "ClearApplicationTerminateResult"},
73 {58, nullptr, "GetLastSdCardMountUnexpectedResult"},
74 {59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
75 {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
76 {61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
77 {62, nullptr, "GetGameCardStopper"},
78 {63, nullptr, "IsSystemProgramInstalled"},
79 {64, nullptr, "StartApplyDeltaTask"},
80 {65, nullptr, "GetRequestServerStopper"},
81 {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
82 {67, nullptr, "CancelApplicationApplyDelta"},
83 {68, nullptr, "ResumeApplicationApplyDelta"},
84 {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
85 {70, nullptr, "ResumeAll"},
86 {71, nullptr, "GetStorageSize"},
87 {80, nullptr, "RequestDownloadApplication"},
88 {81, nullptr, "RequestDownloadAddOnContent"},
89 {82, nullptr, "DownloadApplication"},
90 {83, nullptr, "CheckApplicationResumeRights"},
91 {84, nullptr, "GetDynamicCommitEvent"},
92 {85, nullptr, "RequestUpdateApplication2"},
93 {86, nullptr, "EnableApplicationCrashReport"},
94 {87, nullptr, "IsApplicationCrashReportEnabled"},
95 {90, nullptr, "BoostSystemMemoryResourceLimit"},
96 {100, nullptr, "ResetToFactorySettings"},
97 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
98 {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
99 {200, nullptr, "CalculateUserSaveDataStatistics"},
100 {201, nullptr, "DeleteUserSaveDataAll"},
101 {210, nullptr, "DeleteUserSystemSaveData"},
102 {220, nullptr, "UnregisterNetworkServiceAccount"},
103 {300, nullptr, "GetApplicationShellEvent"},
104 {301, nullptr, "PopApplicationShellEventInfo"},
105 {302, nullptr, "LaunchLibraryApplet"},
106 {303, nullptr, "TerminateLibraryApplet"},
107 {304, nullptr, "LaunchSystemApplet"},
108 {305, nullptr, "TerminateSystemApplet"},
109 {306, nullptr, "LaunchOverlayApplet"},
110 {307, nullptr, "TerminateOverlayApplet"},
111 {400, nullptr, "GetApplicationControlData"},
112 {401, nullptr, "InvalidateAllApplicationControlCache"},
113 {402, nullptr, "RequestDownloadApplicationControlData"},
114 {403, nullptr, "GetMaxApplicationControlCacheCount"},
115 {404, nullptr, "InvalidateApplicationControlCache"},
116 {405, nullptr, "ListApplicationControlCacheEntryInfo"},
117 {502, nullptr, "RequestCheckGameCardRegistration"},
118 {503, nullptr, "RequestGameCardRegistrationGoldPoint"},
119 {504, nullptr, "RequestRegisterGameCard"},
120 {505, nullptr, "GetGameCardMountFailureEvent"},
121 {506, nullptr, "IsGameCardInserted"},
122 {507, nullptr, "EnsureGameCardAccess"},
123 {508, nullptr, "GetLastGameCardMountFailureResult"},
124 {509, nullptr, "ListApplicationIdOnGameCard"},
125 {600, nullptr, "CountApplicationContentMeta"},
126 {601, nullptr, "ListApplicationContentMetaStatus"},
127 {602, nullptr, "ListAvailableAddOnContent"},
128 {603, nullptr, "GetOwnedApplicationContentMetaStatus"},
129 {604, nullptr, "RegisterContentsExternalKey"},
130 {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
131 {606, nullptr, "GetContentMetaStorage"},
132 {700, nullptr, "PushDownloadTaskList"},
133 {701, nullptr, "ClearTaskStatusList"},
134 {702, nullptr, "RequestDownloadTaskList"},
135 {703, nullptr, "RequestEnsureDownloadTask"},
136 {704, nullptr, "ListDownloadTaskStatus"},
137 {705, nullptr, "RequestDownloadTaskListData"},
138 {800, nullptr, "RequestVersionList"},
139 {801, nullptr, "ListVersionList"},
140 {802, nullptr, "RequestVersionListData"},
141 {900, nullptr, "GetApplicationRecord"},
142 {901, nullptr, "GetApplicationRecordProperty"},
143 {902, nullptr, "EnableApplicationAutoUpdate"},
144 {903, nullptr, "DisableApplicationAutoUpdate"},
145 {904, nullptr, "TouchApplication"},
146 {905, nullptr, "RequestApplicationUpdate"},
147 {906, nullptr, "IsApplicationUpdateRequested"},
148 {907, nullptr, "WithdrawApplicationUpdateRequest"},
149 {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
150 {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
151 {1000, nullptr, "RequestVerifyApplicationDeprecated"},
152 {1001, nullptr, "CorruptApplicationForDebug"},
153 {1002, nullptr, "RequestVerifyAddOnContentsRights"},
154 {1003, nullptr, "RequestVerifyApplication"},
155 {1004, nullptr, "CorruptContentForDebug"},
156 {1200, nullptr, "NeedsUpdateVulnerability"},
157 {1300, nullptr, "IsAnyApplicationEntityInstalled"},
158 {1301, nullptr, "DeleteApplicationContentEntities"},
159 {1302, nullptr, "CleanupUnrecordedApplicationEntity"},
160 {1303, nullptr, "CleanupAddOnContentsWithNoRights"},
161 {1304, nullptr, "DeleteApplicationContentEntity"},
162 {1305, nullptr, "TryDeleteRunningApplicationEntity"},
163 {1306, nullptr, "TryDeleteRunningApplicationCompletely"},
164 {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
165 {1400, nullptr, "PrepareShutdown"},
166 {1500, nullptr, "FormatSdCard"},
167 {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
168 {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
169 {1504, nullptr, "InsertSdCard"},
170 {1505, nullptr, "RemoveSdCard"},
171 {1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
172 {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
173 {1700, nullptr, "ListApplicationDownloadingContentMeta"},
174 {1701, nullptr, "GetApplicationView"},
175 {1702, nullptr, "GetApplicationDownloadTaskStatus"},
176 {1703, nullptr, "GetApplicationViewDownloadErrorContext"},
177 {1800, nullptr, "IsNotificationSetupCompleted"},
178 {1801, nullptr, "GetLastNotificationInfoCount"},
179 {1802, nullptr, "ListLastNotificationInfo"},
180 {1803, nullptr, "ListNotificationTask"},
181 {1900, nullptr, "IsActiveAccount"},
182 {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
183 {1902, nullptr, "GetApplicationTicketInfo"},
184 {2000, nullptr, "GetSystemDeliveryInfo"},
185 {2001, nullptr, "SelectLatestSystemDeliveryInfo"},
186 {2002, nullptr, "VerifyDeliveryProtocolVersion"},
187 {2003, nullptr, "GetApplicationDeliveryInfo"},
188 {2004, nullptr, "HasAllContentsToDeliver"},
189 {2005, nullptr, "CompareApplicationDeliveryInfo"},
190 {2006, nullptr, "CanDeliverApplication"},
191 {2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
192 {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
193 {2009, nullptr, "EstimateRequiredSize"},
194 {2010, nullptr, "RequestReceiveApplication"},
195 {2011, nullptr, "CommitReceiveApplication"},
196 {2012, nullptr, "GetReceiveApplicationProgress"},
197 {2013, nullptr, "RequestSendApplication"},
198 {2014, nullptr, "GetSendApplicationProgress"},
199 {2015, nullptr, "CompareSystemDeliveryInfo"},
200 {2016, nullptr, "ListNotCommittedContentMeta"},
201 {2017, nullptr, "CreateDownloadTask"},
202 };
203 // clang-format on
204
205 RegisterHandlers(functions);
206 }
207};
208
209class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
210public:
211 explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} {
212 // clang-format off
213 static const FunctionInfo functions[] = {
214 {0, nullptr, "GetLaunchRequiredVersion"},
215 {1, nullptr, "UpgradeLaunchRequiredVersion"},
216 {35, nullptr, "UpdateVersionList"},
217 {36, nullptr, "PushLaunchVersion"},
218 {37, nullptr, "ListRequiredVersion"},
219 {800, nullptr, "RequestVersionList"},
220 {801, nullptr, "ListVersionList"},
221 {802, nullptr, "RequestVersionListData"},
222 {1000, nullptr, "PerformAutoUpdate"},
223 };
224 // clang-format on
225
226 RegisterHandlers(functions);
227 }
228};
229
230class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
231public:
232 explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} {
233 // clang-format off
234 static const FunctionInfo functions[] = {
235 {11, nullptr, "CalculateApplicationOccupiedSize"},
236 {43, nullptr, "CheckSdCardMountStatus"},
237 {47, nullptr, "GetTotalSpaceSize"},
238 {48, nullptr, "GetFreeSpaceSize"},
239 {600, nullptr, "CountApplicationContentMeta"},
240 {601, nullptr, "ListApplicationContentMetaStatus"},
241 {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
242 {607, nullptr, "IsAnyApplicationRunning"},
243 };
244 // clang-format on
245
246 RegisterHandlers(functions);
247 }
248};
249
250class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
251public:
252 explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
253 // clang-format off
254 static const FunctionInfo functions[] = {
255 {21, nullptr, "GetApplicationContentPath"},
256 {23, nullptr, "ResolveApplicationContentPath"},
257 };
258 // clang-format on
259
260 RegisterHandlers(functions);
261 }
262};
263
264class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
265public:
266 explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
267 // clang-format off
268 static const FunctionInfo functions[] = {
269 {701, nullptr, "ClearTaskStatusList"},
270 {702, nullptr, "RequestDownloadTaskList"},
271 {703, nullptr, "RequestEnsureDownloadTask"},
272 {704, nullptr, "ListDownloadTaskStatus"},
273 {705, nullptr, "RequestDownloadTaskListData"},
274 {706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
275 {707, nullptr, "EnableAutoCommit"},
276 {708, nullptr, "DisableAutoCommit"},
277 {709, nullptr, "TriggerDynamicCommitEvent"},
278 };
279 // clang-format on
280
281 RegisterHandlers(functions);
282 }
283};
284
285class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
286public:
287 explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
288 // clang-format off
289 static const FunctionInfo functions[] = {
290 {0, nullptr, "RequestLinkDevice"},
291 };
292 // clang-format on
293
294 RegisterHandlers(functions);
295 }
296};
297
298class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
299public:
300 explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} {
301 // clang-format off
302 static const FunctionInfo functions[] = {
303 {100, nullptr, "ResetToFactorySettings"},
304 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
305 {102, nullptr, "ResetToFactorySettingsForRefurbishment "},
306 };
307 // clang-format on
308
309 RegisterHandlers(functions);
310 }
311};
312
313class NS final : public ServiceFramework<NS> {
314public:
315 explicit NS(const char* name) : ServiceFramework{name} {
316 // clang-format off
317 static const FunctionInfo functions[] = {
318 {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
319 {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
320 {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
321 {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
322 {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
323 {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
324 {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
325 {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
326 };
327 // clang-format on
328
329 RegisterHandlers(functions);
330 }
331
332private:
333 template <typename T>
334 void PushInterface(Kernel::HLERequestContext& ctx) {
335 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
336 rb.Push(RESULT_SUCCESS);
337 rb.PushIpcInterface<T>();
338
339 LOG_DEBUG(Service_NS, "called");
340 }
341};
342
343class NS_DEV final : public ServiceFramework<NS_DEV> {
344public:
345 explicit NS_DEV() : ServiceFramework{"ns:dev"} {
346 // clang-format off
347 static const FunctionInfo functions[] = {
348 {0, nullptr, "LaunchProgram"},
349 {1, nullptr, "TerminateProcess"},
350 {2, nullptr, "TerminateProgram"},
351 {3, nullptr, "GetShellEventHandle"},
352 {4, nullptr, "GetShellEventInfo"},
353 {5, nullptr, "TerminateApplication"},
354 {6, nullptr, "PrepareLaunchProgramFromHost"},
355 {7, nullptr, "LaunchApplication"},
356 {8, nullptr, "LaunchApplicationWithStorageId"},
357 };
358 // clang-format on
359
360 RegisterHandlers(functions);
361 }
362};
363
364class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
365public:
366 explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} {
367 // clang-format off
368 static const FunctionInfo functions[] = {
369 {0, nullptr, "HasDownloaded"},
370 {1, nullptr, "RequestCheckLatestUpdate"},
371 {2, nullptr, "RequestDownloadLatestUpdate"},
372 {3, nullptr, "GetDownloadProgress"},
373 {4, nullptr, "ApplyDownloadedUpdate"},
374 {5, nullptr, "RequestPrepareCardUpdate"},
375 {6, nullptr, "GetPrepareCardUpdateProgress"},
376 {7, nullptr, "HasPreparedCardUpdate"},
377 {8, nullptr, "ApplyCardUpdate"},
378 {9, nullptr, "GetDownloadedEulaDataSize"},
379 {10, nullptr, "GetDownloadedEulaData"},
380 {11, nullptr, "SetupCardUpdate"},
381 {12, nullptr, "GetPreparedCardUpdateEulaDataSize"},
382 {13, nullptr, "GetPreparedCardUpdateEulaData"},
383 {14, nullptr, "SetupCardUpdateViaSystemUpdater"},
384 {15, nullptr, "HasReceived"},
385 {16, nullptr, "RequestReceiveSystemUpdate"},
386 {17, nullptr, "GetReceiveProgress"},
387 {18, nullptr, "ApplyReceivedUpdate"},
388 {19, nullptr, "GetReceivedEulaDataSize"},
389 {20, nullptr, "GetReceivedEulaData"},
390 {21, nullptr, "SetupToReceiveSystemUpdate"},
391 };
392 // clang-format on
393
394 RegisterHandlers(functions);
395 }
396};
397
398class NS_SU final : public ServiceFramework<NS_SU> {
399public:
400 explicit NS_SU() : ServiceFramework{"ns:su"} {
401 // clang-format off
402 static const FunctionInfo functions[] = {
403 {0, nullptr, "GetBackgroundNetworkUpdateState"},
404 {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"},
405 {2, nullptr, "NotifyExFatDriverRequired"},
406 {3, nullptr, "ClearExFatDriverStatusForDebug"},
407 {4, nullptr, "RequestBackgroundNetworkUpdate"},
408 {5, nullptr, "NotifyBackgroundNetworkUpdate"},
409 {6, nullptr, "NotifyExFatDriverDownloadedForDebug"},
410 {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"},
411 {10, nullptr, "NotifySystemUpdateForContentDelivery"},
412 {11, nullptr, "PrepareShutdown"},
413 {16, nullptr, "DestroySystemUpdateTask"},
414 {17, nullptr, "RequestSendSystemUpdate"},
415 {18, nullptr, "GetSendSystemUpdateProgress"},
416 };
417 // clang-format on
418
419 RegisterHandlers(functions);
420 }
421
422private:
423 void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) {
424 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
425 rb.Push(RESULT_SUCCESS);
426 rb.PushIpcInterface<ISystemUpdateControl>();
427
428 LOG_DEBUG(Service_NS, "called");
429 }
430};
431
432class NS_VM final : public ServiceFramework<NS_VM> {
433public:
434 explicit NS_VM() : ServiceFramework{"ns:vm"} {
435 // clang-format off
436 static const FunctionInfo functions[] = {
437 {1200, nullptr, "NeedsUpdateVulnerability"},
438 {1201, nullptr, "UpdateSafeSystemVersionForDebug"},
439 {1202, nullptr, "GetSafeSystemVersion"},
440 };
441 // clang-format on
442
443 RegisterHandlers(functions);
444 }
445};
446
10void InstallInterfaces(SM::ServiceManager& service_manager) { 447void InstallInterfaces(SM::ServiceManager& service_manager) {
448 std::make_shared<NS>("ns:am2")->InstallAsService(service_manager);
449 std::make_shared<NS>("ns:ec")->InstallAsService(service_manager);
450 std::make_shared<NS>("ns:rid")->InstallAsService(service_manager);
451 std::make_shared<NS>("ns:rt")->InstallAsService(service_manager);
452 std::make_shared<NS>("ns:web")->InstallAsService(service_manager);
453
454 std::make_shared<NS_DEV>()->InstallAsService(service_manager);
455 std::make_shared<NS_SU>()->InstallAsService(service_manager);
456 std::make_shared<NS_VM>()->InstallAsService(service_manager);
457
11 std::make_shared<PL_U>()->InstallAsService(service_manager); 458 std::make_shared<PL_U>()->InstallAsService(service_manager);
12} 459}
13 460
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 @@
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 8#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
9#include "core/hle/service/nvdrv/devices/nvmap.h" 9#include "core/hle/service/nvdrv/devices/nvmap.h"
10#include "video_core/gpu.h"
10#include "video_core/renderer_base.h" 11#include "video_core/renderer_base.h"
11#include "video_core/video_core.h"
12 12
13namespace Service::Nvidia::Devices { 13namespace Service::Nvidia::Devices {
14 14
@@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
30 addr, offset, width, height, stride, static_cast<PixelFormat>(format), 30 addr, offset, width, height, stride, static_cast<PixelFormat>(format),
31 transform, crop_rect}; 31 transform, crop_rect};
32 32
33 Core::System::GetInstance().perf_stats.EndGameFrame(); 33 auto& instance = Core::System::GetInstance();
34 34 instance.perf_stats.EndGameFrame();
35 VideoCore::g_renderer->SwapBuffers(framebuffer); 35 instance.Renderer().SwapBuffers(framebuffer);
36} 36}
37 37
38} // namespace Service::Nvidia::Devices 38} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" 9#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
10#include "core/hle/service/nvdrv/devices/nvmap.h" 10#include "core/hle/service/nvdrv/devices/nvmap.h"
11#include "video_core/memory_manager.h"
12#include "video_core/rasterizer_interface.h"
11#include "video_core/renderer_base.h" 13#include "video_core/renderer_base.h"
12#include "video_core/video_core.h"
13 14
14namespace Service::Nvidia::Devices { 15namespace Service::Nvidia::Devices {
15 16
@@ -150,15 +151,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
150 151
151 LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); 152 LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
152 153
153 auto& gpu = Core::System::GetInstance().GPU(); 154 const auto itr = buffer_mappings.find(params.offset);
154
155 auto itr = buffer_mappings.find(params.offset);
156
157 ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); 155 ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping");
158 156
157 auto& system_instance = Core::System::GetInstance();
158
159 // Remove this memory region from the rasterizer cache. 159 // Remove this memory region from the rasterizer cache.
160 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); 160 system_instance.Renderer().Rasterizer().FlushAndInvalidateRegion(params.offset,
161 itr->second.size);
161 162
163 auto& gpu = system_instance.GPU();
162 params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); 164 params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size);
163 165
164 buffer_mappings.erase(itr->second.offset); 166 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstdlib>
6#include <cstring>
7
5#include "common/assert.h" 8#include "common/assert.h"
6#include "common/logging/log.h" 9#include "common/logging/log.h"
7#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" 10#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 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <cstdlib>
9#include <cstring>
10#include <vector> 8#include <vector>
11#include "common/common_types.h" 9#include "common/common_types.h"
12#include "core/hle/service/nvdrv/devices/nvdevice.h" 10#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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" 8#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>&
97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { 97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
98 LOG_DEBUG(Service_NVDRV, "called"); 98 LOG_DEBUG(Service_NVDRV, "called");
99 IoctlActiveSlotMask params{}; 99 IoctlActiveSlotMask params{};
100 std::memcpy(&params, input.data(), input.size()); 100 if (input.size() > 0) {
101 std::memcpy(&params, input.data(), input.size());
102 }
101 params.slot = 0x07; 103 params.slot = 0x07;
102 params.mask = 0x01; 104 params.mask = 0x01;
103 std::memcpy(output.data(), &params, output.size()); 105 std::memcpy(output.data(), &params, output.size());
@@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
107u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { 109u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
108 LOG_DEBUG(Service_NVDRV, "called"); 110 LOG_DEBUG(Service_NVDRV, "called");
109 IoctlZcullGetCtxSize params{}; 111 IoctlZcullGetCtxSize params{};
110 std::memcpy(&params, input.data(), input.size()); 112 if (input.size() > 0) {
113 std::memcpy(&params, input.data(), input.size());
114 }
111 params.size = 0x1; 115 params.size = 0x1;
112 std::memcpy(output.data(), &params, output.size()); 116 std::memcpy(output.data(), &params, output.size());
113 return 0; 117 return 0;
@@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
116u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { 120u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
117 LOG_DEBUG(Service_NVDRV, "called"); 121 LOG_DEBUG(Service_NVDRV, "called");
118 IoctlNvgpuGpuZcullGetInfoArgs params{}; 122 IoctlNvgpuGpuZcullGetInfoArgs params{};
119 std::memcpy(&params, input.data(), input.size()); 123
124 if (input.size() > 0) {
125 std::memcpy(&params, input.data(), input.size());
126 }
127
120 params.width_align_pixels = 0x20; 128 params.width_align_pixels = 0x20;
121 params.height_align_pixels = 0x20; 129 params.height_align_pixels = 0x20;
122 params.pixel_squares_by_aliquots = 0x400; 130 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cstring>
6#include <map>
7#include "common/assert.h" 6#include "common/assert.h"
8#include "common/logging/log.h" 7#include "common/logging/log.h"
9#include "core/core.h" 8#include "core/core.h"
10#include "core/hle/service/nvdrv/devices/nvhost_gpu.h" 9#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
10#include "core/memory.h"
11#include "video_core/gpu.h"
12#include "video_core/memory_manager.h"
11 13
12namespace Service::Nvidia::Devices { 14namespace Service::Nvidia::Devices {
13 15
@@ -132,9 +134,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
132 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", 134 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
133 params.address, params.num_entries, params.flags); 135 params.address, params.num_entries, params.flags);
134 136
135 auto entries = std::vector<IoctlGpfifoEntry>(); 137 ASSERT_MSG(input.size() ==
136 entries.resize(params.num_entries); 138 sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry),
137 std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], 139 "Incorrect input size");
140
141 std::vector<IoctlGpfifoEntry> entries(params.num_entries);
142 std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)],
138 params.num_entries * sizeof(IoctlGpfifoEntry)); 143 params.num_entries * sizeof(IoctlGpfifoEntry));
139 for (auto entry : entries) { 144 for (auto entry : entries) {
140 Tegra::GPUVAddr va_addr = entry.Address(); 145 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 @@
6 6
7#include <memory> 7#include <memory>
8#include <vector> 8#include <vector>
9#include "common/bit_field.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "common/swap.h" 11#include "common/swap.h"
11#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
6
5#include "common/assert.h" 7#include "common/assert.h"
6#include "common/logging/log.h" 8#include "common/logging/log.h"
7#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" 9#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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
8#include <cstdlib>
9#include <cstring>
10#include <vector> 7#include <vector>
11#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/swap.h"
12#include "core/hle/service/nvdrv/devices/nvdevice.h" 10#include "core/hle/service/nvdrv/devices/nvdevice.h"
13 11
14namespace Service::Nvidia::Devices { 12namespace 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cinttypes> 6#include <cstring>
7 7
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/logging/log.h" 9#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 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <string>
9#include "core/hle/kernel/event.h" 8#include "core/hle/kernel/event.h"
10#include "core/hle/service/nvdrv/nvdrv.h" 9#include "core/hle/service/nvdrv/nvdrv.h"
11#include "core/hle/service/service.h" 10#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) {
54 return fd; 54 return fd;
55} 55}
56 56
57u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) { 57u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) {
58 auto itr = open_files.find(fd); 58 auto itr = open_files.find(fd);
59 ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); 59 ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
60 60
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 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/nvdrv/nvdrv.h"
9#include "core/hle/service/nvdrv/nvmemp.h" 7#include "core/hle/service/nvdrv/nvmemp.h"
10 8
11namespace Service::Nvidia { 9namespace 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 @@
4 4
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/alignment.h" 7#include "common/assert.h"
8#include "common/scope_exit.h" 8#include "common/logging/log.h"
9#include "core/core_timing.h"
10#include "core/hle/service/nvflinger/buffer_queue.h" 9#include "core/hle/service/nvflinger/buffer_queue.h"
11 10
12namespace Service { 11namespace 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <boost/optional.hpp>
6 7
7#include "common/alignment.h" 8#include "common/alignment.h"
9#include "common/assert.h"
10#include "common/logging/log.h"
8#include "common/microprofile.h" 11#include "common/microprofile.h"
9#include "common/scope_exit.h" 12#include "common/scope_exit.h"
10#include "core/core.h" 13#include "core/core.h"
@@ -31,7 +34,7 @@ NVFlinger::NVFlinger() {
31 34
32 // Schedule the screen composition events 35 // Schedule the screen composition events
33 composition_event = 36 composition_event =
34 CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { 37 CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
35 Compose(); 38 Compose();
36 CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); 39 CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event);
37 }); 40 });
@@ -43,7 +46,7 @@ NVFlinger::~NVFlinger() {
43 CoreTiming::UnscheduleEvent(composition_event, 0); 46 CoreTiming::UnscheduleEvent(composition_event, 0);
44} 47}
45 48
46u64 NVFlinger::OpenDisplay(const std::string& name) { 49u64 NVFlinger::OpenDisplay(std::string_view name) {
47 LOG_WARNING(Service, "Opening display {}", name); 50 LOG_WARNING(Service, "Opening display {}", name);
48 51
49 // TODO(Subv): Currently we only support the Default display. 52 // TODO(Subv): Currently we only support the Default display.
@@ -127,9 +130,11 @@ void NVFlinger::Compose() {
127 MicroProfileFlip(); 130 MicroProfileFlip();
128 131
129 if (buffer == boost::none) { 132 if (buffer == boost::none) {
133 auto& system_instance = Core::System::GetInstance();
134
130 // There was no queued buffer to draw, render previous frame 135 // There was no queued buffer to draw, render previous frame
131 Core::System::GetInstance().perf_stats.EndGameFrame(); 136 system_instance.perf_stats.EndGameFrame();
132 VideoCore::g_renderer->SwapBuffers({}); 137 system_instance.Renderer().SwapBuffers({});
133 continue; 138 continue;
134 } 139 }
135 140
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 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <boost/optional.hpp> 8#include <string>
9#include <string_view>
10#include <vector>
11
12#include "common/common_types.h"
9#include "core/hle/kernel/event.h" 13#include "core/hle/kernel/event.h"
10 14
11namespace CoreTiming { 15namespace CoreTiming {
@@ -41,7 +45,7 @@ public:
41 ~NVFlinger(); 45 ~NVFlinger();
42 46
43 /// Opens the specified display and returns the id. 47 /// Opens the specified display and returns the id.
44 u64 OpenDisplay(const std::string& name); 48 u64 OpenDisplay(std::string_view name);
45 49
46 /// Creates a layer on the specified display and returns the layer id. 50 /// Creates a layer on the specified display and returns the layer id.
47 u64 CreateLayer(u64 display_id); 51 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/pcie/pcie.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::PCIe {
12
13class ISession final : public ServiceFramework<ISession> {
14public:
15 explicit ISession() : ServiceFramework{"ISession"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "QueryFunctions"},
19 {1, nullptr, "AcquireFunction"},
20 {2, nullptr, "ReleaseFunction"},
21 {3, nullptr, "GetFunctionState"},
22 {4, nullptr, "GetBarProfile"},
23 {5, nullptr, "ReadConfig"},
24 {6, nullptr, "WriteConfig"},
25 {7, nullptr, "ReadBarRegion"},
26 {8, nullptr, "WriteBarRegion"},
27 {9, nullptr, "FindCapability"},
28 {10, nullptr, "FindExtendedCapability"},
29 {11, nullptr, "MapDma"},
30 {12, nullptr, "UnmapDma"},
31 {13, nullptr, "UnmapDmaBusAddress"},
32 {14, nullptr, "GetDmaBusAddress"},
33 {15, nullptr, "GetDmaBusAddressRange"},
34 {16, nullptr, "SetDmaEnable"},
35 {17, nullptr, "AcquireIrq"},
36 {18, nullptr, "ReleaseIrq"},
37 {19, nullptr, "SetIrqEnable"},
38 {20, nullptr, "SetAspmEnable"},
39 };
40 // clang-format on
41
42 RegisterHandlers(functions);
43 }
44};
45
46class PCIe final : public ServiceFramework<PCIe> {
47public:
48 explicit PCIe() : ServiceFramework{"pcie"} {
49 // clang-format off
50 static const FunctionInfo functions[] = {
51 {0, nullptr, "RegisterClassDriver"},
52 {1, nullptr, "QueryFunctionsUnregistered"},
53 };
54 // clang-format on
55
56 RegisterHandlers(functions);
57 }
58};
59
60void InstallInterfaces(SM::ServiceManager& sm) {
61 std::make_shared<PCIe>()->InstallAsService(sm);
62}
63
64} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PCIe {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/pcv/pcv.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::PCV {
12
13class PCV final : public ServiceFramework<PCV> {
14public:
15 explicit PCV() : ServiceFramework{"pcv"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SetPowerEnabled"},
19 {1, nullptr, "SetClockEnabled"},
20 {2, nullptr, "SetClockRate"},
21 {3, nullptr, "GetClockRate"},
22 {4, nullptr, "GetState"},
23 {5, nullptr, "GetPossibleClockRates"},
24 {6, nullptr, "SetMinVClockRate"},
25 {7, nullptr, "SetReset"},
26 {8, nullptr, "SetVoltageEnabled"},
27 {9, nullptr, "GetVoltageEnabled"},
28 {10, nullptr, "GetVoltageRange"},
29 {11, nullptr, "SetVoltageValue"},
30 {12, nullptr, "GetVoltageValue"},
31 {13, nullptr, "GetTemperatureThresholds"},
32 {14, nullptr, "SetTemperature"},
33 {15, nullptr, "Initialize"},
34 {16, nullptr, "IsInitialized"},
35 {17, nullptr, "Finalize"},
36 {18, nullptr, "PowerOn"},
37 {19, nullptr, "PowerOff"},
38 {20, nullptr, "ChangeVoltage"},
39 {21, nullptr, "GetPowerClockInfoEvent"},
40 {22, nullptr, "GetOscillatorClock"},
41 {23, nullptr, "GetDvfsTable"},
42 {24, nullptr, "GetModuleStateTable"},
43 {25, nullptr, "GetPowerDomainStateTable"},
44 {26, nullptr, "GetFuseInfo"},
45 };
46 // clang-format on
47
48 RegisterHandlers(functions);
49 }
50};
51
52class PCV_ARB final : public ServiceFramework<PCV_ARB> {
53public:
54 explicit PCV_ARB() : ServiceFramework{"pcv:arb"} {
55 // clang-format off
56 static const FunctionInfo functions[] = {
57 {0, nullptr, "ReleaseControl"},
58 };
59 // clang-format on
60
61 RegisterHandlers(functions);
62 }
63};
64
65class PCV_IMM final : public ServiceFramework<PCV_IMM> {
66public:
67 explicit PCV_IMM() : ServiceFramework{"pcv:imm"} {
68 // clang-format off
69 static const FunctionInfo functions[] = {
70 {0, nullptr, "SetClockRate"},
71 };
72 // clang-format on
73
74 RegisterHandlers(functions);
75 }
76};
77
78void InstallInterfaces(SM::ServiceManager& sm) {
79 std::make_shared<PCV>()->InstallAsService(sm);
80 std::make_shared<PCV_ARB>()->InstallAsService(sm);
81 std::make_shared<PCV_IMM>()->InstallAsService(sm);
82}
83
84} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PCV {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/service/psc/psc.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12
13namespace Service::PSC {
14
15class PSC_C final : public ServiceFramework<PSC_C> {
16public:
17 explicit PSC_C() : ServiceFramework{"psc:c"} {
18 // clang-format off
19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Unknown1"},
21 {1, nullptr, "Unknown2"},
22 {2, nullptr, "Unknown3"},
23 {3, nullptr, "Unknown4"},
24 {4, nullptr, "Unknown5"},
25 {5, nullptr, "Unknown6"},
26 {6, nullptr, "Unknown7"},
27 };
28 // clang-format on
29
30 RegisterHandlers(functions);
31 }
32};
33
34class IPmModule final : public ServiceFramework<IPmModule> {
35public:
36 explicit IPmModule() : ServiceFramework{"IPmModule"} {
37 // clang-format off
38 static const FunctionInfo functions[] = {
39 {0, nullptr, "Initialize"},
40 {1, nullptr, "GetRequest"},
41 {2, nullptr, "Acknowledge"},
42 {3, nullptr, "Unknown1"},
43 };
44 // clang-format on
45
46 RegisterHandlers(functions);
47 }
48};
49
50class PSC_M final : public ServiceFramework<PSC_M> {
51public:
52 explicit PSC_M() : ServiceFramework{"psc:m"} {
53 // clang-format off
54 static const FunctionInfo functions[] = {
55 {0, &PSC_M::GetPmModule, "GetPmModule"},
56 };
57 // clang-format on
58
59 RegisterHandlers(functions);
60 }
61
62private:
63 void GetPmModule(Kernel::HLERequestContext& ctx) {
64 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
65 rb.Push(RESULT_SUCCESS);
66 rb.PushIpcInterface<IPmModule>();
67
68 LOG_DEBUG(Service_PSC, "called");
69 }
70};
71
72void InstallInterfaces(SM::ServiceManager& sm) {
73 std::make_shared<PSC_C>()->InstallAsService(sm);
74 std::make_shared<PSC_M>()->InstallAsService(sm);
75}
76
77} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PSC {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
19#include "core/hle/service/am/am.h" 19#include "core/hle/service/am/am.h"
20#include "core/hle/service/aoc/aoc_u.h" 20#include "core/hle/service/aoc/aoc_u.h"
21#include "core/hle/service/apm/apm.h" 21#include "core/hle/service/apm/apm.h"
22#include "core/hle/service/arp/arp.h"
22#include "core/hle/service/audio/audio.h" 23#include "core/hle/service/audio/audio.h"
23#include "core/hle/service/bcat/bcat.h" 24#include "core/hle/service/bcat/bcat.h"
25#include "core/hle/service/bpc/bpc.h"
26#include "core/hle/service/btdrv/btdrv.h"
27#include "core/hle/service/btm/btm.h"
28#include "core/hle/service/caps/caps.h"
24#include "core/hle/service/erpt/erpt.h" 29#include "core/hle/service/erpt/erpt.h"
25#include "core/hle/service/es/es.h" 30#include "core/hle/service/es/es.h"
26#include "core/hle/service/eupld/eupld.h" 31#include "core/hle/service/eupld/eupld.h"
27#include "core/hle/service/fatal/fatal.h" 32#include "core/hle/service/fatal/fatal.h"
33#include "core/hle/service/fgm/fgm.h"
28#include "core/hle/service/filesystem/filesystem.h" 34#include "core/hle/service/filesystem/filesystem.h"
29#include "core/hle/service/friend/friend.h" 35#include "core/hle/service/friend/friend.h"
30#include "core/hle/service/grc/grc.h" 36#include "core/hle/service/grc/grc.h"
31#include "core/hle/service/hid/hid.h" 37#include "core/hle/service/hid/hid.h"
38#include "core/hle/service/lbl/lbl.h"
32#include "core/hle/service/ldn/ldn.h" 39#include "core/hle/service/ldn/ldn.h"
33#include "core/hle/service/ldr/ldr.h" 40#include "core/hle/service/ldr/ldr.h"
34#include "core/hle/service/lm/lm.h" 41#include "core/hle/service/lm/lm.h"
42#include "core/hle/service/mig/mig.h"
43#include "core/hle/service/mii/mii.h"
35#include "core/hle/service/mm/mm_u.h" 44#include "core/hle/service/mm/mm_u.h"
45#include "core/hle/service/ncm/ncm.h"
46#include "core/hle/service/nfc/nfc.h"
36#include "core/hle/service/nfp/nfp.h" 47#include "core/hle/service/nfp/nfp.h"
37#include "core/hle/service/nifm/nifm.h" 48#include "core/hle/service/nifm/nifm.h"
38#include "core/hle/service/nim/nim.h" 49#include "core/hle/service/nim/nim.h"
39#include "core/hle/service/ns/ns.h" 50#include "core/hle/service/ns/ns.h"
40#include "core/hle/service/nvdrv/nvdrv.h" 51#include "core/hle/service/nvdrv/nvdrv.h"
52#include "core/hle/service/pcie/pcie.h"
41#include "core/hle/service/pctl/pctl.h" 53#include "core/hle/service/pctl/pctl.h"
54#include "core/hle/service/pcv/pcv.h"
42#include "core/hle/service/pm/pm.h" 55#include "core/hle/service/pm/pm.h"
43#include "core/hle/service/prepo/prepo.h" 56#include "core/hle/service/prepo/prepo.h"
57#include "core/hle/service/psc/psc.h"
44#include "core/hle/service/service.h" 58#include "core/hle/service/service.h"
45#include "core/hle/service/set/settings.h" 59#include "core/hle/service/set/settings.h"
46#include "core/hle/service/sm/controller.h" 60#include "core/hle/service/sm/controller.h"
@@ -49,7 +63,9 @@
49#include "core/hle/service/spl/module.h" 63#include "core/hle/service/spl/module.h"
50#include "core/hle/service/ssl/ssl.h" 64#include "core/hle/service/ssl/ssl.h"
51#include "core/hle/service/time/time.h" 65#include "core/hle/service/time/time.h"
66#include "core/hle/service/usb/usb.h"
52#include "core/hle/service/vi/vi.h" 67#include "core/hle/service/vi/vi.h"
68#include "core/hle/service/wlan/wlan.h"
53 69
54using Kernel::ClientPort; 70using Kernel::ClientPort;
55using Kernel::ServerPort; 71using Kernel::ServerPort;
@@ -193,34 +209,50 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
193 AM::InstallInterfaces(*sm, nv_flinger); 209 AM::InstallInterfaces(*sm, nv_flinger);
194 AOC::InstallInterfaces(*sm); 210 AOC::InstallInterfaces(*sm);
195 APM::InstallInterfaces(*sm); 211 APM::InstallInterfaces(*sm);
196 BCAT::InstallInterfaces(*sm); 212 ARP::InstallInterfaces(*sm);
197 Audio::InstallInterfaces(*sm); 213 Audio::InstallInterfaces(*sm);
214 BCAT::InstallInterfaces(*sm);
215 BPC::InstallInterfaces(*sm);
216 BtDrv::InstallInterfaces(*sm);
217 BTM::InstallInterfaces(*sm);
218 Capture::InstallInterfaces(*sm);
198 ERPT::InstallInterfaces(*sm); 219 ERPT::InstallInterfaces(*sm);
199 ES::InstallInterfaces(*sm); 220 ES::InstallInterfaces(*sm);
200 EUPLD::InstallInterfaces(*sm); 221 EUPLD::InstallInterfaces(*sm);
201 Fatal::InstallInterfaces(*sm); 222 Fatal::InstallInterfaces(*sm);
223 FGM::InstallInterfaces(*sm);
202 FileSystem::InstallInterfaces(*sm); 224 FileSystem::InstallInterfaces(*sm);
203 Friend::InstallInterfaces(*sm); 225 Friend::InstallInterfaces(*sm);
204 GRC::InstallInterfaces(*sm); 226 GRC::InstallInterfaces(*sm);
205 HID::InstallInterfaces(*sm); 227 HID::InstallInterfaces(*sm);
228 LBL::InstallInterfaces(*sm);
206 LDN::InstallInterfaces(*sm); 229 LDN::InstallInterfaces(*sm);
207 LDR::InstallInterfaces(*sm); 230 LDR::InstallInterfaces(*sm);
208 LM::InstallInterfaces(*sm); 231 LM::InstallInterfaces(*sm);
232 Migration::InstallInterfaces(*sm);
233 Mii::InstallInterfaces(*sm);
209 MM::InstallInterfaces(*sm); 234 MM::InstallInterfaces(*sm);
235 NCM::InstallInterfaces(*sm);
236 NFC::InstallInterfaces(*sm);
210 NFP::InstallInterfaces(*sm); 237 NFP::InstallInterfaces(*sm);
211 NIFM::InstallInterfaces(*sm); 238 NIFM::InstallInterfaces(*sm);
212 NIM::InstallInterfaces(*sm); 239 NIM::InstallInterfaces(*sm);
213 NS::InstallInterfaces(*sm); 240 NS::InstallInterfaces(*sm);
214 Nvidia::InstallInterfaces(*sm); 241 Nvidia::InstallInterfaces(*sm);
242 PCIe::InstallInterfaces(*sm);
215 PCTL::InstallInterfaces(*sm); 243 PCTL::InstallInterfaces(*sm);
244 PCV::InstallInterfaces(*sm);
216 PlayReport::InstallInterfaces(*sm); 245 PlayReport::InstallInterfaces(*sm);
217 PM::InstallInterfaces(*sm); 246 PM::InstallInterfaces(*sm);
247 PSC::InstallInterfaces(*sm);
248 Set::InstallInterfaces(*sm);
218 Sockets::InstallInterfaces(*sm); 249 Sockets::InstallInterfaces(*sm);
219 SPL::InstallInterfaces(*sm); 250 SPL::InstallInterfaces(*sm);
220 SSL::InstallInterfaces(*sm); 251 SSL::InstallInterfaces(*sm);
221 Time::InstallInterfaces(*sm); 252 Time::InstallInterfaces(*sm);
253 USB::InstallInterfaces(*sm);
222 VI::InstallInterfaces(*sm, nv_flinger); 254 VI::InstallInterfaces(*sm, nv_flinger);
223 Set::InstallInterfaces(*sm); 255 WLAN::InstallInterfaces(*sm);
224 256
225 LOG_DEBUG(Service, "initialized OK"); 257 LOG_DEBUG(Service, "initialized OK");
226} 258}
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 @@
8#include <string> 8#include <string>
9#include <unordered_map> 9#include <unordered_map>
10#include <boost/container/flat_map.hpp> 10#include <boost/container/flat_map.hpp>
11#include "common/bit_field.h"
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "core/hle/kernel/hle_ipc.h" 12#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/object.h"
15 14
16//////////////////////////////////////////////////////////////////////////////////////////////////// 15////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace Service 16// 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 @@
8#include "core/hle/kernel/client_port.h" 8#include "core/hle/kernel/client_port.h"
9#include "core/hle/kernel/client_session.h" 9#include "core/hle/kernel/client_session.h"
10#include "core/hle/service/set/set.h" 10#include "core/hle/service/set/set.h"
11#include "core/settings.h"
11 12
12namespace Service::Set { 13namespace Service::Set {
13 14
@@ -31,6 +32,10 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
31 LanguageCode::ZH_HANT, 32 LanguageCode::ZH_HANT,
32}}; 33}};
33 34
35LanguageCode GetLanguageCodeFromIndex(size_t index) {
36 return available_language_codes.at(index);
37}
38
34void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { 39void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
35 ctx.WriteBuffer(available_language_codes); 40 ctx.WriteBuffer(available_language_codes);
36 41
@@ -49,9 +54,17 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
49 LOG_DEBUG(Service_SET, "called"); 54 LOG_DEBUG(Service_SET, "called");
50} 55}
51 56
57void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
58 IPC::ResponseBuilder rb{ctx, 4};
59 rb.Push(RESULT_SUCCESS);
60 rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index]));
61
62 LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index);
63}
64
52SET::SET() : ServiceFramework("set") { 65SET::SET() : ServiceFramework("set") {
53 static const FunctionInfo functions[] = { 66 static const FunctionInfo functions[] = {
54 {0, nullptr, "GetLanguageCode"}, 67 {0, &SET::GetLanguageCode, "GetLanguageCode"},
55 {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, 68 {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
56 {2, nullptr, "MakeLanguageCode"}, 69 {2, nullptr, "MakeLanguageCode"},
57 {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, 70 {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 {
28 ZH_HANS = 0x00736E61482D687A, 28 ZH_HANS = 0x00736E61482D687A,
29 ZH_HANT = 0x00746E61482D687A, 29 ZH_HANT = 0x00746E61482D687A,
30}; 30};
31LanguageCode GetLanguageCodeFromIndex(size_t idx);
31 32
32class SET final : public ServiceFramework<SET> { 33class SET final : public ServiceFramework<SET> {
33public: 34public:
@@ -35,6 +36,7 @@ public:
35 ~SET() = default; 36 ~SET() = default;
36 37
37private: 38private:
39 void GetLanguageCode(Kernel::HLERequestContext& ctx);
38 void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); 40 void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
39 void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); 41 void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx);
40}; 42};
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <string> 8#include <string>
8#include <unordered_map> 9#include <unordered_map>
9#include "core/hle/kernel/kernel.h" 10
11#include "core/hle/kernel/object.h"
10#include "core/hle/result.h" 12#include "core/hle/result.h"
11#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
12 14
@@ -19,6 +21,8 @@ class SessionRequestHandler;
19 21
20namespace Service::SM { 22namespace Service::SM {
21 23
24class Controller;
25
22/// Interface to "sm:" service 26/// Interface to "sm:" service
23class SM final : public ServiceFramework<SM> { 27class SM final : public ServiceFramework<SM> {
24public: 28public:
@@ -32,8 +36,6 @@ private:
32 std::shared_ptr<ServiceManager> service_manager; 36 std::shared_ptr<ServiceManager> service_manager;
33}; 37};
34 38
35class Controller;
36
37constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); 39constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1);
38constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); 40constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
39constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); 41constexpr 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:
80 {5, nullptr, "GetTimeZoneRuleVersion"}, 80 {5, nullptr, "GetTimeZoneRuleVersion"},
81 {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, 81 {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
82 {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, 82 {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
83 {200, nullptr, "ToPosixTime"}, 83 {201, nullptr, "ToPosixTime"},
84 {201, nullptr, "ToPosixTimeWithMyRule"}, 84 {202, nullptr, "ToPosixTimeWithMyRule"},
85 }; 85 };
86 RegisterHandlers(functions); 86 RegisterHandlers(functions);
87 } 87 }
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12#include "core/hle/service/usb/usb.h"
13
14namespace Service::USB {
15
16class IDsInterface final : public ServiceFramework<IDsInterface> {
17public:
18 explicit IDsInterface() : ServiceFramework{"IDsInterface"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "GetDsEndpoint"},
22 {1, nullptr, "GetSetupEvent"},
23 {2, nullptr, "Unknown"},
24 {3, nullptr, "EnableInterface"},
25 {4, nullptr, "DisableInterface"},
26 {5, nullptr, "CtrlInPostBufferAsync"},
27 {6, nullptr, "CtrlOutPostBufferAsync"},
28 {7, nullptr, "GetCtrlInCompletionEvent"},
29 {8, nullptr, "GetCtrlInReportData"},
30 {9, nullptr, "GetCtrlOutCompletionEvent"},
31 {10, nullptr, "GetCtrlOutReportData"},
32 {11, nullptr, "StallCtrl"},
33 {12, nullptr, "AppendConfigurationData"},
34 };
35 // clang-format on
36
37 RegisterHandlers(functions);
38 }
39};
40
41class USB_DS final : public ServiceFramework<USB_DS> {
42public:
43 explicit USB_DS() : ServiceFramework{"usb:ds"} {
44 // clang-format off
45 static const FunctionInfo functions[] = {
46 {0, nullptr, "BindDevice"},
47 {1, nullptr, "BindClientProcess"},
48 {2, nullptr, "GetDsInterface"},
49 {3, nullptr, "GetStateChangeEvent"},
50 {4, nullptr, "GetState"},
51 {5, nullptr, "ClearDeviceData"},
52 {6, nullptr, "AddUsbStringDescriptor"},
53 {7, nullptr, "DeleteUsbStringDescriptor"},
54 {8, nullptr, "SetUsbDeviceDescriptor"},
55 {9, nullptr, "SetBinaryObjectStore"},
56 {10, nullptr, "Enable"},
57 {11, nullptr, "Disable"},
58 };
59 // clang-format on
60
61 RegisterHandlers(functions);
62 }
63};
64
65class IClientEpSession final : public ServiceFramework<IClientEpSession> {
66public:
67 explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} {
68 // clang-format off
69 static const FunctionInfo functions[] = {
70 {0, nullptr, "Unknown1"},
71 {1, nullptr, "Unknown2"},
72 {2, nullptr, "Unknown3"},
73 {3, nullptr, "Unknown4"},
74 {4, nullptr, "PostBufferAsync"},
75 {5, nullptr, "Unknown5"},
76 {6, nullptr, "Unknown6"},
77 {7, nullptr, "Unknown7"},
78 {8, nullptr, "Unknown8"},
79 };
80 // clang-format on
81
82 RegisterHandlers(functions);
83 }
84};
85
86class IClientIfSession final : public ServiceFramework<IClientIfSession> {
87public:
88 explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} {
89 // clang-format off
90 static const FunctionInfo functions[] = {
91 {0, nullptr, "Unknown1"},
92 {1, nullptr, "Unknown2"},
93 {2, nullptr, "Unknown3"},
94 {3, nullptr, "Unknown4"},
95 {4, nullptr, "Unknown5"},
96 {5, nullptr, "CtrlXferAsync"},
97 {6, nullptr, "Unknown6"},
98 {7, nullptr, "GetCtrlXferReport"},
99 {8, nullptr, "Unknown7"},
100 {9, nullptr, "GetClientEpSession"},
101 };
102 // clang-format on
103
104 RegisterHandlers(functions);
105 }
106};
107
108class USB_HS final : public ServiceFramework<USB_HS> {
109public:
110 explicit USB_HS() : ServiceFramework{"usb:hs"} {
111 // clang-format off
112 static const FunctionInfo functions[] = {
113 {0, nullptr, "BindClientProcess"},
114 {1, nullptr, "Unknown1"},
115 {2, nullptr, "Unknown2"},
116 {3, nullptr, "Unknown3"},
117 {4, nullptr, "Unknown4"},
118 {5, nullptr, "Unknown5"},
119 {6, nullptr, "GetInterfaceStateChangeEvent"},
120 {7, nullptr, "GetClientIfSession"},
121 };
122 // clang-format on
123
124 RegisterHandlers(functions);
125 }
126};
127
128class IPdSession final : public ServiceFramework<IPdSession> {
129public:
130 explicit IPdSession() : ServiceFramework{"IPdSession"} {
131 // clang-format off
132 static const FunctionInfo functions[] = {
133 {0, nullptr, "BindNoticeEvent"},
134 {1, nullptr, "Unknown1"},
135 {2, nullptr, "GetStatus"},
136 {3, nullptr, "GetNotice"},
137 {4, nullptr, "Unknown2"},
138 {5, nullptr, "Unknown3"},
139 {6, nullptr, "ReplyPowerRequest"},
140 };
141 // clang-format on
142
143 RegisterHandlers(functions);
144 }
145};
146
147class USB_PD final : public ServiceFramework<USB_PD> {
148public:
149 explicit USB_PD() : ServiceFramework{"usb:pd"} {
150 // clang-format off
151 static const FunctionInfo functions[] = {
152 {0, &USB_PD::GetPdSession, "GetPdSession"},
153 };
154 // clang-format on
155
156 RegisterHandlers(functions);
157 }
158
159private:
160 void GetPdSession(Kernel::HLERequestContext& ctx) {
161 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
162 rb.Push(RESULT_SUCCESS);
163 rb.PushIpcInterface<IPdSession>();
164
165 LOG_DEBUG(Service_USB, "called");
166 }
167};
168
169class IPdCradleSession final : public ServiceFramework<IPdCradleSession> {
170public:
171 explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} {
172 // clang-format off
173 static const FunctionInfo functions[] = {
174 {0, nullptr, "VdmUserWrite"},
175 {1, nullptr, "VdmUserRead"},
176 {2, nullptr, "Vdm20Init"},
177 {3, nullptr, "GetFwType"},
178 {4, nullptr, "GetFwRevision"},
179 {5, nullptr, "GetManufacturerId"},
180 {6, nullptr, "GetDeviceId"},
181 {7, nullptr, "Unknown1"},
182 {8, nullptr, "Unknown2"},
183 };
184 // clang-format on
185
186 RegisterHandlers(functions);
187 }
188};
189
190class USB_PD_C final : public ServiceFramework<USB_PD_C> {
191public:
192 explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} {
193 // clang-format off
194 static const FunctionInfo functions[] = {
195 {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"},
196 };
197 // clang-format on
198
199 RegisterHandlers(functions);
200 }
201
202private:
203 void GetPdCradleSession(Kernel::HLERequestContext& ctx) {
204 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
205 rb.Push(RESULT_SUCCESS);
206 rb.PushIpcInterface<IPdCradleSession>();
207
208 LOG_DEBUG(Service_USB, "called");
209 }
210};
211
212class USB_PM final : public ServiceFramework<USB_PM> {
213public:
214 explicit USB_PM() : ServiceFramework{"usb:pm"} {
215 // clang-format off
216 static const FunctionInfo functions[] = {
217 {0, nullptr, "Unknown1"},
218 {1, nullptr, "Unknown2"},
219 {2, nullptr, "Unknown3"},
220 {3, nullptr, "Unknown4"},
221 {4, nullptr, "Unknown5"},
222 {5, nullptr, "Unknown6"},
223 };
224 // clang-format on
225
226 RegisterHandlers(functions);
227 }
228};
229
230void InstallInterfaces(SM::ServiceManager& sm) {
231 std::make_shared<USB_DS>()->InstallAsService(sm);
232 std::make_shared<USB_HS>()->InstallAsService(sm);
233 std::make_shared<USB_PD>()->InstallAsService(sm);
234 std::make_shared<USB_PD_C>()->InstallAsService(sm);
235 std::make_shared<USB_PM>()->InstallAsService(sm);
236}
237
238} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::USB {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9#include "core/hle/service/wlan/wlan.h"
10
11namespace Service::WLAN {
12
13class WLANInfra final : public ServiceFramework<WLANInfra> {
14public:
15 explicit WLANInfra() : ServiceFramework{"wlan:inf"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "Unknown1"},
19 {1, nullptr, "Unknown2"},
20 {2, nullptr, "GetMacAddress"},
21 {3, nullptr, "StartScan"},
22 {4, nullptr, "StopScan"},
23 {5, nullptr, "Connect"},
24 {6, nullptr, "CancelConnect"},
25 {7, nullptr, "Disconnect"},
26 {8, nullptr, "Unknown3"},
27 {9, nullptr, "Unknown4"},
28 {10, nullptr, "GetState"},
29 {11, nullptr, "GetScanResult"},
30 {12, nullptr, "GetRssi"},
31 {13, nullptr, "ChangeRxAntenna"},
32 {14, nullptr, "Unknown5"},
33 {15, nullptr, "Unknown6"},
34 {16, nullptr, "RequestWakeUp"},
35 {17, nullptr, "RequestIfUpDown"},
36 {18, nullptr, "Unknown7"},
37 {19, nullptr, "Unknown8"},
38 {20, nullptr, "Unknown9"},
39 {21, nullptr, "Unknown10"},
40 {22, nullptr, "Unknown11"},
41 {23, nullptr, "Unknown12"},
42 {24, nullptr, "Unknown13"},
43 {25, nullptr, "Unknown14"},
44 {26, nullptr, "Unknown15"},
45 {27, nullptr, "Unknown16"},
46 };
47 // clang-format on
48
49 RegisterHandlers(functions);
50 }
51};
52
53class WLANLocal final : public ServiceFramework<WLANLocal> {
54public:
55 explicit WLANLocal() : ServiceFramework{"wlan:lcl"} {
56 // clang-format off
57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Unknown1"},
59 {1, nullptr, "Unknown2"},
60 {2, nullptr, "Unknown3"},
61 {3, nullptr, "Unknown4"},
62 {4, nullptr, "Unknown5"},
63 {5, nullptr, "Unknown6"},
64 {6, nullptr, "GetMacAddress"},
65 {7, nullptr, "CreateBss"},
66 {8, nullptr, "DestroyBss"},
67 {9, nullptr, "StartScan"},
68 {10, nullptr, "StopScan"},
69 {11, nullptr, "Connect"},
70 {12, nullptr, "CancelConnect"},
71 {13, nullptr, "Join"},
72 {14, nullptr, "CancelJoin"},
73 {15, nullptr, "Disconnect"},
74 {16, nullptr, "SetBeaconLostCount"},
75 {17, nullptr, "Unknown7"},
76 {18, nullptr, "Unknown8"},
77 {19, nullptr, "Unknown9"},
78 {20, nullptr, "GetBssIndicationEvent"},
79 {21, nullptr, "GetBssIndicationInfo"},
80 {22, nullptr, "GetState"},
81 {23, nullptr, "GetAllowedChannels"},
82 {24, nullptr, "AddIe"},
83 {25, nullptr, "DeleteIe"},
84 {26, nullptr, "Unknown10"},
85 {27, nullptr, "Unknown11"},
86 {28, nullptr, "CreateRxEntry"},
87 {29, nullptr, "DeleteRxEntry"},
88 {30, nullptr, "Unknown12"},
89 {31, nullptr, "Unknown13"},
90 {32, nullptr, "AddMatchingDataToRxEntry"},
91 {33, nullptr, "RemoveMatchingDataFromRxEntry"},
92 {34, nullptr, "GetScanResult"},
93 {35, nullptr, "Unknown14"},
94 {36, nullptr, "SetActionFrameWithBeacon"},
95 {37, nullptr, "CancelActionFrameWithBeacon"},
96 {38, nullptr, "CreateRxEntryForActionFrame"},
97 {39, nullptr, "DeleteRxEntryForActionFrame"},
98 {40, nullptr, "Unknown15"},
99 {41, nullptr, "Unknown16"},
100 {42, nullptr, "CancelGetActionFrame"},
101 {43, nullptr, "GetRssi"},
102 {44, nullptr, "Unknown17"},
103 {45, nullptr, "Unknown18"},
104 {46, nullptr, "Unknown19"},
105 {47, nullptr, "Unknown20"},
106 {48, nullptr, "Unknown21"},
107 };
108 // clang-format on
109
110 RegisterHandlers(functions);
111 }
112};
113
114class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> {
115public:
116 explicit WLANLocalGetFrame() : ServiceFramework{"wlan:lg"} {
117 // clang-format off
118 static const FunctionInfo functions[] = {
119 {0, nullptr, "Unknown"},
120 };
121 // clang-format on
122
123 RegisterHandlers(functions);
124 }
125};
126
127class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> {
128public:
129 explicit WLANSocketGetFrame() : ServiceFramework{"wlan:sg"} {
130 // clang-format off
131 static const FunctionInfo functions[] = {
132 {0, nullptr, "Unknown"},
133 };
134 // clang-format on
135
136 RegisterHandlers(functions);
137 }
138};
139
140class WLANSocketManager final : public ServiceFramework<WLANSocketManager> {
141public:
142 explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} {
143 // clang-format off
144 static const FunctionInfo functions[] = {
145 {0, nullptr, "Unknown1"},
146 {1, nullptr, "Unknown2"},
147 {2, nullptr, "Unknown3"},
148 {3, nullptr, "Unknown4"},
149 {4, nullptr, "Unknown5"},
150 {5, nullptr, "Unknown6"},
151 {6, nullptr, "GetMacAddress"},
152 {7, nullptr, "SwitchTsfTimerFunction"},
153 {8, nullptr, "Unknown7"},
154 {9, nullptr, "Unknown8"},
155 {10, nullptr, "Unknown9"},
156 {11, nullptr, "Unknown10"},
157 };
158 // clang-format on
159
160 RegisterHandlers(functions);
161 }
162};
163
164void InstallInterfaces(SM::ServiceManager& sm) {
165 std::make_shared<WLANInfra>()->InstallAsService(sm);
166 std::make_shared<WLANLocal>()->InstallAsService(sm);
167 std::make_shared<WLANLocalGetFrame>()->InstallAsService(sm);
168 std::make_shared<WLANSocketGetFrame>()->InstallAsService(sm);
169 std::make_shared<WLANSocketManager>()->InstallAsService(sm);
170}
171
172} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::WLAN {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // 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 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include "common/alignment.h"
7#include "common/assert.h"
8#include "common/logging/log.h"
9#include "core/hw/aes/ccm.h"
10#include "core/hw/aes/key.h"
11
12namespace HW {
13namespace AES {
14
15std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce,
16 size_t slot_id) {
17 UNIMPLEMENTED();
18 return {};
19}
20
21std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce,
22 size_t slot_id) {
23 UNIMPLEMENTED();
24 return {};
25}
26
27} // namespace AES
28} // 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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/logging/log.h"
7#include "core/hw/hw.h"
8#include "core/hw/lcd.h"
9
10namespace HW {
11
12template <typename T>
13inline void Read(T& var, const u32 addr) {
14 switch (addr & 0xFFFFF000) {
15 case VADDR_GPU:
16 case VADDR_GPU + 0x1000:
17 case VADDR_GPU + 0x2000:
18 case VADDR_GPU + 0x3000:
19 case VADDR_GPU + 0x4000:
20 case VADDR_GPU + 0x5000:
21 case VADDR_GPU + 0x6000:
22 case VADDR_GPU + 0x7000:
23 case VADDR_GPU + 0x8000:
24 case VADDR_GPU + 0x9000:
25 case VADDR_GPU + 0xA000:
26 case VADDR_GPU + 0xB000:
27 case VADDR_GPU + 0xC000:
28 case VADDR_GPU + 0xD000:
29 case VADDR_GPU + 0xE000:
30 case VADDR_GPU + 0xF000:
31 break;
32 case VADDR_LCD:
33 LCD::Read(var, addr);
34 break;
35 default:
36 LOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
37 break;
38 }
39}
40
41template <typename T>
42inline void Write(u32 addr, const T data) {
43 switch (addr & 0xFFFFF000) {
44 case VADDR_GPU:
45 case VADDR_GPU + 0x1000:
46 case VADDR_GPU + 0x2000:
47 case VADDR_GPU + 0x3000:
48 case VADDR_GPU + 0x4000:
49 case VADDR_GPU + 0x5000:
50 case VADDR_GPU + 0x6000:
51 case VADDR_GPU + 0x7000:
52 case VADDR_GPU + 0x8000:
53 case VADDR_GPU + 0x9000:
54 case VADDR_GPU + 0xA000:
55 case VADDR_GPU + 0xB000:
56 case VADDR_GPU + 0xC000:
57 case VADDR_GPU + 0xD000:
58 case VADDR_GPU + 0xE000:
59 case VADDR_GPU + 0xF000:
60 break;
61 case VADDR_LCD:
62 LCD::Write(addr, data);
63 break;
64 default:
65 LOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
66 break;
67 }
68}
69
70// Explicitly instantiate template functions because we aren't defining this in the header:
71
72template void Read<u64>(u64& var, const u32 addr);
73template void Read<u32>(u32& var, const u32 addr);
74template void Read<u16>(u16& var, const u32 addr);
75template void Read<u8>(u8& var, const u32 addr);
76
77template void Write<u64>(u32 addr, const u64 data);
78template void Write<u32>(u32 addr, const u32 data);
79template void Write<u16>(u32 addr, const u16 data);
80template void Write<u8>(u32 addr, const u8 data);
81
82/// Update hardware
83void Update() {}
84
85/// Initialize hardware
86void Init() {
87 LCD::Init();
88 LOG_DEBUG(HW, "Initialized OK");
89}
90
91/// Shutdown hardware
92void Shutdown() {
93 LCD::Shutdown();
94 LOG_DEBUG(HW, "Shutdown OK");
95}
96} // 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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace HW {
10
11/// Beginnings of IO register regions, in the user VA space.
12enum : u32 {
13 VADDR_HASH = 0x1EC01000,
14 VADDR_CSND = 0x1EC03000,
15 VADDR_DSP = 0x1EC40000,
16 VADDR_PDN = 0x1EC41000,
17 VADDR_CODEC = 0x1EC41000,
18 VADDR_SPI = 0x1EC42000,
19 VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM?
20 VADDR_I2C = 0x1EC44000,
21 VADDR_CODEC_2 = 0x1EC45000,
22 VADDR_HID = 0x1EC46000,
23 VADDR_GPIO = 0x1EC47000,
24 VADDR_I2C_2 = 0x1EC48000,
25 VADDR_SPI_3 = 0x1EC60000,
26 VADDR_I2C_3 = 0x1EC61000,
27 VADDR_MIC = 0x1EC62000,
28 VADDR_PXI = 0x1EC63000,
29 VADDR_LCD = 0x1ED02000,
30 VADDR_DSP_2 = 0x1ED03000,
31 VADDR_HASH_2 = 0x1EE01000,
32 VADDR_GPU = 0x1EF00000,
33};
34
35template <typename T>
36void Read(T& var, const u32 addr);
37
38template <typename T>
39void Write(u32 addr, const T data);
40
41/// Update hardware
42void Update();
43
44/// Initialize hardware
45void Init();
46
47/// Shutdown hardware
48void Shutdown();
49
50} // 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 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include "common/common_types.h"
7#include "common/logging/log.h"
8#include "core/hw/hw.h"
9#include "core/hw/lcd.h"
10#include "core/tracer/recorder.h"
11
12namespace LCD {
13
14Regs g_regs;
15
16template <typename T>
17inline void Read(T& var, const u32 raw_addr) {
18 u32 addr = raw_addr - HW::VADDR_LCD;
19 u32 index = addr / 4;
20
21 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
22 if (index >= 0x400 || !std::is_same<T, u32>::value) {
23 LOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
24 return;
25 }
26
27 var = g_regs[index];
28}
29
30template <typename T>
31inline void Write(u32 addr, const T data) {
32 addr -= HW::VADDR_LCD;
33 u32 index = addr / 4;
34
35 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
36 if (index >= 0x400 || !std::is_same<T, u32>::value) {
37 LOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
38 return;
39 }
40
41 g_regs[index] = static_cast<u32>(data);
42}
43
44// Explicitly instantiate template functions because we aren't defining this in the header:
45
46template void Read<u64>(u64& var, const u32 addr);
47template void Read<u32>(u32& var, const u32 addr);
48template void Read<u16>(u16& var, const u32 addr);
49template void Read<u8>(u8& var, const u32 addr);
50
51template void Write<u64>(u32 addr, const u64 data);
52template void Write<u32>(u32 addr, const u32 data);
53template void Write<u16>(u32 addr, const u16 data);
54template void Write<u8>(u32 addr, const u8 data);
55
56/// Initialize hardware
57void Init() {
58 memset(&g_regs, 0, sizeof(g_regs));
59 LOG_DEBUG(HW_LCD, "Initialized OK");
60}
61
62/// Shutdown hardware
63void Shutdown() {
64 LOG_DEBUG(HW_LCD, "Shutdown OK");
65}
66
67} // 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 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8#include <type_traits>
9#include "common/bit_field.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h"
12
13#define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32))
14
15namespace LCD {
16
17struct Regs {
18
19 union ColorFill {
20 u32 raw;
21
22 BitField<0, 8, u32> color_r;
23 BitField<8, 8, u32> color_g;
24 BitField<16, 8, u32> color_b;
25 BitField<24, 1, u32> is_enabled;
26 };
27
28 INSERT_PADDING_WORDS(0x81);
29 ColorFill color_fill_top;
30 INSERT_PADDING_WORDS(0xE);
31 u32 backlight_top;
32
33 INSERT_PADDING_WORDS(0x1F0);
34
35 ColorFill color_fill_bottom;
36 INSERT_PADDING_WORDS(0xE);
37 u32 backlight_bottom;
38 INSERT_PADDING_WORDS(0x16F);
39
40 static constexpr size_t NumIds() {
41 return sizeof(Regs) / sizeof(u32);
42 }
43
44 const u32& operator[](int index) const {
45 const u32* content = reinterpret_cast<const u32*>(this);
46 return content[index];
47 }
48
49 u32& operator[](int index) {
50 u32* content = reinterpret_cast<u32*>(this);
51 return content[index];
52 }
53};
54static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout");
55
56// TODO: MSVC does not support using offsetof() on non-static data members even though this
57// is technically allowed since C++11. This macro should be enabled once MSVC adds
58// support for that.
59#ifndef _MSC_VER
60#define ASSERT_REG_POSITION(field_name, position) \
61 static_assert(offsetof(Regs, field_name) == position * 4, \
62 "Field " #field_name " has invalid position")
63
64ASSERT_REG_POSITION(color_fill_top, 0x81);
65ASSERT_REG_POSITION(backlight_top, 0x90);
66ASSERT_REG_POSITION(color_fill_bottom, 0x281);
67ASSERT_REG_POSITION(backlight_bottom, 0x290);
68
69#undef ASSERT_REG_POSITION
70#endif // !defined(_MSC_VER)
71
72extern Regs g_regs;
73
74template <typename T>
75void Read(T& var, const u32 addr);
76
77template <typename T>
78void Write(u32 addr, const T data);
79
80/// Initialize hardware
81void Init();
82
83/// Shutdown hardware
84void Shutdown();
85
86} // 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 {
20AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) 20AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
21 : AppLoader(std::move(file)) {} 21 : AppLoader(std::move(file)) {}
22 22
23AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
24 FileSys::VirtualDir directory)
25 : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {}
26
23FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { 27FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
24 if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { 28 if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
25 return FileType::DeconstructedRomDirectory; 29 return FileType::DeconstructedRomDirectory;
@@ -34,7 +38,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
34 return ResultStatus::ErrorAlreadyLoaded; 38 return ResultStatus::ErrorAlreadyLoaded;
35 } 39 }
36 40
37 const FileSys::VirtualDir dir = file->GetContainingDirectory(); 41 if (dir == nullptr) {
42 if (file == nullptr)
43 return ResultStatus::ErrorInvalidFormat;
44 dir = file->GetContainingDirectory();
45 }
46
38 const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); 47 const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
39 if (npdm == nullptr) 48 if (npdm == nullptr)
40 return ResultStatus::ErrorInvalidFormat; 49 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 @@
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/file_sys/program_metadata.h" 9#include "core/file_sys/program_metadata.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
13namespace Loader { 13namespace Loader {
@@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader {
22public: 22public:
23 explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); 23 explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file);
24 24
25 // Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
26 explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory);
27
25 /** 28 /**
26 * Returns the type of the file 29 * Returns the type of the file
27 * @param file std::shared_ptr<VfsFile> open file 30 * @param file std::shared_ptr<VfsFile> open file
@@ -40,6 +43,7 @@ public:
40private: 43private:
41 FileSys::ProgramMetadata metadata; 44 FileSys::ProgramMetadata metadata;
42 FileSys::VirtualFile romfs; 45 FileSys::VirtualFile romfs;
46 FileSys::VirtualDir dir;
43}; 47};
44 48
45} // namespace Loader 49} // 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) {
311 CodeSet::Segment* codeset_segment; 311 CodeSet::Segment* codeset_segment;
312 u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); 312 u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
313 if (permission_flags == (PF_R | PF_X)) { 313 if (permission_flags == (PF_R | PF_X)) {
314 codeset_segment = &codeset->code; 314 codeset_segment = &codeset->CodeSegment();
315 } else if (permission_flags == (PF_R)) { 315 } else if (permission_flags == (PF_R)) {
316 codeset_segment = &codeset->rodata; 316 codeset_segment = &codeset->RODataSegment();
317 } else if (permission_flags == (PF_R | PF_W)) { 317 } else if (permission_flags == (PF_R | PF_W)) {
318 codeset_segment = &codeset->data; 318 codeset_segment = &codeset->DataSegment();
319 } else { 319 } else {
320 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, 320 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
321 p->p_flags); 321 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 @@
13#include "core/loader/nca.h" 13#include "core/loader/nca.h"
14#include "core/loader/nro.h" 14#include "core/loader/nro.h"
15#include "core/loader/nso.h" 15#include "core/loader/nso.h"
16#include "core/loader/xci.h"
16 17
17namespace Loader { 18namespace Loader {
18 19
@@ -35,6 +36,7 @@ FileType IdentifyFile(FileSys::VirtualFile file) {
35 CHECK_TYPE(NSO) 36 CHECK_TYPE(NSO)
36 CHECK_TYPE(NRO) 37 CHECK_TYPE(NRO)
37 CHECK_TYPE(NCA) 38 CHECK_TYPE(NCA)
39 CHECK_TYPE(XCI)
38 40
39#undef CHECK_TYPE 41#undef CHECK_TYPE
40 42
@@ -60,6 +62,8 @@ FileType GuessFromFilename(const std::string& name) {
60 return FileType::NSO; 62 return FileType::NSO;
61 if (extension == "nca") 63 if (extension == "nca")
62 return FileType::NCA; 64 return FileType::NCA;
65 if (extension == "xci")
66 return FileType::XCI;
63 67
64 return FileType::Unknown; 68 return FileType::Unknown;
65} 69}
@@ -74,6 +78,8 @@ const char* GetFileTypeString(FileType type) {
74 return "NSO"; 78 return "NSO";
75 case FileType::NCA: 79 case FileType::NCA:
76 return "NCA"; 80 return "NCA";
81 case FileType::XCI:
82 return "XCI";
77 case FileType::DeconstructedRomDirectory: 83 case FileType::DeconstructedRomDirectory:
78 return "Directory"; 84 return "Directory";
79 case FileType::Error: 85 case FileType::Error:
@@ -111,6 +117,9 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
111 case FileType::NCA: 117 case FileType::NCA:
112 return std::make_unique<AppLoader_NCA>(std::move(file)); 118 return std::make_unique<AppLoader_NCA>(std::move(file));
113 119
120 case FileType::XCI:
121 return std::make_unique<AppLoader_XCI>(std::move(file));
122
114 // NX deconstructed ROM directory. 123 // NX deconstructed ROM directory.
115 case FileType::DeconstructedRomDirectory: 124 case FileType::DeconstructedRomDirectory:
116 return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file)); 125 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 @@
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/file_util.h" 15#include "common/file_util.h"
16#include "core/file_sys/vfs.h" 16#include "core/file_sys/vfs.h"
17#include "core/hle/kernel/kernel.h" 17#include "core/hle/kernel/object.h"
18 18
19namespace Kernel { 19namespace Kernel {
20struct AddressMapping; 20struct AddressMapping;
@@ -31,6 +31,7 @@ enum class FileType {
31 NSO, 31 NSO,
32 NRO, 32 NRO,
33 NCA, 33 NCA,
34 XCI,
34 DeconstructedRomDirectory, 35 DeconstructedRomDirectory,
35}; 36};
36 37
@@ -72,7 +73,8 @@ enum class ResultStatus {
72 ErrorNotUsed, 73 ErrorNotUsed,
73 ErrorAlreadyLoaded, 74 ErrorAlreadyLoaded,
74 ErrorMemoryAllocationFailed, 75 ErrorMemoryAllocationFailed,
75 ErrorEncrypted, 76 ErrorMissingKeys,
77 ErrorDecrypting,
76 ErrorUnsupportedArch, 78 ErrorUnsupportedArch,
77}; 79};
78 80
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 @@
22 22
23namespace Loader { 23namespace Loader {
24 24
25AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} 25AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_)
26 : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {}
26 27
27FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { 28FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
28 // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. 29 FileSys::NCA nca(file);
29 FileSys::NCAHeader header{};
30 if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header))
31 return FileType::Error;
32 30
33 if (IsValidNCA(header) && header.content_type == FileSys::NCAContentType::Program) 31 if (nca.GetStatus() == ResultStatus::Success &&
32 nca.GetType() == FileSys::NCAContentType::Program)
34 return FileType::NCA; 33 return FileType::NCA;
35 34
36 return FileType::Error; 35 return FileType::Error;
@@ -41,8 +40,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
41 return ResultStatus::ErrorAlreadyLoaded; 40 return ResultStatus::ErrorAlreadyLoaded;
42 } 41 }
43 42
44 nca = std::make_unique<FileSys::NCA>(file); 43 const auto result = nca->GetStatus();
45 ResultStatus result = nca->GetStatus();
46 if (result != ResultStatus::Success) { 44 if (result != ResultStatus::Success) {
47 return result; 45 return result;
48 } 46 }
@@ -50,44 +48,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
50 if (nca->GetType() != FileSys::NCAContentType::Program) 48 if (nca->GetType() != FileSys::NCAContentType::Program)
51 return ResultStatus::ErrorInvalidFormat; 49 return ResultStatus::ErrorInvalidFormat;
52 50
53 auto exefs = nca->GetExeFS(); 51 const auto exefs = nca->GetExeFS();
54 52
55 if (exefs == nullptr) 53 if (exefs == nullptr)
56 return ResultStatus::ErrorInvalidFormat; 54 return ResultStatus::ErrorInvalidFormat;
57 55
58 result = metadata.Load(exefs->GetFile("main.npdm")); 56 directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs);
59 if (result != ResultStatus::Success) {
60 return result;
61 }
62 metadata.Print();
63
64 const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
65 if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
66 return ResultStatus::ErrorUnsupportedArch;
67 }
68 57
69 VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; 58 const auto load_result = directory_loader->Load(process);
70 for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", 59 if (load_result != ResultStatus::Success)
71 "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { 60 return load_result;
72 const VAddr load_addr = next_load_addr;
73
74 next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr);
75 if (next_load_addr) {
76 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
77 // Register module with GDBStub
78 GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
79 } else {
80 next_load_addr = load_addr;
81 }
82 }
83
84 process->program_id = metadata.GetTitleID();
85 process->svc_access_mask.set();
86 process->address_mappings = default_address_mappings;
87 process->resource_limit =
88 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
89 process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
90 metadata.GetMainThreadStackSize());
91 61
92 if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) 62 if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0)
93 Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); 63 Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this));
@@ -98,12 +68,21 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
98} 68}
99 69
100ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { 70ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
101 if (nca == nullptr || nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) 71 if (nca == nullptr)
72 return ResultStatus::ErrorNotLoaded;
73 if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0)
102 return ResultStatus::ErrorNotUsed; 74 return ResultStatus::ErrorNotUsed;
103 dir = nca->GetRomFS(); 75 dir = nca->GetRomFS();
104 return ResultStatus::Success; 76 return ResultStatus::Success;
105} 77}
106 78
79ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
80 if (nca == nullptr)
81 return ResultStatus::ErrorNotLoaded;
82 out_program_id = nca->GetTitleId();
83 return ResultStatus::Success;
84}
85
107AppLoader_NCA::~AppLoader_NCA() = default; 86AppLoader_NCA::~AppLoader_NCA() = default;
108 87
109} // namespace Loader 88} // 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 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/file_sys/content_archive.h" 9#include "core/file_sys/content_archive.h"
10#include "core/file_sys/program_metadata.h" 10#include "core/file_sys/program_metadata.h"
11#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
12#include "core/loader/loader.h" 12#include "core/loader/loader.h"
13#include "deconstructed_rom_directory.h"
13 14
14namespace Loader { 15namespace Loader {
15 16
@@ -33,12 +34,15 @@ public:
33 34
34 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; 35 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
35 36
37 ResultStatus ReadProgramId(u64& out_program_id) override;
38
36 ~AppLoader_NCA(); 39 ~AppLoader_NCA();
37 40
38private: 41private:
39 FileSys::ProgramMetadata metadata; 42 FileSys::ProgramMetadata metadata;
40 43
41 std::unique_ptr<FileSys::NCA> nca; 44 std::unique_ptr<FileSys::NCA> nca;
45 std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
42}; 46};
43 47
44} // namespace Loader 48} // 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) {
159 // Resize program image to include .bss section and page align each section 159 // Resize program image to include .bss section and page align each section
160 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); 160 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
161 } 161 }
162 codeset->data.size += bss_size; 162 codeset->DataSegment().size += bss_size;
163 program_image.resize(static_cast<u32>(program_image.size()) + bss_size); 163 program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
164 164
165 // Load codeset for current process 165 // 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 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/loader/linker.h" 10#include "core/loader/linker.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
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) {
127 // Resize program image to include .bss section and page align each section 127 // Resize program image to include .bss section and page align each section
128 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); 128 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
129 } 129 }
130 codeset->data.size += bss_size; 130 codeset->DataSegment().size += bss_size;
131 const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; 131 const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
132 program_image.resize(image_size); 132 program_image.resize(image_size);
133 133
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 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/loader/linker.h" 10#include "core/loader/linker.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <vector>
6
7#include "common/file_util.h"
8#include "common/logging/log.h"
9#include "common/string_util.h"
10#include "common/swap.h"
11#include "core/core.h"
12#include "core/file_sys/content_archive.h"
13#include "core/file_sys/control_metadata.h"
14#include "core/file_sys/program_metadata.h"
15#include "core/file_sys/romfs.h"
16#include "core/gdbstub/gdbstub.h"
17#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/resource_limit.h"
19#include "core/hle/service/filesystem/filesystem.h"
20#include "core/loader/nso.h"
21#include "core/loader/xci.h"
22#include "core/memory.h"
23
24namespace Loader {
25
26AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
27 : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
28 nca_loader(std::make_unique<AppLoader_NCA>(
29 xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {}
30
31AppLoader_XCI::~AppLoader_XCI() = default;
32
33FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) {
34 FileSys::XCI xci(file);
35
36 if (xci.GetStatus() == ResultStatus::Success &&
37 xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr &&
38 AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) ==
39 FileType::NCA) {
40 return FileType::XCI;
41 }
42
43 return FileType::Error;
44}
45
46ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
47 if (is_loaded) {
48 return ResultStatus::ErrorAlreadyLoaded;
49 }
50
51 if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) {
52 if (!Core::Crypto::KeyManager::KeyFileExists(false))
53 return ResultStatus::ErrorMissingKeys;
54 return ResultStatus::ErrorDecrypting;
55 }
56
57 auto result = nca_loader->Load(process);
58 if (result != ResultStatus::Success)
59 return result;
60
61 is_loaded = true;
62
63 return ResultStatus::Success;
64}
65
66ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) {
67 return nca_loader->ReadRomFS(dir);
68}
69
70ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
71 return nca_loader->ReadProgramId(out_program_id);
72}
73
74} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "common/common_types.h"
9#include "core/file_sys/card_image.h"
10#include "core/loader/loader.h"
11#include "core/loader/nca.h"
12
13namespace Loader {
14
15/// Loads an XCI file
16class AppLoader_XCI final : public AppLoader {
17public:
18 explicit AppLoader_XCI(FileSys::VirtualFile file);
19 ~AppLoader_XCI();
20
21 /**
22 * Returns the type of the file
23 * @param file std::shared_ptr<VfsFile> open file
24 * @return FileType found, or FileType::Error if this loader doesn't know it
25 */
26 static FileType IdentifyType(const FileSys::VirtualFile& file);
27
28 FileType GetFileType() override {
29 return IdentifyType(file);
30 }
31
32 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
33
34 ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
35 ResultStatus ReadProgramId(u64& out_program_id) override;
36
37private:
38 FileSys::ProgramMetadata metadata;
39
40 std::unique_ptr<FileSys::XCI> xci;
41 std::unique_ptr<AppLoader_NCA> nca_loader;
42};
43
44} // 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 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/hle/kernel/memory.h"
18#include "core/hle/kernel/process.h" 17#include "core/hle/kernel/process.h"
19#include "core/hle/lock.h" 18#include "core/hle/lock.h"
20#include "core/memory.h" 19#include "core/memory.h"
@@ -24,8 +23,6 @@
24 23
25namespace Memory { 24namespace Memory {
26 25
27static std::array<u8, Memory::VRAM_SIZE> vram;
28
29static PageTable* current_page_table = nullptr; 26static PageTable* current_page_table = nullptr;
30 27
31void SetCurrentPageTable(PageTable* page_table) { 28void SetCurrentPageTable(PageTable* page_table) {
@@ -102,22 +99,6 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
102} 99}
103 100
104/** 101/**
105 * This function should only be called for virtual addreses with attribute `PageType::Special`.
106 */
107static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_table, VAddr vaddr,
108 u64 size) {
109 std::set<MemoryHookPointer> result;
110 auto interval = boost::icl::discrete_interval<VAddr>::closed(vaddr, vaddr + size - 1);
111 auto interval_list = page_table.special_regions.equal_range(interval);
112 for (auto it = interval_list.first; it != interval_list.second; ++it) {
113 for (const auto& region : it->second) {
114 result.insert(region.handler);
115 }
116 }
117 return result;
118}
119
120/**
121 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) 102 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
122 * using a VMA from the current process 103 * using a VMA from the current process
123 */ 104 */
@@ -242,10 +223,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
242 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; 223 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
243} 224}
244 225
245bool IsValidPhysicalAddress(const PAddr paddr) {
246 return GetPhysicalPointer(paddr) != nullptr;
247}
248
249u8* GetPointer(const VAddr vaddr) { 226u8* GetPointer(const VAddr vaddr) {
250 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 227 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
251 if (page_pointer) { 228 if (page_pointer) {
@@ -274,61 +251,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) {
274 return string; 251 return string;
275} 252}
276 253
277u8* GetPhysicalPointer(PAddr address) {
278 struct MemoryArea {
279 PAddr paddr_base;
280 u32 size;
281 };
282
283 static constexpr MemoryArea memory_areas[] = {
284 {VRAM_PADDR, VRAM_SIZE},
285 {IO_AREA_PADDR, IO_AREA_SIZE},
286 {DSP_RAM_PADDR, DSP_RAM_SIZE},
287 {FCRAM_PADDR, FCRAM_N3DS_SIZE},
288 };
289
290 const auto area =
291 std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) {
292 return address >= area.paddr_base && address < area.paddr_base + area.size;
293 });
294
295 if (area == std::end(memory_areas)) {
296 LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
297 return nullptr;
298 }
299
300 if (area->paddr_base == IO_AREA_PADDR) {
301 LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
302 return nullptr;
303 }
304
305 u64 offset_into_region = address - area->paddr_base;
306
307 u8* target_pointer = nullptr;
308 switch (area->paddr_base) {
309 case VRAM_PADDR:
310 target_pointer = vram.data() + offset_into_region;
311 break;
312 case DSP_RAM_PADDR:
313 break;
314 case FCRAM_PADDR:
315 for (const auto& region : Kernel::memory_regions) {
316 if (offset_into_region >= region.base &&
317 offset_into_region < region.base + region.size) {
318 target_pointer =
319 region.linear_heap_memory->data() + offset_into_region - region.base;
320 break;
321 }
322 }
323 ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
324 break;
325 default:
326 UNREACHABLE();
327 }
328
329 return target_pointer;
330}
331
332void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { 254void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
333 if (gpu_addr == 0) { 255 if (gpu_addr == 0) {
334 return; 256 return;
@@ -404,43 +326,45 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached)
404} 326}
405 327
406void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { 328void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
329 auto& system_instance = Core::System::GetInstance();
330
407 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be 331 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
408 // null here 332 // null here
409 if (VideoCore::g_renderer == nullptr) { 333 if (!system_instance.IsPoweredOn()) {
410 return; 334 return;
411 } 335 }
412 336
413 VAddr end = start + size; 337 VAddr end = start + size;
414 338
415 auto CheckRegion = [&](VAddr region_start, VAddr region_end) { 339 const auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
416 if (start >= region_end || end <= region_start) { 340 if (start >= region_end || end <= region_start) {
417 // No overlap with region 341 // No overlap with region
418 return; 342 return;
419 } 343 }
420 344
421 VAddr overlap_start = std::max(start, region_start); 345 const VAddr overlap_start = std::max(start, region_start);
422 VAddr overlap_end = std::min(end, region_end); 346 const VAddr overlap_end = std::min(end, region_end);
423 347
424 std::vector<Tegra::GPUVAddr> gpu_addresses = 348 const std::vector<Tegra::GPUVAddr> gpu_addresses =
425 Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); 349 system_instance.GPU().memory_manager->CpuToGpuAddress(overlap_start);
426 350
427 if (gpu_addresses.empty()) { 351 if (gpu_addresses.empty()) {
428 return; 352 return;
429 } 353 }
430 354
431 u64 overlap_size = overlap_end - overlap_start; 355 const u64 overlap_size = overlap_end - overlap_start;
432 356
433 for (const auto& gpu_address : gpu_addresses) { 357 for (const auto& gpu_address : gpu_addresses) {
434 auto* rasterizer = VideoCore::g_renderer->Rasterizer(); 358 auto& rasterizer = system_instance.Renderer().Rasterizer();
435 switch (mode) { 359 switch (mode) {
436 case FlushMode::Flush: 360 case FlushMode::Flush:
437 rasterizer->FlushRegion(gpu_address, overlap_size); 361 rasterizer.FlushRegion(gpu_address, overlap_size);
438 break; 362 break;
439 case FlushMode::Invalidate: 363 case FlushMode::Invalidate:
440 rasterizer->InvalidateRegion(gpu_address, overlap_size); 364 rasterizer.InvalidateRegion(gpu_address, overlap_size);
441 break; 365 break;
442 case FlushMode::FlushAndInvalidate: 366 case FlushMode::FlushAndInvalidate:
443 rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size); 367 rasterizer.FlushAndInvalidateRegion(gpu_address, overlap_size);
444 break; 368 break;
445 } 369 }
446 } 370 }
@@ -666,48 +590,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
666 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); 590 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
667} 591}
668 592
669boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
670 if (addr == 0) {
671 return 0;
672 } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) {
673 return addr - VRAM_VADDR + VRAM_PADDR;
674 } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) {
675 return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR;
676 } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) {
677 return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR;
678 } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) {
679 return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
680 } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
681 return addr - IO_AREA_VADDR + IO_AREA_PADDR;
682 }
683
684 return boost::none;
685}
686
687PAddr VirtualToPhysicalAddress(const VAddr addr) {
688 auto paddr = TryVirtualToPhysicalAddress(addr);
689 if (!paddr) {
690 LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
691 // To help with debugging, set bit on address so that it's obviously invalid.
692 return addr | 0x80000000;
693 }
694 return *paddr;
695}
696
697boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
698 if (addr == 0) {
699 return 0;
700 } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
701 return addr - VRAM_PADDR + VRAM_VADDR;
702 } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
703 return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
704 } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
705 return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
706 } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
707 return addr - IO_AREA_PADDR + IO_AREA_VADDR;
708 }
709
710 return boost::none;
711}
712
713} // namespace Memory 593} // 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 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <map>
10#include <string> 9#include <string>
11#include <tuple> 10#include <tuple>
12#include <vector>
13#include <boost/icl/interval_map.hpp> 11#include <boost/icl/interval_map.hpp>
14#include <boost/optional.hpp>
15#include "common/common_types.h" 12#include "common/common_types.h"
16#include "core/memory_hook.h" 13#include "core/memory_hook.h"
17#include "video_core/memory_manager.h" 14#include "video_core/memory_manager.h"
@@ -85,40 +82,6 @@ struct PageTable {
85 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; 82 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
86}; 83};
87 84
88/// Physical memory regions as seen from the ARM11
89enum : PAddr {
90 /// IO register area
91 IO_AREA_PADDR = 0x10100000,
92 IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB)
93 IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE,
94
95 /// MPCore internal memory region
96 MPCORE_RAM_PADDR = 0x17E00000,
97 MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB)
98 MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE,
99
100 /// Video memory
101 VRAM_PADDR = 0x18000000,
102 VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
103 VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
104
105 /// DSP memory
106 DSP_RAM_PADDR = 0x1FF00000,
107 DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
108 DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE,
109
110 /// AXI WRAM
111 AXI_WRAM_PADDR = 0x1FF80000,
112 AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB)
113 AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE,
114
115 /// Main FCRAM
116 FCRAM_PADDR = 0x20000000,
117 FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
118 FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
119 FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
120};
121
122/// Virtual user-space memory regions 85/// Virtual user-space memory regions
123enum : VAddr { 86enum : VAddr {
124 /// Where the application text, data and bss reside. 87 /// Where the application text, data and bss reside.
@@ -126,24 +89,6 @@ enum : VAddr {
126 PROCESS_IMAGE_MAX_SIZE = 0x08000000, 89 PROCESS_IMAGE_MAX_SIZE = 0x08000000,
127 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, 90 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
128 91
129 /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
130 /// memory.
131 LINEAR_HEAP_VADDR = 0x14000000,
132 LINEAR_HEAP_SIZE = 0x08000000,
133 LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
134
135 /// Maps 1:1 to the IO register area.
136 IO_AREA_VADDR = 0x1EC00000,
137 IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
138
139 /// Maps 1:1 to VRAM.
140 VRAM_VADDR = 0x1F000000,
141 VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE,
142
143 /// Maps 1:1 to DSP memory.
144 DSP_RAM_VADDR = 0x1FF00000,
145 DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE,
146
147 /// Read-only page containing kernel and system configuration values. 92 /// Read-only page containing kernel and system configuration values.
148 CONFIG_MEMORY_VADDR = 0x1FF80000, 93 CONFIG_MEMORY_VADDR = 0x1FF80000,
149 CONFIG_MEMORY_SIZE = 0x00001000, 94 CONFIG_MEMORY_SIZE = 0x00001000,
@@ -154,13 +99,8 @@ enum : VAddr {
154 SHARED_PAGE_SIZE = 0x00001000, 99 SHARED_PAGE_SIZE = 0x00001000,
155 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, 100 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
156 101
157 /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
158 NEW_LINEAR_HEAP_VADDR = 0x30000000,
159 NEW_LINEAR_HEAP_SIZE = 0x10000000,
160 NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
161
162 /// Area where TLS (Thread-Local Storage) buffers are allocated. 102 /// Area where TLS (Thread-Local Storage) buffers are allocated.
163 TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END, 103 TLS_AREA_VADDR = 0x40000000,
164 TLS_ENTRY_SIZE = 0x200, 104 TLS_ENTRY_SIZE = 0x200,
165 TLS_AREA_SIZE = 0x10000000, 105 TLS_AREA_SIZE = 0x10000000,
166 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, 106 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
@@ -200,12 +140,10 @@ void SetCurrentPageTable(PageTable* page_table);
200PageTable* GetCurrentPageTable(); 140PageTable* GetCurrentPageTable();
201 141
202/// Determines if the given VAddr is valid for the specified process. 142/// Determines if the given VAddr is valid for the specified process.
203bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); 143bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr);
204bool IsValidVirtualAddress(const VAddr addr); 144bool IsValidVirtualAddress(VAddr vaddr);
205/// Determines if the given VAddr is a kernel address 145/// Determines if the given VAddr is a kernel address
206bool IsKernelVirtualAddress(const VAddr addr); 146bool IsKernelVirtualAddress(VAddr vaddr);
207
208bool IsValidPhysicalAddress(const PAddr addr);
209 147
210u8 Read8(VAddr addr); 148u8 Read8(VAddr addr);
211u16 Read16(VAddr addr); 149u16 Read16(VAddr addr);
@@ -217,42 +155,17 @@ void Write16(VAddr addr, u16 data);
217void Write32(VAddr addr, u32 data); 155void Write32(VAddr addr, u32 data);
218void Write64(VAddr addr, u64 data); 156void Write64(VAddr addr, u64 data);
219 157
220void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, 158void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, size_t size);
221 size_t size); 159void ReadBlock(VAddr src_addr, void* dest_buffer, size_t size);
222void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); 160void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
223void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
224 size_t size); 161 size_t size);
225void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); 162void WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size);
226void ZeroBlock(const VAddr dest_addr, const size_t size); 163void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, size_t size);
227void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); 164void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size);
228 165
229u8* GetPointer(VAddr virtual_address); 166u8* GetPointer(VAddr vaddr);
230
231std::string ReadCString(VAddr virtual_address, std::size_t max_length);
232
233/**
234 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
235 * address. This should be used by services to translate addresses for use by the hardware.
236 */
237boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr);
238
239/**
240 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
241 * address. This should be used by services to translate addresses for use by the hardware.
242 *
243 * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure.
244 */
245PAddr VirtualToPhysicalAddress(VAddr addr);
246 167
247/** 168std::string ReadCString(VAddr vaddr, std::size_t max_length);
248 * Undoes a mapping performed by VirtualToPhysicalAddress().
249 */
250boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
251
252/**
253 * Gets a pointer to the memory region beginning at the specified physical address.
254 */
255u8* GetPhysicalPointer(PAddr address);
256 169
257enum class FlushMode { 170enum class FlushMode {
258 /// Write back modified surfaces to RAM 171 /// Write back modified surfaces to RAM
@@ -266,7 +179,7 @@ enum class FlushMode {
266/** 179/**
267 * Mark each page touching the region as cached. 180 * Mark each page touching the region as cached.
268 */ 181 */
269void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); 182void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached);
270 183
271/** 184/**
272 * Flushes and invalidates any externally cached rasterizer resources touching the given virtual 185 * 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() {
40 game_frames += 1; 40 game_frames += 1;
41} 41}
42 42
43PerfStats::Results PerfStats::GetAndResetStats(u64 current_system_time_us) { 43PerfStats::Results PerfStats::GetAndResetStats(microseconds current_system_time_us) {
44 std::lock_guard<std::mutex> lock(object_mutex); 44 std::lock_guard<std::mutex> lock(object_mutex);
45 45
46 auto now = Clock::now(); 46 const auto now = Clock::now();
47 // Walltime elapsed since stats were reset 47 // Walltime elapsed since stats were reset
48 auto interval = duration_cast<DoubleSecs>(now - reset_point).count(); 48 const auto interval = duration_cast<DoubleSecs>(now - reset_point).count();
49 49
50 auto system_us_per_second = 50 const auto system_us_per_second = (current_system_time_us - reset_point_system_us) / interval;
51 static_cast<double>(current_system_time_us - reset_point_system_us) / interval;
52 51
53 Results results{}; 52 Results results{};
54 results.system_fps = static_cast<double>(system_frames) / interval; 53 results.system_fps = static_cast<double>(system_frames) / interval;
55 results.game_fps = static_cast<double>(game_frames) / interval; 54 results.game_fps = static_cast<double>(game_frames) / interval;
56 results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() / 55 results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() /
57 static_cast<double>(system_frames); 56 static_cast<double>(system_frames);
58 results.emulation_speed = system_us_per_second / 1'000'000.0; 57 results.emulation_speed = system_us_per_second.count() / 1'000'000.0;
59 58
60 // Reset counters 59 // Reset counters
61 reset_point = now; 60 reset_point = now;
@@ -74,10 +73,10 @@ double PerfStats::GetLastFrameTimeScale() {
74 return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; 73 return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH;
75} 74}
76 75
77void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) { 76void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) {
78 // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher 77 // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher
79 // values increase the time needed to recover and limit framerate again after spikes. 78 // values increase the time needed to recover and limit framerate again after spikes.
80 constexpr microseconds MAX_LAG_TIME_US = 25ms; 79 constexpr microseconds MAX_LAG_TIME_US = 25us;
81 80
82 if (!Settings::values.toggle_framelimit) { 81 if (!Settings::values.toggle_framelimit) {
83 return; 82 return;
@@ -85,7 +84,7 @@ void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) {
85 84
86 auto now = Clock::now(); 85 auto now = Clock::now();
87 86
88 frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us); 87 frame_limiting_delta_err += current_system_time_us - previous_system_time_us;
89 frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime); 88 frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime);
90 frame_limiting_delta_err = 89 frame_limiting_delta_err =
91 std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US); 90 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:
33 void EndSystemFrame(); 33 void EndSystemFrame();
34 void EndGameFrame(); 34 void EndGameFrame();
35 35
36 Results GetAndResetStats(u64 current_system_time_us); 36 Results GetAndResetStats(std::chrono::microseconds current_system_time_us);
37 37
38 /** 38 /**
39 * Gets the ratio between walltime and the emulated time of the previous system frame. This is 39 * Gets the ratio between walltime and the emulated time of the previous system frame. This is
@@ -47,7 +47,7 @@ private:
47 /// Point when the cumulative counters were reset 47 /// Point when the cumulative counters were reset
48 Clock::time_point reset_point = Clock::now(); 48 Clock::time_point reset_point = Clock::now();
49 /// System time when the cumulative counters were reset 49 /// System time when the cumulative counters were reset
50 u64 reset_point_system_us = 0; 50 std::chrono::microseconds reset_point_system_us{0};
51 51
52 /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset 52 /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset
53 Clock::duration accumulated_frametime = Clock::duration::zero(); 53 Clock::duration accumulated_frametime = Clock::duration::zero();
@@ -68,11 +68,11 @@ class FrameLimiter {
68public: 68public:
69 using Clock = std::chrono::high_resolution_clock; 69 using Clock = std::chrono::high_resolution_clock;
70 70
71 void DoFrameLimiting(u64 current_system_time_us); 71 void DoFrameLimiting(std::chrono::microseconds current_system_time_us);
72 72
73private: 73private:
74 /// Emulated system time (in microseconds) at the last limiter invocation 74 /// Emulated system time (in microseconds) at the last limiter invocation
75 u64 previous_system_time_us = 0; 75 std::chrono::microseconds previous_system_time_us{0};
76 /// Walltime at the last limiter invocation 76 /// Walltime at the last limiter invocation
77 Clock::time_point previous_walltime = Clock::now(); 77 Clock::time_point previous_walltime = Clock::now();
78 78
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h"
5#include "core/gdbstub/gdbstub.h" 6#include "core/gdbstub/gdbstub.h"
6#include "core/hle/service/hid/hid.h" 7#include "core/hle/service/hid/hid.h"
7#include "core/settings.h" 8#include "core/settings.h"
9#include "video_core/renderer_base.h"
8#include "video_core/video_core.h" 10#include "video_core/video_core.h"
9 11
10#include "core/frontend/emu_window.h"
11
12namespace Settings { 12namespace Settings {
13 13
14Values values = {}; 14Values values = {};
@@ -20,9 +20,9 @@ void Apply() {
20 20
21 VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; 21 VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit;
22 22
23 if (VideoCore::g_emu_window) { 23 auto& system_instance = Core::System::GetInstance();
24 auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); 24 if (system_instance.IsPoweredOn()) {
25 VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height); 25 system_instance.Renderer().UpdateCurrentFramebufferLayout();
26 } 26 }
27 27
28 Service::HID::ReloadInputDevices(); 28 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 = {{
112struct Values { 112struct Values {
113 // System 113 // System
114 bool use_docked_mode; 114 bool use_docked_mode;
115 std::string username;
116 int language_index;
115 117
116 // Controls 118 // Controls
117 std::array<std::string, NativeButton::NumButtons> buttons; 119 std::array<std::string, NativeButton::NumButtons> buttons;
@@ -137,6 +139,13 @@ struct Values {
137 139
138 std::string log_filter; 140 std::string log_filter;
139 141
142 bool use_dev_keys;
143
144 // Audio
145 std::string sink_id;
146 std::string audio_device_id;
147 float volume;
148
140 // Debugging 149 // Debugging
141 bool use_gdbstub; 150 bool use_gdbstub;
142 u16 gdbstub_port; 151 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 @@
5#include <atomic> 5#include <atomic>
6#include <list> 6#include <list>
7#include <mutex> 7#include <mutex>
8#include <utility>
8#include "input_common/keyboard.h" 9#include "input_common/keyboard.h"
9 10
10namespace InputCommon { 11namespace InputCommon {
@@ -12,9 +13,9 @@ namespace InputCommon {
12class KeyButton final : public Input::ButtonDevice { 13class KeyButton final : public Input::ButtonDevice {
13public: 14public:
14 explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) 15 explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
15 : key_button_list(key_button_list_) {} 16 : key_button_list(std::move(key_button_list_)) {}
16 17
17 ~KeyButton(); 18 ~KeyButton() override;
18 19
19 bool GetStatus() const override { 20 bool GetStatus() const override {
20 return status.load(); 21 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:
131 device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); 131 device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
132 } 132 }
133 133
134 std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const { 134 std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override {
135 return device->GetStatus(); 135 return device->GetStatus();
136 } 136 }
137 137
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:
82class SDLButton final : public Input::ButtonDevice { 82class SDLButton final : public Input::ButtonDevice {
83public: 83public:
84 explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) 84 explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_)
85 : joystick(joystick_), button(button_) {} 85 : joystick(std::move(joystick_)), button(button_) {}
86 86
87 bool GetStatus() const override { 87 bool GetStatus() const override {
88 return joystick->GetButton(button); 88 return joystick->GetButton(button);
@@ -96,7 +96,7 @@ private:
96class SDLDirectionButton final : public Input::ButtonDevice { 96class SDLDirectionButton final : public Input::ButtonDevice {
97public: 97public:
98 explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_) 98 explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_)
99 : joystick(joystick_), hat(hat_), direction(direction_) {} 99 : joystick(std::move(joystick_)), hat(hat_), direction(direction_) {}
100 100
101 bool GetStatus() const override { 101 bool GetStatus() const override {
102 return joystick->GetHatDirection(hat, direction); 102 return joystick->GetHatDirection(hat, direction);
@@ -112,7 +112,7 @@ class SDLAxisButton final : public Input::ButtonDevice {
112public: 112public:
113 explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_, 113 explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_,
114 bool trigger_if_greater_) 114 bool trigger_if_greater_)
115 : joystick(joystick_), axis(axis_), threshold(threshold_), 115 : joystick(std::move(joystick_)), axis(axis_), threshold(threshold_),
116 trigger_if_greater(trigger_if_greater_) {} 116 trigger_if_greater(trigger_if_greater_) {}
117 117
118 bool GetStatus() const override { 118 bool GetStatus() const override {
@@ -132,7 +132,7 @@ private:
132class SDLAnalog final : public Input::AnalogDevice { 132class SDLAnalog final : public Input::AnalogDevice {
133public: 133public:
134 SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_) 134 SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_)
135 : joystick(joystick_), axis_x(axis_x_), axis_y(axis_y_) {} 135 : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_) {}
136 136
137 std::tuple<float, float> GetStatus() const override { 137 std::tuple<float, float> GetStatus() const override {
138 return joystick->GetAnalog(axis_x, axis_y); 138 return joystick->GetAnalog(axis_x, axis_y);
@@ -314,10 +314,6 @@ namespace Polling {
314 314
315class SDLPoller : public InputCommon::Polling::DevicePoller { 315class SDLPoller : public InputCommon::Polling::DevicePoller {
316public: 316public:
317 SDLPoller() = default;
318
319 ~SDLPoller() = default;
320
321 void Start() override { 317 void Start() override {
322 // SDL joysticks must be opened, otherwise they don't generate events 318 // SDL joysticks must be opened, otherwise they don't generate events
323 SDL_JoystickUpdate(); 319 SDL_JoystickUpdate();
@@ -341,10 +337,6 @@ private:
341 337
342class SDLButtonPoller final : public SDLPoller { 338class SDLButtonPoller final : public SDLPoller {
343public: 339public:
344 SDLButtonPoller() = default;
345
346 ~SDLButtonPoller() = default;
347
348 Common::ParamPackage GetNextInput() override { 340 Common::ParamPackage GetNextInput() override {
349 SDL_Event event; 341 SDL_Event event;
350 while (SDL_PollEvent(&event)) { 342 while (SDL_PollEvent(&event)) {
@@ -364,10 +356,6 @@ public:
364 356
365class SDLAnalogPoller final : public SDLPoller { 357class SDLAnalogPoller final : public SDLPoller {
366public: 358public:
367 SDLAnalogPoller() = default;
368
369 ~SDLAnalogPoller() = default;
370
371 void Start() override { 359 void Start() override {
372 SDLPoller::Start(); 360 SDLPoller::Start();
373 361
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
3 core/arm/arm_test_common.cpp 3 core/arm/arm_test_common.cpp
4 core/arm/arm_test_common.h 4 core/arm/arm_test_common.h
5 core/core_timing.cpp 5 core/core_timing.cpp
6 core/memory/memory.cpp
7 glad.cpp 6 glad.cpp
8 tests.cpp 7 tests.cpp
9) 8)
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 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <catch.hpp>
6#include "core/hle/kernel/memory.h"
7#include "core/hle/kernel/process.h"
8#include "core/memory.h"
9
10TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
11 SECTION("these regions should not be mapped on an empty process") {
12 auto process = Kernel::Process::Create("");
13 CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
14 CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
15 CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
16 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
17 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
18 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
19 CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
20 }
21
22 SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
23 auto process = Kernel::Process::Create("");
24 Kernel::MapSharedPages(process->vm_manager);
25 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
26 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
27 }
28
29 SECTION("special regions should be valid after mapping them") {
30 auto process = Kernel::Process::Create("");
31 SECTION("VRAM") {
32 Kernel::HandleSpecialMapping(process->vm_manager,
33 {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
34 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
35 }
36
37 SECTION("IO (Not yet implemented)") {
38 Kernel::HandleSpecialMapping(
39 process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
40 CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
41 }
42
43 SECTION("DSP") {
44 Kernel::HandleSpecialMapping(
45 process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
46 CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
47 }
48 }
49
50 SECTION("Unmapping a VAddr should make it invalid") {
51 auto process = Kernel::Process::Create("");
52 Kernel::MapSharedPages(process->vm_manager);
53 process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
54 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
55 }
56}
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 {
19/// First register id that is actually a Macro call. 19/// First register id that is actually a Macro call.
20constexpr u32 MacroRegistersStart = 0xE00; 20constexpr u32 MacroRegistersStart = 0xE00;
21 21
22Maxwell3D::Maxwell3D(MemoryManager& memory_manager) 22Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
23 : memory_manager(memory_manager), macro_interpreter(*this) {} 23 : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {}
24 24
25void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { 25void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
26 auto macro_code = uploaded_macros.find(method); 26 auto macro_code = uploaded_macros.find(method);
@@ -130,7 +130,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
130 break; 130 break;
131 } 131 }
132 132
133 VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method); 133 rasterizer.NotifyMaxwellRegisterChanged(method);
134 134
135 if (debug_context) { 135 if (debug_context) {
136 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); 136 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr);
@@ -218,7 +218,7 @@ void Maxwell3D::DrawArrays() {
218 } 218 }
219 219
220 const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; 220 const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count};
221 VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed); 221 rasterizer.AccelerateDrawBatch(is_indexed);
222 222
223 // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if 223 // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if
224 // the game is trying to draw indexed or direct mode. This needs to be verified on HW still - 224 // 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 {
285 285
286 // TODO(Subv): Different data types for separate components are not supported 286 // TODO(Subv): Different data types for separate components are not supported
287 ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); 287 ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
288 // TODO(Subv): Only UNORM formats are supported for now.
289 ASSERT(r_type == Texture::ComponentType::UNORM);
290 288
291 return tic_entry; 289 return tic_entry;
292} 290}
@@ -393,7 +391,7 @@ void Maxwell3D::ProcessClearBuffers() {
393 regs.clear_buffers.R == regs.clear_buffers.B && 391 regs.clear_buffers.R == regs.clear_buffers.B &&
394 regs.clear_buffers.R == regs.clear_buffers.A); 392 regs.clear_buffers.R == regs.clear_buffers.A);
395 393
396 VideoCore::g_renderer->Rasterizer()->Clear(); 394 rasterizer.Clear();
397} 395}
398 396
399} // namespace Engines 397} // 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 @@
17#include "video_core/memory_manager.h" 17#include "video_core/memory_manager.h"
18#include "video_core/textures/texture.h" 18#include "video_core/textures/texture.h"
19 19
20namespace VideoCore {
21class RasterizerInterface;
22}
23
20namespace Tegra::Engines { 24namespace Tegra::Engines {
21 25
22#define MAXWELL3D_REG_INDEX(field_name) \ 26#define MAXWELL3D_REG_INDEX(field_name) \
@@ -24,7 +28,7 @@ namespace Tegra::Engines {
24 28
25class Maxwell3D final { 29class Maxwell3D final {
26public: 30public:
27 explicit Maxwell3D(MemoryManager& memory_manager); 31 explicit Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager);
28 ~Maxwell3D() = default; 32 ~Maxwell3D() = default;
29 33
30 /// Register structure of the Maxwell3D engine. 34 /// Register structure of the Maxwell3D engine.
@@ -818,6 +822,8 @@ public:
818 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; 822 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const;
819 823
820private: 824private:
825 VideoCore::RasterizerInterface& rasterizer;
826
821 std::unordered_map<u32, std::vector<u32>> uploaded_macros; 827 std::unordered_map<u32, std::vector<u32>> uploaded_macros;
822 828
823 /// Macro method that is currently being executed / being fed parameters. 829 /// 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 @@
7#include "video_core/engines/maxwell_compute.h" 7#include "video_core/engines/maxwell_compute.h"
8#include "video_core/engines/maxwell_dma.h" 8#include "video_core/engines/maxwell_dma.h"
9#include "video_core/gpu.h" 9#include "video_core/gpu.h"
10#include "video_core/rasterizer_interface.h"
10 11
11namespace Tegra { 12namespace Tegra {
12 13
13GPU::GPU() { 14GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
14 memory_manager = std::make_unique<MemoryManager>(); 15 memory_manager = std::make_unique<MemoryManager>();
15 maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); 16 maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
16 fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); 17 fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);
17 maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); 18 maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
18 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); 19 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager);
@@ -40,6 +41,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
40 case RenderTargetFormat::RGBA8_UNORM: 41 case RenderTargetFormat::RGBA8_UNORM:
41 case RenderTargetFormat::RGB10_A2_UNORM: 42 case RenderTargetFormat::RGB10_A2_UNORM:
42 case RenderTargetFormat::BGRA8_UNORM: 43 case RenderTargetFormat::BGRA8_UNORM:
44 case RenderTargetFormat::R32_FLOAT:
43 return 4; 45 return 4;
44 default: 46 default:
45 UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); 47 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 @@
11#include "core/hle/service/nvflinger/buffer_queue.h" 11#include "core/hle/service/nvflinger/buffer_queue.h"
12#include "video_core/memory_manager.h" 12#include "video_core/memory_manager.h"
13 13
14namespace VideoCore {
15class RasterizerInterface;
16}
17
14namespace Tegra { 18namespace Tegra {
15 19
16enum class RenderTargetFormat : u32 { 20enum class RenderTargetFormat : u32 {
@@ -29,6 +33,7 @@ enum class RenderTargetFormat : u32 {
29 RG16_UINT = 0xDD, 33 RG16_UINT = 0xDD,
30 RG16_FLOAT = 0xDE, 34 RG16_FLOAT = 0xDE,
31 R11G11B10_FLOAT = 0xE0, 35 R11G11B10_FLOAT = 0xE0,
36 R32_FLOAT = 0xE5,
32 R16_FLOAT = 0xF2, 37 R16_FLOAT = 0xF2,
33 R8_UNORM = 0xF3, 38 R8_UNORM = 0xF3,
34}; 39};
@@ -97,7 +102,7 @@ enum class EngineID {
97 102
98class GPU final { 103class GPU final {
99public: 104public:
100 GPU(); 105 explicit GPU(VideoCore::RasterizerInterface& rasterizer);
101 ~GPU(); 106 ~GPU();
102 107
103 /// Processes a command list stored at the specified address in GPU memory. 108 /// 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) {
102 if (taken) { 102 if (taken) {
103 // Ignore the delay slot if the branch has the annul bit. 103 // Ignore the delay slot if the branch has the annul bit.
104 if (opcode.branch_annul) { 104 if (opcode.branch_annul) {
105 pc = base_address + (opcode.immediate << 2); 105 pc = base_address + opcode.GetBranchTarget();
106 return true; 106 return true;
107 } 107 }
108 108
109 delayed_pc = base_address + (opcode.immediate << 2); 109 delayed_pc = base_address + opcode.GetBranchTarget();
110 // Execute one more instruction due to the delay slot. 110 // Execute one more instruction due to the delay slot.
111 return Step(code, true); 111 return Step(code, true);
112 } 112 }
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:
91 u32 GetBitfieldMask() const { 91 u32 GetBitfieldMask() const {
92 return (1 << bf_size) - 1; 92 return (1 << bf_size) - 1;
93 } 93 }
94
95 s32 GetBranchTarget() const {
96 return static_cast<s32>(immediate * sizeof(u32));
97 }
94 }; 98 };
95 99
96 union MethodAddress { 100 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
6#include <memory> 5#include <memory>
6#include "core/frontend/emu_window.h"
7#include "video_core/renderer_base.h" 7#include "video_core/renderer_base.h"
8#include "video_core/renderer_opengl/gl_rasterizer.h" 8#include "video_core/renderer_opengl/gl_rasterizer.h"
9#include "video_core/video_core.h" 9
10namespace VideoCore {
11
12RendererBase::RendererBase(EmuWindow& window) : render_window{window} {}
13RendererBase::~RendererBase() = default;
14
15void RendererBase::UpdateCurrentFramebufferLayout() {
16 const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
17
18 render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
19}
10 20
11void RendererBase::RefreshRasterizerSetting() { 21void RendererBase::RefreshRasterizerSetting() {
12 if (rasterizer == nullptr) { 22 if (rasterizer == nullptr) {
13 rasterizer = std::make_unique<RasterizerOpenGL>(); 23 rasterizer = std::make_unique<RasterizerOpenGL>(render_window);
14 } 24 }
15} 25}
26
27} // 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 @@
13 13
14class EmuWindow; 14class EmuWindow;
15 15
16namespace VideoCore {
17
16class RendererBase : NonCopyable { 18class RendererBase : NonCopyable {
17public: 19public:
18 /// Used to reference a framebuffer 20 /// Used to reference a framebuffer
19 enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; 21 enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture };
20 22
21 virtual ~RendererBase() {} 23 explicit RendererBase(EmuWindow& window);
24 virtual ~RendererBase();
22 25
23 /// Swap buffers (render frame) 26 /// Swap buffers (render frame)
24 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; 27 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0;
25 28
26 /**
27 * Set the emulator window to use for renderer
28 * @param window EmuWindow handle to emulator window to use for rendering
29 */
30 virtual void SetWindow(EmuWindow* window) = 0;
31
32 /// Initialize the renderer 29 /// Initialize the renderer
33 virtual bool Init() = 0; 30 virtual bool Init() = 0;
34 31
35 /// Shutdown the renderer 32 /// Shutdown the renderer
36 virtual void ShutDown() = 0; 33 virtual void ShutDown() = 0;
37 34
35 /// Updates the framebuffer layout of the contained render window handle.
36 void UpdateCurrentFramebufferLayout();
37
38 // Getter/setter functions: 38 // Getter/setter functions:
39 // ------------------------ 39 // ------------------------
40 40
@@ -46,16 +46,21 @@ public:
46 return m_current_frame; 46 return m_current_frame;
47 } 47 }
48 48
49 VideoCore::RasterizerInterface* Rasterizer() const { 49 RasterizerInterface& Rasterizer() {
50 return rasterizer.get(); 50 return *rasterizer;
51 }
52
53 const RasterizerInterface& Rasterizer() const {
54 return *rasterizer;
51 } 55 }
52 56
53 void RefreshRasterizerSetting(); 57 void RefreshRasterizerSetting();
54 58
55protected: 59protected:
56 std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; 60 EmuWindow& render_window; ///< Reference to the render window handle.
61 std::unique_ptr<RasterizerInterface> rasterizer;
57 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer 62 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
58 int m_current_frame = 0; ///< Current frame, should be set by the renderer 63 int m_current_frame = 0; ///< Current frame, should be set by the renderer
59
60private:
61}; 64};
65
66} // 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 @@
14#include "common/logging/log.h" 14#include "common/logging/log.h"
15#include "common/math_util.h" 15#include "common/math_util.h"
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h"
18#include "core/core.h" 17#include "core/core.h"
19#include "core/frontend/emu_window.h" 18#include "core/frontend/emu_window.h"
20#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
@@ -37,7 +36,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
37MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); 36MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
38MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); 37MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
39 38
40RasterizerOpenGL::RasterizerOpenGL() { 39RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} {
41 // Create sampler objects 40 // Create sampler objects
42 for (size_t i = 0; i < texture_samplers.size(); ++i) { 41 for (size_t i = 0; i < texture_samplers.size(); ++i) {
43 texture_samplers[i].Create(); 42 texture_samplers[i].Create();
@@ -170,8 +169,14 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
170 ASSERT(buffer.IsEnabled()); 169 ASSERT(buffer.IsEnabled());
171 170
172 glEnableVertexAttribArray(index); 171 glEnableVertexAttribArray(index);
173 glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), 172 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
174 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); 173 attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
174 glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
175 attrib.offset);
176 } else {
177 glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
178 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
179 }
175 glVertexAttribBinding(index, attrib.buffer); 180 glVertexAttribBinding(index, attrib.buffer);
176 } 181 }
177 182
@@ -395,7 +400,7 @@ void RasterizerOpenGL::Clear() {
395 if (clear_mask == 0) 400 if (clear_mask == 0)
396 return; 401 return;
397 402
398 ScopeAcquireGLContext acquire_context; 403 ScopeAcquireGLContext acquire_context{emu_window};
399 404
400 auto [dirty_color_surface, dirty_depth_surface] = 405 auto [dirty_color_surface, dirty_depth_surface] =
401 ConfigureFramebuffers(use_color_fb, use_depth_fb); 406 ConfigureFramebuffers(use_color_fb, use_depth_fb);
@@ -425,7 +430,7 @@ void RasterizerOpenGL::DrawArrays() {
425 MICROPROFILE_SCOPE(OpenGL_Drawing); 430 MICROPROFILE_SCOPE(OpenGL_Drawing);
426 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 431 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
427 432
428 ScopeAcquireGLContext acquire_context; 433 ScopeAcquireGLContext acquire_context{emu_window};
429 434
430 auto [dirty_color_surface, dirty_depth_surface] = 435 auto [dirty_color_surface, dirty_depth_surface] =
431 ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0); 436 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 @@
21#include "video_core/renderer_opengl/gl_state.h" 21#include "video_core/renderer_opengl/gl_state.h"
22#include "video_core/renderer_opengl/gl_stream_buffer.h" 22#include "video_core/renderer_opengl/gl_stream_buffer.h"
23 23
24class EmuWindow;
24struct ScreenInfo; 25struct ScreenInfo;
25 26
26class RasterizerOpenGL : public VideoCore::RasterizerInterface { 27class RasterizerOpenGL : public VideoCore::RasterizerInterface {
27public: 28public:
28 RasterizerOpenGL(); 29 explicit RasterizerOpenGL(EmuWindow& renderer);
29 ~RasterizerOpenGL() override; 30 ~RasterizerOpenGL() override;
30 31
31 void DrawArrays() override; 32 void DrawArrays() override;
@@ -144,6 +145,8 @@ private:
144 145
145 RasterizerCacheOpenGL res_cache; 146 RasterizerCacheOpenGL res_cache;
146 147
148 EmuWindow& emu_window;
149
147 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 150 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
148 OGLVertexArray sw_vao; 151 OGLVertexArray sw_vao;
149 OGLVertexArray hw_vao; 152 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 {
46 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); 46 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
47 params.unaligned_height = config.tic.Height(); 47 params.unaligned_height = config.tic.Height();
48 params.size_in_bytes = params.SizeInBytes(); 48 params.size_in_bytes = params.SizeInBytes();
49 params.cache_width = Common::AlignUp(params.width, 16);
50 params.cache_height = Common::AlignUp(params.height, 16);
49 return params; 51 return params;
50} 52}
51 53
@@ -63,6 +65,8 @@ struct FormatTuple {
63 params.height = config.height; 65 params.height = config.height;
64 params.unaligned_height = config.height; 66 params.unaligned_height = config.height;
65 params.size_in_bytes = params.SizeInBytes(); 67 params.size_in_bytes = params.SizeInBytes();
68 params.cache_width = Common::AlignUp(params.width, 16);
69 params.cache_height = Common::AlignUp(params.height, 16);
66 return params; 70 return params;
67} 71}
68 72
@@ -82,6 +86,8 @@ struct FormatTuple {
82 params.height = zeta_height; 86 params.height = zeta_height;
83 params.unaligned_height = zeta_height; 87 params.unaligned_height = zeta_height;
84 params.size_in_bytes = params.SizeInBytes(); 88 params.size_in_bytes = params.SizeInBytes();
89 params.cache_width = Common::AlignUp(params.width, 16);
90 params.cache_height = Common::AlignUp(params.height, 16);
85 return params; 91 return params;
86} 92}
87 93
@@ -118,6 +124,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
118 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI 124 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI
119 {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I 125 {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I
120 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S 126 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S
127 {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F
121 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 128 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8
122 129
123 // DepthStencil formats 130 // DepthStencil formats
@@ -218,9 +225,10 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
218 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, 225 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>,
219 MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, 226 MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>,
220 MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, 227 MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>,
221 MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::Z24S8>, 228 MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>,
222 MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>, 229 MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>,
223 MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>, 230 MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>,
231 MortonCopy<true, PixelFormat::Z32FS8>,
224}; 232};
225 233
226static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), 234static 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),
253 MortonCopy<false, PixelFormat::RG16UI>, 261 MortonCopy<false, PixelFormat::RG16UI>,
254 MortonCopy<false, PixelFormat::RG16I>, 262 MortonCopy<false, PixelFormat::RG16I>,
255 MortonCopy<false, PixelFormat::RG16S>, 263 MortonCopy<false, PixelFormat::RG16S>,
264 MortonCopy<false, PixelFormat::RGB32F>,
256 MortonCopy<false, PixelFormat::SRGBA8>, 265 MortonCopy<false, PixelFormat::SRGBA8>,
257 MortonCopy<false, PixelFormat::Z24S8>, 266 MortonCopy<false, PixelFormat::Z24S8>,
258 MortonCopy<false, PixelFormat::S8Z24>, 267 MortonCopy<false, PixelFormat::S8Z24>,
@@ -677,12 +686,12 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
677 // If use_accurate_framebuffers is enabled, always load from memory 686 // If use_accurate_framebuffers is enabled, always load from memory
678 FlushSurface(surface); 687 FlushSurface(surface);
679 UnregisterSurface(surface); 688 UnregisterSurface(surface);
680 } else if (surface->GetSurfaceParams() != params) { 689 } else if (surface->GetSurfaceParams().IsCompatibleSurface(params)) {
681 // If surface parameters changed, recreate the surface from the old one
682 return RecreateSurface(surface, params);
683 } else {
684 // Use the cached surface as-is 690 // Use the cached surface as-is
685 return surface; 691 return surface;
692 } else {
693 // If surface parameters changed, recreate the surface from the old one
694 return RecreateSurface(surface, params);
686 } 695 }
687 } 696 }
688 697
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 @@
9#include <memory> 9#include <memory>
10#include <vector> 10#include <vector>
11#include <boost/icl/interval_map.hpp> 11#include <boost/icl/interval_map.hpp>
12
12#include "common/common_types.h" 13#include "common/common_types.h"
13#include "common/math_util.h" 14#include "common/math_util.h"
14#include "video_core/engines/maxwell_3d.h" 15#include "video_core/engines/maxwell_3d.h"
@@ -48,16 +49,17 @@ struct SurfaceParams {
48 RG16UI = 23, 49 RG16UI = 23,
49 RG16I = 24, 50 RG16I = 24,
50 RG16S = 25, 51 RG16S = 25,
51 SRGBA8 = 26, 52 RGB32F = 26,
53 SRGBA8 = 27,
52 54
53 MaxColorFormat, 55 MaxColorFormat,
54 56
55 // DepthStencil formats 57 // DepthStencil formats
56 Z24S8 = 27, 58 Z24S8 = 28,
57 S8Z24 = 28, 59 S8Z24 = 29,
58 Z32F = 29, 60 Z32F = 30,
59 Z16 = 30, 61 Z16 = 31,
60 Z32FS8 = 31, 62 Z32FS8 = 32,
61 63
62 MaxDepthStencilFormat, 64 MaxDepthStencilFormat,
63 65
@@ -121,6 +123,7 @@ struct SurfaceParams {
121 1, // RG16UI 123 1, // RG16UI
122 1, // RG16I 124 1, // RG16I
123 1, // RG16S 125 1, // RG16S
126 1, // RGB32F
124 1, // SRGBA8 127 1, // SRGBA8
125 1, // Z24S8 128 1, // Z24S8
126 1, // S8Z24 129 1, // S8Z24
@@ -164,6 +167,7 @@ struct SurfaceParams {
164 32, // RG16UI 167 32, // RG16UI
165 32, // RG16I 168 32, // RG16I
166 32, // RG16S 169 32, // RG16S
170 96, // RGB32F
167 32, // SRGBA8 171 32, // SRGBA8
168 32, // Z24S8 172 32, // Z24S8
169 32, // S8Z24 173 32, // S8Z24
@@ -200,8 +204,9 @@ struct SurfaceParams {
200 204
201 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { 205 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
202 switch (format) { 206 switch (format) {
207 // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
208 // gamma.
203 case Tegra::RenderTargetFormat::RGBA8_SRGB: 209 case Tegra::RenderTargetFormat::RGBA8_SRGB:
204 return PixelFormat::SRGBA8;
205 case Tegra::RenderTargetFormat::RGBA8_UNORM: 210 case Tegra::RenderTargetFormat::RGBA8_UNORM:
206 return PixelFormat::ABGR8; 211 return PixelFormat::ABGR8;
207 case Tegra::RenderTargetFormat::BGRA8_UNORM: 212 case Tegra::RenderTargetFormat::BGRA8_UNORM:
@@ -232,6 +237,8 @@ struct SurfaceParams {
232 return PixelFormat::RG16S; 237 return PixelFormat::RG16S;
233 case Tegra::RenderTargetFormat::R16_FLOAT: 238 case Tegra::RenderTargetFormat::R16_FLOAT:
234 return PixelFormat::R16F; 239 return PixelFormat::R16F;
240 case Tegra::RenderTargetFormat::R32_FLOAT:
241 return PixelFormat::R32F;
235 default: 242 default:
236 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 243 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
237 UNREACHABLE(); 244 UNREACHABLE();
@@ -270,6 +277,8 @@ struct SurfaceParams {
270 UNREACHABLE(); 277 UNREACHABLE();
271 case Tegra::Texture::TextureFormat::R32_G32: 278 case Tegra::Texture::TextureFormat::R32_G32:
272 return PixelFormat::RG32F; 279 return PixelFormat::RG32F;
280 case Tegra::Texture::TextureFormat::R32_G32_B32:
281 return PixelFormat::RGB32F;
273 case Tegra::Texture::TextureFormat::R16: 282 case Tegra::Texture::TextureFormat::R16:
274 switch (component_type) { 283 switch (component_type) {
275 case Tegra::Texture::ComponentType::FLOAT: 284 case Tegra::Texture::ComponentType::FLOAT:
@@ -361,6 +370,8 @@ struct SurfaceParams {
361 return Tegra::Texture::TextureFormat::A8R8G8B8; 370 return Tegra::Texture::TextureFormat::A8R8G8B8;
362 case PixelFormat::RGBA32F: 371 case PixelFormat::RGBA32F:
363 return Tegra::Texture::TextureFormat::R32_G32_B32_A32; 372 return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
373 case PixelFormat::RGB32F:
374 return Tegra::Texture::TextureFormat::R32_G32_B32;
364 case PixelFormat::RG32F: 375 case PixelFormat::RG32F:
365 return Tegra::Texture::TextureFormat::R32_G32; 376 return Tegra::Texture::TextureFormat::R32_G32;
366 case PixelFormat::R32F: 377 case PixelFormat::R32F:
@@ -439,6 +450,7 @@ struct SurfaceParams {
439 case Tegra::RenderTargetFormat::RG32_FLOAT: 450 case Tegra::RenderTargetFormat::RG32_FLOAT:
440 case Tegra::RenderTargetFormat::RG16_FLOAT: 451 case Tegra::RenderTargetFormat::RG16_FLOAT:
441 case Tegra::RenderTargetFormat::R16_FLOAT: 452 case Tegra::RenderTargetFormat::R16_FLOAT:
453 case Tegra::RenderTargetFormat::R32_FLOAT:
442 return ComponentType::Float; 454 return ComponentType::Float;
443 case Tegra::RenderTargetFormat::RGBA32_UINT: 455 case Tegra::RenderTargetFormat::RGBA32_UINT:
444 case Tegra::RenderTargetFormat::RG16_UINT: 456 case Tegra::RenderTargetFormat::RG16_UINT:
@@ -536,6 +548,12 @@ struct SurfaceParams {
536 return !operator==(other); 548 return !operator==(other);
537 } 549 }
538 550
551 /// Checks if surfaces are compatible for caching
552 bool IsCompatibleSurface(const SurfaceParams& other) const {
553 return std::tie(pixel_format, type, cache_width, cache_height) ==
554 std::tie(other.pixel_format, other.type, other.cache_width, other.cache_height);
555 }
556
539 Tegra::GPUVAddr addr; 557 Tegra::GPUVAddr addr;
540 bool is_tiled; 558 bool is_tiled;
541 u32 block_height; 559 u32 block_height;
@@ -546,6 +564,10 @@ struct SurfaceParams {
546 u32 height; 564 u32 height;
547 u32 unaligned_height; 565 u32 unaligned_height;
548 size_t size_in_bytes; 566 size_t size_in_bytes;
567
568 // Parameters used for caching only
569 u32 cache_width;
570 u32 cache_height;
549}; 571};
550 572
551class CachedSurface final { 573class 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:
412 } 412 }
413 declarations.AddNewLine(); 413 declarations.AddNewLine();
414 414
415 unsigned const_buffer_layout = 0;
416 for (const auto& entry : GetConstBuffersDeclarations()) { 415 for (const auto& entry : GetConstBuffersDeclarations()) {
417 declarations.AddLine("layout(std140) uniform " + entry.GetName()); 416 declarations.AddLine("layout(std140) uniform " + entry.GetName());
418 declarations.AddLine('{'); 417 declarations.AddLine('{');
@@ -420,7 +419,6 @@ public:
420 "[MAX_CONSTBUFFER_ELEMENTS];"); 419 "[MAX_CONSTBUFFER_ELEMENTS];");
421 declarations.AddLine("};"); 420 declarations.AddLine("};");
422 declarations.AddNewLine(); 421 declarations.AddNewLine();
423 ++const_buffer_layout;
424 } 422 }
425 declarations.AddNewLine(); 423 declarations.AddNewLine();
426 424
@@ -768,13 +766,16 @@ private:
768 // goes into gpr28+0 and gpr28+1 766 // goes into gpr28+0 and gpr28+1
769 size_t texs_offset{}; 767 size_t texs_offset{};
770 768
769 size_t src_elem{};
771 for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { 770 for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) {
771 size_t dest_elem{};
772 for (unsigned elem = 0; elem < 2; ++elem) { 772 for (unsigned elem = 0; elem < 2; ++elem) {
773 if (!instr.texs.IsComponentEnabled(elem)) { 773 if (!instr.texs.IsComponentEnabled(src_elem++)) {
774 // Skip disabled components 774 // Skip disabled components
775 continue; 775 continue;
776 } 776 }
777 regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); 777 regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false,
778 dest_elem++);
778 } 779 }
779 780
780 if (!instr.texs.HasTwoDestinations()) { 781 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 {
13static void SetShaderUniformBlockBinding(GLuint shader, const char* name, 13static void SetShaderUniformBlockBinding(GLuint shader, const char* name,
14 Maxwell3D::Regs::ShaderStage binding, 14 Maxwell3D::Regs::ShaderStage binding,
15 size_t expected_size) { 15 size_t expected_size) {
16 GLuint ub_index = glGetUniformBlockIndex(shader, name); 16 const GLuint ub_index = glGetUniformBlockIndex(shader, name);
17 if (ub_index != GL_INVALID_INDEX) { 17 if (ub_index == GL_INVALID_INDEX) {
18 GLint ub_size = 0; 18 return;
19 glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
20 ASSERT_MSG(ub_size == expected_size,
21 "Uniform block size did not match! Got {}, expected {}",
22 static_cast<int>(ub_size), expected_size);
23 glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
24 } 19 }
20
21 GLint ub_size = 0;
22 glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
23 ASSERT_MSG(static_cast<size_t>(ub_size) == expected_size,
24 "Uniform block size did not match! Got {}, expected {}", ub_size, expected_size);
25 glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
25} 26}
26 27
27void SetShaderUniformBlockBindings(GLuint shader) { 28void 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:
105 } 105 }
106 106
107 ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config, 107 ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config,
108 const ShaderSetup setup) { 108 const ShaderSetup& setup) {
109 ShaderEntries result; 109 ShaderEntries result;
110 std::tie(current.vs, result) = vertex_shaders.Get(config, setup); 110 std::tie(current.vs, result) = vertex_shaders.Get(config, setup);
111 return result; 111 return result;
112 } 112 }
113 113
114 ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config, 114 ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config,
115 const ShaderSetup setup) { 115 const ShaderSetup& setup) {
116 ShaderEntries result; 116 ShaderEntries result;
117 std::tie(current.fs, result) = fragment_shaders.Get(config, setup); 117 std::tie(current.fs, result) = fragment_shaders.Get(config, setup);
118 return result; 118 return result;
119 } 119 }
120 120
121 GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) { 121 GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) const {
122 switch (stage) { 122 switch (stage) {
123 case Maxwell3D::Regs::ShaderStage::Vertex: 123 case Maxwell3D::Regs::ShaderStage::Vertex:
124 return current.vs; 124 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:
82 GLenum logic_op; // GL_LOGIC_OP_MODE 82 GLenum logic_op; // GL_LOGIC_OP_MODE
83 83
84 // 3 texture units - one for each that is used in PICA fragment shader emulation 84 // 3 texture units - one for each that is used in PICA fragment shader emulation
85 struct { 85 struct TextureUnit {
86 GLuint texture_2d; // GL_TEXTURE_BINDING_2D 86 GLuint texture_2d; // GL_TEXTURE_BINDING_2D
87 GLuint sampler; // GL_SAMPLER_BINDING 87 GLuint sampler; // GL_SAMPLER_BINDING
88 struct { 88 struct {
@@ -104,7 +104,8 @@ public:
104 Unbind(); 104 Unbind();
105 sampler = 0; 105 sampler = 0;
106 } 106 }
107 } texture_units[32]; 107 };
108 std::array<TextureUnit, 32> texture_units;
108 109
109 struct { 110 struct {
110 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING 111 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
92 return matrix; 92 return matrix;
93} 93}
94 94
95ScopeAcquireGLContext::ScopeAcquireGLContext() { 95ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} {
96 if (Settings::values.use_multi_core) { 96 if (Settings::values.use_multi_core) {
97 VideoCore::g_emu_window->MakeCurrent(); 97 emu_window.MakeCurrent();
98 } 98 }
99} 99}
100ScopeAcquireGLContext::~ScopeAcquireGLContext() { 100ScopeAcquireGLContext::~ScopeAcquireGLContext() {
101 if (Settings::values.use_multi_core) { 101 if (Settings::values.use_multi_core) {
102 VideoCore::g_emu_window->DoneCurrent(); 102 emu_window.DoneCurrent();
103 } 103 }
104} 104}
105 105
106RendererOpenGL::RendererOpenGL() = default; 106RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {}
107RendererOpenGL::~RendererOpenGL() = default; 107RendererOpenGL::~RendererOpenGL() = default;
108 108
109/// Swap buffers (render frame) 109/// Swap buffers (render frame)
110void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { 110void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) {
111 ScopeAcquireGLContext acquire_context; 111 ScopeAcquireGLContext acquire_context{render_window};
112 112
113 Core::System::GetInstance().perf_stats.EndSystemFrame(); 113 Core::System::GetInstance().perf_stats.EndSystemFrame();
114 114
@@ -130,10 +130,10 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
130 // Load the framebuffer from memory, draw it to the screen, and swap buffers 130 // Load the framebuffer from memory, draw it to the screen, and swap buffers
131 LoadFBToScreenInfo(*framebuffer, screen_info); 131 LoadFBToScreenInfo(*framebuffer, screen_info);
132 DrawScreen(); 132 DrawScreen();
133 render_window->SwapBuffers(); 133 render_window.SwapBuffers();
134 } 134 }
135 135
136 render_window->PollEvents(); 136 render_window.PollEvents();
137 137
138 Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); 138 Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
139 Core::System::GetInstance().perf_stats.BeginSystemFrame(); 139 Core::System::GetInstance().perf_stats.BeginSystemFrame();
@@ -160,8 +160,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
160 // only allows rows to have a memory alignement of 4. 160 // only allows rows to have a memory alignement of 4.
161 ASSERT(framebuffer.stride % 4 == 0); 161 ASSERT(framebuffer.stride % 4 == 0);
162 162
163 if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, 163 if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride,
164 screen_info)) { 164 screen_info)) {
165 // Reset the screen info's display texture to its own permanent texture 165 // Reset the screen info's display texture to its own permanent texture
166 screen_info.display_texture = screen_info.texture.resource.handle; 166 screen_info.display_texture = screen_info.texture.resource.handle;
167 167
@@ -356,7 +356,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
356 * Draws the emulated screens to the emulator window. 356 * Draws the emulated screens to the emulator window.
357 */ 357 */
358void RendererOpenGL::DrawScreen() { 358void RendererOpenGL::DrawScreen() {
359 const auto& layout = render_window->GetFramebufferLayout(); 359 const auto& layout = render_window.GetFramebufferLayout();
360 const auto& screen = layout.screen; 360 const auto& screen = layout.screen;
361 361
362 glViewport(0, 0, layout.width, layout.height); 362 glViewport(0, 0, layout.width, layout.height);
@@ -380,14 +380,6 @@ void RendererOpenGL::DrawScreen() {
380/// Updates the framerate 380/// Updates the framerate
381void RendererOpenGL::UpdateFramerate() {} 381void RendererOpenGL::UpdateFramerate() {}
382 382
383/**
384 * Set the emulator window to use for renderer
385 * @param window EmuWindow handle to emulator window to use for rendering
386 */
387void RendererOpenGL::SetWindow(EmuWindow* window) {
388 render_window = window;
389}
390
391static const char* GetSource(GLenum source) { 383static const char* GetSource(GLenum source) {
392#define RET(s) \ 384#define RET(s) \
393 case GL_DEBUG_SOURCE_##s: \ 385 case GL_DEBUG_SOURCE_##s: \
@@ -445,7 +437,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
445 437
446/// Initialize the renderer 438/// Initialize the renderer
447bool RendererOpenGL::Init() { 439bool RendererOpenGL::Init() {
448 ScopeAcquireGLContext acquire_context; 440 ScopeAcquireGLContext acquire_context{render_window};
449 441
450 if (GLAD_GL_KHR_debug) { 442 if (GLAD_GL_KHR_debug) {
451 glEnable(GL_DEBUG_OUTPUT); 443 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 {
34/// Helper class to acquire/release OpenGL context within a given scope 34/// Helper class to acquire/release OpenGL context within a given scope
35class ScopeAcquireGLContext : NonCopyable { 35class ScopeAcquireGLContext : NonCopyable {
36public: 36public:
37 ScopeAcquireGLContext(); 37 explicit ScopeAcquireGLContext(EmuWindow& window);
38 ~ScopeAcquireGLContext(); 38 ~ScopeAcquireGLContext();
39
40private:
41 EmuWindow& emu_window;
39}; 42};
40 43
41class RendererOpenGL : public RendererBase { 44class RendererOpenGL : public VideoCore::RendererBase {
42public: 45public:
43 RendererOpenGL(); 46 explicit RendererOpenGL(EmuWindow& window);
44 ~RendererOpenGL() override; 47 ~RendererOpenGL() override;
45 48
46 /// Swap buffers (render frame) 49 /// Swap buffers (render frame)
47 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; 50 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override;
48 51
49 /**
50 * Set the emulator window to use for renderer
51 * @param window EmuWindow handle to emulator window to use for rendering
52 */
53 void SetWindow(EmuWindow* window) override;
54
55 /// Initialize the renderer 52 /// Initialize the renderer
56 bool Init() override; 53 bool Init() override;
57 54
@@ -72,8 +69,6 @@ private:
72 void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, 69 void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
73 const TextureInfo& texture); 70 const TextureInfo& texture);
74 71
75 EmuWindow* render_window; ///< Handle to render window
76
77 OpenGLState state; 72 OpenGLState state;
78 73
79 // OpenGL object IDs 74 // 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) {
57 case TextureFormat::BC7U: 57 case TextureFormat::BC7U:
58 // In this case a 'pixel' actually refers to a 4x4 tile. 58 // In this case a 'pixel' actually refers to a 4x4 tile.
59 return 16; 59 return 16;
60 case TextureFormat::R32_G32_B32:
61 return 12;
60 case TextureFormat::ASTC_2D_4X4: 62 case TextureFormat::ASTC_2D_4X4:
61 case TextureFormat::A8R8G8B8: 63 case TextureFormat::A8R8G8B8:
62 case TextureFormat::A2B10G10R10: 64 case TextureFormat::A2B10G10R10:
@@ -131,6 +133,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
131 case TextureFormat::R16_G16: 133 case TextureFormat::R16_G16:
132 case TextureFormat::BF10GF11RF11: 134 case TextureFormat::BF10GF11RF11:
133 case TextureFormat::ASTC_2D_4X4: 135 case TextureFormat::ASTC_2D_4X4:
136 case TextureFormat::R32_G32_B32:
134 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, 137 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
135 unswizzled_data.data(), true, block_height); 138 unswizzled_data.data(), true, block_height);
136 break; 139 break;
@@ -190,6 +193,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
190 case TextureFormat::R32: 193 case TextureFormat::R32:
191 case TextureFormat::R16: 194 case TextureFormat::R16:
192 case TextureFormat::R16_G16: 195 case TextureFormat::R16_G16:
196 case TextureFormat::R32_G32_B32:
193 // TODO(Subv): For the time being just forward the same data without any decoding. 197 // TODO(Subv): For the time being just forward the same data without any decoding.
194 rgba_data = texture_data; 198 rgba_data = texture_data;
195 break; 199 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory> 5#include <memory>
6#include "common/logging/log.h"
7#include "video_core/renderer_base.h" 6#include "video_core/renderer_base.h"
8#include "video_core/renderer_opengl/renderer_opengl.h" 7#include "video_core/renderer_opengl/renderer_opengl.h"
9#include "video_core/video_core.h" 8#include "video_core/video_core.h"
10 9
11////////////////////////////////////////////////////////////////////////////////////////////////////
12// Video Core namespace
13
14namespace VideoCore { 10namespace VideoCore {
15 11
16EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window
17std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
18
19std::atomic<bool> g_toggle_framelimit_enabled; 12std::atomic<bool> g_toggle_framelimit_enabled;
20 13
21/// Initialize the video core 14std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) {
22bool Init(EmuWindow* emu_window) { 15 return std::make_unique<RendererOpenGL>(emu_window);
23 g_emu_window = emu_window;
24 g_renderer = std::make_unique<RendererOpenGL>();
25 g_renderer->SetWindow(g_emu_window);
26 if (g_renderer->Init()) {
27 LOG_DEBUG(Render, "initialized OK");
28 } else {
29 LOG_CRITICAL(Render, "initialization failed !");
30 return false;
31 }
32 return true;
33}
34
35/// Shutdown the video core
36void Shutdown() {
37 g_renderer.reset();
38
39 LOG_DEBUG(Render, "shutdown OK");
40} 16}
41 17
42} // namespace VideoCore 18} // 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 @@
8#include <memory> 8#include <memory>
9 9
10class EmuWindow; 10class EmuWindow;
11class RendererBase;
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// Video Core namespace
15 11
16namespace VideoCore { 12namespace VideoCore {
17 13
18enum class Renderer { Software, OpenGL }; 14class RendererBase;
19 15
20extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin 16enum class Renderer { Software, OpenGL };
21extern EmuWindow* g_emu_window; ///< Emu window
22 17
23// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from 18// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
24// qt ui) 19// qt ui)
25extern std::atomic<bool> g_toggle_framelimit_enabled; 20extern std::atomic<bool> g_toggle_framelimit_enabled;
26 21
27/// Start the video core 22/**
28void Start(); 23 * Creates a renderer instance.
29 24 *
30/// Initialize the video core 25 * @note The returned renderer instance is simply allocated. Its Init()
31bool Init(EmuWindow* emu_window); 26 * function still needs to be called to fully complete its setup.
32 27 */
33/// Shutdown the video core 28std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window);
34void Shutdown();
35 29
36} // namespace VideoCore 30} // 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
11 bootmanager.h 11 bootmanager.h
12 configuration/config.cpp 12 configuration/config.cpp
13 configuration/config.h 13 configuration/config.h
14 configuration/configure_audio.cpp
15 configuration/configure_audio.h
14 configuration/configure_debug.cpp 16 configuration/configure_debug.cpp
15 configuration/configure_debug.h 17 configuration/configure_debug.h
16 configuration/configure_dialog.cpp 18 configuration/configure_dialog.cpp
@@ -55,6 +57,7 @@ add_executable(yuzu
55set(UIS 57set(UIS
56 aboutdialog.ui 58 aboutdialog.ui
57 configuration/configure.ui 59 configuration/configure.ui
60 configuration/configure_audio.ui
58 configuration/configure_debug.ui 61 configuration/configure_debug.ui
59 configuration/configure_general.ui 62 configuration/configure_general.ui
60 configuration/configure_graphics.ui 63 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 @@
10AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { 10AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
11 ui->setupUi(this); 11 ui->setupUi(this);
12 ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200)); 12 ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200));
13 ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg( 13 ui->labelBuildInfo->setText(
14 Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); 14 ui->labelBuildInfo->text().arg(Common::g_build_name, Common::g_scm_branch,
15 Common::g_scm_desc, QString(Common::g_build_date).left(10)));
15} 16}
16 17
17AboutDialog::~AboutDialog() {} 18AboutDialog::~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 {
16 16
17public: 17public:
18 explicit AboutDialog(QWidget* parent); 18 explicit AboutDialog(QWidget* parent);
19 ~AboutDialog(); 19 ~AboutDialog() override;
20 20
21private: 21private:
22 std::unique_ptr<Ui::AboutDialog> ui; 22 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 @@
70 </sizepolicy> 70 </sizepolicy>
71 </property> 71 </property>
72 <property name="text"> 72 <property name="text">
73 <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> 73 <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>
74 </property> 74 </property>
75 </widget> 75 </widget>
76 </item> 76 </item>
@@ -115,7 +115,7 @@ p, li { white-space: pre-wrap; }
115 <item> 115 <item>
116 <widget class="QLabel" name="labelLinks"> 116 <widget class="QLabel" name="labelLinks">
117 <property name="text"> 117 <property name="text">
118 <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> 118 <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>
119 </property> 119 </property>
120 <property name="openExternalLinks"> 120 <property name="openExternalLinks">
121 <bool>true</bool> 121 <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 {
106 106
107public: 107public:
108 GRenderWindow(QWidget* parent, EmuThread* emu_thread); 108 GRenderWindow(QWidget* parent, EmuThread* emu_thread);
109 ~GRenderWindow(); 109 ~GRenderWindow() override;
110 110
111 // EmuWindow implementation 111 // EmuWindow implementation
112 void SwapBuffers() override; 112 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() {
92 Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat(); 92 Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat();
93 qt_config->endGroup(); 93 qt_config->endGroup();
94 94
95 qt_config->beginGroup("Audio");
96 Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString();
97 Settings::values.audio_device_id =
98 qt_config->value("output_device", "auto").toString().toStdString();
99 Settings::values.volume = qt_config->value("volume", 1).toFloat();
100 qt_config->endGroup();
101
95 qt_config->beginGroup("Data Storage"); 102 qt_config->beginGroup("Data Storage");
96 Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); 103 Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
97 qt_config->endGroup(); 104 qt_config->endGroup();
98 105
99 qt_config->beginGroup("System"); 106 qt_config->beginGroup("System");
100 Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool(); 107 Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool();
108 Settings::values.username = qt_config->value("username", "yuzu").toString().toStdString();
109 Settings::values.language_index = qt_config->value("language_index", 1).toInt();
101 qt_config->endGroup(); 110 qt_config->endGroup();
102 111
103 qt_config->beginGroup("Miscellaneous"); 112 qt_config->beginGroup("Miscellaneous");
104 Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString(); 113 Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString();
114 Settings::values.use_dev_keys = qt_config->value("use_dev_keys", false).toBool();
105 qt_config->endGroup(); 115 qt_config->endGroup();
106 116
107 qt_config->beginGroup("Debugging"); 117 qt_config->beginGroup("Debugging");
@@ -195,16 +205,25 @@ void Config::SaveValues() {
195 qt_config->setValue("bg_blue", (double)Settings::values.bg_blue); 205 qt_config->setValue("bg_blue", (double)Settings::values.bg_blue);
196 qt_config->endGroup(); 206 qt_config->endGroup();
197 207
208 qt_config->beginGroup("Audio");
209 qt_config->setValue("output_engine", QString::fromStdString(Settings::values.sink_id));
210 qt_config->setValue("output_device", QString::fromStdString(Settings::values.audio_device_id));
211 qt_config->setValue("volume", Settings::values.volume);
212 qt_config->endGroup();
213
198 qt_config->beginGroup("Data Storage"); 214 qt_config->beginGroup("Data Storage");
199 qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); 215 qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
200 qt_config->endGroup(); 216 qt_config->endGroup();
201 217
202 qt_config->beginGroup("System"); 218 qt_config->beginGroup("System");
203 qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode); 219 qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode);
220 qt_config->setValue("username", QString::fromStdString(Settings::values.username));
221 qt_config->setValue("language_index", Settings::values.language_index);
204 qt_config->endGroup(); 222 qt_config->endGroup();
205 223
206 qt_config->beginGroup("Miscellaneous"); 224 qt_config->beginGroup("Miscellaneous");
207 qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter)); 225 qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter));
226 qt_config->setValue("use_dev_keys", Settings::values.use_dev_keys);
208 qt_config->endGroup(); 227 qt_config->endGroup();
209 228
210 qt_config->beginGroup("Debugging"); 229 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 @@
34 <string>Input</string> 34 <string>Input</string>
35 </attribute> 35 </attribute>
36 </widget> 36 </widget>
37 <widget class="ConfigureGraphics" name="graphicsTab"> 37 <widget class="ConfigureGraphics" name="graphicsTab">
38 <attribute name="title"> 38 <attribute name="title">
39 <string>Graphics</string> 39 <string>Graphics</string>
40 </attribute> 40 </attribute>
41 </widget> 41 </widget>
42 <widget class="ConfigureAudio" name="audioTab">
43 <attribute name="title">
44 <string>Audio</string>
45 </attribute>
46 </widget>
42 <widget class="ConfigureDebug" name="debugTab"> 47 <widget class="ConfigureDebug" name="debugTab">
43 <attribute name="title"> 48 <attribute name="title">
44 <string>Debug</string> 49 <string>Debug</string>
@@ -69,6 +74,12 @@
69 <container>1</container> 74 <container>1</container>
70 </customwidget> 75 </customwidget>
71 <customwidget> 76 <customwidget>
77 <class>ConfigureAudio</class>
78 <extends>QWidget</extends>
79 <header>configuration/configure_audio.h</header>
80 <container>1</container>
81 </customwidget>
82 <customwidget>
72 <class>ConfigureDebug</class> 83 <class>ConfigureDebug</class>
73 <extends>QWidget</extends> 84 <extends>QWidget</extends>
74 <header>configuration/configure_debug.h</header> 85 <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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "audio_core/sink.h"
8#include "audio_core/sink_details.h"
9#include "core/core.h"
10#include "core/settings.h"
11#include "ui_configure_audio.h"
12#include "yuzu/configuration/configure_audio.h"
13
14ConfigureAudio::ConfigureAudio(QWidget* parent)
15 : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
16 ui->setupUi(this);
17
18 ui->output_sink_combo_box->clear();
19 ui->output_sink_combo_box->addItem("auto");
20 for (const auto& sink_detail : AudioCore::g_sink_details) {
21 ui->output_sink_combo_box->addItem(sink_detail.id);
22 }
23
24 connect(ui->volume_slider, &QSlider::valueChanged, [this] {
25 ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
26 });
27
28 this->setConfiguration();
29 connect(ui->output_sink_combo_box,
30 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
31 &ConfigureAudio::updateAudioDevices);
32
33 ui->output_sink_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
34 ui->audio_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
35}
36
37ConfigureAudio::~ConfigureAudio() = default;
38
39void ConfigureAudio::setConfiguration() {
40 int new_sink_index = 0;
41 for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
42 if (ui->output_sink_combo_box->itemText(index).toStdString() == Settings::values.sink_id) {
43 new_sink_index = index;
44 break;
45 }
46 }
47 ui->output_sink_combo_box->setCurrentIndex(new_sink_index);
48
49 // The device list cannot be pre-populated (nor listed) until the output sink is known.
50 updateAudioDevices(new_sink_index);
51
52 int new_device_index = -1;
53 for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
54 if (ui->audio_device_combo_box->itemText(index).toStdString() ==
55 Settings::values.audio_device_id) {
56 new_device_index = index;
57 break;
58 }
59 }
60 ui->audio_device_combo_box->setCurrentIndex(new_device_index);
61
62 ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum());
63 ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
64}
65
66void ConfigureAudio::applyConfiguration() {
67 Settings::values.sink_id =
68 ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
69 .toStdString();
70 Settings::values.audio_device_id =
71 ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
72 .toStdString();
73 Settings::values.volume =
74 static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
75}
76
77void ConfigureAudio::updateAudioDevices(int sink_index) {
78 ui->audio_device_combo_box->clear();
79 ui->audio_device_combo_box->addItem(AudioCore::auto_device_name);
80
81 std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
82 std::vector<std::string> device_list = AudioCore::GetSinkDetails(sink_id).list_devices();
83 for (const auto& device : device_list) {
84 ui->audio_device_combo_box->addItem(device.c_str());
85 }
86}
87
88void ConfigureAudio::retranslateUi() {
89 ui->retranslateUi(this);
90}
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 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9
10namespace Ui {
11class ConfigureAudio;
12}
13
14class ConfigureAudio : public QWidget {
15 Q_OBJECT
16
17public:
18 explicit ConfigureAudio(QWidget* parent = nullptr);
19 ~ConfigureAudio();
20
21 void applyConfiguration();
22 void retranslateUi();
23
24public slots:
25 void updateAudioDevices(int sink_index);
26
27private:
28 void setConfiguration();
29
30 std::unique_ptr<Ui::ConfigureAudio> ui;
31};
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 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureAudio</class>
4 <widget class="QWidget" name="ConfigureAudio">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>188</width>
10 <height>246</height>
11 </rect>
12 </property>
13 <layout class="QVBoxLayout">
14 <item>
15 <widget class="QGroupBox" name="groupBox">
16 <property name="title">
17 <string>Audio</string>
18 </property>
19 <layout class="QVBoxLayout">
20 <item>
21 <layout class="QHBoxLayout">
22 <item>
23 <widget class="QLabel" name="label">
24 <property name="text">
25 <string>Output Engine:</string>
26 </property>
27 </widget>
28 </item>
29 <item>
30 <widget class="QComboBox" name="output_sink_combo_box"/>
31 </item>
32 </layout>
33 </item>
34 <item>
35 <layout class="QHBoxLayout">
36 <item>
37 <widget class="QLabel" name="label">
38 <property name="text">
39 <string>Audio Device:</string>
40 </property>
41 </widget>
42 </item>
43 <item>
44 <widget class="QComboBox" name="audio_device_combo_box"/>
45 </item>
46 </layout>
47 </item>
48 <item>
49 <layout class="QHBoxLayout" name="horizontalLayout_2">
50 <property name="topMargin">
51 <number>0</number>
52 </property>
53 <item>
54 <widget class="QLabel" name="label">
55 <property name="text">
56 <string>Volume:</string>
57 </property>
58 </widget>
59 </item>
60 <item>
61 <spacer name="horizontalSpacer">
62 <property name="orientation">
63 <enum>Qt::Horizontal</enum>
64 </property>
65 <property name="sizeHint" stdset="0">
66 <size>
67 <width>40</width>
68 <height>20</height>
69 </size>
70 </property>
71 </spacer>
72 </item>
73 <item>
74 <widget class="QSlider" name="volume_slider">
75 <property name="sizePolicy">
76 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
77 <horstretch>0</horstretch>
78 <verstretch>0</verstretch>
79 </sizepolicy>
80 </property>
81 <property name="maximum">
82 <number>100</number>
83 </property>
84 <property name="pageStep">
85 <number>10</number>
86 </property>
87 <property name="orientation">
88 <enum>Qt::Horizontal</enum>
89 </property>
90 </widget>
91 </item>
92 <item>
93 <widget class="QLabel" name="volume_indicator">
94 <property name="minimumSize">
95 <size>
96 <width>32</width>
97 <height>0</height>
98 </size>
99 </property>
100 <property name="text">
101 <string>0 %</string>
102 </property>
103 <property name="alignment">
104 <set>Qt::AlignCenter</set>
105 </property>
106 </widget>
107 </item>
108 </layout>
109 </item>
110 </layout>
111 </widget>
112 </item>
113 <item>
114 <spacer>
115 <property name="orientation">
116 <enum>Qt::Vertical</enum>
117 </property>
118 <property name="sizeHint" stdset="0">
119 <size>
120 <width>167</width>
121 <height>55</height>
122 </size>
123 </property>
124 </spacer>
125 </item>
126 </layout>
127 </widget>
128 <resources/>
129 <connections/>
130</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
24 }); 24 });
25} 25}
26 26
27ConfigureDebug::~ConfigureDebug() {} 27ConfigureDebug::~ConfigureDebug() = default;
28 28
29void ConfigureDebug::setConfiguration() { 29void ConfigureDebug::setConfiguration() {
30 ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); 30 ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub);
@@ -44,5 +44,4 @@ void ConfigureDebug::applyConfiguration() {
44 Log::Filter filter; 44 Log::Filter filter;
45 filter.ParseFilterString(Settings::values.log_filter); 45 filter.ParseFilterString(Settings::values.log_filter);
46 Log::SetGlobalFilter(filter); 46 Log::SetGlobalFilter(filter);
47 Settings::Apply();
48} 47}
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 @@
23 </property> 23 </property>
24 <layout class="QVBoxLayout" name="verticalLayout_3"> 24 <layout class="QVBoxLayout" name="verticalLayout_3">
25 <item> 25 <item>
26 <widget class="QLabel" name="label_1">
27 <property name="text">
28 <string>The GDB Stub only works correctly when the CPU JIT is off.</string>
29 </property>
30 </widget>
31 </item>
32 <item>
33 <layout class="QHBoxLayout" name="horizontalLayout_1"> 26 <layout class="QHBoxLayout" name="horizontalLayout_1">
34 <item> 27 <item>
35 <widget class="QCheckBox" name="toggle_gdbstub"> 28 <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 @@
6#include "ui_configure.h" 6#include "ui_configure.h"
7#include "yuzu/configuration/config.h" 7#include "yuzu/configuration/config.h"
8#include "yuzu/configuration/configure_dialog.h" 8#include "yuzu/configuration/configure_dialog.h"
9#include "yuzu/hotkeys.h"
9 10
10ConfigureDialog::ConfigureDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ConfigureDialog) { 11ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry)
12 : QDialog(parent), ui(new Ui::ConfigureDialog) {
11 ui->setupUi(this); 13 ui->setupUi(this);
14 ui->generalTab->PopulateHotkeyList(registry);
12 this->setConfiguration(); 15 this->setConfiguration();
13} 16}
14 17
15ConfigureDialog::~ConfigureDialog() {} 18ConfigureDialog::~ConfigureDialog() = default;
16 19
17void ConfigureDialog::setConfiguration() {} 20void ConfigureDialog::setConfiguration() {}
18 21
@@ -21,6 +24,7 @@ void ConfigureDialog::applyConfiguration() {
21 ui->systemTab->applyConfiguration(); 24 ui->systemTab->applyConfiguration();
22 ui->inputTab->applyConfiguration(); 25 ui->inputTab->applyConfiguration();
23 ui->graphicsTab->applyConfiguration(); 26 ui->graphicsTab->applyConfiguration();
27 ui->audioTab->applyConfiguration();
24 ui->debugTab->applyConfiguration(); 28 ui->debugTab->applyConfiguration();
25 Settings::Apply(); 29 Settings::Apply();
26} 30}
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 @@
7#include <memory> 7#include <memory>
8#include <QDialog> 8#include <QDialog>
9 9
10class HotkeyRegistry;
11
10namespace Ui { 12namespace Ui {
11class ConfigureDialog; 13class ConfigureDialog;
12} 14}
@@ -15,7 +17,7 @@ class ConfigureDialog : public QDialog {
15 Q_OBJECT 17 Q_OBJECT
16 18
17public: 19public:
18 explicit ConfigureDialog(QWidget* parent); 20 explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry);
19 ~ConfigureDialog(); 21 ~ConfigureDialog();
20 22
21 void applyConfiguration(); 23 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)
24 ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 24 ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
25} 25}
26 26
27ConfigureGeneral::~ConfigureGeneral() {} 27ConfigureGeneral::~ConfigureGeneral() = default;
28 28
29void ConfigureGeneral::setConfiguration() { 29void ConfigureGeneral::setConfiguration() {
30 ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan); 30 ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan);
@@ -35,6 +35,10 @@ void ConfigureGeneral::setConfiguration() {
35 ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); 35 ui->use_docked_mode->setChecked(Settings::values.use_docked_mode);
36} 36}
37 37
38void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
39 ui->widget->Populate(registry);
40}
41
38void ConfigureGeneral::applyConfiguration() { 42void ConfigureGeneral::applyConfiguration() {
39 UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked(); 43 UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked();
40 UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); 44 UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
@@ -44,5 +48,4 @@ void ConfigureGeneral::applyConfiguration() {
44 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); 48 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
45 Settings::values.use_multi_core = ui->use_multi_core->isChecked(); 49 Settings::values.use_multi_core = ui->use_multi_core->isChecked();
46 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); 50 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
47 Settings::Apply();
48} 51}
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 @@
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9 9
10class HotkeyRegistry;
11
10namespace Ui { 12namespace Ui {
11class ConfigureGeneral; 13class ConfigureGeneral;
12} 14}
@@ -18,11 +20,11 @@ public:
18 explicit ConfigureGeneral(QWidget* parent = nullptr); 20 explicit ConfigureGeneral(QWidget* parent = nullptr);
19 ~ConfigureGeneral(); 21 ~ConfigureGeneral();
20 22
23 void PopulateHotkeyList(const HotkeyRegistry& registry);
21 void applyConfiguration(); 24 void applyConfiguration();
22 25
23private: 26private:
24 void setConfiguration(); 27 void setConfiguration();
25 28
26private:
27 std::unique_ptr<Ui::ConfigureGeneral> ui; 29 std::unique_ptr<Ui::ConfigureGeneral> ui;
28}; 30};
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)
14 this->setConfiguration(); 14 this->setConfiguration();
15} 15}
16 16
17ConfigureGraphics::~ConfigureGraphics() {} 17ConfigureGraphics::~ConfigureGraphics() = default;
18 18
19enum class Resolution : int { 19enum class Resolution : int {
20 Auto, 20 Auto,
@@ -67,5 +67,4 @@ void ConfigureGraphics::applyConfiguration() {
67 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); 67 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
68 Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked(); 68 Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked();
69 Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked(); 69 Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked();
70 Settings::Apply();
71} 70}
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() {
191 [](const Common::ParamPackage& param) { return param.Serialize(); }); 191 [](const Common::ParamPackage& param) { return param.Serialize(); });
192 std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(), 192 std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(),
193 [](const Common::ParamPackage& param) { return param.Serialize(); }); 193 [](const Common::ParamPackage& param) { return param.Serialize(); });
194
195 Settings::Apply();
196} 194}
197 195
198void ConfigureInput::loadConfiguration() { 196void 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 @@
4 4
5#include <QMessageBox> 5#include <QMessageBox>
6#include "core/core.h" 6#include "core/core.h"
7#include "core/settings.h"
7#include "ui_configure_system.h" 8#include "ui_configure_system.h"
8#include "yuzu/configuration/configure_system.h" 9#include "yuzu/configuration/configure_system.h"
9#include "yuzu/ui_settings.h" 10#include "yuzu/main.h"
10 11
11static const std::array<int, 12> days_in_month = {{ 12static const std::array<int, 12> days_in_month = {{
12 31, 13 31,
@@ -34,10 +35,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::
34 this->setConfiguration(); 35 this->setConfiguration();
35} 36}
36 37
37ConfigureSystem::~ConfigureSystem() {} 38ConfigureSystem::~ConfigureSystem() = default;
38 39
39void ConfigureSystem::setConfiguration() { 40void ConfigureSystem::setConfiguration() {
40 enabled = !Core::System::GetInstance().IsPoweredOn(); 41 enabled = !Core::System::GetInstance().IsPoweredOn();
42 ui->edit_username->setText(QString::fromStdString(Settings::values.username));
43 ui->combo_language->setCurrentIndex(Settings::values.language_index);
41} 44}
42 45
43void ConfigureSystem::ReadSystemSettings() {} 46void ConfigureSystem::ReadSystemSettings() {}
@@ -45,6 +48,9 @@ void ConfigureSystem::ReadSystemSettings() {}
45void ConfigureSystem::applyConfiguration() { 48void ConfigureSystem::applyConfiguration() {
46 if (!enabled) 49 if (!enabled)
47 return; 50 return;
51 Settings::values.username = ui->edit_username->text().toStdString();
52 Settings::values.language_index = ui->combo_language->currentIndex();
53 Settings::Apply();
48} 54}
49 55
50void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { 56void 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 @@
38 </sizepolicy> 38 </sizepolicy>
39 </property> 39 </property>
40 <property name="maxLength"> 40 <property name="maxLength">
41 <number>10</number> 41 <number>32</number>
42 </property> 42 </property>
43 </widget> 43 </widget>
44 </item> 44 </item>
@@ -164,7 +164,7 @@
164 </item> 164 </item>
165 <item> 165 <item>
166 <property name="text"> 166 <property name="text">
167 <string>Simplified Chinese (简体中文)</string> 167 <string>Chinese</string>
168 </property> 168 </property>
169 </item> 169 </item>
170 <item> 170 <item>
@@ -187,6 +187,31 @@
187 <string>Russian (Русский)</string> 187 <string>Russian (Русский)</string>
188 </property> 188 </property>
189 </item> 189 </item>
190 <item>
191 <property name="text">
192 <string>Taiwanese</string>
193 </property>
194 </item>
195 <item>
196 <property name="text">
197 <string>British English</string>
198 </property>
199 </item>
200 <item>
201 <property name="text">
202 <string>Canadian French</string>
203 </property>
204 </item>
205 <item>
206 <property name="text">
207 <string>Latin American Spanish</string>
208 </property>
209 </item>
210 <item>
211 <property name="text">
212 <string>Simplified Chinese</string>
213 </property>
214 </item>
190 <item> 215 <item>
191 <property name="text"> 216 <property name="text">
192 <string>Traditional Chinese (正體中文)</string> 217 <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
10 : QDockWidget(title, parent), BreakPointObserver(debug_context) { 10 : QDockWidget(title, parent), BreakPointObserver(debug_context) {
11 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); 11 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
12 12
13 connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); 13 connect(this, &BreakPointObserverDock::Resumed, this, &BreakPointObserverDock::OnResumed);
14 14
15 // NOTE: This signal is emitted from a non-GUI thread, but connect() takes 15 // NOTE: This signal is emitted from a non-GUI thread, but connect() takes
16 // care of delaying its handling to the GUI thread. 16 // care of delaying its handling to the GUI thread.
17 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, 17 connect(this, &BreakPointObserverDock::BreakPointHit, this,
18 SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); 18 &BreakPointObserverDock::OnBreakPointHit, Qt::BlockingQueuedConnection);
19} 19}
20 20
21void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) { 21void 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:
23 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 23 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
24 void OnMaxwellResume() override; 24 void OnMaxwellResume() override;
25 25
26private slots:
27 virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
28 virtual void OnResumed() = 0;
29
30signals: 26signals:
31 void Resumed(); 27 void Resumed();
32 void BreakPointHit(Tegra::DebugContext::Event event, void* data); 28 void BreakPointHit(Tegra::DebugContext::Event event, void* data);
29
30private:
31 virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
32 virtual void OnResumed() = 0;
33}; 33};
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(
144 144
145 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); 145 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
146 146
147 connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), this, 147 connect(breakpoint_list, &QTreeView::doubleClicked, this,
148 SLOT(OnItemDoubleClicked(const QModelIndex&))); 148 &GraphicsBreakPointsWidget::OnItemDoubleClicked);
149 149
150 connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested())); 150 connect(resume_button, &QPushButton::clicked, this,
151 &GraphicsBreakPointsWidget::OnResumeRequested);
151 152
152 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, 153 connect(this, &GraphicsBreakPointsWidget::BreakPointHit, this,
153 SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); 154 &GraphicsBreakPointsWidget::OnBreakPointHit, Qt::BlockingQueuedConnection);
154 connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); 155 connect(this, &GraphicsBreakPointsWidget::Resumed, this, &GraphicsBreakPointsWidget::OnResumed);
155 156
156 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), breakpoint_model, 157 connect(this, &GraphicsBreakPointsWidget::BreakPointHit, breakpoint_model,
157 SLOT(OnBreakPointHit(Tegra::DebugContext::Event)), Qt::BlockingQueuedConnection); 158 &BreakPointModel::OnBreakPointHit, Qt::BlockingQueuedConnection);
158 connect(this, SIGNAL(Resumed()), breakpoint_model, SLOT(OnResumed())); 159 connect(this, &GraphicsBreakPointsWidget::Resumed, breakpoint_model,
160 &BreakPointModel::OnResumed);
159 161
160 connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&, const QModelIndex&)), 162 connect(this, &GraphicsBreakPointsWidget::BreakPointsChanged,
161 breakpoint_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&))); 163 [this](const QModelIndex& top_left, const QModelIndex& bottom_right) {
164 breakpoint_model->dataChanged(top_left, bottom_right);
165 });
162 166
163 QWidget* main_widget = new QWidget; 167 QWidget* main_widget = new QWidget;
164 auto main_layout = new QVBoxLayout; 168 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:
26 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 26 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
27 void OnMaxwellResume() override; 27 void OnMaxwellResume() override;
28 28
29public slots:
30 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
31 void OnItemDoubleClicked(const QModelIndex&);
32 void OnResumeRequested();
33 void OnResumed();
34
35signals: 29signals:
36 void Resumed(); 30 void Resumed();
37 void BreakPointHit(Tegra::DebugContext::Event event, void* data); 31 void BreakPointHit(Tegra::DebugContext::Event event, void* data);
38 void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); 32 void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
39 33
40private: 34private:
35 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
36 void OnItemDoubleClicked(const QModelIndex&);
37 void OnResumeRequested();
38 void OnResumed();
39
41 QLabel* status_text; 40 QLabel* status_text;
42 QPushButton* resume_button; 41 QPushButton* resume_button;
43 42
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:
25 25
26 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 26 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
27 27
28public slots:
29 void OnBreakPointHit(Tegra::DebugContext::Event event); 28 void OnBreakPointHit(Tegra::DebugContext::Event event);
30 void OnResumed(); 29 void OnResumed();
31 30
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(
34 34
35SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) 35SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_)
36 : QLabel(parent), surface_widget(surface_widget_) {} 36 : QLabel(parent), surface_widget(surface_widget_) {}
37SurfacePicture::~SurfacePicture() {} 37
38SurfacePicture::~SurfacePicture() = default;
38 39
39void SurfacePicture::mousePressEvent(QMouseEvent* event) { 40void SurfacePicture::mousePressEvent(QMouseEvent* event) {
40 // Only do something while the left mouse button is held down 41 // Only do something while the left mouse button is held down
@@ -153,22 +154,24 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext
153 save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save")); 154 save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save"));
154 155
155 // Connections 156 // Connections
156 connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); 157 connect(this, &GraphicsSurfaceWidget::Update, this, &GraphicsSurfaceWidget::OnUpdate);
157 connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, 158 connect(surface_source_list,
158 SLOT(OnSurfaceSourceChanged(int))); 159 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
159 connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, 160 &GraphicsSurfaceWidget::OnSurfaceSourceChanged);
160 SLOT(OnSurfaceAddressChanged(qint64))); 161 connect(surface_address_control, &CSpinBox::ValueChanged, this,
161 connect(surface_width_control, SIGNAL(valueChanged(int)), this, 162 &GraphicsSurfaceWidget::OnSurfaceAddressChanged);
162 SLOT(OnSurfaceWidthChanged(int))); 163 connect(surface_width_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
163 connect(surface_height_control, SIGNAL(valueChanged(int)), this, 164 this, &GraphicsSurfaceWidget::OnSurfaceWidthChanged);
164 SLOT(OnSurfaceHeightChanged(int))); 165 connect(surface_height_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
165 connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, 166 this, &GraphicsSurfaceWidget::OnSurfaceHeightChanged);
166 SLOT(OnSurfaceFormatChanged(int))); 167 connect(surface_format_control,
167 connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, 168 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
168 SLOT(OnSurfacePickerXChanged(int))); 169 &GraphicsSurfaceWidget::OnSurfaceFormatChanged);
169 connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, 170 connect(surface_picker_x_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
170 SLOT(OnSurfacePickerYChanged(int))); 171 this, &GraphicsSurfaceWidget::OnSurfacePickerXChanged);
171 connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); 172 connect(surface_picker_y_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
173 this, &GraphicsSurfaceWidget::OnSurfacePickerYChanged);
174 connect(save_surface, &QPushButton::clicked, this, &GraphicsSurfaceWidget::SaveSurface);
172 175
173 auto main_widget = new QWidget; 176 auto main_widget = new QWidget;
174 auto main_layout = new QVBoxLayout; 177 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 {
22public: 22public:
23 explicit SurfacePicture(QWidget* parent = nullptr, 23 explicit SurfacePicture(QWidget* parent = nullptr,
24 GraphicsSurfaceWidget* surface_widget = nullptr); 24 GraphicsSurfaceWidget* surface_widget = nullptr);
25 ~SurfacePicture(); 25 ~SurfacePicture() override;
26 26
27protected slots: 27protected slots:
28 virtual void mouseMoveEvent(QMouseEvent* event); 28 void mouseMoveEvent(QMouseEvent* event) override;
29 virtual void mousePressEvent(QMouseEvent* event); 29 void mousePressEvent(QMouseEvent* event) override;
30 30
31private: 31private:
32 GraphicsSurfaceWidget* surface_widget; 32 GraphicsSurfaceWidget* surface_widget;
@@ -65,16 +65,15 @@ public slots:
65 void OnSurfacePickerYChanged(int new_value); 65 void OnSurfacePickerYChanged(int new_value);
66 void OnUpdate(); 66 void OnUpdate();
67 67
68private slots: 68signals:
69 void Update();
70
71private:
69 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 72 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
70 void OnResumed() override; 73 void OnResumed() override;
71 74
72 void SaveSurface(); 75 void SaveSurface();
73 76
74signals:
75 void Update();
76
77private:
78 QComboBox* surface_source_list; 77 QComboBox* surface_source_list;
79 CSpinBox* surface_address_control; 78 CSpinBox* surface_address_control;
80 QSpinBox* surface_width_control; 79 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 @@
14#include "core/hle/kernel/timer.h" 14#include "core/hle/kernel/timer.h"
15#include "core/hle/kernel/wait_object.h" 15#include "core/hle/kernel/wait_object.h"
16 16
17WaitTreeItem::~WaitTreeItem() {} 17WaitTreeItem::~WaitTreeItem() = default;
18 18
19QColor WaitTreeItem::GetColor() const { 19QColor WaitTreeItem::GetColor() const {
20 return QColor(Qt::GlobalColor::black); 20 return QColor(Qt::GlobalColor::black);
@@ -316,7 +316,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
316 316
317 list.push_back(std::make_unique<WaitTreeText>( 317 list.push_back(std::make_unique<WaitTreeText>(
318 tr("reset type = %1") 318 tr("reset type = %1")
319 .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).reset_type)))); 319 .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType()))));
320 return list; 320 return list;
321} 321}
322 322
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 @@
9#include <QTreeView> 9#include <QTreeView>
10#include <boost/container/flat_set.hpp> 10#include <boost/container/flat_set.hpp>
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13 13
14class EmuThread; 14class EmuThread;
15 15
@@ -25,11 +25,13 @@ class WaitTreeThread;
25class WaitTreeItem : public QObject { 25class WaitTreeItem : public QObject {
26 Q_OBJECT 26 Q_OBJECT
27public: 27public:
28 ~WaitTreeItem() override;
29
28 virtual bool IsExpandable() const; 30 virtual bool IsExpandable() const;
29 virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const; 31 virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const;
30 virtual QString GetText() const = 0; 32 virtual QString GetText() const = 0;
31 virtual QColor GetColor() const; 33 virtual QColor GetColor() const;
32 virtual ~WaitTreeItem(); 34
33 void Expand(); 35 void Expand();
34 WaitTreeItem* Parent() const; 36 WaitTreeItem* Parent() const;
35 const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const; 37 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) {
162 } 162 }
163 search_field->setFilterResult(rowCount, rowCount); 163 search_field->setFilterResult(rowCount, rowCount);
164 } else { 164 } else {
165 QStandardItem* child_file;
166 QString file_path, file_name, file_title, file_programmid;
167 int result_count = 0; 165 int result_count = 0;
168 for (int i = 0; i < rowCount; ++i) { 166 for (int i = 0; i < rowCount; ++i) {
169 child_file = item_model->item(i, 0); 167 const QStandardItem* child_file = item_model->item(i, 0);
170 file_path = child_file->data(GameListItemPath::FullPathRole).toString().toLower(); 168 const QString file_path =
171 file_name = file_path.mid(file_path.lastIndexOf("/") + 1); 169 child_file->data(GameListItemPath::FullPathRole).toString().toLower();
172 file_title = child_file->data(GameListItemPath::TitleRole).toString().toLower(); 170 QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1);
173 file_programmid = 171 const QString file_title =
172 child_file->data(GameListItemPath::TitleRole).toString().toLower();
173 const QString file_programmid =
174 child_file->data(GameListItemPath::ProgramIdRole).toString().toLower(); 174 child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
175 175
176 // Only items which filename in combination with its title contains all words 176 // Only items which filename in combination with its title contains all words
@@ -258,18 +258,20 @@ void GameList::AddEntry(const QList<QStandardItem*>& entry_items) {
258 258
259void GameList::ValidateEntry(const QModelIndex& item) { 259void GameList::ValidateEntry(const QModelIndex& item) {
260 // We don't care about the individual QStandardItem that was selected, but its row. 260 // We don't care about the individual QStandardItem that was selected, but its row.
261 int row = item_model->itemFromIndex(item)->row(); 261 const int row = item_model->itemFromIndex(item)->row();
262 QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); 262 const QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME);
263 QString file_path = child_file->data(GameListItemPath::FullPathRole).toString(); 263 const QString file_path = child_file->data(GameListItemPath::FullPathRole).toString();
264 264
265 if (file_path.isEmpty()) 265 if (file_path.isEmpty())
266 return; 266 return;
267 std::string std_file_path(file_path.toStdString()); 267
268 if (!FileUtil::Exists(std_file_path)) 268 if (!QFileInfo::exists(file_path))
269 return; 269 return;
270 if (FileUtil::IsDirectory(std_file_path)) { 270
271 QDir dir(std_file_path.c_str()); 271 const QFileInfo file_info{file_path};
272 QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); 272 if (file_info.isDir()) {
273 const QDir dir{file_path};
274 const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
273 if (matching_main.size() == 1) { 275 if (matching_main.size() == 1) {
274 emit GameChosen(dir.path() + DIR_SEP + matching_main[0]); 276 emit GameChosen(dir.path() + DIR_SEP + matching_main[0]);
275 } 277 }
@@ -365,24 +367,26 @@ void GameList::LoadInterfaceLayout() {
365 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); 367 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
366} 368}
367 369
368const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca"}; 370const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci"};
369 371
370static bool HasSupportedFileExtension(const std::string& file_name) { 372static bool HasSupportedFileExtension(const std::string& file_name) {
371 QFileInfo file = QFileInfo(file_name.c_str()); 373 const QFileInfo file = QFileInfo(QString::fromStdString(file_name));
372 return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); 374 return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive);
373} 375}
374 376
375static bool IsExtractedNCAMain(const std::string& file_name) { 377static bool IsExtractedNCAMain(const std::string& file_name) {
376 return QFileInfo(file_name.c_str()).fileName() == "main"; 378 return QFileInfo(QString::fromStdString(file_name)).fileName() == "main";
377} 379}
378 380
379static QString FormatGameName(const std::string& physical_name) { 381static QString FormatGameName(const std::string& physical_name) {
380 QFileInfo file_info(physical_name.c_str()); 382 const QString physical_name_as_qstring = QString::fromStdString(physical_name);
383 const QFileInfo file_info(physical_name_as_qstring);
384
381 if (IsExtractedNCAMain(physical_name)) { 385 if (IsExtractedNCAMain(physical_name)) {
382 return file_info.dir().path(); 386 return file_info.dir().path();
383 } else {
384 return QString::fromStdString(physical_name);
385 } 387 }
388
389 return physical_name_as_qstring;
386} 390}
387 391
388void GameList::RefreshGameDirectory() { 392void 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 @@
5#pragma once 5#pragma once
6 6
7#include <atomic> 7#include <atomic>
8#include <utility>
8#include <QImage> 9#include <QImage>
9#include <QRunnable> 10#include <QRunnable>
10#include <QStandardItem> 11#include <QStandardItem>
@@ -27,9 +28,8 @@ static QPixmap GetDefaultIcon(bool large) {
27class GameListItem : public QStandardItem { 28class GameListItem : public QStandardItem {
28 29
29public: 30public:
30 GameListItem() : QStandardItem() {} 31 GameListItem() = default;
31 GameListItem(const QString& string) : QStandardItem(string) {} 32 explicit GameListItem(const QString& string) : QStandardItem(string) {}
32 virtual ~GameListItem() override {}
33}; 33};
34 34
35/** 35/**
@@ -45,9 +45,8 @@ public:
45 static const int TitleRole = Qt::UserRole + 2; 45 static const int TitleRole = Qt::UserRole + 2;
46 static const int ProgramIdRole = Qt::UserRole + 3; 46 static const int ProgramIdRole = Qt::UserRole + 3;
47 47
48 GameListItemPath() : GameListItem() {} 48 GameListItemPath() = default;
49 GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) 49 GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) {
50 : GameListItem() {
51 setData(game_path, FullPathRole); 50 setData(game_path, FullPathRole);
52 setData(qulonglong(program_id), ProgramIdRole); 51 setData(qulonglong(program_id), ProgramIdRole);
53 } 52 }
@@ -75,8 +74,8 @@ class GameListItemSize : public GameListItem {
75public: 74public:
76 static const int SizeRole = Qt::UserRole + 1; 75 static const int SizeRole = Qt::UserRole + 1;
77 76
78 GameListItemSize() : GameListItem() {} 77 GameListItemSize() = default;
79 GameListItemSize(const qulonglong size_bytes) : GameListItem() { 78 explicit GameListItemSize(const qulonglong size_bytes) {
80 setData(size_bytes, SizeRole); 79 setData(size_bytes, SizeRole);
81 } 80 }
82 81
@@ -111,7 +110,7 @@ class GameListWorker : public QObject, public QRunnable {
111 110
112public: 111public:
113 GameListWorker(QString dir_path, bool deep_scan) 112 GameListWorker(QString dir_path, bool deep_scan)
114 : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} 113 : dir_path(std::move(dir_path)), deep_scan(deep_scan) {}
115 114
116public slots: 115public slots:
117 /// Starts the processing of directory tree information. 116 /// 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 @@
10#include "yuzu/hotkeys.h" 10#include "yuzu/hotkeys.h"
11#include "yuzu/ui_settings.h" 11#include "yuzu/ui_settings.h"
12 12
13struct Hotkey { 13HotkeyRegistry::HotkeyRegistry() = default;
14 Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} 14HotkeyRegistry::~HotkeyRegistry() = default;
15 15
16 QKeySequence keyseq; 16void HotkeyRegistry::LoadHotkeys() {
17 QShortcut* shortcut;
18 Qt::ShortcutContext context;
19};
20
21typedef std::map<QString, Hotkey> HotkeyMap;
22typedef std::map<QString, HotkeyMap> HotkeyGroupMap;
23
24HotkeyGroupMap hotkey_groups;
25
26void SaveHotkeys() {
27 UISettings::values.shortcuts.clear();
28 for (auto group : hotkey_groups) {
29 for (auto hotkey : group.second) {
30 UISettings::values.shortcuts.emplace_back(
31 UISettings::Shortcut(group.first + "/" + hotkey.first,
32 UISettings::ContextualShortcut(hotkey.second.keyseq.toString(),
33 hotkey.second.context)));
34 }
35 }
36}
37
38void LoadHotkeys() {
39 // Make sure NOT to use a reference here because it would become invalid once we call 17 // Make sure NOT to use a reference here because it would become invalid once we call
40 // beginGroup() 18 // beginGroup()
41 for (auto shortcut : UISettings::values.shortcuts) { 19 for (auto shortcut : UISettings::values.shortcuts) {
42 QStringList cat = shortcut.first.split("/"); 20 const QStringList cat = shortcut.first.split('/');
43 Q_ASSERT(cat.size() >= 2); 21 Q_ASSERT(cat.size() >= 2);
44 22
45 // RegisterHotkey assigns default keybindings, so use old values as default parameters 23 // RegisterHotkey assigns default keybindings, so use old values as default parameters
46 Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; 24 Hotkey& hk = hotkey_groups[cat[0]][cat[1]];
47 if (!shortcut.second.first.isEmpty()) { 25 if (!shortcut.second.first.isEmpty()) {
48 hk.keyseq = QKeySequence::fromString(shortcut.second.first); 26 hk.keyseq = QKeySequence::fromString(shortcut.second.first);
49 hk.context = (Qt::ShortcutContext)shortcut.second.second; 27 hk.context = static_cast<Qt::ShortcutContext>(shortcut.second.second);
50 } 28 }
51 if (hk.shortcut) 29 if (hk.shortcut)
52 hk.shortcut->setKey(hk.keyseq); 30 hk.shortcut->setKey(hk.keyseq);
53 } 31 }
54} 32}
55 33
56void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, 34void HotkeyRegistry::SaveHotkeys() {
57 Qt::ShortcutContext default_context) { 35 UISettings::values.shortcuts.clear();
58 if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) { 36 for (const auto& group : hotkey_groups) {
59 hotkey_groups[group][action].keyseq = default_keyseq; 37 for (const auto& hotkey : group.second) {
60 hotkey_groups[group][action].context = default_context; 38 UISettings::values.shortcuts.emplace_back(
39 UISettings::Shortcut(group.first + '/' + hotkey.first,
40 UISettings::ContextualShortcut(hotkey.second.keyseq.toString(),
41 hotkey.second.context)));
42 }
61 } 43 }
62} 44}
63 45
64QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) { 46void HotkeyRegistry::RegisterHotkey(const QString& group, const QString& action,
47 const QKeySequence& default_keyseq,
48 Qt::ShortcutContext default_context) {
49 auto& hotkey_group = hotkey_groups[group];
50 if (hotkey_group.find(action) != hotkey_group.end()) {
51 return;
52 }
53
54 auto& hotkey_action = hotkey_groups[group][action];
55 hotkey_action.keyseq = default_keyseq;
56 hotkey_action.context = default_context;
57}
58
59QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) {
65 Hotkey& hk = hotkey_groups[group][action]; 60 Hotkey& hk = hotkey_groups[group][action];
66 61
67 if (!hk.shortcut) 62 if (!hk.shortcut)
@@ -72,10 +67,12 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge
72 67
73GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { 68GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) {
74 ui.setupUi(this); 69 ui.setupUi(this);
70}
75 71
76 for (auto group : hotkey_groups) { 72void GHotkeysDialog::Populate(const HotkeyRegistry& registry) {
73 for (const auto& group : registry.hotkey_groups) {
77 QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); 74 QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first));
78 for (auto hotkey : group.second) { 75 for (const auto& hotkey : group.second) {
79 QStringList columns; 76 QStringList columns;
80 columns << hotkey.first << hotkey.second.keyseq.toString(); 77 columns << hotkey.first << hotkey.second.keyseq.toString();
81 QTreeWidgetItem* item = new QTreeWidgetItem(columns); 78 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <map>
7#include "ui_hotkeys.h" 8#include "ui_hotkeys.h"
8 9
9class QDialog; 10class QDialog;
@@ -11,47 +12,69 @@ class QKeySequence;
11class QSettings; 12class QSettings;
12class QShortcut; 13class QShortcut;
13 14
14/** 15class HotkeyRegistry final {
15 * Register a hotkey. 16public:
16 * 17 friend class GHotkeysDialog;
17 * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") 18
18 * @param action Name of the action (e.g. "Start Emulation", "Load Image") 19 explicit HotkeyRegistry();
19 * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings 20 ~HotkeyRegistry();
20 * file before 21
21 * @param default_context Default context to assign if the hotkey wasn't present in the settings 22 /**
22 * file before 23 * Loads hotkeys from the settings file.
23 * @warning Both the group and action strings will be displayed in the hotkey settings dialog 24 *
24 */ 25 * @note Yet unregistered hotkeys which are present in the settings will automatically be
25void RegisterHotkey(const QString& group, const QString& action, 26 * registered.
26 const QKeySequence& default_keyseq = QKeySequence(), 27 */
27 Qt::ShortcutContext default_context = Qt::WindowShortcut); 28 void LoadHotkeys();
28 29
29/** 30 /**
30 * Returns a QShortcut object whose activated() signal can be connected to other QObjects' slots. 31 * Saves all registered hotkeys to the settings file.
31 * 32 *
32 * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger"). 33 * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a
33 * @param action Name of the action (e.g. "Start Emulation", "Load Image"). 34 * settings group will be created to store the key sequence and the hotkey context.
34 * @param widget Parent widget of the returned QShortcut. 35 */
35 * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut 36 void SaveHotkeys();
36 * will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent. 37
37 */ 38 /**
38QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); 39 * Returns a QShortcut object whose activated() signal can be connected to other QObjects'
39 40 * slots.
40/** 41 *
41 * Saves all registered hotkeys to the settings file. 42 * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger").
42 * 43 * @param action Name of the action (e.g. "Start Emulation", "Load Image").
43 * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a 44 * @param widget Parent widget of the returned QShortcut.
44 * settings group will be created to store the key sequence and the hotkey context. 45 * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut
45 */ 46 * will be the same. Thus, you shouldn't rely on the caller really being the
46void SaveHotkeys(); 47 * QShortcut's parent.
47 48 */
48/** 49 QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
49 * Loads hotkeys from the settings file. 50
50 * 51 /**
51 * @note Yet unregistered hotkeys which are present in the settings will automatically be 52 * Register a hotkey.
52 * registered. 53 *
53 */ 54 * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger")
54void LoadHotkeys(); 55 * @param action Name of the action (e.g. "Start Emulation", "Load Image")
56 * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the
57 * settings file before
58 * @param default_context Default context to assign if the hotkey wasn't present in the settings
59 * file before
60 * @warning Both the group and action strings will be displayed in the hotkey settings dialog
61 */
62 void RegisterHotkey(const QString& group, const QString& action,
63 const QKeySequence& default_keyseq = {},
64 Qt::ShortcutContext default_context = Qt::WindowShortcut);
65
66private:
67 struct Hotkey {
68 QKeySequence keyseq;
69 QShortcut* shortcut = nullptr;
70 Qt::ShortcutContext context = Qt::WindowShortcut;
71 };
72
73 using HotkeyMap = std::map<QString, Hotkey>;
74 using HotkeyGroupMap = std::map<QString, HotkeyMap>;
75
76 HotkeyGroupMap hotkey_groups;
77};
55 78
56class GHotkeysDialog : public QWidget { 79class GHotkeysDialog : public QWidget {
57 Q_OBJECT 80 Q_OBJECT
@@ -59,6 +82,8 @@ class GHotkeysDialog : public QWidget {
59public: 82public:
60 explicit GHotkeysDialog(QWidget* parent = nullptr); 83 explicit GHotkeysDialog(QWidget* parent = nullptr);
61 84
85 void Populate(const HotkeyRegistry& registry);
86
62private: 87private:
63 Ui::hotkeys ui; 88 Ui::hotkeys ui;
64}; 89};
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 @@
23#include "common/scope_exit.h" 23#include "common/scope_exit.h"
24#include "common/string_util.h" 24#include "common/string_util.h"
25#include "core/core.h" 25#include "core/core.h"
26#include "core/crypto/key_manager.h"
26#include "core/gdbstub/gdbstub.h" 27#include "core/gdbstub/gdbstub.h"
27#include "core/loader/loader.h" 28#include "core/loader/loader.h"
28#include "core/settings.h" 29#include "core/settings.h"
@@ -80,6 +81,8 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) {
80 81
81void GMainWindow::ShowCallouts() {} 82void GMainWindow::ShowCallouts() {}
82 83
84const int GMainWindow::max_recent_files_item;
85
83GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { 86GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
84 87
85 debug_context = Tegra::DebugContext::Construct(); 88 debug_context = Tegra::DebugContext::Construct();
@@ -205,27 +208,46 @@ void GMainWindow::InitializeRecentFileMenuActions() {
205} 208}
206 209
207void GMainWindow::InitializeHotkeys() { 210void GMainWindow::InitializeHotkeys() {
208 RegisterHotkey("Main Window", "Load File", QKeySequence::Open); 211 hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
209 RegisterHotkey("Main Window", "Start Emulation"); 212 hotkey_registry.RegisterHotkey("Main Window", "Start Emulation");
210 RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); 213 hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4));
211 RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), 214 hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen);
212 Qt::ApplicationShortcut); 215 hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape),
213 LoadHotkeys(); 216 Qt::ApplicationShortcut);
214 217 hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"),
215 connect(GetHotkey("Main Window", "Load File", this), &QShortcut::activated, this, 218 Qt::ApplicationShortcut);
216 &GMainWindow::OnMenuLoadFile); 219 hotkey_registry.LoadHotkeys();
217 connect(GetHotkey("Main Window", "Start Emulation", this), &QShortcut::activated, this, 220
218 &GMainWindow::OnStartGame); 221 connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
219 connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activated, 222 this, &GMainWindow::OnMenuLoadFile);
220 ui.action_Fullscreen, &QAction::trigger); 223 connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this),
221 connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activatedAmbiguously, 224 &QShortcut::activated, this, &GMainWindow::OnStartGame);
222 ui.action_Fullscreen, &QAction::trigger); 225 connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated,
223 connect(GetHotkey("Main Window", "Exit Fullscreen", this), &QShortcut::activated, this, [&] { 226 this, [&] {
224 if (emulation_running) { 227 if (emulation_running) {
225 ui.action_Fullscreen->setChecked(false); 228 if (emu_thread->IsRunning()) {
226 ToggleFullscreen(); 229 OnPauseGame();
227 } 230 } else {
228 }); 231 OnStartGame();
232 }
233 }
234 });
235 connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
236 &QShortcut::activated, ui.action_Fullscreen, &QAction::trigger);
237 connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
238 &QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger);
239 connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this),
240 &QShortcut::activated, this, [&] {
241 if (emulation_running) {
242 ui.action_Fullscreen->setChecked(false);
243 ToggleFullscreen();
244 }
245 });
246 connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),
247 &QShortcut::activated, this, [&] {
248 Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit;
249 UpdateStatusBar();
250 });
229} 251}
230 252
231void GMainWindow::SetDefaultUIGeometry() { 253void GMainWindow::SetDefaultUIGeometry() {
@@ -304,7 +326,8 @@ void GMainWindow::ConnectMenuEvents() {
304 connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); 326 connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible);
305 327
306 // Fullscreen 328 // Fullscreen
307 ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key()); 329 ui.action_Fullscreen->setShortcut(
330 hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
308 connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); 331 connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
309 332
310 // Help 333 // Help
@@ -386,7 +409,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
386 409
387 system.SetGPUDebugContext(debug_context); 410 system.SetGPUDebugContext(debug_context);
388 411
389 const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; 412 const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
390 413
391 render_window->DoneCurrent(); 414 render_window->DoneCurrent();
392 415
@@ -408,18 +431,49 @@ bool GMainWindow::LoadROM(const QString& filename) {
408 tr("Could not determine the system mode.")); 431 tr("Could not determine the system mode."));
409 break; 432 break;
410 433
411 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: { 434 case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: {
435 const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false);
436 const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true);
437
438 std::string file_text;
439
440 if (!reg_found && !title_found) {
441 file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be "
442 "found. You will need to dump your keys from your switch to continue.";
443 } else if (reg_found && title_found) {
444 file_text =
445 "Both key files were found in your config directory, but the correct key could"
446 "not be found. You may be missing a titlekey or general key, depending on "
447 "the game.";
448 } else if (reg_found) {
449 file_text =
450 "The regular keys file (prod.keys/dev.keys) was found in your config, but the "
451 "titlekeys file (title.keys) was not. You are either missing the correct "
452 "titlekey or missing a general key required to decrypt the game.";
453 } else {
454 file_text = "The title keys file (title.keys) was found in your config, but "
455 "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, "
456 "having the titlekey is not enough, you need additional general keys "
457 "to properly decrypt the game. You should double-check to make sure "
458 "your keys are correct.";
459 }
460
412 QMessageBox::critical( 461 QMessageBox::critical(
413 this, tr("Error while loading ROM!"), 462 this, tr("Error while loading ROM!"),
414 tr("The game that you are trying to load must be decrypted before being used with " 463 tr(("The game you are trying to load is encrypted and the required keys to load "
415 "yuzu. A real Switch is required.<br/><br/>" 464 "the game could not be found in your configuration. " +
416 "For more information on dumping and decrypting games, please see the following " 465 file_text + " Please refer to the yuzu wiki for help.")
417 "wiki pages: <ul>" 466 .c_str()));
418 "<li><a href='https://yuzu-emu.org/wiki/dumping-game-cartridges/'>Dumping Game " 467 break;
419 "Cartridges</a></li>" 468 }
420 "<li><a href='https://yuzu-emu.org/wiki/dumping-installed-titles/'>Dumping " 469 case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: {
421 "Installed Titles</a></li>" 470 QMessageBox::critical(
422 "</ul>")); 471 this, tr("Error while loading ROM!"),
472 tr("There was a general error while decrypting the game. This means that the keys "
473 "necessary were found, but were either incorrect, the game itself was not a "
474 "valid game or the game uses an unhandled cryptographic scheme. Please double "
475 "check that you have the correct "
476 "keys."));
423 break; 477 break;
424 } 478 }
425 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: 479 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
@@ -429,7 +483,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
429 483
430 case Core::System::ResultStatus::ErrorVideoCore: 484 case Core::System::ResultStatus::ErrorVideoCore:
431 QMessageBox::critical( 485 QMessageBox::critical(
432 this, tr("An error occured in the video core."), 486 this, tr("An error occurred initializing the video core."),
433 tr("yuzu has encountered an error while running the video core, please see the " 487 tr("yuzu has encountered an error while running the video core, please see the "
434 "log for more details." 488 "log for more details."
435 "For more information on accessing the log, please see the following page: " 489 "For more information on accessing the log, please see the following page: "
@@ -443,7 +497,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
443 default: 497 default:
444 QMessageBox::critical( 498 QMessageBox::critical(
445 this, tr("Error while loading ROM!"), 499 this, tr("Error while loading ROM!"),
446 tr("An unknown error occured. Please see the log for more details.")); 500 tr("An unknown error occurred. Please see the log for more details."));
447 break; 501 break;
448 } 502 }
449 return false; 503 return false;
@@ -531,11 +585,11 @@ void GMainWindow::StoreRecentFile(const QString& filename) {
531} 585}
532 586
533void GMainWindow::UpdateRecentFiles() { 587void GMainWindow::UpdateRecentFiles() {
534 unsigned int num_recent_files = 588 const int num_recent_files =
535 std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item)); 589 std::min(UISettings::values.recent_files.size(), max_recent_files_item);
536 590
537 for (unsigned int i = 0; i < num_recent_files; i++) { 591 for (int i = 0; i < num_recent_files; i++) {
538 QString text = QString("&%1. %2").arg(i + 1).arg( 592 const QString text = QString("&%1. %2").arg(i + 1).arg(
539 QFileInfo(UISettings::values.recent_files[i]).fileName()); 593 QFileInfo(UISettings::values.recent_files[i]).fileName());
540 actions_recent_files[i]->setText(text); 594 actions_recent_files[i]->setText(text);
541 actions_recent_files[i]->setData(UISettings::values.recent_files[i]); 595 actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
@@ -547,12 +601,8 @@ void GMainWindow::UpdateRecentFiles() {
547 actions_recent_files[j]->setVisible(false); 601 actions_recent_files[j]->setVisible(false);
548 } 602 }
549 603
550 // Grey out the recent files menu if the list is empty 604 // Enable the recent files menu if the list isn't empty
551 if (num_recent_files == 0) { 605 ui.menu_recent_files->setEnabled(num_recent_files != 0);
552 ui.menu_recent_files->setEnabled(false);
553 } else {
554 ui.menu_recent_files->setEnabled(true);
555 }
556} 606}
557 607
558void GMainWindow::OnGameListLoadFile(QString game_path) { 608void GMainWindow::OnGameListLoadFile(QString game_path) {
@@ -583,9 +633,15 @@ void GMainWindow::OnMenuLoadFile() {
583} 633}
584 634
585void GMainWindow::OnMenuLoadFolder() { 635void GMainWindow::OnMenuLoadFolder() {
586 QDir dir = QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); 636 const QString dir_path =
637 QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory"));
638
639 if (dir_path.isNull()) {
640 return;
641 }
587 642
588 QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); 643 const QDir dir{dir_path};
644 const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
589 if (matching_main.size() == 1) { 645 if (matching_main.size() == 1) {
590 BootGame(dir.path() + DIR_SEP + matching_main[0]); 646 BootGame(dir.path() + DIR_SEP + matching_main[0]);
591 } else { 647 } else {
@@ -606,9 +662,8 @@ void GMainWindow::OnMenuRecentFile() {
606 QAction* action = qobject_cast<QAction*>(sender()); 662 QAction* action = qobject_cast<QAction*>(sender());
607 assert(action); 663 assert(action);
608 664
609 QString filename = action->data().toString(); 665 const QString filename = action->data().toString();
610 QFileInfo file_info(filename); 666 if (QFileInfo::exists(filename)) {
611 if (file_info.exists()) {
612 BootGame(filename); 667 BootGame(filename);
613 } else { 668 } else {
614 // Display an error message and remove the file from the list. 669 // Display an error message and remove the file from the list.
@@ -706,11 +761,13 @@ void GMainWindow::ToggleWindowMode() {
706} 761}
707 762
708void GMainWindow::OnConfigure() { 763void GMainWindow::OnConfigure() {
709 ConfigureDialog configureDialog(this); 764 ConfigureDialog configureDialog(this, hotkey_registry);
765 auto old_theme = UISettings::values.theme;
710 auto result = configureDialog.exec(); 766 auto result = configureDialog.exec();
711 if (result == QDialog::Accepted) { 767 if (result == QDialog::Accepted) {
712 configureDialog.applyConfiguration(); 768 configureDialog.applyConfiguration();
713 UpdateUITheme(); 769 if (UISettings::values.theme != old_theme)
770 UpdateUITheme();
714 config->Save(); 771 config->Save();
715 } 772 }
716} 773}
@@ -843,7 +900,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
843 UISettings::values.first_start = false; 900 UISettings::values.first_start = false;
844 901
845 game_list->SaveInterfaceLayout(); 902 game_list->SaveInterfaceLayout();
846 SaveHotkeys(); 903 hotkey_registry.SaveHotkeys();
847 904
848 // Shutdown session if the emu thread is active... 905 // Shutdown session if the emu thread is active...
849 if (emu_thread != nullptr) 906 if (emu_thread != nullptr)
@@ -897,15 +954,14 @@ void GMainWindow::UpdateUITheme() {
897 QStringList theme_paths(default_theme_paths); 954 QStringList theme_paths(default_theme_paths);
898 if (UISettings::values.theme != UISettings::themes[0].second && 955 if (UISettings::values.theme != UISettings::themes[0].second &&
899 !UISettings::values.theme.isEmpty()) { 956 !UISettings::values.theme.isEmpty()) {
900 QString theme_uri(":" + UISettings::values.theme + "/style.qss"); 957 const QString theme_uri(":" + UISettings::values.theme + "/style.qss");
901 QFile f(theme_uri); 958 QFile f(theme_uri);
902 if (!f.exists()) { 959 if (f.open(QFile::ReadOnly | QFile::Text)) {
903 LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
904 } else {
905 f.open(QFile::ReadOnly | QFile::Text);
906 QTextStream ts(&f); 960 QTextStream ts(&f);
907 qApp->setStyleSheet(ts.readAll()); 961 qApp->setStyleSheet(ts.readAll());
908 GMainWindow::setStyleSheet(ts.readAll()); 962 GMainWindow::setStyleSheet(ts.readAll());
963 } else {
964 LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
909 } 965 }
910 theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme}); 966 theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme});
911 QIcon::setThemeName(":/icons/" + UISettings::values.theme); 967 QIcon::setThemeName(":/icons/" + UISettings::values.theme);
@@ -941,7 +997,6 @@ int main(int argc, char* argv[]) {
941 QCoreApplication::setOrganizationName("yuzu team"); 997 QCoreApplication::setOrganizationName("yuzu team");
942 QCoreApplication::setApplicationName("yuzu"); 998 QCoreApplication::setApplicationName("yuzu");
943 999
944 QApplication::setAttribute(Qt::AA_X11InitThreads);
945 QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); 1000 QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
946 QApplication app(argc, argv); 1001 QApplication app(argc, argv);
947 1002
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 @@
9#include <QTimer> 9#include <QTimer>
10#include "core/core.h" 10#include "core/core.h"
11#include "ui_main.h" 11#include "ui_main.h"
12#include "yuzu/hotkeys.h"
12 13
13class Config; 14class Config;
14class EmuThread; 15class EmuThread;
@@ -43,7 +44,7 @@ public:
43 void filterBarSetChecked(bool state); 44 void filterBarSetChecked(bool state);
44 void UpdateUITheme(); 45 void UpdateUITheme();
45 GMainWindow(); 46 GMainWindow();
46 ~GMainWindow(); 47 ~GMainWindow() override;
47 48
48signals: 49signals:
49 50
@@ -172,6 +173,8 @@ private:
172 // stores default icon theme search paths for the platform 173 // stores default icon theme search paths for the platform
173 QStringList default_theme_paths; 174 QStringList default_theme_paths;
174 175
176 HotkeyRegistry hotkey_registry;
177
175protected: 178protected:
176 void dropEvent(QDropEvent* event) override; 179 void dropEvent(QDropEvent* event) override;
177 void dragEnterEvent(QDragEnterEvent* event) override; 180 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() {
105 Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); 105 Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0);
106 Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); 106 Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0);
107 107
108 // Audio
109 Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
110 Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
111 Settings::values.volume = sdl2_config->GetReal("Audio", "volume", 1);
112
108 // Data Storage 113 // Data Storage
109 Settings::values.use_virtual_sd = 114 Settings::values.use_virtual_sd =
110 sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); 115 sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
@@ -114,6 +119,7 @@ void Config::ReadValues() {
114 119
115 // Miscellaneous 120 // Miscellaneous
116 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); 121 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
122 Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false);
117 123
118 // Debugging 124 // Debugging
119 Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); 125 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 =
143 143
144[Audio] 144[Audio]
145# Which audio output engine to use. 145# Which audio output engine to use.
146# auto (default): Auto-select, null: No audio output, sdl2: SDL2 (if available) 146# auto (default): Auto-select, null: No audio output, cubeb: Cubeb audio engine (if available)
147output_engine = 147output_engine =
148 148
149# Whether or not to enable the audio-stretching post-processing effect.
150# This effect adjusts audio speed to match emulation speed and helps prevent audio stutter,
151# at the cost of increasing audio latency.
152# 0: No, 1 (default): Yes
153enable_audio_stretching =
154
155# Which audio device to use. 149# Which audio device to use.
156# auto (default): Auto-select 150# auto (default): Auto-select
157output_device = 151output_device =
158 152
153# Output volume.
154# 1.0 (default): 100%, 0.0; mute
155volume =
156
159[Data Storage] 157[Data Storage]
160# Whether to create a virtual SD card. 158# Whether to create a virtual SD card.
161# 1 (default): Yes, 0: No 159# 1 (default): Yes, 0: No
@@ -166,6 +164,16 @@ use_virtual_sd =
166# 1: Yes, 0 (default): No 164# 1: Yes, 0 (default): No
167use_docked_mode = 165use_docked_mode =
168 166
167# Sets the account username, max length is 32 characters
168# yuzu (default)
169username =
170
171# Sets the systems language index
172# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
173# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
174# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
175language_index =
176
169# The system region that yuzu will use during emulation 177# The system region that yuzu will use during emulation
170# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan 178# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
171region_value = 179region_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 @@
23#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 23#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
24 24
25#include <getopt.h> 25#include <getopt.h>
26#include "core/crypto/key_manager.h"
26#ifndef _MSC_VER 27#ifndef _MSC_VER
27#include <unistd.h> 28#include <unistd.h>
28#endif 29#endif
@@ -71,6 +72,7 @@ static void InitializeLogging() {
71/// Application entry point 72/// Application entry point
72int main(int argc, char** argv) { 73int main(int argc, char** argv) {
73 Config config; 74 Config config;
75
74 int option_index = 0; 76 int option_index = 0;
75 bool use_gdbstub = Settings::values.use_gdbstub; 77 bool use_gdbstub = Settings::values.use_gdbstub;
76 u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); 78 u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port);
@@ -162,7 +164,7 @@ int main(int argc, char** argv) {
162 164
163 SCOPE_EXIT({ system.Shutdown(); }); 165 SCOPE_EXIT({ system.Shutdown(); });
164 166
165 const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)}; 167 const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)};
166 168
167 switch (load_result) { 169 switch (load_result) {
168 case Core::System::ResultStatus::ErrorGetLoader: 170 case Core::System::ResultStatus::ErrorGetLoader:
@@ -171,11 +173,15 @@ int main(int argc, char** argv) {
171 case Core::System::ResultStatus::ErrorLoader: 173 case Core::System::ResultStatus::ErrorLoader:
172 LOG_CRITICAL(Frontend, "Failed to load ROM!"); 174 LOG_CRITICAL(Frontend, "Failed to load ROM!");
173 return -1; 175 return -1;
174 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: 176 case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys:
175 LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " 177 LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required "
176 "being used with yuzu. \n\n For more information on dumping and " 178 "could not be found. Please refer to the yuzu wiki for help");
177 "decrypting games, please refer to: " 179 return -1;
178 "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); 180 case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting:
181 LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a "
182 "general error while decrypting. This could mean that the keys are "
183 "incorrect, game is invalid or game uses an unsupported method of "
184 "crypto. Please double-check your keys");
179 return -1; 185 return -1;
180 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: 186 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
181 LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); 187 LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported.");
@@ -187,7 +193,7 @@ int main(int argc, char** argv) {
187 LOG_CRITICAL(Frontend, "Failed to determine system mode!"); 193 LOG_CRITICAL(Frontend, "Failed to determine system mode!");
188 return -1; 194 return -1;
189 case Core::System::ResultStatus::ErrorVideoCore: 195 case Core::System::ResultStatus::ErrorVideoCore:
190 LOG_CRITICAL(Frontend, "VideoCore not initialized"); 196 LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!");
191 return -1; 197 return -1;
192 case Core::System::ResultStatus::Success: 198 case Core::System::ResultStatus::Success:
193 break; // Expected case 199 break; // Expected case