From b5d6f645bd67633f54b96aa0bd500ca750d17e1e Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Mon, 27 Mar 2023 14:29:17 +0300 Subject: [PATCH] Prepare frontend for multiple graphics APIs (#6347) * externals: Update dynarmic * settings: Introduce GraphicsAPI enum * For now it's OpenGL only but will be expanded upon later * citra_qt: Introduce backend agnostic context management * Mostly a direct port from yuzu * core: Simplify context acquire * settings: Add option to create debug contexts * renderer_opengl: Abstract initialization to Driver * This commit also updates glad and adds some useful extensions which we will use in part 2 * Rasterizer construction is moved to the specific renderer instead of RendererBase. Software rendering has been disable to achieve this but will be brought back in the next commit. * video_core: Remove Init/Shutdown methods from renderer * The constructor and destructor can do the same job * In addition move opengl function loading to Qt since SDL already does this. Also remove ErrorVideoCore which is never reached * citra_qt: Decouple software renderer from opengl part 1 * citra: Decouple software renderer from opengl part 2 * android: Decouple software renderer from opengl part 3 * swrasterizer: Decouple software renderer from opengl part 4 * This commit simply enforces the renderer naming conventions in the software renderer * video_core: Move RendererBase to VideoCore * video_core: De-globalize screenshot state * video_core: Pass system to the renderers * video_core: Commonize shader uniform data * video_core: Abstract backend agnostic rasterizer operations * bootmanager: Remove references to OpenGL for macOS OpenGL macOS headers definitions clash heavily with each other * citra_qt: Proper title for api settings * video_core: Reduce boost usage * bootmanager: Fix hide mouse option Remove event handlers from RenderWidget for events that are already handled by the parent GRenderWindow. Also enable mouse tracking on the RenderWidget. * android: Remove software from graphics api list * code: Address review comments * citra: Port per-game settings read * Having to update the default value for all backends is a pain so lets centralize it * android: Rename to OpenGLES --------- Co-authored-by: MerryMage Co-authored-by: Vitor Kiguchi --- externals/dynarmic | 2 +- externals/glad/Readme.md | 2 +- externals/glad/include/glad/glad.h | 1614 +---------------- externals/glad/src/glad.c | 776 +------- .../org/citra/citra_emu/NativeLibrary.java | 3 - .../ui/SettingsFragmentPresenter.java | 6 +- .../features/settings/utils/SettingsFile.java | 3 +- src/android/app/src/main/jni/config.cpp | 150 +- src/android/app/src/main/jni/config.h | 11 + src/android/app/src/main/jni/default_ini.h | 20 +- src/android/app/src/main/jni/native.cpp | 12 +- .../app/src/main/res/values-de/strings.xml | 2 - .../app/src/main/res/values-es/strings.xml | 2 - .../app/src/main/res/values-fi/strings.xml | 2 - .../app/src/main/res/values-fr/strings.xml | 2 - .../app/src/main/res/values-it/strings.xml | 2 - .../app/src/main/res/values-ja/strings.xml | 2 - .../app/src/main/res/values-ko/strings.xml | 2 - .../app/src/main/res/values-nb/strings.xml | 2 - .../app/src/main/res/values-pt/strings.xml | 2 - .../app/src/main/res/values-zh/strings.xml | 2 - .../app/src/main/res/values/arrays.xml | 8 + .../app/src/main/res/values/strings.xml | 5 +- src/citra/CMakeLists.txt | 4 + src/citra/citra.cpp | 29 +- src/citra/config.cpp | 172 +- src/citra/config.h | 11 + src/citra/default_ini.h | 14 +- src/citra/emu_window/emu_window_sdl2.cpp | 127 +- src/citra/emu_window/emu_window_sdl2.h | 50 +- src/citra/emu_window/emu_window_sdl2_gl.cpp | 152 ++ src/citra/emu_window/emu_window_sdl2_gl.h | 35 + src/citra/emu_window/emu_window_sdl2_sw.cpp | 127 ++ src/citra/emu_window/emu_window_sdl2_sw.h | 32 + src/citra_qt/CMakeLists.txt | 8 + src/citra_qt/bootmanager.cpp | 489 +++-- src/citra_qt/bootmanager.h | 56 +- src/citra_qt/configuration/config.cpp | 6 +- .../configuration/configuration_shared.h | 15 + .../configuration/configure_debug.cpp | 3 + src/citra_qt/configuration/configure_debug.h | 1 + src/citra_qt/configuration/configure_debug.ui | 35 +- .../configuration/configure_enhancements.cpp | 4 +- .../configuration/configure_graphics.cpp | 50 +- .../configuration/configure_graphics.h | 2 +- .../configuration/configure_graphics.ui | 64 +- src/citra_qt/main.cpp | 43 +- src/common/common_funcs.h | 54 + src/common/settings.cpp | 18 +- src/common/settings.h | 8 +- src/core/CMakeLists.txt | 2 - src/core/core.cpp | 14 +- src/core/core.h | 15 +- src/core/frontend/emu_window.h | 62 +- src/core/frontend/scope_acquire_context.cpp | 17 - src/core/frontend/scope_acquire_context.h | 23 - src/core/telemetry_session.cpp | 4 +- src/video_core/CMakeLists.txt | 36 +- src/video_core/rasterizer_accelerated.cpp | 832 +++++++++ src/video_core/rasterizer_accelerated.h | 159 ++ src/video_core/renderer_base.cpp | 52 +- src/video_core/renderer_base.h | 73 +- .../renderer_opengl/frame_dumper_opengl.cpp | 3 +- src/video_core/renderer_opengl/gl_driver.cpp | 156 ++ src/video_core/renderer_opengl/gl_driver.h | 114 ++ .../renderer_opengl/gl_rasterizer.cpp | 905 +-------- .../renderer_opengl/gl_rasterizer.h | 171 +- .../renderer_opengl/gl_shader_gen.cpp | 49 +- .../renderer_opengl/gl_shader_manager.cpp | 63 +- .../renderer_opengl/gl_shader_manager.h | 88 +- .../renderer_opengl/gl_stream_buffer.cpp | 10 +- .../renderer_opengl/gl_stream_buffer.h | 5 +- .../renderer_opengl/renderer_opengl.cpp | 142 +- .../renderer_opengl/renderer_opengl.h | 37 +- .../rasterizer.cpp | 10 +- .../rasterizer.h | 0 .../renderer_software/renderer_software.cpp | 19 + .../renderer_software/renderer_software.h | 33 + .../sw_clipper.cpp} | 4 +- .../sw_clipper.h} | 0 .../sw_framebuffer.cpp} | 2 +- .../sw_framebuffer.h} | 0 .../sw_lighting.cpp} | 2 +- .../sw_lighting.h} | 0 .../sw_proctex.cpp} | 2 +- .../sw_proctex.h} | 0 .../renderer_software/sw_rasterizer.cpp | 16 + .../sw_rasterizer.h} | 2 +- .../sw_texturing.cpp} | 2 +- .../sw_texturing.h} | 0 src/video_core/shader/shader.cpp | 4 +- src/video_core/shader/shader.h | 9 +- src/video_core/shader/shader_interpreter.cpp | 3 +- src/video_core/shader/shader_uniforms.cpp | 78 + src/video_core/shader/shader_uniforms.h | 101 ++ src/video_core/swrasterizer/swrasterizer.cpp | 16 - src/video_core/vertex_loader.cpp | 3 +- src/video_core/video_core.cpp | 61 +- src/video_core/video_core.h | 26 +- 99 files changed, 3165 insertions(+), 4501 deletions(-) create mode 100644 src/citra/emu_window/emu_window_sdl2_gl.cpp create mode 100644 src/citra/emu_window/emu_window_sdl2_gl.h create mode 100644 src/citra/emu_window/emu_window_sdl2_sw.cpp create mode 100644 src/citra/emu_window/emu_window_sdl2_sw.h delete mode 100644 src/core/frontend/scope_acquire_context.cpp delete mode 100644 src/core/frontend/scope_acquire_context.h create mode 100644 src/video_core/rasterizer_accelerated.cpp create mode 100644 src/video_core/rasterizer_accelerated.h create mode 100644 src/video_core/renderer_opengl/gl_driver.cpp create mode 100644 src/video_core/renderer_opengl/gl_driver.h rename src/video_core/{swrasterizer => renderer_software}/rasterizer.cpp (99%) rename src/video_core/{swrasterizer => renderer_software}/rasterizer.h (100%) create mode 100644 src/video_core/renderer_software/renderer_software.cpp create mode 100644 src/video_core/renderer_software/renderer_software.h rename src/video_core/{swrasterizer/clipper.cpp => renderer_software/sw_clipper.cpp} (98%) rename src/video_core/{swrasterizer/clipper.h => renderer_software/sw_clipper.h} (100%) rename src/video_core/{swrasterizer/framebuffer.cpp => renderer_software/sw_framebuffer.cpp} (99%) rename src/video_core/{swrasterizer/framebuffer.h => renderer_software/sw_framebuffer.h} (100%) rename src/video_core/{swrasterizer/lighting.cpp => renderer_software/sw_lighting.cpp} (99%) rename src/video_core/{swrasterizer/lighting.h => renderer_software/sw_lighting.h} (100%) rename src/video_core/{swrasterizer/proctex.cpp => renderer_software/sw_proctex.cpp} (99%) rename src/video_core/{swrasterizer/proctex.h => renderer_software/sw_proctex.h} (100%) create mode 100644 src/video_core/renderer_software/sw_rasterizer.cpp rename src/video_core/{swrasterizer/swrasterizer.h => renderer_software/sw_rasterizer.h} (93%) rename src/video_core/{swrasterizer/texturing.cpp => renderer_software/sw_texturing.cpp} (99%) rename src/video_core/{swrasterizer/texturing.h => renderer_software/sw_texturing.h} (100%) create mode 100644 src/video_core/shader/shader_uniforms.cpp create mode 100644 src/video_core/shader/shader_uniforms.h delete mode 100644 src/video_core/swrasterizer/swrasterizer.cpp diff --git a/externals/dynarmic b/externals/dynarmic index 9af4b970d..b3a92ab54 160000 --- a/externals/dynarmic +++ b/externals/dynarmic @@ -1 +1 @@ -Subproject commit 9af4b970d302389829448a30608c7cb4fce9b662 +Subproject commit b3a92ab54dadd26a0c2a87d2677b80249d2e1a5a diff --git a/externals/glad/Readme.md b/externals/glad/Readme.md index f2173d1af..5c16ed29e 100644 --- a/externals/glad/Readme.md +++ b/externals/glad/Readme.md @@ -1,5 +1,5 @@ These files were generated by the [glad](https://github.com/Dav1dde/glad) OpenGL loader generator and have been checked in as-is. You can re-generate them using glad with the following command: ``` -python -m glad --profile core --out-path glad/ --api "gl=3.3,gles2=3.2" --generator=c +python -m glad --profile core --out-path glad/ --api "gl=4.6,gles2=3.2" --generator=c ``` diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h index 4104ae9c2..d2fc37740 100644 --- a/externals/glad/include/glad/glad.h +++ b/externals/glad/include/glad/glad.h @@ -1,24 +1,26 @@ /* - OpenGL, OpenGL ES loader generated by glad 0.1.36 on Mon Aug 22 20:31:42 2022. + OpenGL, OpenGL ES loader generated by glad 0.1.36 on Sun Mar 12 10:25:27 2023. Language/Generator: C/C++ Specification: gl APIs: gl=4.6, gles2=3.2 - Profile: compatibility + Profile: core Extensions: GL_ARB_buffer_storage, - GL_EXT_clip_cull_distance, - GL_KHR_debug + GL_ARB_clear_texture, + GL_ARB_get_texture_sub_image, + GL_EXT_buffer_storage, + GL_EXT_clip_cull_distance Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="compatibility" --api="gl=4.6,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_EXT_clip_cull_distance,GL_KHR_debug" + --profile="core" --api="gl=4.6,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_get_texture_sub_image,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance" Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D4.6&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_KHR_debug + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.6&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_get_texture_sub_image&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance */ @@ -159,7 +161,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 @@ -268,8 +269,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 #define GL_CLEAR 0x1500 #define GL_AND 0x1501 #define GL_AND_REVERSE 0x1502 @@ -320,257 +319,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 #define GL_REPEAT 0x2901 -#define GL_CURRENT_BIT 0x00000001 -#define GL_POINT_BIT 0x00000002 -#define GL_LINE_BIT 0x00000004 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_HINT_BIT 0x00008000 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON 0x0009 -#define GL_ACCUM 0x0100 -#define GL_LOAD 0x0101 -#define GL_RETURN 0x0102 -#define GL_MULT 0x0103 -#define GL_ADD 0x0104 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_POINT_SMOOTH 0x0B10 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LIST_MODE 0x0B30 -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_SHADE_MODEL 0x0B54 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_FOG 0x0B60 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_COLOR 0x0B66 -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_MATRIX_MODE 0x0BA0 -#define GL_NORMALIZE 0x0BA1 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_FUNC 0x0BC1 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_LOGIC_OP 0x0BF1 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_INDEX_MODE 0x0C30 -#define GL_RGBA_MODE 0x0C31 -#define GL_RENDER_MODE 0x0C40 -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_FOG_HINT 0x0C54 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_INDEX_BITS 0x0D51 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_EMISSION 0x1600 -#define GL_SHININESS 0x1601 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_COLOR_INDEX 0x1900 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_BITMAP 0x1A00 -#define GL_RENDER 0x1C00 -#define GL_FEEDBACK 0x1C01 -#define GL_SELECT 0x1C02 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_S 0x2000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_MODULATE 0x2100 -#define GL_DECAL 0x2101 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_ENV 0x2300 -#define GL_EYE_LINEAR 0x2400 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_SPHERE_MAP 0x2402 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_PLANE 0x2502 -#define GL_CLAMP 0x2900 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 #define GL_COLOR_LOGIC_OP 0x0BF2 #define GL_POLYGON_OFFSET_UNITS 0x2A00 #define GL_POLYGON_OFFSET_POINT 0x2A01 @@ -601,80 +349,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_RGB10_A2 0x8059 #define GL_RGBA12 0x805A #define GL_RGBA16 0x805B -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 @@ -711,11 +385,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_RESCALE_NORMAL 0x803A -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 @@ -775,43 +444,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA @@ -828,29 +460,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_COMPARE_R_TO_TEXTURE 0x884E #define GL_BLEND_COLOR 0x8005 #define GL_BLEND_EQUATION 0x8009 #define GL_CONSTANT_COLOR 0x8001 @@ -890,28 +499,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #define GL_SRC1_ALPHA 0x8589 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_COORD 0x8451 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_RGB 0x8582 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC2_ALPHA 0x858A #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 @@ -992,10 +579,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_TEXTURE_COORDS 0x8871 #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED @@ -1012,13 +595,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_SRGB8_ALPHA8 0x8C43 #define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B #define GL_COMPARE_REF_TO_TEXTURE 0x884E #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 @@ -1215,9 +791,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #define GL_FRAMEBUFFER_SRGB 0x8DB9 #define GL_HALF_FLOAT 0x140B #define GL_MAP_READ_BIT 0x0001 @@ -1253,9 +826,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_ALPHA_INTEGER 0x8D97 #define GL_SAMPLER_2D_RECT 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 #define GL_SAMPLER_BUFFER 0x8DC2 @@ -1447,6 +1017,7 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_TESS_GEN_VERTEX_ORDER 0x8E78 #define GL_TESS_GEN_POINT_MODE 0x8E79 #define GL_ISOLINES 0x8E7A +#define GL_QUADS 0x0007 #define GL_FRACTIONAL_ODD 0x8E7B #define GL_FRACTIONAL_EVEN 0x8E7C #define GL_MAX_PATCH_VERTICES 0x8E7D @@ -1685,6 +1256,7 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_BUFFER 0x82E0 #define GL_SHADER 0x82E1 #define GL_PROGRAM 0x82E2 +#define GL_VERTEX_ARRAY 0x8074 #define GL_QUERY 0x82E3 #define GL_PROGRAM_PIPELINE 0x82E4 #define GL_SAMPLER 0x82E6 @@ -1880,6 +1452,8 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA #define GL_VERTEX_BINDING_BUFFER 0x8F4F #define GL_DISPLAY_LIST 0x82E7 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STACK_OVERFLOW 0x0503 #define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 #define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 #define GL_TEXTURE_BUFFER_BINDING 0x8C2A @@ -1955,6 +1529,16 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF #define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC #define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 #define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381 #define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382 @@ -2149,780 +1733,6 @@ GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); GLAPI PFNGLVIEWPORTPROC glad_glViewport; #define glViewport glad_glViewport -typedef void (APIENTRYP PFNGLNEWLISTPROC)(GLuint list, GLenum mode); -GLAPI PFNGLNEWLISTPROC glad_glNewList; -#define glNewList glad_glNewList -typedef void (APIENTRYP PFNGLENDLISTPROC)(void); -GLAPI PFNGLENDLISTPROC glad_glEndList; -#define glEndList glad_glEndList -typedef void (APIENTRYP PFNGLCALLLISTPROC)(GLuint list); -GLAPI PFNGLCALLLISTPROC glad_glCallList; -#define glCallList glad_glCallList -typedef void (APIENTRYP PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void *lists); -GLAPI PFNGLCALLLISTSPROC glad_glCallLists; -#define glCallLists glad_glCallLists -typedef void (APIENTRYP PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); -GLAPI PFNGLDELETELISTSPROC glad_glDeleteLists; -#define glDeleteLists glad_glDeleteLists -typedef GLuint (APIENTRYP PFNGLGENLISTSPROC)(GLsizei range); -GLAPI PFNGLGENLISTSPROC glad_glGenLists; -#define glGenLists glad_glGenLists -typedef void (APIENTRYP PFNGLLISTBASEPROC)(GLuint base); -GLAPI PFNGLLISTBASEPROC glad_glListBase; -#define glListBase glad_glListBase -typedef void (APIENTRYP PFNGLBEGINPROC)(GLenum mode); -GLAPI PFNGLBEGINPROC glad_glBegin; -#define glBegin glad_glBegin -typedef void (APIENTRYP PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); -GLAPI PFNGLBITMAPPROC glad_glBitmap; -#define glBitmap glad_glBitmap -typedef void (APIENTRYP PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -GLAPI PFNGLCOLOR3BPROC glad_glColor3b; -#define glColor3b glad_glColor3b -typedef void (APIENTRYP PFNGLCOLOR3BVPROC)(const GLbyte *v); -GLAPI PFNGLCOLOR3BVPROC glad_glColor3bv; -#define glColor3bv glad_glColor3bv -typedef void (APIENTRYP PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -GLAPI PFNGLCOLOR3DPROC glad_glColor3d; -#define glColor3d glad_glColor3d -typedef void (APIENTRYP PFNGLCOLOR3DVPROC)(const GLdouble *v); -GLAPI PFNGLCOLOR3DVPROC glad_glColor3dv; -#define glColor3dv glad_glColor3dv -typedef void (APIENTRYP PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -GLAPI PFNGLCOLOR3FPROC glad_glColor3f; -#define glColor3f glad_glColor3f -typedef void (APIENTRYP PFNGLCOLOR3FVPROC)(const GLfloat *v); -GLAPI PFNGLCOLOR3FVPROC glad_glColor3fv; -#define glColor3fv glad_glColor3fv -typedef void (APIENTRYP PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); -GLAPI PFNGLCOLOR3IPROC glad_glColor3i; -#define glColor3i glad_glColor3i -typedef void (APIENTRYP PFNGLCOLOR3IVPROC)(const GLint *v); -GLAPI PFNGLCOLOR3IVPROC glad_glColor3iv; -#define glColor3iv glad_glColor3iv -typedef void (APIENTRYP PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -GLAPI PFNGLCOLOR3SPROC glad_glColor3s; -#define glColor3s glad_glColor3s -typedef void (APIENTRYP PFNGLCOLOR3SVPROC)(const GLshort *v); -GLAPI PFNGLCOLOR3SVPROC glad_glColor3sv; -#define glColor3sv glad_glColor3sv -typedef void (APIENTRYP PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -GLAPI PFNGLCOLOR3UBPROC glad_glColor3ub; -#define glColor3ub glad_glColor3ub -typedef void (APIENTRYP PFNGLCOLOR3UBVPROC)(const GLubyte *v); -GLAPI PFNGLCOLOR3UBVPROC glad_glColor3ubv; -#define glColor3ubv glad_glColor3ubv -typedef void (APIENTRYP PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -GLAPI PFNGLCOLOR3UIPROC glad_glColor3ui; -#define glColor3ui glad_glColor3ui -typedef void (APIENTRYP PFNGLCOLOR3UIVPROC)(const GLuint *v); -GLAPI PFNGLCOLOR3UIVPROC glad_glColor3uiv; -#define glColor3uiv glad_glColor3uiv -typedef void (APIENTRYP PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -GLAPI PFNGLCOLOR3USPROC glad_glColor3us; -#define glColor3us glad_glColor3us -typedef void (APIENTRYP PFNGLCOLOR3USVPROC)(const GLushort *v); -GLAPI PFNGLCOLOR3USVPROC glad_glColor3usv; -#define glColor3usv glad_glColor3usv -typedef void (APIENTRYP PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -GLAPI PFNGLCOLOR4BPROC glad_glColor4b; -#define glColor4b glad_glColor4b -typedef void (APIENTRYP PFNGLCOLOR4BVPROC)(const GLbyte *v); -GLAPI PFNGLCOLOR4BVPROC glad_glColor4bv; -#define glColor4bv glad_glColor4bv -typedef void (APIENTRYP PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -GLAPI PFNGLCOLOR4DPROC glad_glColor4d; -#define glColor4d glad_glColor4d -typedef void (APIENTRYP PFNGLCOLOR4DVPROC)(const GLdouble *v); -GLAPI PFNGLCOLOR4DVPROC glad_glColor4dv; -#define glColor4dv glad_glColor4dv -typedef void (APIENTRYP PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCOLOR4FPROC glad_glColor4f; -#define glColor4f glad_glColor4f -typedef void (APIENTRYP PFNGLCOLOR4FVPROC)(const GLfloat *v); -GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv; -#define glColor4fv glad_glColor4fv -typedef void (APIENTRYP PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); -GLAPI PFNGLCOLOR4IPROC glad_glColor4i; -#define glColor4i glad_glColor4i -typedef void (APIENTRYP PFNGLCOLOR4IVPROC)(const GLint *v); -GLAPI PFNGLCOLOR4IVPROC glad_glColor4iv; -#define glColor4iv glad_glColor4iv -typedef void (APIENTRYP PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); -GLAPI PFNGLCOLOR4SPROC glad_glColor4s; -#define glColor4s glad_glColor4s -typedef void (APIENTRYP PFNGLCOLOR4SVPROC)(const GLshort *v); -GLAPI PFNGLCOLOR4SVPROC glad_glColor4sv; -#define glColor4sv glad_glColor4sv -typedef void (APIENTRYP PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -GLAPI PFNGLCOLOR4UBPROC glad_glColor4ub; -#define glColor4ub glad_glColor4ub -typedef void (APIENTRYP PFNGLCOLOR4UBVPROC)(const GLubyte *v); -GLAPI PFNGLCOLOR4UBVPROC glad_glColor4ubv; -#define glColor4ubv glad_glColor4ubv -typedef void (APIENTRYP PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); -GLAPI PFNGLCOLOR4UIPROC glad_glColor4ui; -#define glColor4ui glad_glColor4ui -typedef void (APIENTRYP PFNGLCOLOR4UIVPROC)(const GLuint *v); -GLAPI PFNGLCOLOR4UIVPROC glad_glColor4uiv; -#define glColor4uiv glad_glColor4uiv -typedef void (APIENTRYP PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); -GLAPI PFNGLCOLOR4USPROC glad_glColor4us; -#define glColor4us glad_glColor4us -typedef void (APIENTRYP PFNGLCOLOR4USVPROC)(const GLushort *v); -GLAPI PFNGLCOLOR4USVPROC glad_glColor4usv; -#define glColor4usv glad_glColor4usv -typedef void (APIENTRYP PFNGLEDGEFLAGPROC)(GLboolean flag); -GLAPI PFNGLEDGEFLAGPROC glad_glEdgeFlag; -#define glEdgeFlag glad_glEdgeFlag -typedef void (APIENTRYP PFNGLEDGEFLAGVPROC)(const GLboolean *flag); -GLAPI PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; -#define glEdgeFlagv glad_glEdgeFlagv -typedef void (APIENTRYP PFNGLENDPROC)(void); -GLAPI PFNGLENDPROC glad_glEnd; -#define glEnd glad_glEnd -typedef void (APIENTRYP PFNGLINDEXDPROC)(GLdouble c); -GLAPI PFNGLINDEXDPROC glad_glIndexd; -#define glIndexd glad_glIndexd -typedef void (APIENTRYP PFNGLINDEXDVPROC)(const GLdouble *c); -GLAPI PFNGLINDEXDVPROC glad_glIndexdv; -#define glIndexdv glad_glIndexdv -typedef void (APIENTRYP PFNGLINDEXFPROC)(GLfloat c); -GLAPI PFNGLINDEXFPROC glad_glIndexf; -#define glIndexf glad_glIndexf -typedef void (APIENTRYP PFNGLINDEXFVPROC)(const GLfloat *c); -GLAPI PFNGLINDEXFVPROC glad_glIndexfv; -#define glIndexfv glad_glIndexfv -typedef void (APIENTRYP PFNGLINDEXIPROC)(GLint c); -GLAPI PFNGLINDEXIPROC glad_glIndexi; -#define glIndexi glad_glIndexi -typedef void (APIENTRYP PFNGLINDEXIVPROC)(const GLint *c); -GLAPI PFNGLINDEXIVPROC glad_glIndexiv; -#define glIndexiv glad_glIndexiv -typedef void (APIENTRYP PFNGLINDEXSPROC)(GLshort c); -GLAPI PFNGLINDEXSPROC glad_glIndexs; -#define glIndexs glad_glIndexs -typedef void (APIENTRYP PFNGLINDEXSVPROC)(const GLshort *c); -GLAPI PFNGLINDEXSVPROC glad_glIndexsv; -#define glIndexsv glad_glIndexsv -typedef void (APIENTRYP PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI PFNGLNORMAL3BPROC glad_glNormal3b; -#define glNormal3b glad_glNormal3b -typedef void (APIENTRYP PFNGLNORMAL3BVPROC)(const GLbyte *v); -GLAPI PFNGLNORMAL3BVPROC glad_glNormal3bv; -#define glNormal3bv glad_glNormal3bv -typedef void (APIENTRYP PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI PFNGLNORMAL3DPROC glad_glNormal3d; -#define glNormal3d glad_glNormal3d -typedef void (APIENTRYP PFNGLNORMAL3DVPROC)(const GLdouble *v); -GLAPI PFNGLNORMAL3DVPROC glad_glNormal3dv; -#define glNormal3dv glad_glNormal3dv -typedef void (APIENTRYP PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI PFNGLNORMAL3FPROC glad_glNormal3f; -#define glNormal3f glad_glNormal3f -typedef void (APIENTRYP PFNGLNORMAL3FVPROC)(const GLfloat *v); -GLAPI PFNGLNORMAL3FVPROC glad_glNormal3fv; -#define glNormal3fv glad_glNormal3fv -typedef void (APIENTRYP PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); -GLAPI PFNGLNORMAL3IPROC glad_glNormal3i; -#define glNormal3i glad_glNormal3i -typedef void (APIENTRYP PFNGLNORMAL3IVPROC)(const GLint *v); -GLAPI PFNGLNORMAL3IVPROC glad_glNormal3iv; -#define glNormal3iv glad_glNormal3iv -typedef void (APIENTRYP PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); -GLAPI PFNGLNORMAL3SPROC glad_glNormal3s; -#define glNormal3s glad_glNormal3s -typedef void (APIENTRYP PFNGLNORMAL3SVPROC)(const GLshort *v); -GLAPI PFNGLNORMAL3SVPROC glad_glNormal3sv; -#define glNormal3sv glad_glNormal3sv -typedef void (APIENTRYP PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLRASTERPOS2DPROC glad_glRasterPos2d; -#define glRasterPos2d glad_glRasterPos2d -typedef void (APIENTRYP PFNGLRASTERPOS2DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; -#define glRasterPos2dv glad_glRasterPos2dv -typedef void (APIENTRYP PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLRASTERPOS2FPROC glad_glRasterPos2f; -#define glRasterPos2f glad_glRasterPos2f -typedef void (APIENTRYP PFNGLRASTERPOS2FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; -#define glRasterPos2fv glad_glRasterPos2fv -typedef void (APIENTRYP PFNGLRASTERPOS2IPROC)(GLint x, GLint y); -GLAPI PFNGLRASTERPOS2IPROC glad_glRasterPos2i; -#define glRasterPos2i glad_glRasterPos2i -typedef void (APIENTRYP PFNGLRASTERPOS2IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; -#define glRasterPos2iv glad_glRasterPos2iv -typedef void (APIENTRYP PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLRASTERPOS2SPROC glad_glRasterPos2s; -#define glRasterPos2s glad_glRasterPos2s -typedef void (APIENTRYP PFNGLRASTERPOS2SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; -#define glRasterPos2sv glad_glRasterPos2sv -typedef void (APIENTRYP PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLRASTERPOS3DPROC glad_glRasterPos3d; -#define glRasterPos3d glad_glRasterPos3d -typedef void (APIENTRYP PFNGLRASTERPOS3DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; -#define glRasterPos3dv glad_glRasterPos3dv -typedef void (APIENTRYP PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLRASTERPOS3FPROC glad_glRasterPos3f; -#define glRasterPos3f glad_glRasterPos3f -typedef void (APIENTRYP PFNGLRASTERPOS3FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; -#define glRasterPos3fv glad_glRasterPos3fv -typedef void (APIENTRYP PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLRASTERPOS3IPROC glad_glRasterPos3i; -#define glRasterPos3i glad_glRasterPos3i -typedef void (APIENTRYP PFNGLRASTERPOS3IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; -#define glRasterPos3iv glad_glRasterPos3iv -typedef void (APIENTRYP PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLRASTERPOS3SPROC glad_glRasterPos3s; -#define glRasterPos3s glad_glRasterPos3s -typedef void (APIENTRYP PFNGLRASTERPOS3SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; -#define glRasterPos3sv glad_glRasterPos3sv -typedef void (APIENTRYP PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI PFNGLRASTERPOS4DPROC glad_glRasterPos4d; -#define glRasterPos4d glad_glRasterPos4d -typedef void (APIENTRYP PFNGLRASTERPOS4DVPROC)(const GLdouble *v); -GLAPI PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; -#define glRasterPos4dv glad_glRasterPos4dv -typedef void (APIENTRYP PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLRASTERPOS4FPROC glad_glRasterPos4f; -#define glRasterPos4f glad_glRasterPos4f -typedef void (APIENTRYP PFNGLRASTERPOS4FVPROC)(const GLfloat *v); -GLAPI PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; -#define glRasterPos4fv glad_glRasterPos4fv -typedef void (APIENTRYP PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLRASTERPOS4IPROC glad_glRasterPos4i; -#define glRasterPos4i glad_glRasterPos4i -typedef void (APIENTRYP PFNGLRASTERPOS4IVPROC)(const GLint *v); -GLAPI PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; -#define glRasterPos4iv glad_glRasterPos4iv -typedef void (APIENTRYP PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI PFNGLRASTERPOS4SPROC glad_glRasterPos4s; -#define glRasterPos4s glad_glRasterPos4s -typedef void (APIENTRYP PFNGLRASTERPOS4SVPROC)(const GLshort *v); -GLAPI PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; -#define glRasterPos4sv glad_glRasterPos4sv -typedef void (APIENTRYP PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -GLAPI PFNGLRECTDPROC glad_glRectd; -#define glRectd glad_glRectd -typedef void (APIENTRYP PFNGLRECTDVPROC)(const GLdouble *v1, const GLdouble *v2); -GLAPI PFNGLRECTDVPROC glad_glRectdv; -#define glRectdv glad_glRectdv -typedef void (APIENTRYP PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -GLAPI PFNGLRECTFPROC glad_glRectf; -#define glRectf glad_glRectf -typedef void (APIENTRYP PFNGLRECTFVPROC)(const GLfloat *v1, const GLfloat *v2); -GLAPI PFNGLRECTFVPROC glad_glRectfv; -#define glRectfv glad_glRectfv -typedef void (APIENTRYP PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); -GLAPI PFNGLRECTIPROC glad_glRecti; -#define glRecti glad_glRecti -typedef void (APIENTRYP PFNGLRECTIVPROC)(const GLint *v1, const GLint *v2); -GLAPI PFNGLRECTIVPROC glad_glRectiv; -#define glRectiv glad_glRectiv -typedef void (APIENTRYP PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); -GLAPI PFNGLRECTSPROC glad_glRects; -#define glRects glad_glRects -typedef void (APIENTRYP PFNGLRECTSVPROC)(const GLshort *v1, const GLshort *v2); -GLAPI PFNGLRECTSVPROC glad_glRectsv; -#define glRectsv glad_glRectsv -typedef void (APIENTRYP PFNGLTEXCOORD1DPROC)(GLdouble s); -GLAPI PFNGLTEXCOORD1DPROC glad_glTexCoord1d; -#define glTexCoord1d glad_glTexCoord1d -typedef void (APIENTRYP PFNGLTEXCOORD1DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; -#define glTexCoord1dv glad_glTexCoord1dv -typedef void (APIENTRYP PFNGLTEXCOORD1FPROC)(GLfloat s); -GLAPI PFNGLTEXCOORD1FPROC glad_glTexCoord1f; -#define glTexCoord1f glad_glTexCoord1f -typedef void (APIENTRYP PFNGLTEXCOORD1FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; -#define glTexCoord1fv glad_glTexCoord1fv -typedef void (APIENTRYP PFNGLTEXCOORD1IPROC)(GLint s); -GLAPI PFNGLTEXCOORD1IPROC glad_glTexCoord1i; -#define glTexCoord1i glad_glTexCoord1i -typedef void (APIENTRYP PFNGLTEXCOORD1IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; -#define glTexCoord1iv glad_glTexCoord1iv -typedef void (APIENTRYP PFNGLTEXCOORD1SPROC)(GLshort s); -GLAPI PFNGLTEXCOORD1SPROC glad_glTexCoord1s; -#define glTexCoord1s glad_glTexCoord1s -typedef void (APIENTRYP PFNGLTEXCOORD1SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; -#define glTexCoord1sv glad_glTexCoord1sv -typedef void (APIENTRYP PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); -GLAPI PFNGLTEXCOORD2DPROC glad_glTexCoord2d; -#define glTexCoord2d glad_glTexCoord2d -typedef void (APIENTRYP PFNGLTEXCOORD2DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; -#define glTexCoord2dv glad_glTexCoord2dv -typedef void (APIENTRYP PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); -GLAPI PFNGLTEXCOORD2FPROC glad_glTexCoord2f; -#define glTexCoord2f glad_glTexCoord2f -typedef void (APIENTRYP PFNGLTEXCOORD2FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; -#define glTexCoord2fv glad_glTexCoord2fv -typedef void (APIENTRYP PFNGLTEXCOORD2IPROC)(GLint s, GLint t); -GLAPI PFNGLTEXCOORD2IPROC glad_glTexCoord2i; -#define glTexCoord2i glad_glTexCoord2i -typedef void (APIENTRYP PFNGLTEXCOORD2IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; -#define glTexCoord2iv glad_glTexCoord2iv -typedef void (APIENTRYP PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); -GLAPI PFNGLTEXCOORD2SPROC glad_glTexCoord2s; -#define glTexCoord2s glad_glTexCoord2s -typedef void (APIENTRYP PFNGLTEXCOORD2SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; -#define glTexCoord2sv glad_glTexCoord2sv -typedef void (APIENTRYP PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); -GLAPI PFNGLTEXCOORD3DPROC glad_glTexCoord3d; -#define glTexCoord3d glad_glTexCoord3d -typedef void (APIENTRYP PFNGLTEXCOORD3DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; -#define glTexCoord3dv glad_glTexCoord3dv -typedef void (APIENTRYP PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); -GLAPI PFNGLTEXCOORD3FPROC glad_glTexCoord3f; -#define glTexCoord3f glad_glTexCoord3f -typedef void (APIENTRYP PFNGLTEXCOORD3FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; -#define glTexCoord3fv glad_glTexCoord3fv -typedef void (APIENTRYP PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); -GLAPI PFNGLTEXCOORD3IPROC glad_glTexCoord3i; -#define glTexCoord3i glad_glTexCoord3i -typedef void (APIENTRYP PFNGLTEXCOORD3IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; -#define glTexCoord3iv glad_glTexCoord3iv -typedef void (APIENTRYP PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); -GLAPI PFNGLTEXCOORD3SPROC glad_glTexCoord3s; -#define glTexCoord3s glad_glTexCoord3s -typedef void (APIENTRYP PFNGLTEXCOORD3SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; -#define glTexCoord3sv glad_glTexCoord3sv -typedef void (APIENTRYP PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI PFNGLTEXCOORD4DPROC glad_glTexCoord4d; -#define glTexCoord4d glad_glTexCoord4d -typedef void (APIENTRYP PFNGLTEXCOORD4DVPROC)(const GLdouble *v); -GLAPI PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; -#define glTexCoord4dv glad_glTexCoord4dv -typedef void (APIENTRYP PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI PFNGLTEXCOORD4FPROC glad_glTexCoord4f; -#define glTexCoord4f glad_glTexCoord4f -typedef void (APIENTRYP PFNGLTEXCOORD4FVPROC)(const GLfloat *v); -GLAPI PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; -#define glTexCoord4fv glad_glTexCoord4fv -typedef void (APIENTRYP PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); -GLAPI PFNGLTEXCOORD4IPROC glad_glTexCoord4i; -#define glTexCoord4i glad_glTexCoord4i -typedef void (APIENTRYP PFNGLTEXCOORD4IVPROC)(const GLint *v); -GLAPI PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; -#define glTexCoord4iv glad_glTexCoord4iv -typedef void (APIENTRYP PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI PFNGLTEXCOORD4SPROC glad_glTexCoord4s; -#define glTexCoord4s glad_glTexCoord4s -typedef void (APIENTRYP PFNGLTEXCOORD4SVPROC)(const GLshort *v); -GLAPI PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; -#define glTexCoord4sv glad_glTexCoord4sv -typedef void (APIENTRYP PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLVERTEX2DPROC glad_glVertex2d; -#define glVertex2d glad_glVertex2d -typedef void (APIENTRYP PFNGLVERTEX2DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX2DVPROC glad_glVertex2dv; -#define glVertex2dv glad_glVertex2dv -typedef void (APIENTRYP PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLVERTEX2FPROC glad_glVertex2f; -#define glVertex2f glad_glVertex2f -typedef void (APIENTRYP PFNGLVERTEX2FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX2FVPROC glad_glVertex2fv; -#define glVertex2fv glad_glVertex2fv -typedef void (APIENTRYP PFNGLVERTEX2IPROC)(GLint x, GLint y); -GLAPI PFNGLVERTEX2IPROC glad_glVertex2i; -#define glVertex2i glad_glVertex2i -typedef void (APIENTRYP PFNGLVERTEX2IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX2IVPROC glad_glVertex2iv; -#define glVertex2iv glad_glVertex2iv -typedef void (APIENTRYP PFNGLVERTEX2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLVERTEX2SPROC glad_glVertex2s; -#define glVertex2s glad_glVertex2s -typedef void (APIENTRYP PFNGLVERTEX2SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX2SVPROC glad_glVertex2sv; -#define glVertex2sv glad_glVertex2sv -typedef void (APIENTRYP PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLVERTEX3DPROC glad_glVertex3d; -#define glVertex3d glad_glVertex3d -typedef void (APIENTRYP PFNGLVERTEX3DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX3DVPROC glad_glVertex3dv; -#define glVertex3dv glad_glVertex3dv -typedef void (APIENTRYP PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLVERTEX3FPROC glad_glVertex3f; -#define glVertex3f glad_glVertex3f -typedef void (APIENTRYP PFNGLVERTEX3FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX3FVPROC glad_glVertex3fv; -#define glVertex3fv glad_glVertex3fv -typedef void (APIENTRYP PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLVERTEX3IPROC glad_glVertex3i; -#define glVertex3i glad_glVertex3i -typedef void (APIENTRYP PFNGLVERTEX3IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX3IVPROC glad_glVertex3iv; -#define glVertex3iv glad_glVertex3iv -typedef void (APIENTRYP PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLVERTEX3SPROC glad_glVertex3s; -#define glVertex3s glad_glVertex3s -typedef void (APIENTRYP PFNGLVERTEX3SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX3SVPROC glad_glVertex3sv; -#define glVertex3sv glad_glVertex3sv -typedef void (APIENTRYP PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI PFNGLVERTEX4DPROC glad_glVertex4d; -#define glVertex4d glad_glVertex4d -typedef void (APIENTRYP PFNGLVERTEX4DVPROC)(const GLdouble *v); -GLAPI PFNGLVERTEX4DVPROC glad_glVertex4dv; -#define glVertex4dv glad_glVertex4dv -typedef void (APIENTRYP PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLVERTEX4FPROC glad_glVertex4f; -#define glVertex4f glad_glVertex4f -typedef void (APIENTRYP PFNGLVERTEX4FVPROC)(const GLfloat *v); -GLAPI PFNGLVERTEX4FVPROC glad_glVertex4fv; -#define glVertex4fv glad_glVertex4fv -typedef void (APIENTRYP PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLVERTEX4IPROC glad_glVertex4i; -#define glVertex4i glad_glVertex4i -typedef void (APIENTRYP PFNGLVERTEX4IVPROC)(const GLint *v); -GLAPI PFNGLVERTEX4IVPROC glad_glVertex4iv; -#define glVertex4iv glad_glVertex4iv -typedef void (APIENTRYP PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI PFNGLVERTEX4SPROC glad_glVertex4s; -#define glVertex4s glad_glVertex4s -typedef void (APIENTRYP PFNGLVERTEX4SVPROC)(const GLshort *v); -GLAPI PFNGLVERTEX4SVPROC glad_glVertex4sv; -#define glVertex4sv glad_glVertex4sv -typedef void (APIENTRYP PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble *equation); -GLAPI PFNGLCLIPPLANEPROC glad_glClipPlane; -#define glClipPlane glad_glClipPlane -typedef void (APIENTRYP PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); -GLAPI PFNGLCOLORMATERIALPROC glad_glColorMaterial; -#define glColorMaterial glad_glColorMaterial -typedef void (APIENTRYP PFNGLFOGFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLFOGFPROC glad_glFogf; -#define glFogf glad_glFogf -typedef void (APIENTRYP PFNGLFOGFVPROC)(GLenum pname, const GLfloat *params); -GLAPI PFNGLFOGFVPROC glad_glFogfv; -#define glFogfv glad_glFogfv -typedef void (APIENTRYP PFNGLFOGIPROC)(GLenum pname, GLint param); -GLAPI PFNGLFOGIPROC glad_glFogi; -#define glFogi glad_glFogi -typedef void (APIENTRYP PFNGLFOGIVPROC)(GLenum pname, const GLint *params); -GLAPI PFNGLFOGIVPROC glad_glFogiv; -#define glFogiv glad_glFogiv -typedef void (APIENTRYP PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); -GLAPI PFNGLLIGHTFPROC glad_glLightf; -#define glLightf glad_glLightf -typedef void (APIENTRYP PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat *params); -GLAPI PFNGLLIGHTFVPROC glad_glLightfv; -#define glLightfv glad_glLightfv -typedef void (APIENTRYP PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); -GLAPI PFNGLLIGHTIPROC glad_glLighti; -#define glLighti glad_glLighti -typedef void (APIENTRYP PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint *params); -GLAPI PFNGLLIGHTIVPROC glad_glLightiv; -#define glLightiv glad_glLightiv -typedef void (APIENTRYP PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLLIGHTMODELFPROC glad_glLightModelf; -#define glLightModelf glad_glLightModelf -typedef void (APIENTRYP PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat *params); -GLAPI PFNGLLIGHTMODELFVPROC glad_glLightModelfv; -#define glLightModelfv glad_glLightModelfv -typedef void (APIENTRYP PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); -GLAPI PFNGLLIGHTMODELIPROC glad_glLightModeli; -#define glLightModeli glad_glLightModeli -typedef void (APIENTRYP PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint *params); -GLAPI PFNGLLIGHTMODELIVPROC glad_glLightModeliv; -#define glLightModeliv glad_glLightModeliv -typedef void (APIENTRYP PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); -GLAPI PFNGLLINESTIPPLEPROC glad_glLineStipple; -#define glLineStipple glad_glLineStipple -typedef void (APIENTRYP PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); -GLAPI PFNGLMATERIALFPROC glad_glMaterialf; -#define glMaterialf glad_glMaterialf -typedef void (APIENTRYP PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat *params); -GLAPI PFNGLMATERIALFVPROC glad_glMaterialfv; -#define glMaterialfv glad_glMaterialfv -typedef void (APIENTRYP PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); -GLAPI PFNGLMATERIALIPROC glad_glMateriali; -#define glMateriali glad_glMateriali -typedef void (APIENTRYP PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint *params); -GLAPI PFNGLMATERIALIVPROC glad_glMaterialiv; -#define glMaterialiv glad_glMaterialiv -typedef void (APIENTRYP PFNGLPOLYGONSTIPPLEPROC)(const GLubyte *mask); -GLAPI PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; -#define glPolygonStipple glad_glPolygonStipple -typedef void (APIENTRYP PFNGLSHADEMODELPROC)(GLenum mode); -GLAPI PFNGLSHADEMODELPROC glad_glShadeModel; -#define glShadeModel glad_glShadeModel -typedef void (APIENTRYP PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); -GLAPI PFNGLTEXENVFPROC glad_glTexEnvf; -#define glTexEnvf glad_glTexEnvf -typedef void (APIENTRYP PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXENVFVPROC glad_glTexEnvfv; -#define glTexEnvfv glad_glTexEnvfv -typedef void (APIENTRYP PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); -GLAPI PFNGLTEXENVIPROC glad_glTexEnvi; -#define glTexEnvi glad_glTexEnvi -typedef void (APIENTRYP PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint *params); -GLAPI PFNGLTEXENVIVPROC glad_glTexEnviv; -#define glTexEnviv glad_glTexEnviv -typedef void (APIENTRYP PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); -GLAPI PFNGLTEXGENDPROC glad_glTexGend; -#define glTexGend glad_glTexGend -typedef void (APIENTRYP PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble *params); -GLAPI PFNGLTEXGENDVPROC glad_glTexGendv; -#define glTexGendv glad_glTexGendv -typedef void (APIENTRYP PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); -GLAPI PFNGLTEXGENFPROC glad_glTexGenf; -#define glTexGenf glad_glTexGenf -typedef void (APIENTRYP PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXGENFVPROC glad_glTexGenfv; -#define glTexGenfv glad_glTexGenfv -typedef void (APIENTRYP PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); -GLAPI PFNGLTEXGENIPROC glad_glTexGeni; -#define glTexGeni glad_glTexGeni -typedef void (APIENTRYP PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint *params); -GLAPI PFNGLTEXGENIVPROC glad_glTexGeniv; -#define glTexGeniv glad_glTexGeniv -typedef void (APIENTRYP PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat *buffer); -GLAPI PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; -#define glFeedbackBuffer glad_glFeedbackBuffer -typedef void (APIENTRYP PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint *buffer); -GLAPI PFNGLSELECTBUFFERPROC glad_glSelectBuffer; -#define glSelectBuffer glad_glSelectBuffer -typedef GLint (APIENTRYP PFNGLRENDERMODEPROC)(GLenum mode); -GLAPI PFNGLRENDERMODEPROC glad_glRenderMode; -#define glRenderMode glad_glRenderMode -typedef void (APIENTRYP PFNGLINITNAMESPROC)(void); -GLAPI PFNGLINITNAMESPROC glad_glInitNames; -#define glInitNames glad_glInitNames -typedef void (APIENTRYP PFNGLLOADNAMEPROC)(GLuint name); -GLAPI PFNGLLOADNAMEPROC glad_glLoadName; -#define glLoadName glad_glLoadName -typedef void (APIENTRYP PFNGLPASSTHROUGHPROC)(GLfloat token); -GLAPI PFNGLPASSTHROUGHPROC glad_glPassThrough; -#define glPassThrough glad_glPassThrough -typedef void (APIENTRYP PFNGLPOPNAMEPROC)(void); -GLAPI PFNGLPOPNAMEPROC glad_glPopName; -#define glPopName glad_glPopName -typedef void (APIENTRYP PFNGLPUSHNAMEPROC)(GLuint name); -GLAPI PFNGLPUSHNAMEPROC glad_glPushName; -#define glPushName glad_glPushName -typedef void (APIENTRYP PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCLEARACCUMPROC glad_glClearAccum; -#define glClearAccum glad_glClearAccum -typedef void (APIENTRYP PFNGLCLEARINDEXPROC)(GLfloat c); -GLAPI PFNGLCLEARINDEXPROC glad_glClearIndex; -#define glClearIndex glad_glClearIndex -typedef void (APIENTRYP PFNGLINDEXMASKPROC)(GLuint mask); -GLAPI PFNGLINDEXMASKPROC glad_glIndexMask; -#define glIndexMask glad_glIndexMask -typedef void (APIENTRYP PFNGLACCUMPROC)(GLenum op, GLfloat value); -GLAPI PFNGLACCUMPROC glad_glAccum; -#define glAccum glad_glAccum -typedef void (APIENTRYP PFNGLPOPATTRIBPROC)(void); -GLAPI PFNGLPOPATTRIBPROC glad_glPopAttrib; -#define glPopAttrib glad_glPopAttrib -typedef void (APIENTRYP PFNGLPUSHATTRIBPROC)(GLbitfield mask); -GLAPI PFNGLPUSHATTRIBPROC glad_glPushAttrib; -#define glPushAttrib glad_glPushAttrib -typedef void (APIENTRYP PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI PFNGLMAP1DPROC glad_glMap1d; -#define glMap1d glad_glMap1d -typedef void (APIENTRYP PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI PFNGLMAP1FPROC glad_glMap1f; -#define glMap1f glad_glMap1f -typedef void (APIENTRYP PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI PFNGLMAP2DPROC glad_glMap2d; -#define glMap2d glad_glMap2d -typedef void (APIENTRYP PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -GLAPI PFNGLMAP2FPROC glad_glMap2f; -#define glMap2f glad_glMap2f -typedef void (APIENTRYP PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); -GLAPI PFNGLMAPGRID1DPROC glad_glMapGrid1d; -#define glMapGrid1d glad_glMapGrid1d -typedef void (APIENTRYP PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); -GLAPI PFNGLMAPGRID1FPROC glad_glMapGrid1f; -#define glMapGrid1f glad_glMapGrid1f -typedef void (APIENTRYP PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -GLAPI PFNGLMAPGRID2DPROC glad_glMapGrid2d; -#define glMapGrid2d glad_glMapGrid2d -typedef void (APIENTRYP PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -GLAPI PFNGLMAPGRID2FPROC glad_glMapGrid2f; -#define glMapGrid2f glad_glMapGrid2f -typedef void (APIENTRYP PFNGLEVALCOORD1DPROC)(GLdouble u); -GLAPI PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; -#define glEvalCoord1d glad_glEvalCoord1d -typedef void (APIENTRYP PFNGLEVALCOORD1DVPROC)(const GLdouble *u); -GLAPI PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; -#define glEvalCoord1dv glad_glEvalCoord1dv -typedef void (APIENTRYP PFNGLEVALCOORD1FPROC)(GLfloat u); -GLAPI PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; -#define glEvalCoord1f glad_glEvalCoord1f -typedef void (APIENTRYP PFNGLEVALCOORD1FVPROC)(const GLfloat *u); -GLAPI PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; -#define glEvalCoord1fv glad_glEvalCoord1fv -typedef void (APIENTRYP PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); -GLAPI PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; -#define glEvalCoord2d glad_glEvalCoord2d -typedef void (APIENTRYP PFNGLEVALCOORD2DVPROC)(const GLdouble *u); -GLAPI PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; -#define glEvalCoord2dv glad_glEvalCoord2dv -typedef void (APIENTRYP PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); -GLAPI PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; -#define glEvalCoord2f glad_glEvalCoord2f -typedef void (APIENTRYP PFNGLEVALCOORD2FVPROC)(const GLfloat *u); -GLAPI PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; -#define glEvalCoord2fv glad_glEvalCoord2fv -typedef void (APIENTRYP PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); -GLAPI PFNGLEVALMESH1PROC glad_glEvalMesh1; -#define glEvalMesh1 glad_glEvalMesh1 -typedef void (APIENTRYP PFNGLEVALPOINT1PROC)(GLint i); -GLAPI PFNGLEVALPOINT1PROC glad_glEvalPoint1; -#define glEvalPoint1 glad_glEvalPoint1 -typedef void (APIENTRYP PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -GLAPI PFNGLEVALMESH2PROC glad_glEvalMesh2; -#define glEvalMesh2 glad_glEvalMesh2 -typedef void (APIENTRYP PFNGLEVALPOINT2PROC)(GLint i, GLint j); -GLAPI PFNGLEVALPOINT2PROC glad_glEvalPoint2; -#define glEvalPoint2 glad_glEvalPoint2 -typedef void (APIENTRYP PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); -GLAPI PFNGLALPHAFUNCPROC glad_glAlphaFunc; -#define glAlphaFunc glad_glAlphaFunc -typedef void (APIENTRYP PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); -GLAPI PFNGLPIXELZOOMPROC glad_glPixelZoom; -#define glPixelZoom glad_glPixelZoom -typedef void (APIENTRYP PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); -GLAPI PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; -#define glPixelTransferf glad_glPixelTransferf -typedef void (APIENTRYP PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); -GLAPI PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; -#define glPixelTransferi glad_glPixelTransferi -typedef void (APIENTRYP PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat *values); -GLAPI PFNGLPIXELMAPFVPROC glad_glPixelMapfv; -#define glPixelMapfv glad_glPixelMapfv -typedef void (APIENTRYP PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint *values); -GLAPI PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; -#define glPixelMapuiv glad_glPixelMapuiv -typedef void (APIENTRYP PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort *values); -GLAPI PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; -#define glPixelMapusv glad_glPixelMapusv -typedef void (APIENTRYP PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -GLAPI PFNGLCOPYPIXELSPROC glad_glCopyPixels; -#define glCopyPixels glad_glCopyPixels -typedef void (APIENTRYP PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLDRAWPIXELSPROC glad_glDrawPixels; -#define glDrawPixels glad_glDrawPixels -typedef void (APIENTRYP PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble *equation); -GLAPI PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; -#define glGetClipPlane glad_glGetClipPlane -typedef void (APIENTRYP PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat *params); -GLAPI PFNGLGETLIGHTFVPROC glad_glGetLightfv; -#define glGetLightfv glad_glGetLightfv -typedef void (APIENTRYP PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint *params); -GLAPI PFNGLGETLIGHTIVPROC glad_glGetLightiv; -#define glGetLightiv glad_glGetLightiv -typedef void (APIENTRYP PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble *v); -GLAPI PFNGLGETMAPDVPROC glad_glGetMapdv; -#define glGetMapdv glad_glGetMapdv -typedef void (APIENTRYP PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat *v); -GLAPI PFNGLGETMAPFVPROC glad_glGetMapfv; -#define glGetMapfv glad_glGetMapfv -typedef void (APIENTRYP PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint *v); -GLAPI PFNGLGETMAPIVPROC glad_glGetMapiv; -#define glGetMapiv glad_glGetMapiv -typedef void (APIENTRYP PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat *params); -GLAPI PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; -#define glGetMaterialfv glad_glGetMaterialfv -typedef void (APIENTRYP PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint *params); -GLAPI PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; -#define glGetMaterialiv glad_glGetMaterialiv -typedef void (APIENTRYP PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat *values); -GLAPI PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; -#define glGetPixelMapfv glad_glGetPixelMapfv -typedef void (APIENTRYP PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint *values); -GLAPI PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; -#define glGetPixelMapuiv glad_glGetPixelMapuiv -typedef void (APIENTRYP PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort *values); -GLAPI PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; -#define glGetPixelMapusv glad_glGetPixelMapusv -typedef void (APIENTRYP PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte *mask); -GLAPI PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; -#define glGetPolygonStipple glad_glGetPolygonStipple -typedef void (APIENTRYP PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; -#define glGetTexEnvfv glad_glGetTexEnvfv -typedef void (APIENTRYP PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; -#define glGetTexEnviv glad_glGetTexEnviv -typedef void (APIENTRYP PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble *params); -GLAPI PFNGLGETTEXGENDVPROC glad_glGetTexGendv; -#define glGetTexGendv glad_glGetTexGendv -typedef void (APIENTRYP PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; -#define glGetTexGenfv glad_glGetTexGenfv -typedef void (APIENTRYP PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; -#define glGetTexGeniv glad_glGetTexGeniv -typedef GLboolean (APIENTRYP PFNGLISLISTPROC)(GLuint list); -GLAPI PFNGLISLISTPROC glad_glIsList; -#define glIsList glad_glIsList -typedef void (APIENTRYP PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI PFNGLFRUSTUMPROC glad_glFrustum; -#define glFrustum glad_glFrustum -typedef void (APIENTRYP PFNGLLOADIDENTITYPROC)(void); -GLAPI PFNGLLOADIDENTITYPROC glad_glLoadIdentity; -#define glLoadIdentity glad_glLoadIdentity -typedef void (APIENTRYP PFNGLLOADMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; -#define glLoadMatrixf glad_glLoadMatrixf -typedef void (APIENTRYP PFNGLLOADMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; -#define glLoadMatrixd glad_glLoadMatrixd -typedef void (APIENTRYP PFNGLMATRIXMODEPROC)(GLenum mode); -GLAPI PFNGLMATRIXMODEPROC glad_glMatrixMode; -#define glMatrixMode glad_glMatrixMode -typedef void (APIENTRYP PFNGLMULTMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLMULTMATRIXFPROC glad_glMultMatrixf; -#define glMultMatrixf glad_glMultMatrixf -typedef void (APIENTRYP PFNGLMULTMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLMULTMATRIXDPROC glad_glMultMatrixd; -#define glMultMatrixd glad_glMultMatrixd -typedef void (APIENTRYP PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI PFNGLORTHOPROC glad_glOrtho; -#define glOrtho glad_glOrtho -typedef void (APIENTRYP PFNGLPOPMATRIXPROC)(void); -GLAPI PFNGLPOPMATRIXPROC glad_glPopMatrix; -#define glPopMatrix glad_glPopMatrix -typedef void (APIENTRYP PFNGLPUSHMATRIXPROC)(void); -GLAPI PFNGLPUSHMATRIXPROC glad_glPushMatrix; -#define glPushMatrix glad_glPushMatrix -typedef void (APIENTRYP PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLROTATEDPROC glad_glRotated; -#define glRotated glad_glRotated -typedef void (APIENTRYP PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLROTATEFPROC glad_glRotatef; -#define glRotatef glad_glRotatef -typedef void (APIENTRYP PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLSCALEDPROC glad_glScaled; -#define glScaled glad_glScaled -typedef void (APIENTRYP PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLSCALEFPROC glad_glScalef; -#define glScalef glad_glScalef -typedef void (APIENTRYP PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLTRANSLATEDPROC glad_glTranslated; -#define glTranslated glad_glTranslated -typedef void (APIENTRYP PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLTRANSLATEFPROC glad_glTranslatef; -#define glTranslatef glad_glTranslatef #endif #ifndef GL_VERSION_1_1 #define GL_VERSION_1_1 1 @@ -2933,9 +1743,6 @@ GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; #define glDrawElements glad_glDrawElements -typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void **params); -GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; -#define glGetPointerv glad_glGetPointerv typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; #define glPolygonOffset glad_glPolygonOffset @@ -2969,54 +1776,6 @@ GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture); GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; #define glIsTexture glad_glIsTexture -typedef void (APIENTRYP PFNGLARRAYELEMENTPROC)(GLint i); -GLAPI PFNGLARRAYELEMENTPROC glad_glArrayElement; -#define glArrayElement glad_glArrayElement -typedef void (APIENTRYP PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLCOLORPOINTERPROC glad_glColorPointer; -#define glColorPointer glad_glColorPointer -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEPROC)(GLenum array); -GLAPI PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; -#define glDisableClientState glad_glDisableClientState -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void *pointer); -GLAPI PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; -#define glEdgeFlagPointer glad_glEdgeFlagPointer -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEPROC)(GLenum array); -GLAPI PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; -#define glEnableClientState glad_glEnableClientState -typedef void (APIENTRYP PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLINDEXPOINTERPROC glad_glIndexPointer; -#define glIndexPointer glad_glIndexPointer -typedef void (APIENTRYP PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void *pointer); -GLAPI PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; -#define glInterleavedArrays glad_glInterleavedArrays -typedef void (APIENTRYP PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLNORMALPOINTERPROC glad_glNormalPointer; -#define glNormalPointer glad_glNormalPointer -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; -#define glTexCoordPointer glad_glTexCoordPointer -typedef void (APIENTRYP PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXPOINTERPROC glad_glVertexPointer; -#define glVertexPointer glad_glVertexPointer -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; -#define glAreTexturesResident glad_glAreTexturesResident -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint *textures, const GLfloat *priorities); -GLAPI PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; -#define glPrioritizeTextures glad_glPrioritizeTextures -typedef void (APIENTRYP PFNGLINDEXUBPROC)(GLubyte c); -GLAPI PFNGLINDEXUBPROC glad_glIndexub; -#define glIndexub glad_glIndexub -typedef void (APIENTRYP PFNGLINDEXUBVPROC)(const GLubyte *c); -GLAPI PFNGLINDEXUBVPROC glad_glIndexubv; -#define glIndexubv glad_glIndexubv -typedef void (APIENTRYP PFNGLPOPCLIENTATTRIBPROC)(void); -GLAPI PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; -#define glPopClientAttrib glad_glPopClientAttrib -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); -GLAPI PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; -#define glPushClientAttrib glad_glPushClientAttrib #endif #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 @@ -3064,117 +1823,6 @@ GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void *img); GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; #define glGetCompressedTexImage glad_glGetCompressedTexImage -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); -GLAPI PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; -#define glClientActiveTexture glad_glClientActiveTexture -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); -GLAPI PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; -#define glMultiTexCoord1d glad_glMultiTexCoord1d -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; -#define glMultiTexCoord1dv glad_glMultiTexCoord1dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); -GLAPI PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; -#define glMultiTexCoord1f glad_glMultiTexCoord1f -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; -#define glMultiTexCoord1fv glad_glMultiTexCoord1fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); -GLAPI PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; -#define glMultiTexCoord1i glad_glMultiTexCoord1i -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; -#define glMultiTexCoord1iv glad_glMultiTexCoord1iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); -GLAPI PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; -#define glMultiTexCoord1s glad_glMultiTexCoord1s -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; -#define glMultiTexCoord1sv glad_glMultiTexCoord1sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); -GLAPI PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; -#define glMultiTexCoord2d glad_glMultiTexCoord2d -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; -#define glMultiTexCoord2dv glad_glMultiTexCoord2dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); -GLAPI PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; -#define glMultiTexCoord2f glad_glMultiTexCoord2f -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; -#define glMultiTexCoord2fv glad_glMultiTexCoord2fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); -GLAPI PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; -#define glMultiTexCoord2i glad_glMultiTexCoord2i -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; -#define glMultiTexCoord2iv glad_glMultiTexCoord2iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); -GLAPI PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; -#define glMultiTexCoord2s glad_glMultiTexCoord2s -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; -#define glMultiTexCoord2sv glad_glMultiTexCoord2sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; -#define glMultiTexCoord3d glad_glMultiTexCoord3d -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; -#define glMultiTexCoord3dv glad_glMultiTexCoord3dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; -#define glMultiTexCoord3f glad_glMultiTexCoord3f -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; -#define glMultiTexCoord3fv glad_glMultiTexCoord3fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); -GLAPI PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; -#define glMultiTexCoord3i glad_glMultiTexCoord3i -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; -#define glMultiTexCoord3iv glad_glMultiTexCoord3iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; -#define glMultiTexCoord3s glad_glMultiTexCoord3s -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; -#define glMultiTexCoord3sv glad_glMultiTexCoord3sv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; -#define glMultiTexCoord4d glad_glMultiTexCoord4d -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble *v); -GLAPI PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; -#define glMultiTexCoord4dv glad_glMultiTexCoord4dv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; -#define glMultiTexCoord4f glad_glMultiTexCoord4f -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat *v); -GLAPI PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; -#define glMultiTexCoord4fv glad_glMultiTexCoord4fv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; -#define glMultiTexCoord4i glad_glMultiTexCoord4i -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint *v); -GLAPI PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; -#define glMultiTexCoord4iv glad_glMultiTexCoord4iv -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; -#define glMultiTexCoord4s glad_glMultiTexCoord4s -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort *v); -GLAPI PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; -#define glMultiTexCoord4sv glad_glMultiTexCoord4sv -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; -#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; -#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat *m); -GLAPI PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; -#define glMultTransposeMatrixf glad_glMultTransposeMatrixf -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble *m); -GLAPI PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; -#define glMultTransposeMatrixd glad_glMultTransposeMatrixd #endif #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 @@ -3200,120 +1848,6 @@ GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint *params); GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; #define glPointParameteriv glad_glPointParameteriv -typedef void (APIENTRYP PFNGLFOGCOORDFPROC)(GLfloat coord); -GLAPI PFNGLFOGCOORDFPROC glad_glFogCoordf; -#define glFogCoordf glad_glFogCoordf -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC)(const GLfloat *coord); -GLAPI PFNGLFOGCOORDFVPROC glad_glFogCoordfv; -#define glFogCoordfv glad_glFogCoordfv -typedef void (APIENTRYP PFNGLFOGCOORDDPROC)(GLdouble coord); -GLAPI PFNGLFOGCOORDDPROC glad_glFogCoordd; -#define glFogCoordd glad_glFogCoordd -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC)(const GLdouble *coord); -GLAPI PFNGLFOGCOORDDVPROC glad_glFogCoorddv; -#define glFogCoorddv glad_glFogCoorddv -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; -#define glFogCoordPointer glad_glFogCoordPointer -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -GLAPI PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; -#define glSecondaryColor3b glad_glSecondaryColor3b -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte *v); -GLAPI PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; -#define glSecondaryColor3bv glad_glSecondaryColor3bv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -GLAPI PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; -#define glSecondaryColor3d glad_glSecondaryColor3d -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble *v); -GLAPI PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; -#define glSecondaryColor3dv glad_glSecondaryColor3dv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -GLAPI PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; -#define glSecondaryColor3f glad_glSecondaryColor3f -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat *v); -GLAPI PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; -#define glSecondaryColor3fv glad_glSecondaryColor3fv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); -GLAPI PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; -#define glSecondaryColor3i glad_glSecondaryColor3i -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC)(const GLint *v); -GLAPI PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; -#define glSecondaryColor3iv glad_glSecondaryColor3iv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -GLAPI PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; -#define glSecondaryColor3s glad_glSecondaryColor3s -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC)(const GLshort *v); -GLAPI PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; -#define glSecondaryColor3sv glad_glSecondaryColor3sv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -GLAPI PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; -#define glSecondaryColor3ub glad_glSecondaryColor3ub -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte *v); -GLAPI PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; -#define glSecondaryColor3ubv glad_glSecondaryColor3ubv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -GLAPI PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; -#define glSecondaryColor3ui glad_glSecondaryColor3ui -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint *v); -GLAPI PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; -#define glSecondaryColor3uiv glad_glSecondaryColor3uiv -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -GLAPI PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; -#define glSecondaryColor3us glad_glSecondaryColor3us -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC)(const GLushort *v); -GLAPI PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; -#define glSecondaryColor3usv glad_glSecondaryColor3usv -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; -#define glSecondaryColorPointer glad_glSecondaryColorPointer -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); -GLAPI PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; -#define glWindowPos2d glad_glWindowPos2d -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC)(const GLdouble *v); -GLAPI PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; -#define glWindowPos2dv glad_glWindowPos2dv -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); -GLAPI PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; -#define glWindowPos2f glad_glWindowPos2f -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC)(const GLfloat *v); -GLAPI PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; -#define glWindowPos2fv glad_glWindowPos2fv -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); -GLAPI PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; -#define glWindowPos2i glad_glWindowPos2i -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC)(const GLint *v); -GLAPI PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; -#define glWindowPos2iv glad_glWindowPos2iv -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); -GLAPI PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; -#define glWindowPos2s glad_glWindowPos2s -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC)(const GLshort *v); -GLAPI PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; -#define glWindowPos2sv glad_glWindowPos2sv -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -GLAPI PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; -#define glWindowPos3d glad_glWindowPos3d -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC)(const GLdouble *v); -GLAPI PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; -#define glWindowPos3dv glad_glWindowPos3dv -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; -#define glWindowPos3f glad_glWindowPos3f -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC)(const GLfloat *v); -GLAPI PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; -#define glWindowPos3fv glad_glWindowPos3fv -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); -GLAPI PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; -#define glWindowPos3i glad_glWindowPos3i -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC)(const GLint *v); -GLAPI PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; -#define glWindowPos3iv glad_glWindowPos3iv -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); -GLAPI PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; -#define glWindowPos3s glad_glWindowPos3s -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC)(const GLshort *v); -GLAPI PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; -#define glWindowPos3sv glad_glWindowPos3sv typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; #define glBlendColor glad_glBlendColor @@ -4804,6 +3338,9 @@ GLAPI PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); GLAPI PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; #define glGetObjectPtrLabel glad_glGetObjectPtrLabel +typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void **params); +GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv #endif #ifndef GL_VERSION_4_4 #define GL_VERSION_4_4 1 @@ -5244,46 +3781,13 @@ typedef void (APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXPROC)(GLfloat minX, GLfloat min GLAPI PFNGLPRIMITIVEBOUNDINGBOXPROC glad_glPrimitiveBoundingBox; #define glPrimitiveBoundingBox glad_glPrimitiveBoundingBox #endif -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 -#define GL_DEBUG_SOURCE_API_KHR 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A -#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B -#define GL_DEBUG_TYPE_ERROR_KHR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 -#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 -#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D -#define GL_BUFFER_KHR 0x82E0 -#define GL_SHADER_KHR 0x82E1 -#define GL_PROGRAM_KHR 0x82E2 -#define GL_VERTEX_ARRAY_KHR 0x8074 -#define GL_QUERY_KHR 0x82E3 -#define GL_PROGRAM_PIPELINE_KHR 0x82E4 -#define GL_SAMPLER_KHR 0x82E6 -#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 -#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 -#define GL_DEBUG_OUTPUT_KHR 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 -#define GL_STACK_OVERFLOW_KHR 0x0503 -#define GL_STACK_UNDERFLOW_KHR 0x0504 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 #define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 #define GL_MAX_CULL_DISTANCES_EXT 0x82F9 #define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA @@ -5299,51 +3803,25 @@ GLAPI PFNGLPRIMITIVEBOUNDINGBOXPROC glad_glPrimitiveBoundingBox; #define GL_ARB_buffer_storage 1 GLAPI int GLAD_GL_ARB_buffer_storage; #endif -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -GLAPI int GLAD_GL_KHR_debug; -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; -#define glDebugMessageControlKHR glad_glDebugMessageControlKHR -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; -#define glDebugMessageInsertKHR glad_glDebugMessageInsertKHR -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC)(GLDEBUGPROCKHR callback, const void *userParam); -GLAPI PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; -#define glDebugMessageCallbackKHR glad_glDebugMessageCallbackKHR -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; -#define glGetDebugMessageLogKHR glad_glGetDebugMessageLogKHR -typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC)(GLenum source, GLuint id, GLsizei length, const GLchar *message); -GLAPI PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; -#define glPushDebugGroupKHR glad_glPushDebugGroupKHR -typedef void (APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC)(void); -GLAPI PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; -#define glPopDebugGroupKHR glad_glPopDebugGroupKHR -typedef void (APIENTRYP PFNGLOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; -#define glObjectLabelKHR glad_glObjectLabelKHR -typedef void (APIENTRYP PFNGLGETOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; -#define glGetObjectLabelKHR glad_glGetObjectLabelKHR -typedef void (APIENTRYP PFNGLOBJECTPTRLABELKHRPROC)(const void *ptr, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; -#define glObjectPtrLabelKHR glad_glObjectPtrLabelKHR -typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; -#define glGetObjectPtrLabelKHR glad_glGetObjectPtrLabelKHR -typedef void (APIENTRYP PFNGLGETPOINTERVKHRPROC)(GLenum pname, void **params); -GLAPI PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; -#define glGetPointervKHR glad_glGetPointervKHR +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 +GLAPI int GLAD_GL_ARB_clear_texture; +#endif +#ifndef GL_ARB_get_texture_sub_image +#define GL_ARB_get_texture_sub_image 1 +GLAPI int GLAD_GL_ARB_get_texture_sub_image; +#endif +#ifndef GL_EXT_buffer_storage +#define GL_EXT_buffer_storage 1 +GLAPI int GLAD_GL_EXT_buffer_storage; +typedef void (APIENTRYP PFNGLBUFFERSTORAGEEXTPROC)(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI PFNGLBUFFERSTORAGEEXTPROC glad_glBufferStorageEXT; +#define glBufferStorageEXT glad_glBufferStorageEXT #endif #ifndef GL_EXT_clip_cull_distance #define GL_EXT_clip_cull_distance 1 GLAPI int GLAD_GL_EXT_clip_cull_distance; #endif -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -GLAPI int GLAD_GL_KHR_debug; -#endif #ifdef __cplusplus } diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c index 901a86b4e..1630ebc19 100644 --- a/externals/glad/src/glad.c +++ b/externals/glad/src/glad.c @@ -1,24 +1,26 @@ /* - OpenGL, OpenGL ES loader generated by glad 0.1.36 on Mon Aug 22 20:31:42 2022. + OpenGL, OpenGL ES loader generated by glad 0.1.36 on Sun Mar 12 10:25:27 2023. Language/Generator: C/C++ Specification: gl APIs: gl=4.6, gles2=3.2 - Profile: compatibility + Profile: core Extensions: GL_ARB_buffer_storage, - GL_EXT_clip_cull_distance, - GL_KHR_debug + GL_ARB_clear_texture, + GL_ARB_get_texture_sub_image, + GL_EXT_buffer_storage, + GL_EXT_clip_cull_distance Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="compatibility" --api="gl=4.6,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_EXT_clip_cull_distance,GL_KHR_debug" + --profile="core" --api="gl=4.6,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_get_texture_sub_image,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance" Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D4.6&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_KHR_debug + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.6&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_get_texture_sub_image&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance */ #include @@ -280,14 +282,9 @@ int GLAD_GL_ES_VERSION_2_0 = 0; int GLAD_GL_ES_VERSION_3_0 = 0; int GLAD_GL_ES_VERSION_3_1 = 0; int GLAD_GL_ES_VERSION_3_2 = 0; -PFNGLACCUMPROC glad_glAccum = NULL; PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; -PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; -PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINPROC glad_glBegin = NULL; PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; @@ -314,7 +311,6 @@ PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; -PFNGLBITMAPPROC glad_glBitmap = NULL; PFNGLBLENDBARRIERPROC glad_glBlendBarrier = NULL; PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; @@ -330,13 +326,10 @@ PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; PFNGLBUFFERDATAPROC glad_glBufferData = NULL; PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCALLLISTPROC glad_glCallList = NULL; -PFNGLCALLLISTSPROC glad_glCallLists = NULL; PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL; PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL; PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; @@ -346,7 +339,6 @@ PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; PFNGLCLEARCOLORPROC glad_glClearColor = NULL; PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; -PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL; PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL; @@ -356,50 +348,14 @@ PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL; PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL; PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL; -PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; -PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; -PFNGLCOLOR3BPROC glad_glColor3b = NULL; -PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; -PFNGLCOLOR3DPROC glad_glColor3d = NULL; -PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; -PFNGLCOLOR3FPROC glad_glColor3f = NULL; -PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; -PFNGLCOLOR3IPROC glad_glColor3i = NULL; -PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; -PFNGLCOLOR3SPROC glad_glColor3s = NULL; -PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; -PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; -PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; -PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; -PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; -PFNGLCOLOR3USPROC glad_glColor3us = NULL; -PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; -PFNGLCOLOR4BPROC glad_glColor4b = NULL; -PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; -PFNGLCOLOR4DPROC glad_glColor4d = NULL; -PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; -PFNGLCOLOR4FPROC glad_glColor4f = NULL; -PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; -PFNGLCOLOR4IPROC glad_glColor4i = NULL; -PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; -PFNGLCOLOR4SPROC glad_glColor4s = NULL; -PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; -PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; -PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; -PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; -PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; -PFNGLCOLOR4USPROC glad_glColor4us = NULL; -PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; PFNGLCOLORMASKPROC glad_glColorMask = NULL; PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; -PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; @@ -413,7 +369,6 @@ PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; -PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; @@ -440,7 +395,6 @@ PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; @@ -459,7 +413,6 @@ PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; PFNGLDISABLEIPROC glad_glDisablei = NULL; @@ -478,54 +431,25 @@ PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; -PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; -PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; -PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; -PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDPROC glad_glEnd = NULL; PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDLISTPROC glad_glEndList = NULL; PFNGLENDQUERYPROC glad_glEndQuery = NULL; PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; -PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; -PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; -PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; -PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; -PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; -PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; -PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; -PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; -PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; -PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; -PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; -PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; PFNGLFENCESYNCPROC glad_glFenceSync = NULL; PFNGLFINISHPROC glad_glFinish = NULL; PFNGLFLUSHPROC glad_glFlush = NULL; PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; -PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; -PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; -PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; -PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; -PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; -PFNGLFOGFPROC glad_glFogf = NULL; -PFNGLFOGFVPROC glad_glFogfv = NULL; -PFNGLFOGIPROC glad_glFogi = NULL; -PFNGLFOGIVPROC glad_glFogiv = NULL; PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; @@ -534,10 +458,8 @@ PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLFRUSTUMPROC glad_glFrustum = NULL; PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENLISTSPROC glad_glGenLists = NULL; PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; PFNGLGENQUERIESPROC glad_glGenQueries = NULL; PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; @@ -565,7 +487,6 @@ PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; @@ -586,13 +507,6 @@ PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; -PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; -PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; -PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; -PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; -PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; -PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; -PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; @@ -603,11 +517,7 @@ PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; -PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; -PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; -PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; -PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; @@ -644,11 +554,6 @@ PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; -PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; -PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; -PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; -PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; @@ -705,20 +610,6 @@ PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; PFNGLHINTPROC glad_glHint = NULL; -PFNGLINDEXMASKPROC glad_glIndexMask = NULL; -PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; -PFNGLINDEXDPROC glad_glIndexd = NULL; -PFNGLINDEXDVPROC glad_glIndexdv = NULL; -PFNGLINDEXFPROC glad_glIndexf = NULL; -PFNGLINDEXFVPROC glad_glIndexfv = NULL; -PFNGLINDEXIPROC glad_glIndexi = NULL; -PFNGLINDEXIVPROC glad_glIndexiv = NULL; -PFNGLINDEXSPROC glad_glIndexs = NULL; -PFNGLINDEXSVPROC glad_glIndexsv = NULL; -PFNGLINDEXUBPROC glad_glIndexub = NULL; -PFNGLINDEXUBVPROC glad_glIndexubv = NULL; -PFNGLINITNAMESPROC glad_glInitNames = NULL; -PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; @@ -731,7 +622,6 @@ PFNGLISBUFFERPROC glad_glIsBuffer = NULL; PFNGLISENABLEDPROC glad_glIsEnabled = NULL; PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISLISTPROC glad_glIsList = NULL; PFNGLISPROGRAMPROC glad_glIsProgram = NULL; PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; PFNGLISQUERYPROC glad_glIsQuery = NULL; @@ -742,49 +632,16 @@ PFNGLISSYNCPROC glad_glIsSync = NULL; PFNGLISTEXTUREPROC glad_glIsTexture = NULL; PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; -PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; -PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; -PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; -PFNGLLIGHTFPROC glad_glLightf = NULL; -PFNGLLIGHTFVPROC glad_glLightfv = NULL; -PFNGLLIGHTIPROC glad_glLighti = NULL; -PFNGLLIGHTIVPROC glad_glLightiv = NULL; -PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLISTBASEPROC glad_glListBase = NULL; -PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; -PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; -PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; -PFNGLLOADNAMEPROC glad_glLoadName = NULL; -PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; -PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAP1DPROC glad_glMap1d = NULL; -PFNGLMAP1FPROC glad_glMap1f = NULL; -PFNGLMAP2DPROC glad_glMap2d = NULL; -PFNGLMAP2FPROC glad_glMap2f = NULL; PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; -PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; -PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; -PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; -PFNGLMATERIALFPROC glad_glMaterialf = NULL; -PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; -PFNGLMATERIALIPROC glad_glMateriali = NULL; -PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; -PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL; -PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; -PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; -PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; -PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount = NULL; @@ -792,38 +649,6 @@ PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount = NULL; -PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; -PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; -PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; -PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; -PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; -PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; -PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; -PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; -PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; -PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; -PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; -PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; -PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; -PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; -PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; -PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; -PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; -PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; -PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; -PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; -PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; -PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; -PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; -PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; -PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; -PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; -PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; -PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; -PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; -PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; -PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; -PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; @@ -844,35 +669,15 @@ PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; -PFNGLNEWLISTPROC glad_glNewList = NULL; -PFNGLNORMAL3BPROC glad_glNormal3b = NULL; -PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; -PFNGLNORMAL3DPROC glad_glNormal3d = NULL; -PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; -PFNGLNORMAL3FPROC glad_glNormal3f = NULL; -PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; -PFNGLNORMAL3IPROC glad_glNormal3i = NULL; -PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; -PFNGLNORMAL3SPROC glad_glNormal3s = NULL; -PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; -PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; -PFNGLORTHOPROC glad_glOrtho = NULL; -PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; -PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; -PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; -PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; -PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; -PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; @@ -881,15 +686,9 @@ PFNGLPOINTSIZEPROC glad_glPointSize = NULL; PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; -PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; -PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; -PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; -PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; -PFNGLPOPNAMEPROC glad_glPopName = NULL; PFNGLPRIMITIVEBOUNDINGBOXPROC glad_glPrimitiveBoundingBox = NULL; PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; @@ -943,54 +742,15 @@ PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; -PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; -PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; -PFNGLPUSHNAMEPROC glad_glPushName = NULL; PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; -PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; -PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; -PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; -PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; -PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; -PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; -PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; -PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; -PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; -PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; -PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; -PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; -PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; -PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; -PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; -PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; -PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; -PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; -PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; -PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; -PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; -PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; -PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; -PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; PFNGLREADPIXELSPROC glad_glReadPixels = NULL; PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL; -PFNGLRECTDPROC glad_glRectd = NULL; -PFNGLRECTDVPROC glad_glRectdv = NULL; -PFNGLRECTFPROC glad_glRectf = NULL; -PFNGLRECTFVPROC glad_glRectfv = NULL; -PFNGLRECTIPROC glad_glRecti = NULL; -PFNGLRECTIVPROC glad_glRectiv = NULL; -PFNGLRECTSPROC glad_glRects = NULL; -PFNGLRECTSVPROC glad_glRectsv = NULL; PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; -PFNGLRENDERMODEPROC glad_glRenderMode = NULL; PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; -PFNGLROTATEDPROC glad_glRotated = NULL; -PFNGLROTATEFPROC glad_glRotatef = NULL; PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; @@ -999,33 +759,12 @@ PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; -PFNGLSCALEDPROC glad_glScaled = NULL; -PFNGLSCALEFPROC glad_glScalef = NULL; PFNGLSCISSORPROC glad_glScissor = NULL; PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; -PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; -PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; -PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; -PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; -PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; -PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; -PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; -PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; -PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; -PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; -PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; -PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; -PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; -PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; -PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; -PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; -PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; -PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; -PFNGLSHADEMODELPROC glad_glShadeModel = NULL; PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; @@ -1038,38 +777,6 @@ PFNGLSTENCILOPPROC glad_glStencilOp = NULL; PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; -PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; -PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; -PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; -PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; -PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; -PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; -PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; -PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; -PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; -PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; -PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; -PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; -PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; -PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; -PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; -PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; -PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; -PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; -PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; -PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; -PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; -PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; -PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; -PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; -PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; -PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; -PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; -PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; -PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; -PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; -PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; -PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; @@ -1078,17 +785,6 @@ PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; -PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; -PFNGLTEXENVFPROC glad_glTexEnvf = NULL; -PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; -PFNGLTEXENVIPROC glad_glTexEnvi = NULL; -PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; -PFNGLTEXGENDPROC glad_glTexGend = NULL; -PFNGLTEXGENDVPROC glad_glTexGendv = NULL; -PFNGLTEXGENFPROC glad_glTexGenf = NULL; -PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; -PFNGLTEXGENIPROC glad_glTexGeni = NULL; -PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; @@ -1129,8 +825,6 @@ PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLTRANSLATEDPROC glad_glTranslated = NULL; -PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; @@ -1189,30 +883,6 @@ PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; -PFNGLVERTEX2DPROC glad_glVertex2d = NULL; -PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; -PFNGLVERTEX2FPROC glad_glVertex2f = NULL; -PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; -PFNGLVERTEX2IPROC glad_glVertex2i = NULL; -PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; -PFNGLVERTEX2SPROC glad_glVertex2s = NULL; -PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; -PFNGLVERTEX3DPROC glad_glVertex3d = NULL; -PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; -PFNGLVERTEX3FPROC glad_glVertex3f = NULL; -PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; -PFNGLVERTEX3IPROC glad_glVertex3i = NULL; -PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; -PFNGLVERTEX3SPROC glad_glVertex3s = NULL; -PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; -PFNGLVERTEX4DPROC glad_glVertex4d = NULL; -PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; -PFNGLVERTEX4FPROC glad_glVertex4f = NULL; -PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; -PFNGLVERTEX4IPROC glad_glVertex4i = NULL; -PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; -PFNGLVERTEX4SPROC glad_glVertex4s = NULL; -PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; @@ -1308,42 +978,17 @@ PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; -PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; PFNGLVIEWPORTPROC glad_glViewport = NULL; PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; -PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; -PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; -PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; -PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; -PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; -PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; -PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; -PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; -PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; -PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; -PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; -PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; -PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; -PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; -PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; int GLAD_GL_ARB_buffer_storage = 0; +int GLAD_GL_ARB_clear_texture = 0; +int GLAD_GL_ARB_get_texture_sub_image = 0; +int GLAD_GL_EXT_buffer_storage = 0; int GLAD_GL_EXT_clip_cull_distance = 0; -int GLAD_GL_KHR_debug = 0; -PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; -PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; -PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; -PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; -PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; -PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; -PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; -PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; -PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; -PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; -PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; +PFNGLBUFFERSTORAGEEXTPROC glad_glBufferStorageEXT = NULL; static void load_GL_VERSION_1_0(GLADloadproc load) { if(!GLAD_GL_VERSION_1_0) return; glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); @@ -1394,270 +1039,11 @@ static void load_GL_VERSION_1_0(GLADloadproc load) { glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); - glad_glNewList = (PFNGLNEWLISTPROC)load("glNewList"); - glad_glEndList = (PFNGLENDLISTPROC)load("glEndList"); - glad_glCallList = (PFNGLCALLLISTPROC)load("glCallList"); - glad_glCallLists = (PFNGLCALLLISTSPROC)load("glCallLists"); - glad_glDeleteLists = (PFNGLDELETELISTSPROC)load("glDeleteLists"); - glad_glGenLists = (PFNGLGENLISTSPROC)load("glGenLists"); - glad_glListBase = (PFNGLLISTBASEPROC)load("glListBase"); - glad_glBegin = (PFNGLBEGINPROC)load("glBegin"); - glad_glBitmap = (PFNGLBITMAPPROC)load("glBitmap"); - glad_glColor3b = (PFNGLCOLOR3BPROC)load("glColor3b"); - glad_glColor3bv = (PFNGLCOLOR3BVPROC)load("glColor3bv"); - glad_glColor3d = (PFNGLCOLOR3DPROC)load("glColor3d"); - glad_glColor3dv = (PFNGLCOLOR3DVPROC)load("glColor3dv"); - glad_glColor3f = (PFNGLCOLOR3FPROC)load("glColor3f"); - glad_glColor3fv = (PFNGLCOLOR3FVPROC)load("glColor3fv"); - glad_glColor3i = (PFNGLCOLOR3IPROC)load("glColor3i"); - glad_glColor3iv = (PFNGLCOLOR3IVPROC)load("glColor3iv"); - glad_glColor3s = (PFNGLCOLOR3SPROC)load("glColor3s"); - glad_glColor3sv = (PFNGLCOLOR3SVPROC)load("glColor3sv"); - glad_glColor3ub = (PFNGLCOLOR3UBPROC)load("glColor3ub"); - glad_glColor3ubv = (PFNGLCOLOR3UBVPROC)load("glColor3ubv"); - glad_glColor3ui = (PFNGLCOLOR3UIPROC)load("glColor3ui"); - glad_glColor3uiv = (PFNGLCOLOR3UIVPROC)load("glColor3uiv"); - glad_glColor3us = (PFNGLCOLOR3USPROC)load("glColor3us"); - glad_glColor3usv = (PFNGLCOLOR3USVPROC)load("glColor3usv"); - glad_glColor4b = (PFNGLCOLOR4BPROC)load("glColor4b"); - glad_glColor4bv = (PFNGLCOLOR4BVPROC)load("glColor4bv"); - glad_glColor4d = (PFNGLCOLOR4DPROC)load("glColor4d"); - glad_glColor4dv = (PFNGLCOLOR4DVPROC)load("glColor4dv"); - glad_glColor4f = (PFNGLCOLOR4FPROC)load("glColor4f"); - glad_glColor4fv = (PFNGLCOLOR4FVPROC)load("glColor4fv"); - glad_glColor4i = (PFNGLCOLOR4IPROC)load("glColor4i"); - glad_glColor4iv = (PFNGLCOLOR4IVPROC)load("glColor4iv"); - glad_glColor4s = (PFNGLCOLOR4SPROC)load("glColor4s"); - glad_glColor4sv = (PFNGLCOLOR4SVPROC)load("glColor4sv"); - glad_glColor4ub = (PFNGLCOLOR4UBPROC)load("glColor4ub"); - glad_glColor4ubv = (PFNGLCOLOR4UBVPROC)load("glColor4ubv"); - glad_glColor4ui = (PFNGLCOLOR4UIPROC)load("glColor4ui"); - glad_glColor4uiv = (PFNGLCOLOR4UIVPROC)load("glColor4uiv"); - glad_glColor4us = (PFNGLCOLOR4USPROC)load("glColor4us"); - glad_glColor4usv = (PFNGLCOLOR4USVPROC)load("glColor4usv"); - glad_glEdgeFlag = (PFNGLEDGEFLAGPROC)load("glEdgeFlag"); - glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC)load("glEdgeFlagv"); - glad_glEnd = (PFNGLENDPROC)load("glEnd"); - glad_glIndexd = (PFNGLINDEXDPROC)load("glIndexd"); - glad_glIndexdv = (PFNGLINDEXDVPROC)load("glIndexdv"); - glad_glIndexf = (PFNGLINDEXFPROC)load("glIndexf"); - glad_glIndexfv = (PFNGLINDEXFVPROC)load("glIndexfv"); - glad_glIndexi = (PFNGLINDEXIPROC)load("glIndexi"); - glad_glIndexiv = (PFNGLINDEXIVPROC)load("glIndexiv"); - glad_glIndexs = (PFNGLINDEXSPROC)load("glIndexs"); - glad_glIndexsv = (PFNGLINDEXSVPROC)load("glIndexsv"); - glad_glNormal3b = (PFNGLNORMAL3BPROC)load("glNormal3b"); - glad_glNormal3bv = (PFNGLNORMAL3BVPROC)load("glNormal3bv"); - glad_glNormal3d = (PFNGLNORMAL3DPROC)load("glNormal3d"); - glad_glNormal3dv = (PFNGLNORMAL3DVPROC)load("glNormal3dv"); - glad_glNormal3f = (PFNGLNORMAL3FPROC)load("glNormal3f"); - glad_glNormal3fv = (PFNGLNORMAL3FVPROC)load("glNormal3fv"); - glad_glNormal3i = (PFNGLNORMAL3IPROC)load("glNormal3i"); - glad_glNormal3iv = (PFNGLNORMAL3IVPROC)load("glNormal3iv"); - glad_glNormal3s = (PFNGLNORMAL3SPROC)load("glNormal3s"); - glad_glNormal3sv = (PFNGLNORMAL3SVPROC)load("glNormal3sv"); - glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC)load("glRasterPos2d"); - glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)load("glRasterPos2dv"); - glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC)load("glRasterPos2f"); - glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)load("glRasterPos2fv"); - glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC)load("glRasterPos2i"); - glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)load("glRasterPos2iv"); - glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC)load("glRasterPos2s"); - glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)load("glRasterPos2sv"); - glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC)load("glRasterPos3d"); - glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)load("glRasterPos3dv"); - glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC)load("glRasterPos3f"); - glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)load("glRasterPos3fv"); - glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC)load("glRasterPos3i"); - glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)load("glRasterPos3iv"); - glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC)load("glRasterPos3s"); - glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)load("glRasterPos3sv"); - glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC)load("glRasterPos4d"); - glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)load("glRasterPos4dv"); - glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC)load("glRasterPos4f"); - glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)load("glRasterPos4fv"); - glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC)load("glRasterPos4i"); - glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)load("glRasterPos4iv"); - glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC)load("glRasterPos4s"); - glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)load("glRasterPos4sv"); - glad_glRectd = (PFNGLRECTDPROC)load("glRectd"); - glad_glRectdv = (PFNGLRECTDVPROC)load("glRectdv"); - glad_glRectf = (PFNGLRECTFPROC)load("glRectf"); - glad_glRectfv = (PFNGLRECTFVPROC)load("glRectfv"); - glad_glRecti = (PFNGLRECTIPROC)load("glRecti"); - glad_glRectiv = (PFNGLRECTIVPROC)load("glRectiv"); - glad_glRects = (PFNGLRECTSPROC)load("glRects"); - glad_glRectsv = (PFNGLRECTSVPROC)load("glRectsv"); - glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC)load("glTexCoord1d"); - glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)load("glTexCoord1dv"); - glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC)load("glTexCoord1f"); - glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)load("glTexCoord1fv"); - glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC)load("glTexCoord1i"); - glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)load("glTexCoord1iv"); - glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC)load("glTexCoord1s"); - glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)load("glTexCoord1sv"); - glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC)load("glTexCoord2d"); - glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)load("glTexCoord2dv"); - glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC)load("glTexCoord2f"); - glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)load("glTexCoord2fv"); - glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC)load("glTexCoord2i"); - glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)load("glTexCoord2iv"); - glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC)load("glTexCoord2s"); - glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)load("glTexCoord2sv"); - glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC)load("glTexCoord3d"); - glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)load("glTexCoord3dv"); - glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC)load("glTexCoord3f"); - glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)load("glTexCoord3fv"); - glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC)load("glTexCoord3i"); - glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)load("glTexCoord3iv"); - glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC)load("glTexCoord3s"); - glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)load("glTexCoord3sv"); - glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC)load("glTexCoord4d"); - glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)load("glTexCoord4dv"); - glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC)load("glTexCoord4f"); - glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)load("glTexCoord4fv"); - glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC)load("glTexCoord4i"); - glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)load("glTexCoord4iv"); - glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC)load("glTexCoord4s"); - glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)load("glTexCoord4sv"); - glad_glVertex2d = (PFNGLVERTEX2DPROC)load("glVertex2d"); - glad_glVertex2dv = (PFNGLVERTEX2DVPROC)load("glVertex2dv"); - glad_glVertex2f = (PFNGLVERTEX2FPROC)load("glVertex2f"); - glad_glVertex2fv = (PFNGLVERTEX2FVPROC)load("glVertex2fv"); - glad_glVertex2i = (PFNGLVERTEX2IPROC)load("glVertex2i"); - glad_glVertex2iv = (PFNGLVERTEX2IVPROC)load("glVertex2iv"); - glad_glVertex2s = (PFNGLVERTEX2SPROC)load("glVertex2s"); - glad_glVertex2sv = (PFNGLVERTEX2SVPROC)load("glVertex2sv"); - glad_glVertex3d = (PFNGLVERTEX3DPROC)load("glVertex3d"); - glad_glVertex3dv = (PFNGLVERTEX3DVPROC)load("glVertex3dv"); - glad_glVertex3f = (PFNGLVERTEX3FPROC)load("glVertex3f"); - glad_glVertex3fv = (PFNGLVERTEX3FVPROC)load("glVertex3fv"); - glad_glVertex3i = (PFNGLVERTEX3IPROC)load("glVertex3i"); - glad_glVertex3iv = (PFNGLVERTEX3IVPROC)load("glVertex3iv"); - glad_glVertex3s = (PFNGLVERTEX3SPROC)load("glVertex3s"); - glad_glVertex3sv = (PFNGLVERTEX3SVPROC)load("glVertex3sv"); - glad_glVertex4d = (PFNGLVERTEX4DPROC)load("glVertex4d"); - glad_glVertex4dv = (PFNGLVERTEX4DVPROC)load("glVertex4dv"); - glad_glVertex4f = (PFNGLVERTEX4FPROC)load("glVertex4f"); - glad_glVertex4fv = (PFNGLVERTEX4FVPROC)load("glVertex4fv"); - glad_glVertex4i = (PFNGLVERTEX4IPROC)load("glVertex4i"); - glad_glVertex4iv = (PFNGLVERTEX4IVPROC)load("glVertex4iv"); - glad_glVertex4s = (PFNGLVERTEX4SPROC)load("glVertex4s"); - glad_glVertex4sv = (PFNGLVERTEX4SVPROC)load("glVertex4sv"); - glad_glClipPlane = (PFNGLCLIPPLANEPROC)load("glClipPlane"); - glad_glColorMaterial = (PFNGLCOLORMATERIALPROC)load("glColorMaterial"); - glad_glFogf = (PFNGLFOGFPROC)load("glFogf"); - glad_glFogfv = (PFNGLFOGFVPROC)load("glFogfv"); - glad_glFogi = (PFNGLFOGIPROC)load("glFogi"); - glad_glFogiv = (PFNGLFOGIVPROC)load("glFogiv"); - glad_glLightf = (PFNGLLIGHTFPROC)load("glLightf"); - glad_glLightfv = (PFNGLLIGHTFVPROC)load("glLightfv"); - glad_glLighti = (PFNGLLIGHTIPROC)load("glLighti"); - glad_glLightiv = (PFNGLLIGHTIVPROC)load("glLightiv"); - glad_glLightModelf = (PFNGLLIGHTMODELFPROC)load("glLightModelf"); - glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC)load("glLightModelfv"); - glad_glLightModeli = (PFNGLLIGHTMODELIPROC)load("glLightModeli"); - glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC)load("glLightModeliv"); - glad_glLineStipple = (PFNGLLINESTIPPLEPROC)load("glLineStipple"); - glad_glMaterialf = (PFNGLMATERIALFPROC)load("glMaterialf"); - glad_glMaterialfv = (PFNGLMATERIALFVPROC)load("glMaterialfv"); - glad_glMateriali = (PFNGLMATERIALIPROC)load("glMateriali"); - glad_glMaterialiv = (PFNGLMATERIALIVPROC)load("glMaterialiv"); - glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)load("glPolygonStipple"); - glad_glShadeModel = (PFNGLSHADEMODELPROC)load("glShadeModel"); - glad_glTexEnvf = (PFNGLTEXENVFPROC)load("glTexEnvf"); - glad_glTexEnvfv = (PFNGLTEXENVFVPROC)load("glTexEnvfv"); - glad_glTexEnvi = (PFNGLTEXENVIPROC)load("glTexEnvi"); - glad_glTexEnviv = (PFNGLTEXENVIVPROC)load("glTexEnviv"); - glad_glTexGend = (PFNGLTEXGENDPROC)load("glTexGend"); - glad_glTexGendv = (PFNGLTEXGENDVPROC)load("glTexGendv"); - glad_glTexGenf = (PFNGLTEXGENFPROC)load("glTexGenf"); - glad_glTexGenfv = (PFNGLTEXGENFVPROC)load("glTexGenfv"); - glad_glTexGeni = (PFNGLTEXGENIPROC)load("glTexGeni"); - glad_glTexGeniv = (PFNGLTEXGENIVPROC)load("glTexGeniv"); - glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)load("glFeedbackBuffer"); - glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC)load("glSelectBuffer"); - glad_glRenderMode = (PFNGLRENDERMODEPROC)load("glRenderMode"); - glad_glInitNames = (PFNGLINITNAMESPROC)load("glInitNames"); - glad_glLoadName = (PFNGLLOADNAMEPROC)load("glLoadName"); - glad_glPassThrough = (PFNGLPASSTHROUGHPROC)load("glPassThrough"); - glad_glPopName = (PFNGLPOPNAMEPROC)load("glPopName"); - glad_glPushName = (PFNGLPUSHNAMEPROC)load("glPushName"); - glad_glClearAccum = (PFNGLCLEARACCUMPROC)load("glClearAccum"); - glad_glClearIndex = (PFNGLCLEARINDEXPROC)load("glClearIndex"); - glad_glIndexMask = (PFNGLINDEXMASKPROC)load("glIndexMask"); - glad_glAccum = (PFNGLACCUMPROC)load("glAccum"); - glad_glPopAttrib = (PFNGLPOPATTRIBPROC)load("glPopAttrib"); - glad_glPushAttrib = (PFNGLPUSHATTRIBPROC)load("glPushAttrib"); - glad_glMap1d = (PFNGLMAP1DPROC)load("glMap1d"); - glad_glMap1f = (PFNGLMAP1FPROC)load("glMap1f"); - glad_glMap2d = (PFNGLMAP2DPROC)load("glMap2d"); - glad_glMap2f = (PFNGLMAP2FPROC)load("glMap2f"); - glad_glMapGrid1d = (PFNGLMAPGRID1DPROC)load("glMapGrid1d"); - glad_glMapGrid1f = (PFNGLMAPGRID1FPROC)load("glMapGrid1f"); - glad_glMapGrid2d = (PFNGLMAPGRID2DPROC)load("glMapGrid2d"); - glad_glMapGrid2f = (PFNGLMAPGRID2FPROC)load("glMapGrid2f"); - glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC)load("glEvalCoord1d"); - glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)load("glEvalCoord1dv"); - glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC)load("glEvalCoord1f"); - glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)load("glEvalCoord1fv"); - glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC)load("glEvalCoord2d"); - glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)load("glEvalCoord2dv"); - glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC)load("glEvalCoord2f"); - glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)load("glEvalCoord2fv"); - glad_glEvalMesh1 = (PFNGLEVALMESH1PROC)load("glEvalMesh1"); - glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC)load("glEvalPoint1"); - glad_glEvalMesh2 = (PFNGLEVALMESH2PROC)load("glEvalMesh2"); - glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC)load("glEvalPoint2"); - glad_glAlphaFunc = (PFNGLALPHAFUNCPROC)load("glAlphaFunc"); - glad_glPixelZoom = (PFNGLPIXELZOOMPROC)load("glPixelZoom"); - glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)load("glPixelTransferf"); - glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)load("glPixelTransferi"); - glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC)load("glPixelMapfv"); - glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)load("glPixelMapuiv"); - glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC)load("glPixelMapusv"); - glad_glCopyPixels = (PFNGLCOPYPIXELSPROC)load("glCopyPixels"); - glad_glDrawPixels = (PFNGLDRAWPIXELSPROC)load("glDrawPixels"); - glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC)load("glGetClipPlane"); - glad_glGetLightfv = (PFNGLGETLIGHTFVPROC)load("glGetLightfv"); - glad_glGetLightiv = (PFNGLGETLIGHTIVPROC)load("glGetLightiv"); - glad_glGetMapdv = (PFNGLGETMAPDVPROC)load("glGetMapdv"); - glad_glGetMapfv = (PFNGLGETMAPFVPROC)load("glGetMapfv"); - glad_glGetMapiv = (PFNGLGETMAPIVPROC)load("glGetMapiv"); - glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC)load("glGetMaterialfv"); - glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC)load("glGetMaterialiv"); - glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)load("glGetPixelMapfv"); - glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)load("glGetPixelMapuiv"); - glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)load("glGetPixelMapusv"); - glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)load("glGetPolygonStipple"); - glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)load("glGetTexEnvfv"); - glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC)load("glGetTexEnviv"); - glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC)load("glGetTexGendv"); - glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC)load("glGetTexGenfv"); - glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC)load("glGetTexGeniv"); - glad_glIsList = (PFNGLISLISTPROC)load("glIsList"); - glad_glFrustum = (PFNGLFRUSTUMPROC)load("glFrustum"); - glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC)load("glLoadIdentity"); - glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC)load("glLoadMatrixf"); - glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC)load("glLoadMatrixd"); - glad_glMatrixMode = (PFNGLMATRIXMODEPROC)load("glMatrixMode"); - glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC)load("glMultMatrixf"); - glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC)load("glMultMatrixd"); - glad_glOrtho = (PFNGLORTHOPROC)load("glOrtho"); - glad_glPopMatrix = (PFNGLPOPMATRIXPROC)load("glPopMatrix"); - glad_glPushMatrix = (PFNGLPUSHMATRIXPROC)load("glPushMatrix"); - glad_glRotated = (PFNGLROTATEDPROC)load("glRotated"); - glad_glRotatef = (PFNGLROTATEFPROC)load("glRotatef"); - glad_glScaled = (PFNGLSCALEDPROC)load("glScaled"); - glad_glScalef = (PFNGLSCALEFPROC)load("glScalef"); - glad_glTranslated = (PFNGLTRANSLATEDPROC)load("glTranslated"); - glad_glTranslatef = (PFNGLTRANSLATEFPROC)load("glTranslatef"); } static void load_GL_VERSION_1_1(GLADloadproc load) { if(!GLAD_GL_VERSION_1_1) return; glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); @@ -1669,22 +1055,6 @@ static void load_GL_VERSION_1_1(GLADloadproc load) { glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); - glad_glArrayElement = (PFNGLARRAYELEMENTPROC)load("glArrayElement"); - glad_glColorPointer = (PFNGLCOLORPOINTERPROC)load("glColorPointer"); - glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)load("glDisableClientState"); - glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)load("glEdgeFlagPointer"); - glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)load("glEnableClientState"); - glad_glIndexPointer = (PFNGLINDEXPOINTERPROC)load("glIndexPointer"); - glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)load("glInterleavedArrays"); - glad_glNormalPointer = (PFNGLNORMALPOINTERPROC)load("glNormalPointer"); - glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)load("glTexCoordPointer"); - glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC)load("glVertexPointer"); - glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)load("glAreTexturesResident"); - glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)load("glPrioritizeTextures"); - glad_glIndexub = (PFNGLINDEXUBPROC)load("glIndexub"); - glad_glIndexubv = (PFNGLINDEXUBVPROC)load("glIndexubv"); - glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)load("glPopClientAttrib"); - glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)load("glPushClientAttrib"); } static void load_GL_VERSION_1_2(GLADloadproc load) { if(!GLAD_GL_VERSION_1_2) return; @@ -1704,43 +1074,6 @@ static void load_GL_VERSION_1_3(GLADloadproc load) { glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); - glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)load("glClientActiveTexture"); - glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)load("glMultiTexCoord1d"); - glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)load("glMultiTexCoord1dv"); - glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)load("glMultiTexCoord1f"); - glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)load("glMultiTexCoord1fv"); - glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)load("glMultiTexCoord1i"); - glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)load("glMultiTexCoord1iv"); - glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)load("glMultiTexCoord1s"); - glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)load("glMultiTexCoord1sv"); - glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)load("glMultiTexCoord2d"); - glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)load("glMultiTexCoord2dv"); - glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)load("glMultiTexCoord2f"); - glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)load("glMultiTexCoord2fv"); - glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)load("glMultiTexCoord2i"); - glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)load("glMultiTexCoord2iv"); - glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)load("glMultiTexCoord2s"); - glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)load("glMultiTexCoord2sv"); - glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)load("glMultiTexCoord3d"); - glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)load("glMultiTexCoord3dv"); - glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)load("glMultiTexCoord3f"); - glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)load("glMultiTexCoord3fv"); - glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)load("glMultiTexCoord3i"); - glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)load("glMultiTexCoord3iv"); - glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)load("glMultiTexCoord3s"); - glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)load("glMultiTexCoord3sv"); - glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)load("glMultiTexCoord4d"); - glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)load("glMultiTexCoord4dv"); - glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)load("glMultiTexCoord4f"); - glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)load("glMultiTexCoord4fv"); - glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)load("glMultiTexCoord4i"); - glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)load("glMultiTexCoord4iv"); - glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)load("glMultiTexCoord4s"); - glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)load("glMultiTexCoord4sv"); - glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)load("glLoadTransposeMatrixf"); - glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)load("glLoadTransposeMatrixd"); - glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)load("glMultTransposeMatrixf"); - glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)load("glMultTransposeMatrixd"); } static void load_GL_VERSION_1_4(GLADloadproc load) { if(!GLAD_GL_VERSION_1_4) return; @@ -1751,44 +1084,6 @@ static void load_GL_VERSION_1_4(GLADloadproc load) { glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); - glad_glFogCoordf = (PFNGLFOGCOORDFPROC)load("glFogCoordf"); - glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC)load("glFogCoordfv"); - glad_glFogCoordd = (PFNGLFOGCOORDDPROC)load("glFogCoordd"); - glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC)load("glFogCoorddv"); - glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)load("glFogCoordPointer"); - glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)load("glSecondaryColor3b"); - glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)load("glSecondaryColor3bv"); - glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)load("glSecondaryColor3d"); - glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)load("glSecondaryColor3dv"); - glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)load("glSecondaryColor3f"); - glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)load("glSecondaryColor3fv"); - glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)load("glSecondaryColor3i"); - glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)load("glSecondaryColor3iv"); - glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)load("glSecondaryColor3s"); - glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)load("glSecondaryColor3sv"); - glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)load("glSecondaryColor3ub"); - glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)load("glSecondaryColor3ubv"); - glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)load("glSecondaryColor3ui"); - glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)load("glSecondaryColor3uiv"); - glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)load("glSecondaryColor3us"); - glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)load("glSecondaryColor3usv"); - glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)load("glSecondaryColorPointer"); - glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)load("glWindowPos2d"); - glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)load("glWindowPos2dv"); - glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)load("glWindowPos2f"); - glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)load("glWindowPos2fv"); - glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)load("glWindowPos2i"); - glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)load("glWindowPos2iv"); - glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)load("glWindowPos2s"); - glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)load("glWindowPos2sv"); - glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)load("glWindowPos3d"); - glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)load("glWindowPos3dv"); - glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)load("glWindowPos3f"); - glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)load("glWindowPos3fv"); - glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)load("glWindowPos3i"); - glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)load("glWindowPos3iv"); - glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)load("glWindowPos3s"); - glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)load("glWindowPos3sv"); glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); } @@ -2458,35 +1753,21 @@ static void load_GL_ARB_buffer_storage(GLADloadproc load) { if(!GLAD_GL_ARB_buffer_storage) return; glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC)load("glBufferStorage"); } -static void load_GL_KHR_debug(GLADloadproc load) { - if(!GLAD_GL_KHR_debug) return; - glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)load("glDebugMessageControl"); - glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)load("glDebugMessageInsert"); - glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)load("glDebugMessageCallback"); - glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)load("glGetDebugMessageLog"); - glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)load("glPushDebugGroup"); - glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)load("glPopDebugGroup"); - glad_glObjectLabel = (PFNGLOBJECTLABELPROC)load("glObjectLabel"); - glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)load("glGetObjectLabel"); - glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)load("glObjectPtrLabel"); - glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)load("glGetObjectPtrLabel"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); - glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC)load("glDebugMessageControlKHR"); - glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC)load("glDebugMessageInsertKHR"); - glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC)load("glDebugMessageCallbackKHR"); - glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC)load("glGetDebugMessageLogKHR"); - glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC)load("glPushDebugGroupKHR"); - glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC)load("glPopDebugGroupKHR"); - glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC)load("glObjectLabelKHR"); - glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC)load("glGetObjectLabelKHR"); - glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC)load("glObjectPtrLabelKHR"); - glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC)load("glGetObjectPtrLabelKHR"); - glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC)load("glGetPointervKHR"); +static void load_GL_ARB_clear_texture(GLADloadproc load) { + if(!GLAD_GL_ARB_clear_texture) return; + glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)load("glClearTexImage"); + glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)load("glClearTexSubImage"); +} +static void load_GL_ARB_get_texture_sub_image(GLADloadproc load) { + if(!GLAD_GL_ARB_get_texture_sub_image) return; + glad_glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)load("glGetTextureSubImage"); + glad_glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)load("glGetCompressedTextureSubImage"); } static int find_extensionsGL(void) { if (!get_exts()) return 0; GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage"); - GLAD_GL_KHR_debug = has_ext("GL_KHR_debug"); + GLAD_GL_ARB_clear_texture = has_ext("GL_ARB_clear_texture"); + GLAD_GL_ARB_get_texture_sub_image = has_ext("GL_ARB_get_texture_sub_image"); free_exts(); return 1; } @@ -2580,7 +1861,8 @@ int gladLoadGLLoader(GLADloadproc load) { if (!find_extensionsGL()) return 0; load_GL_ARB_buffer_storage(load); - load_GL_KHR_debug(load); + load_GL_ARB_clear_texture(load); + load_GL_ARB_get_texture_sub_image(load); return GLVersion.major != 0 || GLVersion.minor != 0; } @@ -2954,10 +2236,14 @@ static void load_GL_ES_VERSION_3_2(GLADloadproc load) { glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)load("glTexBufferRange"); glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)load("glTexStorage3DMultisample"); } +static void load_GL_EXT_buffer_storage(GLADloadproc load) { + if(!GLAD_GL_EXT_buffer_storage) return; + glad_glBufferStorageEXT = (PFNGLBUFFERSTORAGEEXTPROC)load("glBufferStorageEXT"); +} static int find_extensionsGLES2(void) { if (!get_exts()) return 0; + GLAD_GL_EXT_buffer_storage = has_ext("GL_EXT_buffer_storage"); GLAD_GL_EXT_clip_cull_distance = has_ext("GL_EXT_clip_cull_distance"); - GLAD_GL_KHR_debug = has_ext("GL_KHR_debug"); free_exts(); return 1; } @@ -3020,7 +2306,7 @@ int gladLoadGLES2Loader(GLADloadproc load) { load_GL_ES_VERSION_3_2(load); if (!find_extensionsGLES2()) return 0; - load_GL_KHR_debug(load); + load_GL_EXT_buffer_storage(load); return GLVersion.major != 0 || GLVersion.minor != 0; } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java index 0b683d575..3aa73f99e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java @@ -496,9 +496,6 @@ public final class NativeLibrary { final int ErrorLoader_ErrorEncrypted = 5; final int ErrorLoader_ErrorInvalidFormat = 6; final int ErrorSystemFiles = 7; - final int ErrorVideoCore = 8; - final int ErrorVideoCore_ErrorGenericDrivers = 9; - final int ErrorVideoCore_ErrorBelowGL33 = 10; final int ShutdownRequested = 11; final int ErrorUnknown = 12; diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.java b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.java index d3bf9e5e1..c8e8ad23f 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.java @@ -355,6 +355,7 @@ public final class SettingsFragmentPresenter { mView.getActivity().setTitle(R.string.preferences_graphics); SettingSection rendererSection = mSettings.getSection(Settings.SECTION_RENDERER); + Setting graphicsApi = rendererSection.getSetting(SettingsFile.KEY_GRAPHICS_API); Setting resolutionFactor = rendererSection.getSetting(SettingsFile.KEY_RESOLUTION_FACTOR); Setting filterMode = rendererSection.getSetting(SettingsFile.KEY_FILTER_MODE); Setting shadersAccurateMul = rendererSection.getSetting(SettingsFile.KEY_SHADERS_ACCURATE_MUL); @@ -371,6 +372,7 @@ public final class SettingsFragmentPresenter { //Setting preloadTextures = utilitySection.getSetting(SettingsFile.KEY_PRELOAD_TEXTURES); sl.add(new HeaderSetting(null, null, R.string.renderer, 0)); + sl.add(new SingleChoiceSetting(SettingsFile.KEY_GRAPHICS_API, Settings.SECTION_RENDERER, R.string.graphics_api, 0, R.array.graphicsApiNames, R.array.graphicsApiValues, 0, graphicsApi)); sl.add(new SliderSetting(SettingsFile.KEY_RESOLUTION_FACTOR, Settings.SECTION_RENDERER, R.string.internal_resolution, R.string.internal_resolution_description, 1, 4, "x", 1, resolutionFactor)); sl.add(new CheckBoxSetting(SettingsFile.KEY_FILTER_MODE, Settings.SECTION_RENDERER, R.string.linear_filtering, R.string.linear_filtering_description, true, filterMode)); sl.add(new CheckBoxSetting(SettingsFile.KEY_SHADERS_ACCURATE_MUL, Settings.SECTION_RENDERER, R.string.shaders_accurate_mul, R.string.shaders_accurate_mul_description, false, shadersAccurateMul)); @@ -409,14 +411,14 @@ public final class SettingsFragmentPresenter { SettingSection coreSection = mSettings.getSection(Settings.SECTION_CORE); SettingSection rendererSection = mSettings.getSection(Settings.SECTION_RENDERER); Setting useCpuJit = coreSection.getSetting(SettingsFile.KEY_CPU_JIT); - Setting hardwareRenderer = rendererSection.getSetting(SettingsFile.KEY_HW_RENDERER); Setting hardwareShader = rendererSection.getSetting(SettingsFile.KEY_HW_SHADER); Setting vsyncEnable = rendererSection.getSetting(SettingsFile.KEY_USE_VSYNC); + Setting rendererDebug = rendererSection.getSetting(SettingsFile.KEY_RENDERER_DEBUG); sl.add(new HeaderSetting(null, null, R.string.debug_warning, 0)); sl.add(new CheckBoxSetting(SettingsFile.KEY_CPU_JIT, Settings.SECTION_CORE, R.string.cpu_jit, R.string.cpu_jit_description, true, useCpuJit, true, mView)); - sl.add(new CheckBoxSetting(SettingsFile.KEY_HW_RENDERER, Settings.SECTION_RENDERER, R.string.hw_renderer, R.string.hw_renderer_description, true, hardwareRenderer, true, mView)); sl.add(new CheckBoxSetting(SettingsFile.KEY_HW_SHADER, Settings.SECTION_RENDERER, R.string.hw_shaders, R.string.hw_shaders_description, true, hardwareShader, true, mView)); sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_VSYNC, Settings.SECTION_RENDERER, R.string.vsync, R.string.vsync_description, true, vsyncEnable)); + sl.add(new CheckBoxSetting(SettingsFile.KEY_RENDERER_DEBUG, Settings.SECTION_RENDERER, R.string.renderer_debug, R.string.renderer_debug_description, false, rendererDebug)); } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.java b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.java index 4246b50f6..908d7eae7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.java @@ -44,7 +44,8 @@ public final class SettingsFile { public static final String KEY_PREMIUM = "premium"; - public static final String KEY_HW_RENDERER = "use_hw_renderer"; + public static final String KEY_GRAPHICS_API = "graphics_api"; + public static final String KEY_RENDERER_DEBUG = "renderer_debug"; public static final String KEY_HW_SHADER = "use_hw_shader"; public static final String KEY_SHADERS_ACCURATE_MUL = "shaders_accurate_mul"; public static final String KEY_USE_SHADER_JIT = "use_shader_jit"; diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 019dcee5d..2cd0f76a4 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -82,6 +82,30 @@ void Config::UpdateCFG() { cfg->UpdateConfigNANDSavegame(); } +template <> +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); + if (setting_value.empty()) { + setting_value = setting.GetDefault(); + } + setting = std::move(setting_value); +} + +template <> +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); +} + +template +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + if constexpr (std::is_floating_point_v) { + setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault()); + } else { + setting = static_cast(sdl2_config->GetInteger( + group, setting.GetLabel(), static_cast(setting.GetDefault()))); + } +} + void Config::ReadValues() { // Controls for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { @@ -112,39 +136,32 @@ void Config::ReadValues() { InputCommon::CemuhookUDP::DEFAULT_PORT)); // Core - Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); - Settings::values.cpu_clock_percentage = - static_cast(sdl2_config->GetInteger("Core", "cpu_clock_percentage", 100)); + ReadSetting("Core", Settings::values.use_cpu_jit); + ReadSetting("Core", Settings::values.cpu_clock_percentage); // Premium - Settings::values.texture_filter_name = - sdl2_config->GetString("Premium", "texture_filter_name", "none"); + ReadSetting("Premium", Settings::values.texture_filter_name); // Renderer Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", true); - Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); - Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true); Settings::values.shaders_accurate_mul = sdl2_config->GetBoolean("Renderer", "shaders_accurate_mul", false); - Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); - Settings::values.resolution_factor = - static_cast(sdl2_config->GetInteger("Renderer", "resolution_factor", 1)); - Settings::values.use_disk_shader_cache = - sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true); - Settings::values.use_vsync_new = sdl2_config->GetBoolean("Renderer", "use_vsync_new", true); + ReadSetting("Renderer", Settings::values.graphics_api); + ReadSetting("Renderer", Settings::values.use_hw_shader); + ReadSetting("Renderer", Settings::values.use_shader_jit); + ReadSetting("Renderer", Settings::values.resolution_factor); + ReadSetting("Renderer", Settings::values.use_disk_shader_cache); + ReadSetting("Renderer", Settings::values.use_vsync_new); // Work around to map Android setting for enabling the frame limiter to the format Citra expects if (sdl2_config->GetBoolean("Renderer", "use_frame_limit", true)) { - Settings::values.frame_limit = - static_cast(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); + ReadSetting("Renderer", Settings::values.frame_limit); } else { Settings::values.frame_limit = 0; } - Settings::values.render_3d = static_cast( - sdl2_config->GetInteger("Renderer", "render_3d", 0)); - Settings::values.factor_3d = - static_cast(sdl2_config->GetInteger("Renderer", "factor_3d", 0)); + ReadSetting("Renderer", Settings::values.render_3d); + ReadSetting("Renderer", Settings::values.factor_3d); std::string default_shader = "none (builtin)"; if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph) default_shader = "dubois (builtin)"; @@ -152,70 +169,49 @@ void Config::ReadValues() { default_shader = "horizontal (builtin)"; Settings::values.pp_shader_name = sdl2_config->GetString("Renderer", "pp_shader_name", default_shader); - Settings::values.filter_mode = sdl2_config->GetBoolean("Renderer", "filter_mode", true); + ReadSetting("Renderer", Settings::values.filter_mode); - Settings::values.bg_red = static_cast(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); - Settings::values.bg_green = - static_cast(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); - Settings::values.bg_blue = static_cast(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); + ReadSetting("Renderer", Settings::values.bg_red); + ReadSetting("Renderer", Settings::values.bg_green); + ReadSetting("Renderer", Settings::values.bg_blue); // Layout Settings::values.layout_option = static_cast(sdl2_config->GetInteger( "Layout", "layout_option", static_cast(Settings::LayoutOption::MobileLandscape))); - Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false); - Settings::values.custom_top_left = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_left", 0)); - Settings::values.custom_top_top = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_top", 0)); - Settings::values.custom_top_right = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_right", 400)); - Settings::values.custom_top_bottom = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_bottom", 240)); - Settings::values.custom_bottom_left = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_left", 40)); - Settings::values.custom_bottom_top = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_top", 240)); - Settings::values.custom_bottom_right = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_right", 360)); - Settings::values.custom_bottom_bottom = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_bottom", 480)); - Settings::values.cardboard_screen_size = - static_cast(sdl2_config->GetInteger("Layout", "cardboard_screen_size", 85)); - Settings::values.cardboard_x_shift = - static_cast(sdl2_config->GetInteger("Layout", "cardboard_x_shift", 0)); - Settings::values.cardboard_y_shift = - static_cast(sdl2_config->GetInteger("Layout", "cardboard_y_shift", 0)); + ReadSetting("Layout", Settings::values.custom_layout); + ReadSetting("Layout", Settings::values.custom_top_left); + ReadSetting("Layout", Settings::values.custom_top_top); + ReadSetting("Layout", Settings::values.custom_top_right); + ReadSetting("Layout", Settings::values.custom_top_bottom); + ReadSetting("Layout", Settings::values.custom_bottom_left); + ReadSetting("Layout", Settings::values.custom_bottom_top); + ReadSetting("Layout", Settings::values.custom_bottom_right); + ReadSetting("Layout", Settings::values.custom_bottom_bottom); + ReadSetting("Layout", Settings::values.cardboard_screen_size); + ReadSetting("Layout", Settings::values.cardboard_x_shift); + ReadSetting("Layout", Settings::values.cardboard_y_shift); // Utility - Settings::values.dump_textures = sdl2_config->GetBoolean("Utility", "dump_textures", false); - Settings::values.custom_textures = sdl2_config->GetBoolean("Utility", "custom_textures", false); - Settings::values.preload_textures = - sdl2_config->GetBoolean("Utility", "preload_textures", false); + ReadSetting("Utility", Settings::values.dump_textures); + ReadSetting("Utility", Settings::values.custom_textures); + ReadSetting("Utility", Settings::values.preload_textures); // Audio - Settings::values.audio_emulation = - static_cast(sdl2_config->GetInteger( - "Audio", "audio_emulation", static_cast(Settings::AudioEmulation::HLE))); - Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto"); - Settings::values.enable_audio_stretching = - sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); - Settings::values.audio_device_id = sdl2_config->GetString("Audio", "output_device", "auto"); - Settings::values.volume = static_cast(sdl2_config->GetReal("Audio", "volume", 1)); - Settings::values.mic_input_device = - sdl2_config->GetString("Audio", "mic_input_device", "Default"); - Settings::values.mic_input_type = - static_cast(sdl2_config->GetInteger("Audio", "mic_input_type", 1)); + ReadSetting("Audio", Settings::values.audio_emulation); + ReadSetting("Audio", Settings::values.sink_id); + ReadSetting("Audio", Settings::values.enable_audio_stretching); + ReadSetting("Audio", Settings::values.audio_device_id); + ReadSetting("Audio", Settings::values.volume); + ReadSetting("Audio", Settings::values.mic_input_device); + ReadSetting("Audio", Settings::values.mic_input_type); // Data Storage - Settings::values.use_virtual_sd = - sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); + ReadSetting("Data Storage", Settings::values.use_virtual_sd); // System - Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", true); - Settings::values.region_value = - sdl2_config->GetInteger("System", "region_value", Settings::REGION_VALUE_AUTO_SELECT); - Settings::values.init_clock = - static_cast(sdl2_config->GetInteger("System", "init_clock", 0)); + ReadSetting("System", Settings::values.is_new_3ds); + ReadSetting("System", Settings::values.region_value); + ReadSetting("System", Settings::values.init_clock); { std::tm t; t.tm_sec = 1; @@ -236,10 +232,8 @@ void Config::ReadValues() { std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch()) .count(); } - Settings::values.plugin_loader_enabled = - sdl2_config->GetBoolean("System", "plugin_loader", false); - Settings::values.allow_plugin_loader = - sdl2_config->GetBoolean("System", "allow_plugin_loader", true); + ReadSetting("System", Settings::values.plugin_loader_enabled); + ReadSetting("System", Settings::values.allow_plugin_loader); // Camera using namespace Service::CAM; @@ -263,14 +257,14 @@ void Config::ReadValues() { sdl2_config->GetInteger("Camera", "camera_outer_left_flip", 0); // Miscellaneous - Settings::values.log_filter = sdl2_config->GetString("Miscellaneous", "log_filter", "*:Info"); + ReadSetting("Miscellaneous", Settings::values.log_filter); // Debugging Settings::values.record_frame_times = sdl2_config->GetBoolean("Debugging", "record_frame_times", false); - Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); - Settings::values.gdbstub_port = - static_cast(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); + ReadSetting("Debugging", Settings::values.renderer_debug); + ReadSetting("Debugging", Settings::values.use_gdbstub); + ReadSetting("Debugging", Settings::values.gdbstub_port); for (const auto& service_module : Service::service_module_map) { bool use_lle = sdl2_config->GetBoolean("Debugging", "LLE\\" + service_module.name, false); diff --git a/src/android/app/src/main/jni/config.h b/src/android/app/src/main/jni/config.h index 465457856..162225728 100644 --- a/src/android/app/src/main/jni/config.h +++ b/src/android/app/src/main/jni/config.h @@ -6,6 +6,7 @@ #include #include +#include "common/settings.h" class INIReader; @@ -23,4 +24,14 @@ public: ~Config(); void Reload(); + +private: + /** + * Applies a value read from the sdl2_config to a Setting. + * + * @param group The name of the INI group + * @param setting The yuzu setting to modify + */ + template + void ReadSetting(const std::string& group, Settings::Setting& setting); }; diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index 875f595a0..8ea457703 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -98,13 +98,9 @@ use_cpu_jit = cpu_clock_percentage = [Renderer] -# Whether to render using GLES or OpenGL -# 0: OpenGL, 1 (default): GLES -use_gles = - -# Whether to use software or hardware rendering. -# 0: Software, 1 (default): Hardware -use_hw_renderer = +# Whether to render using OpenGL +# 1: OpenGLES (default) +graphics_api = # Whether to use hardware shaders to emulate 3DS shaders # 0: Software, 1 (default): Hardware @@ -118,10 +114,6 @@ separable_shader = # 0: Off (Default. Faster, but causes issues in some games) 1: On (Slower, but correct) shaders_accurate_mul = -# Enable asynchronous GPU emulation -# 0: Off (Slower, but more accurate) 1: On (Default. Faster, but may cause issues in some games) -use_asynchronous_gpu_emulation = - # Whether to use the Just-In-Time (JIT) compiler for shader emulation # 0: Interpreter (slow), 1 (default): JIT (fast) use_shader_jit = @@ -325,9 +317,15 @@ log_filter = *:Info [Debugging] # Record frame time data, can be found in the log directory. Boolean value record_frame_times = + +# Whether to enable additional debugging information during emulation +# 0 (default): Off, 1: On +renderer_debug = + # Port for listening to GDB connections. use_gdbstub=false gdbstub_port=24689 + # To LLE a service module add "LLE\=true" [WebService] diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index a91971a15..272b2a9b1 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -25,7 +25,6 @@ #include "core/frontend/applets/default_applets.h" #include "core/frontend/camera/factory.h" #include "core/frontend/mic.h" -#include "core/frontend/scope_acquire_context.h" #include "core/hle/service/am/am.h" #include "core/hle/service/nfc/nfc.h" #include "core/savestate.h" @@ -46,6 +45,7 @@ #include "jni/ndk_motion.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/texture_filters/texture_filterer.h" +#include "video_core/video_core.h" namespace { @@ -149,7 +149,15 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) { return Core::System::ResultStatus::ErrorLoader; } - window = std::make_unique(s_surf); + const auto graphics_api = Settings::values.graphics_api.GetValue(); + switch (graphics_api) { + case Settings::GraphicsAPI::OpenGL: + window = std::make_unique(s_surf); + break; + default: + LOG_CRITICAL(Frontend, "Unknown graphics API {}, using OpenGL", graphics_api); + window = std::make_unique(s_surf); + } Core::System& system{Core::System::GetInstance()}; diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index 56d279596..8f0da4db1 100644 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -58,8 +58,6 @@ Aktiviert lineare Filterung, welche die Spieletexturen glättet. Texturfilter Verbessert die Grafik von Spielen durch das Anwendung eines Texturfilters. Die unterstützten Filter sind Anime4K Ultrafast, Bicubic, ScaleForce und xBRZ freescale. - Aktiviere Hardware Renderer - Benutzt Hardware, um die 3DS-Grafik zu emulieren. Wenn aktiviert, wird die Spieleleistung stark verbessert. Aktiviere Hardware Shader Benutzt Hardware, um die 3DS-Shader zu emulieren. Wenn aktiviert, wird die Spieleleistung stark verbessert. Aktiviere genaue Shader-Multiplikation diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 22d8f0da3..2088c6a9d 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -62,8 +62,6 @@ Activa el filtro linear, que hace que los gráficos del juego se vean más suaves. Filtro de Texturas Mejora los gráficos visuales de los juegos al aplicar un filtro a las texturas. Los filtros soportados son Anime4K Ultrafast, Bicubic, ScaleForce, y xBRZ freescale. - Activar renderizador de hardware - Usa el hardware para emular los gráficos de 3DS. Cuando se active, el rendimiento mejorará notablemente. Activar sombreador de hardware Usa el hardware para emular los sombreadores de 3DS. Cuando se active, el rendimiento mejorará notablemente. Activar multiplicación precisa de sombreado diff --git a/src/android/app/src/main/res/values-fi/strings.xml b/src/android/app/src/main/res/values-fi/strings.xml index 60c131349..f15709acd 100644 --- a/src/android/app/src/main/res/values-fi/strings.xml +++ b/src/android/app/src/main/res/values-fi/strings.xml @@ -46,8 +46,6 @@ Aktivoi V-Sync Synkronoi pelin virkistystaajuus laitteesi virkistystaajuuteen. - Aktivoi Laitteistorenderöinti - Käyttää laitteistoa emuloidakseen 3DS-grafiikoita. Kun tämä on päällä, pelien suorituskyky on huomattavasti parempi. Aktivoi Laitteistovarjostin Käyttää laitteistoa emuloidakseen 3DS:n varjostimia. Kun tämä on päällä, pelien suorituskyky on huomattavasti parempi. Aktivoi nopeuden rajoitus diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index 7752f7f13..3a1ba075e 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -58,8 +58,6 @@ Active le filtrage linéaire, qui améliorera le lissage graphique du jeu. Filtrage des textures Améliore l\'aspect graphique des jeux en appliquant un filtre aux textures. Les filtres supportés sont Anime4K Ultrafast, Bicubic, ScaleForce, et xBRZ freescale. - Activer le rendu matériel - Utilise le matériel pour émuler les graphismes de la 3DS. Lorsqu\'il est activé, la performance des jeux sera améliorée de manière significative. Activer le shader (nuanceur) matériel Utilise le matériel pour émuler les shaders de la 3DS. Lorsqu\'il est activé, la performance des jeux sera améliorée de manière significative. Activer la multiplication précise dans les shaders diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml index 92cab12ba..dbce0c63a 100644 --- a/src/android/app/src/main/res/values-it/strings.xml +++ b/src/android/app/src/main/res/values-it/strings.xml @@ -58,8 +58,6 @@ Abilita il filtro lineare, che fa sembrare più smussata la grafica dei giochi. Filtro Texture Migliora la grafica dei giochi applicando un filtro alle texture. I filtri supportati sono Anime4k Ultrafast, Bicubic, ScaleForce, e xBRZ freescale. - Abilita renderer hardware - Utilizza l\'hardware per emulare la grafica del 3DS. Se abilitato, le prestazioni dei giochi miglioreranno significativamente. Abilita shader hardware Utilizza l\'hardware per emulare gli shader del 3DS. Se abilitato, le prestazioni dei giochi miglioreranno significativamente. Abilita moltiplicazione shader accurata diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml index dc391230f..4232d24c3 100644 --- a/src/android/app/src/main/res/values-ja/strings.xml +++ b/src/android/app/src/main/res/values-ja/strings.xml @@ -40,8 +40,6 @@ リニアフィルタリングを有効化 有効にすると、よりなめらかな画質が期待できます。 テクスチャフィルタ - ハードウェアレンダラを有効にする - グラフィックエミュレーションにハードウェアを使用します。有効にすると、パフォーマンスが大幅に向上します。 ハードウェアシェーダを有効にする シェーダエミュレーションにハードウェアを使用します。有効にすると、パフォーマンスが大幅に向上します。 正確なシェーダ乗算を有効にする diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml index 3499f17b7..017c733b9 100644 --- a/src/android/app/src/main/res/values-ko/strings.xml +++ b/src/android/app/src/main/res/values-ko/strings.xml @@ -58,8 +58,6 @@ 게임 필터링이 매끄럽게 보이도록 선형 필터링을 활성화합니다. 텍스처 필터 텍스처에 필터를 적용하여 게임의 시각적 효과를 향상시킵니다. 지원되는 필터는 Anime4K Ultrafast, Bicubic, ScaleForce 및 xBRZ 프리스케일입니다. - 하드웨어 렌더러 사용 - 하드웨어를 사용하여 3DS 그래픽을 에뮬레이션합니다. 활성화하면 게임 성능이 크게 향상됩니다. 하드웨어 쉐이더 사용 하드웨어를 사용하여 3DS 쉐이더를 에뮬레이션합니다. 활성화하면 게임 성능이 크게 향상됩니다. 정확한 쉐이더 곱셉 사용 diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml index bdbf0206f..f72d24056 100644 --- a/src/android/app/src/main/res/values-nb/strings.xml +++ b/src/android/app/src/main/res/values-nb/strings.xml @@ -58,8 +58,6 @@ Aktiverer lineær filtrering, noe som får spillvisualer til å vises jevnere. Tekstur Filter Forbedrer det visuelle i spill ved å bruke et filter på teksturer. De støttede filtrene er Anime4K Ultrafast, Bicubic, ScaleForce og xBRZ freescale. - Aktiver maskinvaregjengivelse - Bruker maskinvare til å emulere 3DS grafikk. Når dette er aktivert, vil spillytelsen bli betydelig forbedret. Aktiver maskinvare shader Bruker maskinvare for å etterligne 3DS shaders. Når dette er aktivert, vil spillytelsen bli betydelig forbedret. Aktiver nøyaktig shader-multiplikasjon diff --git a/src/android/app/src/main/res/values-pt/strings.xml b/src/android/app/src/main/res/values-pt/strings.xml index 7f6b71a8a..b00f6b8e4 100644 --- a/src/android/app/src/main/res/values-pt/strings.xml +++ b/src/android/app/src/main/res/values-pt/strings.xml @@ -58,8 +58,6 @@ Ativa a filtragem linear, que suaviza o visual do jogo. Filtro de texturas Aprimora o visual dos jogos ao aplicar filtros às texturas. Os filtros compatíveis são: Anime4K Ultrafast, Bicúbico, ScaleForce e xBRZ Freescale. - Ativar renderizador por hardware - Utiliza o hardware para emular os gráficos do 3DS. Quando ativado, o desempenho de jogo será consideravelmente melhorado. Ativar shaders via hardware Utiliza o hardware para emular os shaders do 3DS. Quando ativado, o desempenho do jogo será consideravelmente melhorado. Ativar multiplicação precisa de shaders diff --git a/src/android/app/src/main/res/values-zh/strings.xml b/src/android/app/src/main/res/values-zh/strings.xml index 57a85ddb5..ab2d9939b 100644 --- a/src/android/app/src/main/res/values-zh/strings.xml +++ b/src/android/app/src/main/res/values-zh/strings.xml @@ -58,8 +58,6 @@ 开启后,游戏视觉效果会更加平滑。 纹理滤镜 通过对纹理使用滤镜来增强游戏的视觉效果。支持的滤镜有 Anime4K Ultrafast, Bicubic, ScaleForce 和 xBRZ freescale。 - 启用硬件渲染器 - 使用硬件模拟 3DS 图形。启用后,游戏性能将显著提高。 启用硬件着色器 使用硬件模拟 3DS 着色器。启用后,游戏性能将显著提高。 启用精确乘法运算 diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index c948e6a8b..223714d0a 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -171,4 +171,12 @@ 4 5 + + + OpenGLES + + + + 1 + diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 7ce41141e..add6fe47e 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -72,14 +72,15 @@ Renderer + Graphics API + Enable debug renderer + Log additional graphics related debug information. When enabled, game performance will be significantly reduced Enable V-Sync Synchronizes the game frame rate to the refresh rate of your device. Enable linear filtering Enables linear filtering, which causes game visuals to appear smoother. Texture Filter Enhances the visuals of games by applying a filter to textures. The supported filters are Anime4K Ultrafast, Bicubic, ScaleForce, and xBRZ freescale. - Enable hardware renderer - Uses hardware to emulate 3DS graphics. When enabled, game performance will be significantly improved. Enable hardware shader Uses hardware to emulate 3DS shaders. When enabled, game performance will be significantly improved. Enable accurate shader multiplication diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt index affbec3f8..55494d376 100644 --- a/src/citra/CMakeLists.txt +++ b/src/citra/CMakeLists.txt @@ -8,6 +8,10 @@ add_executable(citra default_ini.h emu_window/emu_window_sdl2.cpp emu_window/emu_window_sdl2.h + emu_window/emu_window_sdl2_gl.cpp + emu_window/emu_window_sdl2_gl.h + emu_window/emu_window_sdl2_sw.cpp + emu_window/emu_window_sdl2_sw.h lodepng_image_interface.cpp lodepng_image_interface.h precompiled_headers.h diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index acd3092cc..ea3e6b102 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -13,6 +13,8 @@ #include "citra/config.h" #include "citra/emu_window/emu_window_sdl2.h" +#include "citra/emu_window/emu_window_sdl2_gl.h" +#include "citra/emu_window/emu_window_sdl2_sw.h" #include "citra/lodepng_image_interface.h" #include "common/common_paths.h" #include "common/detached_tasks.h" @@ -29,7 +31,6 @@ #include "core/file_sys/cia_container.h" #include "core/frontend/applets/default_applets.h" #include "core/frontend/framebuffer_layout.h" -#include "core/frontend/scope_acquire_context.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/service/am/am.h" #include "core/hle/service/cfg/cfg.h" @@ -38,6 +39,7 @@ #include "input_common/main.h" #include "network/network.h" #include "video_core/renderer_base.h" +#include "video_core/video_core.h" #undef _UNICODE #include @@ -362,13 +364,23 @@ int main(int argc, char** argv) { EmuWindow_SDL2::InitializeSDL2(); - const auto emu_window{std::make_unique(fullscreen, false)}; - const bool use_secondary_window{Settings::values.layout_option.GetValue() == - Settings::LayoutOption::SeparateWindows}; - const auto secondary_window = - use_secondary_window ? std::make_unique(false, true) : nullptr; + const auto CreateEmuWindow = [](bool fullscreen, + bool is_secondary) -> std::unique_ptr { + switch (Settings::values.graphics_api.GetValue()) { + case Settings::GraphicsAPI::OpenGL: + return std::make_unique(fullscreen, is_secondary); + case Settings::GraphicsAPI::Software: + return std::make_unique(fullscreen, is_secondary); + } + }; - Frontend::ScopeAcquireContext scope(*emu_window); + const auto emu_window{CreateEmuWindow(fullscreen, false)}; + const bool use_secondary_window{ + Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows && + Settings::values.graphics_api.GetValue() != Settings::GraphicsAPI::Software}; + const auto secondary_window = use_secondary_window ? CreateEmuWindow(false, true) : nullptr; + + const auto scope = emu_window->Acquire(); LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); @@ -400,9 +412,6 @@ int main(int argc, char** argv) { case Core::System::ResultStatus::ErrorSystemMode: LOG_CRITICAL(Frontend, "Failed to determine system mode!"); return -1; - case Core::System::ResultStatus::ErrorVideoCore: - LOG_CRITICAL(Frontend, "VideoCore not initialized"); - return -1; case Core::System::ResultStatus::Success: break; // Expected case default: diff --git a/src/citra/config.cpp b/src/citra/config.cpp index acf85e4e1..cb7f4b10d 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,30 @@ static const std::array, Settings::NativeAnalog::NumAnalogs> }, }}; +template <> +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); + if (setting_value.empty()) { + setting_value = setting.GetDefault(); + } + setting = std::move(setting_value); +} + +template <> +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); +} + +template +void Config::ReadSetting(const std::string& group, Settings::Setting& setting) { + if constexpr (std::is_floating_point_v) { + setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault()); + } else { + setting = static_cast(sdl2_config->GetInteger( + group, setting.GetLabel(), static_cast(setting.GetDefault()))); + } +} + void Config::ReadValues() { // Controls // TODO: add multiple input profile support @@ -104,104 +129,71 @@ void Config::ReadValues() { InputCommon::CemuhookUDP::DEFAULT_PORT)); // Core - Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); - Settings::values.cpu_clock_percentage = - sdl2_config->GetInteger("Core", "cpu_clock_percentage", 100); + ReadSetting("Core", Settings::values.use_cpu_jit); + ReadSetting("Core", Settings::values.cpu_clock_percentage); // Renderer - Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", false); - Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); - Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true); + ReadSetting("Renderer", Settings::values.graphics_api); + ReadSetting("Renderer", Settings::values.use_gles); + ReadSetting("Renderer", Settings::values.use_hw_shader); #ifdef __APPLE__ // Separable shader is broken on macos with Intel GPU thanks to poor drivers. // We still want to provide this option for test/development purposes, but disable it by // default. - Settings::values.separable_shader = - sdl2_config->GetBoolean("Renderer", "separable_shader", false); + ReadSetting("Renderer", Settings::values.separable_shader); #endif - Settings::values.shaders_accurate_mul = - sdl2_config->GetBoolean("Renderer", "shaders_accurate_mul", true); - Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); - Settings::values.resolution_factor = - static_cast(sdl2_config->GetInteger("Renderer", "resolution_factor", 1)); - Settings::values.use_disk_shader_cache = - sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true); - Settings::values.frame_limit = - static_cast(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); - Settings::values.use_vsync_new = - static_cast(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1)); - Settings::values.texture_filter_name = - sdl2_config->GetString("Renderer", "texture_filter_name", "none"); + ReadSetting("Renderer", Settings::values.shaders_accurate_mul); + ReadSetting("Renderer", Settings::values.use_shader_jit); + ReadSetting("Renderer", Settings::values.resolution_factor); + ReadSetting("Renderer", Settings::values.use_disk_shader_cache); + ReadSetting("Renderer", Settings::values.frame_limit); + ReadSetting("Renderer", Settings::values.use_vsync_new); + ReadSetting("Renderer", Settings::values.texture_filter_name); - Settings::values.mono_render_option = static_cast( - sdl2_config->GetInteger("Renderer", "mono_render_option", 0)); - Settings::values.render_3d = static_cast( - sdl2_config->GetInteger("Renderer", "render_3d", 0)); - Settings::values.factor_3d = - static_cast(sdl2_config->GetInteger("Renderer", "factor_3d", 0)); - Settings::values.pp_shader_name = - sdl2_config->GetString("Renderer", "pp_shader_name", "none (builtin)"); - Settings::values.anaglyph_shader_name = - sdl2_config->GetString("Renderer", "anaglyph_shader_name", "dubois (builtin)"); - Settings::values.filter_mode = sdl2_config->GetBoolean("Renderer", "filter_mode", true); + ReadSetting("Renderer", Settings::values.mono_render_option); + ReadSetting("Renderer", Settings::values.render_3d); + ReadSetting("Renderer", Settings::values.factor_3d); + ReadSetting("Renderer", Settings::values.pp_shader_name); + ReadSetting("Renderer", Settings::values.anaglyph_shader_name); + ReadSetting("Renderer", Settings::values.filter_mode); - Settings::values.bg_red = static_cast(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); - Settings::values.bg_green = - static_cast(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); - Settings::values.bg_blue = static_cast(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); + ReadSetting("Renderer", Settings::values.bg_red); + ReadSetting("Renderer", Settings::values.bg_green); + ReadSetting("Renderer", Settings::values.bg_blue); // Layout - Settings::values.layout_option = - static_cast(sdl2_config->GetInteger("Layout", "layout_option", 0)); - Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false); - Settings::values.upright_screen = sdl2_config->GetBoolean("Layout", "upright_screen", false); - Settings::values.large_screen_proportion = - sdl2_config->GetReal("Layout", "large_screen_proportion", 4.0); - Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false); - Settings::values.custom_top_left = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_left", 0)); - Settings::values.custom_top_top = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_top", 0)); - Settings::values.custom_top_right = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_right", 400)); - Settings::values.custom_top_bottom = - static_cast(sdl2_config->GetInteger("Layout", "custom_top_bottom", 240)); - Settings::values.custom_bottom_left = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_left", 40)); - Settings::values.custom_bottom_top = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_top", 240)); - Settings::values.custom_bottom_right = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_right", 360)); - Settings::values.custom_bottom_bottom = - static_cast(sdl2_config->GetInteger("Layout", "custom_bottom_bottom", 480)); - Settings::values.custom_second_layer_opacity = - static_cast(sdl2_config->GetInteger("Layout", "custom_second_layer_opacity", 100)); + ReadSetting("Layout", Settings::values.layout_option); + ReadSetting("Layout", Settings::values.swap_screen); + ReadSetting("Layout", Settings::values.upright_screen); + ReadSetting("Layout", Settings::values.large_screen_proportion); + ReadSetting("Layout", Settings::values.custom_layout); + ReadSetting("Layout", Settings::values.custom_top_left); + ReadSetting("Layout", Settings::values.custom_top_top); + ReadSetting("Layout", Settings::values.custom_top_right); + ReadSetting("Layout", Settings::values.custom_top_bottom); + ReadSetting("Layout", Settings::values.custom_bottom_left); + ReadSetting("Layout", Settings::values.custom_bottom_top); + ReadSetting("Layout", Settings::values.custom_bottom_right); + ReadSetting("Layout", Settings::values.custom_bottom_bottom); + ReadSetting("Layout", Settings::values.custom_second_layer_opacity); // Utility - Settings::values.dump_textures = sdl2_config->GetBoolean("Utility", "dump_textures", false); - Settings::values.custom_textures = sdl2_config->GetBoolean("Utility", "custom_textures", false); - Settings::values.preload_textures = - sdl2_config->GetBoolean("Utility", "preload_textures", false); + ReadSetting("Utility", Settings::values.dump_textures); + ReadSetting("Utility", Settings::values.custom_textures); + ReadSetting("Utility", Settings::values.preload_textures); // Audio - Settings::values.audio_emulation = static_cast( - sdl2_config->GetInteger("Audio", "audio_emulation", 0)); - Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto"); - Settings::values.enable_audio_stretching = - sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); - Settings::values.audio_device_id = sdl2_config->GetString("Audio", "output_device", "auto"); - Settings::values.volume = static_cast(sdl2_config->GetReal("Audio", "volume", 1)); - Settings::values.mic_input_device = - sdl2_config->GetString("Audio", "mic_input_device", Frontend::Mic::default_device_name); - Settings::values.mic_input_type = - static_cast(sdl2_config->GetInteger("Audio", "mic_input_type", 0)); + ReadSetting("Audio", Settings::values.audio_emulation); + ReadSetting("Audio", Settings::values.sink_id); + ReadSetting("Audio", Settings::values.enable_audio_stretching); + ReadSetting("Audio", Settings::values.audio_device_id); + ReadSetting("Audio", Settings::values.volume); + ReadSetting("Audio", Settings::values.mic_input_device); + ReadSetting("Audio", Settings::values.mic_input_type); // Data Storage - Settings::values.use_virtual_sd = - sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); - - Settings::values.use_custom_storage = - sdl2_config->GetBoolean("Data Storage", "use_custom_storage", false); + ReadSetting("Data Storage", Settings::values.use_virtual_sd); + ReadSetting("Data Storage", Settings::values.use_custom_storage); if (Settings::values.use_custom_storage) { FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir, @@ -211,11 +203,9 @@ void Config::ReadValues() { } // System - Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", true); - Settings::values.region_value = - sdl2_config->GetInteger("System", "region_value", Settings::REGION_VALUE_AUTO_SELECT); - Settings::values.init_clock = - static_cast(sdl2_config->GetInteger("System", "init_clock", 1)); + ReadSetting("System", Settings::values.is_new_3ds); + ReadSetting("System", Settings::values.region_value); + ReadSetting("System", Settings::values.init_clock); { std::tm t; t.tm_sec = 1; @@ -236,6 +226,8 @@ void Config::ReadValues() { std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch()) .count(); } + ReadSetting("System", Settings::values.plugin_loader_enabled); + ReadSetting("System", Settings::values.allow_plugin_loader); { constexpr const char* default_init_time_offset = "0 00:00:00"; @@ -311,14 +303,14 @@ void Config::ReadValues() { sdl2_config->GetInteger("Camera", "camera_outer_left_flip", 0); // Miscellaneous - Settings::values.log_filter = sdl2_config->GetString("Miscellaneous", "log_filter", "*:Info"); + ReadSetting("Miscellaneous", Settings::values.log_filter); // Debugging Settings::values.record_frame_times = sdl2_config->GetBoolean("Debugging", "record_frame_times", false); - Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); - Settings::values.gdbstub_port = - static_cast(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); + ReadSetting("Debugging", Settings::values.renderer_debug); + ReadSetting("Debugging", Settings::values.use_gdbstub); + ReadSetting("Debugging", Settings::values.gdbstub_port); for (const auto& service_module : Service::service_module_map) { bool use_lle = sdl2_config->GetBoolean("Debugging", "LLE\\" + service_module.name, false); diff --git a/src/citra/config.h b/src/citra/config.h index abc90f642..22a71891b 100644 --- a/src/citra/config.h +++ b/src/citra/config.h @@ -6,6 +6,7 @@ #include #include +#include "common/settings.h" class INIReader; @@ -21,4 +22,14 @@ public: ~Config(); void Reload(); + +private: + /** + * Applies a value read from the sdl2_config to a Setting. + * + * @param group The name of the INI group + * @param setting The yuzu setting to modify + */ + template + void ReadSetting(const std::string& group, Settings::Setting& setting); }; diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index c545aa77d..692134590 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -98,14 +98,14 @@ use_cpu_jit = cpu_clock_percentage = [Renderer] +# Whether to render using OpenGL or Software +# 0: Software, 1: OpenGL (default) +graphics_api = + # Whether to render using GLES or OpenGL # 0 (default): OpenGL, 1: GLES use_gles = -# Whether to use software or hardware rendering. -# 0: Software, 1 (default): Hardware -use_hw_renderer = - # Whether to use hardware shaders to emulate 3DS shaders # 0: Software, 1 (default): Hardware use_hw_shader = @@ -328,9 +328,15 @@ log_filter = *:Info [Debugging] # Record frame time data, can be found in the log directory. Boolean value record_frame_times = + # Port for listening to GDB connections. use_gdbstub=false gdbstub_port=24689 + +# Whether to enable additional debugging information during emulation +# 0 (default): Off, 1: On +renderer_debug = + # To LLE a service module add "LLE\=true" [WebService] diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp index 9e7b7924f..c7d2513b5 100644 --- a/src/citra/emu_window/emu_window_sdl2.cpp +++ b/src/citra/emu_window/emu_window_sdl2.cpp @@ -7,40 +7,14 @@ #include #define SDL_MAIN_HANDLED #include -#include -#include #include "citra/emu_window/emu_window_sdl2.h" #include "common/logging/log.h" #include "common/scm_rev.h" -#include "common/settings.h" -#include "core/3ds.h" #include "core/core.h" #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/motion_emu.h" -#include "input_common/sdl/sdl.h" #include "network/network.h" -#include "video_core/renderer_base.h" -#include "video_core/video_core.h" - -SharedContext_SDL2::SharedContext_SDL2() { - window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, - SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); - context = SDL_GL_CreateContext(window); -} - -SharedContext_SDL2::~SharedContext_SDL2() { - SDL_GL_DeleteContext(context); - SDL_DestroyWindow(window); -} - -void SharedContext_SDL2::MakeCurrent() { - SDL_GL_MakeCurrent(window, context); -} - -void SharedContext_SDL2::DoneCurrent() { - SDL_GL_MakeCurrent(window, nullptr); -} void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); @@ -135,78 +109,9 @@ void EmuWindow_SDL2::Fullscreen() { SDL_MaximizeWindow(render_window); } -EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen, bool is_secondary) : EmuWindow(is_secondary) { - // Initialize the window - if (Settings::values.use_gles) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - } else { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - } - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); - // Enable context sharing for the shared context - SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); - // Enable vsync - SDL_GL_SetSwapInterval(1); - - std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_fullname, - Common::g_scm_branch, Common::g_scm_desc); - render_window = - SDL_CreateWindow(window_title.c_str(), - SDL_WINDOWPOS_UNDEFINED, // x position - SDL_WINDOWPOS_UNDEFINED, // y position - Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - - if (render_window == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 window: {}", SDL_GetError()); - exit(1); - } - - dummy_window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, - SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); - - if (fullscreen) { - Fullscreen(); - } - - window_context = SDL_GL_CreateContext(render_window); - core_context = CreateSharedContext(); - last_saved_context = nullptr; - - if (window_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); - exit(1); - } - if (core_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create shared SDL2 GL context: {}", SDL_GetError()); - exit(1); - } - - render_window_id = SDL_GetWindowID(render_window); - auto gl_load_func = Settings::values.use_gles ? gladLoadGLES2Loader : gladLoadGLLoader; - - if (!gl_load_func(static_cast(SDL_GL_GetProcAddress))) { - LOG_CRITICAL(Frontend, "Failed to initialize GL functions: {}", SDL_GetError()); - exit(1); - } - - OnResize(); - OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); - SDL_PumpEvents(); -} +EmuWindow_SDL2::EmuWindow_SDL2(bool is_secondary) : EmuWindow(is_secondary) {} EmuWindow_SDL2::~EmuWindow_SDL2() { - core_context.reset(); - SDL_GL_DeleteContext(window_context); SDL_Quit(); } @@ -222,28 +127,6 @@ void EmuWindow_SDL2::InitializeSDL2() { SDL_SetMainReady(); } -std::unique_ptr EmuWindow_SDL2::CreateSharedContext() const { - return std::make_unique(); -} - -void EmuWindow_SDL2::SaveContext() { - last_saved_context = SDL_GL_GetCurrentContext(); -} - -void EmuWindow_SDL2::RestoreContext() { - SDL_GL_MakeCurrent(render_window, last_saved_context); -} - -void EmuWindow_SDL2::Present() { - SDL_GL_MakeCurrent(render_window, window_context); - SDL_GL_SetSwapInterval(1); - while (IsOpen()) { - VideoCore::g_renderer->TryPresent(100, is_secondary); - SDL_GL_SwapWindow(render_window); - } - SDL_GL_MakeCurrent(render_window, nullptr); -} - void EmuWindow_SDL2::PollEvents() { SDL_Event event; std::vector other_window_events; @@ -312,14 +195,6 @@ void EmuWindow_SDL2::PollEvents() { } } -void EmuWindow_SDL2::MakeCurrent() { - core_context->MakeCurrent(); -} - -void EmuWindow_SDL2::DoneCurrent() { - core_context->DoneCurrent(); -} - void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/citra/emu_window/emu_window_sdl2.h b/src/citra/emu_window/emu_window_sdl2.h index e5f3cdf2b..db85a5c62 100644 --- a/src/citra/emu_window/emu_window_sdl2.h +++ b/src/citra/emu_window/emu_window_sdl2.h @@ -10,56 +10,27 @@ struct SDL_Window; -class SharedContext_SDL2 : public Frontend::GraphicsContext { -public: - using SDL_GLContext = void*; - - SharedContext_SDL2(); - - ~SharedContext_SDL2() override; - - void MakeCurrent() override; - - void DoneCurrent() override; - -private: - SDL_GLContext context; - SDL_Window* window; -}; - class EmuWindow_SDL2 : public Frontend::EmuWindow { public: - explicit EmuWindow_SDL2(bool fullscreen, bool is_secondary); + explicit EmuWindow_SDL2(bool is_secondary); ~EmuWindow_SDL2(); + /// Initializes SDL2 static void InitializeSDL2(); - void Present(); + /// Presents the most recent frame from the video backend + virtual void Present() {} /// Polls window events void PollEvents() override; - /// Makes the graphics context current for the caller thread - void MakeCurrent() override; - - /// Releases the GL context from the caller thread - void DoneCurrent() override; - /// Whether the window is still open, and a close request hasn't yet been sent bool IsOpen() const; /// Close the window. void RequestClose(); - /// Creates a new context that is shared with the current context - std::unique_ptr CreateSharedContext() const override; - - /// Saves the current context, for the purpose of e.g. creating new shared contexts - void SaveContext() override; - /// Restores the context previously saved - void RestoreContext() override; - -private: +protected: /// Called by PollEvents when a key is pressed or released. void OnKeyEvent(int key, u8 state); @@ -105,17 +76,6 @@ private: /// Fake hidden window for the core context SDL_Window* dummy_window; - using SDL_GLContext = void*; - - /// The OpenGL context associated with the window - SDL_GLContext window_context; - - /// Used by SaveContext and RestoreContext - SDL_GLContext last_saved_context; - - /// The OpenGL context associated with the core - std::unique_ptr core_context; - /// Keeps track of how often to update the title bar during gameplay u32 last_time = 0; }; diff --git a/src/citra/emu_window/emu_window_sdl2_gl.cpp b/src/citra/emu_window/emu_window_sdl2_gl.cpp new file mode 100644 index 000000000..46098a7e7 --- /dev/null +++ b/src/citra/emu_window/emu_window_sdl2_gl.cpp @@ -0,0 +1,152 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#define SDL_MAIN_HANDLED +#include +#include +#include "citra/emu_window/emu_window_sdl2_gl.h" +#include "common/scm_rev.h" +#include "video_core/renderer_base.h" +#include "video_core/video_core.h" + +class SDLGLContext : public Frontend::GraphicsContext { +public: + using SDL_GLContext = void*; + + SDLGLContext() { + window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + context = SDL_GL_CreateContext(window); + } + + ~SDLGLContext() override { + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); + } + + void MakeCurrent() override { + SDL_GL_MakeCurrent(window, context); + } + + void DoneCurrent() override { + SDL_GL_MakeCurrent(window, nullptr); + } + +private: + SDL_Window* window; + SDL_GLContext context; +}; + +EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen, bool is_secondary) + : EmuWindow_SDL2{is_secondary} { + // Initialize the window + if (Settings::values.use_gles) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + } else { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + } + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); + // Enable context sharing for the shared context + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + // Enable vsync + SDL_GL_SetSwapInterval(1); + // Enable debug context + if (Settings::values.renderer_debug) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); + } + + std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_fullname, + Common::g_scm_branch, Common::g_scm_desc); + render_window = + SDL_CreateWindow(window_title.c_str(), + SDL_WINDOWPOS_UNDEFINED, // x position + SDL_WINDOWPOS_UNDEFINED, // y position + Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + + if (render_window == nullptr) { + LOG_CRITICAL(Frontend, "Failed to create SDL2 window: {}", SDL_GetError()); + exit(1); + } + + dummy_window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + + if (fullscreen) { + Fullscreen(); + } + + window_context = SDL_GL_CreateContext(render_window); + core_context = CreateSharedContext(); + last_saved_context = nullptr; + + if (window_context == nullptr) { + LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); + exit(1); + } + if (core_context == nullptr) { + LOG_CRITICAL(Frontend, "Failed to create shared SDL2 GL context: {}", SDL_GetError()); + exit(1); + } + + render_window_id = SDL_GetWindowID(render_window); + auto gl_load_func = Settings::values.use_gles ? gladLoadGLES2Loader : gladLoadGLLoader; + + if (!gl_load_func(static_cast(SDL_GL_GetProcAddress))) { + LOG_CRITICAL(Frontend, "Failed to initialize GL functions: {}", SDL_GetError()); + exit(1); + } + + OnResize(); + OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); + SDL_PumpEvents(); +} + +EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() { + core_context.reset(); + SDL_DestroyWindow(render_window); + SDL_GL_DeleteContext(window_context); +} + +std::unique_ptr EmuWindow_SDL2_GL::CreateSharedContext() const { + return std::make_unique(); +} + +void EmuWindow_SDL2_GL::MakeCurrent() { + core_context->MakeCurrent(); +} + +void EmuWindow_SDL2_GL::DoneCurrent() { + core_context->DoneCurrent(); +} + +void EmuWindow_SDL2_GL::SaveContext() { + last_saved_context = SDL_GL_GetCurrentContext(); +} + +void EmuWindow_SDL2_GL::RestoreContext() { + SDL_GL_MakeCurrent(render_window, last_saved_context); +} + +void EmuWindow_SDL2_GL::Present() { + SDL_GL_MakeCurrent(render_window, window_context); + SDL_GL_SetSwapInterval(1); + while (IsOpen()) { + VideoCore::g_renderer->TryPresent(100, is_secondary); + SDL_GL_SwapWindow(render_window); + } + SDL_GL_MakeCurrent(render_window, nullptr); +} diff --git a/src/citra/emu_window/emu_window_sdl2_gl.h b/src/citra/emu_window/emu_window_sdl2_gl.h new file mode 100644 index 000000000..e56cd2c42 --- /dev/null +++ b/src/citra/emu_window/emu_window_sdl2_gl.h @@ -0,0 +1,35 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "citra/emu_window/emu_window_sdl2.h" + +struct SDL_Window; + +class EmuWindow_SDL2_GL : public EmuWindow_SDL2 { +public: + explicit EmuWindow_SDL2_GL(bool fullscreen, bool is_secondary); + ~EmuWindow_SDL2_GL(); + + void Present() override; + std::unique_ptr CreateSharedContext() const override; + void MakeCurrent() override; + void DoneCurrent() override; + void SaveContext() override; + void RestoreContext() override; + +private: + using SDL_GLContext = void*; + + /// The OpenGL context associated with the window + SDL_GLContext window_context; + + /// Used by SaveContext and RestoreContext + SDL_GLContext last_saved_context; + + /// The OpenGL context associated with the core + std::unique_ptr core_context; +}; diff --git a/src/citra/emu_window/emu_window_sdl2_sw.cpp b/src/citra/emu_window/emu_window_sdl2_sw.cpp new file mode 100644 index 000000000..c4ac3b9c3 --- /dev/null +++ b/src/citra/emu_window/emu_window_sdl2_sw.cpp @@ -0,0 +1,127 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#define SDL_MAIN_HANDLED +#include +#include +#include "citra/emu_window/emu_window_sdl2_sw.h" +#include "common/color.h" +#include "common/scm_rev.h" +#include "core/frontend/emu_window.h" +#include "core/hw/gpu.h" +#include "core/memory.h" +#include "video_core/video_core.h" + +class DummyContext : public Frontend::GraphicsContext {}; + +EmuWindow_SDL2_SW::EmuWindow_SDL2_SW(bool fullscreen, bool is_secondary) + : EmuWindow_SDL2{is_secondary} { + std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_fullname, + Common::g_scm_branch, Common::g_scm_desc); + render_window = + SDL_CreateWindow(window_title.c_str(), + SDL_WINDOWPOS_UNDEFINED, // x position + SDL_WINDOWPOS_UNDEFINED, // y position + Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, + SDL_WINDOW_SHOWN); + + if (render_window == nullptr) { + LOG_CRITICAL(Frontend, "Failed to create SDL2 window: {}", SDL_GetError()); + exit(1); + } + + window_surface = SDL_GetWindowSurface(render_window); + renderer = SDL_CreateSoftwareRenderer(window_surface); + + if (fullscreen) { + Fullscreen(); + } + + render_window_id = SDL_GetWindowID(render_window); + + OnResize(); + OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); + SDL_PumpEvents(); +} + +EmuWindow_SDL2_SW::~EmuWindow_SDL2_SW() { + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(render_window); +} + +std::unique_ptr EmuWindow_SDL2_SW::CreateSharedContext() const { + return std::make_unique(); +} + +void EmuWindow_SDL2_SW::Present() { + const auto layout{Layout::DefaultFrameLayout( + Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, false, false)}; + + while (IsOpen()) { + SDL_SetRenderDrawColor(renderer, Settings::values.bg_red.GetValue() * 255, + Settings::values.bg_green.GetValue() * 255, + Settings::values.bg_blue.GetValue() * 255, 0xFF); + SDL_RenderClear(renderer); + + const auto draw_screen = [&](int fb_id) { + const auto dst_rect = fb_id == 0 ? layout.top_screen : layout.bottom_screen; + SDL_Rect sdl_rect{static_cast(dst_rect.left), static_cast(dst_rect.top), + static_cast(dst_rect.GetWidth()), + static_cast(dst_rect.GetHeight())}; + SDL_Surface* screen = LoadFramebuffer(fb_id); + SDL_BlitSurface(screen, nullptr, window_surface, &sdl_rect); + SDL_FreeSurface(screen); + }; + + draw_screen(0); + draw_screen(1); + + SDL_RenderPresent(renderer); + SDL_UpdateWindowSurface(render_window); + } +} + +SDL_Surface* EmuWindow_SDL2_SW::LoadFramebuffer(int fb_id) { + const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id]; + const PAddr framebuffer_addr = + framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2; + + Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height); + const u8* framebuffer_data = VideoCore::g_memory->GetPhysicalPointer(framebuffer_addr); + + const int width = framebuffer.height; + const int height = framebuffer.width; + const int bpp = GPU::Regs::BytesPerPixel(framebuffer.color_format); + + SDL_Surface* surface = + SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_ABGR8888); + SDL_LockSurface(surface); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + const u8* pixel = framebuffer_data + (x * height + height - y) * bpp; + const Common::Vec4 color = [&] { + switch (framebuffer.color_format) { + case GPU::Regs::PixelFormat::RGBA8: + return Common::Color::DecodeRGBA8(pixel); + case GPU::Regs::PixelFormat::RGB8: + return Common::Color::DecodeRGB8(pixel); + case GPU::Regs::PixelFormat::RGB565: + return Common::Color::DecodeRGB565(pixel); + case GPU::Regs::PixelFormat::RGB5A1: + return Common::Color::DecodeRGB5A1(pixel); + case GPU::Regs::PixelFormat::RGBA4: + return Common::Color::DecodeRGBA4(pixel); + } + }(); + + u8* dst_pixel = reinterpret_cast(surface->pixels) + (y * width + x) * 4; + std::memcpy(dst_pixel, color.AsArray(), sizeof(color)); + } + } + SDL_UnlockSurface(surface); + return surface; +} diff --git a/src/citra/emu_window/emu_window_sdl2_sw.h b/src/citra/emu_window/emu_window_sdl2_sw.h new file mode 100644 index 000000000..e1d35f687 --- /dev/null +++ b/src/citra/emu_window/emu_window_sdl2_sw.h @@ -0,0 +1,32 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "citra/emu_window/emu_window_sdl2.h" + +struct SDL_Renderer; +struct SDL_Surface; + +class EmuWindow_SDL2_SW : public EmuWindow_SDL2 { +public: + explicit EmuWindow_SDL2_SW(bool fullscreen, bool is_secondary); + ~EmuWindow_SDL2_SW(); + + void Present() override; + std::unique_ptr CreateSharedContext() const override; + void MakeCurrent() override {} + void DoneCurrent() override {} + +private: + /// Loads a framebuffer to an SDL surface + SDL_Surface* LoadFramebuffer(int fb_id); + + /// The SDL software renderer + SDL_Renderer* renderer; + + /// The window surface + SDL_Surface* window_surface; +}; diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 07be722c5..5b4e9802d 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -269,6 +269,10 @@ target_link_libraries(citra-qt PRIVATE audio_core common core input_common netwo target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt5::Widgets Qt5::Multimedia Qt5::Concurrent) target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) +if (NOT WIN32) + target_include_directories(citra-qt PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) +endif() + if (UNIX AND NOT APPLE) target_link_libraries(citra-qt PRIVATE Qt5::DBus) endif() @@ -325,6 +329,10 @@ if (MSVC) endif() endif() +if (NOT APPLE) + target_compile_definitions(citra-qt PRIVATE HAS_OPENGL) +endif() + if (CITRA_USE_PRECOMPILED_HEADERS) target_precompile_headers(citra-qt PRIVATE precompiled_headers.h) endif() diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index ef89f890b..be58060b1 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -2,31 +2,45 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include + #include #include #include #include -#include -#include -#include -#include +#include +#include #include #include "citra_qt/bootmanager.h" #include "citra_qt/main.h" +#include "common/color.h" #include "common/microprofile.h" #include "common/scm_rev.h" #include "common/settings.h" #include "core/3ds.h" #include "core/core.h" -#include "core/frontend/scope_acquire_context.h" +#include "core/frontend/framebuffer_layout.h" #include "core/perf_stats.h" #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/motion_emu.h" -#include "network/network.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" +#ifdef HAS_OPENGL +#include +#include +#endif + +#if defined(__APPLE__) +#include +#include +#endif + +#if !defined(WIN32) +#include +#endif + EmuThread::EmuThread(Frontend::GraphicsContext& core_context) : core_context(core_context) {} EmuThread::~EmuThread() = default; @@ -44,7 +58,7 @@ static GMainWindow* GetMainWindow() { void EmuThread::run() { MicroProfileOnThreadCreate("EmuThread"); - Frontend::ScopeAcquireContext scope(core_context); + const auto scope = core_context.Acquire(); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); @@ -55,6 +69,7 @@ void EmuThread::run() { }); emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); + emit HideLoadingScreen(); core_context.MakeCurrent(); @@ -113,90 +128,263 @@ void EmuThread::run() { #endif } -OpenGLWindow::OpenGLWindow(QWindow* parent, QWidget* event_handler, QOpenGLContext* shared_context, - bool is_secondary) - : QWindow(parent), context(std::make_unique(shared_context->parent())), - event_handler(event_handler), is_secondary{is_secondary} { +#ifdef HAS_OPENGL +class OpenGLSharedContext : public Frontend::GraphicsContext { +public: + /// Create the original context that should be shared from + explicit OpenGLSharedContext() { + QSurfaceFormat format; - // disable vsync for any shared contexts - auto format = shared_context->format(); - format.setSwapInterval(Settings::values.use_vsync_new ? 1 : 0); - this->setFormat(format); + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); - context->setShareContext(shared_context); - context->setScreen(this->screen()); - context->setFormat(format); - context->create(); + if (Settings::values.renderer_debug) { + format.setOption(QSurfaceFormat::FormatOption::DebugContext); + } - setSurfaceType(QWindow::OpenGLSurface); + // TODO: expose a setting for buffer value (ie default/single/double/triple) + format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); + format.setSwapInterval(0); - // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, - // WA_DontShowOnScreen, WA_DeleteOnClose -} + context = std::make_unique(); + context->setFormat(format); + if (!context->create()) { + LOG_ERROR(Frontend, "Unable to create main openGL context"); + } -OpenGLWindow::~OpenGLWindow() { - context->doneCurrent(); -} - -void OpenGLWindow::Present() { - if (!isExposed()) - return; - - context->makeCurrent(this); - if (VideoCore::g_renderer) { - VideoCore::g_renderer->TryPresent(100, is_secondary); + offscreen_surface = std::make_unique(nullptr); + offscreen_surface->setFormat(format); + offscreen_surface->create(); + surface = offscreen_surface.get(); } - context->swapBuffers(this); - auto f = context->versionFunctions(); - f->glFinish(); - QWindow::requestUpdate(); -} -bool OpenGLWindow::event(QEvent* event) { - switch (event->type()) { - case QEvent::UpdateRequest: + /// Create the shared contexts for rendering and presentation + explicit OpenGLSharedContext(QOpenGLContext* share_context, QSurface* main_surface) { + + // disable vsync for any shared contexts + auto format = share_context->format(); + format.setSwapInterval(main_surface ? Settings::values.use_vsync_new.GetValue() : 0); + + context = std::make_unique(); + context->setShareContext(share_context); + context->setFormat(format); + if (!context->create()) { + LOG_ERROR(Frontend, "Unable to create shared openGL context"); + } + + surface = main_surface; + } + + ~OpenGLSharedContext() { + context->doneCurrent(); + } + + void SwapBuffers() override { + context->swapBuffers(surface); + } + + void MakeCurrent() override { + // We can't track the current state of the underlying context in this wrapper class because + // Qt may make the underlying context not current for one reason or another. In particular, + // the WebBrowser uses GL, so it seems to conflict if we aren't careful. + // Instead of always just making the context current (which does not have any caching to + // check if the underlying context is already current) we can check for the current context + // in the thread local data by calling `currentContext()` and checking if its ours. + if (QOpenGLContext::currentContext() != context.get()) { + context->makeCurrent(surface); + } + } + + void DoneCurrent() override { + context->doneCurrent(); + } + + QOpenGLContext* GetShareContext() const { + return context.get(); + } + +private: + // Avoid using Qt parent system here since we might move the QObjects to new threads + // As a note, this means we should avoid using slots/signals with the objects too + std::unique_ptr context; + std::unique_ptr offscreen_surface{}; + QSurface* surface; +}; +#endif + +class DummyContext : public Frontend::GraphicsContext {}; + +class RenderWidget : public QWidget { +public: + RenderWidget(GRenderWindow* parent) : QWidget(parent) { + setMouseTracking(true); + } + + virtual ~RenderWidget() = default; + + virtual void Present() {} + + void paintEvent(QPaintEvent* event) override { Present(); - return true; - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - case QEvent::KeyPress: - case QEvent::KeyRelease: - case QEvent::FocusIn: - case QEvent::FocusOut: - case QEvent::FocusAboutToChange: - case QEvent::Enter: - case QEvent::Leave: - case QEvent::Wheel: - case QEvent::TabletMove: - case QEvent::TabletPress: - case QEvent::TabletRelease: - case QEvent::TabletEnterProximity: - case QEvent::TabletLeaveProximity: - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - case QEvent::InputMethodQuery: - case QEvent::TouchCancel: - return QCoreApplication::sendEvent(event_handler, event); - case QEvent::Drop: - GetMainWindow()->DropAction(static_cast(event)); - return true; - case QEvent::DragEnter: - case QEvent::DragMove: - GetMainWindow()->AcceptDropEvent(static_cast(event)); - return true; - default: - return QWindow::event(event); + update(); } + + std::pair GetSize() const { + return std::make_pair(width(), height()); + } +}; + +#ifdef HAS_OPENGL +class OpenGLRenderWidget : public RenderWidget { +public: + explicit OpenGLRenderWidget(GRenderWindow* parent, bool is_secondary) + : RenderWidget(parent), is_secondary(is_secondary) { + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_PaintOnScreen); + windowHandle()->setSurfaceType(QWindow::OpenGLSurface); + } + + void SetContext(std::unique_ptr&& context_) { + context = std::move(context_); + } + + void Present() override { + if (!isVisible()) { + return; + } + if (!Core::System::GetInstance().IsPoweredOn()) { + return; + } + context->MakeCurrent(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + VideoCore::g_renderer->TryPresent(100, is_secondary); + context->SwapBuffers(); + glFinish(); + } + + QPaintEngine* paintEngine() const override { + return nullptr; + } + +private: + std::unique_ptr context{}; + bool is_secondary; +}; +#endif + +struct SoftwareRenderWidget : public RenderWidget { + explicit SoftwareRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {} + + void Present() override { + if (!isVisible()) { + return; + } + if (!Core::System::GetInstance().IsPoweredOn()) { + return; + } + + const auto layout{Layout::DefaultFrameLayout(width(), height(), false, false)}; + QPainter painter(this); + + const auto draw_screen = [&](int fb_id) { + const auto rect = fb_id == 0 ? layout.top_screen : layout.bottom_screen; + const QImage screen = LoadFramebuffer(fb_id); + painter.drawImage(rect.left, rect.top, screen); + }; + + painter.fillRect(rect(), qRgb(Settings::values.bg_red.GetValue() * 255, + Settings::values.bg_green.GetValue() * 255, + Settings::values.bg_blue.GetValue() * 255)); + draw_screen(0); + draw_screen(1); + + painter.end(); + } + + QImage LoadFramebuffer(int fb_id) { + const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id]; + const PAddr framebuffer_addr = + framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2; + + Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height); + const u8* framebuffer_data = VideoCore::g_memory->GetPhysicalPointer(framebuffer_addr); + + const int width = framebuffer.height; + const int height = framebuffer.width; + const int bpp = GPU::Regs::BytesPerPixel(framebuffer.color_format); + + QImage image{width, height, QImage::Format_RGBA8888}; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + const u8* pixel = framebuffer_data + (x * height + height - y) * bpp; + const Common::Vec4 color = [&] { + switch (framebuffer.color_format) { + case GPU::Regs::PixelFormat::RGBA8: + return Common::Color::DecodeRGBA8(pixel); + case GPU::Regs::PixelFormat::RGB8: + return Common::Color::DecodeRGB8(pixel); + case GPU::Regs::PixelFormat::RGB565: + return Common::Color::DecodeRGB565(pixel); + case GPU::Regs::PixelFormat::RGB5A1: + return Common::Color::DecodeRGB5A1(pixel); + case GPU::Regs::PixelFormat::RGBA4: + return Common::Color::DecodeRGBA4(pixel); + } + }(); + + image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); + } + } + return image; + } +}; + +static Frontend::WindowSystemType GetWindowSystemType() { + // Determine WSI type based on Qt platform. + const QString platform_name = QGuiApplication::platformName(); + if (platform_name == QStringLiteral("windows")) + return Frontend::WindowSystemType::Windows; + else if (platform_name == QStringLiteral("xcb")) + return Frontend::WindowSystemType::X11; + else if (platform_name == QStringLiteral("wayland")) + return Frontend::WindowSystemType::Wayland; + else if (platform_name == QStringLiteral("cocoa")) + return Frontend::WindowSystemType::MacOS; + + LOG_CRITICAL(Frontend, "Unknown Qt platform!"); + return Frontend::WindowSystemType::Windows; } -void OpenGLWindow::exposeEvent(QExposeEvent* event) { - QWindow::requestUpdate(); - QWindow::exposeEvent(event); +static Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) { + Frontend::EmuWindow::WindowSystemInfo wsi; + wsi.type = GetWindowSystemType(); + + if (window) { +#if defined(WIN32) + // Our Win32 Qt external doesn't have the private API. + wsi.render_surface = reinterpret_cast(window->winId()); +#elif defined(__APPLE__) + wsi.render_surface = reinterpret_cast(objc_msgSend)( + reinterpret_cast(window->winId()), sel_registerName("layer")); +#else + QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); + wsi.display_connection = pni->nativeResourceForWindow("display", window); + if (wsi.type == Frontend::WindowSystemType::Wayland) + wsi.render_surface = pni->nativeResourceForWindow("surface", window); + else + wsi.render_surface = reinterpret_cast(window->winId()); +#endif + wsi.render_surface_scale = static_cast(window->devicePixelRatio()); + } else { + wsi.render_surface = nullptr; + wsi.render_surface_scale = 1.0f; + } + + return wsi; } +std::shared_ptr GRenderWindow::main_context; + GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_secondary_) : QWidget(parent_), EmuWindow(is_secondary_), emu_thread(emu_thread) { @@ -218,11 +406,11 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_se GRenderWindow::~GRenderWindow() = default; void GRenderWindow::MakeCurrent() { - core_context->MakeCurrent(); + main_context->MakeCurrent(); } void GRenderWindow::DoneCurrent() { - core_context->DoneCurrent(); + main_context->DoneCurrent(); } void GRenderWindow::PollEvents() { @@ -295,8 +483,9 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { } void GRenderWindow::mousePressEvent(QMouseEvent* event) { - if (event->source() == Qt::MouseEventSynthesizedBySystem) + if (event->source() == Qt::MouseEventSynthesizedBySystem) { return; // touch input is handled in TouchBeginEvent + } auto pos = event->pos(); if (event->button() == Qt::LeftButton) { @@ -309,8 +498,9 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) { } void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { - if (event->source() == Qt::MouseEventSynthesizedBySystem) + if (event->source() == Qt::MouseEventSynthesizedBySystem) { return; // touch input is handled in TouchUpdateEvent + } auto pos = event->pos(); const auto [x, y] = ScaleTouch(pos); @@ -320,8 +510,9 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { } void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { - if (event->source() == Qt::MouseEventSynthesizedBySystem) + if (event->source() == Qt::MouseEventSynthesizedBySystem) { return; // touch input is handled in TouchEndEvent + } if (event->button() == Qt::LeftButton) this->TouchReleased(); @@ -393,42 +584,61 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) { OnFramebufferSizeChanged(); } -void GRenderWindow::InitRenderTarget() { - ReleaseRenderTarget(); +bool GRenderWindow::InitRenderTarget() { + { + // Create a dummy render widget so that Qt + // places the render window at the correct position. + const RenderWidget dummy_widget{this}; + } first_frame = false; - GMainWindow* parent = GetMainWindow(); - QWindow* parent_win_handle = parent ? parent->windowHandle() : nullptr; - child_window = new OpenGLWindow(parent_win_handle, this, QOpenGLContext::globalShareContext(), - is_secondary); - child_window->create(); - child_widget = createWindowContainer(child_window, this); + const auto graphics_api = Settings::values.graphics_api.GetValue(); + switch (graphics_api) { + case Settings::GraphicsAPI::Software: + InitializeSoftware(); + break; + case Settings::GraphicsAPI::OpenGL: + if (!InitializeOpenGL() || !LoadOpenGL()) { + return false; + } + break; + } + + // Update the Window System information with the new render target + window_info = GetWindowSystemInfo(child_widget->windowHandle()); + child_widget->resize(Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight); layout()->addWidget(child_widget); + // Reset minimum required size to avoid resizing issues on the main window after restarting. + setMinimumSize(1, 1); - core_context = CreateSharedContext(); resize(Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); OnFramebufferSizeChanged(); BackupGeometry(); + + return true; } void GRenderWindow::ReleaseRenderTarget() { if (child_widget) { layout()->removeWidget(child_widget); - delete child_widget; + child_widget->deleteLater(); child_widget = nullptr; } + main_context.reset(); } void GRenderWindow::CaptureScreenshot(u32 res_scale, const QString& screenshot_path) { - if (res_scale == 0) + if (res_scale == 0) { res_scale = VideoCore::GetResolutionScaleFactor(); + } + const auto layout{Layout::FrameLayoutFromResolutionScale(res_scale, is_secondary)}; screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32); - VideoCore::RequestScreenshot( + VideoCore::g_renderer->RequestScreenshot( screenshot_image.bits(), [this, screenshot_path] { const std::string std_screenshot_path = screenshot_path.toStdString(); @@ -445,6 +655,59 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair minimal setMinimumSize(minimal_size.first, minimal_size.second); } +bool GRenderWindow::InitializeOpenGL() { +#ifdef HAS_OPENGL + // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, + // WA_DontShowOnScreen, WA_DeleteOnClose + auto child = new OpenGLRenderWidget(this, is_secondary); + child_widget = child; + child_widget->windowHandle()->create(); + + if (!main_context) { + main_context = std::make_shared(); + } + + auto child_context = CreateSharedContext(); + child->SetContext(std::move(child_context)); + + return true; +#else + QMessageBox::warning(this, tr("OpenGL not available!"), + tr("Citra has not been compiled with OpenGL support.")); + return false; +#endif +} + +void GRenderWindow::InitializeSoftware() { + child_widget = new SoftwareRenderWidget(this); + main_context = std::make_unique(); +} + +bool GRenderWindow::LoadOpenGL() { + auto context = CreateSharedContext(); + auto scope = context->Acquire(); + if (!gladLoadGL()) { + QMessageBox::warning( + this, tr("Error while initializing OpenGL!"), + tr("Your GPU may not support OpenGL, or you do not have the latest graphics driver.")); + return false; + } + + const QString renderer = + QString::fromUtf8(reinterpret_cast(glGetString(GL_RENDERER))); + + if (!GLAD_GL_VERSION_4_3) { + LOG_ERROR(Frontend, "GPU does not support OpenGL 4.3: {}", renderer.toStdString()); + QMessageBox::warning(this, tr("Error while initializing OpenGL 4.3!"), + tr("Your GPU may not support OpenGL 4.3, or you do not have the " + "latest graphics driver.

GL Renderer:
%1") + .arg(renderer)); + return false; + } + + return true; +} + void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { this->emu_thread = emu_thread; } @@ -458,29 +721,15 @@ void GRenderWindow::showEvent(QShowEvent* event) { } std::unique_ptr GRenderWindow::CreateSharedContext() const { - return std::make_unique(QOpenGLContext::globalShareContext()); -} - -GLContext::GLContext(QOpenGLContext* shared_context) - : context(std::make_unique(shared_context->parent())), - surface(std::make_unique(nullptr)) { - - // disable vsync for any shared contexts - auto format = shared_context->format(); - format.setSwapInterval(0); - - context->setShareContext(shared_context); - context->setFormat(format); - context->create(); - surface->setParent(shared_context->parent()); - surface->setFormat(format); - surface->create(); -} - -void GLContext::MakeCurrent() { - context->makeCurrent(surface.get()); -} - -void GLContext::DoneCurrent() { - context->doneCurrent(); +#ifdef HAS_OPENGL + const auto graphics_api = Settings::values.graphics_api.GetValue(); + if (graphics_api == Settings::GraphicsAPI::OpenGL) { + auto gl_context = static_cast(main_context.get()); + // Bind the shared contexts to the main surface in case the backend wants to take over + // presentation + return std::make_unique(gl_context->GetShareContext(), + child_widget->windowHandle()); + } +#endif + return std::make_unique(); } diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index 0dc550555..d06c1ce5e 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -27,19 +27,6 @@ namespace VideoCore { enum class LoadCallbackStage; } -class GLContext : public Frontend::GraphicsContext { -public: - explicit GLContext(QOpenGLContext* shared_context); - - void MakeCurrent() override; - - void DoneCurrent() override; - -private: - std::unique_ptr context; - std::unique_ptr surface; -}; - class EmuThread final : public QThread { Q_OBJECT @@ -126,26 +113,6 @@ signals: void HideLoadingScreen(); }; -class OpenGLWindow : public QWindow { - Q_OBJECT -public: - explicit OpenGLWindow(QWindow* parent, QWidget* event_handler, QOpenGLContext* shared_context, - bool is_secondary = false); - - ~OpenGLWindow(); - - void Present(); - -protected: - bool event(QEvent* event) override; - void exposeEvent(QExposeEvent* event) override; - -private: - std::unique_ptr context; - QWidget* event_handler; - bool is_secondary; -}; - class GRenderWindow : public QWidget, public Frontend::EmuWindow { Q_OBJECT @@ -185,13 +152,15 @@ public: return has_focus; } - void InitRenderTarget(); + bool InitRenderTarget(); /// Destroy the previous run's child_widget which should also destroy the child_window void ReleaseRenderTarget(); void CaptureScreenshot(u32 res_scale, const QString& screenshot_path); + std::pair ScaleTouch(const QPointF pos) const; + public slots: void OnEmulationStarting(EmuThread* emu_thread); @@ -211,29 +180,28 @@ signals: void MouseActivity(); private: - std::pair ScaleTouch(QPointF pos) const; void TouchBeginEvent(const QTouchEvent* event); void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); void OnMinimalClientAreaChangeRequest(std::pair minimal_size) override; - std::unique_ptr core_context; + bool InitializeOpenGL(); + void InitializeSoftware(); + bool LoadOpenGL(); - QByteArray geometry; - - /// Native window handle that backs this presentation widget - QWindow* child_window = nullptr; - - /// In order to embed the window into GRenderWindow, you need to use createWindowContainer to - /// put the child_window into a widget then add it to the layout. This child_widget can be - /// parented to GRenderWindow and use Qt's lifetime system QWidget* child_widget = nullptr; EmuThread* emu_thread; + /// Main context that will be shared with all other contexts that are requested. + /// If this is used in a shared context setting, then this should not be used directly, but + /// should instead be shared from + static std::shared_ptr main_context; + /// Temporary storage of the screenshot taken QImage screenshot_image; + QByteArray geometry; bool first_frame = false; bool has_focus = false; diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index d7ae2b377..6da3dec9b 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -482,6 +482,7 @@ void Config::ReadDebuggingValues() { qt_config->value(QStringLiteral("record_frame_times"), false).toBool(); ReadBasicSetting(Settings::values.use_gdbstub); ReadBasicSetting(Settings::values.gdbstub_port); + ReadBasicSetting(Settings::values.renderer_debug); qt_config->beginGroup(QStringLiteral("LLE")); for (const auto& service_module : Service::service_module_map) { @@ -625,7 +626,7 @@ void Config::ReadPathValues() { void Config::ReadRendererValues() { qt_config->beginGroup(QStringLiteral("Renderer")); - ReadGlobalSetting(Settings::values.use_hw_renderer); + ReadGlobalSetting(Settings::values.graphics_api); ReadGlobalSetting(Settings::values.use_hw_shader); #ifdef __APPLE__ // Hardware shader is broken on macos with Intel GPUs thanks to poor drivers. @@ -992,6 +993,7 @@ void Config::SaveDebuggingValues() { qt_config->setValue(QStringLiteral("record_frame_times"), Settings::values.record_frame_times); WriteBasicSetting(Settings::values.use_gdbstub); WriteBasicSetting(Settings::values.gdbstub_port); + WriteBasicSetting(Settings::values.renderer_debug); qt_config->beginGroup(QStringLiteral("LLE")); for (const auto& service_module : Settings::values.lle_modules) { @@ -1103,7 +1105,7 @@ void Config::SavePathValues() { void Config::SaveRendererValues() { qt_config->beginGroup(QStringLiteral("Renderer")); - WriteGlobalSetting(Settings::values.use_hw_renderer); + WriteGlobalSetting(Settings::values.graphics_api); WriteGlobalSetting(Settings::values.use_hw_shader); #ifdef __APPLE__ // Hardware shader is broken on macos thanks to poor drivers. diff --git a/src/citra_qt/configuration/configuration_shared.h b/src/citra_qt/configuration/configuration_shared.h index 74bd17d2d..7eef18076 100644 --- a/src/citra_qt/configuration/configuration_shared.h +++ b/src/citra_qt/configuration/configuration_shared.h @@ -83,6 +83,21 @@ template <> void SetPerGameSetting(QComboBox* combobox, const Settings::SwitchableSetting* setting); +/// Given an index of a combobox setting extracts the setting taking into +/// account per-game status +template +Type GetComboboxSetting(int index, const Settings::SwitchableSetting* setting) { + if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) { + return static_cast(index); + } else if (!Settings::IsConfiguringGlobal()) { + if (index == 0) { + return setting->GetValue(); + } else { + return static_cast(index - ConfigurationShared::USE_GLOBAL_OFFSET); + } + } +} + /// Given a Qt widget sets the background color to indicate whether the setting /// is per-game overriden (highlighted) or global (non-highlighted) void SetHighlight(QWidget* widget, bool highlighted); diff --git a/src/citra_qt/configuration/configure_debug.cpp b/src/citra_qt/configuration/configure_debug.cpp index d08491f04..a75592fe0 100644 --- a/src/citra_qt/configuration/configure_debug.cpp +++ b/src/citra_qt/configuration/configure_debug.cpp @@ -37,6 +37,7 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) const bool is_powered_on = Core::System::GetInstance().IsPoweredOn(); ui->toggle_cpu_jit->setEnabled(!is_powered_on); + ui->toggle_renderer_debug->setEnabled(!is_powered_on); // Set a minimum width for the label to prevent the slider from changing size. // This scales across DPIs. (This value should be enough for "xxx%") @@ -62,6 +63,7 @@ void ConfigureDebug::SetConfiguration() { ui->toggle_console->setChecked(UISettings::values.show_console.GetValue()); ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue())); ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue()); + ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue()); if (!Settings::IsConfiguringGlobal()) { if (Settings::values.cpu_clock_percentage.UsingGlobal()) { @@ -91,6 +93,7 @@ void ConfigureDebug::ApplyConfiguration() { filter.ParseFilterString(Settings::values.log_filter.GetValue()); Log::SetGlobalFilter(filter); Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked(); + Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked(); ConfigurationShared::ApplyPerGameSetting( &Settings::values.cpu_clock_percentage, ui->clock_speed_combo, diff --git a/src/citra_qt/configuration/configure_debug.h b/src/citra_qt/configuration/configure_debug.h index 59d05f41f..02101016f 100644 --- a/src/citra_qt/configuration/configure_debug.h +++ b/src/citra_qt/configuration/configure_debug.h @@ -23,5 +23,6 @@ public: void SetConfiguration(); void SetupPerGameUI(); +private: std::unique_ptr ui; }; diff --git a/src/citra_qt/configuration/configure_debug.ui b/src/citra_qt/configuration/configure_debug.ui index 6bfb7cb67..afdbc2b8f 100644 --- a/src/citra_qt/configuration/configure_debug.ui +++ b/src/citra_qt/configuration/configure_debug.ui @@ -6,8 +6,8 @@ 0 0 - 443 - 358 + 523 + 447 @@ -112,12 +112,34 @@ CPU + + + + <html><head/><body><p>Enables the use of the ARM JIT compiler for emulating the 3DS CPUs. Don't disable unless for debugging purposes</p></body></html> + + + Enable CPU JIT + + + 7 + + 0 + + + 0 + + + 0 + + + 0 + @@ -180,13 +202,10 @@ - - - - <html><head/><body><p>Enables the use of the ARM JIT compiler for emulating the 3DS CPUs. Don't disable unless for debugging purposes</p></body></html> - + + - Enable CPU JIT + Enable debug renderer diff --git a/src/citra_qt/configuration/configure_enhancements.cpp b/src/citra_qt/configuration/configure_enhancements.cpp index 88e5a62ea..02af11dcf 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -22,7 +22,9 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent) ui->layout_group->setEnabled(!Settings::values.custom_layout); - ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer.GetValue()); + const auto graphics_api = Settings::values.graphics_api.GetValue(); + const bool res_scale_enabled = graphics_api != Settings::GraphicsAPI::Software; + ui->resolution_factor_combobox->setEnabled(res_scale_enabled); connect(ui->render_3d_combobox, static_cast(&QComboBox::currentIndexChanged), this, diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index 58c281490..1a48e5c66 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -16,22 +16,20 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); - SetupPerGameUI(); - SetConfiguration(); - - ui->hw_renderer_group->setEnabled(ui->hw_renderer_group->isEnabled() && - ui->toggle_hw_renderer->isChecked()); ui->toggle_vsync_new->setEnabled(!Core::System::GetInstance().IsPoweredOn()); + // Set the index to -1 to ensure the below lambda is called with setCurrentIndex + ui->graphics_api_combo->setCurrentIndex(-1); - connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] { - const bool checked = ui->toggle_hw_renderer->isChecked(); - ui->hw_renderer_group->setEnabled(checked); - ui->toggle_disk_shader_cache->setEnabled(checked && ui->toggle_hw_shader->isChecked()); - }); + connect(ui->graphics_api_combo, qOverload(&QComboBox::currentIndexChanged), this, + [this](int index) { + const auto graphics_api = + ConfigurationShared::GetComboboxSetting(index, &Settings::values.graphics_api); + const bool is_software = graphics_api == Settings::GraphicsAPI::Software; - ui->hw_shader_group->setEnabled(ui->toggle_hw_shader->isChecked()); - ui->toggle_disk_shader_cache->setEnabled(ui->toggle_hw_renderer->isChecked() && - ui->toggle_hw_shader->isChecked()); + ui->hw_renderer_group->setEnabled(!is_software); + ui->toggle_disk_shader_cache->setEnabled(!is_software && + ui->toggle_hw_shader->isChecked()); + }); connect(ui->toggle_hw_shader, &QCheckBox::toggled, this, [this] { const bool checked = ui->toggle_hw_shader->isChecked(); @@ -60,12 +58,24 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) // TODO(B3N30): Hide this for macs with none Intel GPUs, too. ui->toggle_separable_shader->setVisible(false); #endif + + SetupPerGameUI(); + SetConfiguration(); } ConfigureGraphics::~ConfigureGraphics() = default; void ConfigureGraphics::SetConfiguration() { - ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer.GetValue()); + if (!Settings::IsConfiguringGlobal()) { + ConfigurationShared::SetHighlight(ui->graphics_api_group, + !Settings::values.graphics_api.UsingGlobal()); + ConfigurationShared::SetPerGameSetting(ui->graphics_api_combo, + &Settings::values.graphics_api); + } else { + ui->graphics_api_combo->setCurrentIndex( + static_cast(Settings::values.graphics_api.GetValue())); + } + ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue()); ui->toggle_separable_shader->setChecked(Settings::values.separable_shader.GetValue()); ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue()); @@ -78,8 +88,8 @@ void ConfigureGraphics::SetConfiguration() { } void ConfigureGraphics::ApplyConfiguration() { - ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_renderer, - ui->toggle_hw_renderer, use_hw_renderer); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.graphics_api, + ui->graphics_api_combo); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader, use_hw_shader); ConfigurationShared::ApplyPerGameSetting(&Settings::values.separable_shader, @@ -103,7 +113,7 @@ void ConfigureGraphics::RetranslateUI() { void ConfigureGraphics::SetupPerGameUI() { // Block the global settings if a game is currently running that overrides them if (Settings::IsConfiguringGlobal()) { - ui->toggle_hw_renderer->setEnabled(Settings::values.use_hw_renderer.UsingGlobal()); + ui->graphics_api_group->setEnabled(Settings::values.graphics_api.UsingGlobal()); ui->toggle_hw_shader->setEnabled(Settings::values.use_hw_shader.UsingGlobal()); ui->toggle_separable_shader->setEnabled(Settings::values.separable_shader.UsingGlobal()); ui->toggle_accurate_mul->setEnabled(Settings::values.shaders_accurate_mul.UsingGlobal()); @@ -115,8 +125,10 @@ void ConfigureGraphics::SetupPerGameUI() { ui->toggle_shader_jit->setVisible(false); - ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer, - Settings::values.use_hw_renderer, use_hw_renderer); + ConfigurationShared::SetColoredComboBox( + ui->graphics_api_combo, ui->graphics_api_group, + static_cast(Settings::values.graphics_api.GetValue(true))); + ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader, use_hw_shader); ConfigurationShared::SetColoredTristate(ui->toggle_separable_shader, diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 2517e1553..89d9fa543 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -28,9 +28,9 @@ public: void UpdateBackgroundColorButton(const QColor& color); +private: void SetupPerGameUI(); - ConfigurationShared::CheckState use_hw_renderer; ConfigurationShared::CheckState use_hw_shader; ConfigurationShared::CheckState separable_shader; ConfigurationShared::CheckState shaders_accurate_mul; diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index 97dc851d4..f0f2b5c58 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -7,7 +7,7 @@ 0 0 400 - 430 + 443 @@ -20,27 +20,65 @@ Form + + + + API Settings + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Graphics API + + + + + + + + Software + + + + + OpenGL + + + + + + + + + + Renderer - - - - <html><head/><body><p>Use OpenGL to accelerate rendering.</p><p>Disable to debug graphics-related problem.</p></body></html> - - - Enable Hardware Renderer - - - - 16 + 0 0 @@ -157,8 +195,6 @@ - toggle_hw_renderer - toggle_hw_shader toggle_separable_shader toggle_accurate_mul toggle_shader_jit diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 4f7b30a84..b2cf72f18 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -88,7 +87,6 @@ #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_source_sd_savedata.h" #include "core/frontend/applets/default_applets.h" -#include "core/frontend/scope_acquire_context.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/fs/archive.h" @@ -1026,16 +1024,7 @@ bool GMainWindow::LoadROM(const QString& filename) { render_window->InitRenderTarget(); secondary_window->InitRenderTarget(); - Frontend::ScopeAcquireContext scope(*render_window); - - const QString below_gl43_title = tr("OpenGL 4.3 Unsupported"); - const QString below_gl43_message = tr("Your GPU may not support OpenGL 4.3, or you do not " - "have the latest graphics driver."); - - if (!QOpenGLContext::globalShareContext()->versionFunctions()) { - QMessageBox::critical(this, below_gl43_title, below_gl43_message); - return false; - } + const auto scope = render_window->Acquire(); Core::System& system{Core::System::GetInstance()}; @@ -1091,28 +1080,6 @@ bool GMainWindow::LoadROM(const QString& filename) { tr("GBA Virtual Console ROMs are not supported by Citra.")); break; - case Core::System::ResultStatus::ErrorVideoCore: - QMessageBox::critical( - this, tr("Video Core Error"), - tr("An error has occurred. Please see " - "the " - "log for more details. " - "Ensure that you have the latest graphics drivers for your GPU.")); - break; - - case Core::System::ResultStatus::ErrorVideoCore_ErrorGenericDrivers: - QMessageBox::critical( - this, tr("Video Core Error"), - tr("You are running default Windows drivers " - "for your GPU. You need to install the " - "proper drivers for your graphics card from the manufacturer's website.")); - break; - - case Core::System::ResultStatus::ErrorVideoCore_ErrorBelowGL43: - QMessageBox::critical(this, below_gl43_title, below_gl43_message); - break; - default: QMessageBox::critical( this, tr("Error while loading ROM!"), @@ -2786,14 +2753,6 @@ int main(int argc, char* argv[]) { QCoreApplication::setOrganizationName(QStringLiteral("Citra team")); QCoreApplication::setApplicationName(QStringLiteral("Citra")); - QSurfaceFormat format; - format.setVersion(4, 3); - format.setProfile(QSurfaceFormat::CoreProfile); - format.setSwapInterval(0); - // TODO: expose a setting for buffer value (ie default/single/double/triple) - format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); - QSurfaceFormat::setDefaultFormat(format); - SetHighDPIAttributes(); #ifdef __APPLE__ diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 385af24c5..ca3701061 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -55,6 +55,60 @@ __declspec(dllimport) void __stdcall DebugBreak(void); #endif // _MSC_VER +#define DECLARE_ENUM_FLAG_OPERATORS(type) \ + [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) | static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator&(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) & static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator^(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) ^ static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) << static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) >> static_cast(b)); \ + } \ + constexpr type& operator|=(type& a, type b) noexcept { \ + a = a | b; \ + return a; \ + } \ + constexpr type& operator&=(type& a, type b) noexcept { \ + a = a & b; \ + return a; \ + } \ + constexpr type& operator^=(type& a, type b) noexcept { \ + a = a ^ b; \ + return a; \ + } \ + constexpr type& operator<<=(type& a, type b) noexcept { \ + a = a << b; \ + return a; \ + } \ + constexpr type& operator>>=(type& a, type b) noexcept { \ + a = a >> b; \ + return a; \ + } \ + [[nodiscard]] constexpr type operator~(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(~static_cast(key)); \ + } \ + [[nodiscard]] constexpr bool True(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) != 0; \ + } \ + [[nodiscard]] constexpr bool False(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) == 0; \ + } + // Generic function to get last error message. // Call directly after the command or use the error num. // This function might change the error code. diff --git a/src/common/settings.cpp b/src/common/settings.cpp index a94c89218..46aa2e8e1 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -20,6 +20,8 @@ namespace Settings { +namespace { + std::string_view GetAudioEmulationName(AudioEmulation emulation) { switch (emulation) { case AudioEmulation::HLE: @@ -31,6 +33,17 @@ std::string_view GetAudioEmulationName(AudioEmulation emulation) { } }; +std::string_view GetGraphicsAPIName(GraphicsAPI api) { + switch (api) { + case GraphicsAPI::Software: + return "Software"; + case GraphicsAPI::OpenGL: + return "OpenGL"; + } +} + +} // Anonymous namespace + Values values = {}; static bool configuring_global = true; @@ -38,7 +51,6 @@ void Apply() { GDBStub::SetServerPort(values.gdbstub_port.GetValue()); GDBStub::ToggleServer(values.use_gdbstub.GetValue()); - VideoCore::g_hw_renderer_enabled = values.use_hw_renderer.GetValue(); VideoCore::g_shader_jit_enabled = values.use_shader_jit.GetValue(); VideoCore::g_hw_shader_enabled = values.use_hw_shader.GetValue(); VideoCore::g_separable_shader_enabled = values.separable_shader.GetValue(); @@ -101,7 +113,7 @@ void LogSettings() { log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue()); log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage.GetValue()); log_setting("Renderer_UseGLES", values.use_gles.GetValue()); - log_setting("Renderer_UseHwRenderer", values.use_hw_renderer.GetValue()); + log_setting("Renderer_GraphicsAPI", GetGraphicsAPIName(values.graphics_api.GetValue())); log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue()); log_setting("Renderer_SeparableShader", values.separable_shader.GetValue()); log_setting("Renderer_ShadersAccurateMul", values.shaders_accurate_mul.GetValue()); @@ -186,7 +198,7 @@ void RestoreGlobalState(bool is_powered_on) { values.is_new_3ds.SetGlobal(true); // Renderer - values.use_hw_renderer.SetGlobal(true); + values.graphics_api.SetGlobal(true); values.use_hw_shader.SetGlobal(true); values.separable_shader.SetGlobal(true); values.use_disk_shader_cache.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 354dbafce..bd25c1b13 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -15,6 +15,11 @@ namespace Settings { +enum class GraphicsAPI { + Software = 0, + OpenGL = 1, +}; + enum class InitClock : u32 { SystemTime = 0, FixedTime = 1, @@ -415,8 +420,9 @@ struct Values { Setting allow_plugin_loader{true, "allow_plugin_loader"}; // Renderer + SwitchableSetting graphics_api{GraphicsAPI::OpenGL, "graphics_api"}; Setting use_gles{false, "use_gles"}; - SwitchableSetting use_hw_renderer{true, "use_hw_renderer"}; + Setting renderer_debug{false, "renderer_debug"}; SwitchableSetting use_hw_shader{true, "use_hw_shader"}; SwitchableSetting separable_shader{false, "use_separable_shader"}; SwitchableSetting use_disk_shader_cache{true, "use_disk_shader_cache"}; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9b3d40a07..aedb6b135 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -113,8 +113,6 @@ add_library(core STATIC frontend/input.h frontend/mic.cpp frontend/mic.h - frontend/scope_acquire_context.cpp - frontend/scope_acquire_context.h gdbstub/gdbstub.cpp gdbstub/gdbstub.h hle/applets/applet.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index a74e7b430..39bafcd40 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -431,17 +431,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, video_dumper = std::make_unique(); #endif - VideoCore::ResultStatus result = VideoCore::Init(emu_window, secondary_window, *memory); - if (result != VideoCore::ResultStatus::Success) { - switch (result) { - case VideoCore::ResultStatus::ErrorGenericDrivers: - return ResultStatus::ErrorVideoCore_ErrorGenericDrivers; - case VideoCore::ResultStatus::ErrorBelowGL43: - return ResultStatus::ErrorVideoCore_ErrorBelowGL43; - default: - return ResultStatus::ErrorVideoCore; - } - } + VideoCore::Init(emu_window, secondary_window, *this); LOG_DEBUG(Core, "Initialized OK"); @@ -450,7 +440,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, return ResultStatus::Success; } -RendererBase& System::Renderer() { +VideoCore::RendererBase& System::Renderer() { return *VideoCore::g_renderer; } diff --git a/src/core/core.h b/src/core/core.h index c4e06e2aa..978186eaa 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -57,7 +57,9 @@ namespace VideoDumper { class Backend; } +namespace VideoCore { class RendererBase; +} namespace Core { @@ -87,14 +89,9 @@ public: ErrorLoader_ErrorGbaTitle, ///< Error loading the specified application as it is GBA Virtual ///< Console ErrorSystemFiles, ///< Error in finding system files - ErrorVideoCore, ///< Error in the video core - ErrorVideoCore_ErrorGenericDrivers, ///< Error in the video core due to the user having - /// generic drivers installed - ErrorVideoCore_ErrorBelowGL43, ///< Error in the video core due to the user not having - /// OpenGL 4.3 or higher - ErrorSavestate, ///< Error saving or loading - ShutdownRequested, ///< Emulated program requested a system shutdown - ErrorUnknown ///< Any other error + ErrorSavestate, ///< Error saving or loading + ShutdownRequested, ///< Emulated program requested a system shutdown + ErrorUnknown ///< Any other error }; ~System(); @@ -210,7 +207,7 @@ public: return *dsp_core; } - [[nodiscard]] RendererBase& Renderer(); + [[nodiscard]] VideoCore::RendererBase& Renderer(); /** * Gets a reference to the service manager. diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 81cc930d2..61846a8a5 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -14,6 +14,17 @@ namespace Frontend { +/// Information for the Graphics Backends signifying what type of screen pointer is in +/// WindowInformation +enum class WindowSystemType : u8 { + Headless, + Android, + Windows, + MacOS, + X11, + Wayland, +}; + struct Frame; /** * For smooth Vsync rendering, we want to always present the latest frame that the core generates, @@ -62,11 +73,33 @@ class GraphicsContext { public: virtual ~GraphicsContext(); + /// Inform the driver to swap the front/back buffers and present the current image + virtual void SwapBuffers(){}; + /// Makes the graphics context current for the caller thread - virtual void MakeCurrent() = 0; + virtual void MakeCurrent(){}; /// Releases (dunno if this is the "right" word) the context from the caller thread - virtual void DoneCurrent() = 0; + virtual void DoneCurrent(){}; + + class Scoped { + public: + explicit Scoped(GraphicsContext& context_) : context(context_) { + context.MakeCurrent(); + } + ~Scoped() { + context.DoneCurrent(); + } + + private: + GraphicsContext& context; + }; + + /// Calls MakeCurrent on the context and calls DoneCurrent when the scope for the returned value + /// ends + [[nodiscard]] Scoped Acquire() { + return Scoped{*this}; + } }; /** @@ -100,6 +133,23 @@ public: Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight}; }; + /// Data describing host window system information + struct WindowSystemInfo { + // Window system type. Determines which GL context or Vulkan WSI is used. + WindowSystemType type = WindowSystemType::Headless; + + // Connection to a display server. This is used on X11 and Wayland platforms. + void* display_connection = nullptr; + + // Render surface. This is a pointer to the native window handle, which depends + // on the platform. e.g. HWND for Windows, Window for X11. If the surface is + // set to nullptr, the video backend will run in headless mode. + void* render_surface = nullptr; + + // Scale of the render surface. For hidpi systems, this will be >1. + float render_surface_scale = 1.0f; + }; + /// Polls window events virtual void PollEvents() = 0; @@ -163,6 +213,13 @@ public: config = val; } + /** + * Returns system information about the drawing area. + */ + const WindowSystemInfo& GetWindowInfo() const { + return window_info; + } + /** * Gets the framebuffer layout (width, height, and screen regions) * @note This method is thread-safe @@ -211,6 +268,7 @@ protected: } bool is_secondary{}; + WindowSystemInfo window_info; private: /** diff --git a/src/core/frontend/scope_acquire_context.cpp b/src/core/frontend/scope_acquire_context.cpp deleted file mode 100644 index 3689483af..000000000 --- a/src/core/frontend/scope_acquire_context.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "core/frontend/emu_window.h" -#include "core/frontend/scope_acquire_context.h" - -namespace Frontend { - -ScopeAcquireContext::ScopeAcquireContext(Frontend::GraphicsContext& context) : context{context} { - context.MakeCurrent(); -} -ScopeAcquireContext::~ScopeAcquireContext() { - context.DoneCurrent(); -} - -} // namespace Frontend \ No newline at end of file diff --git a/src/core/frontend/scope_acquire_context.h b/src/core/frontend/scope_acquire_context.h deleted file mode 100644 index 12ab61ec6..000000000 --- a/src/core/frontend/scope_acquire_context.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -namespace Frontend { - -class GraphicsContext; - -/// Helper class to acquire/release window context within a given scope -class ScopeAcquireContext : NonCopyable { -public: - explicit ScopeAcquireContext(Frontend::GraphicsContext& context); - ~ScopeAcquireContext(); - -private: - Frontend::GraphicsContext& context; -}; - -} // namespace Frontend \ No newline at end of file diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index f7a7754e5..2ae8863ae 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -133,8 +133,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { Settings::values.resolution_factor.GetValue()); AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit", Settings::values.frame_limit.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer", - Settings::values.use_hw_renderer.GetValue()); + AddField(Telemetry::FieldType::UserConfig, "Renderer_Backend", + static_cast(Settings::values.graphics_api.GetValue())); AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader", Settings::values.use_hw_shader.GetValue()); AddField(Telemetry::FieldType::UserConfig, "Renderer_ShadersAccurateMul", diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 17d7149da..197f6aa5e 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(video_core STATIC precompiled_headers.h primitive_assembly.cpp primitive_assembly.h + rasterizer_accelerated.cpp + rasterizer_accelerated.h rasterizer_interface.h regs.cpp regs.h @@ -39,6 +41,8 @@ add_library(video_core STATIC rasterizer_cache/texture_runtime.h renderer_opengl/frame_dumper_opengl.cpp renderer_opengl/frame_dumper_opengl.h + renderer_opengl/gl_driver.cpp + renderer_opengl/gl_driver.h renderer_opengl/gl_rasterizer.cpp renderer_opengl/gl_rasterizer.h renderer_opengl/gl_resource_manager.cpp @@ -82,6 +86,22 @@ add_library(video_core STATIC #temporary, move these back in alphabetical order before merging renderer_opengl/gl_format_reinterpreter.cpp renderer_opengl/gl_format_reinterpreter.h + renderer_software/rasterizer.cpp + renderer_software/rasterizer.h + renderer_software/renderer_software.cpp + renderer_software/renderer_software.h + renderer_software/sw_clipper.cpp + renderer_software/sw_clipper.h + renderer_software/sw_framebuffer.cpp + renderer_software/sw_framebuffer.h + renderer_software/sw_lighting.cpp + renderer_software/sw_lighting.h + renderer_software/sw_proctex.cpp + renderer_software/sw_proctex.h + renderer_software/sw_rasterizer.cpp + renderer_software/sw_rasterizer.h + renderer_software/sw_texturing.cpp + renderer_software/sw_texturing.h shader/debug_data.h shader/shader.cpp shader/shader.h @@ -91,20 +111,8 @@ add_library(video_core STATIC shader/shader_jit_x64_compiler.cpp shader/shader_jit_x64.h shader/shader_jit_x64_compiler.h - swrasterizer/clipper.cpp - swrasterizer/clipper.h - swrasterizer/framebuffer.cpp - swrasterizer/framebuffer.h - swrasterizer/lighting.cpp - swrasterizer/lighting.h - swrasterizer/proctex.cpp - swrasterizer/proctex.h - swrasterizer/rasterizer.cpp - swrasterizer/rasterizer.h - swrasterizer/swrasterizer.cpp - swrasterizer/swrasterizer.h - swrasterizer/texturing.cpp - swrasterizer/texturing.h + shader/shader_uniforms.cpp + shader/shader_uniforms.h texture/etc1.cpp texture/etc1.h texture/texture_decode.cpp diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp new file mode 100644 index 000000000..f46379716 --- /dev/null +++ b/src/video_core/rasterizer_accelerated.cpp @@ -0,0 +1,832 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "common/alignment.h" +#include "core/memory.h" +#include "video_core/pica_state.h" +#include "video_core/rasterizer_accelerated.h" + +namespace VideoCore { + +static Common::Vec4f ColorRGBA8(const u32 color) { + const auto rgba = + Common::Vec4u{color >> 0 & 0xFF, color >> 8 & 0xFF, color >> 16 & 0xFF, color >> 24 & 0xFF}; + return rgba / 255.0f; +} + +static Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) { + return Common::Vec3u{color.r, color.g, color.b} / 255.0f; +} + +RasterizerAccelerated::HardwareVertex::HardwareVertex(const Pica::Shader::OutputVertex& v, + bool flip_quaternion) { + position[0] = v.pos.x.ToFloat32(); + position[1] = v.pos.y.ToFloat32(); + position[2] = v.pos.z.ToFloat32(); + position[3] = v.pos.w.ToFloat32(); + color[0] = v.color.x.ToFloat32(); + color[1] = v.color.y.ToFloat32(); + color[2] = v.color.z.ToFloat32(); + color[3] = v.color.w.ToFloat32(); + tex_coord0[0] = v.tc0.x.ToFloat32(); + tex_coord0[1] = v.tc0.y.ToFloat32(); + tex_coord1[0] = v.tc1.x.ToFloat32(); + tex_coord1[1] = v.tc1.y.ToFloat32(); + tex_coord2[0] = v.tc2.x.ToFloat32(); + tex_coord2[1] = v.tc2.y.ToFloat32(); + tex_coord0_w = v.tc0_w.ToFloat32(); + normquat[0] = v.quat.x.ToFloat32(); + normquat[1] = v.quat.y.ToFloat32(); + normquat[2] = v.quat.z.ToFloat32(); + normquat[3] = v.quat.w.ToFloat32(); + view[0] = v.view.x.ToFloat32(); + view[1] = v.view.y.ToFloat32(); + view[2] = v.view.z.ToFloat32(); + + if (flip_quaternion) { + normquat = -normquat; + } +} + +RasterizerAccelerated::RasterizerAccelerated(Memory::MemorySystem& memory_) + : memory{memory_}, regs{Pica::g_state.regs} { + uniform_block_data.lighting_lut_dirty.fill(true); +} + +/** + * This is a helper function to resolve an issue when interpolating opposite quaternions. See below + * for a detailed description of this issue (yuriks): + * + * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you + * interpolate two quaternions that are opposite, instead of going from one rotation to another + * using the shortest path, you'll go around the longest path. You can test if two quaternions are + * opposite by checking if Dot(Q1, Q2) < 0. In that case, you can flip either of them, therefore + * making Dot(Q1, -Q2) positive. + * + * This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This is + * correct for most cases but can still rotate around the long way sometimes. An implementation + * which did `lerp(lerp(Q1, Q2), Q3)` (with proper weighting), applying the dot product check + * between each step would work for those cases at the cost of being more complex to implement. + * + * Fortunately however, the 3DS hardware happens to also use this exact same logic to work around + * these issues, making this basic implementation actually more accurate to the hardware. + */ +static bool AreQuaternionsOpposite(Common::Vec4 qa, Common::Vec4 qb) { + Common::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()}; + Common::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()}; + + return (Common::Dot(a, b) < 0.f); +} + +void RasterizerAccelerated::AddTriangle(const Pica::Shader::OutputVertex& v0, + const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) { + vertex_batch.emplace_back(v0, false); + vertex_batch.emplace_back(v1, AreQuaternionsOpposite(v0.quat, v1.quat)); + vertex_batch.emplace_back(v2, AreQuaternionsOpposite(v0.quat, v2.quat)); +} + +RasterizerAccelerated::VertexArrayInfo RasterizerAccelerated::AnalyzeVertexArray( + bool is_indexed, u32 stride_alignment) { + const auto& vertex_attributes = regs.pipeline.vertex_attributes; + + u32 vertex_min; + u32 vertex_max; + if (is_indexed) { + const auto& index_info = regs.pipeline.index_array; + const PAddr address = vertex_attributes.GetPhysicalBaseAddress() + index_info.offset; + const u8* index_address_8 = memory.GetPhysicalPointer(address); + const u16* index_address_16 = reinterpret_cast(index_address_8); + const bool index_u16 = index_info.format != 0; + + vertex_min = 0xFFFF; + vertex_max = 0; + const u32 size = regs.pipeline.num_vertices * (index_u16 ? 2 : 1); + FlushRegion(address, size); + for (u32 index = 0; index < regs.pipeline.num_vertices; ++index) { + const u32 vertex = index_u16 ? index_address_16[index] : index_address_8[index]; + vertex_min = std::min(vertex_min, vertex); + vertex_max = std::max(vertex_max, vertex); + } + } else { + vertex_min = regs.pipeline.vertex_offset; + vertex_max = regs.pipeline.vertex_offset + regs.pipeline.num_vertices - 1; + } + + const u32 vertex_num = vertex_max - vertex_min + 1; + u32 vs_input_size = 0; + for (const auto& loader : vertex_attributes.attribute_loaders) { + if (loader.component_count != 0) { + const u32 aligned_stride = + Common::AlignUp(static_cast(loader.byte_count), stride_alignment); + vs_input_size += Common::AlignUp(aligned_stride * vertex_num, 4); + } + } + + return {vertex_min, vertex_max, vs_input_size}; +} + +void RasterizerAccelerated::SyncEntireState() { + // Sync renderer-specific fixed-function state + SyncFixedState(); + + // Sync uniforms + SyncClipCoef(); + SyncDepthScale(); + SyncDepthOffset(); + SyncAlphaTest(); + SyncCombinerColor(); + auto& tev_stages = regs.texturing.GetTevStages(); + for (std::size_t index = 0; index < tev_stages.size(); ++index) { + SyncTevConstColor(index, tev_stages[index]); + } + + SyncGlobalAmbient(); + for (unsigned light_index = 0; light_index < 8; light_index++) { + SyncLightSpecular0(light_index); + SyncLightSpecular1(light_index); + SyncLightDiffuse(light_index); + SyncLightAmbient(light_index); + SyncLightPosition(light_index); + SyncLightDistanceAttenuationBias(light_index); + SyncLightDistanceAttenuationScale(light_index); + } + + SyncFogColor(); + SyncProcTexNoise(); + SyncProcTexBias(); + SyncShadowBias(); + SyncShadowTextureBias(); + + for (unsigned tex_index = 0; tex_index < 3; tex_index++) { + SyncTextureLodBias(tex_index); + } +} + +void RasterizerAccelerated::NotifyPicaRegisterChanged(u32 id) { + switch (id) { + // Depth modifiers + case PICA_REG_INDEX(rasterizer.viewport_depth_range): + SyncDepthScale(); + break; + case PICA_REG_INDEX(rasterizer.viewport_depth_near_plane): + SyncDepthOffset(); + break; + + // Depth buffering + case PICA_REG_INDEX(rasterizer.depthmap_enable): + shader_dirty = true; + break; + + // Shadow texture + case PICA_REG_INDEX(texturing.shadow): + SyncShadowTextureBias(); + break; + + // Fog state + case PICA_REG_INDEX(texturing.fog_color): + SyncFogColor(); + break; + case PICA_REG_INDEX(texturing.fog_lut_data[0]): + case PICA_REG_INDEX(texturing.fog_lut_data[1]): + case PICA_REG_INDEX(texturing.fog_lut_data[2]): + case PICA_REG_INDEX(texturing.fog_lut_data[3]): + case PICA_REG_INDEX(texturing.fog_lut_data[4]): + case PICA_REG_INDEX(texturing.fog_lut_data[5]): + case PICA_REG_INDEX(texturing.fog_lut_data[6]): + case PICA_REG_INDEX(texturing.fog_lut_data[7]): + uniform_block_data.fog_lut_dirty = true; + break; + + // ProcTex state + case PICA_REG_INDEX(texturing.proctex): + case PICA_REG_INDEX(texturing.proctex_lut): + case PICA_REG_INDEX(texturing.proctex_lut_offset): + SyncProcTexBias(); + shader_dirty = true; + break; + + case PICA_REG_INDEX(texturing.proctex_noise_u): + case PICA_REG_INDEX(texturing.proctex_noise_v): + case PICA_REG_INDEX(texturing.proctex_noise_frequency): + SyncProcTexNoise(); + break; + + case PICA_REG_INDEX(texturing.proctex_lut_data[0]): + case PICA_REG_INDEX(texturing.proctex_lut_data[1]): + case PICA_REG_INDEX(texturing.proctex_lut_data[2]): + case PICA_REG_INDEX(texturing.proctex_lut_data[3]): + case PICA_REG_INDEX(texturing.proctex_lut_data[4]): + case PICA_REG_INDEX(texturing.proctex_lut_data[5]): + case PICA_REG_INDEX(texturing.proctex_lut_data[6]): + case PICA_REG_INDEX(texturing.proctex_lut_data[7]): + using Pica::TexturingRegs; + switch (regs.texturing.proctex_lut_config.ref_table.Value()) { + case TexturingRegs::ProcTexLutTable::Noise: + uniform_block_data.proctex_noise_lut_dirty = true; + break; + case TexturingRegs::ProcTexLutTable::ColorMap: + uniform_block_data.proctex_color_map_dirty = true; + break; + case TexturingRegs::ProcTexLutTable::AlphaMap: + uniform_block_data.proctex_alpha_map_dirty = true; + break; + case TexturingRegs::ProcTexLutTable::Color: + uniform_block_data.proctex_lut_dirty = true; + break; + case TexturingRegs::ProcTexLutTable::ColorDiff: + uniform_block_data.proctex_diff_lut_dirty = true; + break; + } + break; + + // Alpha test + case PICA_REG_INDEX(framebuffer.output_merger.alpha_test): + SyncAlphaTest(); + shader_dirty = true; + break; + + case PICA_REG_INDEX(framebuffer.shadow): + SyncShadowBias(); + break; + + // Scissor test + case PICA_REG_INDEX(rasterizer.scissor_test.mode): + shader_dirty = true; + break; + + case PICA_REG_INDEX(texturing.main_config): + shader_dirty = true; + break; + + // Texture 0 type + case PICA_REG_INDEX(texturing.texture0.type): + shader_dirty = true; + break; + + // TEV stages + // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) + case PICA_REG_INDEX(texturing.tev_stage0.color_source1): + case PICA_REG_INDEX(texturing.tev_stage0.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage0.color_op): + case PICA_REG_INDEX(texturing.tev_stage0.color_scale): + case PICA_REG_INDEX(texturing.tev_stage1.color_source1): + case PICA_REG_INDEX(texturing.tev_stage1.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage1.color_op): + case PICA_REG_INDEX(texturing.tev_stage1.color_scale): + case PICA_REG_INDEX(texturing.tev_stage2.color_source1): + case PICA_REG_INDEX(texturing.tev_stage2.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage2.color_op): + case PICA_REG_INDEX(texturing.tev_stage2.color_scale): + case PICA_REG_INDEX(texturing.tev_stage3.color_source1): + case PICA_REG_INDEX(texturing.tev_stage3.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage3.color_op): + case PICA_REG_INDEX(texturing.tev_stage3.color_scale): + case PICA_REG_INDEX(texturing.tev_stage4.color_source1): + case PICA_REG_INDEX(texturing.tev_stage4.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage4.color_op): + case PICA_REG_INDEX(texturing.tev_stage4.color_scale): + case PICA_REG_INDEX(texturing.tev_stage5.color_source1): + case PICA_REG_INDEX(texturing.tev_stage5.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage5.color_op): + case PICA_REG_INDEX(texturing.tev_stage5.color_scale): + case PICA_REG_INDEX(texturing.tev_combiner_buffer_input): + shader_dirty = true; + break; + case PICA_REG_INDEX(texturing.tev_stage0.const_r): + SyncTevConstColor(0, regs.texturing.tev_stage0); + break; + case PICA_REG_INDEX(texturing.tev_stage1.const_r): + SyncTevConstColor(1, regs.texturing.tev_stage1); + break; + case PICA_REG_INDEX(texturing.tev_stage2.const_r): + SyncTevConstColor(2, regs.texturing.tev_stage2); + break; + case PICA_REG_INDEX(texturing.tev_stage3.const_r): + SyncTevConstColor(3, regs.texturing.tev_stage3); + break; + case PICA_REG_INDEX(texturing.tev_stage4.const_r): + SyncTevConstColor(4, regs.texturing.tev_stage4); + break; + case PICA_REG_INDEX(texturing.tev_stage5.const_r): + SyncTevConstColor(5, regs.texturing.tev_stage5); + break; + + // TEV combiner buffer color + case PICA_REG_INDEX(texturing.tev_combiner_buffer_color): + SyncCombinerColor(); + break; + + // Fragment lighting switches + case PICA_REG_INDEX(lighting.disable): + case PICA_REG_INDEX(lighting.max_light_index): + case PICA_REG_INDEX(lighting.config0): + case PICA_REG_INDEX(lighting.config1): + case PICA_REG_INDEX(lighting.abs_lut_input): + case PICA_REG_INDEX(lighting.lut_input): + case PICA_REG_INDEX(lighting.lut_scale): + case PICA_REG_INDEX(lighting.light_enable): + break; + + // Fragment lighting specular 0 color + case PICA_REG_INDEX(lighting.light[0].specular_0): + SyncLightSpecular0(0); + break; + case PICA_REG_INDEX(lighting.light[1].specular_0): + SyncLightSpecular0(1); + break; + case PICA_REG_INDEX(lighting.light[2].specular_0): + SyncLightSpecular0(2); + break; + case PICA_REG_INDEX(lighting.light[3].specular_0): + SyncLightSpecular0(3); + break; + case PICA_REG_INDEX(lighting.light[4].specular_0): + SyncLightSpecular0(4); + break; + case PICA_REG_INDEX(lighting.light[5].specular_0): + SyncLightSpecular0(5); + break; + case PICA_REG_INDEX(lighting.light[6].specular_0): + SyncLightSpecular0(6); + break; + case PICA_REG_INDEX(lighting.light[7].specular_0): + SyncLightSpecular0(7); + break; + + // Fragment lighting specular 1 color + case PICA_REG_INDEX(lighting.light[0].specular_1): + SyncLightSpecular1(0); + break; + case PICA_REG_INDEX(lighting.light[1].specular_1): + SyncLightSpecular1(1); + break; + case PICA_REG_INDEX(lighting.light[2].specular_1): + SyncLightSpecular1(2); + break; + case PICA_REG_INDEX(lighting.light[3].specular_1): + SyncLightSpecular1(3); + break; + case PICA_REG_INDEX(lighting.light[4].specular_1): + SyncLightSpecular1(4); + break; + case PICA_REG_INDEX(lighting.light[5].specular_1): + SyncLightSpecular1(5); + break; + case PICA_REG_INDEX(lighting.light[6].specular_1): + SyncLightSpecular1(6); + break; + case PICA_REG_INDEX(lighting.light[7].specular_1): + SyncLightSpecular1(7); + break; + + // Fragment lighting diffuse color + case PICA_REG_INDEX(lighting.light[0].diffuse): + SyncLightDiffuse(0); + break; + case PICA_REG_INDEX(lighting.light[1].diffuse): + SyncLightDiffuse(1); + break; + case PICA_REG_INDEX(lighting.light[2].diffuse): + SyncLightDiffuse(2); + break; + case PICA_REG_INDEX(lighting.light[3].diffuse): + SyncLightDiffuse(3); + break; + case PICA_REG_INDEX(lighting.light[4].diffuse): + SyncLightDiffuse(4); + break; + case PICA_REG_INDEX(lighting.light[5].diffuse): + SyncLightDiffuse(5); + break; + case PICA_REG_INDEX(lighting.light[6].diffuse): + SyncLightDiffuse(6); + break; + case PICA_REG_INDEX(lighting.light[7].diffuse): + SyncLightDiffuse(7); + break; + + // Fragment lighting ambient color + case PICA_REG_INDEX(lighting.light[0].ambient): + SyncLightAmbient(0); + break; + case PICA_REG_INDEX(lighting.light[1].ambient): + SyncLightAmbient(1); + break; + case PICA_REG_INDEX(lighting.light[2].ambient): + SyncLightAmbient(2); + break; + case PICA_REG_INDEX(lighting.light[3].ambient): + SyncLightAmbient(3); + break; + case PICA_REG_INDEX(lighting.light[4].ambient): + SyncLightAmbient(4); + break; + case PICA_REG_INDEX(lighting.light[5].ambient): + SyncLightAmbient(5); + break; + case PICA_REG_INDEX(lighting.light[6].ambient): + SyncLightAmbient(6); + break; + case PICA_REG_INDEX(lighting.light[7].ambient): + SyncLightAmbient(7); + break; + + // Fragment lighting position + case PICA_REG_INDEX(lighting.light[0].x): + case PICA_REG_INDEX(lighting.light[0].z): + SyncLightPosition(0); + break; + case PICA_REG_INDEX(lighting.light[1].x): + case PICA_REG_INDEX(lighting.light[1].z): + SyncLightPosition(1); + break; + case PICA_REG_INDEX(lighting.light[2].x): + case PICA_REG_INDEX(lighting.light[2].z): + SyncLightPosition(2); + break; + case PICA_REG_INDEX(lighting.light[3].x): + case PICA_REG_INDEX(lighting.light[3].z): + SyncLightPosition(3); + break; + case PICA_REG_INDEX(lighting.light[4].x): + case PICA_REG_INDEX(lighting.light[4].z): + SyncLightPosition(4); + break; + case PICA_REG_INDEX(lighting.light[5].x): + case PICA_REG_INDEX(lighting.light[5].z): + SyncLightPosition(5); + break; + case PICA_REG_INDEX(lighting.light[6].x): + case PICA_REG_INDEX(lighting.light[6].z): + SyncLightPosition(6); + break; + case PICA_REG_INDEX(lighting.light[7].x): + case PICA_REG_INDEX(lighting.light[7].z): + SyncLightPosition(7); + break; + + // Fragment spot lighting direction + case PICA_REG_INDEX(lighting.light[0].spot_x): + case PICA_REG_INDEX(lighting.light[0].spot_z): + SyncLightSpotDirection(0); + break; + case PICA_REG_INDEX(lighting.light[1].spot_x): + case PICA_REG_INDEX(lighting.light[1].spot_z): + SyncLightSpotDirection(1); + break; + case PICA_REG_INDEX(lighting.light[2].spot_x): + case PICA_REG_INDEX(lighting.light[2].spot_z): + SyncLightSpotDirection(2); + break; + case PICA_REG_INDEX(lighting.light[3].spot_x): + case PICA_REG_INDEX(lighting.light[3].spot_z): + SyncLightSpotDirection(3); + break; + case PICA_REG_INDEX(lighting.light[4].spot_x): + case PICA_REG_INDEX(lighting.light[4].spot_z): + SyncLightSpotDirection(4); + break; + case PICA_REG_INDEX(lighting.light[5].spot_x): + case PICA_REG_INDEX(lighting.light[5].spot_z): + SyncLightSpotDirection(5); + break; + case PICA_REG_INDEX(lighting.light[6].spot_x): + case PICA_REG_INDEX(lighting.light[6].spot_z): + SyncLightSpotDirection(6); + break; + case PICA_REG_INDEX(lighting.light[7].spot_x): + case PICA_REG_INDEX(lighting.light[7].spot_z): + SyncLightSpotDirection(7); + break; + + // Fragment lighting light source config + case PICA_REG_INDEX(lighting.light[0].config): + case PICA_REG_INDEX(lighting.light[1].config): + case PICA_REG_INDEX(lighting.light[2].config): + case PICA_REG_INDEX(lighting.light[3].config): + case PICA_REG_INDEX(lighting.light[4].config): + case PICA_REG_INDEX(lighting.light[5].config): + case PICA_REG_INDEX(lighting.light[6].config): + case PICA_REG_INDEX(lighting.light[7].config): + shader_dirty = true; + break; + + // Fragment lighting distance attenuation bias + case PICA_REG_INDEX(lighting.light[0].dist_atten_bias): + SyncLightDistanceAttenuationBias(0); + break; + case PICA_REG_INDEX(lighting.light[1].dist_atten_bias): + SyncLightDistanceAttenuationBias(1); + break; + case PICA_REG_INDEX(lighting.light[2].dist_atten_bias): + SyncLightDistanceAttenuationBias(2); + break; + case PICA_REG_INDEX(lighting.light[3].dist_atten_bias): + SyncLightDistanceAttenuationBias(3); + break; + case PICA_REG_INDEX(lighting.light[4].dist_atten_bias): + SyncLightDistanceAttenuationBias(4); + break; + case PICA_REG_INDEX(lighting.light[5].dist_atten_bias): + SyncLightDistanceAttenuationBias(5); + break; + case PICA_REG_INDEX(lighting.light[6].dist_atten_bias): + SyncLightDistanceAttenuationBias(6); + break; + case PICA_REG_INDEX(lighting.light[7].dist_atten_bias): + SyncLightDistanceAttenuationBias(7); + break; + + // Fragment lighting distance attenuation scale + case PICA_REG_INDEX(lighting.light[0].dist_atten_scale): + SyncLightDistanceAttenuationScale(0); + break; + case PICA_REG_INDEX(lighting.light[1].dist_atten_scale): + SyncLightDistanceAttenuationScale(1); + break; + case PICA_REG_INDEX(lighting.light[2].dist_atten_scale): + SyncLightDistanceAttenuationScale(2); + break; + case PICA_REG_INDEX(lighting.light[3].dist_atten_scale): + SyncLightDistanceAttenuationScale(3); + break; + case PICA_REG_INDEX(lighting.light[4].dist_atten_scale): + SyncLightDistanceAttenuationScale(4); + break; + case PICA_REG_INDEX(lighting.light[5].dist_atten_scale): + SyncLightDistanceAttenuationScale(5); + break; + case PICA_REG_INDEX(lighting.light[6].dist_atten_scale): + SyncLightDistanceAttenuationScale(6); + break; + case PICA_REG_INDEX(lighting.light[7].dist_atten_scale): + SyncLightDistanceAttenuationScale(7); + break; + + // Fragment lighting global ambient color (emission + ambient * ambient) + case PICA_REG_INDEX(lighting.global_ambient): + SyncGlobalAmbient(); + break; + + // Fragment lighting lookup tables + case PICA_REG_INDEX(lighting.lut_data[0]): + case PICA_REG_INDEX(lighting.lut_data[1]): + case PICA_REG_INDEX(lighting.lut_data[2]): + case PICA_REG_INDEX(lighting.lut_data[3]): + case PICA_REG_INDEX(lighting.lut_data[4]): + case PICA_REG_INDEX(lighting.lut_data[5]): + case PICA_REG_INDEX(lighting.lut_data[6]): + case PICA_REG_INDEX(lighting.lut_data[7]): { + const auto& lut_config = regs.lighting.lut_config; + uniform_block_data.lighting_lut_dirty[lut_config.type] = true; + uniform_block_data.lighting_lut_dirty_any = true; + break; + } + + // Texture LOD biases + case PICA_REG_INDEX(texturing.texture0.lod.bias): + SyncTextureLodBias(0); + break; + case PICA_REG_INDEX(texturing.texture1.lod.bias): + SyncTextureLodBias(1); + break; + case PICA_REG_INDEX(texturing.texture2.lod.bias): + SyncTextureLodBias(2); + break; + + // Clipping plane + case PICA_REG_INDEX(rasterizer.clip_coef[0]): + case PICA_REG_INDEX(rasterizer.clip_coef[1]): + case PICA_REG_INDEX(rasterizer.clip_coef[2]): + case PICA_REG_INDEX(rasterizer.clip_coef[3]): + SyncClipCoef(); + break; + + default: + // Forward registers that map to fixed function API features to the video backend + NotifyFixedFunctionPicaRegisterChanged(id); + } +} + +void RasterizerAccelerated::SyncDepthScale() { + float depth_scale = Pica::float24::FromRaw(regs.rasterizer.viewport_depth_range).ToFloat32(); + + if (depth_scale != uniform_block_data.data.depth_scale) { + uniform_block_data.data.depth_scale = depth_scale; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncDepthOffset() { + float depth_offset = + Pica::float24::FromRaw(regs.rasterizer.viewport_depth_near_plane).ToFloat32(); + + if (depth_offset != uniform_block_data.data.depth_offset) { + uniform_block_data.data.depth_offset = depth_offset; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncFogColor() { + const auto& fog_color_regs = regs.texturing.fog_color; + const Common::Vec3f fog_color = { + fog_color_regs.r.Value() / 255.0f, + fog_color_regs.g.Value() / 255.0f, + fog_color_regs.b.Value() / 255.0f, + }; + + if (fog_color != uniform_block_data.data.fog_color) { + uniform_block_data.data.fog_color = fog_color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncProcTexNoise() { + const Common::Vec2f proctex_noise_f = { + Pica::float16::FromRaw(regs.texturing.proctex_noise_frequency.u).ToFloat32(), + Pica::float16::FromRaw(regs.texturing.proctex_noise_frequency.v).ToFloat32(), + }; + const Common::Vec2f proctex_noise_a = { + regs.texturing.proctex_noise_u.amplitude / 4095.0f, + regs.texturing.proctex_noise_v.amplitude / 4095.0f, + }; + const Common::Vec2f proctex_noise_p = { + Pica::float16::FromRaw(regs.texturing.proctex_noise_u.phase).ToFloat32(), + Pica::float16::FromRaw(regs.texturing.proctex_noise_v.phase).ToFloat32(), + }; + + if (proctex_noise_f != uniform_block_data.data.proctex_noise_f || + proctex_noise_a != uniform_block_data.data.proctex_noise_a || + proctex_noise_p != uniform_block_data.data.proctex_noise_p) { + uniform_block_data.data.proctex_noise_f = proctex_noise_f; + uniform_block_data.data.proctex_noise_a = proctex_noise_a; + uniform_block_data.data.proctex_noise_p = proctex_noise_p; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncProcTexBias() { + const auto proctex_bias = Pica::float16::FromRaw(regs.texturing.proctex.bias_low | + (regs.texturing.proctex_lut.bias_high << 8)) + .ToFloat32(); + if (proctex_bias != uniform_block_data.data.proctex_bias) { + uniform_block_data.data.proctex_bias = proctex_bias; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncAlphaTest() { + if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { + uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncCombinerColor() { + auto combiner_color = ColorRGBA8(regs.texturing.tev_combiner_buffer_color.raw); + if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { + uniform_block_data.data.tev_combiner_buffer_color = combiner_color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncTevConstColor( + std::size_t stage_index, const Pica::TexturingRegs::TevStageConfig& tev_stage) { + const auto const_color = ColorRGBA8(tev_stage.const_color); + + if (const_color == uniform_block_data.data.const_color[stage_index]) { + return; + } + + uniform_block_data.data.const_color[stage_index] = const_color; + uniform_block_data.dirty = true; +} + +void RasterizerAccelerated::SyncGlobalAmbient() { + auto color = LightColor(regs.lighting.global_ambient); + if (color != uniform_block_data.data.lighting_global_ambient) { + uniform_block_data.data.lighting_global_ambient = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpecular0(int light_index) { + auto color = LightColor(regs.lighting.light[light_index].specular_0); + if (color != uniform_block_data.data.light_src[light_index].specular_0) { + uniform_block_data.data.light_src[light_index].specular_0 = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpecular1(int light_index) { + auto color = LightColor(regs.lighting.light[light_index].specular_1); + if (color != uniform_block_data.data.light_src[light_index].specular_1) { + uniform_block_data.data.light_src[light_index].specular_1 = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDiffuse(int light_index) { + auto color = LightColor(regs.lighting.light[light_index].diffuse); + if (color != uniform_block_data.data.light_src[light_index].diffuse) { + uniform_block_data.data.light_src[light_index].diffuse = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightAmbient(int light_index) { + auto color = LightColor(regs.lighting.light[light_index].ambient); + if (color != uniform_block_data.data.light_src[light_index].ambient) { + uniform_block_data.data.light_src[light_index].ambient = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightPosition(int light_index) { + const Common::Vec3f position = { + Pica::float16::FromRaw(regs.lighting.light[light_index].x).ToFloat32(), + Pica::float16::FromRaw(regs.lighting.light[light_index].y).ToFloat32(), + Pica::float16::FromRaw(regs.lighting.light[light_index].z).ToFloat32(), + }; + + if (position != uniform_block_data.data.light_src[light_index].position) { + uniform_block_data.data.light_src[light_index].position = position; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpotDirection(int light_index) { + const auto& light = regs.lighting.light[light_index]; + const auto spot_direction = + Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f}; + + if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { + uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDistanceAttenuationBias(int light_index) { + float dist_atten_bias = + Pica::float20::FromRaw(regs.lighting.light[light_index].dist_atten_bias).ToFloat32(); + + if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { + uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDistanceAttenuationScale(int light_index) { + float dist_atten_scale = + Pica::float20::FromRaw(regs.lighting.light[light_index].dist_atten_scale).ToFloat32(); + + if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { + uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncShadowBias() { + const auto& shadow = regs.framebuffer.shadow; + float constant = Pica::float16::FromRaw(shadow.constant).ToFloat32(); + float linear = Pica::float16::FromRaw(shadow.linear).ToFloat32(); + + if (constant != uniform_block_data.data.shadow_bias_constant || + linear != uniform_block_data.data.shadow_bias_linear) { + uniform_block_data.data.shadow_bias_constant = constant; + uniform_block_data.data.shadow_bias_linear = linear; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncShadowTextureBias() { + int bias = regs.texturing.shadow.bias << 1; + if (bias != uniform_block_data.data.shadow_texture_bias) { + uniform_block_data.data.shadow_texture_bias = bias; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncTextureLodBias(int tex_index) { + const auto pica_textures = regs.texturing.GetTextures(); + const float bias = pica_textures[tex_index].config.lod.bias / 256.0f; + if (bias != uniform_block_data.data.tex_lod_bias[tex_index]) { + uniform_block_data.data.tex_lod_bias[tex_index] = bias; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncClipCoef() { + const auto raw_clip_coef = regs.rasterizer.GetClipCoef(); + const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(), + raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()}; + if (new_clip_coef != uniform_block_data.data.clip_coef) { + uniform_block_data.data.clip_coef = new_clip_coef; + uniform_block_data.dirty = true; + } +} + +} // namespace VideoCore diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h new file mode 100644 index 000000000..d9191226b --- /dev/null +++ b/src/video_core/rasterizer_accelerated.h @@ -0,0 +1,159 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/vector_math.h" +#include "video_core/rasterizer_interface.h" +#include "video_core/regs_texturing.h" +#include "video_core/shader/shader_uniforms.h" + +namespace Memory { +class MemorySystem; +} + +namespace Pica { +struct Regs; +} + +namespace VideoCore { + +class RasterizerAccelerated : public RasterizerInterface { +public: + RasterizerAccelerated(Memory::MemorySystem& memory); + virtual ~RasterizerAccelerated() = default; + + void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) override; + void NotifyPicaRegisterChanged(u32 id) override; + void SyncEntireState() override; + +protected: + /// Sync fixed-function pipeline state + virtual void SyncFixedState() = 0; + + /// Notifies that a fixed function PICA register changed to the video backend + virtual void NotifyFixedFunctionPicaRegisterChanged(u32 id) = 0; + + /// Syncs the depth scale to match the PICA register + void SyncDepthScale(); + + /// Syncs the depth offset to match the PICA register + void SyncDepthOffset(); + + /// Syncs the fog states to match the PICA register + void SyncFogColor(); + + /// Sync the procedural texture noise configuration to match the PICA register + void SyncProcTexNoise(); + + /// Sync the procedural texture bias configuration to match the PICA register + void SyncProcTexBias(); + + /// Syncs the alpha test states to match the PICA register + void SyncAlphaTest(); + + /// Syncs the TEV combiner color buffer to match the PICA register + void SyncCombinerColor(); + + /// Syncs the TEV constant color to match the PICA register + void SyncTevConstColor(std::size_t tev_index, + const Pica::TexturingRegs::TevStageConfig& tev_stage); + + /// Syncs the lighting global ambient color to match the PICA register + void SyncGlobalAmbient(); + + /// Syncs the specified light's specular 0 color to match the PICA register + void SyncLightSpecular0(int light_index); + + /// Syncs the specified light's specular 1 color to match the PICA register + void SyncLightSpecular1(int light_index); + + /// Syncs the specified light's diffuse color to match the PICA register + void SyncLightDiffuse(int light_index); + + /// Syncs the specified light's ambient color to match the PICA register + void SyncLightAmbient(int light_index); + + /// Syncs the specified light's position to match the PICA register + void SyncLightPosition(int light_index); + + /// Syncs the specified spot light direcition to match the PICA register + void SyncLightSpotDirection(int light_index); + + /// Syncs the specified light's distance attenuation bias to match the PICA register + void SyncLightDistanceAttenuationBias(int light_index); + + /// Syncs the specified light's distance attenuation scale to match the PICA register + void SyncLightDistanceAttenuationScale(int light_index); + + /// Syncs the shadow rendering bias to match the PICA register + void SyncShadowBias(); + + /// Syncs the shadow texture bias to match the PICA register + void SyncShadowTextureBias(); + + /// Syncs the texture LOD bias to match the PICA register + void SyncTextureLodBias(int tex_index); + + /// Syncs the clip coefficients to match the PICA register + void SyncClipCoef(); + +protected: + /// Structure that keeps tracks of the uniform state + struct UniformBlockData { + Pica::Shader::UniformData data{}; + std::array lighting_lut_dirty{}; + bool lighting_lut_dirty_any = true; + bool fog_lut_dirty = true; + bool proctex_noise_lut_dirty = true; + bool proctex_color_map_dirty = true; + bool proctex_alpha_map_dirty = true; + bool proctex_lut_dirty = true; + bool proctex_diff_lut_dirty = true; + bool dirty = true; + }; + + /// Structure that the hardware rendered vertices are composed of + struct HardwareVertex { + HardwareVertex() = default; + HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion); + + Common::Vec4f position; + Common::Vec4f color; + Common::Vec2f tex_coord0; + Common::Vec2f tex_coord1; + Common::Vec2f tex_coord2; + float tex_coord0_w; + Common::Vec4f normquat; + Common::Vec3f view; + }; + + struct VertexArrayInfo { + u32 vs_input_index_min; + u32 vs_input_index_max; + u32 vs_input_size; + }; + + /// Retrieve the range and the size of the input vertex + VertexArrayInfo AnalyzeVertexArray(bool is_indexed, u32 stride_alignment = 1); + +protected: + Memory::MemorySystem& memory; + Pica::Regs& regs; + + std::vector vertex_batch; + bool shader_dirty = true; + + UniformBlockData uniform_block_data{}; + std::array, Pica::LightingRegs::NumLightingSampler> + lighting_lut_data{}; + std::array fog_lut_data{}; + std::array proctex_noise_lut_data{}; + std::array proctex_color_map_data{}; + std::array proctex_alpha_map_data{}; + std::array proctex_lut_data{}; + std::array proctex_diff_lut_data{}; +}; +} // namespace VideoCore diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 38b9ce445..90be75287 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -2,15 +2,17 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include +#include "core/core.h" #include "core/frontend/emu_window.h" +#include "core/tracer/recorder.h" +#include "video_core/debug_utils/debug_utils.h" #include "video_core/renderer_base.h" -#include "video_core/renderer_opengl/gl_rasterizer.h" -#include "video_core/swrasterizer/swrasterizer.h" -#include "video_core/video_core.h" -RendererBase::RendererBase(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window_) - : render_window{window}, secondary_window{secondary_window_} {} +namespace VideoCore { + +RendererBase::RendererBase(Core::System& system_, Frontend::EmuWindow& window, + Frontend::EmuWindow* secondary_window_) + : system{system_}, render_window{window}, secondary_window{secondary_window_} {} RendererBase::~RendererBase() = default; @@ -25,19 +27,35 @@ void RendererBase::UpdateCurrentFramebufferLayout(bool is_portrait_mode) { } } -void RendererBase::RefreshRasterizerSetting() { - bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; - if (rasterizer == nullptr || opengl_rasterizer_active != hw_renderer_enabled) { - opengl_rasterizer_active = hw_renderer_enabled; +void RendererBase::EndFrame() { + current_frame++; - if (hw_renderer_enabled) { - rasterizer = std::make_unique(render_window); - } else { - rasterizer = std::make_unique(); - } + system.perf_stats->EndSystemFrame(); + + render_window.PollEvents(); + + system.frame_limiter.DoFrameLimiting(system.CoreTiming().GetGlobalTimeUs()); + system.perf_stats->BeginSystemFrame(); + + if (Pica::g_debug_context && Pica::g_debug_context->recorder) { + Pica::g_debug_context->recorder->FrameFinished(); } } -void RendererBase::Sync() { - rasterizer->SyncEntireState(); +bool RendererBase::IsScreenshotPending() const { + return renderer_settings.screenshot_requested; } + +void RendererBase::RequestScreenshot(void* data, std::function callback, + const Layout::FramebufferLayout& layout) { + if (renderer_settings.screenshot_requested) { + LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request"); + return; + } + renderer_settings.screenshot_bits = data; + renderer_settings.screenshot_complete_callback = callback; + renderer_settings.screenshot_framebuffer_layout = layout; + renderer_settings.screenshot_requested = true; +} + +} // namespace VideoCore diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 01a87d261..ab9c4d333 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -4,25 +4,36 @@ #pragma once -#include #include "common/common_types.h" +#include "core/frontend/framebuffer_layout.h" #include "video_core/rasterizer_interface.h" -#include "video_core/video_core.h" namespace Frontend { class EmuWindow; } +namespace Core { +class System; +} + +namespace VideoCore { + +struct RendererSettings { + // Screenshot + std::atomic_bool screenshot_requested{false}; + void* screenshot_bits{}; + std::function screenshot_complete_callback; + Layout::FramebufferLayout screenshot_framebuffer_layout; +}; + class RendererBase : NonCopyable { public: - explicit RendererBase(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window); + explicit RendererBase(Core::System& system, Frontend::EmuWindow& window, + Frontend::EmuWindow* secondary_window); virtual ~RendererBase(); - /// Initialize the renderer - virtual VideoCore::ResultStatus Init() = 0; - - /// Shutdown the renderer - virtual void ShutDown() = 0; + /// Returns the rasterizer owned by the renderer + virtual VideoCore::RasterizerInterface* Rasterizer() const = 0; /// Finalize rendering the guest frame and draw into the presentation texture virtual void SwapBuffers() = 0; @@ -35,27 +46,29 @@ public: } /// Prepares for video dumping (e.g. create necessary buffers, etc) - virtual void PrepareVideoDumping() = 0; + virtual void PrepareVideoDumping() {} /// Cleans up after video dumping is ended - virtual void CleanupVideoDumping() = 0; + virtual void CleanupVideoDumping() {} + + /// Synchronizes fixed function renderer state + virtual void Sync() {} /// Updates the framebuffer layout of the contained render window handle. void UpdateCurrentFramebufferLayout(bool is_portrait_mode = {}); + /// Ends the current frame + void EndFrame(); + // Getter/setter functions: // ------------------------ f32 GetCurrentFPS() const { - return m_current_fps; + return current_fps; } int GetCurrentFrame() const { - return m_current_frame; - } - - VideoCore::RasterizerInterface* Rasterizer() const { - return rasterizer.get(); + return current_frame; } Frontend::EmuWindow& GetRenderWindow() { @@ -66,16 +79,28 @@ public: return render_window; } - void RefreshRasterizerSetting(); - void Sync(); + [[nodiscard]] RendererSettings& Settings() { + return renderer_settings; + } + + [[nodiscard]] const RendererSettings& Settings() const { + return renderer_settings; + } + + /// Returns true if a screenshot is being processed + [[nodiscard]] bool IsScreenshotPending() const; + + /// Request a screenshot of the next frame + void RequestScreenshot(void* data, std::function callback, + const Layout::FramebufferLayout& layout); protected: + Core::System& system; + RendererSettings renderer_settings; Frontend::EmuWindow& render_window; ///< Reference to the render window handle. Frontend::EmuWindow* secondary_window; ///< Reference to the secondary render window handle. - std::unique_ptr rasterizer; - f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer - int m_current_frame = 0; ///< Current frame, should be set by the renderer - -private: - bool opengl_rasterizer_active = false; + f32 current_fps = 0.0f; ///< Current framerate, should be set by the renderer + int current_frame = 0; ///< Current frame, should be set by the renderer }; + +} // namespace VideoCore diff --git a/src/video_core/renderer_opengl/frame_dumper_opengl.cpp b/src/video_core/renderer_opengl/frame_dumper_opengl.cpp index 53985823c..3122de2f7 100644 --- a/src/video_core/renderer_opengl/frame_dumper_opengl.cpp +++ b/src/video_core/renderer_opengl/frame_dumper_opengl.cpp @@ -4,7 +4,6 @@ #include #include "core/frontend/emu_window.h" -#include "core/frontend/scope_acquire_context.h" #include "video_core/renderer_opengl/frame_dumper_opengl.h" #include "video_core/renderer_opengl/renderer_opengl.h" @@ -39,7 +38,7 @@ void FrameDumperOpenGL::StopDumping() { } void FrameDumperOpenGL::PresentLoop() { - Frontend::ScopeAcquireContext scope{*context}; + const auto scope = context->Acquire(); InitializeOpenGLObjects(); const auto& layout = GetLayout(); diff --git a/src/video_core/renderer_opengl/gl_driver.cpp b/src/video_core/renderer_opengl/gl_driver.cpp new file mode 100644 index 000000000..13d585270 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_driver.cpp @@ -0,0 +1,156 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "common/assert.h" +#include "common/settings.h" +#include "core/telemetry_session.h" +#include "video_core/renderer_opengl/gl_driver.h" + +namespace OpenGL { + +DECLARE_ENUM_FLAG_OPERATORS(DriverBug); + +inline std::string_view GetSource(GLenum source) { +#define RET(s) \ + case GL_DEBUG_SOURCE_##s: \ + return #s + switch (source) { + RET(API); + RET(WINDOW_SYSTEM); + RET(SHADER_COMPILER); + RET(THIRD_PARTY); + RET(APPLICATION); + RET(OTHER); + default: + UNREACHABLE(); + } +#undef RET + + return std::string_view{}; +} + +inline std::string_view GetType(GLenum type) { +#define RET(t) \ + case GL_DEBUG_TYPE_##t: \ + return #t + switch (type) { + RET(ERROR); + RET(DEPRECATED_BEHAVIOR); + RET(UNDEFINED_BEHAVIOR); + RET(PORTABILITY); + RET(PERFORMANCE); + RET(OTHER); + RET(MARKER); + default: + UNREACHABLE(); + } +#undef RET + + return std::string_view{}; +} + +static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* message, const void* user_param) { + Log::Level level = Log::Level::Info; + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: + level = Log::Level::Critical; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + level = Log::Level::Warning; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + case GL_DEBUG_SEVERITY_LOW: + level = Log::Level::Debug; + break; + } + + LOG_GENERIC(Log::Class::Render_OpenGL, level, "{} {} {}: {}", GetSource(source), GetType(type), + id, message); +} + +Driver::Driver(Core::TelemetrySession& telemetry_session_) : telemetry_session{telemetry_session_} { + const bool enable_debug = Settings::values.renderer_debug.GetValue(); + if (enable_debug) { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(DebugHandler, nullptr); + } + + ReportDriverInfo(); + DeduceVendor(); + CheckExtensionSupport(); + FindBugs(); +} + +Driver::~Driver() = default; + +bool Driver::HasBug(DriverBug bug) const { + return True(bugs & bug); +} + +void Driver::ReportDriverInfo() { + // Report the context version and the vendor string + gl_version = std::string_view{reinterpret_cast(glGetString(GL_VERSION))}; + gpu_vendor = std::string_view{reinterpret_cast(glGetString(GL_VENDOR))}; + gpu_model = std::string_view{reinterpret_cast(glGetString(GL_RENDERER))}; + + LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version); + LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); + LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); + + // Add the information to the telemetry system + constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; + telemetry_session.AddField(user_system, "GPU_Vendor", std::string{gpu_vendor}); + telemetry_session.AddField(user_system, "GPU_Model", std::string{gpu_model}); + telemetry_session.AddField(user_system, "GPU_OpenGL_Version", std::string{gl_version}); +} + +void Driver::DeduceVendor() { + if (gpu_vendor.find("NVIDIA") != gpu_vendor.npos) { + vendor = Vendor::Nvidia; + } else if ((gpu_vendor.find("ATI") != gpu_vendor.npos) || + (gpu_vendor.find("AMD") != gpu_vendor.npos) || + (gpu_vendor.find("Advanced Micro Devices") != gpu_vendor.npos)) { + vendor = Vendor::AMD; + } else if (gpu_vendor.find("Intel") != gpu_vendor.npos) { + vendor = Vendor::Intel; + } else if (gpu_vendor.find("ARM") != gpu_vendor.npos) { + vendor = Vendor::ARM; + } else if (gpu_vendor.find("Qualcomm") != gpu_vendor.npos) { + vendor = Vendor::Qualcomm; + } else if (gpu_vendor.find("Samsung") != gpu_vendor.npos) { + vendor = Vendor::Samsung; + } else if (gpu_vendor.find("GDI Generic") != gpu_vendor.npos) { + vendor = Vendor::Generic; + } +} + +void Driver::CheckExtensionSupport() { + ext_buffer_storage = GLAD_GL_EXT_buffer_storage; + arb_buffer_storage = GLAD_GL_ARB_buffer_storage; + arb_clear_texture = GLAD_GL_ARB_clear_texture; + arb_get_texture_sub_image = GLAD_GL_ARB_get_texture_sub_image; + ext_clip_cull_distance = GLAD_GL_EXT_clip_cull_distance; + is_suitable = GLAD_GL_VERSION_4_3 || GLAD_GL_ES_VERSION_3_1; +} + +void Driver::FindBugs() { +#ifdef __unix__ + const bool is_linux = true; +#else + const bool is_linux = false; +#endif + + // TODO: Check if these have been fixed in the newer driver + if (vendor == Vendor::AMD) { + bugs |= DriverBug::ShaderStageChangeFreeze | DriverBug::VertexArrayOutOfBound; + } + + if (vendor == Vendor::AMD || (vendor == Vendor::Intel && !is_linux)) { + bugs |= DriverBug::BrokenTextureView; + } +} + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_driver.h b/src/video_core/renderer_opengl/gl_driver.h new file mode 100644 index 000000000..a7a995305 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_driver.h @@ -0,0 +1,114 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "common/common_types.h" + +namespace Core { +class TelemetrySession; +} + +namespace OpenGL { + +enum class Vendor { + Unknown = 0, + AMD = 1, + Nvidia = 2, + Intel = 3, + ARM = 4, + Qualcomm = 5, + Samsung = 6, + Generic = 7, +}; + +enum class DriverBug { + // AMD drivers sometimes freezes when one shader stage is changed but not the others. + ShaderStageChangeFreeze = 1 << 0, + // On AMD drivers there is a strange crash in indexed drawing. The crash happens when the buffer + // read position is near the end and is an out-of-bound access to the vertex buffer. This is + // probably a bug in the driver and is related to the usage of vec3 attributes in the + // vertex array. Doubling the allocation size for the vertex buffer seems to avoid the crash. + VertexArrayOutOfBound = 1 << 1, + // On AMD and Intel drivers on Windows glTextureView produces incorrect results + BrokenTextureView = 1 << 2, +}; + +/** + * Utility class that loads the OpenGL function pointers and reports + * information about the graphics device and driver used + */ +class Driver { +public: + Driver(Core::TelemetrySession& telemetry_session); + ~Driver(); + + /// Returns true of the driver has a particular bug stated in the DriverBug enum + bool HasBug(DriverBug bug) const; + + /// Returns the vendor of the currently selected physical device + Vendor GetVendor() const { + return vendor; + } + + /// Returns the gpu vendor string returned by the driver + std::string_view GetVendorString() const { + return gpu_vendor; + } + + /// Returns true if the implementation is suitable for emulation + bool IsSuitable() const { + return is_suitable; + } + + /// Returns true if the implementation supports ARB_buffer_storage + bool HasArbBufferStorage() const { + return arb_buffer_storage; + } + + /// Returns true if the implementation supports EXT_buffer_storage + bool HasExtBufferStorage() const { + return ext_buffer_storage; + } + + /// Returns true if the implementation supports ARB_clear_texture + bool HasArbClearTexture() const { + return arb_clear_texture; + } + + /// Returns true if the implementation supports ARB_get_texture_sub_image + bool HasArbGetTextureSubImage() const { + return arb_get_texture_sub_image; + } + + /// Returns true if the implementation supports EXT_clip_cull_distance + bool HasExtClipCullDistance() const { + return ext_clip_cull_distance; + } + +private: + void ReportDriverInfo(); + void DeduceVendor(); + void CheckExtensionSupport(); + void FindBugs(); + +private: + Core::TelemetrySession& telemetry_session; + Vendor vendor = Vendor::Unknown; + DriverBug bugs{}; + bool is_suitable{}; + + bool ext_buffer_storage{}; + bool arb_buffer_storage{}; + bool arb_clear_texture{}; + bool arb_get_texture_sub_image{}; + bool ext_clip_cull_distance{}; + + std::string_view gl_version{}; + std::string_view gpu_vendor{}; + std::string_view gpu_model{}; +}; + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9592c3d1d..1cf3f4760 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -19,6 +19,8 @@ namespace OpenGL { +namespace { + MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(255, 128, 0)); MICROPROFILE_DEFINE(OpenGL_VS, "OpenGL", "Vertex Shader Setup", MP_RGB(192, 128, 128)); MICROPROFILE_DEFINE(OpenGL_GS, "OpenGL", "Geometry Shader Setup", MP_RGB(128, 192, 128)); @@ -26,23 +28,52 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); -static bool IsVendorAmd() { - const std::string_view gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; - return gpu_vendor == "ATI Technologies Inc." || gpu_vendor == "Advanced Micro Devices, Inc."; -} -#ifdef __APPLE__ -static bool IsVendorIntel() { - std::string gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; - return gpu_vendor == "Intel Inc."; -} -#endif +constexpr std::size_t VERTEX_BUFFER_SIZE = 16 * 1024 * 1024; +constexpr std::size_t INDEX_BUFFER_SIZE = 2 * 1024 * 1024; +constexpr std::size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024; +constexpr std::size_t TEXTURE_BUFFER_SIZE = 2 * 1024 * 1024; -RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window) - : is_amd(IsVendorAmd()), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), - uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE, false), - index_buffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE, false), - texture_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE, false), - texture_lf_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE, false) { +GLenum MakePrimitiveMode(Pica::PipelineRegs::TriangleTopology topology) { + switch (topology) { + case Pica::PipelineRegs::TriangleTopology::Shader: + case Pica::PipelineRegs::TriangleTopology::List: + return GL_TRIANGLES; + case Pica::PipelineRegs::TriangleTopology::Fan: + return GL_TRIANGLE_FAN; + case Pica::PipelineRegs::TriangleTopology::Strip: + return GL_TRIANGLE_STRIP; + default: + UNREACHABLE(); + } + return GL_TRIANGLES; +} + +GLenum MakeAttributeType(Pica::PipelineRegs::VertexAttributeFormat format) { + switch (format) { + case Pica::PipelineRegs::VertexAttributeFormat::BYTE: + return GL_BYTE; + case Pica::PipelineRegs::VertexAttributeFormat::UBYTE: + return GL_UNSIGNED_BYTE; + case Pica::PipelineRegs::VertexAttributeFormat::SHORT: + return GL_SHORT; + case Pica::PipelineRegs::VertexAttributeFormat::FLOAT: + return GL_FLOAT; + } + return GL_UNSIGNED_BYTE; +} + +} // Anonymous namespace + +RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory, Frontend::EmuWindow& emu_window, + Driver& driver_) + : VideoCore::RasterizerAccelerated{memory}, driver{driver_}, vertex_buffer{driver, + GL_ARRAY_BUFFER, + VERTEX_BUFFER_SIZE}, + uniform_buffer{driver, GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE}, + index_buffer{driver, GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE}, + texture_buffer{driver, GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE}, texture_lf_buffer{ + driver, GL_TEXTURE_BUFFER, + TEXTURE_BUFFER_SIZE} { // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0 state.clip_distance[0] = true; @@ -69,24 +100,11 @@ RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window) sw_vao.Create(); hw_vao.Create(); - uniform_block_data.dirty = true; - - uniform_block_data.lighting_lut_dirty.fill(true); - uniform_block_data.lighting_lut_dirty_any = true; - - uniform_block_data.fog_lut_dirty = true; - - uniform_block_data.proctex_noise_lut_dirty = true; - uniform_block_data.proctex_color_map_dirty = true; - uniform_block_data.proctex_alpha_map_dirty = true; - uniform_block_data.proctex_lut_dirty = true; - uniform_block_data.proctex_diff_lut_dirty = true; - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); uniform_size_aligned_vs = - Common::AlignUp(sizeof(VSUniformData), uniform_buffer_alignment); + Common::AlignUp(sizeof(Pica::Shader::VSUniformData), uniform_buffer_alignment); uniform_size_aligned_fs = - Common::AlignUp(sizeof(UniformData), uniform_buffer_alignment); + Common::AlignUp(sizeof(Pica::Shader::UniformData), uniform_buffer_alignment); // Set vertex attributes for software shader path state.draw.vertex_array = sw_vao.handle; @@ -147,21 +165,19 @@ RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.GetHandle()); #ifdef __APPLE__ - if (IsVendorIntel()) { + if (driver.GetVendor() == Vendor::Intel) { shader_program_manager = std::make_unique( - emu_window, VideoCore::g_separable_shader_enabled, is_amd); + emu_window, driver, VideoCore::g_separable_shader_enabled); } else { - shader_program_manager = std::make_unique(emu_window, true, is_amd); + shader_program_manager = std::make_unique(emu_window, driver, true); } #else - shader_program_manager = std::make_unique(emu_window, !GLES, is_amd); + shader_program_manager = std::make_unique(emu_window, driver, !GLES); #endif glEnable(GL_BLEND); - // Explicitly call the derived version to avoid warnings about calling virtual - // methods in the constructor - RasterizerOpenGL::SyncEntireState(); + SyncEntireState(); } RasterizerOpenGL::~RasterizerOpenGL() = default; @@ -171,8 +187,7 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, shader_program_manager->LoadDiskCache(stop_loading, callback); } -void RasterizerOpenGL::SyncEntireState() { - // Sync fixed function OpenGL state +void RasterizerOpenGL::SyncFixedState() { SyncClipEnabled(); SyncCullMode(); SyncBlendEnabled(); @@ -184,123 +199,11 @@ void RasterizerOpenGL::SyncEntireState() { SyncColorWriteMask(); SyncStencilWriteMask(); SyncDepthWriteMask(); - - // Sync uniforms - SyncClipCoef(); - SyncDepthScale(); - SyncDepthOffset(); - SyncAlphaTest(); - SyncCombinerColor(); - auto& tev_stages = Pica::g_state.regs.texturing.GetTevStages(); - for (std::size_t index = 0; index < tev_stages.size(); ++index) - SyncTevConstColor(index, tev_stages[index]); - - SyncGlobalAmbient(); - for (unsigned light_index = 0; light_index < 8; light_index++) { - SyncLightSpecular0(light_index); - SyncLightSpecular1(light_index); - SyncLightDiffuse(light_index); - SyncLightAmbient(light_index); - SyncLightPosition(light_index); - SyncLightDistanceAttenuationBias(light_index); - SyncLightDistanceAttenuationScale(light_index); - } - - SyncFogColor(); - SyncProcTexNoise(); - SyncProcTexBias(); - SyncShadowBias(); - SyncShadowTextureBias(); -} - -/** - * This is a helper function to resolve an issue when interpolating opposite quaternions. See below - * for a detailed description of this issue (yuriks): - * - * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you - * interpolate two quaternions that are opposite, instead of going from one rotation to another - * using the shortest path, you'll go around the longest path. You can test if two quaternions are - * opposite by checking if Dot(Q1, Q2) < 0. In that case, you can flip either of them, therefore - * making Dot(Q1, -Q2) positive. - * - * This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This is - * correct for most cases but can still rotate around the long way sometimes. An implementation - * which did `lerp(lerp(Q1, Q2), Q3)` (with proper weighting), applying the dot product check - * between each step would work for those cases at the cost of being more complex to implement. - * - * Fortunately however, the 3DS hardware happens to also use this exact same logic to work around - * these issues, making this basic implementation actually more accurate to the hardware. - */ -static bool AreQuaternionsOpposite(Common::Vec4 qa, Common::Vec4 qb) { - Common::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()}; - Common::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()}; - - return (Common::Dot(a, b) < 0.f); -} - -void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) { - vertex_batch.emplace_back(v0, false); - vertex_batch.emplace_back(v1, AreQuaternionsOpposite(v0.quat, v1.quat)); - vertex_batch.emplace_back(v2, AreQuaternionsOpposite(v0.quat, v2.quat)); -} - -static constexpr std::array vs_attrib_types{ - GL_BYTE, // VertexAttributeFormat::BYTE - GL_UNSIGNED_BYTE, // VertexAttributeFormat::UBYTE - GL_SHORT, // VertexAttributeFormat::SHORT - GL_FLOAT // VertexAttributeFormat::FLOAT -}; - -struct VertexArrayInfo { - u32 vs_input_index_min; - u32 vs_input_index_max; - u32 vs_input_size; -}; - -RasterizerOpenGL::VertexArrayInfo RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) { - const auto& regs = Pica::g_state.regs; - const auto& vertex_attributes = regs.pipeline.vertex_attributes; - - u32 vertex_min; - u32 vertex_max; - if (is_indexed) { - const auto& index_info = regs.pipeline.index_array; - const PAddr address = vertex_attributes.GetPhysicalBaseAddress() + index_info.offset; - const u8* index_address_8 = VideoCore::g_memory->GetPhysicalPointer(address); - const u16* index_address_16 = reinterpret_cast(index_address_8); - const bool index_u16 = index_info.format != 0; - - vertex_min = 0xFFFF; - vertex_max = 0; - const u32 size = regs.pipeline.num_vertices * (index_u16 ? 2 : 1); - res_cache.FlushRegion(address, size, nullptr); - for (u32 index = 0; index < regs.pipeline.num_vertices; ++index) { - const u32 vertex = index_u16 ? index_address_16[index] : index_address_8[index]; - vertex_min = std::min(vertex_min, vertex); - vertex_max = std::max(vertex_max, vertex); - } - } else { - vertex_min = regs.pipeline.vertex_offset; - vertex_max = regs.pipeline.vertex_offset + regs.pipeline.num_vertices - 1; - } - - const u32 vertex_num = vertex_max - vertex_min + 1; - u32 vs_input_size = 0; - for (const auto& loader : vertex_attributes.attribute_loaders) { - if (loader.component_count != 0) { - vs_input_size += loader.byte_count * vertex_num; - } - } - - return {vertex_min, vertex_max, vs_input_size}; } void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset, GLuint vs_input_index_min, GLuint vs_input_index_max) { MICROPROFILE_SCOPE(OpenGL_VAO); - const auto& regs = Pica::g_state.regs; const auto& vertex_attributes = regs.pipeline.vertex_attributes; PAddr base_address = vertex_attributes.GetPhysicalBaseAddress(); @@ -325,8 +228,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset, u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index); GLint size = vertex_attributes.GetNumElements(attribute_index); - GLenum type = vs_attrib_types[static_cast( - vertex_attributes.GetFormat(attribute_index))]; + GLenum type = MakeAttributeType(vertex_attributes.GetFormat(attribute_index)); GLsizei stride = loader.byte_count; glVertexAttribPointer(input_reg, size, type, GL_FALSE, stride, reinterpret_cast(buffer_offset + offset)); @@ -384,7 +286,6 @@ bool RasterizerOpenGL::SetupVertexShader() { bool RasterizerOpenGL::SetupGeometryShader() { MICROPROFILE_SCOPE(OpenGL_GS); - const auto& regs = Pica::g_state.regs; if (regs.pipeline.use_gs != Pica::PipelineRegs::UseGS::No) { LOG_ERROR(Render_OpenGL, "Accelerate draw doesn't support geometry shader"); @@ -396,7 +297,6 @@ bool RasterizerOpenGL::SetupGeometryShader() { } bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { - const auto& regs = Pica::g_state.regs; if (regs.pipeline.use_gs != Pica::PipelineRegs::UseGS::No) { if (regs.pipeline.gs_config.mode != Pica::PipelineRegs::GSMode::Point) { return false; @@ -415,27 +315,8 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { return Draw(true, is_indexed); } -static GLenum GetCurrentPrimitiveMode() { - const auto& regs = Pica::g_state.regs; - switch (regs.pipeline.triangle_topology) { - case Pica::PipelineRegs::TriangleTopology::Shader: - case Pica::PipelineRegs::TriangleTopology::List: - return GL_TRIANGLES; - case Pica::PipelineRegs::TriangleTopology::Fan: - return GL_TRIANGLE_FAN; - case Pica::PipelineRegs::TriangleTopology::Strip: - return GL_TRIANGLE_STRIP; - default: - UNREACHABLE(); - } - - return GL_TRIANGLES; -} - bool RasterizerOpenGL::AccelerateDrawBatchInternal(bool is_indexed) { - const auto& regs = Pica::g_state.regs; - GLenum primitive_mode = GetCurrentPrimitiveMode(); - + const GLenum primitive_mode = MakePrimitiveMode(regs.pipeline.triangle_topology); auto [vs_input_index_min, vs_input_index_max, vs_input_size] = AnalyzeVertexArray(is_indexed); if (vs_input_size > VERTEX_BUFFER_SIZE) { @@ -489,7 +370,6 @@ void RasterizerOpenGL::DrawTriangles() { bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { MICROPROFILE_SCOPE(OpenGL_Drawing); - const auto& regs = Pica::g_state.regs; bool shadow_rendering = regs.framebuffer.output_merger.fragment_operation_mode == Pica::FramebufferRegs::FragmentOperationMode::Shadow; @@ -841,47 +721,24 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { return succeeded; } -void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { - const auto& regs = Pica::g_state.regs; - +void RasterizerOpenGL::NotifyFixedFunctionPicaRegisterChanged(u32 id) { switch (id) { - // Culling - case PICA_REG_INDEX(rasterizer.cull_mode): - SyncCullMode(); - break; - // Clipping plane case PICA_REG_INDEX(rasterizer.clip_enable): SyncClipEnabled(); break; - case PICA_REG_INDEX(rasterizer.clip_coef[0]): - case PICA_REG_INDEX(rasterizer.clip_coef[1]): - case PICA_REG_INDEX(rasterizer.clip_coef[2]): - case PICA_REG_INDEX(rasterizer.clip_coef[3]): - SyncClipCoef(); - break; - - // Depth modifiers - case PICA_REG_INDEX(rasterizer.viewport_depth_range): - SyncDepthScale(); - break; - case PICA_REG_INDEX(rasterizer.viewport_depth_near_plane): - SyncDepthOffset(); - break; - - // Depth buffering - case PICA_REG_INDEX(rasterizer.depthmap_enable): - shader_dirty = true; + // Culling + case PICA_REG_INDEX(rasterizer.cull_mode): + SyncCullMode(); break; // Blending case PICA_REG_INDEX(framebuffer.output_merger.alphablend_enable): - if (GLES) { - // With GLES, we need this in the fragment shader to emulate logic operations - shader_dirty = true; - } SyncBlendEnabled(); + // Update since logic op emulation depends on alpha blend enable. + SyncLogicOp(); + SyncColorWriteMask(); break; case PICA_REG_INDEX(framebuffer.output_merger.alpha_blending): SyncBlendFuncs(); @@ -890,74 +747,6 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncBlendColor(); break; - // Shadow texture - case PICA_REG_INDEX(texturing.shadow): - SyncShadowTextureBias(); - break; - - // Fog state - case PICA_REG_INDEX(texturing.fog_color): - SyncFogColor(); - break; - case PICA_REG_INDEX(texturing.fog_lut_data[0]): - case PICA_REG_INDEX(texturing.fog_lut_data[1]): - case PICA_REG_INDEX(texturing.fog_lut_data[2]): - case PICA_REG_INDEX(texturing.fog_lut_data[3]): - case PICA_REG_INDEX(texturing.fog_lut_data[4]): - case PICA_REG_INDEX(texturing.fog_lut_data[5]): - case PICA_REG_INDEX(texturing.fog_lut_data[6]): - case PICA_REG_INDEX(texturing.fog_lut_data[7]): - uniform_block_data.fog_lut_dirty = true; - break; - - // ProcTex state - case PICA_REG_INDEX(texturing.proctex): - case PICA_REG_INDEX(texturing.proctex_lut): - case PICA_REG_INDEX(texturing.proctex_lut_offset): - SyncProcTexBias(); - shader_dirty = true; - break; - - case PICA_REG_INDEX(texturing.proctex_noise_u): - case PICA_REG_INDEX(texturing.proctex_noise_v): - case PICA_REG_INDEX(texturing.proctex_noise_frequency): - SyncProcTexNoise(); - break; - - case PICA_REG_INDEX(texturing.proctex_lut_data[0]): - case PICA_REG_INDEX(texturing.proctex_lut_data[1]): - case PICA_REG_INDEX(texturing.proctex_lut_data[2]): - case PICA_REG_INDEX(texturing.proctex_lut_data[3]): - case PICA_REG_INDEX(texturing.proctex_lut_data[4]): - case PICA_REG_INDEX(texturing.proctex_lut_data[5]): - case PICA_REG_INDEX(texturing.proctex_lut_data[6]): - case PICA_REG_INDEX(texturing.proctex_lut_data[7]): - using Pica::TexturingRegs; - switch (regs.texturing.proctex_lut_config.ref_table.Value()) { - case TexturingRegs::ProcTexLutTable::Noise: - uniform_block_data.proctex_noise_lut_dirty = true; - break; - case TexturingRegs::ProcTexLutTable::ColorMap: - uniform_block_data.proctex_color_map_dirty = true; - break; - case TexturingRegs::ProcTexLutTable::AlphaMap: - uniform_block_data.proctex_alpha_map_dirty = true; - break; - case TexturingRegs::ProcTexLutTable::Color: - uniform_block_data.proctex_lut_dirty = true; - break; - case TexturingRegs::ProcTexLutTable::ColorDiff: - uniform_block_data.proctex_diff_lut_dirty = true; - break; - } - break; - - // Alpha test - case PICA_REG_INDEX(framebuffer.output_merger.alpha_test): - SyncAlphaTest(); - shader_dirty = true; - break; - // Sync GL stencil test + stencil write mask // (Pica stencil test function register also contains a stencil write mask) case PICA_REG_INDEX(framebuffer.output_merger.stencil_test.raw_func): @@ -990,352 +779,12 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncColorWriteMask(); break; - case PICA_REG_INDEX(framebuffer.shadow): - SyncShadowBias(); - break; - - // Scissor test - case PICA_REG_INDEX(rasterizer.scissor_test.mode): - shader_dirty = true; - break; - // Logic op case PICA_REG_INDEX(framebuffer.output_merger.logic_op): - if (GLES) { - // With GLES, we need this in the fragment shader to emulate logic operations - shader_dirty = true; - } SyncLogicOp(); + // Update since color write mask is used to emulate no-op. + SyncColorWriteMask(); break; - - case PICA_REG_INDEX(texturing.main_config): - shader_dirty = true; - break; - - // Texture 0 type - case PICA_REG_INDEX(texturing.texture0.type): - shader_dirty = true; - break; - - // TEV stages - // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) - case PICA_REG_INDEX(texturing.tev_stage0.color_source1): - case PICA_REG_INDEX(texturing.tev_stage0.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage0.color_op): - case PICA_REG_INDEX(texturing.tev_stage0.color_scale): - case PICA_REG_INDEX(texturing.tev_stage1.color_source1): - case PICA_REG_INDEX(texturing.tev_stage1.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage1.color_op): - case PICA_REG_INDEX(texturing.tev_stage1.color_scale): - case PICA_REG_INDEX(texturing.tev_stage2.color_source1): - case PICA_REG_INDEX(texturing.tev_stage2.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage2.color_op): - case PICA_REG_INDEX(texturing.tev_stage2.color_scale): - case PICA_REG_INDEX(texturing.tev_stage3.color_source1): - case PICA_REG_INDEX(texturing.tev_stage3.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage3.color_op): - case PICA_REG_INDEX(texturing.tev_stage3.color_scale): - case PICA_REG_INDEX(texturing.tev_stage4.color_source1): - case PICA_REG_INDEX(texturing.tev_stage4.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage4.color_op): - case PICA_REG_INDEX(texturing.tev_stage4.color_scale): - case PICA_REG_INDEX(texturing.tev_stage5.color_source1): - case PICA_REG_INDEX(texturing.tev_stage5.color_modifier1): - case PICA_REG_INDEX(texturing.tev_stage5.color_op): - case PICA_REG_INDEX(texturing.tev_stage5.color_scale): - case PICA_REG_INDEX(texturing.tev_combiner_buffer_input): - shader_dirty = true; - break; - case PICA_REG_INDEX(texturing.tev_stage0.const_r): - SyncTevConstColor(0, regs.texturing.tev_stage0); - break; - case PICA_REG_INDEX(texturing.tev_stage1.const_r): - SyncTevConstColor(1, regs.texturing.tev_stage1); - break; - case PICA_REG_INDEX(texturing.tev_stage2.const_r): - SyncTevConstColor(2, regs.texturing.tev_stage2); - break; - case PICA_REG_INDEX(texturing.tev_stage3.const_r): - SyncTevConstColor(3, regs.texturing.tev_stage3); - break; - case PICA_REG_INDEX(texturing.tev_stage4.const_r): - SyncTevConstColor(4, regs.texturing.tev_stage4); - break; - case PICA_REG_INDEX(texturing.tev_stage5.const_r): - SyncTevConstColor(5, regs.texturing.tev_stage5); - break; - - // TEV combiner buffer color - case PICA_REG_INDEX(texturing.tev_combiner_buffer_color): - SyncCombinerColor(); - break; - - // Fragment lighting switches - case PICA_REG_INDEX(lighting.disable): - case PICA_REG_INDEX(lighting.max_light_index): - case PICA_REG_INDEX(lighting.config0): - case PICA_REG_INDEX(lighting.config1): - case PICA_REG_INDEX(lighting.abs_lut_input): - case PICA_REG_INDEX(lighting.lut_input): - case PICA_REG_INDEX(lighting.lut_scale): - case PICA_REG_INDEX(lighting.light_enable): - break; - - // Fragment lighting specular 0 color - case PICA_REG_INDEX(lighting.light[0].specular_0): - SyncLightSpecular0(0); - break; - case PICA_REG_INDEX(lighting.light[1].specular_0): - SyncLightSpecular0(1); - break; - case PICA_REG_INDEX(lighting.light[2].specular_0): - SyncLightSpecular0(2); - break; - case PICA_REG_INDEX(lighting.light[3].specular_0): - SyncLightSpecular0(3); - break; - case PICA_REG_INDEX(lighting.light[4].specular_0): - SyncLightSpecular0(4); - break; - case PICA_REG_INDEX(lighting.light[5].specular_0): - SyncLightSpecular0(5); - break; - case PICA_REG_INDEX(lighting.light[6].specular_0): - SyncLightSpecular0(6); - break; - case PICA_REG_INDEX(lighting.light[7].specular_0): - SyncLightSpecular0(7); - break; - - // Fragment lighting specular 1 color - case PICA_REG_INDEX(lighting.light[0].specular_1): - SyncLightSpecular1(0); - break; - case PICA_REG_INDEX(lighting.light[1].specular_1): - SyncLightSpecular1(1); - break; - case PICA_REG_INDEX(lighting.light[2].specular_1): - SyncLightSpecular1(2); - break; - case PICA_REG_INDEX(lighting.light[3].specular_1): - SyncLightSpecular1(3); - break; - case PICA_REG_INDEX(lighting.light[4].specular_1): - SyncLightSpecular1(4); - break; - case PICA_REG_INDEX(lighting.light[5].specular_1): - SyncLightSpecular1(5); - break; - case PICA_REG_INDEX(lighting.light[6].specular_1): - SyncLightSpecular1(6); - break; - case PICA_REG_INDEX(lighting.light[7].specular_1): - SyncLightSpecular1(7); - break; - - // Fragment lighting diffuse color - case PICA_REG_INDEX(lighting.light[0].diffuse): - SyncLightDiffuse(0); - break; - case PICA_REG_INDEX(lighting.light[1].diffuse): - SyncLightDiffuse(1); - break; - case PICA_REG_INDEX(lighting.light[2].diffuse): - SyncLightDiffuse(2); - break; - case PICA_REG_INDEX(lighting.light[3].diffuse): - SyncLightDiffuse(3); - break; - case PICA_REG_INDEX(lighting.light[4].diffuse): - SyncLightDiffuse(4); - break; - case PICA_REG_INDEX(lighting.light[5].diffuse): - SyncLightDiffuse(5); - break; - case PICA_REG_INDEX(lighting.light[6].diffuse): - SyncLightDiffuse(6); - break; - case PICA_REG_INDEX(lighting.light[7].diffuse): - SyncLightDiffuse(7); - break; - - // Fragment lighting ambient color - case PICA_REG_INDEX(lighting.light[0].ambient): - SyncLightAmbient(0); - break; - case PICA_REG_INDEX(lighting.light[1].ambient): - SyncLightAmbient(1); - break; - case PICA_REG_INDEX(lighting.light[2].ambient): - SyncLightAmbient(2); - break; - case PICA_REG_INDEX(lighting.light[3].ambient): - SyncLightAmbient(3); - break; - case PICA_REG_INDEX(lighting.light[4].ambient): - SyncLightAmbient(4); - break; - case PICA_REG_INDEX(lighting.light[5].ambient): - SyncLightAmbient(5); - break; - case PICA_REG_INDEX(lighting.light[6].ambient): - SyncLightAmbient(6); - break; - case PICA_REG_INDEX(lighting.light[7].ambient): - SyncLightAmbient(7); - break; - - // Fragment lighting position - case PICA_REG_INDEX(lighting.light[0].x): - case PICA_REG_INDEX(lighting.light[0].z): - SyncLightPosition(0); - break; - case PICA_REG_INDEX(lighting.light[1].x): - case PICA_REG_INDEX(lighting.light[1].z): - SyncLightPosition(1); - break; - case PICA_REG_INDEX(lighting.light[2].x): - case PICA_REG_INDEX(lighting.light[2].z): - SyncLightPosition(2); - break; - case PICA_REG_INDEX(lighting.light[3].x): - case PICA_REG_INDEX(lighting.light[3].z): - SyncLightPosition(3); - break; - case PICA_REG_INDEX(lighting.light[4].x): - case PICA_REG_INDEX(lighting.light[4].z): - SyncLightPosition(4); - break; - case PICA_REG_INDEX(lighting.light[5].x): - case PICA_REG_INDEX(lighting.light[5].z): - SyncLightPosition(5); - break; - case PICA_REG_INDEX(lighting.light[6].x): - case PICA_REG_INDEX(lighting.light[6].z): - SyncLightPosition(6); - break; - case PICA_REG_INDEX(lighting.light[7].x): - case PICA_REG_INDEX(lighting.light[7].z): - SyncLightPosition(7); - break; - - // Fragment spot lighting direction - case PICA_REG_INDEX(lighting.light[0].spot_x): - case PICA_REG_INDEX(lighting.light[0].spot_z): - SyncLightSpotDirection(0); - break; - case PICA_REG_INDEX(lighting.light[1].spot_x): - case PICA_REG_INDEX(lighting.light[1].spot_z): - SyncLightSpotDirection(1); - break; - case PICA_REG_INDEX(lighting.light[2].spot_x): - case PICA_REG_INDEX(lighting.light[2].spot_z): - SyncLightSpotDirection(2); - break; - case PICA_REG_INDEX(lighting.light[3].spot_x): - case PICA_REG_INDEX(lighting.light[3].spot_z): - SyncLightSpotDirection(3); - break; - case PICA_REG_INDEX(lighting.light[4].spot_x): - case PICA_REG_INDEX(lighting.light[4].spot_z): - SyncLightSpotDirection(4); - break; - case PICA_REG_INDEX(lighting.light[5].spot_x): - case PICA_REG_INDEX(lighting.light[5].spot_z): - SyncLightSpotDirection(5); - break; - case PICA_REG_INDEX(lighting.light[6].spot_x): - case PICA_REG_INDEX(lighting.light[6].spot_z): - SyncLightSpotDirection(6); - break; - case PICA_REG_INDEX(lighting.light[7].spot_x): - case PICA_REG_INDEX(lighting.light[7].spot_z): - SyncLightSpotDirection(7); - break; - - // Fragment lighting light source config - case PICA_REG_INDEX(lighting.light[0].config): - case PICA_REG_INDEX(lighting.light[1].config): - case PICA_REG_INDEX(lighting.light[2].config): - case PICA_REG_INDEX(lighting.light[3].config): - case PICA_REG_INDEX(lighting.light[4].config): - case PICA_REG_INDEX(lighting.light[5].config): - case PICA_REG_INDEX(lighting.light[6].config): - case PICA_REG_INDEX(lighting.light[7].config): - shader_dirty = true; - break; - - // Fragment lighting distance attenuation bias - case PICA_REG_INDEX(lighting.light[0].dist_atten_bias): - SyncLightDistanceAttenuationBias(0); - break; - case PICA_REG_INDEX(lighting.light[1].dist_atten_bias): - SyncLightDistanceAttenuationBias(1); - break; - case PICA_REG_INDEX(lighting.light[2].dist_atten_bias): - SyncLightDistanceAttenuationBias(2); - break; - case PICA_REG_INDEX(lighting.light[3].dist_atten_bias): - SyncLightDistanceAttenuationBias(3); - break; - case PICA_REG_INDEX(lighting.light[4].dist_atten_bias): - SyncLightDistanceAttenuationBias(4); - break; - case PICA_REG_INDEX(lighting.light[5].dist_atten_bias): - SyncLightDistanceAttenuationBias(5); - break; - case PICA_REG_INDEX(lighting.light[6].dist_atten_bias): - SyncLightDistanceAttenuationBias(6); - break; - case PICA_REG_INDEX(lighting.light[7].dist_atten_bias): - SyncLightDistanceAttenuationBias(7); - break; - - // Fragment lighting distance attenuation scale - case PICA_REG_INDEX(lighting.light[0].dist_atten_scale): - SyncLightDistanceAttenuationScale(0); - break; - case PICA_REG_INDEX(lighting.light[1].dist_atten_scale): - SyncLightDistanceAttenuationScale(1); - break; - case PICA_REG_INDEX(lighting.light[2].dist_atten_scale): - SyncLightDistanceAttenuationScale(2); - break; - case PICA_REG_INDEX(lighting.light[3].dist_atten_scale): - SyncLightDistanceAttenuationScale(3); - break; - case PICA_REG_INDEX(lighting.light[4].dist_atten_scale): - SyncLightDistanceAttenuationScale(4); - break; - case PICA_REG_INDEX(lighting.light[5].dist_atten_scale): - SyncLightDistanceAttenuationScale(5); - break; - case PICA_REG_INDEX(lighting.light[6].dist_atten_scale): - SyncLightDistanceAttenuationScale(6); - break; - case PICA_REG_INDEX(lighting.light[7].dist_atten_scale): - SyncLightDistanceAttenuationScale(7); - break; - - // Fragment lighting global ambient color (emission + ambient * ambient) - case PICA_REG_INDEX(lighting.global_ambient): - SyncGlobalAmbient(); - break; - - // Fragment lighting lookup tables - case PICA_REG_INDEX(lighting.lut_data[0]): - case PICA_REG_INDEX(lighting.lut_data[1]): - case PICA_REG_INDEX(lighting.lut_data[2]): - case PICA_REG_INDEX(lighting.lut_data[3]): - case PICA_REG_INDEX(lighting.lut_data[4]): - case PICA_REG_INDEX(lighting.lut_data[5]): - case PICA_REG_INDEX(lighting.lut_data[6]): - case PICA_REG_INDEX(lighting.lut_data[7]): { - const auto& lut_config = regs.lighting.lut_config; - uniform_block_data.lighting_lut_dirty[lut_config.type] = true; - uniform_block_data.lighting_lut_dirty_any = true; - break; - } } } @@ -1630,19 +1079,7 @@ void RasterizerOpenGL::SyncClipEnabled() { state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0; } -void RasterizerOpenGL::SyncClipCoef() { - const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef(); - const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(), - raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()}; - if (new_clip_coef != uniform_block_data.data.clip_coef) { - uniform_block_data.data.clip_coef = new_clip_coef; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncCullMode() { - const auto& regs = Pica::g_state.regs; - switch (regs.rasterizer.cull_mode) { case Pica::RasterizerRegs::CullMode::KeepAll: state.cull.enabled = false; @@ -1666,30 +1103,11 @@ void RasterizerOpenGL::SyncCullMode() { } } -void RasterizerOpenGL::SyncDepthScale() { - float depth_scale = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); - if (depth_scale != uniform_block_data.data.depth_scale) { - uniform_block_data.data.depth_scale = depth_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncDepthOffset() { - float depth_offset = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); - if (depth_offset != uniform_block_data.data.depth_offset) { - uniform_block_data.data.depth_offset = depth_offset; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncBlendEnabled() { state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1); } void RasterizerOpenGL::SyncBlendFuncs() { - const auto& regs = Pica::g_state.regs; state.blend.rgb_equation = PicaToGL::BlendEquation(regs.framebuffer.output_merger.alpha_blending.blend_equation_rgb); state.blend.a_equation = @@ -1713,53 +1131,7 @@ void RasterizerOpenGL::SyncBlendColor() { state.blend.color.alpha = blend_color[3]; } -void RasterizerOpenGL::SyncFogColor() { - const auto& regs = Pica::g_state.regs; - uniform_block_data.data.fog_color = { - regs.texturing.fog_color.r.Value() / 255.0f, - regs.texturing.fog_color.g.Value() / 255.0f, - regs.texturing.fog_color.b.Value() / 255.0f, - }; - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncProcTexNoise() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_noise_f = { - Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(), - }; - uniform_block_data.data.proctex_noise_a = { - regs.proctex_noise_u.amplitude / 4095.0f, - regs.proctex_noise_v.amplitude / 4095.0f, - }; - uniform_block_data.data.proctex_noise_p = { - Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(), - }; - - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncProcTexBias() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_bias = - Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8)) - .ToFloat32(); - - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncAlphaTest() { - const auto& regs = Pica::g_state.regs; - if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { - uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncLogicOp() { - const auto& regs = Pica::g_state.regs; state.logic_op = PicaToGL::LogicOp(regs.framebuffer.output_merger.logic_op); if (GLES) { @@ -1774,7 +1146,6 @@ void RasterizerOpenGL::SyncLogicOp() { } void RasterizerOpenGL::SyncColorWriteMask() { - const auto& regs = Pica::g_state.regs; if (GLES) { if (!regs.framebuffer.output_merger.alphablend_enable) { if (regs.framebuffer.output_merger.logic_op == Pica::FramebufferRegs::LogicOp::NoOp) { @@ -1799,7 +1170,6 @@ void RasterizerOpenGL::SyncColorWriteMask() { } void RasterizerOpenGL::SyncStencilWriteMask() { - const auto& regs = Pica::g_state.regs; state.stencil.write_mask = (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0) ? static_cast(regs.framebuffer.output_merger.stencil_test.write_mask) @@ -1807,7 +1177,6 @@ void RasterizerOpenGL::SyncStencilWriteMask() { } void RasterizerOpenGL::SyncDepthWriteMask() { - const auto& regs = Pica::g_state.regs; state.depth.write_mask = (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0 && regs.framebuffer.output_merger.depth_write_enable) ? GL_TRUE @@ -1815,7 +1184,6 @@ void RasterizerOpenGL::SyncDepthWriteMask() { } void RasterizerOpenGL::SyncStencilTest() { - const auto& regs = Pica::g_state.regs; state.stencil.test_enabled = regs.framebuffer.output_merger.stencil_test.enable && regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; @@ -1832,7 +1200,6 @@ void RasterizerOpenGL::SyncStencilTest() { } void RasterizerOpenGL::SyncDepthTest() { - const auto& regs = Pica::g_state.regs; state.depth.test_enabled = regs.framebuffer.output_merger.depth_test_enable == 1 || regs.framebuffer.output_merger.depth_write_enable == 1; state.depth.test_func = @@ -1841,131 +1208,6 @@ void RasterizerOpenGL::SyncDepthTest() { : GL_ALWAYS; } -void RasterizerOpenGL::SyncCombinerColor() { - auto combiner_color = - PicaToGL::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); - if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { - uniform_block_data.data.tev_combiner_buffer_color = combiner_color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncTevConstColor(std::size_t stage_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage) { - const auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); - - if (const_color == uniform_block_data.data.const_color[stage_index]) { - return; - } - - uniform_block_data.data.const_color[stage_index] = const_color; - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncGlobalAmbient() { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.global_ambient); - if (color != uniform_block_data.data.lighting_global_ambient) { - uniform_block_data.data.lighting_global_ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpecular0(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0); - if (color != uniform_block_data.data.light_src[light_index].specular_0) { - uniform_block_data.data.light_src[light_index].specular_0 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpecular1(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1); - if (color != uniform_block_data.data.light_src[light_index].specular_1) { - uniform_block_data.data.light_src[light_index].specular_1 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDiffuse(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); - if (color != uniform_block_data.data.light_src[light_index].diffuse) { - uniform_block_data.data.light_src[light_index].diffuse = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightAmbient(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient); - if (color != uniform_block_data.data.light_src[light_index].ambient) { - uniform_block_data.data.light_src[light_index].ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightPosition(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - const Common::Vec3f position = {Pica::float16::FromRaw(light.x).ToFloat32(), - Pica::float16::FromRaw(light.y).ToFloat32(), - Pica::float16::FromRaw(light.z).ToFloat32()}; - - if (position != uniform_block_data.data.light_src[light_index].position) { - uniform_block_data.data.light_src[light_index].position = position; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpotDirection(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - const auto spot_direction = - Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f}; - - if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { - uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - float dist_atten_bias = Pica::float20::FromRaw(light.dist_atten_bias).ToFloat32(); - - if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { - uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - float dist_atten_scale = Pica::float20::FromRaw(light.dist_atten_scale).ToFloat32(); - - if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { - uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncShadowBias() { - const auto& shadow = Pica::g_state.regs.framebuffer.shadow; - GLfloat constant = Pica::float16::FromRaw(shadow.constant).ToFloat32(); - GLfloat linear = Pica::float16::FromRaw(shadow.linear).ToFloat32(); - - if (constant != uniform_block_data.data.shadow_bias_constant || - linear != uniform_block_data.data.shadow_bias_linear) { - uniform_block_data.data.shadow_bias_constant = constant; - uniform_block_data.data.shadow_bias_linear = linear; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncShadowTextureBias() { - GLint bias = Pica::g_state.regs.texturing.shadow.bias << 1; - if (bias != uniform_block_data.data.shadow_texture_bias) { - uniform_block_data.data.shadow_texture_bias = bias; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncAndUploadLUTsLF() { constexpr std::size_t max_size = sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler + @@ -2162,18 +1404,21 @@ void RasterizerOpenGL::UploadUniforms(bool accelerate_draw) { uniform_buffer.Map(uniform_size, uniform_buffer_alignment); if (sync_vs) { - VSUniformData vs_uniforms; + Pica::Shader::VSUniformData vs_uniforms; vs_uniforms.uniforms.SetFromRegs(Pica::g_state.regs.vs, Pica::g_state.vs); std::memcpy(uniforms + used_bytes, &vs_uniforms, sizeof(vs_uniforms)); - glBindBufferRange(GL_UNIFORM_BUFFER, static_cast(UniformBindings::VS), - uniform_buffer.GetHandle(), offset + used_bytes, sizeof(VSUniformData)); + glBindBufferRange(GL_UNIFORM_BUFFER, static_cast(Pica::Shader::UniformBindings::VS), + uniform_buffer.GetHandle(), offset + used_bytes, + sizeof(Pica::Shader::VSUniformData)); used_bytes += uniform_size_aligned_vs; } if (sync_fs || invalidate) { - std::memcpy(uniforms + used_bytes, &uniform_block_data.data, sizeof(UniformData)); - glBindBufferRange(GL_UNIFORM_BUFFER, static_cast(UniformBindings::Common), - uniform_buffer.GetHandle(), offset + used_bytes, sizeof(UniformData)); + std::memcpy(uniforms + used_bytes, &uniform_block_data.data, + sizeof(Pica::Shader::UniformData)); + glBindBufferRange( + GL_UNIFORM_BUFFER, static_cast(Pica::Shader::UniformBindings::Common), + uniform_buffer.GetHandle(), offset + used_bytes, sizeof(Pica::Shader::UniformData)); uniform_block_data.dirty = false; used_bytes += uniform_size_aligned_fs; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 98008ad99..6f44e5850 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -3,12 +3,11 @@ // Refer to the license.txt file included. #pragma once -#include "common/vector_math.h" + #include "core/hw/gpu.h" -#include "video_core/pica_types.h" +#include "video_core/rasterizer_accelerated.h" #include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/rasterizer_interface.h" -#include "video_core/regs_lighting.h" #include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_state.h" @@ -20,20 +19,20 @@ class EmuWindow; } namespace OpenGL { + +class Driver; class ShaderProgramManager; -class RasterizerOpenGL : public VideoCore::RasterizerInterface { +class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { public: - explicit RasterizerOpenGL(Frontend::EmuWindow& emu_window); + explicit RasterizerOpenGL(Memory::MemorySystem& memory, Frontend::EmuWindow& emu_window, + Driver& driver); ~RasterizerOpenGL() override; void LoadDiskResources(const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback) override; - void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) override; void DrawTriangles() override; - void NotifyPicaRegisterChanged(u32 id) override; void FlushAll() override; void FlushRegion(PAddr addr, u32 size) override; void InvalidateRegion(PAddr addr, u32 size) override; @@ -46,10 +45,10 @@ public: u32 pixel_stride, ScreenInfo& screen_info) override; bool AccelerateDrawBatch(bool is_indexed) override; - /// Syncs entire status to match PICA registers - void SyncEntireState() override; - private: + void SyncFixedState() override; + void NotifyFixedFunctionPicaRegisterChanged(u32 id) override; + struct SamplerInfo { using TextureConfig = Pica::TexturingRegs::TextureConfig; @@ -76,66 +75,15 @@ private: bool supress_mipmap_for_cube = false; }; - /// Structure that the hardware rendered vertices are composed of - struct HardwareVertex { - HardwareVertex() = default; - HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion) { - position[0] = v.pos.x.ToFloat32(); - position[1] = v.pos.y.ToFloat32(); - position[2] = v.pos.z.ToFloat32(); - position[3] = v.pos.w.ToFloat32(); - color[0] = v.color.x.ToFloat32(); - color[1] = v.color.y.ToFloat32(); - color[2] = v.color.z.ToFloat32(); - color[3] = v.color.w.ToFloat32(); - tex_coord0[0] = v.tc0.x.ToFloat32(); - tex_coord0[1] = v.tc0.y.ToFloat32(); - tex_coord1[0] = v.tc1.x.ToFloat32(); - tex_coord1[1] = v.tc1.y.ToFloat32(); - tex_coord2[0] = v.tc2.x.ToFloat32(); - tex_coord2[1] = v.tc2.y.ToFloat32(); - tex_coord0_w = v.tc0_w.ToFloat32(); - normquat[0] = v.quat.x.ToFloat32(); - normquat[1] = v.quat.y.ToFloat32(); - normquat[2] = v.quat.z.ToFloat32(); - normquat[3] = v.quat.w.ToFloat32(); - view[0] = v.view.x.ToFloat32(); - view[1] = v.view.y.ToFloat32(); - view[2] = v.view.z.ToFloat32(); - - if (flip_quaternion) { - normquat = -normquat; - } - } - - Common::Vec4f position; - Common::Vec4f color; - Common::Vec2f tex_coord0; - Common::Vec2f tex_coord1; - Common::Vec2f tex_coord2; - float tex_coord0_w; - Common::Vec4f normquat; - Common::Vec3f view; - }; - /// Syncs the clip enabled status to match the PICA register void SyncClipEnabled(); - /// Syncs the clip coefficients to match the PICA register - void SyncClipCoef(); - /// Sets the OpenGL shader in accordance with the current PICA register state void SetShader(); /// Syncs the cull mode to match the PICA register void SyncCullMode(); - /// Syncs the depth scale to match the PICA register - void SyncDepthScale(); - - /// Syncs the depth offset to match the PICA register - void SyncDepthOffset(); - /// Syncs the blend enabled status to match the PICA register void SyncBlendEnabled(); @@ -145,18 +93,6 @@ private: /// Syncs the blend color to match the PICA register void SyncBlendColor(); - /// Syncs the fog states to match the PICA register - void SyncFogColor(); - - /// Sync the procedural texture noise configuration to match the PICA register - void SyncProcTexNoise(); - - /// Sync the procedural texture bias configuration to match the PICA register - void SyncProcTexBias(); - - /// Syncs the alpha test states to match the PICA register - void SyncAlphaTest(); - /// Syncs the logic op states to match the PICA register void SyncLogicOp(); @@ -175,46 +111,6 @@ private: /// Syncs the depth test states to match the PICA register void SyncDepthTest(); - /// Syncs the TEV combiner color buffer to match the PICA register - void SyncCombinerColor(); - - /// Syncs the TEV constant color to match the PICA register - void SyncTevConstColor(std::size_t tev_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage); - - /// Syncs the lighting global ambient color to match the PICA register - void SyncGlobalAmbient(); - - /// Syncs the specified light's specular 0 color to match the PICA register - void SyncLightSpecular0(int light_index); - - /// Syncs the specified light's specular 1 color to match the PICA register - void SyncLightSpecular1(int light_index); - - /// Syncs the specified light's diffuse color to match the PICA register - void SyncLightDiffuse(int light_index); - - /// Syncs the specified light's ambient color to match the PICA register - void SyncLightAmbient(int light_index); - - /// Syncs the specified light's position to match the PICA register - void SyncLightPosition(int light_index); - - /// Syncs the specified spot light direcition to match the PICA register - void SyncLightSpotDirection(int light_index); - - /// Syncs the specified light's distance attenuation bias to match the PICA register - void SyncLightDistanceAttenuationBias(int light_index); - - /// Syncs the specified light's distance attenuation scale to match the PICA register - void SyncLightDistanceAttenuationScale(int light_index); - - /// Syncs the shadow rendering bias to match the PICA register - void SyncShadowBias(); - - /// Syncs the shadow texture bias to match the PICA register - void SyncShadowTextureBias(); - /// Syncs and uploads the lighting, fog and proctex LUTs void SyncAndUploadLUTs(); void SyncAndUploadLUTsLF(); @@ -228,15 +124,6 @@ private: /// Internal implementation for AccelerateDrawBatch bool AccelerateDrawBatchInternal(bool is_indexed); - struct VertexArrayInfo { - u32 vs_input_index_min; - u32 vs_input_index_max; - u32 vs_input_size; - }; - - /// Retrieve the range and the size of the input vertex - VertexArrayInfo AnalyzeVertexArray(bool is_indexed); - /// Setup vertex array for AccelerateDrawBatch void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset, GLuint vs_input_index_min, GLuint vs_input_index_max); @@ -247,38 +134,13 @@ private: /// Setup geometry shader for AccelerateDrawBatch bool SetupGeometryShader(); - bool is_amd; - +private: + Driver& driver; OpenGLState state; GLuint default_texture; - RasterizerCacheOpenGL res_cache; - - std::vector vertex_batch; - - bool shader_dirty = true; - - struct { - UniformData data; - std::array lighting_lut_dirty; - bool lighting_lut_dirty_any; - bool fog_lut_dirty; - bool proctex_noise_lut_dirty; - bool proctex_color_map_dirty; - bool proctex_alpha_map_dirty; - bool proctex_lut_dirty; - bool proctex_diff_lut_dirty; - bool dirty; - } uniform_block_data = {}; - std::unique_ptr shader_program_manager; - // They shall be big enough for about one frame. - static constexpr std::size_t VERTEX_BUFFER_SIZE = 16 * 1024 * 1024; - static constexpr std::size_t INDEX_BUFFER_SIZE = 1 * 1024 * 1024; - static constexpr std::size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024; - static constexpr std::size_t TEXTURE_BUFFER_SIZE = 1 * 1024 * 1024; - OGLVertexArray sw_vao; // VAO for software shader draw OGLVertexArray hw_vao; // VAO for hardware shader / accelerate draw std::array hw_vao_enabled_attributes{}; @@ -299,15 +161,6 @@ private: OGLTexture texture_buffer_lut_lf; OGLTexture texture_buffer_lut_rg; OGLTexture texture_buffer_lut_rgba; - - std::array, Pica::LightingRegs::NumLightingSampler> - lighting_lut_data{}; - std::array fog_lut_data{}; - std::array proctex_noise_lut_data{}; - std::array proctex_color_map_data{}; - std::array proctex_alpha_map_data{}; - std::array proctex_lut_data{}; - std::array proctex_diff_lut_data{}; }; } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index a5435e864..f70a1adea 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -12,6 +12,7 @@ #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_vars.h" +#include "video_core/shader/shader_uniforms.h" #include "video_core/video_core.h" using Pica::FramebufferRegs; @@ -23,53 +24,7 @@ using VSOutputAttributes = RasterizerRegs::VSOutputAttributes; namespace OpenGL { -constexpr std::string_view UniformBlockDef = R"( -#define NUM_TEV_STAGES 6 -#define NUM_LIGHTS 8 -#define NUM_LIGHTING_SAMPLERS 24 - -struct LightSrc { - vec3 specular_0; - vec3 specular_1; - vec3 diffuse; - vec3 ambient; - vec3 position; - vec3 spot_direction; - float dist_atten_bias; - float dist_atten_scale; -}; - -layout (std140) uniform shader_data { - int framebuffer_scale; - int alphatest_ref; - float depth_scale; - float depth_offset; - float shadow_bias_constant; - float shadow_bias_linear; - int scissor_x1; - int scissor_y1; - int scissor_x2; - int scissor_y2; - int fog_lut_offset; - int proctex_noise_lut_offset; - int proctex_color_map_offset; - int proctex_alpha_map_offset; - int proctex_lut_offset; - int proctex_diff_lut_offset; - float proctex_bias; - int shadow_texture_bias; - ivec4 lighting_lut_offset[NUM_LIGHTING_SAMPLERS / 4]; - vec3 fog_color; - vec2 proctex_noise_f; - vec2 proctex_noise_a; - vec2 proctex_noise_p; - vec3 lighting_global_ambient; - LightSrc light_src[NUM_LIGHTS]; - vec4 const_color[NUM_TEV_STAGES]; - vec4 tev_combiner_buffer_color; - vec4 clip_coef; -}; -)"; +const std::string UniformBlockDef = Pica::Shader::BuildShaderUniformDefinitions(); static std::string GetVertexInterfaceDeclaration(bool is_output, bool separable_shader) { std::string out; diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 9b8033b41..c3ad18b57 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -6,13 +6,13 @@ #include #include #include -#include -#include "core/frontend/scope_acquire_context.h" +#include +#include "video_core/renderer_opengl/gl_driver.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_shader_disk_cache.h" #include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_state.h" -#include "video_core/renderer_opengl/gl_vars.h" +#include "video_core/shader/shader_uniforms.h" #include "video_core/video_core.h" namespace OpenGL { @@ -85,7 +85,8 @@ static std::tuple BuildVSConfigFromRaw( return {PicaVSConfig{raw.GetRawShaderConfig().vs, setup}, setup}; } -static void SetShaderUniformBlockBinding(GLuint shader, const char* name, UniformBindings binding, +static void SetShaderUniformBlockBinding(GLuint shader, const char* name, + Pica::Shader::UniformBindings binding, std::size_t expected_size) { const GLuint ub_index = glGetUniformBlockIndex(shader, name); if (ub_index == GL_INVALID_INDEX) { @@ -100,9 +101,10 @@ static void SetShaderUniformBlockBinding(GLuint shader, const char* name, Unifor } static void SetShaderUniformBlockBindings(GLuint shader) { - SetShaderUniformBlockBinding(shader, "shader_data", UniformBindings::Common, - sizeof(UniformData)); - SetShaderUniformBlockBinding(shader, "vs_config", UniformBindings::VS, sizeof(VSUniformData)); + SetShaderUniformBlockBinding(shader, "shader_data", Pica::Shader::UniformBindings::Common, + sizeof(Pica::Shader::UniformData)); + SetShaderUniformBlockBinding(shader, "vs_config", Pica::Shader::UniformBindings::VS, + sizeof(Pica::Shader::VSUniformData)); } static void SetShaderSamplerBinding(GLuint shader, const char* name, @@ -148,21 +150,6 @@ static void SetShaderSamplerBindings(GLuint shader) { cur_state.Apply(); } -void PicaUniformsData::SetFromRegs(const Pica::ShaderRegs& regs, - const Pica::Shader::ShaderSetup& setup) { - std::transform(std::begin(setup.uniforms.b), std::end(setup.uniforms.b), std::begin(bools), - [](bool value) -> BoolAligned { return {value ? GL_TRUE : GL_FALSE}; }); - std::transform(std::begin(regs.int_uniforms), std::end(regs.int_uniforms), std::begin(i), - [](const auto& value) -> Common::Vec4u { - return {value.x.Value(), value.y.Value(), value.z.Value(), value.w.Value()}; - }); - std::transform(std::begin(setup.uniforms.f), std::end(setup.uniforms.f), std::begin(f), - [](const auto& value) -> Common::Vec4f { - return {value.x.ToFloat32(), value.y.ToFloat32(), value.z.ToFloat32(), - value.w.ToFloat32()}; - }); -} - /** * An object representing a shader program staging. It can be either a shader object or a program * object, depending on whether separable program is used. @@ -178,12 +165,12 @@ public: } void Create(const char* source, GLenum type) { - if (shader_or_program.which() == 0) { - boost::get(shader_or_program).Create(source, type); + if (shader_or_program.index() == 0) { + std::get(shader_or_program).Create(source, type); } else { OGLShader shader; shader.Create(source, type); - OGLProgram& program = boost::get(shader_or_program); + OGLProgram& program = std::get(shader_or_program); program.Create(true, {shader.handle}); SetShaderUniformBlockBindings(program.handle); @@ -194,10 +181,10 @@ public: } GLuint GetHandle() const { - if (shader_or_program.which() == 0) { - return boost::get(shader_or_program).handle; + if (shader_or_program.index() == 0) { + return std::get(shader_or_program).handle; } else { - return boost::get(shader_or_program).handle; + return std::get(shader_or_program).handle; } } @@ -208,7 +195,7 @@ public: } private: - boost::variant shader_or_program; + std::variant shader_or_program; }; class TrivialVertexShader { @@ -329,8 +316,8 @@ using FragmentShaders = ShaderCache(separable, is_amd)), emu_window{emu_window_} {} +ShaderProgramManager::ShaderProgramManager(Frontend::EmuWindow& emu_window_, const Driver& driver_, + bool separable) + : impl(std::make_unique(separable)), emu_window{emu_window_}, driver{driver_} {} ShaderProgramManager::~ShaderProgramManager() = default; @@ -443,10 +429,7 @@ void ShaderProgramManager::UseFragmentShader(const Pica::Regs& regs) { void ShaderProgramManager::ApplyTo(OpenGLState& state) { if (impl->separable) { - if (impl->is_amd) { - // Without this reseting, AMD sometimes freezes when one stage is changed but not - // for the others. On the other hand, including this reset seems to introduce memory - // leak in Intel Graphics. + if (driver.HasBug(DriverBug::ShaderStageChangeFreeze)) { glUseProgramStages( impl->pipeline.handle, GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, 0); @@ -641,7 +624,7 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, std::size_t built_shaders = 0; // It doesn't have be atomic since it's used behind a mutex const auto LoadRawSepareble = [&](Frontend::GraphicsContext* context, std::size_t begin, std::size_t end) { - Frontend::ScopeAcquireContext scope(*context); + const auto scope = context->Acquire(); for (std::size_t i = begin; i < end; ++i) { if (stop_loading || compilation_failed) { return; diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 66883e7e6..561046aa7 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -5,13 +5,7 @@ #pragma once #include -#include "common/vector_math.h" #include "video_core/rasterizer_interface.h" -#include "video_core/regs_lighting.h" - -namespace Core { -class System; -} namespace Frontend { class EmuWindow; @@ -19,8 +13,7 @@ class EmuWindow; namespace Pica { struct Regs; -struct ShaderRegs; -} // namespace Pica +} namespace Pica::Shader { struct ShaderSetup; @@ -28,87 +21,13 @@ struct ShaderSetup; namespace OpenGL { -enum class UniformBindings : u32 { Common, VS, GS }; - -struct LightSrc { - alignas(16) Common::Vec3f specular_0; - alignas(16) Common::Vec3f specular_1; - alignas(16) Common::Vec3f diffuse; - alignas(16) Common::Vec3f ambient; - alignas(16) Common::Vec3f position; - alignas(16) Common::Vec3f spot_direction; // negated - float dist_atten_bias; - float dist_atten_scale; -}; - -/// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned -// NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at -// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. -// Not following that rule will cause problems on some AMD drivers. -struct UniformData { - int framebuffer_scale; - int alphatest_ref; - float depth_scale; - float depth_offset; - float shadow_bias_constant; - float shadow_bias_linear; - int scissor_x1; - int scissor_y1; - int scissor_x2; - int scissor_y2; - int fog_lut_offset; - int proctex_noise_lut_offset; - int proctex_color_map_offset; - int proctex_alpha_map_offset; - int proctex_lut_offset; - int proctex_diff_lut_offset; - float proctex_bias; - int shadow_texture_bias; - alignas(16) Common::Vec4i lighting_lut_offset[Pica::LightingRegs::NumLightingSampler / 4]; - alignas(16) Common::Vec3f fog_color; - alignas(8) Common::Vec2f proctex_noise_f; - alignas(8) Common::Vec2f proctex_noise_a; - alignas(8) Common::Vec2f proctex_noise_p; - alignas(16) Common::Vec3f lighting_global_ambient; - LightSrc light_src[8]; - alignas(16) Common::Vec4f const_color[6]; // A vec4 color for each of the six tev stages - alignas(16) Common::Vec4f tev_combiner_buffer_color; - alignas(16) Common::Vec4f clip_coef; -}; - -static_assert(sizeof(UniformData) == 0x4F0, - "The size of the UniformData does not match the structure in the shader"); -static_assert(sizeof(UniformData) < 16384, - "UniformData structure must be less than 16kb as per the OpenGL spec"); - -/// Uniform struct for the Uniform Buffer Object that contains PICA vertex/geometry shader uniforms. -// NOTE: the same rule from UniformData also applies here. -struct PicaUniformsData { - void SetFromRegs(const Pica::ShaderRegs& regs, const Pica::Shader::ShaderSetup& setup); - - struct BoolAligned { - alignas(16) int b; - }; - - std::array bools; - alignas(16) std::array i; - alignas(16) std::array f; -}; - -struct VSUniformData { - PicaUniformsData uniforms; -}; -static_assert(sizeof(VSUniformData) == 1856, - "The size of the VSUniformData does not match the structure in the shader"); -static_assert(sizeof(VSUniformData) < 16384, - "VSUniformData structure must be less than 16kb as per the OpenGL spec"); - +class Driver; class OpenGLState; /// A class that manage different shader stages and configures them with given config data. class ShaderProgramManager { public: - ShaderProgramManager(Frontend::EmuWindow& emu_window_, bool separable, bool is_amd); + ShaderProgramManager(Frontend::EmuWindow& emu_window, const Driver& driver, bool separable); ~ShaderProgramManager(); void LoadDiskCache(const std::atomic_bool& stop_loading, @@ -131,5 +50,6 @@ private: std::unique_ptr impl; Frontend::EmuWindow& emu_window; + const Driver& driver; }; } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp index 1ff5ba62d..804b462e7 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp +++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp @@ -5,6 +5,7 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/microprofile.h" +#include "video_core/renderer_opengl/gl_driver.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning", @@ -12,19 +13,14 @@ MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning", namespace OpenGL { -OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool array_buffer_for_amd, +OGLStreamBuffer::OGLStreamBuffer(Driver& driver, GLenum target, GLsizeiptr size, bool prefer_coherent) : gl_target(target), buffer_size(size) { gl_buffer.Create(); glBindBuffer(gl_target, gl_buffer.handle); GLsizeiptr allocate_size = size; - if (array_buffer_for_amd) { - // On AMD GPU there is a strange crash in indexed drawing. The crash happens when the buffer - // read position is near the end and is an out-of-bound access to the vertex buffer. This is - // probably a bug in the driver and is related to the usage of vec3 attributes in the - // vertex array. Doubling the allocation size for the vertex buffer seems to avoid the - // crash. + if (driver.HasBug(DriverBug::VertexArrayOutOfBound) && target == GL_ARRAY_BUFFER) { allocate_size *= 2; } diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_stream_buffer.h index 1a2853198..78f724ab7 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.h +++ b/src/video_core/renderer_opengl/gl_stream_buffer.h @@ -3,14 +3,17 @@ // Refer to the license.txt file included. #pragma once + #include #include "video_core/renderer_opengl/gl_resource_manager.h" namespace OpenGL { +class Driver; + class OGLStreamBuffer : private NonCopyable { public: - explicit OGLStreamBuffer(GLenum target, GLsizeiptr size, bool array_buffer_for_amd, + explicit OGLStreamBuffer(Driver& driver, GLenum target, GLsizeiptr size, bool prefer_coherent = false); ~OGLStreamBuffer(); diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 730194be8..cd1c20a98 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -13,8 +13,6 @@ #include "core/hw/hw.h" #include "core/hw/lcd.h" #include "core/memory.h" -#include "core/tracer/recorder.h" -#include "video_core/debug_utils/debug_utils.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_state.h" @@ -352,14 +350,17 @@ static std::array MakeOrthographicMatrix(const float width, cons return matrix; } -RendererOpenGL::RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window) - : RendererBase{window, secondary_window}, - frame_dumper(Core::System::GetInstance().VideoDumper(), window) { +RendererOpenGL::RendererOpenGL(Core::System& system, Frontend::EmuWindow& window, + Frontend::EmuWindow* secondary_window) + : VideoCore::RendererBase{system, window, secondary_window}, driver{system.TelemetrySession()}, + frame_dumper{system.VideoDumper(), window} { window.mailbox = std::make_unique(); if (secondary_window) { secondary_window->mailbox = std::make_unique(); } frame_dumper.mailbox = std::make_unique(); + InitOpenGLObjects(); + rasterizer = std::make_unique(system.Memory(), render_window, driver); } RendererOpenGL::~RendererOpenGL() = default; @@ -374,7 +375,6 @@ void RendererOpenGL::SwapBuffers() { state.Apply(); PrepareRendertarget(); - RenderScreenshot(); const auto& main_layout = render_window.GetFramebufferLayout(); @@ -396,26 +396,12 @@ void RendererOpenGL::SwapBuffers() { } } - m_current_frame++; - - Core::System::GetInstance().perf_stats->EndSystemFrame(); - - render_window.PollEvents(); - - Core::System::GetInstance().frame_limiter.DoFrameLimiting( - Core::System::GetInstance().CoreTiming().GetGlobalTimeUs()); - Core::System::GetInstance().perf_stats->BeginSystemFrame(); - + EndFrame(); prev_state.Apply(); - RefreshRasterizerSetting(); - - if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->FrameFinished(); - } } void RendererOpenGL::RenderScreenshot() { - if (VideoCore::g_renderer_screenshot_requested) { + if (renderer_settings.screenshot_requested.exchange(false)) { // Draw this frame to the screenshot framebuffer screenshot_framebuffer.Create(); GLuint old_read_fb = state.draw.read_framebuffer; @@ -423,7 +409,7 @@ void RendererOpenGL::RenderScreenshot() { state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle; state.Apply(); - Layout::FramebufferLayout layout{VideoCore::g_screenshot_framebuffer_layout}; + const auto layout{renderer_settings.screenshot_framebuffer_layout}; GLuint renderbuffer; glGenRenderbuffers(1, &renderbuffer); @@ -435,7 +421,7 @@ void RendererOpenGL::RenderScreenshot() { DrawScreens(layout, false); glReadPixels(0, 0, layout.width, layout.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - VideoCore::g_screenshot_bits); + renderer_settings.screenshot_bits); screenshot_framebuffer.Release(); state.draw.read_framebuffer = old_read_fb; @@ -443,8 +429,7 @@ void RendererOpenGL::RenderScreenshot() { state.Apply(); glDeleteRenderbuffers(1, &renderbuffer); - VideoCore::g_screenshot_complete_callback(); - VideoCore::g_renderer_screenshot_requested = false; + renderer_settings.screenshot_complete_callback(); } } @@ -1226,109 +1211,8 @@ void RendererOpenGL::CleanupVideoDumping() { mailbox->free_cv.notify_one(); } -static const char* GetSource(GLenum source) { -#define RET(s) \ - case GL_DEBUG_SOURCE_##s: \ - return #s - switch (source) { - RET(API); - RET(WINDOW_SYSTEM); - RET(SHADER_COMPILER); - RET(THIRD_PARTY); - RET(APPLICATION); - RET(OTHER); - default: - UNREACHABLE(); - } -#undef RET - - return ""; +void RendererOpenGL::Sync() { + rasterizer->SyncEntireState(); } -static const char* GetType(GLenum type) { -#define RET(t) \ - case GL_DEBUG_TYPE_##t: \ - return #t - switch (type) { - RET(ERROR); - RET(DEPRECATED_BEHAVIOR); - RET(UNDEFINED_BEHAVIOR); - RET(PORTABILITY); - RET(PERFORMANCE); - RET(OTHER); - RET(MARKER); - default: - UNREACHABLE(); - } -#undef RET - - return ""; -} - -static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar* message, const void* user_param) { - Log::Level level; - switch (severity) { - case GL_DEBUG_SEVERITY_HIGH: - level = Log::Level::Critical; - break; - case GL_DEBUG_SEVERITY_MEDIUM: - level = Log::Level::Warning; - break; - case GL_DEBUG_SEVERITY_NOTIFICATION: - case GL_DEBUG_SEVERITY_LOW: - level = Log::Level::Debug; - break; - } - LOG_GENERIC(Log::Class::Render_OpenGL, level, "{} {} {}: {}", GetSource(source), GetType(type), - id, message); -} - -/// Initialize the renderer -VideoCore::ResultStatus RendererOpenGL::Init() { -#ifndef ANDROID - if (!gladLoadGL()) { - return VideoCore::ResultStatus::ErrorBelowGL43; - } - - // Qualcomm has some spammy info messages that are marked as errors but not important - // https://developer.qualcomm.com/comment/11845 - if (GLAD_GL_KHR_debug) { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(DebugHandler, nullptr); - } -#endif - - const std::string_view gl_version{reinterpret_cast(glGetString(GL_VERSION))}; - const std::string_view gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; - const std::string_view gpu_model{reinterpret_cast(glGetString(GL_RENDERER))}; - - LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version); - LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); - LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); - - auto& telemetry_session = Core::System::GetInstance().TelemetrySession(); - constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; - telemetry_session.AddField(user_system, "GPU_Vendor", std::string(gpu_vendor)); - telemetry_session.AddField(user_system, "GPU_Model", std::string(gpu_model)); - telemetry_session.AddField(user_system, "GPU_OpenGL_Version", std::string(gl_version)); - - if (gpu_vendor == "GDI Generic") { - return VideoCore::ResultStatus::ErrorGenericDrivers; - } - - if (!(GLAD_GL_VERSION_4_3 || GLAD_GL_ES_VERSION_3_1)) { - return VideoCore::ResultStatus::ErrorBelowGL43; - } - - InitOpenGLObjects(); - - RefreshRasterizerSetting(); - - return VideoCore::ResultStatus::Success; -} - -/// Shutdown the renderer -void RendererOpenGL::ShutDown() {} - } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index c823730e9..f3beb3a35 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -8,6 +8,8 @@ #include "core/hw/gpu.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/frame_dumper_opengl.h" +#include "video_core/renderer_opengl/gl_driver.h" +#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" @@ -15,6 +17,10 @@ namespace Layout { struct FramebufferLayout; } +namespace Core { +class System; +} + namespace Frontend { struct Frame { @@ -48,35 +54,21 @@ struct ScreenInfo { TextureInfo texture; }; -struct PresentationTexture { - u32 width = 0; - u32 height = 0; - OGLTexture texture; -}; - -class RendererOpenGL : public RendererBase { +class RendererOpenGL : public VideoCore::RendererBase { public: - explicit RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window); + explicit RendererOpenGL(Core::System& system, Frontend::EmuWindow& window, + Frontend::EmuWindow* secondary_window); ~RendererOpenGL() override; - /// Initialize the renderer - VideoCore::ResultStatus Init() override; + [[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() const override { + return rasterizer.get(); + } - /// Shutdown the renderer - void ShutDown() override; - - /// Finalizes rendering the guest frame void SwapBuffers() override; - - /// Draws the latest frame from texture mailbox to the currently bound draw framebuffer in this - /// context void TryPresent(int timeout_ms, bool is_secondary) override; - - /// Prepares for video dumping (e.g. create necessary buffers, etc) void PrepareVideoDumping() override; - - /// Cleans up after video dumping is ended void CleanupVideoDumping() override; + void Sync() override; private: void InitOpenGLObjects(); @@ -111,7 +103,10 @@ private: // Fills active OpenGL texture with the given RGB color. void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture); +private: + Driver driver; OpenGLState state; + std::unique_ptr rasterizer; // OpenGL object IDs OGLVertexArray vertex_array; diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/renderer_software/rasterizer.cpp similarity index 99% rename from src/video_core/swrasterizer/rasterizer.cpp rename to src/video_core/renderer_software/rasterizer.cpp index c52523924..9e9fd40e7 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/renderer_software/rasterizer.cpp @@ -22,12 +22,12 @@ #include "video_core/regs_framebuffer.h" #include "video_core/regs_rasterizer.h" #include "video_core/regs_texturing.h" +#include "video_core/renderer_software/rasterizer.h" +#include "video_core/renderer_software/sw_framebuffer.h" +#include "video_core/renderer_software/sw_lighting.h" +#include "video_core/renderer_software/sw_proctex.h" +#include "video_core/renderer_software/sw_texturing.h" #include "video_core/shader/shader.h" -#include "video_core/swrasterizer/framebuffer.h" -#include "video_core/swrasterizer/lighting.h" -#include "video_core/swrasterizer/proctex.h" -#include "video_core/swrasterizer/rasterizer.h" -#include "video_core/swrasterizer/texturing.h" #include "video_core/texture/texture_decode.h" #include "video_core/utils.h" #include "video_core/video_core.h" diff --git a/src/video_core/swrasterizer/rasterizer.h b/src/video_core/renderer_software/rasterizer.h similarity index 100% rename from src/video_core/swrasterizer/rasterizer.h rename to src/video_core/renderer_software/rasterizer.h diff --git a/src/video_core/renderer_software/renderer_software.cpp b/src/video_core/renderer_software/renderer_software.cpp new file mode 100644 index 000000000..9f7bf37d3 --- /dev/null +++ b/src/video_core/renderer_software/renderer_software.cpp @@ -0,0 +1,19 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "video_core/renderer_software/renderer_software.h" + +namespace VideoCore { + +RendererSoftware::RendererSoftware(Core::System& system, Frontend::EmuWindow& window) + : VideoCore::RendererBase{system, window, nullptr}, + rasterizer{std::make_unique()} {} + +RendererSoftware::~RendererSoftware() = default; + +void RendererSoftware::SwapBuffers() { + EndFrame(); +} + +} // namespace VideoCore diff --git a/src/video_core/renderer_software/renderer_software.h b/src/video_core/renderer_software/renderer_software.h new file mode 100644 index 000000000..443f7c307 --- /dev/null +++ b/src/video_core/renderer_software/renderer_software.h @@ -0,0 +1,33 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "video_core/renderer_base.h" +#include "video_core/renderer_software/sw_rasterizer.h" + +namespace Core { +class System; +} + +namespace VideoCore { + +class RendererSoftware : public VideoCore::RendererBase { +public: + explicit RendererSoftware(Core::System& system, Frontend::EmuWindow& window); + ~RendererSoftware() override; + + [[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() const override { + return rasterizer.get(); + } + + void SwapBuffers() override; + void TryPresent(int timeout_ms, bool is_secondary) override {} + void Sync() override {} + +private: + std::unique_ptr rasterizer; +}; + +} // namespace VideoCore diff --git a/src/video_core/swrasterizer/clipper.cpp b/src/video_core/renderer_software/sw_clipper.cpp similarity index 98% rename from src/video_core/swrasterizer/clipper.cpp rename to src/video_core/renderer_software/sw_clipper.cpp index 4a6e00d53..b745353ce 100644 --- a/src/video_core/swrasterizer/clipper.cpp +++ b/src/video_core/renderer_software/sw_clipper.cpp @@ -12,9 +12,9 @@ #include "common/vector_math.h" #include "video_core/pica_state.h" #include "video_core/pica_types.h" +#include "video_core/renderer_software/rasterizer.h" +#include "video_core/renderer_software/sw_clipper.h" #include "video_core/shader/shader.h" -#include "video_core/swrasterizer/clipper.h" -#include "video_core/swrasterizer/rasterizer.h" using Pica::Rasterizer::Vertex; diff --git a/src/video_core/swrasterizer/clipper.h b/src/video_core/renderer_software/sw_clipper.h similarity index 100% rename from src/video_core/swrasterizer/clipper.h rename to src/video_core/renderer_software/sw_clipper.h diff --git a/src/video_core/swrasterizer/framebuffer.cpp b/src/video_core/renderer_software/sw_framebuffer.cpp similarity index 99% rename from src/video_core/swrasterizer/framebuffer.cpp rename to src/video_core/renderer_software/sw_framebuffer.cpp index c157fa496..b24fe0cad 100644 --- a/src/video_core/swrasterizer/framebuffer.cpp +++ b/src/video_core/renderer_software/sw_framebuffer.cpp @@ -12,7 +12,7 @@ #include "core/memory.h" #include "video_core/pica_state.h" #include "video_core/regs_framebuffer.h" -#include "video_core/swrasterizer/framebuffer.h" +#include "video_core/renderer_software/sw_framebuffer.h" #include "video_core/utils.h" #include "video_core/video_core.h" diff --git a/src/video_core/swrasterizer/framebuffer.h b/src/video_core/renderer_software/sw_framebuffer.h similarity index 100% rename from src/video_core/swrasterizer/framebuffer.h rename to src/video_core/renderer_software/sw_framebuffer.h diff --git a/src/video_core/swrasterizer/lighting.cpp b/src/video_core/renderer_software/sw_lighting.cpp similarity index 99% rename from src/video_core/swrasterizer/lighting.cpp rename to src/video_core/renderer_software/sw_lighting.cpp index 014eb25d2..83f966635 100644 --- a/src/video_core/swrasterizer/lighting.cpp +++ b/src/video_core/renderer_software/sw_lighting.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include -#include "video_core/swrasterizer/lighting.h" +#include "video_core/renderer_software/sw_lighting.h" namespace Pica { diff --git a/src/video_core/swrasterizer/lighting.h b/src/video_core/renderer_software/sw_lighting.h similarity index 100% rename from src/video_core/swrasterizer/lighting.h rename to src/video_core/renderer_software/sw_lighting.h diff --git a/src/video_core/swrasterizer/proctex.cpp b/src/video_core/renderer_software/sw_proctex.cpp similarity index 99% rename from src/video_core/swrasterizer/proctex.cpp rename to src/video_core/renderer_software/sw_proctex.cpp index dc0b1e5d8..a3a4a7993 100644 --- a/src/video_core/swrasterizer/proctex.cpp +++ b/src/video_core/renderer_software/sw_proctex.cpp @@ -5,7 +5,7 @@ #include #include #include "common/math_util.h" -#include "video_core/swrasterizer/proctex.h" +#include "video_core/renderer_software/sw_proctex.h" namespace Pica::Rasterizer { diff --git a/src/video_core/swrasterizer/proctex.h b/src/video_core/renderer_software/sw_proctex.h similarity index 100% rename from src/video_core/swrasterizer/proctex.h rename to src/video_core/renderer_software/sw_proctex.h diff --git a/src/video_core/renderer_software/sw_rasterizer.cpp b/src/video_core/renderer_software/sw_rasterizer.cpp new file mode 100644 index 000000000..cba79273c --- /dev/null +++ b/src/video_core/renderer_software/sw_rasterizer.cpp @@ -0,0 +1,16 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "video_core/renderer_software/sw_clipper.h" +#include "video_core/renderer_software/sw_rasterizer.h" + +namespace VideoCore { + +void RasterizerSoftware::AddTriangle(const Pica::Shader::OutputVertex& v0, + const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) { + Pica::Clipper::ProcessTriangle(v0, v1, v2); +} + +} // namespace VideoCore diff --git a/src/video_core/swrasterizer/swrasterizer.h b/src/video_core/renderer_software/sw_rasterizer.h similarity index 93% rename from src/video_core/swrasterizer/swrasterizer.h rename to src/video_core/renderer_software/sw_rasterizer.h index 9e7a140f1..26235df01 100644 --- a/src/video_core/swrasterizer/swrasterizer.h +++ b/src/video_core/renderer_software/sw_rasterizer.h @@ -13,7 +13,7 @@ struct OutputVertex; namespace VideoCore { -class SWRasterizer : public RasterizerInterface { +class RasterizerSoftware : public RasterizerInterface { void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, const Pica::Shader::OutputVertex& v2) override; void DrawTriangles() override {} diff --git a/src/video_core/swrasterizer/texturing.cpp b/src/video_core/renderer_software/sw_texturing.cpp similarity index 99% rename from src/video_core/swrasterizer/texturing.cpp rename to src/video_core/renderer_software/sw_texturing.cpp index ff8bc5e6e..799b7e5c2 100644 --- a/src/video_core/swrasterizer/texturing.cpp +++ b/src/video_core/renderer_software/sw_texturing.cpp @@ -7,7 +7,7 @@ #include "common/common_types.h" #include "common/vector_math.h" #include "video_core/regs_texturing.h" -#include "video_core/swrasterizer/texturing.h" +#include "video_core/renderer_software/sw_texturing.h" namespace Pica::Rasterizer { diff --git a/src/video_core/swrasterizer/texturing.h b/src/video_core/renderer_software/sw_texturing.h similarity index 100% rename from src/video_core/swrasterizer/texturing.h rename to src/video_core/renderer_software/sw_texturing.h diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index 2e6f5d436..b54597205 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp @@ -86,7 +86,7 @@ void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input } } -static void CopyRegistersToOutput(const Common::Vec4* regs, u32 mask, +static void CopyRegistersToOutput(std::span, 16> regs, u32 mask, AttributeBuffer& buffer) { int output_i = 0; for (int reg : Common::BitSet(mask)) { @@ -108,7 +108,7 @@ GSEmitter::~GSEmitter() { delete handlers; } -void GSEmitter::Emit(Common::Vec4 (&output_regs)[16]) { +void GSEmitter::Emit(std::span, 16> output_regs) { ASSERT(vertex_id < 3); // TODO: This should be merged with UnitState::WriteOutput somehow CopyRegistersToOutput(output_regs, output_mask, buffer[vertex_id]); diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 3dde933a1..dc98b7cab 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -113,7 +114,7 @@ struct GSEmitter { GSEmitter(); ~GSEmitter(); - void Emit(Common::Vec4 (&output_regs)[16]); + void Emit(std::span, 16> output_regs); private: friend class boost::serialization::access; @@ -140,9 +141,9 @@ struct UnitState { struct Registers { // The registers are accessed by the shader JIT using SSE instructions, and are therefore // required to be 16-byte aligned. - alignas(16) Common::Vec4 input[16]; - alignas(16) Common::Vec4 temporary[16]; - alignas(16) Common::Vec4 output[16]; + alignas(16) std::array, 16> input; + alignas(16) std::array, 16> temporary; + alignas(16) std::array, 16> output; private: friend class boost::serialization::access; diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index c931275e6..e09285016 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "common/assert.h" #include "common/common_types.h" @@ -688,7 +687,7 @@ DebugData InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, DebugData debug_data; // Setup input register table - boost::fill(state.registers.input, Common::Vec4::AssignToAll(float24::Zero())); + state.registers.input.fill(Common::Vec4::AssignToAll(float24::Zero())); state.LoadInput(config, input); RunInterpreter(setup, state, debug_data, setup.engine_data.entry_point); return debug_data; diff --git a/src/video_core/shader/shader_uniforms.cpp b/src/video_core/shader/shader_uniforms.cpp new file mode 100644 index 000000000..8247d697b --- /dev/null +++ b/src/video_core/shader/shader_uniforms.cpp @@ -0,0 +1,78 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "video_core/shader/shader.h" +#include "video_core/shader/shader_uniforms.h" + +namespace Pica::Shader { + +void PicaUniformsData::SetFromRegs(const Pica::ShaderRegs& regs, + const Pica::Shader::ShaderSetup& setup) { + std::transform(std::begin(setup.uniforms.b), std::end(setup.uniforms.b), std::begin(bools), + [](bool value) -> BoolAligned { return {value ? 1 : 0}; }); + std::transform(std::begin(regs.int_uniforms), std::end(regs.int_uniforms), std::begin(i), + [](const auto& value) -> Common::Vec4u { + return {value.x.Value(), value.y.Value(), value.z.Value(), value.w.Value()}; + }); + std::transform(std::begin(setup.uniforms.f), std::end(setup.uniforms.f), std::begin(f), + [](const auto& value) -> Common::Vec4f { + return {value.x.ToFloat32(), value.y.ToFloat32(), value.z.ToFloat32(), + value.w.ToFloat32()}; + }); +} + +constexpr std::string_view UniformBlockDefFormat = R"( +#define NUM_TEV_STAGES 6 +#define NUM_LIGHTS 8 +#define NUM_LIGHTING_SAMPLERS 24 +struct LightSrc {{ + vec3 specular_0; + vec3 specular_1; + vec3 diffuse; + vec3 ambient; + vec3 position; + vec3 spot_direction; + float dist_atten_bias; + float dist_atten_scale; +}}; +layout ({}std140) uniform shader_data {{ + int framebuffer_scale; + int alphatest_ref; + float depth_scale; + float depth_offset; + float shadow_bias_constant; + float shadow_bias_linear; + int scissor_x1; + int scissor_y1; + int scissor_x2; + int scissor_y2; + int fog_lut_offset; + int proctex_noise_lut_offset; + int proctex_color_map_offset; + int proctex_alpha_map_offset; + int proctex_lut_offset; + int proctex_diff_lut_offset; + float proctex_bias; + int shadow_texture_bias; + bool enable_clip1; + ivec4 lighting_lut_offset[NUM_LIGHTING_SAMPLERS / 4]; + vec3 fog_color; + vec2 proctex_noise_f; + vec2 proctex_noise_a; + vec2 proctex_noise_p; + vec3 lighting_global_ambient; + LightSrc light_src[NUM_LIGHTS]; + vec4 const_color[NUM_TEV_STAGES]; + vec4 tev_combiner_buffer_color; + vec3 tex_lod_bias; + vec4 clip_coef; +}}; +)"; + +std::string BuildShaderUniformDefinitions(const std::string& extra_layout_parameters) { + return fmt::format(UniformBlockDefFormat, extra_layout_parameters); +} + +} // namespace Pica::Shader diff --git a/src/video_core/shader/shader_uniforms.h b/src/video_core/shader/shader_uniforms.h new file mode 100644 index 000000000..1cc8e574f --- /dev/null +++ b/src/video_core/shader/shader_uniforms.h @@ -0,0 +1,101 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/vector_math.h" +#include "video_core/regs_lighting.h" + +namespace Pica { +struct ShaderRegs; +} + +namespace Pica::Shader { + +struct ShaderSetup; + +enum class UniformBindings : u32 { Common, VS, GS }; + +struct LightSrc { + alignas(16) Common::Vec3f specular_0; + alignas(16) Common::Vec3f specular_1; + alignas(16) Common::Vec3f diffuse; + alignas(16) Common::Vec3f ambient; + alignas(16) Common::Vec3f position; + alignas(16) Common::Vec3f spot_direction; // negated + float dist_atten_bias; + float dist_atten_scale; +}; + +/** + * Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned + * NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at + * the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. + * Not following that rule will cause problems on some AMD drivers. + */ +struct UniformData { + int framebuffer_scale; + int alphatest_ref; + float depth_scale; + float depth_offset; + float shadow_bias_constant; + float shadow_bias_linear; + int scissor_x1; + int scissor_y1; + int scissor_x2; + int scissor_y2; + int fog_lut_offset; + int proctex_noise_lut_offset; + int proctex_color_map_offset; + int proctex_alpha_map_offset; + int proctex_lut_offset; + int proctex_diff_lut_offset; + float proctex_bias; + int shadow_texture_bias; + alignas(4) bool enable_clip1; + alignas(16) Common::Vec4i lighting_lut_offset[LightingRegs::NumLightingSampler / 4]; + alignas(16) Common::Vec3f fog_color; + alignas(8) Common::Vec2f proctex_noise_f; + alignas(8) Common::Vec2f proctex_noise_a; + alignas(8) Common::Vec2f proctex_noise_p; + alignas(16) Common::Vec3f lighting_global_ambient; + LightSrc light_src[8]; + alignas(16) Common::Vec4f const_color[6]; // A vec4 color for each of the six tev stages + alignas(16) Common::Vec4f tev_combiner_buffer_color; + alignas(16) Common::Vec3f tex_lod_bias; + alignas(16) Common::Vec4f clip_coef; +}; + +static_assert(sizeof(UniformData) == 0x500, + "The size of the UniformData does not match the structure in the shader"); +static_assert(sizeof(UniformData) < 16384, + "UniformData structure must be less than 16kb as per the OpenGL spec"); + +/** + * Uniform struct for the Uniform Buffer Object that contains PICA vertex/geometry shader uniforms. + * NOTE: the same rule from UniformData also applies here. + */ +struct PicaUniformsData { + void SetFromRegs(const ShaderRegs& regs, const ShaderSetup& setup); + + struct BoolAligned { + alignas(16) int b; + }; + + std::array bools; + alignas(16) std::array i; + alignas(16) std::array f; +}; + +struct VSUniformData { + PicaUniformsData uniforms; +}; +static_assert(sizeof(VSUniformData) == 1856, + "The size of the VSUniformData does not match the structure in the shader"); +static_assert(sizeof(VSUniformData) < 16384, + "VSUniformData structure must be less than 16kb as per the OpenGL spec"); + +std::string BuildShaderUniformDefinitions(const std::string& extra_layout_parameters = ""); + +} // namespace Pica::Shader diff --git a/src/video_core/swrasterizer/swrasterizer.cpp b/src/video_core/swrasterizer/swrasterizer.cpp deleted file mode 100644 index cda5d52da..000000000 --- a/src/video_core/swrasterizer/swrasterizer.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "video_core/swrasterizer/clipper.h" -#include "video_core/swrasterizer/swrasterizer.h" - -namespace VideoCore { - -void SWRasterizer::AddTriangle(const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) { - Pica::Clipper::ProcessTriangle(v0, v1, v2); -} - -} // namespace VideoCore diff --git a/src/video_core/vertex_loader.cpp b/src/video_core/vertex_loader.cpp index 64848ebaf..1e9aa4d8e 100644 --- a/src/video_core/vertex_loader.cpp +++ b/src/video_core/vertex_loader.cpp @@ -1,5 +1,4 @@ #include -#include #include "common/alignment.h" #include "common/assert.h" #include "common/bit_field.h" @@ -23,7 +22,7 @@ void VertexLoader::Setup(const PipelineRegs& regs) { const auto& attribute_config = regs.vertex_attributes; num_total_attributes = attribute_config.GetNumTotalAttributes(); - boost::fill(vertex_attribute_sources, 0xdeadbeef); + vertex_attribute_sources.fill(0xdeadbeef); for (int i = 0; i < 16; i++) { vertex_attribute_is_default[i] = attribute_config.IsDefaultAttribute(i); diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index fdf7bcc3e..9b2caac22 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -6,11 +6,13 @@ #include "common/archives.h" #include "common/logging/log.h" #include "common/settings.h" +#include "core/core.h" #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/renderer_opengl.h" +#include "video_core/renderer_software/renderer_software.h" #include "video_core/video_core.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -18,9 +20,8 @@ namespace VideoCore { -std::unique_ptr g_renderer; ///< Renderer plugin +std::unique_ptr g_renderer{}; ///< Renderer plugin -std::atomic g_hw_renderer_enabled; std::atomic g_shader_jit_enabled; std::atomic g_hw_shader_enabled; std::atomic g_separable_shader_enabled; @@ -30,65 +31,49 @@ std::atomic g_renderer_bg_color_update_requested; std::atomic g_renderer_sampler_update_requested; std::atomic g_renderer_shader_update_requested; std::atomic g_texture_filter_update_requested; -// Screenshot -std::atomic g_renderer_screenshot_requested; -void* g_screenshot_bits; -std::function g_screenshot_complete_callback; -Layout::FramebufferLayout g_screenshot_framebuffer_layout; Memory::MemorySystem* g_memory; /// Initialize the video core -ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window, - Memory::MemorySystem& memory) { - g_memory = &memory; +void Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window, + Core::System& system) { + g_memory = &system.Memory(); Pica::Init(); + const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api.GetValue(); OpenGL::GLES = Settings::values.use_gles.GetValue(); - g_renderer = std::make_unique(emu_window, secondary_window); - ResultStatus result = g_renderer->Init(); - - if (result != ResultStatus::Success) { - LOG_ERROR(Render, "initialization failed !"); - } else { - LOG_DEBUG(Render, "initialized OK"); + switch (graphics_api) { + case Settings::GraphicsAPI::Software: + g_renderer = std::make_unique(system, emu_window); + break; + case Settings::GraphicsAPI::OpenGL: + g_renderer = std::make_unique(system, emu_window, secondary_window); + break; + default: + LOG_CRITICAL(Render, "Unknown graphics API {}, using OpenGL", graphics_api); + g_renderer = std::make_unique(system, emu_window, secondary_window); } - - return result; } /// Shutdown the video core void Shutdown() { Pica::Shutdown(); - - g_renderer->ShutDown(); g_renderer.reset(); LOG_DEBUG(Render, "shutdown OK"); } -void RequestScreenshot(void* data, std::function callback, - const Layout::FramebufferLayout& layout) { - if (g_renderer_screenshot_requested) { - LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request"); - return; - } - g_screenshot_bits = data; - g_screenshot_complete_callback = std::move(callback); - g_screenshot_framebuffer_layout = layout; - g_renderer_screenshot_requested = true; -} - u16 GetResolutionScaleFactor() { - if (g_hw_renderer_enabled) { - return Settings::values.resolution_factor.GetValue() - ? Settings::values.resolution_factor.GetValue() - : g_renderer->GetRenderWindow().GetFramebufferLayout().GetScalingRatio(); - } else { + const auto graphics_api = Settings::values.graphics_api.GetValue(); + if (graphics_api == Settings::GraphicsAPI::Software) { // Software renderer always render at native resolution return 1; } + + return Settings::values.resolution_factor.GetValue() + ? Settings::values.resolution_factor.GetValue() + : g_renderer->GetRenderWindow().GetFramebufferLayout().GetScalingRatio(); } template diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 5e0fc3bb5..c91e241f4 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -14,7 +14,9 @@ namespace Frontend { class EmuWindow; } -class RendererBase; +namespace Core { +class System; +} namespace Memory { class MemorySystem; @@ -25,11 +27,12 @@ class MemorySystem; namespace VideoCore { +class RendererBase; + extern std::unique_ptr g_renderer; ///< Renderer plugin // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from // qt ui) -extern std::atomic g_hw_renderer_enabled; extern std::atomic g_shader_jit_enabled; extern std::atomic g_hw_shader_enabled; extern std::atomic g_separable_shader_enabled; @@ -39,31 +42,16 @@ extern std::atomic g_renderer_bg_color_update_requested; extern std::atomic g_renderer_sampler_update_requested; extern std::atomic g_renderer_shader_update_requested; extern std::atomic g_texture_filter_update_requested; -// Screenshot -extern std::atomic g_renderer_screenshot_requested; -extern void* g_screenshot_bits; -extern std::function g_screenshot_complete_callback; -extern Layout::FramebufferLayout g_screenshot_framebuffer_layout; extern Memory::MemorySystem* g_memory; -enum class ResultStatus { - Success, - ErrorGenericDrivers, - ErrorBelowGL43, -}; - /// Initialize the video core -ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window, - Memory::MemorySystem& memory); +void Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window, + Core::System& system); /// Shutdown the video core void Shutdown(); -/// Request a screenshot of the next frame -void RequestScreenshot(void* data, std::function callback, - const Layout::FramebufferLayout& layout); - u16 GetResolutionScaleFactor(); template