diff options
210 files changed, 8026 insertions, 5510 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3639b623c..59c610732 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -# CMake 3.6 required for FindBoost to define IMPORTED libs properly on unknown Boost versions -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.7) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") include(DownloadExternals) @@ -66,10 +66,12 @@ if (NOT ENABLE_GENERIC) detect_architecture("_M_AMD64" x86_64) detect_architecture("_M_IX86" x86) detect_architecture("_M_ARM" ARM) + detect_architecture("_M_ARM64" ARM64) else() detect_architecture("__x86_64__" x86_64) detect_architecture("__i386__" x86) detect_architecture("__arm__" ARM) + detect_architecture("__aarch64__" ARM64) endif() endif() @@ -187,8 +189,8 @@ find_package(Threads REQUIRED) if (ENABLE_SDL2) if (YUZU_USE_BUNDLED_SDL2) # Detect toolchain and platform - if (MSVC14 AND ARCHITECTURE_x86_64) - set(SDL2_VER "SDL2-2.0.5") + if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) AND ARCHITECTURE_x86_64) + set(SDL2_VER "SDL2-2.0.8") else() message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.") endif() @@ -220,7 +222,7 @@ if (YUZU_USE_BUNDLED_UNICORN) if (MSVC) message(STATUS "unicorn not found, falling back to bundled") # Detect toolchain and platform - if (MSVC14 AND ARCHITECTURE_x86_64) + if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) AND ARCHITECTURE_x86_64) set(UNICORN_VER "unicorn-yuzu") else() message(FATAL_ERROR "No bundled Unicorn binaries for your toolchain. Disable YUZU_USE_BUNDLED_UNICORN and provide your own.") @@ -279,7 +281,7 @@ endif() if (ENABLE_QT) if (YUZU_USE_BUNDLED_QT) - if (MSVC14 AND ARCHITECTURE_x86_64) + if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) AND ARCHITECTURE_x86_64) set(QT_VER qt-5.10.0-msvc2015_64) else() message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.") @@ -303,7 +305,7 @@ endif() # ====================================== IF (APPLE) - FIND_LIBRARY(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related + find_library(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) if (CMAKE_CXX_COMPILER_ID STREQUAL Clang) diff --git a/CMakeModules/CopyYuzuQt5Deps.cmake b/CMakeModules/CopyYuzuQt5Deps.cmake index e4a9796c8..aaf80b77b 100644 --- a/CMakeModules/CopyYuzuQt5Deps.cmake +++ b/CMakeModules/CopyYuzuQt5Deps.cmake @@ -4,8 +4,10 @@ function(copy_yuzu_Qt5_deps target_dir) set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin") set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/") + set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/") set(PLATFORMS ${DLL_DEST}platforms/) set(STYLES ${DLL_DEST}styles/) + set(IMAGEFORMATS ${DLL_DEST}imageformats/) windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST} icudt*.dll icuin*.dll @@ -17,4 +19,5 @@ function(copy_yuzu_Qt5_deps target_dir) ) windows_copy_files(yuzu ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*) windows_copy_files(yuzu ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*) + windows_copy_files(yuzu ${Qt5_IMAGEFORMATS_DIR} ${IMAGEFORMATS} qjpeg$<$<CONFIG:Debug>:d>.*) endfunction(copy_yuzu_Qt5_deps) diff --git a/appveyor.yml b/appveyor.yml index 17d1b5fee..a6f12b267 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -117,6 +117,7 @@ after_build: mkdir $RELEASE_DIST mkdir $RELEASE_DIST/platforms mkdir $RELEASE_DIST/styles + mkdir $RELEASE_DIST/imageformats # copy the compiled binaries and other release files to the release folder Get-ChildItem "$CMAKE_BINARY_DIR" -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST @@ -140,6 +141,9 @@ after_build: # copy the qt windows vista style dll to platforms Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/styles/qwindowsvistastyle.dll" -force -destination "$RELEASE_DIST/styles" + # copy the qt jpeg imageformat dll to platforms + Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/imageformats/qjpeg.dll" -force -destination "$RELEASE_DIST/imageformats" + 7z a -tzip $MINGW_BUILD_ZIP $RELEASE_DIST\* 7z a $MINGW_SEVENZIP $RELEASE_DIST } diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 987d0142a..b6eb36f20 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -32,11 +32,11 @@ add_subdirectory(inih) # lz4 set(LZ4_BUNDLED_MODE ON) -add_subdirectory(lz4/contrib/cmake_unofficial) +add_subdirectory(lz4/contrib/cmake_unofficial EXCLUDE_FROM_ALL) target_include_directories(lz4_static INTERFACE ./lz4/lib) # mbedtls -add_subdirectory(mbedtls) +add_subdirectory(mbedtls EXCLUDE_FROM_ALL) target_include_directories(mbedtls PUBLIC ./mbedtls/include) # MicroProfile @@ -62,5 +62,5 @@ target_include_directories(opus INTERFACE ./opus/include) # Cubeb if(ENABLE_CUBEB) set(BUILD_TESTS OFF CACHE BOOL "") - add_subdirectory(cubeb) + add_subdirectory(cubeb EXCLUDE_FROM_ALL) endif() diff --git a/externals/catch b/externals/catch -Subproject d2a130f2433aeaca070e3e4d6298a80049d21cf +Subproject 15cf3caaceb21172ea42a24e595a2eb58c3ec96 diff --git a/externals/dynarmic b/externals/dynarmic -Subproject 4f96c63025af34c1490c59f6729497b9866ffa3 +Subproject 0118ee04f90faaff951989f3c2494bc6ffb70cf diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h index 5f4b962d9..fd41dc702 100644 --- a/externals/glad/include/glad/glad.h +++ b/externals/glad/include/glad/glad.h @@ -1,6 +1,6 @@ /* - OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. + OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018. Language/Generator: C/C++ Specification: gl @@ -15,6 +15,7 @@ GL_AMD_debug_output, GL_AMD_depth_clamp_separate, GL_AMD_draw_buffers_blend, + GL_AMD_framebuffer_multisample_advanced, GL_AMD_framebuffer_sample_positions, GL_AMD_gcn_shader, GL_AMD_gpu_shader_half_float, @@ -600,7 +601,7 @@ Omit khrplatform: False Commandline: - --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" + --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" Online: Too many extensions */ @@ -1409,7 +1410,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 -#define GL_INDEX 0x8222 #define GL_FRAMEBUFFER_SRGB 0x8DB9 #define GL_HALF_FLOAT 0x140B #define GL_MAP_READ_BIT 0x0001 @@ -2780,6 +2780,12 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 #define GL_DEPTH_CLAMP_NEAR_AMD 0x901E #define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 +#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 +#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 +#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 +#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 +#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 #define GL_SUBSAMPLE_DISTANCE_AMD 0x883F #define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE #define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF @@ -3157,6 +3163,7 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; #define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 #define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 #define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_INDEX 0x8222 #define GL_LINES_ADJACENCY_ARB 0x000A #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B #define GL_TRIANGLES_ADJACENCY_ARB 0x000C @@ -6433,6 +6440,16 @@ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)(GLuint buf, GL GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; #define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD #endif +#ifndef GL_AMD_framebuffer_multisample_advanced +#define GL_AMD_framebuffer_multisample_advanced 1 +GLAPI int GLAD_GL_AMD_framebuffer_multisample_advanced; +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD; +#define glRenderbufferStorageMultisampleAdvancedAMD glad_glRenderbufferStorageMultisampleAdvancedAMD +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD; +#define glNamedRenderbufferStorageMultisampleAdvancedAMD glad_glNamedRenderbufferStorageMultisampleAdvancedAMD +#endif #ifndef GL_AMD_framebuffer_sample_positions #define GL_AMD_framebuffer_sample_positions 1 GLAPI int GLAD_GL_AMD_framebuffer_sample_positions; diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c index 13607e449..1cf0890b9 100644 --- a/externals/glad/src/glad.c +++ b/externals/glad/src/glad.c @@ -1,6 +1,6 @@ /* - OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. + OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018. Language/Generator: C/C++ Specification: gl @@ -15,6 +15,7 @@ GL_AMD_debug_output, GL_AMD_depth_clamp_separate, GL_AMD_draw_buffers_blend, + GL_AMD_framebuffer_multisample_advanced, GL_AMD_framebuffer_sample_positions, GL_AMD_gcn_shader, GL_AMD_gpu_shader_half_float, @@ -600,7 +601,7 @@ Omit khrplatform: False Commandline: - --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" + --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" Online: Too many extensions */ @@ -739,7 +740,7 @@ int gladLoadGL(void) { return status; } -struct gladGLversionStruct GLVersion; +struct gladGLversionStruct GLVersion = { 0, 0 }; #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) #define _GLAD_IS_SOME_NEW_VERSION 1 @@ -838,3190 +839,3193 @@ static int has_ext(const char *ext) { return 0; } -int GLAD_GL_VERSION_1_0; -int GLAD_GL_VERSION_1_1; -int GLAD_GL_VERSION_1_2; -int GLAD_GL_VERSION_1_3; -int GLAD_GL_VERSION_1_4; -int GLAD_GL_VERSION_1_5; -int GLAD_GL_VERSION_2_0; -int GLAD_GL_VERSION_2_1; -int GLAD_GL_VERSION_3_0; -int GLAD_GL_VERSION_3_1; -int GLAD_GL_VERSION_3_2; -int GLAD_GL_VERSION_3_3; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -PFNGLBINDSAMPLERPROC glad_glBindSampler; -PFNGLLINEWIDTHPROC glad_glLineWidth; -PFNGLCOLORP3UIVPROC glad_glColorP3uiv; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -PFNGLCOMPILESHADERPROC glad_glCompileShader; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; -PFNGLVERTEXP4UIPROC glad_glVertexP4ui; -PFNGLENABLEIPROC glad_glEnablei; -PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; -PFNGLCREATESHADERPROC glad_glCreateShader; -PFNGLISBUFFERPROC glad_glIsBuffer; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -PFNGLHINTPROC glad_glHint; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -PFNGLVERTEXP2UIPROC glad_glVertexP2ui; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -PFNGLPOINTSIZEPROC glad_glPointSize; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -PFNGLWAITSYNCPROC glad_glWaitSync; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -PFNGLUNIFORM3IPROC glad_glUniform3i; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -PFNGLUNIFORM3FPROC glad_glUniform3f; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; -PFNGLCOLORMASKIPROC glad_glColorMaski; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -PFNGLDRAWARRAYSPROC glad_glDrawArrays; -PFNGLUNIFORM1UIPROC glad_glUniform1ui; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -PFNGLCLEARPROC glad_glClear; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -PFNGLISENABLEDPROC glad_glIsEnabled; -PFNGLSTENCILOPPROC glad_glStencilOp; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -PFNGLGETQUERYIVPROC glad_glGetQueryiv; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -PFNGLISSHADERPROC glad_glIsShader; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -PFNGLENABLEPROC glad_glEnable; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; -PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -PFNGLFLUSHPROC glad_glFlush; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -PFNGLFENCESYNCPROC glad_glFenceSync; -PFNGLCOLORP3UIPROC glad_glColorP3ui; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -PFNGLGENSAMPLERSPROC glad_glGenSamplers; -PFNGLCLAMPCOLORPROC glad_glClampColor; -PFNGLUNIFORM4IVPROC glad_glUniform4iv; -PFNGLCLEARSTENCILPROC glad_glClearStencil; -PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; -PFNGLGENTEXTURESPROC glad_glGenTextures; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -PFNGLISSYNCPROC glad_glIsSync; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -PFNGLUNIFORM2IPROC glad_glUniform2i; -PFNGLUNIFORM2FPROC glad_glUniform2f; -PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -PFNGLGENQUERIESPROC glad_glGenQueries; -PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -PFNGLISENABLEDIPROC glad_glIsEnabledi; -PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -PFNGLUNIFORM2IVPROC glad_glUniform2iv; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -PFNGLGETSHADERIVPROC glad_glGetShaderiv; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -PFNGLGETDOUBLEVPROC glad_glGetDoublev; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; -PFNGLUNIFORM3FVPROC glad_glUniform3fv; -PFNGLDEPTHRANGEPROC glad_glDepthRange; -PFNGLMAPBUFFERPROC glad_glMapBuffer; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -PFNGLDELETESYNCPROC glad_glDeleteSync; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -PFNGLUNIFORM3IVPROC glad_glUniform3iv; -PFNGLPOLYGONMODEPROC glad_glPolygonMode; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -PFNGLUSEPROGRAMPROC glad_glUseProgram; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -PFNGLFINISHPROC glad_glFinish; -PFNGLDELETESHADERPROC glad_glDeleteShader; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -PFNGLVIEWPORTPROC glad_glViewport; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -PFNGLUNIFORM2UIPROC glad_glUniform2ui; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -PFNGLCLEARDEPTHPROC glad_glClearDepth; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -PFNGLTEXBUFFERPROC glad_glTexBuffer; -PFNGLPIXELSTOREIPROC glad_glPixelStorei; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -PFNGLPIXELSTOREFPROC glad_glPixelStoref; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; -PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; -PFNGLLINKPROGRAMPROC glad_glLinkProgram; -PFNGLBINDTEXTUREPROC glad_glBindTexture; -PFNGLGETSTRINGPROC glad_glGetString; -PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; -PFNGLDETACHSHADERPROC glad_glDetachShader; -PFNGLENDQUERYPROC glad_glEndQuery; -PFNGLNORMALP3UIPROC glad_glNormalP3ui; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -PFNGLUNIFORM1FPROC glad_glUniform1f; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -PFNGLUNIFORM1IPROC glad_glUniform1i; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -PFNGLDISABLEPROC glad_glDisable; -PFNGLLOGICOPPROC glad_glLogicOp; -PFNGLUNIFORM4UIPROC glad_glUniform4ui; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -PFNGLCULLFACEPROC glad_glCullFace; -PFNGLGETSTRINGIPROC glad_glGetStringi; -PFNGLATTACHSHADERPROC glad_glAttachShader; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -PFNGLDRAWELEMENTSPROC glad_glDrawElements; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -PFNGLUNIFORM1IVPROC glad_glUniform1iv; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -PFNGLREADBUFFERPROC glad_glReadBuffer; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -PFNGLBLENDCOLORPROC glad_glBlendColor; -PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; -PFNGLISPROGRAMPROC glad_glIsProgram; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -PFNGLUNIFORM4IPROC glad_glUniform4i; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -PFNGLREADPIXELSPROC glad_glReadPixels; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -PFNGLUNIFORM4FPROC glad_glUniform4f; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -PFNGLSTENCILFUNCPROC glad_glStencilFunc; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -PFNGLCOLORP4UIPROC glad_glColorP4ui; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -PFNGLGENBUFFERSPROC glad_glGenBuffers; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -PFNGLBLENDFUNCPROC glad_glBlendFunc; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -PFNGLSCISSORPROC glad_glScissor; -PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -PFNGLCLEARCOLORPROC glad_glClearColor; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -PFNGLCOLORP4UIVPROC glad_glColorP4uiv; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -PFNGLUNIFORM3UIPROC glad_glUniform3ui; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -PFNGLUNIFORM2FVPROC glad_glUniform2fv; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -PFNGLDEPTHFUNCPROC glad_glDepthFunc; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -PFNGLCOLORMASKPROC glad_glColorMask; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -PFNGLUNIFORM4FVPROC glad_glUniform4fv; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -PFNGLISSAMPLERPROC glad_glIsSampler; -PFNGLVERTEXP3UIPROC glad_glVertexP3ui; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -PFNGLDISABLEIPROC glad_glDisablei; -PFNGLSHADERSOURCEPROC glad_glShaderSource; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -PFNGLGETSYNCIVPROC glad_glGetSynciv; -PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; -PFNGLBEGINQUERYPROC glad_glBeginQuery; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -PFNGLBINDBUFFERPROC glad_glBindBuffer; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -PFNGLBUFFERDATAPROC glad_glBufferData; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; -PFNGLGETERRORPROC glad_glGetError; -PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; -PFNGLGETFLOATVPROC glad_glGetFloatv; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; -PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; -PFNGLGETINTEGERVPROC glad_glGetIntegerv; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -PFNGLISQUERYPROC glad_glIsQuery; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -PFNGLSTENCILMASKPROC glad_glStencilMask; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -PFNGLISTEXTUREPROC glad_glIsTexture; -PFNGLUNIFORM1FVPROC glad_glUniform1fv; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -PFNGLDEPTHMASKPROC glad_glDepthMask; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -PFNGLFRONTFACEPROC glad_glFrontFace; -int GLAD_GL_SGIX_pixel_tiles; -int GLAD_GL_EXT_post_depth_coverage; -int GLAD_GL_APPLE_element_array; -int GLAD_GL_AMD_multi_draw_indirect; -int GLAD_GL_EXT_blend_subtract; -int GLAD_GL_SGIX_tag_sample_buffer; -int GLAD_GL_NV_point_sprite; -int GLAD_GL_IBM_texture_mirrored_repeat; -int GLAD_GL_APPLE_transform_hint; -int GLAD_GL_ATI_separate_stencil; -int GLAD_GL_NV_shader_atomic_int64; -int GLAD_GL_EXT_semaphore_win32; -int GLAD_GL_NV_vertex_program2_option; -int GLAD_GL_EXT_texture_buffer_object; -int GLAD_GL_ARB_vertex_blend; -int GLAD_GL_OVR_multiview; -int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch; -int GLAD_GL_NV_vertex_program2; -int GLAD_GL_ARB_program_interface_query; -int GLAD_GL_EXT_misc_attribute; -int GLAD_GL_NV_multisample_coverage; -int GLAD_GL_ARB_shading_language_packing; -int GLAD_GL_EXT_texture_cube_map; -int GLAD_GL_NV_viewport_array2; -int GLAD_GL_ARB_texture_stencil8; -int GLAD_GL_EXT_index_func; -int GLAD_GL_EXT_memory_object_fd; -int GLAD_GL_OES_compressed_paletted_texture; -int GLAD_GL_MESA_shader_integer_functions; -int GLAD_GL_NV_shader_buffer_load; -int GLAD_GL_EXT_color_subtable; -int GLAD_GL_SUNX_constant_data; -int GLAD_GL_EXT_texture_compression_s3tc; -int GLAD_GL_EXT_multi_draw_arrays; -int GLAD_GL_ARB_shader_atomic_counters; -int GLAD_GL_ARB_arrays_of_arrays; -int GLAD_GL_NV_conditional_render; -int GLAD_GL_EXT_texture_env_combine; -int GLAD_GL_NV_fog_distance; -int GLAD_GL_SGIX_async_histogram; -int GLAD_GL_MESA_resize_buffers; -int GLAD_GL_NV_light_max_exponent; -int GLAD_GL_NV_texture_env_combine4; -int GLAD_GL_ARB_spirv_extensions; -int GLAD_GL_ARB_texture_view; -int GLAD_GL_ARB_texture_env_combine; -int GLAD_GL_ARB_map_buffer_range; -int GLAD_GL_EXT_convolution; -int GLAD_GL_NV_compute_program5; -int GLAD_GL_NV_vertex_attrib_integer_64bit; -int GLAD_GL_EXT_paletted_texture; -int GLAD_GL_ARB_texture_buffer_object; -int GLAD_GL_ATI_pn_triangles; -int GLAD_GL_SGIX_resample; -int GLAD_GL_SGIX_flush_raster; -int GLAD_GL_EXT_light_texture; -int GLAD_GL_ARB_point_sprite; -int GLAD_GL_SUN_convolution_border_modes; -int GLAD_GL_EXT_semaphore_fd; -int GLAD_GL_NV_parameter_buffer_object2; -int GLAD_GL_ARB_half_float_pixel; -int GLAD_GL_NV_tessellation_program5; -int GLAD_GL_REND_screen_coordinates; -int GLAD_GL_EXT_shared_texture_palette; -int GLAD_GL_EXT_packed_float; -int GLAD_GL_OML_subsample; -int GLAD_GL_SGIX_vertex_preclip; -int GLAD_GL_SGIX_texture_scale_bias; -int GLAD_GL_AMD_draw_buffers_blend; -int GLAD_GL_APPLE_texture_range; -int GLAD_GL_EXT_texture_array; -int GLAD_GL_NV_texture_barrier; -int GLAD_GL_ARB_texture_query_levels; -int GLAD_GL_NV_texgen_emboss; -int GLAD_GL_EXT_texture_swizzle; -int GLAD_GL_ARB_texture_rg; -int GLAD_GL_ARB_vertex_type_2_10_10_10_rev; -int GLAD_GL_ARB_fragment_shader; -int GLAD_GL_3DFX_tbuffer; -int GLAD_GL_GREMEDY_frame_terminator; -int GLAD_GL_IBM_cull_vertex; -int GLAD_GL_EXT_separate_shader_objects; -int GLAD_GL_NV_texture_multisample; -int GLAD_GL_ARB_shader_objects; -int GLAD_GL_ARB_framebuffer_object; -int GLAD_GL_EXT_external_buffer; -int GLAD_GL_ATI_envmap_bumpmap; -int GLAD_GL_AMD_shader_explicit_vertex_parameter; -int GLAD_GL_ARB_robust_buffer_access_behavior; -int GLAD_GL_ARB_shader_stencil_export; -int GLAD_GL_NV_texture_rectangle; -int GLAD_GL_ARB_enhanced_layouts; -int GLAD_GL_ARB_texture_rectangle; -int GLAD_GL_SGI_texture_color_table; -int GLAD_GL_NV_viewport_swizzle; -int GLAD_GL_ATI_map_object_buffer; -int GLAD_GL_ARB_robustness; -int GLAD_GL_NV_pixel_data_range; -int GLAD_GL_EXT_framebuffer_blit; -int GLAD_GL_ARB_gpu_shader_fp64; -int GLAD_GL_NV_command_list; -int GLAD_GL_SGIX_depth_texture; -int GLAD_GL_AMD_framebuffer_sample_positions; -int GLAD_GL_GREMEDY_string_marker; -int GLAD_GL_ARB_texture_compression_bptc; -int GLAD_GL_EXT_subtexture; -int GLAD_GL_EXT_pixel_transform_color_table; -int GLAD_GL_EXT_texture_compression_rgtc; -int GLAD_GL_ARB_shader_atomic_counter_ops; -int GLAD_GL_SGIX_depth_pass_instrument; -int GLAD_GL_EXT_gpu_program_parameters; -int GLAD_GL_NV_evaluators; -int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent; -int GLAD_GL_SGIS_texture_filter4; -int GLAD_GL_AMD_performance_monitor; -int GLAD_GL_NV_geometry_shader4; -int GLAD_GL_EXT_stencil_clear_tag; -int GLAD_GL_NV_vertex_program1_1; -int GLAD_GL_NV_present_video; -int GLAD_GL_ARB_texture_compression_rgtc; -int GLAD_GL_HP_convolution_border_modes; -int GLAD_GL_EXT_shader_integer_mix; -int GLAD_GL_SGIX_framezoom; -int GLAD_GL_ARB_stencil_texturing; -int GLAD_GL_ARB_shader_clock; -int GLAD_GL_NV_shader_atomic_fp16_vector; -int GLAD_GL_SGIX_fog_offset; -int GLAD_GL_ARB_draw_elements_base_vertex; -int GLAD_GL_INGR_interlace_read; -int GLAD_GL_NV_transform_feedback; -int GLAD_GL_NV_fragment_program; -int GLAD_GL_AMD_stencil_operation_extended; -int GLAD_GL_ARB_seamless_cubemap_per_texture; -int GLAD_GL_ARB_instanced_arrays; -int GLAD_GL_ARB_get_texture_sub_image; -int GLAD_GL_NV_vertex_array_range2; -int GLAD_GL_KHR_robustness; -int GLAD_GL_AMD_sparse_texture; -int GLAD_GL_ARB_clip_control; -int GLAD_GL_NV_fragment_coverage_to_color; -int GLAD_GL_NV_fence; -int GLAD_GL_ARB_texture_buffer_range; -int GLAD_GL_SUN_mesh_array; -int GLAD_GL_ARB_vertex_attrib_binding; -int GLAD_GL_ARB_framebuffer_no_attachments; -int GLAD_GL_ARB_cl_event; -int GLAD_GL_EXT_vertex_weighting; -int GLAD_GL_ARB_derivative_control; -int GLAD_GL_NV_packed_depth_stencil; -int GLAD_GL_OES_single_precision; -int GLAD_GL_NV_primitive_restart; -int GLAD_GL_SUN_global_alpha; -int GLAD_GL_ARB_fragment_shader_interlock; -int GLAD_GL_EXT_texture_object; -int GLAD_GL_AMD_name_gen_delete; -int GLAD_GL_NV_texture_compression_vtc; -int GLAD_GL_NV_sample_mask_override_coverage; -int GLAD_GL_NV_texture_shader3; -int GLAD_GL_MESA_tile_raster_order; -int GLAD_GL_ARB_texture_filter_anisotropic; -int GLAD_GL_EXT_texture; -int GLAD_GL_ARB_buffer_storage; -int GLAD_GL_AMD_shader_atomic_counter_ops; -int GLAD_GL_APPLE_vertex_program_evaluators; -int GLAD_GL_AMD_texture_gather_bias_lod; -int GLAD_GL_NV_texgen_reflection; -int GLAD_GL_ARB_explicit_uniform_location; -int GLAD_GL_ARB_depth_buffer_float; -int GLAD_GL_NV_path_rendering_shared_edge; -int GLAD_GL_SGIX_shadow_ambient; -int GLAD_GL_ARB_texture_cube_map; -int GLAD_GL_AMD_vertex_shader_viewport_index; -int GLAD_GL_SGIX_list_priority; -int GLAD_GL_NV_vertex_buffer_unified_memory; -int GLAD_GL_NV_uniform_buffer_unified_memory; -int GLAD_GL_ARB_clear_texture; -int GLAD_GL_ATI_texture_env_combine3; -int GLAD_GL_NV_depth_clamp; -int GLAD_GL_ARB_map_buffer_alignment; -int GLAD_GL_EXT_memory_object; -int GLAD_GL_NV_blend_equation_advanced; -int GLAD_GL_SGIS_sharpen_texture; -int GLAD_GL_KHR_robust_buffer_access_behavior; -int GLAD_GL_ARB_pipeline_statistics_query; -int GLAD_GL_ARB_vertex_program; -int GLAD_GL_ARB_texture_rgb10_a2ui; -int GLAD_GL_OML_interlace; -int GLAD_GL_ATI_pixel_format_float; -int GLAD_GL_NV_clip_space_w_scaling; -int GLAD_GL_ARB_vertex_buffer_object; -int GLAD_GL_EXT_shadow_funcs; -int GLAD_GL_ATI_text_fragment_shader; -int GLAD_GL_NV_vertex_array_range; -int GLAD_GL_SGIX_fragment_lighting; -int GLAD_GL_AMD_shader_ballot; -int GLAD_GL_NV_texture_expand_normal; -int GLAD_GL_NV_framebuffer_multisample_coverage; -int GLAD_GL_EXT_timer_query; -int GLAD_GL_EXT_vertex_array_bgra; -int GLAD_GL_NV_bindless_texture; -int GLAD_GL_KHR_debug; -int GLAD_GL_SGIS_texture_border_clamp; -int GLAD_GL_ATI_vertex_attrib_array_object; -int GLAD_GL_SGIX_clipmap; -int GLAD_GL_EXT_geometry_shader4; -int GLAD_GL_ARB_shader_texture_image_samples; -int GLAD_GL_MESA_ycbcr_texture; -int GLAD_GL_MESAX_texture_stack; -int GLAD_GL_AMD_seamless_cubemap_per_texture; -int GLAD_GL_EXT_bindable_uniform; -int GLAD_GL_KHR_texture_compression_astc_hdr; -int GLAD_GL_ARB_shader_ballot; -int GLAD_GL_KHR_blend_equation_advanced; -int GLAD_GL_ARB_fragment_program_shadow; -int GLAD_GL_ATI_element_array; -int GLAD_GL_AMD_texture_texture4; -int GLAD_GL_SGIX_reference_plane; -int GLAD_GL_EXT_stencil_two_side; -int GLAD_GL_ARB_transform_feedback_overflow_query; -int GLAD_GL_SGIX_texture_lod_bias; -int GLAD_GL_KHR_no_error; -int GLAD_GL_NV_explicit_multisample; -int GLAD_GL_NV_stereo_view_rendering; -int GLAD_GL_IBM_static_data; -int GLAD_GL_EXT_clip_volume_hint; -int GLAD_GL_EXT_texture_perturb_normal; -int GLAD_GL_NV_fragment_program2; -int GLAD_GL_NV_fragment_program4; -int GLAD_GL_EXT_point_parameters; -int GLAD_GL_PGI_misc_hints; -int GLAD_GL_EXT_EGL_image_storage; -int GLAD_GL_SGIX_subsample; -int GLAD_GL_AMD_shader_stencil_export; -int GLAD_GL_ARB_shader_texture_lod; -int GLAD_GL_ARB_vertex_shader; -int GLAD_GL_ARB_depth_clamp; -int GLAD_GL_SGIS_texture_select; -int GLAD_GL_NV_texture_shader; -int GLAD_GL_ARB_tessellation_shader; -int GLAD_GL_EXT_draw_buffers2; -int GLAD_GL_ARB_vertex_attrib_64bit; -int GLAD_GL_EXT_texture_filter_minmax; -int GLAD_GL_NV_query_resource; -int GLAD_GL_AMD_interleaved_elements; -int GLAD_GL_ARB_fragment_program; -int GLAD_GL_OML_resample; -int GLAD_GL_APPLE_ycbcr_422; -int GLAD_GL_SGIX_texture_add_env; -int GLAD_GL_ARB_shadow_ambient; -int GLAD_GL_ARB_texture_storage; -int GLAD_GL_EXT_pixel_buffer_object; -int GLAD_GL_ARB_copy_image; -int GLAD_GL_SGIS_pixel_texture; -int GLAD_GL_SGIS_generate_mipmap; -int GLAD_GL_SGIX_instruments; -int GLAD_GL_ARB_fragment_layer_viewport; -int GLAD_GL_ARB_shader_storage_buffer_object; -int GLAD_GL_EXT_sparse_texture2; -int GLAD_GL_EXT_blend_minmax; -int GLAD_GL_MESA_pack_invert; -int GLAD_GL_ARB_base_instance; -int GLAD_GL_SGIX_convolution_accuracy; -int GLAD_GL_PGI_vertex_hints; -int GLAD_GL_AMD_transform_feedback4; -int GLAD_GL_ARB_ES3_1_compatibility; -int GLAD_GL_EXT_memory_object_win32; -int GLAD_GL_EXT_texture_integer; -int GLAD_GL_ARB_texture_multisample; -int GLAD_GL_ATI_vertex_streams; -int GLAD_GL_AMD_gpu_shader_int64; -int GLAD_GL_S3_s3tc; -int GLAD_GL_ARB_query_buffer_object; -int GLAD_GL_AMD_vertex_shader_tessellator; -int GLAD_GL_ARB_invalidate_subdata; -int GLAD_GL_NV_draw_vulkan_image; -int GLAD_GL_EXT_index_material; -int GLAD_GL_NVX_linked_gpu_multicast; -int GLAD_GL_NV_blend_equation_advanced_coherent; -int GLAD_GL_KHR_texture_compression_astc_sliced_3d; -int GLAD_GL_INTEL_parallel_arrays; -int GLAD_GL_ATI_draw_buffers; -int GLAD_GL_WIN_specular_fog; -int GLAD_GL_EXT_cmyka; -int GLAD_GL_SGIX_pixel_texture; -int GLAD_GL_APPLE_specular_vector; -int GLAD_GL_ARB_compatibility; -int GLAD_GL_ARB_timer_query; -int GLAD_GL_SGIX_interlace; -int GLAD_GL_NV_parameter_buffer_object; -int GLAD_GL_AMD_shader_trinary_minmax; -int GLAD_GL_ARB_direct_state_access; -int GLAD_GL_EXT_rescale_normal; -int GLAD_GL_ARB_pixel_buffer_object; -int GLAD_GL_ARB_uniform_buffer_object; -int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev; -int GLAD_GL_ARB_texture_swizzle; -int GLAD_GL_NV_transform_feedback2; -int GLAD_GL_SGIX_async_pixel; -int GLAD_GL_NV_fragment_program_option; -int GLAD_GL_ARB_explicit_attrib_location; -int GLAD_GL_EXT_blend_color; -int GLAD_GL_NV_shader_thread_group; -int GLAD_GL_EXT_stencil_wrap; -int GLAD_GL_EXT_index_array_formats; -int GLAD_GL_OVR_multiview2; -int GLAD_GL_EXT_histogram; -int GLAD_GL_EXT_polygon_offset; -int GLAD_GL_SGIS_point_parameters; -int GLAD_GL_SGIX_ycrcb; -int GLAD_GL_EXT_direct_state_access; -int GLAD_GL_ARB_cull_distance; -int GLAD_GL_AMD_sample_positions; -int GLAD_GL_NV_vertex_program; -int GLAD_GL_NV_shader_thread_shuffle; -int GLAD_GL_ARB_shader_precision; -int GLAD_GL_EXT_vertex_shader; -int GLAD_GL_EXT_blend_func_separate; -int GLAD_GL_APPLE_fence; -int GLAD_GL_NV_query_resource_tag; -int GLAD_GL_OES_byte_coordinates; -int GLAD_GL_ARB_transpose_matrix; -int GLAD_GL_ARB_provoking_vertex; -int GLAD_GL_EXT_fog_coord; -int GLAD_GL_EXT_vertex_array; -int GLAD_GL_ARB_half_float_vertex; -int GLAD_GL_EXT_blend_equation_separate; -int GLAD_GL_NV_framebuffer_mixed_samples; -int GLAD_GL_NVX_conditional_render; -int GLAD_GL_ARB_multi_draw_indirect; -int GLAD_GL_EXT_raster_multisample; -int GLAD_GL_NV_copy_image; -int GLAD_GL_HP_texture_lighting; -int GLAD_GL_INTEL_framebuffer_CMAA; -int GLAD_GL_ARB_transform_feedback2; -int GLAD_GL_ARB_transform_feedback3; -int GLAD_GL_SGIX_ycrcba; -int GLAD_GL_EXT_debug_marker; -int GLAD_GL_EXT_bgra; -int GLAD_GL_ARB_sparse_texture_clamp; -int GLAD_GL_EXT_pixel_transform; -int GLAD_GL_ARB_conservative_depth; -int GLAD_GL_ATI_fragment_shader; -int GLAD_GL_ARB_vertex_array_object; -int GLAD_GL_SUN_triangle_list; -int GLAD_GL_EXT_texture_env_add; -int GLAD_GL_EXT_packed_depth_stencil; -int GLAD_GL_EXT_texture_mirror_clamp; -int GLAD_GL_NV_multisample_filter_hint; -int GLAD_GL_APPLE_float_pixels; -int GLAD_GL_ARB_transform_feedback_instanced; -int GLAD_GL_SGIX_async; -int GLAD_GL_EXT_texture_compression_latc; -int GLAD_GL_NV_robustness_video_memory_purge; -int GLAD_GL_ARB_shading_language_100; -int GLAD_GL_INTEL_performance_query; -int GLAD_GL_ARB_texture_mirror_clamp_to_edge; -int GLAD_GL_NV_gpu_shader5; -int GLAD_GL_NV_bindless_multi_draw_indirect_count; -int GLAD_GL_ARB_ES2_compatibility; -int GLAD_GL_ARB_indirect_parameters; -int GLAD_GL_EXT_window_rectangles; -int GLAD_GL_NV_half_float; -int GLAD_GL_ARB_ES3_2_compatibility; -int GLAD_GL_ATI_texture_mirror_once; -int GLAD_GL_IBM_rasterpos_clip; -int GLAD_GL_EXT_semaphore; -int GLAD_GL_SGIX_shadow; -int GLAD_GL_EXT_polygon_offset_clamp; -int GLAD_GL_NV_deep_texture3D; -int GLAD_GL_ARB_shader_draw_parameters; -int GLAD_GL_SGIX_calligraphic_fragment; -int GLAD_GL_ARB_shader_bit_encoding; -int GLAD_GL_EXT_compiled_vertex_array; -int GLAD_GL_NV_depth_buffer_float; -int GLAD_GL_NV_occlusion_query; -int GLAD_GL_APPLE_flush_buffer_range; -int GLAD_GL_ARB_imaging; -int GLAD_GL_NV_shader_atomic_float; -int GLAD_GL_ARB_draw_buffers_blend; -int GLAD_GL_AMD_gcn_shader; -int GLAD_GL_AMD_blend_minmax_factor; -int GLAD_GL_EXT_texture_sRGB_decode; -int GLAD_GL_ARB_shading_language_420pack; -int GLAD_GL_ARB_shader_viewport_layer_array; -int GLAD_GL_ATI_meminfo; -int GLAD_GL_EXT_abgr; -int GLAD_GL_AMD_pinned_memory; -int GLAD_GL_EXT_texture_snorm; -int GLAD_GL_SGIX_texture_coordinate_clamp; -int GLAD_GL_ARB_clear_buffer_object; -int GLAD_GL_ARB_multisample; -int GLAD_GL_EXT_debug_label; -int GLAD_GL_ARB_sample_shading; -int GLAD_GL_NV_internalformat_sample_query; -int GLAD_GL_INTEL_map_texture; -int GLAD_GL_ARB_texture_env_crossbar; -int GLAD_GL_EXT_422_pixels; -int GLAD_GL_NV_blend_minmax_factor; -int GLAD_GL_NV_conservative_raster_pre_snap_triangles; -int GLAD_GL_ARB_compute_shader; -int GLAD_GL_EXT_blend_logic_op; -int GLAD_GL_ARB_blend_func_extended; -int GLAD_GL_IBM_vertex_array_lists; -int GLAD_GL_ARB_color_buffer_float; -int GLAD_GL_ARB_bindless_texture; -int GLAD_GL_ARB_window_pos; -int GLAD_GL_ARB_internalformat_query; -int GLAD_GL_ARB_shadow; -int GLAD_GL_ARB_texture_mirrored_repeat; -int GLAD_GL_EXT_shader_image_load_store; -int GLAD_GL_EXT_copy_texture; -int GLAD_GL_NV_register_combiners2; -int GLAD_GL_SGIX_ycrcb_subsample; -int GLAD_GL_NV_alpha_to_coverage_dither_control; -int GLAD_GL_SGIX_ir_instrument1; -int GLAD_GL_NV_draw_texture; -int GLAD_GL_EXT_texture_shared_exponent; -int GLAD_GL_NV_texture_shader2; -int GLAD_GL_EXT_draw_instanced; -int GLAD_GL_NV_copy_depth_to_color; -int GLAD_GL_ARB_viewport_array; -int GLAD_GL_ARB_separate_shader_objects; -int GLAD_GL_NV_conservative_raster_pre_snap; -int GLAD_GL_EXT_depth_bounds_test; -int GLAD_GL_HP_image_transform; -int GLAD_GL_ARB_texture_env_add; -int GLAD_GL_NV_video_capture; -int GLAD_GL_ARB_sampler_objects; -int GLAD_GL_ARB_matrix_palette; -int GLAD_GL_SGIS_texture_color_mask; -int GLAD_GL_EXT_packed_pixels; -int GLAD_GL_EXT_coordinate_frame; -int GLAD_GL_ARB_texture_compression; -int GLAD_GL_ARB_multi_bind; -int GLAD_GL_APPLE_aux_depth_stencil; -int GLAD_GL_ARB_shader_subroutine; -int GLAD_GL_EXT_framebuffer_sRGB; -int GLAD_GL_ARB_texture_storage_multisample; -int GLAD_GL_KHR_blend_equation_advanced_coherent; -int GLAD_GL_EXT_vertex_attrib_64bit; -int GLAD_GL_NV_shader_atomic_float64; -int GLAD_GL_ARB_depth_texture; -int GLAD_GL_NV_shader_buffer_store; -int GLAD_GL_OES_query_matrix; -int GLAD_GL_MESA_window_pos; -int GLAD_GL_NV_fill_rectangle; -int GLAD_GL_NV_shader_storage_buffer_object; -int GLAD_GL_ARB_texture_query_lod; -int GLAD_GL_ARB_copy_buffer; -int GLAD_GL_ARB_shader_image_size; -int GLAD_GL_NV_shader_atomic_counters; -int GLAD_GL_APPLE_object_purgeable; -int GLAD_GL_ARB_occlusion_query; -int GLAD_GL_INGR_color_clamp; -int GLAD_GL_SGI_color_table; -int GLAD_GL_NV_gpu_program5_mem_extended; -int GLAD_GL_ARB_texture_cube_map_array; -int GLAD_GL_SGIX_scalebias_hint; -int GLAD_GL_EXT_gpu_shader4; -int GLAD_GL_NV_geometry_program4; -int GLAD_GL_EXT_framebuffer_multisample_blit_scaled; -int GLAD_GL_AMD_debug_output; -int GLAD_GL_ARB_texture_border_clamp; -int GLAD_GL_EXT_win32_keyed_mutex; -int GLAD_GL_ARB_fragment_coord_conventions; -int GLAD_GL_ARB_multitexture; -int GLAD_GL_SGIX_polynomial_ffd; -int GLAD_GL_EXT_texture_env_dot3; -int GLAD_GL_EXT_provoking_vertex; -int GLAD_GL_ARB_point_parameters; -int GLAD_GL_ARB_shader_image_load_store; -int GLAD_GL_ARB_conditional_render_inverted; -int GLAD_GL_HP_occlusion_test; -int GLAD_GL_ARB_ES3_compatibility; -int GLAD_GL_ARB_texture_barrier; -int GLAD_GL_ARB_texture_buffer_object_rgb32; -int GLAD_GL_NV_bindless_multi_draw_indirect; -int GLAD_GL_SGIX_texture_multi_buffer; -int GLAD_GL_INTEL_blackhole_render; -int GLAD_GL_AMD_shader_image_load_store_lod; -int GLAD_GL_KHR_texture_compression_astc_ldr; -int GLAD_GL_3DFX_multisample; -int GLAD_GL_INTEL_fragment_shader_ordering; -int GLAD_GL_ARB_texture_env_dot3; -int GLAD_GL_NV_gpu_program4; -int GLAD_GL_NV_gpu_program5; -int GLAD_GL_NV_float_buffer; -int GLAD_GL_SGIS_texture_edge_clamp; -int GLAD_GL_ARB_framebuffer_sRGB; -int GLAD_GL_SUN_slice_accum; -int GLAD_GL_EXT_index_texture; -int GLAD_GL_EXT_shader_image_load_formatted; -int GLAD_GL_ARB_geometry_shader4; -int GLAD_GL_EXT_separate_specular_color; -int GLAD_GL_AMD_depth_clamp_separate; -int GLAD_GL_NV_conservative_raster; -int GLAD_GL_ARB_sparse_texture2; -int GLAD_GL_SGIX_sprite; -int GLAD_GL_ARB_get_program_binary; -int GLAD_GL_AMD_occlusion_query_event; -int GLAD_GL_SGIS_multisample; -int GLAD_GL_EXT_framebuffer_object; -int GLAD_GL_ARB_robustness_isolation; -int GLAD_GL_ARB_vertex_array_bgra; -int GLAD_GL_APPLE_vertex_array_range; -int GLAD_GL_AMD_query_buffer_object; -int GLAD_GL_NV_register_combiners; -int GLAD_GL_ARB_draw_buffers; -int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers; -int GLAD_GL_AMD_gpu_shader_int16; -int GLAD_GL_ARB_debug_output; -int GLAD_GL_EXT_shader_framebuffer_fetch; -int GLAD_GL_SGI_color_matrix; -int GLAD_GL_EXT_cull_vertex; -int GLAD_GL_EXT_texture_sRGB; -int GLAD_GL_APPLE_row_bytes; -int GLAD_GL_NV_conservative_raster_underestimation; -int GLAD_GL_IBM_multimode_draw_arrays; -int GLAD_GL_KHR_parallel_shader_compile; -int GLAD_GL_APPLE_vertex_array_object; -int GLAD_GL_3DFX_texture_compression_FXT1; -int GLAD_GL_NV_fragment_shader_interlock; -int GLAD_GL_AMD_conservative_depth; -int GLAD_GL_ARB_texture_float; -int GLAD_GL_ARB_compressed_texture_pixel_storage; -int GLAD_GL_SGIS_detail_texture; -int GLAD_GL_NV_geometry_shader_passthrough; -int GLAD_GL_ARB_draw_instanced; -int GLAD_GL_OES_read_format; -int GLAD_GL_ATI_texture_float; -int GLAD_GL_ARB_texture_gather; -int GLAD_GL_AMD_vertex_shader_layer; -int GLAD_GL_ARB_shading_language_include; -int GLAD_GL_APPLE_client_storage; -int GLAD_GL_WIN_phong_shading; -int GLAD_GL_INGR_blend_func_separate; -int GLAD_GL_NV_path_rendering; -int GLAD_GL_NV_conservative_raster_dilate; -int GLAD_GL_AMD_gpu_shader_half_float; -int GLAD_GL_ARB_post_depth_coverage; -int GLAD_GL_ARB_texture_non_power_of_two; -int GLAD_GL_APPLE_rgb_422; -int GLAD_GL_EXT_texture_lod_bias; -int GLAD_GL_ARB_gpu_shader_int64; -int GLAD_GL_ARB_seamless_cube_map; -int GLAD_GL_ARB_shader_group_vote; -int GLAD_GL_NV_vdpau_interop; -int GLAD_GL_ARB_occlusion_query2; -int GLAD_GL_ARB_internalformat_query2; -int GLAD_GL_EXT_texture_filter_anisotropic; -int GLAD_GL_SUN_vertex; -int GLAD_GL_EXT_transform_feedback; -int GLAD_GL_SGIX_igloo_interface; -int GLAD_GL_SGIS_texture_lod; -int GLAD_GL_NV_vertex_program3; -int GLAD_GL_ARB_draw_indirect; -int GLAD_GL_NV_vertex_program4; -int GLAD_GL_AMD_transform_feedback3_lines_triangles; -int GLAD_GL_SGIS_fog_function; -int GLAD_GL_EXT_x11_sync_object; -int GLAD_GL_ARB_sync; -int GLAD_GL_NV_texture_rectangle_compressed; -int GLAD_GL_NV_sample_locations; -int GLAD_GL_NV_gpu_multicast; -int GLAD_GL_ARB_gl_spirv; -int GLAD_GL_ARB_compute_variable_group_size; -int GLAD_GL_OES_fixed_point; -int GLAD_GL_MESA_program_binary_formats; -int GLAD_GL_NV_blend_square; -int GLAD_GL_EXT_framebuffer_multisample; -int GLAD_GL_ARB_gpu_shader5; -int GLAD_GL_SGIS_texture4D; -int GLAD_GL_EXT_texture3D; -int GLAD_GL_EXT_multisample; -int GLAD_GL_EXT_secondary_color; -int GLAD_GL_INTEL_conservative_rasterization; -int GLAD_GL_ARB_texture_filter_minmax; -int GLAD_GL_ATI_vertex_array_object; -int GLAD_GL_ARB_parallel_shader_compile; -int GLAD_GL_NVX_gpu_memory_info; -int GLAD_GL_ARB_sparse_texture; -int GLAD_GL_SGIS_point_line_texgen; -int GLAD_GL_ARB_sample_locations; -int GLAD_GL_ARB_sparse_buffer; -int GLAD_GL_ARB_polygon_offset_clamp; -int GLAD_GL_EXT_draw_range_elements; -int GLAD_GL_SGIX_blend_alpha_minmax; -int GLAD_GL_KHR_context_flush_control; -PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX; -PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD; -PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD; -PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD; -PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD; -PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD; -PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD; -PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD; -PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; -PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD; -PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD; -PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD; -PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD; -PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV; -PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV; -PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV; -PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV; -PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV; -PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV; -PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV; -PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV; -PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV; -PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV; -PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV; -PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV; -PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV; -PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV; -PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV; -PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV; -PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV; -PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV; -PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV; -PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV; -PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV; -PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV; -PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV; -PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV; -PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV; -PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV; -PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV; -PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV; -PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV; -PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV; -PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV; -PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV; -PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV; -PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV; -PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD; -PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD; -PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD; -PFNGLGENNAMESAMDPROC glad_glGenNamesAMD; -PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD; -PFNGLISNAMEAMDPROC glad_glIsNameAMD; -PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD; -PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD; -PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD; -PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD; -PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD; -PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD; -PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD; -PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD; -PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD; -PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD; -PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD; -PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD; -PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD; -PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD; -PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD; -PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD; -PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD; -PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD; -PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE; -PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE; -PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE; -PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE; -PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE; -PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE; -PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE; -PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE; -PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE; -PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE; -PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE; -PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE; -PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE; -PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE; -PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE; -PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE; -PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE; -PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE; -PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE; -PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE; -PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE; -PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE; -PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE; -PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE; -PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE; -PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE; -PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE; -PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE; -PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE; -PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE; -PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE; -PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE; -PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE; -PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE; -PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; -PFNGLSHADERBINARYPROC glad_glShaderBinary; -PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; -PFNGLDEPTHRANGEFPROC glad_glDepthRangef; -PFNGLCLEARDEPTHFPROC glad_glClearDepthf; -PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; -PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB; -PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; -PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; -PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB; -PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB; -PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB; -PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB; -PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB; -PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB; -PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB; -PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB; -PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB; -PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB; -PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB; -PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB; -PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB; -PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB; -PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB; -PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB; -PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; -PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB; -PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; -PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; -PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; -PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; -PFNGLCLIPCONTROLPROC glad_glClipControl; -PFNGLCLAMPCOLORARBPROC glad_glClampColorARB; -PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; -PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; -PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB; -PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; -PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; -PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; -PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; -PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; -PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; -PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; -PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; -PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; -PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; -PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; -PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; -PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; -PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; -PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; -PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; -PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; -PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; -PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; -PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; -PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; -PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; -PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; -PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; -PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; -PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; -PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; -PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; -PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; -PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; -PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; -PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; -PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; -PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; -PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; -PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; -PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; -PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; -PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; -PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; -PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; -PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; -PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; -PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; -PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; -PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; -PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; -PFNGLCREATETEXTURESPROC glad_glCreateTextures; -PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; -PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; -PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; -PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; -PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; -PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; -PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; -PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; -PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; -PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; -PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; -PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; -PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; -PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; -PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; -PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; -PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; -PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; -PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; -PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; -PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; -PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; -PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; -PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; -PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; -PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; -PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; -PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; -PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; -PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; -PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; -PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; -PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; -PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; -PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; -PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; -PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; -PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; -PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; -PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; -PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; -PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; -PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; -PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; -PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; -PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; -PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; -PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; -PFNGLCREATEQUERIESPROC glad_glCreateQueries; -PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; -PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; -PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; -PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; -PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB; -PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB; -PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB; -PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB; -PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB; -PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; -PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; -PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB; -PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB; -PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB; -PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB; -PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB; -PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB; -PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB; -PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB; -PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB; -PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB; -PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB; -PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB; -PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB; -PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB; -PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB; -PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB; -PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB; -PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB; -PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB; -PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB; -PFNGLISPROGRAMARBPROC glad_glIsProgramARB; -PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; -PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; -PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB; -PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB; -PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB; -PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB; -PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; -PFNGLPROGRAMBINARYPROC glad_glProgramBinary; -PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; -PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; -PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; -PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB; -PFNGLUNIFORM1DPROC glad_glUniform1d; -PFNGLUNIFORM2DPROC glad_glUniform2d; -PFNGLUNIFORM3DPROC glad_glUniform3d; -PFNGLUNIFORM4DPROC glad_glUniform4d; -PFNGLUNIFORM1DVPROC glad_glUniform1dv; -PFNGLUNIFORM2DVPROC glad_glUniform2dv; -PFNGLUNIFORM3DVPROC glad_glUniform3dv; -PFNGLUNIFORM4DVPROC glad_glUniform4dv; -PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; -PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; -PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; -PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; -PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; -PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; -PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; -PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; -PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; -PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; -PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB; -PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB; -PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB; -PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB; -PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB; -PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB; -PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB; -PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB; -PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB; -PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB; -PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB; -PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB; -PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB; -PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB; -PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB; -PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB; -PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB; -PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB; -PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB; -PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB; -PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB; -PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB; -PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB; -PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB; -PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB; -PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB; -PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB; -PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB; -PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB; -PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB; -PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB; -PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB; -PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB; -PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB; -PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB; -PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB; -PFNGLCOLORTABLEPROC glad_glColorTable; -PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv; -PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv; -PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable; -PFNGLGETCOLORTABLEPROC glad_glGetColorTable; -PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv; -PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv; -PFNGLCOLORSUBTABLEPROC glad_glColorSubTable; -PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable; -PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D; -PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D; -PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf; -PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv; -PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri; -PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv; -PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D; -PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D; -PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter; -PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv; -PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv; -PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter; -PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D; -PFNGLGETHISTOGRAMPROC glad_glGetHistogram; -PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv; -PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv; -PFNGLGETMINMAXPROC glad_glGetMinmax; -PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv; -PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv; -PFNGLHISTOGRAMPROC glad_glHistogram; -PFNGLMINMAXPROC glad_glMinmax; -PFNGLRESETHISTOGRAMPROC glad_glResetHistogram; -PFNGLRESETMINMAXPROC glad_glResetMinmax; -PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB; -PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB; -PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB; -PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; -PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; -PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; -PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; -PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; -PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; -PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; -PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; -PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB; -PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB; -PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB; -PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB; -PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB; -PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; -PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; -PFNGLBINDTEXTURESPROC glad_glBindTextures; -PFNGLBINDSAMPLERSPROC glad_glBindSamplers; -PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; -PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; -PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; -PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; -PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; -PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB; -PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB; -PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB; -PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB; -PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB; -PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB; -PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB; -PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB; -PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB; -PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB; -PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB; -PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB; -PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB; -PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB; -PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB; -PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB; -PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB; -PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB; -PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB; -PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB; -PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB; -PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB; -PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB; -PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB; -PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB; -PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB; -PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB; -PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB; -PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB; -PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB; -PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB; -PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB; -PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB; -PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB; -PFNGLGENQUERIESARBPROC glad_glGenQueriesARB; -PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB; -PFNGLISQUERYARBPROC glad_glIsQueryARB; -PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB; -PFNGLENDQUERYARBPROC glad_glEndQueryARB; -PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB; -PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB; -PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB; -PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB; -PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB; -PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB; -PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; -PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; -PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; -PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; -PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; -PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; -PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; -PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; -PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; -PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; -PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; -PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; -PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; -PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; -PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; -PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; -PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; -PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; -PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; -PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; -PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; -PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; -PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; -PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; -PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; -PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; -PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; -PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB; -PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB; -PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB; -PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB; -PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; -PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; -PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; -PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; -PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; -PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; -PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; -PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; -PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; -PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; -PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; -PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; -PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; -PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; -PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; -PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; -PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; -PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; -PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; -PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; -PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; -PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; -PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; -PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; -PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; -PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; -PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; -PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; -PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; -PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; -PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; -PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; -PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; -PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; -PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; -PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; -PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; -PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; -PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; -PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; -PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; -PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; -PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; -PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; -PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; -PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; -PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; -PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; -PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; -PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; -PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; -PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; -PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; -PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; -PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; -PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; -PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; -PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; -PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; -PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; -PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; -PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; -PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; -PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB; -PFNGLGETHANDLEARBPROC glad_glGetHandleARB; -PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB; -PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB; -PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB; -PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB; -PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB; -PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB; -PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB; -PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB; -PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB; -PFNGLUNIFORM1FARBPROC glad_glUniform1fARB; -PFNGLUNIFORM2FARBPROC glad_glUniform2fARB; -PFNGLUNIFORM3FARBPROC glad_glUniform3fARB; -PFNGLUNIFORM4FARBPROC glad_glUniform4fARB; -PFNGLUNIFORM1IARBPROC glad_glUniform1iARB; -PFNGLUNIFORM2IARBPROC glad_glUniform2iARB; -PFNGLUNIFORM3IARBPROC glad_glUniform3iARB; -PFNGLUNIFORM4IARBPROC glad_glUniform4iARB; -PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB; -PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB; -PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB; -PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB; -PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB; -PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB; -PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB; -PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB; -PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB; -PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB; -PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB; -PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB; -PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB; -PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB; -PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB; -PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB; -PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB; -PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB; -PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB; -PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB; -PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; -PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; -PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; -PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; -PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; -PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; -PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; -PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; -PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; -PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB; -PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB; -PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB; -PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB; -PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB; -PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB; -PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB; -PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT; -PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB; -PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB; -PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; -PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; -PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; -PFNGLTEXBUFFERARBPROC glad_glTexBufferARB; -PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; -PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB; -PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB; -PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB; -PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB; -PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB; -PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB; -PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB; -PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; -PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; -PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; -PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; -PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; -PFNGLTEXTUREVIEWPROC glad_glTextureView; -PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; -PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; -PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; -PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; -PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; -PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; -PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; -PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; -PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; -PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; -PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; -PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB; -PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB; -PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB; -PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB; -PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; -PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; -PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; -PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; -PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; -PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; -PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; -PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; -PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; -PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; -PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; -PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; -PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; -PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; -PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; -PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; -PFNGLWEIGHTBVARBPROC glad_glWeightbvARB; -PFNGLWEIGHTSVARBPROC glad_glWeightsvARB; -PFNGLWEIGHTIVARBPROC glad_glWeightivARB; -PFNGLWEIGHTFVARBPROC glad_glWeightfvARB; -PFNGLWEIGHTDVARBPROC glad_glWeightdvARB; -PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB; -PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB; -PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB; -PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB; -PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB; -PFNGLBINDBUFFERARBPROC glad_glBindBufferARB; -PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB; -PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB; -PFNGLISBUFFERARBPROC glad_glIsBufferARB; -PFNGLBUFFERDATAARBPROC glad_glBufferDataARB; -PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB; -PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB; -PFNGLMAPBUFFERARBPROC glad_glMapBufferARB; -PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB; -PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB; -PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB; -PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB; -PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB; -PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB; -PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB; -PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB; -PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB; -PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB; -PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB; -PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB; -PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB; -PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB; -PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB; -PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB; -PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB; -PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB; -PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB; -PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB; -PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB; -PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB; -PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB; -PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB; -PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB; -PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB; -PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB; -PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB; -PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB; -PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB; -PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB; -PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB; -PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB; -PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB; -PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB; -PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB; -PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB; -PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB; -PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB; -PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB; -PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB; -PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB; -PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB; -PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB; -PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB; -PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB; -PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB; -PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB; -PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB; -PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; -PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; -PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; -PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; -PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; -PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; -PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; -PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; -PFNGLGETFLOATI_VPROC glad_glGetFloati_v; -PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; -PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB; -PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB; -PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB; -PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB; -PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB; -PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB; -PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB; -PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB; -PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB; -PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB; -PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB; -PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB; -PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB; -PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB; -PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB; -PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB; -PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI; -PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI; -PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI; -PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI; -PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI; -PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI; -PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI; -PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI; -PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI; -PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI; -PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI; -PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI; -PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI; -PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI; -PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI; -PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI; -PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI; -PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI; -PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI; -PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI; -PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI; -PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI; -PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI; -PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI; -PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI; -PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI; -PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI; -PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI; -PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI; -PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI; -PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI; -PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI; -PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI; -PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI; -PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI; -PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI; -PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI; -PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI; -PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI; -PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI; -PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI; -PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI; -PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI; -PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI; -PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI; -PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI; -PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI; -PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI; -PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI; -PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI; -PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI; -PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI; -PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI; -PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI; -PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI; -PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI; -PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI; -PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI; -PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI; -PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI; -PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI; -PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI; -PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI; -PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI; -PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI; -PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI; -PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI; -PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI; -PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI; -PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI; -PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI; -PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI; -PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI; -PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI; -PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI; -PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI; -PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI; -PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI; -PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI; -PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI; -PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI; -PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI; -PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI; -PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI; -PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI; -PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI; -PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI; -PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI; -PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT; -PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT; -PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT; -PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT; -PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT; -PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT; -PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT; -PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT; -PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT; -PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT; -PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT; -PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT; -PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT; -PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT; -PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT; -PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT; -PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT; -PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT; -PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT; -PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT; -PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT; -PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT; -PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT; -PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT; -PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT; -PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT; -PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT; -PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT; -PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT; -PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT; -PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT; -PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT; -PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT; -PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT; -PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT; -PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT; -PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT; -PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT; -PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT; -PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT; -PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT; -PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT; -PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT; -PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT; -PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT; -PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT; -PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT; -PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT; -PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT; -PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT; -PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT; -PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT; -PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT; -PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT; -PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT; -PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT; -PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT; -PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT; -PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT; -PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT; -PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT; -PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT; -PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT; -PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT; -PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT; -PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT; -PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT; -PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT; -PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT; -PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT; -PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT; -PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT; -PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT; -PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT; -PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT; -PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT; -PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT; -PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT; -PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT; -PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT; -PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT; -PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT; -PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT; -PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT; -PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT; -PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT; -PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT; -PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT; -PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT; -PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT; -PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT; -PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT; -PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT; -PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT; -PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT; -PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT; -PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT; -PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT; -PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT; -PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT; -PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT; -PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT; -PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT; -PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT; -PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT; -PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT; -PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT; -PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT; -PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT; -PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT; -PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT; -PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT; -PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT; -PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT; -PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT; -PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT; -PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT; -PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT; -PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT; -PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT; -PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT; -PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT; -PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT; -PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT; -PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT; -PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT; -PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT; -PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT; -PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT; -PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT; -PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT; -PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT; -PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT; -PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT; -PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT; -PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT; -PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT; -PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT; -PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT; -PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT; -PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT; -PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT; -PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT; -PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT; -PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT; -PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT; -PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT; -PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT; -PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT; -PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT; -PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT; -PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT; -PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT; -PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT; -PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT; -PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT; -PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT; -PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT; -PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT; -PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT; -PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT; -PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT; -PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT; -PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT; -PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT; -PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT; -PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT; -PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT; -PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT; -PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT; -PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT; -PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT; -PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT; -PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT; -PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT; -PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT; -PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT; -PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT; -PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT; -PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT; -PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT; -PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT; -PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT; -PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT; -PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT; -PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT; -PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT; -PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT; -PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT; -PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT; -PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT; -PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT; -PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT; -PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT; -PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT; -PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT; -PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT; -PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT; -PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT; -PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT; -PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT; -PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT; -PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT; -PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT; -PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT; -PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT; -PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT; -PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT; -PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT; -PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT; -PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT; -PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT; -PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT; -PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT; -PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT; -PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT; -PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT; -PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT; -PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT; -PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT; -PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT; -PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT; -PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT; -PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT; -PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT; -PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT; -PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT; -PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT; -PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT; -PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT; -PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT; -PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT; -PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT; -PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT; -PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT; -PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT; -PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT; -PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT; -PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT; -PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT; -PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT; -PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT; -PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT; -PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT; -PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT; -PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT; -PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT; -PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT; -PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT; -PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT; -PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT; -PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT; -PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT; -PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT; -PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT; -PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT; -PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT; -PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT; -PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT; -PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT; -PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT; -PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT; -PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT; -PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT; -PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT; -PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT; -PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT; -PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT; -PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT; -PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT; -PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT; -PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT; -PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT; -PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT; -PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT; -PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT; -PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT; -PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT; -PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT; -PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT; -PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT; -PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT; -PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT; -PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT; -PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT; -PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT; -PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT; -PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT; -PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT; -PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT; -PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT; -PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT; -PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT; -PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT; -PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT; -PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT; -PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT; -PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT; -PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT; -PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT; -PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT; -PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT; -PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT; -PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT; -PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT; -PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT; -PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT; -PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT; -PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT; -PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT; -PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; -PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; -PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; -PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; -PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; -PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; -PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; -PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; -PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; -PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; -PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; -PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; -PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; -PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; -PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT; -PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT; -PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT; -PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT; -PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT; -PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT; -PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT; -PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT; -PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT; -PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT; -PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT; -PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT; -PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT; -PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT; -PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT; -PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT; -PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT; -PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT; -PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT; -PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT; -PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT; -PFNGLMINMAXEXTPROC glad_glMinmaxEXT; -PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT; -PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT; -PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT; -PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT; -PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT; -PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT; -PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT; -PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT; -PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT; -PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT; -PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT; -PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT; -PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT; -PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT; -PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT; -PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT; -PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT; -PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT; -PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT; -PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT; -PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT; -PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT; -PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT; -PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT; -PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT; -PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT; -PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT; -PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT; -PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT; -PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT; -PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT; -PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT; -PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT; -PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT; -PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT; -PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT; -PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT; -PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT; -PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT; -PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT; -PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT; -PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT; -PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT; -PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT; -PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT; -PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT; -PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT; -PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT; -PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT; -PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT; -PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT; -PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT; -PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT; -PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT; -PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT; -PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT; -PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT; -PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT; -PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT; -PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT; -PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT; -PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT; -PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT; -PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT; -PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT; -PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT; -PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT; -PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT; -PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT; -PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT; -PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT; -PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT; -PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT; -PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT; -PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT; -PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT; -PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT; -PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT; -PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT; -PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT; -PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT; -PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT; -PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT; -PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT; -PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT; -PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT; -PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT; -PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT; -PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT; -PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT; -PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT; -PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT; -PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT; -PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT; -PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT; -PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT; -PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT; -PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT; -PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT; -PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT; -PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT; -PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT; -PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT; -PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT; -PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT; -PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT; -PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT; -PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT; -PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT; -PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT; -PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT; -PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT; -PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT; -PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT; -PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT; -PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT; -PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT; -PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT; -PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT; -PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT; -PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT; -PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT; -PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT; -PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT; -PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT; -PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT; -PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT; -PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT; -PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT; -PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT; -PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT; -PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT; -PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT; -PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT; -PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT; -PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT; -PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT; -PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT; -PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT; -PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT; -PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT; -PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT; -PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT; -PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT; -PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT; -PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT; -PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT; -PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT; -PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT; -PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT; -PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT; -PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT; -PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT; -PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT; -PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT; -PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT; -PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT; -PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT; -PFNGLVARIANTIVEXTPROC glad_glVariantivEXT; -PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT; -PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT; -PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT; -PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT; -PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT; -PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT; -PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT; -PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT; -PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT; -PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT; -PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT; -PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT; -PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT; -PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT; -PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT; -PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT; -PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT; -PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT; -PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT; -PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT; -PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT; -PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT; -PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT; -PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT; -PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT; -PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT; -PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT; -PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT; -PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT; -PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT; -PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT; -PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY; -PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY; -PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP; -PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP; -PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP; -PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP; -PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP; -PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP; -PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM; -PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM; -PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM; -PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM; -PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM; -PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM; -PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM; -PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM; -PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM; -PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM; -PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM; -PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR; -PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL; -PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL; -PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL; -PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL; -PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL; -PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL; -PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL; -PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL; -PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL; -PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL; -PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL; -PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL; -PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL; -PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL; -PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL; -PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL; -PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL; -PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL; -PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; -PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; -PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; -PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; -PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; -PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; -PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; -PFNGLOBJECTLABELPROC glad_glObjectLabel; -PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; -PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; -PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; -PFNGLGETPOINTERVPROC glad_glGetPointerv; -PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; -PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; -PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; -PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; -PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; -PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; -PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; -PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; -PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; -PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; -PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; -PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR; -PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; -PFNGLREADNPIXELSPROC glad_glReadnPixels; -PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; -PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; -PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; -PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR; -PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR; -PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR; -PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR; -PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR; -PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA; -PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA; -PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA; -PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA; -PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA; -PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA; -PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA; -PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA; -PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA; -PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA; -PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA; -PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA; -PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA; -PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA; -PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA; -PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA; -PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA; -PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA; -PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA; -PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA; -PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA; -PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA; -PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA; -PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA; -PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA; -PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX; -PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX; -PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX; -PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX; -PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX; -PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV; -PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV; -PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV; -PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV; -PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV; -PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV; -PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV; -PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV; -PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV; -PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV; -PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV; -PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV; -PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV; -PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV; -PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV; -PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV; -PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV; -PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV; -PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV; -PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV; -PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV; -PFNGLCREATESTATESNVPROC glad_glCreateStatesNV; -PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV; -PFNGLISSTATENVPROC glad_glIsStateNV; -PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV; -PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV; -PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV; -PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV; -PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV; -PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV; -PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV; -PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV; -PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV; -PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV; -PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV; -PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV; -PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV; -PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV; -PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV; -PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV; -PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV; -PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV; -PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV; -PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV; -PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV; -PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV; -PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV; -PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV; -PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV; -PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV; -PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV; -PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV; -PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV; -PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV; -PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV; -PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV; -PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV; -PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV; -PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV; -PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV; -PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV; -PFNGLEVALMAPSNVPROC glad_glEvalMapsNV; -PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV; -PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV; -PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV; -PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV; -PFNGLGENFENCESNVPROC glad_glGenFencesNV; -PFNGLISFENCENVPROC glad_glIsFenceNV; -PFNGLTESTFENCENVPROC glad_glTestFenceNV; -PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV; -PFNGLFINISHFENCENVPROC glad_glFinishFenceNV; -PFNGLSETFENCENVPROC glad_glSetFenceNV; -PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV; -PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV; -PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV; -PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV; -PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV; -PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV; -PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV; -PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV; -PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV; -PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV; -PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV; -PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT; -PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT; -PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV; -PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV; -PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV; -PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV; -PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV; -PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV; -PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV; -PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV; -PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV; -PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV; -PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV; -PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV; -PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV; -PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV; -PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV; -PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV; -PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV; -PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV; -PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV; -PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV; -PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV; -PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV; -PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV; -PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV; -PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV; -PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV; -PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV; -PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV; -PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV; -PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV; -PFNGLVERTEX2HNVPROC glad_glVertex2hNV; -PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV; -PFNGLVERTEX3HNVPROC glad_glVertex3hNV; -PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV; -PFNGLVERTEX4HNVPROC glad_glVertex4hNV; -PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV; -PFNGLNORMAL3HNVPROC glad_glNormal3hNV; -PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV; -PFNGLCOLOR3HNVPROC glad_glColor3hNV; -PFNGLCOLOR3HVNVPROC glad_glColor3hvNV; -PFNGLCOLOR4HNVPROC glad_glColor4hNV; -PFNGLCOLOR4HVNVPROC glad_glColor4hvNV; -PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV; -PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV; -PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV; -PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV; -PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV; -PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV; -PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV; -PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV; -PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV; -PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV; -PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV; -PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV; -PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV; -PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV; -PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV; -PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV; -PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV; -PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV; -PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV; -PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV; -PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV; -PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV; -PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV; -PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV; -PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV; -PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV; -PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV; -PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV; -PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV; -PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV; -PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV; -PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV; -PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV; -PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV; -PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV; -PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV; -PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV; -PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV; -PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV; -PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV; -PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV; -PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV; -PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV; -PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV; -PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV; -PFNGLGENPATHSNVPROC glad_glGenPathsNV; -PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV; -PFNGLISPATHNVPROC glad_glIsPathNV; -PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV; -PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV; -PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV; -PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV; -PFNGLPATHSTRINGNVPROC glad_glPathStringNV; -PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV; -PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV; -PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV; -PFNGLCOPYPATHNVPROC glad_glCopyPathNV; -PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV; -PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV; -PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV; -PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV; -PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV; -PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV; -PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV; -PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV; -PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV; -PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV; -PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV; -PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV; -PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV; -PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV; -PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV; -PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV; -PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV; -PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV; -PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV; -PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV; -PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV; -PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV; -PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV; -PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV; -PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV; -PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV; -PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV; -PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV; -PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV; -PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV; -PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV; -PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV; -PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV; -PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV; -PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV; -PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV; -PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV; -PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV; -PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV; -PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV; -PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV; -PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV; -PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV; -PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV; -PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV; -PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV; -PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV; -PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV; -PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV; -PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV; -PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV; -PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV; -PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV; -PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV; -PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV; -PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV; -PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV; -PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV; -PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV; -PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV; -PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV; -PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV; -PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV; -PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV; -PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV; -PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV; -PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV; -PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV; -PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV; -PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV; -PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV; -PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV; -PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV; -PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV; -PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV; -PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV; -PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV; -PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV; -PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV; -PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV; -PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV; -PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV; -PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV; -PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV; -PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV; -PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV; -PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV; -PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV; -PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV; -PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV; -PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV; -PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV; -PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV; -PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV; -PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV; -PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV; -PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV; -PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV; -PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV; -PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV; -PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV; -PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV; -PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV; -PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV; -PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV; -PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV; -PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV; -PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV; -PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV; -PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV; -PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV; -PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV; -PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV; -PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV; -PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV; -PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV; -PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV; -PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV; -PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV; -PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV; -PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV; -PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV; -PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV; -PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV; -PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV; -PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV; -PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV; -PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV; -PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV; -PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV; -PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV; -PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV; -PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV; -PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV; -PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV; -PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV; -PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV; -PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV; -PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV; -PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV; -PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV; -PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV; -PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV; -PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV; -PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV; -PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV; -PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV; -PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV; -PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV; -PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV; -PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV; -PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV; -PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV; -PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV; -PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV; -PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV; -PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV; -PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV; -PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV; -PFNGLCOLORFORMATNVPROC glad_glColorFormatNV; -PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV; -PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV; -PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV; -PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV; -PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV; -PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV; -PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV; -PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV; -PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV; -PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV; -PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV; -PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV; -PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV; -PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV; -PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV; -PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV; -PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV; -PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV; -PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV; -PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV; -PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV; -PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV; -PFNGLISPROGRAMNVPROC glad_glIsProgramNV; -PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV; -PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV; -PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV; -PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV; -PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV; -PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV; -PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV; -PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV; -PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV; -PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV; -PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV; -PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV; -PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV; -PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV; -PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV; -PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV; -PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV; -PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV; -PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV; -PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV; -PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV; -PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV; -PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV; -PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV; -PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV; -PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV; -PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV; -PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV; -PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV; -PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV; -PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV; -PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV; -PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV; -PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV; -PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV; -PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV; -PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV; -PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV; -PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV; -PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV; -PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV; -PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV; -PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV; -PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV; -PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV; -PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV; -PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV; -PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV; -PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV; -PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT; -PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT; -PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT; -PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT; -PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT; -PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT; -PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT; -PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT; -PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT; -PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT; -PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT; -PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT; -PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT; -PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT; -PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT; -PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT; -PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT; -PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT; -PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT; -PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT; -PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT; -PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT; -PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT; -PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV; -PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV; -PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV; -PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV; -PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV; -PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV; -PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV; -PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV; -PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV; -PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV; -PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV; -PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV; -PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV; -PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES; -PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES; -PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES; -PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES; -PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES; -PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES; -PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES; -PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES; -PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES; -PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES; -PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES; -PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES; -PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES; -PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES; -PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES; -PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES; -PFNGLVERTEX2BOESPROC glad_glVertex2bOES; -PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES; -PFNGLVERTEX3BOESPROC glad_glVertex3bOES; -PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES; -PFNGLVERTEX4BOESPROC glad_glVertex4bOES; -PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES; -PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES; -PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES; -PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES; -PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES; -PFNGLCOLOR4XOESPROC glad_glColor4xOES; -PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES; -PFNGLFOGXOESPROC glad_glFogxOES; -PFNGLFOGXVOESPROC glad_glFogxvOES; -PFNGLFRUSTUMXOESPROC glad_glFrustumxOES; -PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES; -PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES; -PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES; -PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES; -PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES; -PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES; -PFNGLLIGHTXOESPROC glad_glLightxOES; -PFNGLLIGHTXVOESPROC glad_glLightxvOES; -PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES; -PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES; -PFNGLMATERIALXOESPROC glad_glMaterialxOES; -PFNGLMATERIALXVOESPROC glad_glMaterialxvOES; -PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES; -PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES; -PFNGLNORMAL3XOESPROC glad_glNormal3xOES; -PFNGLORTHOXOESPROC glad_glOrthoxOES; -PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES; -PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES; -PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES; -PFNGLROTATEXOESPROC glad_glRotatexOES; -PFNGLSCALEXOESPROC glad_glScalexOES; -PFNGLTEXENVXOESPROC glad_glTexEnvxOES; -PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES; -PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES; -PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES; -PFNGLTRANSLATEXOESPROC glad_glTranslatexOES; -PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES; -PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES; -PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES; -PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES; -PFNGLACCUMXOESPROC glad_glAccumxOES; -PFNGLBITMAPXOESPROC glad_glBitmapxOES; -PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES; -PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES; -PFNGLCOLOR3XOESPROC glad_glColor3xOES; -PFNGLCOLOR3XVOESPROC glad_glColor3xvOES; -PFNGLCOLOR4XVOESPROC glad_glColor4xvOES; -PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES; -PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES; -PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES; -PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES; -PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES; -PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES; -PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES; -PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES; -PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES; -PFNGLGETLIGHTXOESPROC glad_glGetLightxOES; -PFNGLGETMAPXVOESPROC glad_glGetMapxvOES; -PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES; -PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv; -PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES; -PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES; -PFNGLINDEXXOESPROC glad_glIndexxOES; -PFNGLINDEXXVOESPROC glad_glIndexxvOES; -PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES; -PFNGLMAP1XOESPROC glad_glMap1xOES; -PFNGLMAP2XOESPROC glad_glMap2xOES; -PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES; -PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES; -PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES; -PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES; -PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES; -PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES; -PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES; -PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES; -PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES; -PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES; -PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES; -PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES; -PFNGLPIXELMAPXPROC glad_glPixelMapx; -PFNGLPIXELSTOREXPROC glad_glPixelStorex; -PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES; -PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES; -PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES; -PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES; -PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES; -PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES; -PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES; -PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES; -PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES; -PFNGLRECTXOESPROC glad_glRectxOES; -PFNGLRECTXVOESPROC glad_glRectxvOES; -PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES; -PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES; -PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES; -PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES; -PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES; -PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES; -PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES; -PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES; -PFNGLTEXGENXOESPROC glad_glTexGenxOES; -PFNGLTEXGENXVOESPROC glad_glTexGenxvOES; -PFNGLVERTEX2XOESPROC glad_glVertex2xOES; -PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES; -PFNGLVERTEX3XOESPROC glad_glVertex3xOES; -PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES; -PFNGLVERTEX4XOESPROC glad_glVertex4xOES; -PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES; -PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES; -PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES; -PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES; -PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES; -PFNGLFRUSTUMFOESPROC glad_glFrustumfOES; -PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES; -PFNGLORTHOFOESPROC glad_glOrthofOES; -PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; -PFNGLHINTPGIPROC glad_glHintPGI; -PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS; -PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS; -PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS; -PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS; -PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS; -PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS; -PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS; -PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS; -PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS; -PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS; -PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS; -PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS; -PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS; -PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS; -PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS; -PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS; -PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS; -PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS; -PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS; -PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS; -PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS; -PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX; -PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX; -PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX; -PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX; -PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX; -PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX; -PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX; -PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX; -PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX; -PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX; -PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX; -PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX; -PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX; -PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX; -PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX; -PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX; -PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX; -PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX; -PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX; -PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX; -PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX; -PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX; -PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX; -PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX; -PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX; -PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX; -PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX; -PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX; -PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX; -PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX; -PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX; -PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX; -PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX; -PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX; -PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX; -PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX; -PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX; -PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX; -PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX; -PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX; -PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX; -PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX; -PFNGLDEFORMSGIXPROC glad_glDeformSGIX; -PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX; -PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX; -PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX; -PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX; -PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX; -PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX; -PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX; -PFNGLCOLORTABLESGIPROC glad_glColorTableSGI; -PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI; -PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI; -PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI; -PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI; -PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI; -PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI; -PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX; -PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN; -PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN; -PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN; -PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN; -PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN; -PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN; -PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN; -PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN; -PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN; -PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN; -PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN; -PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN; -PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN; -PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN; -PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN; -PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN; -PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN; -PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN; -PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN; -PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN; -PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN; -PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN; -PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN; -PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN; -PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN; -PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN; -PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN; -PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN; -PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN; -PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN; -PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN; -PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN; -PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN; -PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN; -PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN; -PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN; -PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN; -PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN; -PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN; -PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN; -PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN; -PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN; -PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN; -PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN; -PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN; -PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN; -PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN; -PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN; -PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN; -PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; -PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +int GLAD_GL_VERSION_1_0 = 0; +int GLAD_GL_VERSION_1_1 = 0; +int GLAD_GL_VERSION_1_2 = 0; +int GLAD_GL_VERSION_1_3 = 0; +int GLAD_GL_VERSION_1_4 = 0; +int GLAD_GL_VERSION_1_5 = 0; +int GLAD_GL_VERSION_2_0 = 0; +int GLAD_GL_VERSION_2_1 = 0; +int GLAD_GL_VERSION_3_0 = 0; +int GLAD_GL_VERSION_3_1 = 0; +int GLAD_GL_VERSION_3_2 = 0; +int GLAD_GL_VERSION_3_3 = 0; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; +PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; +PFNGLENABLEIPROC glad_glEnablei = NULL; +PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLPOINTSIZEPROC glad_glPointSize = NULL; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; +PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; +PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; +PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; +PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; +PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; +PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; +PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; +PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; +PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLLOGICOPPROC glad_glLogicOp = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; +PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; +PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; +PFNGLDISABLEIPROC glad_glDisablei = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; +PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; +PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +int GLAD_GL_SGIX_pixel_tiles = 0; +int GLAD_GL_EXT_post_depth_coverage = 0; +int GLAD_GL_APPLE_element_array = 0; +int GLAD_GL_AMD_multi_draw_indirect = 0; +int GLAD_GL_EXT_blend_subtract = 0; +int GLAD_GL_SGIX_tag_sample_buffer = 0; +int GLAD_GL_NV_point_sprite = 0; +int GLAD_GL_IBM_texture_mirrored_repeat = 0; +int GLAD_GL_APPLE_transform_hint = 0; +int GLAD_GL_ATI_separate_stencil = 0; +int GLAD_GL_NV_shader_atomic_int64 = 0; +int GLAD_GL_EXT_semaphore_win32 = 0; +int GLAD_GL_NV_vertex_program2_option = 0; +int GLAD_GL_EXT_texture_buffer_object = 0; +int GLAD_GL_ARB_vertex_blend = 0; +int GLAD_GL_OVR_multiview = 0; +int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = 0; +int GLAD_GL_NV_vertex_program2 = 0; +int GLAD_GL_ARB_program_interface_query = 0; +int GLAD_GL_EXT_misc_attribute = 0; +int GLAD_GL_NV_multisample_coverage = 0; +int GLAD_GL_ARB_shading_language_packing = 0; +int GLAD_GL_EXT_texture_cube_map = 0; +int GLAD_GL_NV_viewport_array2 = 0; +int GLAD_GL_ARB_texture_stencil8 = 0; +int GLAD_GL_EXT_index_func = 0; +int GLAD_GL_EXT_memory_object_fd = 0; +int GLAD_GL_OES_compressed_paletted_texture = 0; +int GLAD_GL_MESA_shader_integer_functions = 0; +int GLAD_GL_NV_shader_buffer_load = 0; +int GLAD_GL_EXT_color_subtable = 0; +int GLAD_GL_SUNX_constant_data = 0; +int GLAD_GL_EXT_texture_compression_s3tc = 0; +int GLAD_GL_EXT_multi_draw_arrays = 0; +int GLAD_GL_ARB_shader_atomic_counters = 0; +int GLAD_GL_ARB_arrays_of_arrays = 0; +int GLAD_GL_NV_conditional_render = 0; +int GLAD_GL_EXT_texture_env_combine = 0; +int GLAD_GL_NV_fog_distance = 0; +int GLAD_GL_SGIX_async_histogram = 0; +int GLAD_GL_MESA_resize_buffers = 0; +int GLAD_GL_NV_light_max_exponent = 0; +int GLAD_GL_NV_texture_env_combine4 = 0; +int GLAD_GL_ARB_spirv_extensions = 0; +int GLAD_GL_ARB_texture_view = 0; +int GLAD_GL_ARB_texture_env_combine = 0; +int GLAD_GL_ARB_map_buffer_range = 0; +int GLAD_GL_EXT_convolution = 0; +int GLAD_GL_NV_compute_program5 = 0; +int GLAD_GL_NV_vertex_attrib_integer_64bit = 0; +int GLAD_GL_EXT_paletted_texture = 0; +int GLAD_GL_ARB_texture_buffer_object = 0; +int GLAD_GL_ATI_pn_triangles = 0; +int GLAD_GL_SGIX_resample = 0; +int GLAD_GL_SGIX_flush_raster = 0; +int GLAD_GL_EXT_light_texture = 0; +int GLAD_GL_ARB_point_sprite = 0; +int GLAD_GL_SUN_convolution_border_modes = 0; +int GLAD_GL_EXT_semaphore_fd = 0; +int GLAD_GL_NV_parameter_buffer_object2 = 0; +int GLAD_GL_ARB_half_float_pixel = 0; +int GLAD_GL_NV_tessellation_program5 = 0; +int GLAD_GL_REND_screen_coordinates = 0; +int GLAD_GL_EXT_shared_texture_palette = 0; +int GLAD_GL_EXT_packed_float = 0; +int GLAD_GL_OML_subsample = 0; +int GLAD_GL_SGIX_vertex_preclip = 0; +int GLAD_GL_SGIX_texture_scale_bias = 0; +int GLAD_GL_AMD_draw_buffers_blend = 0; +int GLAD_GL_APPLE_texture_range = 0; +int GLAD_GL_EXT_texture_array = 0; +int GLAD_GL_NV_texture_barrier = 0; +int GLAD_GL_ARB_texture_query_levels = 0; +int GLAD_GL_NV_texgen_emboss = 0; +int GLAD_GL_EXT_texture_swizzle = 0; +int GLAD_GL_ARB_texture_rg = 0; +int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0; +int GLAD_GL_ARB_fragment_shader = 0; +int GLAD_GL_3DFX_tbuffer = 0; +int GLAD_GL_GREMEDY_frame_terminator = 0; +int GLAD_GL_IBM_cull_vertex = 0; +int GLAD_GL_EXT_separate_shader_objects = 0; +int GLAD_GL_NV_texture_multisample = 0; +int GLAD_GL_ARB_shader_objects = 0; +int GLAD_GL_ARB_framebuffer_object = 0; +int GLAD_GL_EXT_external_buffer = 0; +int GLAD_GL_ATI_envmap_bumpmap = 0; +int GLAD_GL_AMD_shader_explicit_vertex_parameter = 0; +int GLAD_GL_ARB_robust_buffer_access_behavior = 0; +int GLAD_GL_ARB_shader_stencil_export = 0; +int GLAD_GL_NV_texture_rectangle = 0; +int GLAD_GL_ARB_enhanced_layouts = 0; +int GLAD_GL_ARB_texture_rectangle = 0; +int GLAD_GL_SGI_texture_color_table = 0; +int GLAD_GL_NV_viewport_swizzle = 0; +int GLAD_GL_ATI_map_object_buffer = 0; +int GLAD_GL_ARB_robustness = 0; +int GLAD_GL_NV_pixel_data_range = 0; +int GLAD_GL_EXT_framebuffer_blit = 0; +int GLAD_GL_ARB_gpu_shader_fp64 = 0; +int GLAD_GL_NV_command_list = 0; +int GLAD_GL_SGIX_depth_texture = 0; +int GLAD_GL_AMD_framebuffer_sample_positions = 0; +int GLAD_GL_GREMEDY_string_marker = 0; +int GLAD_GL_ARB_texture_compression_bptc = 0; +int GLAD_GL_EXT_subtexture = 0; +int GLAD_GL_EXT_pixel_transform_color_table = 0; +int GLAD_GL_EXT_texture_compression_rgtc = 0; +int GLAD_GL_ARB_shader_atomic_counter_ops = 0; +int GLAD_GL_SGIX_depth_pass_instrument = 0; +int GLAD_GL_EXT_gpu_program_parameters = 0; +int GLAD_GL_NV_evaluators = 0; +int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = 0; +int GLAD_GL_SGIS_texture_filter4 = 0; +int GLAD_GL_AMD_performance_monitor = 0; +int GLAD_GL_NV_geometry_shader4 = 0; +int GLAD_GL_EXT_stencil_clear_tag = 0; +int GLAD_GL_NV_vertex_program1_1 = 0; +int GLAD_GL_NV_present_video = 0; +int GLAD_GL_ARB_texture_compression_rgtc = 0; +int GLAD_GL_HP_convolution_border_modes = 0; +int GLAD_GL_EXT_shader_integer_mix = 0; +int GLAD_GL_SGIX_framezoom = 0; +int GLAD_GL_ARB_stencil_texturing = 0; +int GLAD_GL_ARB_shader_clock = 0; +int GLAD_GL_NV_shader_atomic_fp16_vector = 0; +int GLAD_GL_SGIX_fog_offset = 0; +int GLAD_GL_ARB_draw_elements_base_vertex = 0; +int GLAD_GL_INGR_interlace_read = 0; +int GLAD_GL_NV_transform_feedback = 0; +int GLAD_GL_NV_fragment_program = 0; +int GLAD_GL_AMD_stencil_operation_extended = 0; +int GLAD_GL_ARB_seamless_cubemap_per_texture = 0; +int GLAD_GL_ARB_instanced_arrays = 0; +int GLAD_GL_ARB_get_texture_sub_image = 0; +int GLAD_GL_NV_vertex_array_range2 = 0; +int GLAD_GL_KHR_robustness = 0; +int GLAD_GL_AMD_sparse_texture = 0; +int GLAD_GL_ARB_clip_control = 0; +int GLAD_GL_NV_fragment_coverage_to_color = 0; +int GLAD_GL_NV_fence = 0; +int GLAD_GL_ARB_texture_buffer_range = 0; +int GLAD_GL_SUN_mesh_array = 0; +int GLAD_GL_ARB_vertex_attrib_binding = 0; +int GLAD_GL_ARB_framebuffer_no_attachments = 0; +int GLAD_GL_ARB_cl_event = 0; +int GLAD_GL_EXT_vertex_weighting = 0; +int GLAD_GL_ARB_derivative_control = 0; +int GLAD_GL_NV_packed_depth_stencil = 0; +int GLAD_GL_OES_single_precision = 0; +int GLAD_GL_NV_primitive_restart = 0; +int GLAD_GL_SUN_global_alpha = 0; +int GLAD_GL_ARB_fragment_shader_interlock = 0; +int GLAD_GL_EXT_texture_object = 0; +int GLAD_GL_AMD_name_gen_delete = 0; +int GLAD_GL_NV_texture_compression_vtc = 0; +int GLAD_GL_NV_sample_mask_override_coverage = 0; +int GLAD_GL_NV_texture_shader3 = 0; +int GLAD_GL_MESA_tile_raster_order = 0; +int GLAD_GL_ARB_texture_filter_anisotropic = 0; +int GLAD_GL_EXT_texture = 0; +int GLAD_GL_ARB_buffer_storage = 0; +int GLAD_GL_AMD_shader_atomic_counter_ops = 0; +int GLAD_GL_APPLE_vertex_program_evaluators = 0; +int GLAD_GL_AMD_texture_gather_bias_lod = 0; +int GLAD_GL_NV_texgen_reflection = 0; +int GLAD_GL_ARB_explicit_uniform_location = 0; +int GLAD_GL_ARB_depth_buffer_float = 0; +int GLAD_GL_NV_path_rendering_shared_edge = 0; +int GLAD_GL_SGIX_shadow_ambient = 0; +int GLAD_GL_ARB_texture_cube_map = 0; +int GLAD_GL_AMD_vertex_shader_viewport_index = 0; +int GLAD_GL_SGIX_list_priority = 0; +int GLAD_GL_NV_vertex_buffer_unified_memory = 0; +int GLAD_GL_NV_uniform_buffer_unified_memory = 0; +int GLAD_GL_ARB_clear_texture = 0; +int GLAD_GL_ATI_texture_env_combine3 = 0; +int GLAD_GL_NV_depth_clamp = 0; +int GLAD_GL_ARB_map_buffer_alignment = 0; +int GLAD_GL_EXT_memory_object = 0; +int GLAD_GL_NV_blend_equation_advanced = 0; +int GLAD_GL_SGIS_sharpen_texture = 0; +int GLAD_GL_KHR_robust_buffer_access_behavior = 0; +int GLAD_GL_ARB_pipeline_statistics_query = 0; +int GLAD_GL_ARB_vertex_program = 0; +int GLAD_GL_ARB_texture_rgb10_a2ui = 0; +int GLAD_GL_OML_interlace = 0; +int GLAD_GL_ATI_pixel_format_float = 0; +int GLAD_GL_NV_clip_space_w_scaling = 0; +int GLAD_GL_ARB_vertex_buffer_object = 0; +int GLAD_GL_EXT_shadow_funcs = 0; +int GLAD_GL_ATI_text_fragment_shader = 0; +int GLAD_GL_NV_vertex_array_range = 0; +int GLAD_GL_SGIX_fragment_lighting = 0; +int GLAD_GL_AMD_shader_ballot = 0; +int GLAD_GL_NV_texture_expand_normal = 0; +int GLAD_GL_NV_framebuffer_multisample_coverage = 0; +int GLAD_GL_EXT_timer_query = 0; +int GLAD_GL_EXT_vertex_array_bgra = 0; +int GLAD_GL_NV_bindless_texture = 0; +int GLAD_GL_KHR_debug = 0; +int GLAD_GL_SGIS_texture_border_clamp = 0; +int GLAD_GL_ATI_vertex_attrib_array_object = 0; +int GLAD_GL_SGIX_clipmap = 0; +int GLAD_GL_EXT_geometry_shader4 = 0; +int GLAD_GL_ARB_shader_texture_image_samples = 0; +int GLAD_GL_MESA_ycbcr_texture = 0; +int GLAD_GL_MESAX_texture_stack = 0; +int GLAD_GL_AMD_seamless_cubemap_per_texture = 0; +int GLAD_GL_EXT_bindable_uniform = 0; +int GLAD_GL_KHR_texture_compression_astc_hdr = 0; +int GLAD_GL_ARB_shader_ballot = 0; +int GLAD_GL_KHR_blend_equation_advanced = 0; +int GLAD_GL_ARB_fragment_program_shadow = 0; +int GLAD_GL_ATI_element_array = 0; +int GLAD_GL_AMD_texture_texture4 = 0; +int GLAD_GL_SGIX_reference_plane = 0; +int GLAD_GL_EXT_stencil_two_side = 0; +int GLAD_GL_ARB_transform_feedback_overflow_query = 0; +int GLAD_GL_SGIX_texture_lod_bias = 0; +int GLAD_GL_KHR_no_error = 0; +int GLAD_GL_NV_explicit_multisample = 0; +int GLAD_GL_NV_stereo_view_rendering = 0; +int GLAD_GL_IBM_static_data = 0; +int GLAD_GL_EXT_clip_volume_hint = 0; +int GLAD_GL_EXT_texture_perturb_normal = 0; +int GLAD_GL_NV_fragment_program2 = 0; +int GLAD_GL_NV_fragment_program4 = 0; +int GLAD_GL_EXT_point_parameters = 0; +int GLAD_GL_PGI_misc_hints = 0; +int GLAD_GL_EXT_EGL_image_storage = 0; +int GLAD_GL_SGIX_subsample = 0; +int GLAD_GL_AMD_shader_stencil_export = 0; +int GLAD_GL_ARB_shader_texture_lod = 0; +int GLAD_GL_ARB_vertex_shader = 0; +int GLAD_GL_ARB_depth_clamp = 0; +int GLAD_GL_SGIS_texture_select = 0; +int GLAD_GL_NV_texture_shader = 0; +int GLAD_GL_ARB_tessellation_shader = 0; +int GLAD_GL_EXT_draw_buffers2 = 0; +int GLAD_GL_ARB_vertex_attrib_64bit = 0; +int GLAD_GL_EXT_texture_filter_minmax = 0; +int GLAD_GL_NV_query_resource = 0; +int GLAD_GL_AMD_interleaved_elements = 0; +int GLAD_GL_ARB_fragment_program = 0; +int GLAD_GL_OML_resample = 0; +int GLAD_GL_APPLE_ycbcr_422 = 0; +int GLAD_GL_SGIX_texture_add_env = 0; +int GLAD_GL_ARB_shadow_ambient = 0; +int GLAD_GL_ARB_texture_storage = 0; +int GLAD_GL_EXT_pixel_buffer_object = 0; +int GLAD_GL_ARB_copy_image = 0; +int GLAD_GL_SGIS_pixel_texture = 0; +int GLAD_GL_SGIS_generate_mipmap = 0; +int GLAD_GL_SGIX_instruments = 0; +int GLAD_GL_ARB_fragment_layer_viewport = 0; +int GLAD_GL_ARB_shader_storage_buffer_object = 0; +int GLAD_GL_EXT_sparse_texture2 = 0; +int GLAD_GL_EXT_blend_minmax = 0; +int GLAD_GL_MESA_pack_invert = 0; +int GLAD_GL_ARB_base_instance = 0; +int GLAD_GL_SGIX_convolution_accuracy = 0; +int GLAD_GL_PGI_vertex_hints = 0; +int GLAD_GL_AMD_transform_feedback4 = 0; +int GLAD_GL_ARB_ES3_1_compatibility = 0; +int GLAD_GL_EXT_memory_object_win32 = 0; +int GLAD_GL_EXT_texture_integer = 0; +int GLAD_GL_ARB_texture_multisample = 0; +int GLAD_GL_ATI_vertex_streams = 0; +int GLAD_GL_AMD_gpu_shader_int64 = 0; +int GLAD_GL_S3_s3tc = 0; +int GLAD_GL_ARB_query_buffer_object = 0; +int GLAD_GL_AMD_vertex_shader_tessellator = 0; +int GLAD_GL_ARB_invalidate_subdata = 0; +int GLAD_GL_NV_draw_vulkan_image = 0; +int GLAD_GL_EXT_index_material = 0; +int GLAD_GL_NVX_linked_gpu_multicast = 0; +int GLAD_GL_NV_blend_equation_advanced_coherent = 0; +int GLAD_GL_KHR_texture_compression_astc_sliced_3d = 0; +int GLAD_GL_INTEL_parallel_arrays = 0; +int GLAD_GL_ATI_draw_buffers = 0; +int GLAD_GL_WIN_specular_fog = 0; +int GLAD_GL_EXT_cmyka = 0; +int GLAD_GL_SGIX_pixel_texture = 0; +int GLAD_GL_APPLE_specular_vector = 0; +int GLAD_GL_ARB_compatibility = 0; +int GLAD_GL_ARB_timer_query = 0; +int GLAD_GL_SGIX_interlace = 0; +int GLAD_GL_NV_parameter_buffer_object = 0; +int GLAD_GL_AMD_shader_trinary_minmax = 0; +int GLAD_GL_ARB_direct_state_access = 0; +int GLAD_GL_EXT_rescale_normal = 0; +int GLAD_GL_ARB_pixel_buffer_object = 0; +int GLAD_GL_ARB_uniform_buffer_object = 0; +int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = 0; +int GLAD_GL_ARB_texture_swizzle = 0; +int GLAD_GL_NV_transform_feedback2 = 0; +int GLAD_GL_SGIX_async_pixel = 0; +int GLAD_GL_NV_fragment_program_option = 0; +int GLAD_GL_ARB_explicit_attrib_location = 0; +int GLAD_GL_EXT_blend_color = 0; +int GLAD_GL_NV_shader_thread_group = 0; +int GLAD_GL_EXT_stencil_wrap = 0; +int GLAD_GL_EXT_index_array_formats = 0; +int GLAD_GL_OVR_multiview2 = 0; +int GLAD_GL_EXT_histogram = 0; +int GLAD_GL_EXT_polygon_offset = 0; +int GLAD_GL_SGIS_point_parameters = 0; +int GLAD_GL_SGIX_ycrcb = 0; +int GLAD_GL_EXT_direct_state_access = 0; +int GLAD_GL_ARB_cull_distance = 0; +int GLAD_GL_AMD_sample_positions = 0; +int GLAD_GL_NV_vertex_program = 0; +int GLAD_GL_NV_shader_thread_shuffle = 0; +int GLAD_GL_ARB_shader_precision = 0; +int GLAD_GL_EXT_vertex_shader = 0; +int GLAD_GL_EXT_blend_func_separate = 0; +int GLAD_GL_APPLE_fence = 0; +int GLAD_GL_NV_query_resource_tag = 0; +int GLAD_GL_OES_byte_coordinates = 0; +int GLAD_GL_ARB_transpose_matrix = 0; +int GLAD_GL_ARB_provoking_vertex = 0; +int GLAD_GL_EXT_fog_coord = 0; +int GLAD_GL_EXT_vertex_array = 0; +int GLAD_GL_ARB_half_float_vertex = 0; +int GLAD_GL_EXT_blend_equation_separate = 0; +int GLAD_GL_NV_framebuffer_mixed_samples = 0; +int GLAD_GL_NVX_conditional_render = 0; +int GLAD_GL_ARB_multi_draw_indirect = 0; +int GLAD_GL_EXT_raster_multisample = 0; +int GLAD_GL_NV_copy_image = 0; +int GLAD_GL_HP_texture_lighting = 0; +int GLAD_GL_INTEL_framebuffer_CMAA = 0; +int GLAD_GL_ARB_transform_feedback2 = 0; +int GLAD_GL_ARB_transform_feedback3 = 0; +int GLAD_GL_SGIX_ycrcba = 0; +int GLAD_GL_EXT_debug_marker = 0; +int GLAD_GL_EXT_bgra = 0; +int GLAD_GL_ARB_sparse_texture_clamp = 0; +int GLAD_GL_EXT_pixel_transform = 0; +int GLAD_GL_ARB_conservative_depth = 0; +int GLAD_GL_ATI_fragment_shader = 0; +int GLAD_GL_ARB_vertex_array_object = 0; +int GLAD_GL_SUN_triangle_list = 0; +int GLAD_GL_EXT_texture_env_add = 0; +int GLAD_GL_EXT_packed_depth_stencil = 0; +int GLAD_GL_EXT_texture_mirror_clamp = 0; +int GLAD_GL_NV_multisample_filter_hint = 0; +int GLAD_GL_APPLE_float_pixels = 0; +int GLAD_GL_ARB_transform_feedback_instanced = 0; +int GLAD_GL_SGIX_async = 0; +int GLAD_GL_EXT_texture_compression_latc = 0; +int GLAD_GL_NV_robustness_video_memory_purge = 0; +int GLAD_GL_ARB_shading_language_100 = 0; +int GLAD_GL_INTEL_performance_query = 0; +int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0; +int GLAD_GL_NV_gpu_shader5 = 0; +int GLAD_GL_NV_bindless_multi_draw_indirect_count = 0; +int GLAD_GL_ARB_ES2_compatibility = 0; +int GLAD_GL_ARB_indirect_parameters = 0; +int GLAD_GL_EXT_window_rectangles = 0; +int GLAD_GL_NV_half_float = 0; +int GLAD_GL_ARB_ES3_2_compatibility = 0; +int GLAD_GL_ATI_texture_mirror_once = 0; +int GLAD_GL_IBM_rasterpos_clip = 0; +int GLAD_GL_EXT_semaphore = 0; +int GLAD_GL_SGIX_shadow = 0; +int GLAD_GL_EXT_polygon_offset_clamp = 0; +int GLAD_GL_NV_deep_texture3D = 0; +int GLAD_GL_ARB_shader_draw_parameters = 0; +int GLAD_GL_SGIX_calligraphic_fragment = 0; +int GLAD_GL_ARB_shader_bit_encoding = 0; +int GLAD_GL_EXT_compiled_vertex_array = 0; +int GLAD_GL_NV_depth_buffer_float = 0; +int GLAD_GL_NV_occlusion_query = 0; +int GLAD_GL_APPLE_flush_buffer_range = 0; +int GLAD_GL_ARB_imaging = 0; +int GLAD_GL_NV_shader_atomic_float = 0; +int GLAD_GL_ARB_draw_buffers_blend = 0; +int GLAD_GL_AMD_gcn_shader = 0; +int GLAD_GL_AMD_blend_minmax_factor = 0; +int GLAD_GL_EXT_texture_sRGB_decode = 0; +int GLAD_GL_ARB_shading_language_420pack = 0; +int GLAD_GL_ARB_shader_viewport_layer_array = 0; +int GLAD_GL_ATI_meminfo = 0; +int GLAD_GL_EXT_abgr = 0; +int GLAD_GL_AMD_pinned_memory = 0; +int GLAD_GL_EXT_texture_snorm = 0; +int GLAD_GL_SGIX_texture_coordinate_clamp = 0; +int GLAD_GL_ARB_clear_buffer_object = 0; +int GLAD_GL_ARB_multisample = 0; +int GLAD_GL_EXT_debug_label = 0; +int GLAD_GL_ARB_sample_shading = 0; +int GLAD_GL_NV_internalformat_sample_query = 0; +int GLAD_GL_INTEL_map_texture = 0; +int GLAD_GL_ARB_texture_env_crossbar = 0; +int GLAD_GL_EXT_422_pixels = 0; +int GLAD_GL_NV_blend_minmax_factor = 0; +int GLAD_GL_NV_conservative_raster_pre_snap_triangles = 0; +int GLAD_GL_ARB_compute_shader = 0; +int GLAD_GL_EXT_blend_logic_op = 0; +int GLAD_GL_ARB_blend_func_extended = 0; +int GLAD_GL_IBM_vertex_array_lists = 0; +int GLAD_GL_ARB_color_buffer_float = 0; +int GLAD_GL_ARB_bindless_texture = 0; +int GLAD_GL_ARB_window_pos = 0; +int GLAD_GL_ARB_internalformat_query = 0; +int GLAD_GL_ARB_shadow = 0; +int GLAD_GL_ARB_texture_mirrored_repeat = 0; +int GLAD_GL_EXT_shader_image_load_store = 0; +int GLAD_GL_EXT_copy_texture = 0; +int GLAD_GL_NV_register_combiners2 = 0; +int GLAD_GL_SGIX_ycrcb_subsample = 0; +int GLAD_GL_NV_alpha_to_coverage_dither_control = 0; +int GLAD_GL_SGIX_ir_instrument1 = 0; +int GLAD_GL_NV_draw_texture = 0; +int GLAD_GL_EXT_texture_shared_exponent = 0; +int GLAD_GL_NV_texture_shader2 = 0; +int GLAD_GL_EXT_draw_instanced = 0; +int GLAD_GL_NV_copy_depth_to_color = 0; +int GLAD_GL_ARB_viewport_array = 0; +int GLAD_GL_ARB_separate_shader_objects = 0; +int GLAD_GL_NV_conservative_raster_pre_snap = 0; +int GLAD_GL_EXT_depth_bounds_test = 0; +int GLAD_GL_HP_image_transform = 0; +int GLAD_GL_ARB_texture_env_add = 0; +int GLAD_GL_NV_video_capture = 0; +int GLAD_GL_ARB_sampler_objects = 0; +int GLAD_GL_ARB_matrix_palette = 0; +int GLAD_GL_SGIS_texture_color_mask = 0; +int GLAD_GL_EXT_packed_pixels = 0; +int GLAD_GL_EXT_coordinate_frame = 0; +int GLAD_GL_ARB_texture_compression = 0; +int GLAD_GL_ARB_multi_bind = 0; +int GLAD_GL_APPLE_aux_depth_stencil = 0; +int GLAD_GL_ARB_shader_subroutine = 0; +int GLAD_GL_EXT_framebuffer_sRGB = 0; +int GLAD_GL_ARB_texture_storage_multisample = 0; +int GLAD_GL_KHR_blend_equation_advanced_coherent = 0; +int GLAD_GL_EXT_vertex_attrib_64bit = 0; +int GLAD_GL_NV_shader_atomic_float64 = 0; +int GLAD_GL_ARB_depth_texture = 0; +int GLAD_GL_NV_shader_buffer_store = 0; +int GLAD_GL_OES_query_matrix = 0; +int GLAD_GL_MESA_window_pos = 0; +int GLAD_GL_NV_fill_rectangle = 0; +int GLAD_GL_NV_shader_storage_buffer_object = 0; +int GLAD_GL_ARB_texture_query_lod = 0; +int GLAD_GL_ARB_copy_buffer = 0; +int GLAD_GL_ARB_shader_image_size = 0; +int GLAD_GL_NV_shader_atomic_counters = 0; +int GLAD_GL_APPLE_object_purgeable = 0; +int GLAD_GL_ARB_occlusion_query = 0; +int GLAD_GL_INGR_color_clamp = 0; +int GLAD_GL_SGI_color_table = 0; +int GLAD_GL_NV_gpu_program5_mem_extended = 0; +int GLAD_GL_ARB_texture_cube_map_array = 0; +int GLAD_GL_SGIX_scalebias_hint = 0; +int GLAD_GL_EXT_gpu_shader4 = 0; +int GLAD_GL_NV_geometry_program4 = 0; +int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0; +int GLAD_GL_AMD_debug_output = 0; +int GLAD_GL_ARB_texture_border_clamp = 0; +int GLAD_GL_EXT_win32_keyed_mutex = 0; +int GLAD_GL_ARB_fragment_coord_conventions = 0; +int GLAD_GL_ARB_multitexture = 0; +int GLAD_GL_SGIX_polynomial_ffd = 0; +int GLAD_GL_EXT_texture_env_dot3 = 0; +int GLAD_GL_EXT_provoking_vertex = 0; +int GLAD_GL_ARB_point_parameters = 0; +int GLAD_GL_ARB_shader_image_load_store = 0; +int GLAD_GL_ARB_conditional_render_inverted = 0; +int GLAD_GL_HP_occlusion_test = 0; +int GLAD_GL_ARB_ES3_compatibility = 0; +int GLAD_GL_ARB_texture_barrier = 0; +int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0; +int GLAD_GL_NV_bindless_multi_draw_indirect = 0; +int GLAD_GL_SGIX_texture_multi_buffer = 0; +int GLAD_GL_INTEL_blackhole_render = 0; +int GLAD_GL_AMD_shader_image_load_store_lod = 0; +int GLAD_GL_KHR_texture_compression_astc_ldr = 0; +int GLAD_GL_3DFX_multisample = 0; +int GLAD_GL_INTEL_fragment_shader_ordering = 0; +int GLAD_GL_ARB_texture_env_dot3 = 0; +int GLAD_GL_NV_gpu_program4 = 0; +int GLAD_GL_NV_gpu_program5 = 0; +int GLAD_GL_NV_float_buffer = 0; +int GLAD_GL_SGIS_texture_edge_clamp = 0; +int GLAD_GL_ARB_framebuffer_sRGB = 0; +int GLAD_GL_SUN_slice_accum = 0; +int GLAD_GL_EXT_index_texture = 0; +int GLAD_GL_EXT_shader_image_load_formatted = 0; +int GLAD_GL_ARB_geometry_shader4 = 0; +int GLAD_GL_EXT_separate_specular_color = 0; +int GLAD_GL_AMD_depth_clamp_separate = 0; +int GLAD_GL_NV_conservative_raster = 0; +int GLAD_GL_ARB_sparse_texture2 = 0; +int GLAD_GL_SGIX_sprite = 0; +int GLAD_GL_ARB_get_program_binary = 0; +int GLAD_GL_AMD_occlusion_query_event = 0; +int GLAD_GL_SGIS_multisample = 0; +int GLAD_GL_EXT_framebuffer_object = 0; +int GLAD_GL_ARB_robustness_isolation = 0; +int GLAD_GL_ARB_vertex_array_bgra = 0; +int GLAD_GL_APPLE_vertex_array_range = 0; +int GLAD_GL_AMD_query_buffer_object = 0; +int GLAD_GL_NV_register_combiners = 0; +int GLAD_GL_ARB_draw_buffers = 0; +int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = 0; +int GLAD_GL_AMD_gpu_shader_int16 = 0; +int GLAD_GL_ARB_debug_output = 0; +int GLAD_GL_EXT_shader_framebuffer_fetch = 0; +int GLAD_GL_SGI_color_matrix = 0; +int GLAD_GL_EXT_cull_vertex = 0; +int GLAD_GL_AMD_framebuffer_multisample_advanced = 0; +int GLAD_GL_EXT_texture_sRGB = 0; +int GLAD_GL_APPLE_row_bytes = 0; +int GLAD_GL_NV_conservative_raster_underestimation = 0; +int GLAD_GL_IBM_multimode_draw_arrays = 0; +int GLAD_GL_KHR_parallel_shader_compile = 0; +int GLAD_GL_APPLE_vertex_array_object = 0; +int GLAD_GL_3DFX_texture_compression_FXT1 = 0; +int GLAD_GL_NV_fragment_shader_interlock = 0; +int GLAD_GL_AMD_conservative_depth = 0; +int GLAD_GL_ARB_texture_float = 0; +int GLAD_GL_ARB_compressed_texture_pixel_storage = 0; +int GLAD_GL_SGIS_detail_texture = 0; +int GLAD_GL_NV_geometry_shader_passthrough = 0; +int GLAD_GL_ARB_draw_instanced = 0; +int GLAD_GL_OES_read_format = 0; +int GLAD_GL_ATI_texture_float = 0; +int GLAD_GL_ARB_texture_gather = 0; +int GLAD_GL_AMD_vertex_shader_layer = 0; +int GLAD_GL_ARB_shading_language_include = 0; +int GLAD_GL_APPLE_client_storage = 0; +int GLAD_GL_WIN_phong_shading = 0; +int GLAD_GL_INGR_blend_func_separate = 0; +int GLAD_GL_NV_path_rendering = 0; +int GLAD_GL_NV_conservative_raster_dilate = 0; +int GLAD_GL_AMD_gpu_shader_half_float = 0; +int GLAD_GL_ARB_post_depth_coverage = 0; +int GLAD_GL_ARB_texture_non_power_of_two = 0; +int GLAD_GL_APPLE_rgb_422 = 0; +int GLAD_GL_EXT_texture_lod_bias = 0; +int GLAD_GL_ARB_gpu_shader_int64 = 0; +int GLAD_GL_ARB_seamless_cube_map = 0; +int GLAD_GL_ARB_shader_group_vote = 0; +int GLAD_GL_NV_vdpau_interop = 0; +int GLAD_GL_ARB_occlusion_query2 = 0; +int GLAD_GL_ARB_internalformat_query2 = 0; +int GLAD_GL_EXT_texture_filter_anisotropic = 0; +int GLAD_GL_SUN_vertex = 0; +int GLAD_GL_EXT_transform_feedback = 0; +int GLAD_GL_SGIX_igloo_interface = 0; +int GLAD_GL_SGIS_texture_lod = 0; +int GLAD_GL_NV_vertex_program3 = 0; +int GLAD_GL_ARB_draw_indirect = 0; +int GLAD_GL_NV_vertex_program4 = 0; +int GLAD_GL_AMD_transform_feedback3_lines_triangles = 0; +int GLAD_GL_SGIS_fog_function = 0; +int GLAD_GL_EXT_x11_sync_object = 0; +int GLAD_GL_ARB_sync = 0; +int GLAD_GL_NV_texture_rectangle_compressed = 0; +int GLAD_GL_NV_sample_locations = 0; +int GLAD_GL_NV_gpu_multicast = 0; +int GLAD_GL_ARB_gl_spirv = 0; +int GLAD_GL_ARB_compute_variable_group_size = 0; +int GLAD_GL_OES_fixed_point = 0; +int GLAD_GL_MESA_program_binary_formats = 0; +int GLAD_GL_NV_blend_square = 0; +int GLAD_GL_EXT_framebuffer_multisample = 0; +int GLAD_GL_ARB_gpu_shader5 = 0; +int GLAD_GL_SGIS_texture4D = 0; +int GLAD_GL_EXT_texture3D = 0; +int GLAD_GL_EXT_multisample = 0; +int GLAD_GL_EXT_secondary_color = 0; +int GLAD_GL_INTEL_conservative_rasterization = 0; +int GLAD_GL_ARB_texture_filter_minmax = 0; +int GLAD_GL_ATI_vertex_array_object = 0; +int GLAD_GL_ARB_parallel_shader_compile = 0; +int GLAD_GL_NVX_gpu_memory_info = 0; +int GLAD_GL_ARB_sparse_texture = 0; +int GLAD_GL_SGIS_point_line_texgen = 0; +int GLAD_GL_ARB_sample_locations = 0; +int GLAD_GL_ARB_sparse_buffer = 0; +int GLAD_GL_ARB_polygon_offset_clamp = 0; +int GLAD_GL_EXT_draw_range_elements = 0; +int GLAD_GL_SGIX_blend_alpha_minmax = 0; +int GLAD_GL_KHR_context_flush_control = 0; +PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX = NULL; +PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD = NULL; +PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD = NULL; +PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD = NULL; +PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD = NULL; +PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD = NULL; +PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD = NULL; +PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD = NULL; +PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = NULL; +PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD = NULL; +PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD = NULL; +PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV = NULL; +PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV = NULL; +PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV = NULL; +PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV = NULL; +PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV = NULL; +PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV = NULL; +PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV = NULL; +PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV = NULL; +PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV = NULL; +PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV = NULL; +PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV = NULL; +PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV = NULL; +PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV = NULL; +PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV = NULL; +PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV = NULL; +PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV = NULL; +PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV = NULL; +PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV = NULL; +PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV = NULL; +PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV = NULL; +PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV = NULL; +PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV = NULL; +PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV = NULL; +PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV = NULL; +PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV = NULL; +PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV = NULL; +PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV = NULL; +PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV = NULL; +PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV = NULL; +PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV = NULL; +PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV = NULL; +PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV = NULL; +PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV = NULL; +PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV = NULL; +PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD = NULL; +PFNGLGENNAMESAMDPROC glad_glGenNamesAMD = NULL; +PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD = NULL; +PFNGLISNAMEAMDPROC glad_glIsNameAMD = NULL; +PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD = NULL; +PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD = NULL; +PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD = NULL; +PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD = NULL; +PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD = NULL; +PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD = NULL; +PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD = NULL; +PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD = NULL; +PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD = NULL; +PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD = NULL; +PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD = NULL; +PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD = NULL; +PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD = NULL; +PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD = NULL; +PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD = NULL; +PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD = NULL; +PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE = NULL; +PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE = NULL; +PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE = NULL; +PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE = NULL; +PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE = NULL; +PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE = NULL; +PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE = NULL; +PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE = NULL; +PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE = NULL; +PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE = NULL; +PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE = NULL; +PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE = NULL; +PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE = NULL; +PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE = NULL; +PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE = NULL; +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE = NULL; +PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE = NULL; +PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE = NULL; +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE = NULL; +PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE = NULL; +PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE = NULL; +PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; +PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB = NULL; +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; +PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB = NULL; +PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB = NULL; +PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB = NULL; +PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB = NULL; +PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB = NULL; +PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB = NULL; +PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB = NULL; +PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB = NULL; +PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB = NULL; +PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB = NULL; +PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; +PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB = NULL; +PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL; +PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL; +PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL; +PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL; +PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; +PFNGLCLAMPCOLORARBPROC glad_glClampColorARB = NULL; +PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; +PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB = NULL; +PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; +PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; +PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; +PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; +PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; +PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; +PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL; +PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL; +PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL; +PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL; +PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL; +PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL; +PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL; +PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; +PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL; +PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; +PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; +PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; +PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; +PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL; +PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL; +PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL; +PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL; +PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL; +PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; +PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL; +PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL; +PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL; +PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL; +PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL; +PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL; +PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL; +PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL; +PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL; +PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL; +PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL; +PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL; +PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL; +PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL; +PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL; +PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL; +PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL; +PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL; +PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL; +PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL; +PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL; +PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL; +PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; +PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; +PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL; +PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; +PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; +PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; +PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL; +PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL; +PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL; +PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL; +PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL; +PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL; +PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL; +PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL; +PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL; +PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL; +PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL; +PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL; +PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL; +PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB = NULL; +PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB = NULL; +PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB = NULL; +PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB = NULL; +PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; +PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL; +PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB = NULL; +PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB = NULL; +PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB = NULL; +PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB = NULL; +PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB = NULL; +PFNGLISPROGRAMARBPROC glad_glIsProgramARB = NULL; +PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; +PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB = NULL; +PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB = NULL; +PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; +PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; +PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL; +PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; +PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB = NULL; +PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; +PFNGLUNIFORM2DPROC glad_glUniform2d = NULL; +PFNGLUNIFORM3DPROC glad_glUniform3d = NULL; +PFNGLUNIFORM4DPROC glad_glUniform4d = NULL; +PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; +PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL; +PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL; +PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL; +PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL; +PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL; +PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL; +PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL; +PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL; +PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL; +PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL; +PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL; +PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL; +PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL; +PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB = NULL; +PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB = NULL; +PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB = NULL; +PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB = NULL; +PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB = NULL; +PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB = NULL; +PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB = NULL; +PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB = NULL; +PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB = NULL; +PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB = NULL; +PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB = NULL; +PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB = NULL; +PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB = NULL; +PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB = NULL; +PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB = NULL; +PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB = NULL; +PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB = NULL; +PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB = NULL; +PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB = NULL; +PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB = NULL; +PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB = NULL; +PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB = NULL; +PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB = NULL; +PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB = NULL; +PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB = NULL; +PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB = NULL; +PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB = NULL; +PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB = NULL; +PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB = NULL; +PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB = NULL; +PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB = NULL; +PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB = NULL; +PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB = NULL; +PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB = NULL; +PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB = NULL; +PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB = NULL; +PFNGLCOLORTABLEPROC glad_glColorTable = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv = NULL; +PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable = NULL; +PFNGLGETCOLORTABLEPROC glad_glGetColorTable = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv = NULL; +PFNGLCOLORSUBTABLEPROC glad_glColorSubTable = NULL; +PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable = NULL; +PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D = NULL; +PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv = NULL; +PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter = NULL; +PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D = NULL; +PFNGLGETHISTOGRAMPROC glad_glGetHistogram = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv = NULL; +PFNGLGETMINMAXPROC glad_glGetMinmax = NULL; +PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv = NULL; +PFNGLHISTOGRAMPROC glad_glHistogram = NULL; +PFNGLMINMAXPROC glad_glMinmax = NULL; +PFNGLRESETHISTOGRAMPROC glad_glResetHistogram = NULL; +PFNGLRESETMINMAXPROC glad_glResetMinmax = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB = NULL; +PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB = NULL; +PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; +PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL; +PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; +PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB = NULL; +PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL; +PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL; +PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL; +PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL; +PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL; +PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; +PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL; +PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB = NULL; +PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB = NULL; +PFNGLGENQUERIESARBPROC glad_glGenQueriesARB = NULL; +PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB = NULL; +PFNGLISQUERYARBPROC glad_glIsQueryARB = NULL; +PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB = NULL; +PFNGLENDQUERYARBPROC glad_glEndQueryARB = NULL; +PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB = NULL; +PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB = NULL; +PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB = NULL; +PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB = NULL; +PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; +PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL; +PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL; +PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL; +PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL; +PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL; +PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL; +PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL; +PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL; +PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL; +PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL; +PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL; +PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL; +PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL; +PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL; +PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL; +PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL; +PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL; +PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL; +PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL; +PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL; +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB = NULL; +PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB = NULL; +PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB = NULL; +PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; +PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; +PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; +PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; +PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; +PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; +PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; +PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL; +PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL; +PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL; +PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL; +PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL; +PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL; +PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL; +PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; +PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL; +PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; +PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; +PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB = NULL; +PFNGLGETHANDLEARBPROC glad_glGetHandleARB = NULL; +PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB = NULL; +PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB = NULL; +PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB = NULL; +PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB = NULL; +PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB = NULL; +PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB = NULL; +PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB = NULL; +PFNGLUNIFORM1FARBPROC glad_glUniform1fARB = NULL; +PFNGLUNIFORM2FARBPROC glad_glUniform2fARB = NULL; +PFNGLUNIFORM3FARBPROC glad_glUniform3fARB = NULL; +PFNGLUNIFORM4FARBPROC glad_glUniform4fARB = NULL; +PFNGLUNIFORM1IARBPROC glad_glUniform1iARB = NULL; +PFNGLUNIFORM2IARBPROC glad_glUniform2iARB = NULL; +PFNGLUNIFORM3IARBPROC glad_glUniform3iARB = NULL; +PFNGLUNIFORM4IARBPROC glad_glUniform4iARB = NULL; +PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB = NULL; +PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB = NULL; +PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB = NULL; +PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB = NULL; +PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB = NULL; +PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB = NULL; +PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB = NULL; +PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB = NULL; +PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB = NULL; +PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB = NULL; +PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB = NULL; +PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB = NULL; +PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB = NULL; +PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; +PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; +PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL; +PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL; +PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL; +PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL; +PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL; +PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB = NULL; +PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB = NULL; +PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB = NULL; +PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB = NULL; +PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB = NULL; +PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT = NULL; +PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB = NULL; +PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB = NULL; +PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; +PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; +PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL; +PFNGLTEXBUFFERARBPROC glad_glTexBufferARB = NULL; +PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB = NULL; +PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL; +PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; +PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; +PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL; +PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; +PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; +PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; +PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; +PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; +PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; +PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL; +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB = NULL; +PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB = NULL; +PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL; +PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL; +PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL; +PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL; +PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL; +PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL; +PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL; +PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL; +PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL; +PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL; +PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; +PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL; +PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; +PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; +PFNGLWEIGHTBVARBPROC glad_glWeightbvARB = NULL; +PFNGLWEIGHTSVARBPROC glad_glWeightsvARB = NULL; +PFNGLWEIGHTIVARBPROC glad_glWeightivARB = NULL; +PFNGLWEIGHTFVARBPROC glad_glWeightfvARB = NULL; +PFNGLWEIGHTDVARBPROC glad_glWeightdvARB = NULL; +PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB = NULL; +PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB = NULL; +PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB = NULL; +PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB = NULL; +PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB = NULL; +PFNGLBINDBUFFERARBPROC glad_glBindBufferARB = NULL; +PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB = NULL; +PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB = NULL; +PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL; +PFNGLBUFFERDATAARBPROC glad_glBufferDataARB = NULL; +PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB = NULL; +PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB = NULL; +PFNGLMAPBUFFERARBPROC glad_glMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB = NULL; +PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB = NULL; +PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB = NULL; +PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB = NULL; +PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB = NULL; +PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; +PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; +PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; +PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; +PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; +PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; +PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; +PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; +PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL; +PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL; +PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB = NULL; +PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB = NULL; +PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI = NULL; +PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI = NULL; +PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI = NULL; +PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI = NULL; +PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI = NULL; +PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI = NULL; +PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI = NULL; +PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI = NULL; +PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI = NULL; +PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI = NULL; +PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI = NULL; +PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI = NULL; +PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI = NULL; +PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI = NULL; +PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI = NULL; +PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI = NULL; +PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI = NULL; +PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI = NULL; +PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI = NULL; +PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI = NULL; +PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI = NULL; +PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI = NULL; +PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI = NULL; +PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI = NULL; +PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI = NULL; +PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI = NULL; +PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI = NULL; +PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI = NULL; +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI = NULL; +PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI = NULL; +PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT = NULL; +PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT = NULL; +PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT = NULL; +PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT = NULL; +PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT = NULL; +PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT = NULL; +PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT = NULL; +PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT = NULL; +PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT = NULL; +PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT = NULL; +PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT = NULL; +PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT = NULL; +PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT = NULL; +PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT = NULL; +PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT = NULL; +PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT = NULL; +PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT = NULL; +PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT = NULL; +PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT = NULL; +PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT = NULL; +PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT = NULL; +PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT = NULL; +PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT = NULL; +PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT = NULL; +PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT = NULL; +PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT = NULL; +PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT = NULL; +PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT = NULL; +PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT = NULL; +PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT = NULL; +PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT = NULL; +PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT = NULL; +PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT = NULL; +PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT = NULL; +PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT = NULL; +PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT = NULL; +PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT = NULL; +PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT = NULL; +PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT = NULL; +PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT = NULL; +PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT = NULL; +PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT = NULL; +PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT = NULL; +PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT = NULL; +PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT = NULL; +PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT = NULL; +PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT = NULL; +PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT = NULL; +PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT = NULL; +PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT = NULL; +PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT = NULL; +PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT = NULL; +PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT = NULL; +PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT = NULL; +PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT = NULL; +PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT = NULL; +PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT = NULL; +PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT = NULL; +PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT = NULL; +PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT = NULL; +PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT = NULL; +PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT = NULL; +PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT = NULL; +PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT = NULL; +PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT = NULL; +PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT = NULL; +PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT = NULL; +PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT = NULL; +PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT = NULL; +PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT = NULL; +PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT = NULL; +PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT = NULL; +PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT = NULL; +PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT = NULL; +PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT = NULL; +PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT = NULL; +PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT = NULL; +PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT = NULL; +PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT = NULL; +PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT = NULL; +PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT = NULL; +PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT = NULL; +PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT = NULL; +PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT = NULL; +PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT = NULL; +PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT = NULL; +PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT = NULL; +PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT = NULL; +PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT = NULL; +PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT = NULL; +PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT = NULL; +PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT = NULL; +PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT = NULL; +PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT = NULL; +PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT = NULL; +PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT = NULL; +PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT = NULL; +PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT = NULL; +PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT = NULL; +PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT = NULL; +PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT = NULL; +PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT = NULL; +PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT = NULL; +PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT = NULL; +PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT = NULL; +PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT = NULL; +PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT = NULL; +PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT = NULL; +PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT = NULL; +PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT = NULL; +PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT = NULL; +PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT = NULL; +PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT = NULL; +PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT = NULL; +PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT = NULL; +PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT = NULL; +PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT = NULL; +PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT = NULL; +PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT = NULL; +PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT = NULL; +PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT = NULL; +PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT = NULL; +PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT = NULL; +PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT = NULL; +PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT = NULL; +PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT = NULL; +PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT = NULL; +PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT = NULL; +PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT = NULL; +PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT = NULL; +PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT = NULL; +PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT = NULL; +PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT = NULL; +PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT = NULL; +PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT = NULL; +PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT = NULL; +PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT = NULL; +PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT = NULL; +PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT = NULL; +PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT = NULL; +PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT = NULL; +PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT = NULL; +PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT = NULL; +PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT = NULL; +PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT = NULL; +PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT = NULL; +PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT = NULL; +PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT = NULL; +PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT = NULL; +PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT = NULL; +PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT = NULL; +PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT = NULL; +PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT = NULL; +PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT = NULL; +PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT = NULL; +PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT = NULL; +PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT = NULL; +PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT = NULL; +PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT = NULL; +PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT = NULL; +PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT = NULL; +PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT = NULL; +PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT = NULL; +PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT = NULL; +PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT = NULL; +PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT = NULL; +PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT = NULL; +PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT = NULL; +PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT = NULL; +PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT = NULL; +PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT = NULL; +PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT = NULL; +PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT = NULL; +PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT = NULL; +PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT = NULL; +PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT = NULL; +PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL; +PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL; +PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT = NULL; +PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT = NULL; +PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT = NULL; +PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT = NULL; +PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT = NULL; +PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL; +PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT = NULL; +PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT = NULL; +PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT = NULL; +PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT = NULL; +PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT = NULL; +PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT = NULL; +PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT = NULL; +PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; +PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL; +PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL; +PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL; +PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT = NULL; +PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT = NULL; +PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT = NULL; +PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT = NULL; +PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT = NULL; +PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT = NULL; +PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT = NULL; +PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT = NULL; +PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT = NULL; +PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT = NULL; +PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT = NULL; +PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT = NULL; +PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT = NULL; +PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT = NULL; +PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT = NULL; +PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT = NULL; +PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT = NULL; +PFNGLMINMAXEXTPROC glad_glMinmaxEXT = NULL; +PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT = NULL; +PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT = NULL; +PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT = NULL; +PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT = NULL; +PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT = NULL; +PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT = NULL; +PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL; +PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL; +PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL; +PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL; +PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL; +PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL; +PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL; +PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL; +PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL; +PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL; +PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL; +PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL; +PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL; +PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL; +PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL; +PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT = NULL; +PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT = NULL; +PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT = NULL; +PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT = NULL; +PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT = NULL; +PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT = NULL; +PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT = NULL; +PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT = NULL; +PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT = NULL; +PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT = NULL; +PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT = NULL; +PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT = NULL; +PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT = NULL; +PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT = NULL; +PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT = NULL; +PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT = NULL; +PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT = NULL; +PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT = NULL; +PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT = NULL; +PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT = NULL; +PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT = NULL; +PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT = NULL; +PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT = NULL; +PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT = NULL; +PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT = NULL; +PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT = NULL; +PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT = NULL; +PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT = NULL; +PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT = NULL; +PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT = NULL; +PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT = NULL; +PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT = NULL; +PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT = NULL; +PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT = NULL; +PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT = NULL; +PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT = NULL; +PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT = NULL; +PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT = NULL; +PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT = NULL; +PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT = NULL; +PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT = NULL; +PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT = NULL; +PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT = NULL; +PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT = NULL; +PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT = NULL; +PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT = NULL; +PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT = NULL; +PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT = NULL; +PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT = NULL; +PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT = NULL; +PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT = NULL; +PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT = NULL; +PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT = NULL; +PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT = NULL; +PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT = NULL; +PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT = NULL; +PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT = NULL; +PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT = NULL; +PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT = NULL; +PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT = NULL; +PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT = NULL; +PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT = NULL; +PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT = NULL; +PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT = NULL; +PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT = NULL; +PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT = NULL; +PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT = NULL; +PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT = NULL; +PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT = NULL; +PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT = NULL; +PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT = NULL; +PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT = NULL; +PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT = NULL; +PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT = NULL; +PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT = NULL; +PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT = NULL; +PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT = NULL; +PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT = NULL; +PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT = NULL; +PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT = NULL; +PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT = NULL; +PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT = NULL; +PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT = NULL; +PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT = NULL; +PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT = NULL; +PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT = NULL; +PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT = NULL; +PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT = NULL; +PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT = NULL; +PFNGLVARIANTIVEXTPROC glad_glVariantivEXT = NULL; +PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT = NULL; +PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT = NULL; +PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT = NULL; +PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT = NULL; +PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT = NULL; +PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT = NULL; +PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT = NULL; +PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT = NULL; +PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT = NULL; +PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT = NULL; +PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT = NULL; +PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT = NULL; +PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT = NULL; +PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY = NULL; +PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP = NULL; +PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM = NULL; +PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM = NULL; +PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM = NULL; +PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM = NULL; +PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM = NULL; +PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR = NULL; +PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL = NULL; +PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL = NULL; +PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL = NULL; +PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL = NULL; +PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL = NULL; +PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL = NULL; +PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL = NULL; +PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL = NULL; +PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL = NULL; +PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL = NULL; +PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL = NULL; +PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL = NULL; +PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL = NULL; +PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL = NULL; +PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL = NULL; +PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL; +PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; +PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; +PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; +PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; +PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; +PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; +PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; +PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; +PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; +PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; +PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; +PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; +PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; +PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; +PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; +PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; +PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; +PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; +PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; +PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; +PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; +PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; +PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL; +PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL; +PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL; +PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; +PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; +PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; +PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR = NULL; +PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR = NULL; +PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR = NULL; +PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR = NULL; +PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR = NULL; +PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA = NULL; +PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA = NULL; +PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX = NULL; +PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX = NULL; +PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX = NULL; +PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX = NULL; +PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX = NULL; +PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV = NULL; +PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV = NULL; +PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV = NULL; +PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV = NULL; +PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV = NULL; +PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV = NULL; +PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV = NULL; +PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV = NULL; +PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV = NULL; +PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV = NULL; +PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV = NULL; +PFNGLCREATESTATESNVPROC glad_glCreateStatesNV = NULL; +PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV = NULL; +PFNGLISSTATENVPROC glad_glIsStateNV = NULL; +PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV = NULL; +PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV = NULL; +PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV = NULL; +PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV = NULL; +PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV = NULL; +PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV = NULL; +PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV = NULL; +PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV = NULL; +PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV = NULL; +PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV = NULL; +PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV = NULL; +PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV = NULL; +PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV = NULL; +PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV = NULL; +PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV = NULL; +PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV = NULL; +PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV = NULL; +PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV = NULL; +PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV = NULL; +PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV = NULL; +PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV = NULL; +PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV = NULL; +PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV = NULL; +PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV = NULL; +PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV = NULL; +PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV = NULL; +PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV = NULL; +PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV = NULL; +PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV = NULL; +PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV = NULL; +PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV = NULL; +PFNGLEVALMAPSNVPROC glad_glEvalMapsNV = NULL; +PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV = NULL; +PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV = NULL; +PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV = NULL; +PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV = NULL; +PFNGLGENFENCESNVPROC glad_glGenFencesNV = NULL; +PFNGLISFENCENVPROC glad_glIsFenceNV = NULL; +PFNGLTESTFENCENVPROC glad_glTestFenceNV = NULL; +PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV = NULL; +PFNGLFINISHFENCENVPROC glad_glFinishFenceNV = NULL; +PFNGLSETFENCENVPROC glad_glSetFenceNV = NULL; +PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV = NULL; +PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV = NULL; +PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV = NULL; +PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV = NULL; +PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV = NULL; +PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT = NULL; +PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV = NULL; +PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV = NULL; +PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV = NULL; +PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV = NULL; +PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV = NULL; +PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV = NULL; +PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV = NULL; +PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV = NULL; +PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV = NULL; +PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV = NULL; +PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV = NULL; +PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV = NULL; +PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV = NULL; +PFNGLVERTEX2HNVPROC glad_glVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV = NULL; +PFNGLVERTEX3HNVPROC glad_glVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV = NULL; +PFNGLVERTEX4HNVPROC glad_glVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV = NULL; +PFNGLNORMAL3HNVPROC glad_glNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV = NULL; +PFNGLCOLOR3HNVPROC glad_glColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC glad_glColor3hvNV = NULL; +PFNGLCOLOR4HNVPROC glad_glColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC glad_glColor4hvNV = NULL; +PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV = NULL; +PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV = NULL; +PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV = NULL; +PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV = NULL; +PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV = NULL; +PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV = NULL; +PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV = NULL; +PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV = NULL; +PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV = NULL; +PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV = NULL; +PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV = NULL; +PFNGLGENPATHSNVPROC glad_glGenPathsNV = NULL; +PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV = NULL; +PFNGLISPATHNVPROC glad_glIsPathNV = NULL; +PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV = NULL; +PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV = NULL; +PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV = NULL; +PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV = NULL; +PFNGLPATHSTRINGNVPROC glad_glPathStringNV = NULL; +PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV = NULL; +PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV = NULL; +PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV = NULL; +PFNGLCOPYPATHNVPROC glad_glCopyPathNV = NULL; +PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV = NULL; +PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV = NULL; +PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV = NULL; +PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV = NULL; +PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV = NULL; +PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV = NULL; +PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV = NULL; +PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV = NULL; +PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV = NULL; +PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV = NULL; +PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV = NULL; +PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV = NULL; +PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV = NULL; +PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV = NULL; +PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV = NULL; +PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV = NULL; +PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV = NULL; +PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV = NULL; +PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV = NULL; +PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV = NULL; +PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV = NULL; +PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV = NULL; +PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV = NULL; +PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV = NULL; +PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV = NULL; +PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV = NULL; +PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV = NULL; +PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV = NULL; +PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV = NULL; +PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV = NULL; +PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV = NULL; +PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV = NULL; +PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV = NULL; +PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV = NULL; +PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV = NULL; +PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV = NULL; +PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV = NULL; +PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV = NULL; +PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV = NULL; +PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV = NULL; +PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV = NULL; +PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV = NULL; +PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV = NULL; +PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV = NULL; +PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV = NULL; +PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV = NULL; +PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV = NULL; +PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV = NULL; +PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV = NULL; +PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV = NULL; +PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV = NULL; +PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV = NULL; +PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV = NULL; +PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV = NULL; +PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV = NULL; +PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV = NULL; +PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV = NULL; +PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV = NULL; +PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV = NULL; +PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV = NULL; +PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV = NULL; +PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV = NULL; +PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV = NULL; +PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV = NULL; +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV = NULL; +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV = NULL; +PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV = NULL; +PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV = NULL; +PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV = NULL; +PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV = NULL; +PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV = NULL; +PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV = NULL; +PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV = NULL; +PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV = NULL; +PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV = NULL; +PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV = NULL; +PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV = NULL; +PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV = NULL; +PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV = NULL; +PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV = NULL; +PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV = NULL; +PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV = NULL; +PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV = NULL; +PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV = NULL; +PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV = NULL; +PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV = NULL; +PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV = NULL; +PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV = NULL; +PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV = NULL; +PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV = NULL; +PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV = NULL; +PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV = NULL; +PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV = NULL; +PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV = NULL; +PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV = NULL; +PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV = NULL; +PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV = NULL; +PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV = NULL; +PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV = NULL; +PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV = NULL; +PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV = NULL; +PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV = NULL; +PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV = NULL; +PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV = NULL; +PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV = NULL; +PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV = NULL; +PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV = NULL; +PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV = NULL; +PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV = NULL; +PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV = NULL; +PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV = NULL; +PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV = NULL; +PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV = NULL; +PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV = NULL; +PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV = NULL; +PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV = NULL; +PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV = NULL; +PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV = NULL; +PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV = NULL; +PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV = NULL; +PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV = NULL; +PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV = NULL; +PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV = NULL; +PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV = NULL; +PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV = NULL; +PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV = NULL; +PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV = NULL; +PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV = NULL; +PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV = NULL; +PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV = NULL; +PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV = NULL; +PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV = NULL; +PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV = NULL; +PFNGLCOLORFORMATNVPROC glad_glColorFormatNV = NULL; +PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV = NULL; +PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV = NULL; +PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV = NULL; +PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV = NULL; +PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV = NULL; +PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV = NULL; +PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV = NULL; +PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV = NULL; +PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV = NULL; +PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV = NULL; +PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV = NULL; +PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV = NULL; +PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV = NULL; +PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV = NULL; +PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV = NULL; +PFNGLISPROGRAMNVPROC glad_glIsProgramNV = NULL; +PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV = NULL; +PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV = NULL; +PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT = NULL; +PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT = NULL; +PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT = NULL; +PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT = NULL; +PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT = NULL; +PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT = NULL; +PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT = NULL; +PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT = NULL; +PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT = NULL; +PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT = NULL; +PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT = NULL; +PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT = NULL; +PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT = NULL; +PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT = NULL; +PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT = NULL; +PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT = NULL; +PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT = NULL; +PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT = NULL; +PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT = NULL; +PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT = NULL; +PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT = NULL; +PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT = NULL; +PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT = NULL; +PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV = NULL; +PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV = NULL; +PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV = NULL; +PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV = NULL; +PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV = NULL; +PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES = NULL; +PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES = NULL; +PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES = NULL; +PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES = NULL; +PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES = NULL; +PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES = NULL; +PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES = NULL; +PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES = NULL; +PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES = NULL; +PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES = NULL; +PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES = NULL; +PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES = NULL; +PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES = NULL; +PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES = NULL; +PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES = NULL; +PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES = NULL; +PFNGLVERTEX2BOESPROC glad_glVertex2bOES = NULL; +PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES = NULL; +PFNGLVERTEX3BOESPROC glad_glVertex3bOES = NULL; +PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES = NULL; +PFNGLVERTEX4BOESPROC glad_glVertex4bOES = NULL; +PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES = NULL; +PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES = NULL; +PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES = NULL; +PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES = NULL; +PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES = NULL; +PFNGLCOLOR4XOESPROC glad_glColor4xOES = NULL; +PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES = NULL; +PFNGLFOGXOESPROC glad_glFogxOES = NULL; +PFNGLFOGXVOESPROC glad_glFogxvOES = NULL; +PFNGLFRUSTUMXOESPROC glad_glFrustumxOES = NULL; +PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES = NULL; +PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES = NULL; +PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES = NULL; +PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES = NULL; +PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES = NULL; +PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES = NULL; +PFNGLLIGHTXOESPROC glad_glLightxOES = NULL; +PFNGLLIGHTXVOESPROC glad_glLightxvOES = NULL; +PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES = NULL; +PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES = NULL; +PFNGLMATERIALXOESPROC glad_glMaterialxOES = NULL; +PFNGLMATERIALXVOESPROC glad_glMaterialxvOES = NULL; +PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES = NULL; +PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES = NULL; +PFNGLNORMAL3XOESPROC glad_glNormal3xOES = NULL; +PFNGLORTHOXOESPROC glad_glOrthoxOES = NULL; +PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES = NULL; +PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES = NULL; +PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES = NULL; +PFNGLROTATEXOESPROC glad_glRotatexOES = NULL; +PFNGLSCALEXOESPROC glad_glScalexOES = NULL; +PFNGLTEXENVXOESPROC glad_glTexEnvxOES = NULL; +PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES = NULL; +PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES = NULL; +PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES = NULL; +PFNGLTRANSLATEXOESPROC glad_glTranslatexOES = NULL; +PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES = NULL; +PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES = NULL; +PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES = NULL; +PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES = NULL; +PFNGLACCUMXOESPROC glad_glAccumxOES = NULL; +PFNGLBITMAPXOESPROC glad_glBitmapxOES = NULL; +PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES = NULL; +PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES = NULL; +PFNGLCOLOR3XOESPROC glad_glColor3xOES = NULL; +PFNGLCOLOR3XVOESPROC glad_glColor3xvOES = NULL; +PFNGLCOLOR4XVOESPROC glad_glColor4xvOES = NULL; +PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES = NULL; +PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES = NULL; +PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES = NULL; +PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES = NULL; +PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES = NULL; +PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES = NULL; +PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES = NULL; +PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES = NULL; +PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES = NULL; +PFNGLGETLIGHTXOESPROC glad_glGetLightxOES = NULL; +PFNGLGETMAPXVOESPROC glad_glGetMapxvOES = NULL; +PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES = NULL; +PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv = NULL; +PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES = NULL; +PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES = NULL; +PFNGLINDEXXOESPROC glad_glIndexxOES = NULL; +PFNGLINDEXXVOESPROC glad_glIndexxvOES = NULL; +PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES = NULL; +PFNGLMAP1XOESPROC glad_glMap1xOES = NULL; +PFNGLMAP2XOESPROC glad_glMap2xOES = NULL; +PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES = NULL; +PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES = NULL; +PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES = NULL; +PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES = NULL; +PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES = NULL; +PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES = NULL; +PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES = NULL; +PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES = NULL; +PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES = NULL; +PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES = NULL; +PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES = NULL; +PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES = NULL; +PFNGLPIXELMAPXPROC glad_glPixelMapx = NULL; +PFNGLPIXELSTOREXPROC glad_glPixelStorex = NULL; +PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES = NULL; +PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES = NULL; +PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES = NULL; +PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES = NULL; +PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES = NULL; +PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES = NULL; +PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES = NULL; +PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES = NULL; +PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES = NULL; +PFNGLRECTXOESPROC glad_glRectxOES = NULL; +PFNGLRECTXVOESPROC glad_glRectxvOES = NULL; +PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES = NULL; +PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES = NULL; +PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES = NULL; +PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES = NULL; +PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES = NULL; +PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES = NULL; +PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES = NULL; +PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES = NULL; +PFNGLTEXGENXOESPROC glad_glTexGenxOES = NULL; +PFNGLTEXGENXVOESPROC glad_glTexGenxvOES = NULL; +PFNGLVERTEX2XOESPROC glad_glVertex2xOES = NULL; +PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES = NULL; +PFNGLVERTEX3XOESPROC glad_glVertex3xOES = NULL; +PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES = NULL; +PFNGLVERTEX4XOESPROC glad_glVertex4xOES = NULL; +PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES = NULL; +PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES = NULL; +PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES = NULL; +PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES = NULL; +PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES = NULL; +PFNGLFRUSTUMFOESPROC glad_glFrustumfOES = NULL; +PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES = NULL; +PFNGLORTHOFOESPROC glad_glOrthofOES = NULL; +PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL; +PFNGLHINTPGIPROC glad_glHintPGI = NULL; +PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS = NULL; +PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS = NULL; +PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS = NULL; +PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS = NULL; +PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS = NULL; +PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS = NULL; +PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS = NULL; +PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS = NULL; +PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS = NULL; +PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS = NULL; +PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS = NULL; +PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS = NULL; +PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS = NULL; +PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS = NULL; +PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS = NULL; +PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS = NULL; +PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX = NULL; +PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX = NULL; +PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX = NULL; +PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX = NULL; +PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX = NULL; +PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX = NULL; +PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX = NULL; +PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX = NULL; +PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX = NULL; +PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX = NULL; +PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX = NULL; +PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX = NULL; +PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX = NULL; +PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX = NULL; +PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX = NULL; +PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX = NULL; +PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX = NULL; +PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX = NULL; +PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX = NULL; +PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX = NULL; +PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX = NULL; +PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX = NULL; +PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX = NULL; +PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX = NULL; +PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX = NULL; +PFNGLDEFORMSGIXPROC glad_glDeformSGIX = NULL; +PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX = NULL; +PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX = NULL; +PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX = NULL; +PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX = NULL; +PFNGLCOLORTABLESGIPROC glad_glColorTableSGI = NULL; +PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI = NULL; +PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI = NULL; +PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI = NULL; +PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX = NULL; +PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN = NULL; +PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN = NULL; +PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; static void load_GL_VERSION_1_0(GLADloadproc load) { if(!GLAD_GL_VERSION_1_0) return; glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); @@ -4453,6 +4457,11 @@ static void load_GL_AMD_draw_buffers_blend(GLADloadproc load) { glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD"); glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD"); } +static void load_GL_AMD_framebuffer_multisample_advanced(GLADloadproc load) { + if(!GLAD_GL_AMD_framebuffer_multisample_advanced) return; + glad_glRenderbufferStorageMultisampleAdvancedAMD = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glRenderbufferStorageMultisampleAdvancedAMD"); + glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glNamedRenderbufferStorageMultisampleAdvancedAMD"); +} static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) { if(!GLAD_GL_AMD_framebuffer_sample_positions) return; glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD"); @@ -7812,6 +7821,7 @@ static int find_extensionsGL(void) { GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output"); GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate"); GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend"); + GLAD_GL_AMD_framebuffer_multisample_advanced = has_ext("GL_AMD_framebuffer_multisample_advanced"); GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions"); GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader"); GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float"); @@ -8473,6 +8483,7 @@ int gladLoadGLLoader(GLADloadproc load) { load_GL_3DFX_tbuffer(load); load_GL_AMD_debug_output(load); load_GL_AMD_draw_buffers_blend(load); + load_GL_AMD_framebuffer_multisample_advanced(load); load_GL_AMD_framebuffer_sample_positions(load); load_GL_AMD_gpu_shader_int64(load); load_GL_AMD_interleaved_elements(load); diff --git a/externals/mbedtls b/externals/mbedtls -Subproject 06442b840ea62e2ceda0dc58f255cfff49fed5b +Subproject d409b75a4cf75a5b358b352c75826ddbca44db5 diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 81121167d..82e4850f7 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -1,16 +1,24 @@ add_library(audio_core STATIC + algorithm/filter.cpp + algorithm/filter.h + algorithm/interpolate.cpp + algorithm/interpolate.h audio_out.cpp audio_out.h + audio_renderer.cpp + audio_renderer.h buffer.h - cubeb_sink.cpp - cubeb_sink.h + codec.cpp + codec.h null_sink.h - stream.cpp - stream.h sink.h sink_details.cpp sink_details.h sink_stream.h + stream.cpp + stream.h + + $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> ) create_target_directory_groups(audio_core) diff --git a/src/audio_core/algorithm/filter.cpp b/src/audio_core/algorithm/filter.cpp new file mode 100644 index 000000000..403b8503f --- /dev/null +++ b/src/audio_core/algorithm/filter.cpp @@ -0,0 +1,79 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#define _USE_MATH_DEFINES + +#include <algorithm> +#include <array> +#include <cmath> +#include <vector> +#include "audio_core/algorithm/filter.h" +#include "common/common_types.h" + +namespace AudioCore { + +Filter Filter::LowPass(double cutoff, double Q) { + const double w0 = 2.0 * M_PI * cutoff; + const double sin_w0 = std::sin(w0); + const double cos_w0 = std::cos(w0); + const double alpha = sin_w0 / (2 * Q); + + const double a0 = 1 + alpha; + const double a1 = -2.0 * cos_w0; + const double a2 = 1 - alpha; + const double b0 = 0.5 * (1 - cos_w0); + const double b1 = 1.0 * (1 - cos_w0); + const double b2 = 0.5 * (1 - cos_w0); + + return {a0, a1, a2, b0, b1, b2}; +} + +Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {} + +Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2) + : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {} + +void Filter::Process(std::vector<s16>& signal) { + const size_t num_frames = signal.size() / 2; + for (size_t i = 0; i < num_frames; i++) { + std::rotate(in.begin(), in.end() - 1, in.end()); + std::rotate(out.begin(), out.end() - 1, out.end()); + + for (size_t ch = 0; ch < channel_count; ch++) { + in[0][ch] = signal[i * channel_count + ch]; + + out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] - + a2 * out[2][ch]; + + signal[i * 2 + ch] = std::clamp(out[0][ch], -32768.0, 32767.0); + } + } +} + +/// Calculates the appropriate Q for each biquad in a cascading filter. +/// @param total_count The total number of biquads to be cascaded. +/// @param index 0-index of the biquad to calculate the Q value for. +static double CascadingBiquadQ(size_t total_count, size_t index) { + const double pole = M_PI * (2 * index + 1) / (4.0 * total_count); + return 1.0 / (2.0 * std::cos(pole)); +} + +CascadingFilter CascadingFilter::LowPass(double cutoff, size_t cascade_size) { + std::vector<Filter> cascade(cascade_size); + for (size_t i = 0; i < cascade_size; i++) { + cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i)); + } + return CascadingFilter{std::move(cascade)}; +} + +CascadingFilter::CascadingFilter() = default; +CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {} + +void CascadingFilter::Process(std::vector<s16>& signal) { + for (auto& filter : filters) { + filter.Process(signal); + } +} + +} // namespace AudioCore diff --git a/src/audio_core/algorithm/filter.h b/src/audio_core/algorithm/filter.h new file mode 100644 index 000000000..a41beef98 --- /dev/null +++ b/src/audio_core/algorithm/filter.h @@ -0,0 +1,62 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <vector> +#include "common/common_types.h" + +namespace AudioCore { + +/// Digital biquad filter: +/// +/// b0 + b1 z^-1 + b2 z^-2 +/// H(z) = ------------------------ +/// a0 + a1 z^-1 + b2 z^-2 +class Filter { +public: + /// Creates a low-pass filter. + /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0. + /// @param Q Determines the quality factor of this filter. + static Filter LowPass(double cutoff, double Q = 0.7071); + + /// Passthrough filter. + Filter(); + + Filter(double a0, double a1, double a2, double b0, double b1, double b2); + + void Process(std::vector<s16>& signal); + +private: + static constexpr size_t channel_count = 2; + + /// Coefficients are in normalized form (a0 = 1.0). + double a1, a2, b0, b1, b2; + /// Input History + std::array<std::array<double, channel_count>, 3> in; + /// Output History + std::array<std::array<double, channel_count>, 3> out; +}; + +/// Cascade filters to build up higher-order filters from lower-order ones. +class CascadingFilter { +public: + /// Creates a cascading low-pass filter. + /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0. + /// @param cascade_size Number of biquads in cascade. + static CascadingFilter LowPass(double cutoff, size_t cascade_size); + + /// Passthrough. + CascadingFilter(); + + explicit CascadingFilter(std::vector<Filter> filters); + + void Process(std::vector<s16>& signal); + +private: + std::vector<Filter> filters; +}; + +} // namespace AudioCore diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp new file mode 100644 index 000000000..11459821f --- /dev/null +++ b/src/audio_core/algorithm/interpolate.cpp @@ -0,0 +1,71 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#define _USE_MATH_DEFINES + +#include <algorithm> +#include <cmath> +#include <vector> +#include "audio_core/algorithm/interpolate.h" +#include "common/common_types.h" +#include "common/logging/log.h" + +namespace AudioCore { + +/// The Lanczos kernel +static double Lanczos(size_t a, double x) { + if (x == 0.0) + return 1.0; + const double px = M_PI * x; + return a * std::sin(px) * std::sin(px / a) / (px * px); +} + +std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, double ratio) { + if (input.size() < 2) + return {}; + + if (ratio <= 0) { + LOG_CRITICAL(Audio, "Nonsensical interpolation ratio {}", ratio); + ratio = 1.0; + } + + if (ratio != state.current_ratio) { + const double cutoff_frequency = std::min(0.5 / ratio, 0.5 * ratio); + state.nyquist = CascadingFilter::LowPass(std::clamp(cutoff_frequency, 0.0, 0.4), 3); + state.current_ratio = ratio; + } + state.nyquist.Process(input); + + constexpr size_t taps = InterpolationState::lanczos_taps; + const size_t num_frames = input.size() / 2; + + std::vector<s16> output; + output.reserve(static_cast<size_t>(input.size() / ratio + 4)); + + double& pos = state.position; + auto& h = state.history; + for (size_t i = 0; i < num_frames; ++i) { + std::rotate(h.begin(), h.end() - 1, h.end()); + h[0][0] = input[i * 2 + 0]; + h[0][1] = input[i * 2 + 1]; + + while (pos <= 1.0) { + double l = 0.0; + double r = 0.0; + for (size_t j = 0; j < h.size(); j++) { + l += Lanczos(taps, pos + j - taps + 1) * h[j][0]; + r += Lanczos(taps, pos + j - taps + 1) * h[j][1]; + } + output.emplace_back(static_cast<s16>(std::clamp(l, -32768.0, 32767.0))); + output.emplace_back(static_cast<s16>(std::clamp(r, -32768.0, 32767.0))); + + pos += ratio; + } + pos -= 1.0; + } + + return output; +} + +} // namespace AudioCore diff --git a/src/audio_core/algorithm/interpolate.h b/src/audio_core/algorithm/interpolate.h new file mode 100644 index 000000000..c79c2eef4 --- /dev/null +++ b/src/audio_core/algorithm/interpolate.h @@ -0,0 +1,43 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <vector> +#include "audio_core/algorithm/filter.h" +#include "common/common_types.h" + +namespace AudioCore { + +struct InterpolationState { + static constexpr size_t lanczos_taps = 4; + static constexpr size_t history_size = lanczos_taps * 2 - 1; + + double current_ratio = 0.0; + CascadingFilter nyquist; + std::array<std::array<s16, 2>, history_size> history = {}; + double position = 0; +}; + +/// Interpolates input signal to produce output signal. +/// @param input The signal to interpolate. +/// @param ratio Interpolation ratio. +/// ratio > 1.0 results in fewer output samples. +/// ratio < 1.0 results in more output samples. +/// @returns Output signal. +std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, double ratio); + +/// Interpolates input signal to produce output signal. +/// @param input The signal to interpolate. +/// @param input_rate The sample rate of input. +/// @param output_rate The desired sample rate of the output. +/// @returns Output signal. +inline std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, + u32 input_rate, u32 output_rate) { + const double ratio = static_cast<double>(input_rate) / static_cast<double>(output_rate); + return Interpolate(state, std::move(input), ratio); +} + +} // namespace AudioCore diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp index 3dfdf61f9..12632a95c 100644 --- a/src/audio_core/audio_out.cpp +++ b/src/audio_core/audio_out.cpp @@ -27,16 +27,16 @@ static Stream::Format ChannelsToStreamFormat(u32 num_channels) { return {}; } -StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, +StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, Stream::ReleaseCallback&& release_callback) { if (!sink) { const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id); sink = sink_details.factory(Settings::values.audio_device_id); } - return std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels), - std::move(release_callback), - sink->AcquireSinkStream(sample_rate, num_channels)); + return std::make_shared<Stream>( + sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback), + sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name)); } std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { @@ -51,7 +51,7 @@ void AudioOut::StopStream(StreamPtr stream) { stream->Stop(); } -bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data) { +bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data) { return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data))); } diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h index 95e9b53fe..39b7e656b 100644 --- a/src/audio_core/audio_out.h +++ b/src/audio_core/audio_out.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <string> #include <vector> #include "audio_core/buffer.h" @@ -20,7 +21,7 @@ namespace AudioCore { class AudioOut { public: /// Opens a new audio stream - StreamPtr OpenStream(u32 sample_rate, u32 num_channels, + StreamPtr OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, Stream::ReleaseCallback&& release_callback); /// Returns a vector of recently released buffers specified by tag for the specified stream @@ -33,7 +34,7 @@ public: void StopStream(StreamPtr stream); /// Queues a buffer into the specified audio stream, returns true on success - bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data); + bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data); private: SinkPtr sink; diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp new file mode 100644 index 000000000..397b107f5 --- /dev/null +++ b/src/audio_core/audio_renderer.cpp @@ -0,0 +1,249 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "audio_core/algorithm/interpolate.h" +#include "audio_core/audio_renderer.h" +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/memory.h" + +namespace AudioCore { + +constexpr u32 STREAM_SAMPLE_RATE{48000}; +constexpr u32 STREAM_NUM_CHANNELS{2}; + +AudioRenderer::AudioRenderer(AudioRendererParameter params, + Kernel::SharedPtr<Kernel::Event> buffer_event) + : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { + + audio_core = std::make_unique<AudioCore::AudioOut>(); + stream = audio_core->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", + [=]() { buffer_event->Signal(); }); + audio_core->StartStream(stream); + + QueueMixedBuffer(0); + QueueMixedBuffer(1); + QueueMixedBuffer(2); +} + +u32 AudioRenderer::GetSampleRate() const { + return worker_params.sample_rate; +} + +u32 AudioRenderer::GetSampleCount() const { + return worker_params.sample_count; +} + +u32 AudioRenderer::GetMixBufferCount() const { + return worker_params.mix_buffer_count; +} + +std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { + // Copy UpdateDataHeader struct + UpdateDataHeader config{}; + std::memcpy(&config, input_params.data(), sizeof(UpdateDataHeader)); + u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); + + // Copy MemoryPoolInfo structs + std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); + std::memcpy(mem_pool_info.data(), + input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size, + memory_pool_count * sizeof(MemoryPoolInfo)); + + // Copy VoiceInfo structs + size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + + config.voice_resource_size}; + for (auto& voice : voices) { + std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); + offset += sizeof(VoiceInfo); + } + + // Update voices + for (auto& voice : voices) { + voice.UpdateState(); + if (!voice.GetInfo().is_in_use) { + continue; + } + if (voice.GetInfo().is_new) { + voice.SetWaveIndex(voice.GetInfo().wave_buffer_head); + } + } + + // Update memory pool state + std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); + for (size_t index = 0; index < memory_pool.size(); ++index) { + if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { + memory_pool[index].state = MemoryPoolStates::Attached; + } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { + memory_pool[index].state = MemoryPoolStates::Detached; + } + } + + // Release previous buffers and queue next ones for playback + ReleaseAndQueueBuffers(); + + // Copy output header + UpdateDataHeader response_data{worker_params}; + std::vector<u8> output_params(response_data.total_size); + std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); + + // Copy output memory pool entries + std::memcpy(output_params.data() + sizeof(UpdateDataHeader), memory_pool.data(), + response_data.memory_pools_size); + + // Copy output voice status + size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size}; + for (const auto& voice : voices) { + std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(), + sizeof(VoiceOutStatus)); + voice_out_status_offset += sizeof(VoiceOutStatus); + } + + return output_params; +} + +void AudioRenderer::VoiceState::SetWaveIndex(size_t index) { + wave_index = index & 3; + is_refresh_pending = true; +} + +std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) { + if (!IsPlaying()) { + return {}; + } + + if (is_refresh_pending) { + RefreshBuffer(); + } + + const size_t max_size{samples.size() - offset}; + const size_t dequeue_offset{offset}; + size_t size{sample_count * STREAM_NUM_CHANNELS}; + if (size > max_size) { + size = max_size; + } + + out_status.played_sample_count += size / STREAM_NUM_CHANNELS; + offset += size; + + const auto& wave_buffer{info.wave_buffer[wave_index]}; + if (offset == samples.size()) { + offset = 0; + + if (!wave_buffer.is_looping) { + SetWaveIndex(wave_index + 1); + } + + out_status.wave_buffer_consumed++; + + if (wave_buffer.end_of_stream) { + info.play_state = PlayState::Paused; + } + } + + return {samples.begin() + dequeue_offset, samples.begin() + dequeue_offset + size}; +} + +void AudioRenderer::VoiceState::UpdateState() { + if (is_in_use && !info.is_in_use) { + // No longer in use, reset state + is_refresh_pending = true; + wave_index = 0; + offset = 0; + out_status = {}; + } + is_in_use = info.is_in_use; +} + +void AudioRenderer::VoiceState::RefreshBuffer() { + std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16)); + Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(), + info.wave_buffer[wave_index].buffer_sz); + + switch (static_cast<Codec::PcmFormat>(info.sample_format)) { + case Codec::PcmFormat::Int16: { + // PCM16 is played as-is + break; + } + case Codec::PcmFormat::Adpcm: { + // Decode ADPCM to PCM16 + Codec::ADPCM_Coeff coeffs; + Memory::ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff)); + new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()), + new_samples.size() * sizeof(s16), coeffs, adpcm_state); + break; + } + default: + LOG_CRITICAL(Audio, "Unimplemented sample_format={}", info.sample_format); + UNREACHABLE(); + break; + } + + switch (info.channel_count) { + case 1: + // 1 channel is upsampled to 2 channel + samples.resize(new_samples.size() * 2); + for (size_t index = 0; index < new_samples.size(); ++index) { + samples[index * 2] = new_samples[index]; + samples[index * 2 + 1] = new_samples[index]; + } + break; + case 2: { + // 2 channel is played as is + samples = std::move(new_samples); + break; + } + default: + LOG_CRITICAL(Audio, "Unimplemented channel_count={}", info.channel_count); + UNREACHABLE(); + break; + } + + samples = Interpolate(interp_state, std::move(samples), Info().sample_rate, STREAM_SAMPLE_RATE); + + is_refresh_pending = false; +} + +static constexpr s16 ClampToS16(s32 value) { + return static_cast<s16>(std::clamp(value, -32768, 32767)); +} + +void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { + constexpr size_t BUFFER_SIZE{512}; + std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels()); + + for (auto& voice : voices) { + if (!voice.IsPlaying()) { + continue; + } + + size_t offset{}; + s64 samples_remaining{BUFFER_SIZE}; + while (samples_remaining > 0) { + const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)}; + + if (samples.empty()) { + break; + } + + samples_remaining -= samples.size() / stream->GetNumChannels(); + + for (const auto& sample : samples) { + const s32 buffer_sample{buffer[offset]}; + buffer[offset++] = + ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume)); + } + } + } + audio_core->QueueBuffer(stream, tag, std::move(buffer)); +} + +void AudioRenderer::ReleaseAndQueueBuffers() { + const auto released_buffers{audio_core->GetTagsAndReleaseBuffers(stream, 2)}; + for (const auto& tag : released_buffers) { + QueueMixedBuffer(tag); + } +} + +} // namespace AudioCore diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h new file mode 100644 index 000000000..eba67f28e --- /dev/null +++ b/src/audio_core/audio_renderer.h @@ -0,0 +1,211 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <memory> +#include <vector> + +#include "audio_core/algorithm/interpolate.h" +#include "audio_core/audio_out.h" +#include "audio_core/codec.h" +#include "audio_core/stream.h" +#include "common/common_types.h" +#include "common/swap.h" +#include "core/hle/kernel/event.h" + +namespace AudioCore { + +enum class PlayState : u8 { + Started = 0, + Stopped = 1, + Paused = 2, +}; + +struct AudioRendererParameter { + u32_le sample_rate; + u32_le sample_count; + u32_le mix_buffer_count; + u32_le unknown_c; + u32_le voice_count; + u32_le sink_count; + u32_le effect_count; + u32_le unknown_1c; + u8 unknown_20; + INSERT_PADDING_BYTES(3); + u32_le splitter_count; + u32_le unknown_2c; + INSERT_PADDING_WORDS(1); + u32_le revision; +}; +static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size"); + +enum class MemoryPoolStates : u32 { // Should be LE + Invalid = 0x0, + Unknown = 0x1, + RequestDetach = 0x2, + Detached = 0x3, + RequestAttach = 0x4, + Attached = 0x5, + Released = 0x6, +}; + +struct MemoryPoolEntry { + MemoryPoolStates state; + u32_le unknown_4; + u32_le unknown_8; + u32_le unknown_c; +}; +static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); + +struct MemoryPoolInfo { + u64_le pool_address; + u64_le pool_size; + MemoryPoolStates pool_state; + INSERT_PADDING_WORDS(3); // Unknown +}; +static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); +struct BiquadFilter { + u8 enable; + INSERT_PADDING_BYTES(1); + std::array<s16_le, 3> numerator; + std::array<s16_le, 2> denominator; +}; +static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); + +struct WaveBuffer { + u64_le buffer_addr; + u64_le buffer_sz; + s32_le start_sample_offset; + s32_le end_sample_offset; + u8 is_looping; + u8 end_of_stream; + u8 sent_to_server; + INSERT_PADDING_BYTES(5); + u64 context_addr; + u64 context_sz; + INSERT_PADDING_BYTES(8); +}; +static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); + +struct VoiceInfo { + u32_le id; + u32_le node_id; + u8 is_new; + u8 is_in_use; + PlayState play_state; + u8 sample_format; + u32_le sample_rate; + u32_le priority; + u32_le sorting_order; + u32_le channel_count; + float_le pitch; + float_le volume; + std::array<BiquadFilter, 2> biquad_filter; + u32_le wave_buffer_count; + u32_le wave_buffer_head; + INSERT_PADDING_WORDS(1); + u64_le additional_params_addr; + u64_le additional_params_sz; + u32_le mix_id; + u32_le splitter_info_id; + std::array<WaveBuffer, 4> wave_buffer; + std::array<u32_le, 6> voice_channel_resource_ids; + INSERT_PADDING_BYTES(24); +}; +static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); + +struct VoiceOutStatus { + u64_le played_sample_count; + u32_le wave_buffer_consumed; + u32_le voice_drops_count; +}; +static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); + +struct UpdateDataHeader { + UpdateDataHeader() {} + + explicit UpdateDataHeader(const AudioRendererParameter& config) { + revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision + behavior_size = 0xb0; + memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; + voices_size = config.voice_count * 0x10; + voice_resource_size = 0x0; + effects_size = config.effect_count * 0x10; + mixes_size = 0x0; + sinks_size = config.sink_count * 0x20; + performance_manager_size = 0x10; + total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + + effects_size + sinks_size + performance_manager_size; + } + + u32_le revision; + u32_le behavior_size; + u32_le memory_pools_size; + u32_le voices_size; + u32_le voice_resource_size; + u32_le effects_size; + u32_le mixes_size; + u32_le sinks_size; + u32_le performance_manager_size; + INSERT_PADDING_WORDS(6); + u32_le total_size; +}; +static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); + +class AudioRenderer { +public: + AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event); + std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); + void QueueMixedBuffer(Buffer::Tag tag); + void ReleaseAndQueueBuffers(); + u32 GetSampleRate() const; + u32 GetSampleCount() const; + u32 GetMixBufferCount() const; + +private: + class VoiceState { + public: + bool IsPlaying() const { + return is_in_use && info.play_state == PlayState::Started; + } + + const VoiceOutStatus& GetOutStatus() const { + return out_status; + } + + const VoiceInfo& GetInfo() const { + return info; + } + + VoiceInfo& Info() { + return info; + } + + void SetWaveIndex(size_t index); + std::vector<s16> DequeueSamples(size_t sample_count); + void UpdateState(); + void RefreshBuffer(); + + private: + bool is_in_use{}; + bool is_refresh_pending{}; + size_t wave_index{}; + size_t offset{}; + Codec::ADPCMState adpcm_state{}; + InterpolationState interp_state{}; + std::vector<s16> samples; + VoiceOutStatus out_status{}; + VoiceInfo info{}; + }; + + AudioRendererParameter worker_params; + Kernel::SharedPtr<Kernel::Event> buffer_event; + std::vector<VoiceState> voices; + std::unique_ptr<AudioCore::AudioOut> audio_core; + AudioCore::StreamPtr stream; +}; + +} // namespace AudioCore diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h index 4bf5fd58a..a323b23ec 100644 --- a/src/audio_core/buffer.h +++ b/src/audio_core/buffer.h @@ -18,11 +18,16 @@ class Buffer { public: using Tag = u64; - Buffer(Tag tag, std::vector<u8>&& data) : tag{tag}, data{std::move(data)} {} + Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {} /// Returns the raw audio data for the buffer - const std::vector<u8>& GetData() const { - return data; + std::vector<s16>& Samples() { + return samples; + } + + /// Returns the raw audio data for the buffer + const std::vector<s16>& GetSamples() const { + return samples; } /// Returns the buffer tag, this is provided by the game to the audout service @@ -32,7 +37,7 @@ public: private: Tag tag; - std::vector<u8> data; + std::vector<s16> samples; }; using BufferPtr = std::shared_ptr<Buffer>; diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp new file mode 100644 index 000000000..c3021403f --- /dev/null +++ b/src/audio_core/codec.cpp @@ -0,0 +1,77 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <algorithm> + +#include "audio_core/codec.h" + +namespace AudioCore::Codec { + +std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, + ADPCMState& state) { + // GC-ADPCM with scale factor and variable coefficients. + // Frames are 8 bytes long containing 14 samples each. + // Samples are 4 bits (one nibble) long. + + constexpr size_t FRAME_LEN = 8; + constexpr size_t SAMPLES_PER_FRAME = 14; + constexpr std::array<int, 16> SIGNED_NIBBLES = { + {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; + + const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; + const size_t ret_size = + sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. + std::vector<s16> ret(ret_size); + + int yn1 = state.yn1, yn2 = state.yn2; + + const size_t NUM_FRAMES = + (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. + for (size_t framei = 0; framei < NUM_FRAMES; framei++) { + const int frame_header = data[framei * FRAME_LEN]; + const int scale = 1 << (frame_header & 0xF); + const int idx = (frame_header >> 4) & 0x7; + + // Coefficients are fixed point with 11 bits fractional part. + const int coef1 = coeff[idx * 2 + 0]; + const int coef2 = coeff[idx * 2 + 1]; + + // Decodes an audio sample. One nibble produces one sample. + const auto decode_sample = [&](const int nibble) -> s16 { + const int xn = nibble * scale; + // We first transform everything into 11 bit fixed point, perform the second order + // digital filter, then transform back. + // 0x400 == 0.5 in 11 bit fixed point. + // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2] + int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11; + // Clamp to output range. + val = std::clamp<s32>(val, -32768, 32767); + // Advance output feedback. + yn2 = yn1; + yn1 = val; + return static_cast<s16>(val); + }; + + size_t outputi = framei * SAMPLES_PER_FRAME; + size_t datai = framei * FRAME_LEN + 1; + for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { + const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]); + ret[outputi] = sample1; + outputi++; + + const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]); + ret[outputi] = sample2; + outputi++; + + datai++; + } + } + + state.yn1 = yn1; + state.yn2 = yn2; + + return ret; +} + +} // namespace AudioCore::Codec diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h new file mode 100644 index 000000000..3f845c42c --- /dev/null +++ b/src/audio_core/codec.h @@ -0,0 +1,44 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <vector> + +#include "common/common_types.h" + +namespace AudioCore::Codec { + +enum class PcmFormat : u32 { + Invalid = 0, + Int8 = 1, + Int16 = 2, + Int24 = 3, + Int32 = 4, + PcmFloat = 5, + Adpcm = 6, +}; + +/// See: Codec::DecodeADPCM +struct ADPCMState { + // Two historical samples from previous processed buffer, + // required for ADPCM decoding + s16 yn1; ///< y[n-1] + s16 yn2; ///< y[n-2] +}; + +using ADPCM_Coeff = std::array<s16, 16>; + +/** + * @param data Pointer to buffer that contains ADPCM data to decode + * @param size Size of buffer in bytes + * @param coeff ADPCM coefficients + * @param state ADPCM state, this is updated with new state + * @return Decoded stereo signed PCM16 data, sample_count in length + */ +std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, + ADPCMState& state); + +}; // namespace AudioCore::Codec diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 34ae5b062..5a1177d0c 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <cstring> +#include <mutex> #include "audio_core/cubeb_sink.h" #include "audio_core/stream.h" @@ -13,20 +14,30 @@ namespace AudioCore { class SinkStreamImpl final : public SinkStream { public: - SinkStreamImpl(cubeb* ctx, cubeb_devid output_device) : ctx{ctx} { - cubeb_stream_params params; - params.rate = 48000; - params.channels = GetNumChannels(); + SinkStreamImpl(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, + const std::string& name) + : ctx{ctx}, num_channels{num_channels_} { + + if (num_channels == 6) { + // 6-channel audio does not seem to work with cubeb + SDL, so we downsample this to 2 + // channel for now + is_6_channel = true; + num_channels = 2; + } + + cubeb_stream_params params{}; + params.rate = sample_rate; + params.channels = num_channels; params.format = CUBEB_SAMPLE_S16NE; - params.layout = CUBEB_LAYOUT_STEREO; + params.layout = num_channels == 1 ? CUBEB_LAYOUT_MONO : CUBEB_LAYOUT_STEREO; - u32 minimum_latency = 0; + u32 minimum_latency{}; if (cubeb_get_min_latency(ctx, ¶ms, &minimum_latency) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "Error getting minimum latency"); } - if (cubeb_stream_init(ctx, &stream_backend, "yuzu Audio Output", nullptr, nullptr, - output_device, ¶ms, std::max(512u, minimum_latency), + if (cubeb_stream_init(ctx, &stream_backend, name.c_str(), nullptr, nullptr, output_device, + ¶ms, std::max(512u, minimum_latency), &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback, this) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream"); @@ -51,33 +62,31 @@ public: cubeb_stream_destroy(stream_backend); } - void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) override { + void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) override { if (!ctx) { return; } - queue.reserve(queue.size() + sample_count * GetNumChannels()); + std::lock_guard lock{queue_mutex}; - if (num_channels == 2) { - // Copy as-is - std::copy(samples, samples + sample_count * GetNumChannels(), - std::back_inserter(queue)); - } else if (num_channels == 6) { + queue.reserve(queue.size() + samples.size() * GetNumChannels()); + + if (is_6_channel) { // Downsample 6 channels to 2 - const size_t sample_count_copy_size = sample_count * num_channels * 2; + const size_t sample_count_copy_size = samples.size() * 2; queue.reserve(sample_count_copy_size); - for (size_t i = 0; i < sample_count * num_channels; i += num_channels) { + for (size_t i = 0; i < samples.size(); i += num_channels) { queue.push_back(samples[i]); queue.push_back(samples[i + 1]); } } else { - ASSERT_MSG(false, "Unimplemented"); + // Copy as-is + std::copy(samples.begin(), samples.end(), std::back_inserter(queue)); } } u32 GetNumChannels() const { - // Only support 2-channel stereo output for now - return 2; + return num_channels; } private: @@ -85,7 +94,10 @@ private: cubeb* ctx{}; cubeb_stream* stream_backend{}; + u32 num_channels{}; + bool is_6_channel{}; + std::mutex queue_mutex; std::vector<s16> queue; static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, @@ -129,8 +141,10 @@ CubebSink::~CubebSink() { cubeb_destroy(ctx); } -SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels) { - sink_streams.push_back(std::make_unique<SinkStreamImpl>(ctx, output_device)); +SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) { + sink_streams.push_back( + std::make_unique<SinkStreamImpl>(ctx, sample_rate, num_channels, output_device, name)); return *sink_streams.back(); } @@ -143,6 +157,8 @@ long SinkStreamImpl::DataCallback(cubeb_stream* stream, void* user_data, const v return {}; } + std::lock_guard lock{impl->queue_mutex}; + const size_t frames_to_write{ std::min(impl->queue.size() / impl->GetNumChannels(), static_cast<size_t>(num_frames))}; diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h index d07113f1f..59cbf05e9 100644 --- a/src/audio_core/cubeb_sink.h +++ b/src/audio_core/cubeb_sink.h @@ -18,7 +18,8 @@ public: explicit CubebSink(std::string device_id); ~CubebSink() override; - SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) override; + SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) override; private: cubeb* ctx{}; diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index 2e04438f7..f235d93e5 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -13,14 +13,14 @@ public: explicit NullSink(std::string){}; ~NullSink() override = default; - SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/) override { + SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/, + const std::string& /*name*/) override { return null_sink_stream; } private: struct NullSinkStreamImpl final : SinkStream { - void EnqueueSamples(u32 /*num_channels*/, const s16* /*samples*/, - size_t /*sample_count*/) override {} + void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {} } null_sink_stream; }; diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h index d1bb98c3d..95c7b2b6e 100644 --- a/src/audio_core/sink.h +++ b/src/audio_core/sink.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <string> #include "audio_core/sink_stream.h" #include "common/common_types.h" @@ -21,7 +22,8 @@ constexpr char auto_device_name[] = "auto"; class Sink { public: virtual ~Sink() = default; - virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) = 0; + virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) = 0; }; using SinkPtr = std::unique_ptr<Sink>; diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h index e7a3f01b0..41b6736d8 100644 --- a/src/audio_core/sink_stream.h +++ b/src/audio_core/sink_stream.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <vector> #include "common/common_types.h" @@ -22,9 +23,8 @@ public: * Feed stereo samples to sink. * @param num_channels Number of channels used. * @param samples Samples in interleaved stereo PCM16 format. - * @param sample_count Number of samples. */ - virtual void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) = 0; + virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0; }; using SinkStreamPtr = std::unique_ptr<SinkStream>; diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index a0045b7a1..ad9e2915c 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -32,17 +32,13 @@ u32 Stream::GetNumChannels() const { return {}; } -u32 Stream::GetSampleSize() const { - return GetNumChannels() * 2; -} - Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, - SinkStream& sink_stream) + SinkStream& sink_stream, std::string&& name_) : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, - sink_stream{sink_stream} { + sink_stream{sink_stream}, name{std::move(name_)} { release_event = CoreTiming::RegisterEvent( - "Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); + name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); } void Stream::Play() { @@ -55,17 +51,15 @@ void Stream::Stop() { } s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { - const size_t num_samples{buffer.GetData().size() / GetSampleSize()}; + const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); } -static std::vector<s16> GetVolumeAdjustedSamples(const std::vector<u8>& data) { - std::vector<s16> samples(data.size() / sizeof(s16)); - std::memcpy(samples.data(), data.data(), data.size()); +static void VolumeAdjustSamples(std::vector<s16>& samples) { const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)}; if (volume == 1.0f) { - return samples; + return; } // Implementation of a volume slider with a dynamic range of 60 dB @@ -73,8 +67,6 @@ static std::vector<s16> GetVolumeAdjustedSamples(const std::vector<u8>& data) { for (auto& sample : samples) { sample = static_cast<s16>(sample * volume_scale_factor); } - - return samples; } void Stream::PlayNextBuffer() { @@ -96,14 +88,14 @@ void Stream::PlayNextBuffer() { active_buffer = queued_buffers.front(); queued_buffers.pop(); - const size_t sample_count{active_buffer->GetData().size() / GetSampleSize()}; - sink_stream.EnqueueSamples( - GetNumChannels(), GetVolumeAdjustedSamples(active_buffer->GetData()).data(), sample_count); + VolumeAdjustSamples(active_buffer->Samples()); + sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); } void Stream::ReleaseActiveBuffer() { + ASSERT(active_buffer); released_buffers.push(std::move(active_buffer)); release_callback(); PlayNextBuffer(); diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 35253920e..049b92ca9 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h @@ -6,6 +6,7 @@ #include <functional> #include <memory> +#include <string> #include <vector> #include <queue> @@ -33,7 +34,7 @@ public: using ReleaseCallback = std::function<void()>; Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, - SinkStream& sink_stream); + SinkStream& sink_stream, std::string&& name_); /// Plays the audio stream void Play(); @@ -68,9 +69,6 @@ public: /// Gets the number of channels u32 GetNumChannels() const; - /// Gets the sample size in bytes - u32 GetSampleSize() const; - private: /// Current state of the stream enum class State { @@ -96,6 +94,7 @@ private: std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream SinkStream& sink_stream; ///< Output sink for the stream + std::string name; ///< Name of the stream, must be unique }; using StreamPtr = std::shared_ptr<Stream>; diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d5d4f6f82..939b8a7d3 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -29,8 +29,6 @@ add_library(common STATIC assert.h bit_field.h bit_set.h - break_points.cpp - break_points.h cityhash.cpp cityhash.h color.h diff --git a/src/common/alignment.h b/src/common/alignment.h index b77da4a92..b9dd38746 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -9,13 +9,13 @@ namespace Common { template <typename T> constexpr T AlignUp(T value, size_t size) { - static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); + static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); return static_cast<T>(value + (size - value % size) % size); } template <typename T> constexpr T AlignDown(T value, size_t size) { - static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); + static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); return static_cast<T>(value - value % size); } diff --git a/src/common/bit_set.h b/src/common/bit_set.h index 84e3cbe58..5a197d8c1 100644 --- a/src/common/bit_set.h +++ b/src/common/bit_set.h @@ -96,7 +96,7 @@ static inline int LeastSignificantSetBit(u64 val) { template <typename IntTy> class BitSet { - static_assert(!std::is_signed<IntTy>::value, "BitSet should not be used with signed types"); + static_assert(!std::is_signed_v<IntTy>, "BitSet should not be used with signed types"); public: // A reference to a particular bit, returned from operator[]. diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp deleted file mode 100644 index fa367a4ca..000000000 --- a/src/common/break_points.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <algorithm> -#include <sstream> -#include "common/break_points.h" - -bool BreakPoints::IsAddressBreakPoint(u32 iAddress) const { - auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - return it != m_BreakPoints.end(); -} - -bool BreakPoints::IsTempBreakPoint(u32 iAddress) const { - auto cond = [&iAddress](const TBreakPoint& bp) { - return bp.iAddress == iAddress && bp.bTemporary; - }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - return it != m_BreakPoints.end(); -} - -BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const { - TBreakPointsStr bps; - for (auto breakpoint : m_BreakPoints) { - if (!breakpoint.bTemporary) { - std::stringstream bp; - bp << std::hex << breakpoint.iAddress << " " << (breakpoint.bOn ? "n" : ""); - bps.push_back(bp.str()); - } - } - - return bps; -} - -void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) { - for (auto bps_item : bps) { - TBreakPoint bp; - std::stringstream bpstr; - bpstr << std::hex << bps_item; - bpstr >> bp.iAddress; - bp.bOn = bps_item.find("n") != bps_item.npos; - bp.bTemporary = false; - Add(bp); - } -} - -void BreakPoints::Add(const TBreakPoint& bp) { - if (!IsAddressBreakPoint(bp.iAddress)) { - m_BreakPoints.push_back(bp); - // if (jit) - // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); - } -} - -void BreakPoints::Add(u32 em_address, bool temp) { - if (!IsAddressBreakPoint(em_address)) // only add new addresses - { - TBreakPoint pt; // breakpoint settings - pt.bOn = true; - pt.bTemporary = temp; - pt.iAddress = em_address; - - m_BreakPoints.push_back(pt); - - // if (jit) - // jit->GetBlockCache()->InvalidateICache(em_address, 4); - } -} - -void BreakPoints::Remove(u32 em_address) { - auto cond = [&em_address](const TBreakPoint& bp) { return bp.iAddress == em_address; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - if (it != m_BreakPoints.end()) - m_BreakPoints.erase(it); -} - -void BreakPoints::Clear() { - // if (jit) - //{ - // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), - // [](const TBreakPoint& bp) - // { - // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); - // } - // ); - //} - - m_BreakPoints.clear(); -} diff --git a/src/common/break_points.h b/src/common/break_points.h deleted file mode 100644 index e15b9f842..000000000 --- a/src/common/break_points.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <string> -#include <vector> -#include "common/common_types.h" - -class DebugInterface; - -struct TBreakPoint { - u32 iAddress; - bool bOn; - bool bTemporary; -}; - -// Code breakpoints. -class BreakPoints { -public: - typedef std::vector<TBreakPoint> TBreakPoints; - typedef std::vector<std::string> TBreakPointsStr; - - const TBreakPoints& GetBreakPoints() { - return m_BreakPoints; - } - - TBreakPointsStr GetStrings() const; - void AddFromStrings(const TBreakPointsStr& bps); - - // is address breakpoint - bool IsAddressBreakPoint(u32 iAddress) const; - bool IsTempBreakPoint(u32 iAddress) const; - - // Add BreakPoint - void Add(u32 em_address, bool temp = false); - void Add(const TBreakPoint& bp); - - // Remove Breakpoint - void Remove(u32 iAddress); - void Clear(); - - void DeleteByAddress(u32 Address); - -private: - TBreakPoints m_BreakPoints; - u32 m_iBreakOnCount; -}; diff --git a/src/common/color.h b/src/common/color.h index 24a445dac..0379040be 100644 --- a/src/common/color.h +++ b/src/common/color.h @@ -4,6 +4,8 @@ #pragma once +#include <cstring> + #include "common/common_types.h" #include "common/swap.h" #include "common/vector_math.h" @@ -55,7 +57,7 @@ constexpr u8 Convert8To6(u8 value) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { return {bytes[3], bytes[2], bytes[1], bytes[0]}; } @@ -64,7 +66,7 @@ inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRGB8(const u8* bytes) { return {bytes[2], bytes[1], bytes[0], 255}; } @@ -73,7 +75,7 @@ inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRG8(const u8* bytes) { return {bytes[1], bytes[0], 0, 255}; } @@ -82,8 +84,9 @@ inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F), Convert5To8(pixel & 0x1F), 255}; } @@ -93,8 +96,9 @@ inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F), Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)}; } @@ -104,8 +108,9 @@ inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF), Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)}; } @@ -116,7 +121,9 @@ inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { * @return Depth value as an u32 */ inline u32 DecodeD16(const u8* bytes) { - return *reinterpret_cast<const u16_le*>(bytes); + u16_le data; + std::memcpy(&data, bytes, sizeof(data)); + return data; } /** @@ -133,7 +140,7 @@ inline u32 DecodeD24(const u8* bytes) { * @param bytes Pointer to encoded source values * @return Resulting values stored as a Math::Vec2 */ -inline const Math::Vec2<u32> DecodeD24S8(const u8* bytes) { +inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) { return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]}; } @@ -175,8 +182,10 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = + const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -185,9 +194,10 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) | - (Convert8To5(color.g()) << 6) | - (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); + const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To5(color.g()) << 6) | + (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -196,9 +206,10 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = (Convert8To4(color.r()) << 12) | - (Convert8To4(color.g()) << 8) | - (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); + const u16 data = (Convert8To4(color.r()) << 12) | (Convert8To4(color.g()) << 8) | + (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -207,7 +218,8 @@ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Pointer where to store the encoded value */ inline void EncodeD16(u32 value, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = value & 0xFFFF; + const u16_le data = static_cast<u16>(value); + std::memcpy(bytes, &data, sizeof(data)); } /** diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 7aeda737f..3ce590062 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -884,11 +884,21 @@ std::string_view RemoveTrailingSlash(std::string_view path) { return path; } -std::string SanitizePath(std::string_view path_) { +std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { std::string path(path_); - std::replace(path.begin(), path.end(), '\\', '/'); + char type1 = directory_separator == DirectorySeparator::BackwardSlash ? '/' : '\\'; + char type2 = directory_separator == DirectorySeparator::BackwardSlash ? '\\' : '/'; + + if (directory_separator == DirectorySeparator::PlatformDefault) { +#ifdef _WIN32 + type1 = '/'; + type2 = '\\'; +#endif + } + + std::replace(path.begin(), path.end(), type1, type2); path.erase(std::unique(path.begin(), path.end(), - [](char c1, char c2) { return c1 == '/' && c2 == '/'; }), + [type2](char c1, char c2) { return c1 == type2 && c2 == type2; }), path.end()); return std::string(RemoveTrailingSlash(path)); } diff --git a/src/common/file_util.h b/src/common/file_util.h index 28697d527..2711872ae 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -8,6 +8,7 @@ #include <cstdio> #include <fstream> #include <functional> +#include <limits> #include <string> #include <string_view> #include <type_traits> @@ -181,8 +182,12 @@ std::vector<T> SliceVector(const std::vector<T>& vector, size_t first, size_t la return std::vector<T>(vector.begin() + first, vector.begin() + first + last); } -// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. -std::string SanitizePath(std::string_view path); +enum class DirectorySeparator { ForwardSlash, BackwardSlash, PlatformDefault }; + +// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' +// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows +std::string SanitizePath(std::string_view path, + DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash); // simple wrapper for cstdlib file functions to // hopefully will make error checking easier @@ -207,39 +212,42 @@ public: template <typename T> size_t ReadArray(T* data, size_t length) const { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Given array does not consist of trivially copyable objects"); - if (!IsOpen()) - return -1; + if (!IsOpen()) { + return std::numeric_limits<size_t>::max(); + } return std::fread(data, sizeof(T), length, m_file); } template <typename T> size_t WriteArray(const T* data, size_t length) { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Given array does not consist of trivially copyable objects"); - if (!IsOpen()) - return -1; + if (!IsOpen()) { + return std::numeric_limits<size_t>::max(); + } + return std::fwrite(data, sizeof(T), length, m_file); } template <typename T> size_t ReadBytes(T* data, size_t length) const { - static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); + static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); return ReadArray(reinterpret_cast<char*>(data), length); } template <typename T> size_t WriteBytes(const T* data, size_t length) { - static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); + static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); return WriteArray(reinterpret_cast<const char*>(data), length); } template <typename T> size_t WriteObject(const T& object) { - static_assert(!std::is_pointer<T>::value, "Given object is a pointer"); + static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer"); return WriteArray(&object, 1); } diff --git a/src/common/hash.h b/src/common/hash.h index 73c326980..2c761e545 100644 --- a/src/common/hash.h +++ b/src/common/hash.h @@ -28,7 +28,7 @@ static inline u64 ComputeHash64(const void* data, size_t len) { */ template <typename T> static inline u64 ComputeStructHash64(const T& data) { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Type passed to ComputeStructHash64 must be trivially copyable"); return ComputeHash64(&data, sizeof(data)); } @@ -38,7 +38,7 @@ template <typename T> struct HashableStruct { // In addition to being trivially copyable, T must also have a trivial default constructor, // because any member initialization would be overridden by memset - static_assert(std::is_trivial<T>(), "Type passed to HashableStruct must be trivial"); + static_assert(std::is_trivial_v<T>, "Type passed to HashableStruct must be trivial"); /* * We use a union because "implicitly-defined copy/move constructor for a union X copies the * object representation of X." and "implicitly-defined copy assignment operator for a union X diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 816414e8d..1323f8d0f 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -171,15 +171,21 @@ void FileBackend::Write(const Entry& entry) { SUB(Service, ARP) \ SUB(Service, BCAT) \ SUB(Service, BPC) \ + SUB(Service, BTDRV) \ SUB(Service, BTM) \ SUB(Service, Capture) \ + SUB(Service, ERPT) \ + SUB(Service, ETicket) \ + SUB(Service, EUPLD) \ SUB(Service, Fatal) \ SUB(Service, FGM) \ SUB(Service, Friend) \ SUB(Service, FS) \ + SUB(Service, GRC) \ SUB(Service, HID) \ SUB(Service, LBL) \ SUB(Service, LDN) \ + SUB(Service, LDR) \ SUB(Service, LM) \ SUB(Service, Migration) \ SUB(Service, Mii) \ @@ -188,11 +194,13 @@ void FileBackend::Write(const Entry& entry) { SUB(Service, NFC) \ SUB(Service, NFP) \ SUB(Service, NIFM) \ + SUB(Service, NIM) \ SUB(Service, NS) \ SUB(Service, NVDRV) \ SUB(Service, PCIE) \ SUB(Service, PCTL) \ SUB(Service, PCV) \ + SUB(Service, PM) \ SUB(Service, PREPO) \ SUB(Service, PSC) \ SUB(Service, SET) \ @@ -200,6 +208,7 @@ void FileBackend::Write(const Entry& entry) { SUB(Service, SPL) \ SUB(Service, SSL) \ SUB(Service, Time) \ + SUB(Service, USB) \ SUB(Service, VI) \ SUB(Service, WLAN) \ CLS(HW) \ @@ -293,13 +302,14 @@ Backend* GetBackend(std::string_view backend_name) { void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, const char* format, const fmt::format_args& args) { - auto filter = Impl::Instance().GetGlobalFilter(); + auto& instance = Impl::Instance(); + const auto& filter = instance.GetGlobalFilter(); if (!filter.CheckMessage(log_class, log_level)) return; Entry entry = CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); - Impl::Instance().PushEntry(std::move(entry)); + instance.PushEntry(std::move(entry)); } } // namespace Log diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 7ab5277ea..e12f47f8f 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -58,15 +58,21 @@ enum class Class : ClassType { Service_Audio, ///< The Audio (Audio control) service Service_BCAT, ///< The BCAT service Service_BPC, ///< The BPC service + Service_BTDRV, ///< The Bluetooth driver service Service_BTM, ///< The BTM service Service_Capture, ///< The capture service + Service_ERPT, ///< The error reporting service + Service_ETicket, ///< The ETicket service + Service_EUPLD, ///< The error upload service Service_Fatal, ///< The Fatal service Service_FGM, ///< The FGM service Service_Friend, ///< The friend service Service_FS, ///< The FS (Filesystem) service + Service_GRC, ///< The game recording service Service_HID, ///< The HID (Human interface device) service Service_LBL, ///< The LBL (LCD backlight) service Service_LDN, ///< The LDN (Local domain network) service + Service_LDR, ///< The loader service Service_LM, ///< The LM (Logger) service Service_Migration, ///< The migration service Service_Mii, ///< The Mii service @@ -75,11 +81,13 @@ enum class Class : ClassType { Service_NFC, ///< The NFC (Near-field communication) service Service_NFP, ///< The NFP service Service_NIFM, ///< The NIFM (Network interface) service + Service_NIM, ///< The NIM service Service_NS, ///< The NS services Service_NVDRV, ///< The NVDRV (Nvidia driver) service Service_PCIE, ///< The PCIe service Service_PCTL, ///< The PCTL (Parental control) service Service_PCV, ///< The PCV service + Service_PM, ///< The PM service Service_PREPO, ///< The PREPO (Play report) service Service_PSC, ///< The PSC service Service_SET, ///< The SET (Settings) service @@ -87,6 +95,7 @@ enum class Class : ClassType { Service_SPL, ///< The SPL service Service_SSL, ///< The SSL service Service_Time, ///< The time service + Service_USB, ///< The USB (Universal Serial Bus) service Service_VI, ///< The VI (Video interface) service Service_WLAN, ///< The WLAN (Wireless local area network) service HW, ///< Low-level hardware emulation diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 38a450d69..133122c5f 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -16,7 +16,7 @@ struct ThreadQueueList { // (dynamically resizable) circular buffers to remove their overhead when // inserting and popping. - typedef unsigned int Priority; + using Priority = unsigned int; // Number of priority levels. (Valid levels are [0..NUM_QUEUES).) static const Priority NUM_QUEUES = N; @@ -26,9 +26,9 @@ struct ThreadQueueList { } // Only for debugging, returns priority level. - Priority contains(const T& uid) { + Priority contains(const T& uid) const { for (Priority i = 0; i < NUM_QUEUES; ++i) { - Queue& cur = queues[i]; + const Queue& cur = queues[i]; if (std::find(cur.data.cbegin(), cur.data.cend(), uid) != cur.data.cend()) { return i; } @@ -37,8 +37,8 @@ struct ThreadQueueList { return -1; } - T get_first() { - Queue* cur = first; + T get_first() const { + const Queue* cur = first; while (cur != nullptr) { if (!cur->data.empty()) { return cur->data.front(); diff --git a/src/common/vector_math.h b/src/common/vector_math.h index cca43bd4c..8feb49941 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -43,139 +43,135 @@ template <typename T> class Vec4; template <typename T> -static inline Vec2<T> MakeVec(const T& x, const T& y); -template <typename T> -static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z); -template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w); - -template <typename T> class Vec2 { public: T x{}; T y{}; - Vec2() = default; - Vec2(const T& _x, const T& _y) : x(_x), y(_y) {} + constexpr Vec2() = default; + constexpr Vec2(const T& x_, const T& y_) : x(x_), y(y_) {} template <typename T2> - Vec2<T2> Cast() const { - return Vec2<T2>((T2)x, (T2)y); + constexpr Vec2<T2> Cast() const { + return Vec2<T2>(static_cast<T2>(x), static_cast<T2>(y)); } - static Vec2 AssignToAll(const T& f) { - return Vec2<T>(f, f); + static constexpr Vec2 AssignToAll(const T& f) { + return Vec2{f, f}; } - Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { - return MakeVec(x + other.x, y + other.y); + constexpr Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { + return {x + other.x, y + other.y}; } - void operator+=(const Vec2& other) { + constexpr Vec2& operator+=(const Vec2& other) { x += other.x; y += other.y; + return *this; } - Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { - return MakeVec(x - other.x, y - other.y); + constexpr Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { + return {x - other.x, y - other.y}; } - void operator-=(const Vec2& other) { + constexpr Vec2& operator-=(const Vec2& other) { x -= other.x; y -= other.y; + return *this; } template <typename U = T> - Vec2<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y); + constexpr Vec2<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y}; } - Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { - return MakeVec(x * other.x, y * other.y); + constexpr Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { + return {x * other.x, y * other.y}; } + template <typename V> - Vec2<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f); + constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec2& operator*=(const V& f) { *this = *this * f; + return *this; } + template <typename V> - Vec2<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f); + constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec2& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y; } // Only implemented for T=float float Length() const; - void SetLength(const float l); - Vec2 WithLength(const float l) const; - float Distance2To(Vec2& other); - Vec2 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator[](int i) // allow vector[1] = 3 (vector.y=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; } // Common aliases: UV (texel coordinates), ST (texture coordinates) - T& u() { + constexpr T& u() { return x; } - T& v() { + constexpr T& v() { return y; } - T& s() { + constexpr T& s() { return x; } - T& t() { + constexpr T& t() { return y; } - const T& u() const { + constexpr const T& u() const { return x; } - const T& v() const { + constexpr const T& v() const { return y; } - const T& s() const { + constexpr const T& s() const { return x; } - const T& t() const { + constexpr const T& t() const { return y; } // swizzlers - create a subvector of specific components - const Vec2 yx() const { + constexpr Vec2 yx() const { return Vec2(y, x); } - const Vec2 vu() const { + constexpr Vec2 vu() const { return Vec2(y, x); } - const Vec2 ts() const { + constexpr Vec2 ts() const { return Vec2(y, x); } }; template <typename T, typename V> -Vec2<T> operator*(const V& f, const Vec2<T>& vec) { +constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) { return Vec2<T>(f * vec.x, f * vec.y); } -typedef Vec2<float> Vec2f; +using Vec2f = Vec2<float>; template <> inline float Vec2<float>::Length() const { @@ -196,147 +192,151 @@ public: T y{}; T z{}; - Vec3() = default; - Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {} + constexpr Vec3() = default; + constexpr Vec3(const T& x_, const T& y_, const T& z_) : x(x_), y(y_), z(z_) {} template <typename T2> - Vec3<T2> Cast() const { - return MakeVec<T2>((T2)x, (T2)y, (T2)z); + constexpr Vec3<T2> Cast() const { + return Vec3<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z)); } - // Only implemented for T=int and T=float - static Vec3 FromRGB(unsigned int rgb); - unsigned int ToRGB() const; // alpha bits set to zero - - static Vec3 AssignToAll(const T& f) { - return MakeVec(f, f, f); + static constexpr Vec3 AssignToAll(const T& f) { + return Vec3(f, f, f); } - Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { - return MakeVec(x + other.x, y + other.y, z + other.z); + constexpr Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { + return {x + other.x, y + other.y, z + other.z}; } - void operator+=(const Vec3& other) { + + constexpr Vec3& operator+=(const Vec3& other) { x += other.x; y += other.y; z += other.z; + return *this; } - Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { - return MakeVec(x - other.x, y - other.y, z - other.z); + + constexpr Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { + return {x - other.x, y - other.y, z - other.z}; } - void operator-=(const Vec3& other) { + + constexpr Vec3& operator-=(const Vec3& other) { x -= other.x; y -= other.y; z -= other.z; + return *this; } template <typename U = T> - Vec3<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y, -z); + constexpr Vec3<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y, -z}; } - Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { - return MakeVec(x * other.x, y * other.y, z * other.z); + + constexpr Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { + return {x * other.x, y * other.y, z * other.z}; } + template <typename V> - Vec3<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f, z * f); + constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f, z * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec3& operator*=(const V& f) { *this = *this * f; + return *this; } template <typename V> - Vec3<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f, z / f); + constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f, z / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec3& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y + z * z; } // Only implemented for T=float float Length() const; - void SetLength(const float l); - Vec3 WithLength(const float l) const; - float Distance2To(Vec3& other); Vec3 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator[](int i) // allow vector[2] = 3 (vector.z=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; z = 0; } // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates) - T& u() { + constexpr T& u() { return x; } - T& v() { + constexpr T& v() { return y; } - T& w() { + constexpr T& w() { return z; } - T& r() { + constexpr T& r() { return x; } - T& g() { + constexpr T& g() { return y; } - T& b() { + constexpr T& b() { return z; } - T& s() { + constexpr T& s() { return x; } - T& t() { + constexpr T& t() { return y; } - T& q() { + constexpr T& q() { return z; } - const T& u() const { + constexpr const T& u() const { return x; } - const T& v() const { + constexpr const T& v() const { return y; } - const T& w() const { + constexpr const T& w() const { return z; } - const T& r() const { + constexpr const T& r() const { return x; } - const T& g() const { + constexpr const T& g() const { return y; } - const T& b() const { + constexpr const T& b() const { return z; } - const T& s() const { + constexpr const T& s() const { return x; } - const T& t() const { + constexpr const T& t() const { return y; } - const T& q() const { + constexpr const T& q() const { return z; } @@ -345,7 +345,7 @@ public: // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all // component names (x<->r) and permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - const Vec2<T> name() const { \ + constexpr Vec2<T> name() const { \ return Vec2<T>(a, b); \ } #define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ @@ -366,7 +366,7 @@ public: }; template <typename T, typename V> -Vec3<T> operator*(const V& f, const Vec3<T>& vec) { +constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) { return Vec3<T>(f * vec.x, f * vec.y, f * vec.z); } @@ -387,7 +387,7 @@ inline float Vec3<float>::Normalize() { return length; } -typedef Vec3<float> Vec3f; +using Vec3f = Vec3<float>; template <typename T> class Vec4 { @@ -397,86 +397,88 @@ public: T z{}; T w{}; - Vec4() = default; - Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} + constexpr Vec4() = default; + constexpr Vec4(const T& x_, const T& y_, const T& z_, const T& w_) + : x(x_), y(y_), z(z_), w(w_) {} template <typename T2> - Vec4<T2> Cast() const { - return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w); + constexpr Vec4<T2> Cast() const { + return Vec4<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z), + static_cast<T2>(w)); } - // Only implemented for T=int and T=float - static Vec4 FromRGBA(unsigned int rgba); - unsigned int ToRGBA() const; - - static Vec4 AssignToAll(const T& f) { - return Vec4<T>(f, f, f, f); + static constexpr Vec4 AssignToAll(const T& f) { + return Vec4(f, f, f, f); } - Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { - return MakeVec(x + other.x, y + other.y, z + other.z, w + other.w); + constexpr Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { + return {x + other.x, y + other.y, z + other.z, w + other.w}; } - void operator+=(const Vec4& other) { + + constexpr Vec4& operator+=(const Vec4& other) { x += other.x; y += other.y; z += other.z; w += other.w; + return *this; } - Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { - return MakeVec(x - other.x, y - other.y, z - other.z, w - other.w); + + constexpr Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { + return {x - other.x, y - other.y, z - other.z, w - other.w}; } - void operator-=(const Vec4& other) { + + constexpr Vec4& operator-=(const Vec4& other) { x -= other.x; y -= other.y; z -= other.z; w -= other.w; + return *this; } template <typename U = T> - Vec4<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y, -z, -w); + constexpr Vec4<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y, -z, -w}; } - Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { - return MakeVec(x * other.x, y * other.y, z * other.z, w * other.w); + + constexpr Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { + return {x * other.x, y * other.y, z * other.z, w * other.w}; } + template <typename V> - Vec4<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f, z * f, w * f); + constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f, z * f, w * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec4& operator*=(const V& f) { *this = *this * f; + return *this; } + template <typename V> - Vec4<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f, z / f, w / f); + constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f, z / f, w / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec4& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y + z * z + w * w; } - // Only implemented for T=float - float Length() const; - void SetLength(const float l); - Vec4 WithLength(const float l) const; - float Distance2To(Vec4& other); - Vec4 Normalized() const; - float Normalize(); // returns the previous length, which is often useful - - T& operator[](int i) // allow vector[2] = 3 (vector.z=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; z = 0; @@ -484,29 +486,29 @@ public: } // Common alias: RGBA (colors) - T& r() { + constexpr T& r() { return x; } - T& g() { + constexpr T& g() { return y; } - T& b() { + constexpr T& b() { return z; } - T& a() { + constexpr T& a() { return w; } - const T& r() const { + constexpr const T& r() const { return x; } - const T& g() const { + constexpr const T& g() const { return y; } - const T& b() const { + constexpr const T& b() const { return z; } - const T& a() const { + constexpr const T& a() const { return w; } @@ -518,7 +520,7 @@ public: // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and // permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - const Vec2<T> name() const { \ + constexpr Vec2<T> name() const { \ return Vec2<T>(a, b); \ } #define DEFINE_SWIZZLER2_COMP1(a, a2) \ @@ -545,7 +547,7 @@ public: #undef _DEFINE_SWIZZLER2 #define _DEFINE_SWIZZLER3(a, b, c, name) \ - const Vec3<T> name() const { \ + constexpr Vec3<T> name() const { \ return Vec3<T>(a, b, c); \ } #define DEFINE_SWIZZLER3_COMP1(a, a2) \ @@ -579,51 +581,51 @@ public: }; template <typename T, typename V> -Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { - return MakeVec(f * vec.x, f * vec.y, f * vec.z, f * vec.w); +constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { + return {f * vec.x, f * vec.y, f * vec.z, f * vec.w}; } -typedef Vec4<float> Vec4f; +using Vec4f = Vec4<float>; template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { return a.x * b.x + a.y * b.y; } template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } template <typename T> -static inline Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { - return MakeVec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +constexpr Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { + return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } // linear interpolation via float: 0.0=begin, 1.0=end template <typename X> -static inline decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, - const float t) { +constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, + const float t) { return begin * (1.f - t) + end * t; } // linear interpolation via int: 0=begin, base=end template <typename X, int base> -static inline decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, - const int t) { +constexpr decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, + const int t) { return (begin * (base - t) + end * t) / base; } // bilinear interpolation. s is for interpolating x00-x01 and x10-x11, and t is for the second // interpolation. template <typename X> -inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s, - const float t) { +constexpr auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s, + const float t) { auto y0 = Lerp(x00, x01, s); auto y1 = Lerp(x10, x11, s); return Lerp(y0, y1, t); @@ -631,42 +633,42 @@ inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x1 // Utility vector factories template <typename T> -static inline Vec2<T> MakeVec(const T& x, const T& y) { +constexpr Vec2<T> MakeVec(const T& x, const T& y) { return Vec2<T>{x, y}; } template <typename T> -static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) { +constexpr Vec3<T> MakeVec(const T& x, const T& y, const T& z) { return Vec3<T>{x, y, z}; } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { +constexpr Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { return MakeVec(x, y, zw[0], zw[1]); } template <typename T> -static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { +constexpr Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { return MakeVec(xy[0], xy[1], z); } template <typename T> -static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { +constexpr Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { return MakeVec(x, yz[0], yz[1]); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { +constexpr Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { return Vec4<T>{x, y, z, w}; } template <typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { +constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { return MakeVec(xy[0], xy[1], z, w); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { +constexpr Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { return MakeVec(x, yz[0], yz[1], w); } @@ -674,17 +676,17 @@ static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { // Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error // out soon enough due to misuse of the returned structure. template <typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { +constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { return MakeVec(xy[0], xy[1], zw[0], zw[1]); } template <typename T> -static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { +constexpr Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { return MakeVec(xyz[0], xyz[1], xyz[2], w); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { +constexpr Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { return MakeVec(x, yzw[0], yzw[1], yzw[2]); } diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h index 0f52f704b..ec76e0a47 100644 --- a/src/common/x64/xbyak_util.h +++ b/src/common/x64/xbyak_util.h @@ -34,7 +34,7 @@ inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) { template <typename T> inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { - static_assert(std::is_pointer<T>(), "Argument must be a (function) pointer."); + static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer."); size_t addr = reinterpret_cast<size_t>(f); if (IsWithin2G(code, addr)) { code.call(f); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c11f017da..0b0ae5ccc 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -104,8 +104,6 @@ add_library(core STATIC hle/lock.cpp hle/lock.h hle/result.h - hle/romfs.cpp - hle/romfs.h hle/service/acc/acc.cpp hle/service/acc/acc.h hle/service/acc/acc_aa.cpp @@ -251,6 +249,10 @@ add_library(core STATIC hle/service/nvdrv/devices/nvhost_gpu.h hle/service/nvdrv/devices/nvhost_nvdec.cpp hle/service/nvdrv/devices/nvhost_nvdec.h + hle/service/nvdrv/devices/nvhost_nvjpg.cpp + hle/service/nvdrv/devices/nvhost_nvjpg.h + hle/service/nvdrv/devices/nvhost_vic.cpp + hle/service/nvdrv/devices/nvhost_vic.h hle/service/nvdrv/devices/nvmap.cpp hle/service/nvdrv/devices/nvmap.h hle/service/nvdrv/interface.cpp @@ -315,6 +317,8 @@ add_library(core STATIC hle/service/time/interface.h hle/service/time/time.cpp hle/service/time/time.h + hle/service/usb/usb.cpp + hle/service/usb/usb.h hle/service/vi/vi.cpp hle/service/vi/vi.h hle/service/vi/vi_m.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index ceb3f7683..20e5200a8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -86,7 +86,16 @@ public: } void AddTicks(u64 ticks) override { - CoreTiming::AddTicks(ticks - num_interpreted_instructions); + // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a + // rough approximation of the amount of executed ticks in the system, it may be thrown off + // if not all cores are doing a similar amount of work. Instead of doing this, we should + // device a way so that timing is consistent across all cores without increasing the ticks 4 + // times. + u64 amortized_ticks = (ticks - num_interpreted_instructions) / Core::NUM_CPU_CORES; + // Always execute at least one tick. + amortized_ticks = std::max<u64>(amortized_ticks, 1); + + CoreTiming::AddTicks(amortized_ticks); num_interpreted_instructions = 0; } u64 GetTicksRemaining() override { @@ -234,9 +243,7 @@ void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) { } void ARM_Dynarmic::PrepareReschedule() { - if (jit->IsExecuting()) { - jit->HaltExecution(); - } + jit->HaltExecution(); } void ARM_Dynarmic::ClearInstructionCache() { diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 4c11f35a4..6bc349460 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) { } Kernel::Thread* thread = Kernel::GetCurrentThread(); SaveContext(thread->context); - if (last_bkpt_hit || (num_instructions == 1)) { + if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) { last_bkpt_hit = false; GDBStub::Break(); GDBStub::SendTrap(thread, 5); diff --git a/src/core/core.cpp b/src/core/core.cpp index e01c45cdd..83d4d742b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -62,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) { // execute. Otherwise, get out of the loop function. if (GDBStub::GetCpuHaltFlag()) { if (GDBStub::GetCpuStepFlag()) { - GDBStub::SetCpuStepFlag(false); tight_loop = false; } else { return ResultStatus::Success; @@ -78,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) { } } + if (GDBStub::IsServerEnabled()) { + GDBStub::SetCpuStepFlag(false); + } + return status; } @@ -85,8 +88,8 @@ System::ResultStatus System::SingleStep() { return RunLoop(false); } -System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) { - app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); +System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { + app_loader = Loader::GetLoader(virtual_filesystem->OpenFile(filepath, FileSys::Mode::Read)); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); @@ -99,18 +102,8 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!", static_cast<int>(system_mode.second)); - switch (system_mode.second) { - case Loader::ResultStatus::ErrorMissingKeys: - return ResultStatus::ErrorLoader_ErrorMissingKeys; - case Loader::ResultStatus::ErrorDecrypting: - return ResultStatus::ErrorLoader_ErrorDecrypting; - case Loader::ResultStatus::ErrorInvalidFormat: - return ResultStatus::ErrorLoader_ErrorInvalidFormat; - case Loader::ResultStatus::ErrorUnsupportedArch: - return ResultStatus::ErrorUnsupportedArch; - default: + if (system_mode.second != Loader::ResultStatus::Success) return ResultStatus::ErrorSystemMode; - } } ResultStatus init_result{Init(emu_window)}; @@ -126,17 +119,9 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); System::Shutdown(); - switch (load_result) { - case Loader::ResultStatus::ErrorMissingKeys: - return ResultStatus::ErrorLoader_ErrorMissingKeys; - case Loader::ResultStatus::ErrorDecrypting: - return ResultStatus::ErrorLoader_ErrorDecrypting; - case Loader::ResultStatus::ErrorInvalidFormat: - return ResultStatus::ErrorLoader_ErrorInvalidFormat; - case Loader::ResultStatus::ErrorUnsupportedArch: - return ResultStatus::ErrorUnsupportedArch; - default: - return ResultStatus::ErrorLoader; + if (load_result != Loader::ResultStatus::Success) { + return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + + static_cast<u32>(load_result)); } } status = ResultStatus::Success; @@ -166,11 +151,15 @@ Cpu& System::CpuCore(size_t core_index) { return *cpu_cores[core_index]; } -System::ResultStatus System::Init(EmuWindow& emu_window) { +System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { LOG_DEBUG(HW_Memory, "initialized OK"); CoreTiming::Init(); + // Create a default fs if one doesn't already exist. + if (virtual_filesystem == nullptr) + virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); + current_process = Kernel::Process::Create("main"); cpu_barrier = std::make_shared<CpuBarrier>(); @@ -183,7 +172,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window) { service_manager = std::make_shared<Service::SM::ServiceManager>(); Kernel::Init(); - Service::Init(service_manager); + Service::Init(service_manager, virtual_filesystem); GDBStub::Init(); renderer = VideoCore::CreateRenderer(emu_window); diff --git a/src/core/core.h b/src/core/core.h index a3be88aa8..d98b15a71 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -17,12 +17,17 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" +#include "file_sys/vfs_real.h" +#include "hle/service/filesystem/filesystem.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu.h" -class EmuWindow; class ARM_Interface; +namespace Core::Frontend { +class EmuWindow; +} + namespace Service::SM { class ServiceManager; } @@ -47,21 +52,15 @@ public: /// Enumeration representing the return values of the System Initialize and Load process. enum class ResultStatus : u32 { - Success, ///< Succeeded - ErrorNotInitialized, ///< Error trying to use core prior to initialization - ErrorGetLoader, ///< Error finding the correct application loader - ErrorSystemMode, ///< Error determining the system mode - ErrorLoader, ///< Error loading the specified application - ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be - ///< found. - ErrorLoader_ErrorDecrypting, ///< Error loading the specified application due to encryption - ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an - /// invalid format - ErrorSystemFiles, ///< Error in finding system files - ErrorSharedFont, ///< Error in finding shared font - ErrorVideoCore, ///< Error in the video core - ErrorUnsupportedArch, ///< Unsupported Architecture (32-Bit ROMs) - ErrorUnknown ///< Any other error + Success, ///< Succeeded + ErrorNotInitialized, ///< Error trying to use core prior to initialization + ErrorGetLoader, ///< Error finding the correct application loader + ErrorSystemMode, ///< Error determining the system mode + ErrorSystemFiles, ///< Error in finding system files + ErrorSharedFont, ///< Error in finding shared font + ErrorVideoCore, ///< Error in the video core + ErrorUnknown, ///< Any other error + ErrorLoader, ///< The base for loader errors (too many to repeat) }; /** @@ -82,6 +81,17 @@ public: */ ResultStatus SingleStep(); + /** + * Invalidate the CPU instruction caches + * This function should only be used by GDB Stub to support breakpoints, memory updates and + * step/continue commands. + */ + void InvalidateCpuInstructionCaches() { + for (auto& cpu : cpu_cores) { + cpu->ArmInterface().ClearInstructionCache(); + } + } + /// Shutdown the emulated system. void Shutdown(); @@ -92,7 +102,7 @@ public: * @param filepath String path to the executable application to load on the host file system. * @returns ResultStatus code, indicating if the operation succeeded. */ - ResultStatus Load(EmuWindow& emu_window, const std::string& filepath); + ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath); /** * Indicates if the emulated system is powered on (all subsystems initialized and able to run an @@ -200,6 +210,14 @@ public: return debug_context; } + void SetFilesystem(FileSys::VirtualFilesystem vfs) { + virtual_filesystem = std::move(vfs); + } + + FileSys::VirtualFilesystem GetFilesystem() const { + return virtual_filesystem; + } + private: System(); @@ -212,8 +230,10 @@ private: * input. * @return ResultStatus code, indicating if the operation succeeded. */ - ResultStatus Init(EmuWindow& emu_window); + ResultStatus Init(Frontend::EmuWindow& emu_window); + /// RealVfsFilesystem instance + FileSys::VirtualFilesystem virtual_filesystem; /// AppLoader used to load the current executing application std::unique_ptr<Loader::AppLoader> app_loader; std::unique_ptr<VideoCore::RendererBase> renderer; diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index 46a522fcd..b042ee02b 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp @@ -14,6 +14,7 @@ #include "core/core_timing.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" +#include "core/hle/lock.h" #include "core/settings.h" namespace Core { @@ -90,6 +91,7 @@ void Cpu::RunLoop(bool tight_loop) { LOG_TRACE(Core, "Core-{} idling", core_index); if (IsMainCore()) { + // TODO(Subv): Only let CoreTiming idle if all 4 cores are idling. CoreTiming::Idle(); CoreTiming::Advance(); } @@ -125,6 +127,8 @@ void Cpu::Reschedule() { } reschedule_pending = false; + // Lock the global kernel mutex when we manipulate the HLE state + std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); scheduler->Reschedule(); } diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 976952903..56cdae194 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h @@ -79,7 +79,7 @@ private: std::shared_ptr<CpuBarrier> cpu_barrier; std::shared_ptr<Kernel::Scheduler> scheduler; - bool reschedule_pending{}; + std::atomic<bool> reschedule_pending = false; size_t core_index; }; diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a1b6f96f1..f977d1b32 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -135,13 +135,11 @@ void ClearPendingEvents() { void ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 userdata) { ASSERT(event_type != nullptr); s64 timeout = GetTicks() + cycles_into_future; - // If this event needs to be scheduled before the next advance(), force one early if (!is_global_timer_sane) ForceExceptionCheck(cycles_into_future); - event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); - std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); + std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); } void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) { @@ -156,7 +154,7 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) { // Removing random items breaks the invariant so we have to re-establish it. if (itr != event_queue.end()) { event_queue.erase(itr, event_queue.end()); - std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); + std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); } } @@ -167,7 +165,7 @@ void RemoveEvent(const EventType* event_type) { // Removing random items breaks the invariant so we have to re-establish it. if (itr != event_queue.end()) { event_queue.erase(itr, event_queue.end()); - std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); + std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); } } @@ -190,7 +188,7 @@ void MoveEvents() { for (Event ev; ts_queue.Pop(ev);) { ev.fifo_order = event_fifo_id++; event_queue.emplace_back(std::move(ev)); - std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); + std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); } } @@ -205,7 +203,7 @@ void Advance() { while (!event_queue.empty() && event_queue.front().time <= global_timer) { Event evt = std::move(event_queue.front()); - std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); + std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time)); } @@ -226,8 +224,8 @@ void Idle() { downcount = 0; } -u64 GetGlobalTimeUs() { - return GetTicks() * 1000000 / BASE_CLOCK_RATE; +std::chrono::microseconds GetGlobalTimeUs() { + return std::chrono::microseconds{GetTicks() * 1000000 / BASE_CLOCK_RATE}; } int GetDowncount() { diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 7fe6380ad..dfa161c0d 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -17,12 +17,17 @@ * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") */ +#include <chrono> #include <functional> #include <string> #include "common/common_types.h" namespace CoreTiming { +struct EventType; + +using TimedCallback = std::function<void(u64 userdata, int cycles_late)>; + /** * CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is * required to end slice -1 and start slice 0 before the first cycle of code is executed. @@ -30,8 +35,6 @@ namespace CoreTiming { void Init(); void Shutdown(); -typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback; - /** * This should only be called from the emu thread, if you are calling it any other thread, you are * doing something evil @@ -40,8 +43,6 @@ u64 GetTicks(); u64 GetIdleTicks(); void AddTicks(u64 ticks); -struct EventType; - /** * Returns the event_type identifier. if name is not unique, it will assert. */ @@ -86,7 +87,7 @@ void ClearPendingEvents(); void ForceExceptionCheck(s64 cycles); -u64 GetGlobalTimeUs(); +std::chrono::microseconds GetGlobalTimeUs(); int GetDowncount(); diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 395eea8ae..8e05b9d0e 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -5,20 +5,23 @@ #include <array> #include <string> #include <core/loader/loader.h> +#include "common/logging/log.h" #include "core/file_sys/card_image.h" #include "core/file_sys/partition_filesystem.h" #include "core/file_sys/vfs_offset.h" namespace FileSys { +constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", "logo"}; + XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { if (file->ReadObject(&header) != sizeof(GamecardHeader)) { - status = Loader::ResultStatus::ErrorInvalidFormat; + status = Loader::ResultStatus::ErrorBadXCIHeader; return; } if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) { - status = Loader::ResultStatus::ErrorInvalidFormat; + status = Loader::ResultStatus::ErrorBadXCIHeader; return; } @@ -30,9 +33,6 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { return; } - static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", - "logo"}; - for (XCIPartition partition : {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]); @@ -107,19 +107,19 @@ VirtualFile XCI::GetNCAFileByType(NCAContentType type) const { return nullptr; } -std::vector<std::shared_ptr<VfsFile>> XCI::GetFiles() const { +std::vector<VirtualFile> XCI::GetFiles() const { return {}; } -std::vector<std::shared_ptr<VfsDirectory>> XCI::GetSubdirectories() const { - return std::vector<std::shared_ptr<VfsDirectory>>(); +std::vector<VirtualDir> XCI::GetSubdirectories() const { + return {}; } std::string XCI::GetName() const { return file->GetName(); } -std::shared_ptr<VfsDirectory> XCI::GetParentDirectory() const { +VirtualDir XCI::GetParentDirectory() const { return file->GetContainingDirectory(); } @@ -129,15 +129,21 @@ bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { if (partitions[static_cast<size_t>(part)] == nullptr) { - return Loader::ResultStatus::ErrorInvalidFormat; + return Loader::ResultStatus::ErrorXCIMissingPartition; } for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { if (file->GetExtension() != "nca") continue; auto nca = std::make_shared<NCA>(file); - if (nca->GetStatus() == Loader::ResultStatus::Success) + if (nca->GetStatus() == Loader::ResultStatus::Success) { ncas.push_back(std::move(nca)); + } else { + const u16 error_id = static_cast<u16>(nca->GetStatus()); + LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})", + partition_names[static_cast<size_t>(part)], nca->GetName(), error_id, + Loader::GetMessageForResultStatus(nca->GetStatus())); + } } return Loader::ResultStatus::Success; diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index e089d737c..4618d9c00 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -71,13 +71,13 @@ public: std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const; VirtualFile GetNCAFileByType(NCAContentType type) const; - std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; + std::vector<VirtualFile> GetFiles() const override; - std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; + std::vector<VirtualDir> GetSubdirectories() const override; std::string GetName() const override; - std::shared_ptr<VfsDirectory> GetParentDirectory() const override; + VirtualDir GetParentDirectory() const override; protected: bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 79e70f6ef..47afcad9b 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -76,12 +76,17 @@ bool IsValidNCA(const NCAHeader& header) { return header.magic == Common::MakeMagic('N', 'C', 'A', '3'); } -boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const { +u8 NCA::GetCryptoRevision() const { u8 master_key_id = header.crypto_type; if (header.crypto_type_2 > master_key_id) master_key_id = header.crypto_type_2; if (master_key_id > 0) --master_key_id; + return master_key_id; +} + +boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const { + const auto master_key_id = GetCryptoRevision(); if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) return boost::none; @@ -108,44 +113,105 @@ boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType ty return out; } -VirtualFile NCA::Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const { +boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() { + const auto master_key_id = GetCryptoRevision(); + + u128 rights_id{}; + memcpy(rights_id.data(), header.rights_id.data(), 16); + if (rights_id == u128{}) { + status = Loader::ResultStatus::ErrorInvalidRightsID; + return boost::none; + } + + auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]); + if (titlekey == Core::Crypto::Key128{}) { + status = Loader::ResultStatus::ErrorMissingTitlekey; + return boost::none; + } + + if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) { + status = Loader::ResultStatus::ErrorMissingTitlekek; + return boost::none; + } + + Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( + keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB); + cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt); + + return titlekey; +} + +VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) { if (!encrypted) return in; - switch (header.raw.header.crypto_type) { + switch (s_header.raw.header.crypto_type) { case NCASectionCryptoType::NONE: LOG_DEBUG(Crypto, "called with mode=NONE"); return in; case NCASectionCryptoType::CTR: LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); { - const auto key = GetKeyAreaKey(NCASectionCryptoType::CTR); - if (key == boost::none) - return nullptr; + boost::optional<Core::Crypto::Key128> key = boost::none; + if (has_rights_id) { + status = Loader::ResultStatus::Success; + key = GetTitlekey(); + if (key == boost::none) { + if (status == Loader::ResultStatus::Success) + status = Loader::ResultStatus::ErrorMissingTitlekey; + return nullptr; + } + } else { + key = GetKeyAreaKey(NCASectionCryptoType::CTR); + if (key == boost::none) { + status = Loader::ResultStatus::ErrorMissingKeyAreaKey; + return nullptr; + } + } + auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( std::move(in), key.value(), starting_offset); std::vector<u8> iv(16); for (u8 i = 0; i < 8; ++i) - iv[i] = header.raw.section_ctr[0x8 - i - 1]; + iv[i] = s_header.raw.section_ctr[0x8 - i - 1]; out->SetIV(iv); return std::static_pointer_cast<VfsFile>(out); } case NCASectionCryptoType::XTS: - // TODO(DarkLordZach): Implement XTSEncryptionLayer and title key encryption. + // TODO(DarkLordZach): Implement XTSEncryptionLayer. default: LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}", - static_cast<u8>(header.raw.header.crypto_type)); + static_cast<u8>(s_header.raw.header.crypto_type)); return nullptr; } } NCA::NCA(VirtualFile file_) : file(std::move(file_)) { - if (sizeof(NCAHeader) != file->ReadObject(&header)) + status = Loader::ResultStatus::Success; + + if (file == nullptr) { + status = Loader::ResultStatus::ErrorNullFile; + return; + } + + if (sizeof(NCAHeader) != file->ReadObject(&header)) { LOG_ERROR(Loader, "File reader errored out during header read."); + status = Loader::ResultStatus::ErrorBadNCAHeader; + return; + } encrypted = false; if (!IsValidNCA(header)) { + if (header.magic == Common::MakeMagic('N', 'C', 'A', '2')) { + status = Loader::ResultStatus::ErrorNCA2; + return; + } + if (header.magic == Common::MakeMagic('N', 'C', 'A', '0')) { + status = Loader::ResultStatus::ErrorNCA0; + return; + } + NCAHeader dec_header{}; Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); @@ -155,14 +221,26 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { header = dec_header; encrypted = true; } else { + if (dec_header.magic == Common::MakeMagic('N', 'C', 'A', '2')) { + status = Loader::ResultStatus::ErrorNCA2; + return; + } + if (dec_header.magic == Common::MakeMagic('N', 'C', 'A', '0')) { + status = Loader::ResultStatus::ErrorNCA0; + return; + } + if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) - status = Loader::ResultStatus::ErrorMissingKeys; + status = Loader::ResultStatus::ErrorMissingHeaderKey; else - status = Loader::ResultStatus::ErrorDecrypting; + status = Loader::ResultStatus::ErrorIncorrectHeaderKey; return; } } + has_rights_id = std::find_if_not(header.rights_id.begin(), header.rights_id.end(), + [](char c) { return c == '\0'; }) != header.rights_id.end(); + const std::ptrdiff_t number_sections = std::count_if(std::begin(header.section_tables), std::end(header.section_tables), [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); @@ -195,7 +273,12 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { files.push_back(std::move(dec)); romfs = files.back(); } else { - status = Loader::ResultStatus::ErrorMissingKeys; + if (status != Loader::ResultStatus::Success) + return; + if (has_rights_id) + status = Loader::ResultStatus::ErrorIncorrectTitlekeyOrTitlekek; + else + status = Loader::ResultStatus::ErrorIncorrectKeyAreaKey; return; } } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { @@ -215,7 +298,12 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { exefs = dirs.back(); } } else { - status = Loader::ResultStatus::ErrorMissingKeys; + if (status != Loader::ResultStatus::Success) + return; + if (has_rights_id) + status = Loader::ResultStatus::ErrorIncorrectTitlekeyOrTitlekek; + else + status = Loader::ResultStatus::ErrorIncorrectKeyAreaKey; return; } } diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 6492163b5..b82e65ad5 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -12,6 +12,7 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" +#include "control_metadata.h" #include "core/crypto/key_manager.h" #include "core/file_sys/partition_filesystem.h" #include "core/loader/loader.h" @@ -95,8 +96,10 @@ protected: bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; private: + u8 GetCryptoRevision() const; boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const; - VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const; + boost::optional<Core::Crypto::Key128> GetTitlekey(); + VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset); std::vector<VirtualDir> dirs; std::vector<VirtualFile> files; @@ -106,6 +109,7 @@ private: VirtualFile file; NCAHeader header{}; + bool has_rights_id{}; Loader::ResultStatus status{}; diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index cc3b745f7..6582cc240 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -62,6 +62,13 @@ enum class Language : u8 { Chinese = 14, }; +static constexpr std::array<const char*, 15> LANGUAGE_NAMES = { + "AmericanEnglish", "BritishEnglish", "Japanese", + "French", "German", "LatinAmericanSpanish", + "Spanish", "Italian", "Dutch", + "CanadianFrench", "Portugese", "Russian", + "Korean", "Taiwanese", "Chinese"}; + // A class representing the format used by NX metadata files, typically named Control.nacp. // These store application name, dev name, title id, and other miscellaneous data. class NACP { diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h index 213ce1826..3759e743a 100644 --- a/src/core/file_sys/directory.h +++ b/src/core/file_sys/directory.h @@ -4,8 +4,9 @@ #pragma once -#include <array> #include <cstddef> +#include <iterator> +#include <string_view> #include "common/common_funcs.h" #include "common/common_types.h" @@ -21,9 +22,14 @@ enum EntryType : u8 { // Structure of a directory entry, from // http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry -const size_t FILENAME_LENGTH = 0x300; struct Entry { - char filename[FILENAME_LENGTH]; + Entry(std::string_view view, EntryType entry_type, u64 entry_size) + : type{entry_type}, file_size{entry_size} { + const size_t copy_size = view.copy(filename, std::size(filename) - 1); + filename[copy_size] = '\0'; + } + + char filename[0x300]; INSERT_PADDING_BYTES(4); EntryType type; INSERT_PADDING_BYTES(3); diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 47e032b19..c377edc9c 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp @@ -24,19 +24,19 @@ bool PartitionFilesystem::Header::HasValidMagicValue() const { PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { // At least be as large as the header if (file->GetSize() < sizeof(Header)) { - status = Loader::ResultStatus::Error; + status = Loader::ResultStatus::ErrorBadPFSHeader; return; } // For cartridges, HFSs can get very large, so we need to calculate the size up to // the actual content itself instead of just blindly reading in the entire file. if (sizeof(Header) != file->ReadObject(&pfs_header)) { - status = Loader::ResultStatus::Error; + status = Loader::ResultStatus::ErrorBadPFSHeader; return; } if (!pfs_header.HasValidMagicValue()) { - status = Loader::ResultStatus::ErrorInvalidFormat; + status = Loader::ResultStatus::ErrorBadPFSHeader; return; } @@ -51,7 +51,7 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { const size_t total_size = file_data.size(); if (total_size != metadata_size) { - status = Loader::ResultStatus::Error; + status = Loader::ResultStatus::ErrorIncorrectPFSFileSize; return; } diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h index 7c7a75816..be7bc32a8 100644 --- a/src/core/file_sys/partition_filesystem.h +++ b/src/core/file_sys/partition_filesystem.h @@ -13,7 +13,7 @@ #include "core/file_sys/vfs.h" namespace Loader { -enum class ResultStatus; +enum class ResultStatus : u16; } namespace FileSys { diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 63d4b6e4f..279f987d4 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -12,26 +12,26 @@ namespace FileSys { Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { size_t total_size = static_cast<size_t>(file->GetSize()); if (total_size < sizeof(Header)) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadNPDMHeader; // TODO(DarkLordZach): Use ReadObject when Header/AcidHeader becomes trivially copyable. std::vector<u8> npdm_header_data = file->ReadBytes(sizeof(Header)); if (sizeof(Header) != npdm_header_data.size()) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadNPDMHeader; std::memcpy(&npdm_header, npdm_header_data.data(), sizeof(Header)); std::vector<u8> acid_header_data = file->ReadBytes(sizeof(AcidHeader), npdm_header.acid_offset); if (sizeof(AcidHeader) != acid_header_data.size()) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadACIDHeader; std::memcpy(&acid_header, acid_header_data.data(), sizeof(AcidHeader)); if (sizeof(AciHeader) != file->ReadObject(&aci_header, npdm_header.aci_offset)) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadACIHeader; if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadFileAccessControl; if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) - return Loader::ResultStatus::Error; + return Loader::ResultStatus::ErrorBadFileAccessHeader; return Loader::ResultStatus::Success; } diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 06a7315db..74a91052b 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -13,7 +13,7 @@ #include "partition_filesystem.h" namespace Loader { -enum class ResultStatus; +enum class ResultStatus : u16; } namespace FileSys { diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index e3a578c0f..f3cf50d5a 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -7,6 +7,7 @@ #include <memory> #include <string> #include "common/common_types.h" +#include "common/swap.h" #include "core/hle/result.h" namespace FileSys { diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index dae1c16ef..a5ec50b1a 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp @@ -4,12 +4,160 @@ #include <algorithm> #include <numeric> +#include <string> +#include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/backend.h" #include "core/file_sys/vfs.h" namespace FileSys { +VfsFilesystem::VfsFilesystem(VirtualDir root_) : root(std::move(root_)) {} + +VfsFilesystem::~VfsFilesystem() = default; + +std::string VfsFilesystem::GetName() const { + return root->GetName(); +} + +bool VfsFilesystem::IsReadable() const { + return root->IsReadable(); +} + +bool VfsFilesystem::IsWritable() const { + return root->IsWritable(); +} + +VfsEntryType VfsFilesystem::GetEntryType(std::string_view path_) const { + const auto path = FileUtil::SanitizePath(path_); + if (root->GetFileRelative(path) != nullptr) + return VfsEntryType::File; + if (root->GetDirectoryRelative(path) != nullptr) + return VfsEntryType::Directory; + + return VfsEntryType::None; +} + +VirtualFile VfsFilesystem::OpenFile(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_); + return root->GetFileRelative(path); +} + +VirtualFile VfsFilesystem::CreateFile(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_); + return root->CreateFileRelative(path); +} + +VirtualFile VfsFilesystem::CopyFile(std::string_view old_path_, std::string_view new_path_) { + const auto old_path = FileUtil::SanitizePath(old_path_); + const auto new_path = FileUtil::SanitizePath(new_path_); + + // VfsDirectory impls are only required to implement copy across the current directory. + if (FileUtil::GetParentPath(old_path) == FileUtil::GetParentPath(new_path)) { + if (!root->Copy(FileUtil::GetFilename(old_path), FileUtil::GetFilename(new_path))) + return nullptr; + return OpenFile(new_path, Mode::ReadWrite); + } + + // Do it using RawCopy. Non-default impls are encouraged to optimize this. + const auto old_file = OpenFile(old_path, Mode::Read); + if (old_file == nullptr) + return nullptr; + auto new_file = OpenFile(new_path, Mode::Read); + if (new_file != nullptr) + return nullptr; + new_file = CreateFile(new_path, Mode::Write); + if (new_file == nullptr) + return nullptr; + if (!VfsRawCopy(old_file, new_file)) + return nullptr; + return new_file; +} + +VirtualFile VfsFilesystem::MoveFile(std::string_view old_path, std::string_view new_path) { + const auto sanitized_old_path = FileUtil::SanitizePath(old_path); + const auto sanitized_new_path = FileUtil::SanitizePath(new_path); + + // Again, non-default impls are highly encouraged to provide a more optimized version of this. + auto out = CopyFile(sanitized_old_path, sanitized_new_path); + if (out == nullptr) + return nullptr; + if (DeleteFile(sanitized_old_path)) + return out; + return nullptr; +} + +bool VfsFilesystem::DeleteFile(std::string_view path_) { + const auto path = FileUtil::SanitizePath(path_); + auto parent = OpenDirectory(FileUtil::GetParentPath(path), Mode::Write); + if (parent == nullptr) + return false; + return parent->DeleteFile(FileUtil::GetFilename(path)); +} + +VirtualDir VfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_); + return root->GetDirectoryRelative(path); +} + +VirtualDir VfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_); + return root->CreateDirectoryRelative(path); +} + +VirtualDir VfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_view new_path_) { + const auto old_path = FileUtil::SanitizePath(old_path_); + const auto new_path = FileUtil::SanitizePath(new_path_); + + // Non-default impls are highly encouraged to provide a more optimized version of this. + auto old_dir = OpenDirectory(old_path, Mode::Read); + if (old_dir == nullptr) + return nullptr; + auto new_dir = OpenDirectory(new_path, Mode::Read); + if (new_dir != nullptr) + return nullptr; + new_dir = CreateDirectory(new_path, Mode::Write); + if (new_dir == nullptr) + return nullptr; + + for (const auto& file : old_dir->GetFiles()) { + const auto x = + CopyFile(old_path + DIR_SEP + file->GetName(), new_path + DIR_SEP + file->GetName()); + if (x == nullptr) + return nullptr; + } + + for (const auto& dir : old_dir->GetSubdirectories()) { + const auto x = + CopyDirectory(old_path + DIR_SEP + dir->GetName(), new_path + DIR_SEP + dir->GetName()); + if (x == nullptr) + return nullptr; + } + + return new_dir; +} + +VirtualDir VfsFilesystem::MoveDirectory(std::string_view old_path, std::string_view new_path) { + const auto sanitized_old_path = FileUtil::SanitizePath(old_path); + const auto sanitized_new_path = FileUtil::SanitizePath(new_path); + + // Non-default impls are highly encouraged to provide a more optimized version of this. + auto out = CopyDirectory(sanitized_old_path, sanitized_new_path); + if (out == nullptr) + return nullptr; + if (DeleteDirectory(sanitized_old_path)) + return out; + return nullptr; +} + +bool VfsFilesystem::DeleteDirectory(std::string_view path_) { + const auto path = FileUtil::SanitizePath(path_); + auto parent = OpenDirectory(FileUtil::GetParentPath(path), Mode::Write); + if (parent == nullptr) + return false; + return parent->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path)); +} + VfsFile::~VfsFile() = default; std::string VfsFile::GetExtension() const { diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index fab9e2b45..78a63c59b 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h @@ -11,17 +11,79 @@ #include <vector> #include "boost/optional.hpp" #include "common/common_types.h" +#include "core/file_sys/mode.h" namespace FileSys { -struct VfsFile; -struct VfsDirectory; -// Convenience typedefs to use VfsDirectory and VfsFile -using VirtualDir = std::shared_ptr<FileSys::VfsDirectory>; -using VirtualFile = std::shared_ptr<FileSys::VfsFile>; +class VfsDirectory; +class VfsFile; +class VfsFilesystem; + +// Convenience typedefs to use Vfs* interfaces +using VirtualFilesystem = std::shared_ptr<VfsFilesystem>; +using VirtualDir = std::shared_ptr<VfsDirectory>; +using VirtualFile = std::shared_ptr<VfsFile>; + +// An enumeration representing what can be at the end of a path in a VfsFilesystem +enum class VfsEntryType { + None, + File, + Directory, +}; + +// A class representing an abstract filesystem. A default implementation given the root VirtualDir +// is provided for convenience, but if the Vfs implementation has any additional state or +// functionality, they will need to override. +class VfsFilesystem : NonCopyable { +public: + explicit VfsFilesystem(VirtualDir root); + virtual ~VfsFilesystem(); + + // Gets the friendly name for the filesystem. + virtual std::string GetName() const; + + // Return whether or not the user has read permissions on this filesystem. + virtual bool IsReadable() const; + // Return whether or not the user has write permission on this filesystem. + virtual bool IsWritable() const; + + // Determine if the entry at path is non-existant, a file, or a directory. + virtual VfsEntryType GetEntryType(std::string_view path) const; + + // Opens the file with path relative to root. If it doesn't exist, returns nullptr. + virtual VirtualFile OpenFile(std::string_view path, Mode perms); + // Creates a new, empty file at path + virtual VirtualFile CreateFile(std::string_view path, Mode perms); + // Copies the file from old_path to new_path, returning the new file on success and nullptr on + // failure. + virtual VirtualFile CopyFile(std::string_view old_path, std::string_view new_path); + // Moves the file from old_path to new_path, returning the moved file on success and nullptr on + // failure. + virtual VirtualFile MoveFile(std::string_view old_path, std::string_view new_path); + // Deletes the file with path relative to root, returing true on success. + virtual bool DeleteFile(std::string_view path); + + // Opens the directory with path relative to root. If it doesn't exist, returns nullptr. + virtual VirtualDir OpenDirectory(std::string_view path, Mode perms); + // Creates a new, empty directory at path + virtual VirtualDir CreateDirectory(std::string_view path, Mode perms); + // Copies the directory from old_path to new_path, returning the new directory on success and + // nullptr on failure. + virtual VirtualDir CopyDirectory(std::string_view old_path, std::string_view new_path); + // Moves the directory from old_path to new_path, returning the moved directory on success and + // nullptr on failure. + virtual VirtualDir MoveDirectory(std::string_view old_path, std::string_view new_path); + // Deletes the directory with path relative to root, returing true on success. + virtual bool DeleteDirectory(std::string_view path); + +protected: + // Root directory in default implementation. + VirtualDir root; +}; // A class representing a file in an abstract filesystem. -struct VfsFile : NonCopyable { +class VfsFile : NonCopyable { +public: virtual ~VfsFile(); // Retrieves the file name. @@ -119,7 +181,8 @@ struct VfsFile : NonCopyable { }; // A class representing a directory in an abstract filesystem. -struct VfsDirectory : NonCopyable { +class VfsDirectory : NonCopyable { +public: virtual ~VfsDirectory(); // Retrives the file located at path as if the current directory was root. Returns nullptr if @@ -235,7 +298,8 @@ protected: // A convenience partial-implementation of VfsDirectory that stubs out methods that should only work // if writable. This is to avoid redundant empty methods everywhere. -struct ReadOnlyVfsDirectory : public VfsDirectory { +class ReadOnlyVfsDirectory : public VfsDirectory { +public: bool IsWritable() const override; bool IsReadable() const override; std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override; diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h index 235970dc5..cb92d1570 100644 --- a/src/core/file_sys/vfs_offset.h +++ b/src/core/file_sys/vfs_offset.h @@ -15,7 +15,8 @@ namespace FileSys { // Similar to seeking to an offset. // If the file is writable, operations that would write past the end of the offset file will expand // the size of this wrapper. -struct OffsetVfsFile : public VfsFile { +class OffsetVfsFile : public VfsFile { +public: OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, std::string new_name = "", VirtualDir new_parent = nullptr); diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 82d54da4a..1b5919737 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -6,7 +6,7 @@ #include <cstddef> #include <iterator> #include <utility> - +#include "common/assert.h" #include "common/common_paths.h" #include "common/logging/log.h" #include "core/file_sys/vfs_real.h" @@ -29,6 +29,8 @@ static std::string ModeFlagsToString(Mode mode) { mode_str = "a"; else if (mode & Mode::Write) mode_str = "w"; + else + UNREACHABLE_MSG("Invalid file open mode: {:02X}", static_cast<u8>(mode)); } mode_str += "b"; @@ -36,8 +38,174 @@ static std::string ModeFlagsToString(Mode mode) { return mode_str; } -RealVfsFile::RealVfsFile(const std::string& path_, Mode perms_) - : backing(path_, ModeFlagsToString(perms_).c_str()), path(path_), +RealVfsFilesystem::RealVfsFilesystem() : VfsFilesystem(nullptr) {} + +std::string RealVfsFilesystem::GetName() const { + return "Real"; +} + +bool RealVfsFilesystem::IsReadable() const { + return true; +} + +bool RealVfsFilesystem::IsWritable() const { + return true; +} + +VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + if (!FileUtil::Exists(path)) + return VfsEntryType::None; + if (FileUtil::IsDirectory(path)) + return VfsEntryType::Directory; + + return VfsEntryType::File; +} + +VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + if (cache.find(path) != cache.end()) { + auto weak = cache[path]; + if (!weak.expired()) { + return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, weak.lock(), path, perms)); + } + } + + if (!FileUtil::Exists(path) && (perms & Mode::WriteAppend) != 0) + FileUtil::CreateEmptyFile(path); + + auto backing = std::make_shared<FileUtil::IOFile>(path, ModeFlagsToString(perms).c_str()); + cache[path] = backing; + + // Cannot use make_shared as RealVfsFile constructor is private + return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms)); +} + +VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + if (!FileUtil::Exists(path) && !FileUtil::CreateEmptyFile(path)) + return nullptr; + return OpenFile(path, perms); +} + +VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_view new_path_) { + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); + + if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || + FileUtil::IsDirectory(old_path) || !FileUtil::Copy(old_path, new_path)) + return nullptr; + return OpenFile(new_path, Mode::ReadWrite); +} + +VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); + + if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || + FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) + return nullptr; + + if (cache.find(old_path) != cache.end()) { + auto cached = cache[old_path]; + if (!cached.expired()) { + auto file = cached.lock(); + file->Open(new_path, "r+b"); + cache.erase(old_path); + cache[new_path] = file; + } + } + return OpenFile(new_path, Mode::ReadWrite); +} + +bool RealVfsFilesystem::DeleteFile(std::string_view path_) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + if (cache.find(path) != cache.end()) { + if (!cache[path].expired()) + cache[path].lock()->Close(); + cache.erase(path); + } + return FileUtil::Delete(path); +} + +VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + // Cannot use make_shared as RealVfsDirectory constructor is private + return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms)); +} + +VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + if (!FileUtil::Exists(path) && !FileUtil::CreateDir(path)) + return nullptr; + // Cannot use make_shared as RealVfsDirectory constructor is private + return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms)); +} + +VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_, + std::string_view new_path_) { + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); + if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || + !FileUtil::IsDirectory(old_path)) + return nullptr; + FileUtil::CopyDir(old_path, new_path); + return OpenDirectory(new_path, Mode::ReadWrite); +} + +VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, + std::string_view new_path_) { + const auto old_path = + FileUtil::SanitizePath(old_path_, FileUtil::DirectorySeparator::PlatformDefault); + const auto new_path = + FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); + if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || + FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) + return nullptr; + + for (auto& kv : cache) { + // Path in cache starts with old_path + if (kv.first.rfind(old_path, 0) == 0) { + const auto file_old_path = + FileUtil::SanitizePath(kv.first, FileUtil::DirectorySeparator::PlatformDefault); + const auto file_new_path = + FileUtil::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), + FileUtil::DirectorySeparator::PlatformDefault); + auto cached = cache[file_old_path]; + if (!cached.expired()) { + auto file = cached.lock(); + file->Open(file_new_path, "r+b"); + cache.erase(file_old_path); + cache[file_new_path] = file; + } + } + } + + return OpenDirectory(new_path, Mode::ReadWrite); +} + +bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { + const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); + for (auto& kv : cache) { + // Path in cache starts with old_path + if (kv.first.rfind(path, 0) == 0) { + if (!cache[kv.first].expired()) + cache[kv.first].lock()->Close(); + cache.erase(kv.first); + } + } + return FileUtil::DeleteDirRecursively(path); +} + +RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::shared_ptr<FileUtil::IOFile> backing_, + const std::string& path_, Mode perms_) + : base(base_), backing(std::move(backing_)), path(path_), parent_path(FileUtil::GetParentPath(path_)), path_components(FileUtil::SplitPathComponents(path_)), parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)), @@ -48,15 +216,15 @@ std::string RealVfsFile::GetName() const { } size_t RealVfsFile::GetSize() const { - return backing.GetSize(); + return backing->GetSize(); } bool RealVfsFile::Resize(size_t new_size) { - return backing.Resize(new_size); + return backing->Resize(new_size); } std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const { - return std::make_shared<RealVfsDirectory>(parent_path, perms); + return base.OpenDirectory(parent_path, perms); } bool RealVfsFile::IsWritable() const { @@ -68,62 +236,118 @@ bool RealVfsFile::IsReadable() const { } size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const { - if (!backing.Seek(offset, SEEK_SET)) + if (!backing->Seek(offset, SEEK_SET)) return 0; - return backing.ReadBytes(data, length); + return backing->ReadBytes(data, length); } size_t RealVfsFile::Write(const u8* data, size_t length, size_t offset) { - if (!backing.Seek(offset, SEEK_SET)) + if (!backing->Seek(offset, SEEK_SET)) return 0; - return backing.WriteBytes(data, length); + return backing->WriteBytes(data, length); } bool RealVfsFile::Rename(std::string_view name) { - std::string name_str(name.begin(), name.end()); - const auto out = FileUtil::Rename(GetName(), name_str); + return base.MoveFile(path, parent_path + DIR_SEP + std::string(name)) != nullptr; +} + +bool RealVfsFile::Close() { + return backing->Close(); +} - path = (parent_path + DIR_SEP).append(name); - path_components = parent_components; - path_components.push_back(std::move(name_str)); - backing = FileUtil::IOFile(path, ModeFlagsToString(perms).c_str()); +// TODO(DarkLordZach): MSVC would not let me combine the following two functions using 'if +// constexpr' because there is a compile error in the branch not used. + +template <> +std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>() const { + if (perms == Mode::Append) + return {}; + + std::vector<VirtualFile> out; + FileUtil::ForeachDirectoryEntry( + nullptr, path, + [&out, this](u64* entries_out, const std::string& directory, const std::string& filename) { + const std::string full_path = directory + DIR_SEP + filename; + if (!FileUtil::IsDirectory(full_path)) + out.emplace_back(base.OpenFile(full_path, perms)); + return true; + }); return out; } -bool RealVfsFile::Close() { - return backing.Close(); +template <> +std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDirectory>() const { + if (perms == Mode::Append) + return {}; + + std::vector<VirtualDir> out; + FileUtil::ForeachDirectoryEntry( + nullptr, path, + [&out, this](u64* entries_out, const std::string& directory, const std::string& filename) { + const std::string full_path = directory + DIR_SEP + filename; + if (FileUtil::IsDirectory(full_path)) + out.emplace_back(base.OpenDirectory(full_path, perms)); + return true; + }); + + return out; } -RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_) - : path(FileUtil::RemoveTrailingSlash(path_)), parent_path(FileUtil::GetParentPath(path)), +RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string& path_, Mode perms_) + : base(base_), path(FileUtil::RemoveTrailingSlash(path_)), + parent_path(FileUtil::GetParentPath(path)), path_components(FileUtil::SplitPathComponents(path)), parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)), perms(perms_) { if (!FileUtil::Exists(path) && perms & Mode::WriteAppend) FileUtil::CreateDir(path); +} - if (perms == Mode::Append) - return; +std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path) const { + const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path)); + if (!FileUtil::Exists(full_path)) + return nullptr; + return base.OpenFile(full_path, perms); +} - FileUtil::ForeachDirectoryEntry( - nullptr, path, - [this](u64* entries_out, const std::string& directory, const std::string& filename) { - std::string full_path = directory + DIR_SEP + filename; - if (FileUtil::IsDirectory(full_path)) - subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(full_path, perms)); - else - files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms)); - return true; - }); +std::shared_ptr<VfsDirectory> RealVfsDirectory::GetDirectoryRelative(std::string_view path) const { + const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path)); + if (!FileUtil::Exists(full_path)) + return nullptr; + return base.OpenDirectory(full_path, perms); +} + +std::shared_ptr<VfsFile> RealVfsDirectory::GetFile(std::string_view name) const { + return GetFileRelative(name); +} + +std::shared_ptr<VfsDirectory> RealVfsDirectory::GetSubdirectory(std::string_view name) const { + return GetDirectoryRelative(name); +} + +std::shared_ptr<VfsFile> RealVfsDirectory::CreateFileRelative(std::string_view path) { + const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path)); + return base.CreateFile(full_path, perms); +} + +std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateDirectoryRelative(std::string_view path) { + const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path)); + auto parent = std::string(FileUtil::GetParentPath(full_path)); + return base.CreateDirectory(full_path, perms); +} + +bool RealVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) { + auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(name)); + return base.DeleteDirectory(full_path); } std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const { - return files; + return IterateEntries<RealVfsFile, VfsFile>(); } std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() const { - return subdirectories; + return IterateEntries<RealVfsDirectory, VfsDirectory>(); } bool RealVfsDirectory::IsWritable() const { @@ -142,57 +366,32 @@ std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const { if (path_components.size() <= 1) return nullptr; - return std::make_shared<RealVfsDirectory>(parent_path, perms); + return base.OpenDirectory(parent_path, perms); } std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(std::string_view name) { const std::string subdir_path = (path + DIR_SEP).append(name); - - if (!FileUtil::CreateDir(subdir_path)) { - return nullptr; - } - - subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(subdir_path, perms)); - return subdirectories.back(); + return base.CreateDirectory(subdir_path, perms); } std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(std::string_view name) { const std::string file_path = (path + DIR_SEP).append(name); - - if (!FileUtil::CreateEmptyFile(file_path)) { - return nullptr; - } - - files.emplace_back(std::make_shared<RealVfsFile>(file_path, perms)); - return files.back(); + return base.CreateFile(file_path, perms); } bool RealVfsDirectory::DeleteSubdirectory(std::string_view name) { const std::string subdir_path = (path + DIR_SEP).append(name); - - return FileUtil::DeleteDirRecursively(subdir_path); + return base.DeleteDirectory(subdir_path); } bool RealVfsDirectory::DeleteFile(std::string_view name) { - const auto file = GetFile(name); - - if (file == nullptr) { - return false; - } - - files.erase(std::find(files.begin(), files.end(), file)); - - auto real_file = std::static_pointer_cast<RealVfsFile>(file); - real_file->Close(); - const std::string file_path = (path + DIR_SEP).append(name); - return FileUtil::Delete(file_path); + return base.DeleteFile(file_path); } bool RealVfsDirectory::Rename(std::string_view name) { const std::string new_name = (parent_path + DIR_SEP).append(name); - - return FileUtil::Rename(path, new_name); + return base.MoveFile(path, new_name) != nullptr; } std::string RealVfsDirectory::GetFullPath() const { @@ -202,16 +401,6 @@ std::string RealVfsDirectory::GetFullPath() const { } bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { - const auto iter = std::find(files.begin(), files.end(), file); - if (iter == files.end()) - return false; - - const std::ptrdiff_t offset = std::distance(files.begin(), iter); - files[offset] = files.back(); - files.pop_back(); - - subdirectories.emplace_back(std::move(dir)); - - return true; + return false; } } // namespace FileSys diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 243d58576..8a1e79ef6 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -6,18 +6,45 @@ #include <string_view> +#include <boost/container/flat_map.hpp> #include "common/file_util.h" #include "core/file_sys/mode.h" #include "core/file_sys/vfs.h" namespace FileSys { +class RealVfsFilesystem : public VfsFilesystem { +public: + RealVfsFilesystem(); + + std::string GetName() const override; + bool IsReadable() const override; + bool IsWritable() const override; + VfsEntryType GetEntryType(std::string_view path) const override; + VirtualFile OpenFile(std::string_view path, Mode perms = Mode::Read) override; + VirtualFile CreateFile(std::string_view path, Mode perms = Mode::ReadWrite) override; + VirtualFile CopyFile(std::string_view old_path, std::string_view new_path) override; + VirtualFile MoveFile(std::string_view old_path, std::string_view new_path) override; + bool DeleteFile(std::string_view path) override; + VirtualDir OpenDirectory(std::string_view path, Mode perms = Mode::Read) override; + VirtualDir CreateDirectory(std::string_view path, Mode perms = Mode::ReadWrite) override; + VirtualDir CopyDirectory(std::string_view old_path, std::string_view new_path) override; + VirtualDir MoveDirectory(std::string_view old_path, std::string_view new_path) override; + bool DeleteDirectory(std::string_view path) override; + +private: + boost::container::flat_map<std::string, std::weak_ptr<FileUtil::IOFile>> cache; +}; + // An implmentation of VfsFile that represents a file on the user's computer. -struct RealVfsFile : public VfsFile { - friend struct RealVfsDirectory; +class RealVfsFile : public VfsFile { + friend class RealVfsDirectory; + friend class RealVfsFilesystem; - RealVfsFile(const std::string& name, Mode perms = Mode::Read); + RealVfsFile(RealVfsFilesystem& base, std::shared_ptr<FileUtil::IOFile> backing, + const std::string& path, Mode perms = Mode::Read); +public: std::string GetName() const override; size_t GetSize() const override; bool Resize(size_t new_size) override; @@ -31,7 +58,8 @@ struct RealVfsFile : public VfsFile { private: bool Close(); - FileUtil::IOFile backing; + RealVfsFilesystem& base; + std::shared_ptr<FileUtil::IOFile> backing; std::string path; std::string parent_path; std::vector<std::string> path_components; @@ -40,9 +68,19 @@ private: }; // An implementation of VfsDirectory that represents a directory on the user's computer. -struct RealVfsDirectory : public VfsDirectory { - RealVfsDirectory(const std::string& path, Mode perms = Mode::Read); +class RealVfsDirectory : public VfsDirectory { + friend class RealVfsFilesystem; + RealVfsDirectory(RealVfsFilesystem& base, const std::string& path, Mode perms = Mode::Read); + +public: + std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override; + std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override; + std::shared_ptr<VfsFile> GetFile(std::string_view name) const override; + std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override; + std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override; + std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override; + bool DeleteSubdirectoryRecursive(std::string_view name) override; std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; bool IsWritable() const override; @@ -60,13 +98,15 @@ protected: bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; private: + template <typename T, typename R> + std::vector<std::shared_ptr<R>> IterateEntries() const; + + RealVfsFilesystem& base; std::string path; std::string parent_path; std::vector<std::string> path_components; std::vector<std::string> parent_components; Mode perms; - std::vector<std::shared_ptr<VfsFile>> files; - std::vector<std::shared_ptr<VfsDirectory>> subdirectories; }; } // namespace FileSys diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h index ba469647b..b3b468233 100644 --- a/src/core/file_sys/vfs_vector.h +++ b/src/core/file_sys/vfs_vector.h @@ -10,7 +10,8 @@ namespace FileSys { // An implementation of VfsDirectory that maintains two vectors for subdirectories and files. // Vector data is supplied upon construction. -struct VectorVfsDirectory : public VfsDirectory { +class VectorVfsDirectory : public VfsDirectory { +public: explicit VectorVfsDirectory(std::vector<VirtualFile> files = {}, std::vector<VirtualDir> dirs = {}, VirtualDir parent = nullptr, std::string name = ""); diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 2d776c693..9dd493efb 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -8,6 +8,8 @@ #include "core/frontend/input.h" #include "core/settings.h" +namespace Core::Frontend { + class EmuWindow::TouchState : public Input::Factory<Input::TouchDevice>, public std::enable_shared_from_this<TouchState> { public: @@ -108,3 +110,5 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { NotifyFramebufferLayoutChanged(Layout::DefaultFrameLayout(width, height)); } + +} // namespace Core::Frontend diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index e8c29adfb..384dc7822 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -10,6 +10,8 @@ #include "common/common_types.h" #include "core/frontend/framebuffer_layout.h" +namespace Core::Frontend { + /** * Abstraction class used to provide an interface between emulation code and the frontend * (e.g. SDL, QGLWidget, GLFW, etc...). @@ -166,3 +168,5 @@ private: */ std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y); }; + +} // namespace Core::Frontend diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 75f6b8235..332e5c3d0 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -41,40 +41,42 @@ #include "core/loader/loader.h" #include "core/memory.h" -const int GDB_BUFFER_SIZE = 10000; +namespace GDBStub { +namespace { +constexpr int GDB_BUFFER_SIZE = 10000; -const char GDB_STUB_START = '$'; -const char GDB_STUB_END = '#'; -const char GDB_STUB_ACK = '+'; -const char GDB_STUB_NACK = '-'; +constexpr char GDB_STUB_START = '$'; +constexpr char GDB_STUB_END = '#'; +constexpr char GDB_STUB_ACK = '+'; +constexpr char GDB_STUB_NACK = '-'; #ifndef SIGTRAP -const u32 SIGTRAP = 5; +constexpr u32 SIGTRAP = 5; #endif #ifndef SIGTERM -const u32 SIGTERM = 15; +constexpr u32 SIGTERM = 15; #endif #ifndef MSG_WAITALL -const u32 MSG_WAITALL = 8; +constexpr u32 MSG_WAITALL = 8; #endif -const u32 LR_REGISTER = 30; -const u32 SP_REGISTER = 31; -const u32 PC_REGISTER = 32; -const u32 CPSR_REGISTER = 33; -const u32 UC_ARM64_REG_Q0 = 34; -const u32 FPSCR_REGISTER = 66; +constexpr u32 LR_REGISTER = 30; +constexpr u32 SP_REGISTER = 31; +constexpr u32 PC_REGISTER = 32; +constexpr u32 CPSR_REGISTER = 33; +constexpr u32 UC_ARM64_REG_Q0 = 34; +constexpr u32 FPSCR_REGISTER = 66; // TODO/WiP - Used while working on support for FPU -const u32 TODO_DUMMY_REG_997 = 997; -const u32 TODO_DUMMY_REG_998 = 998; +constexpr u32 TODO_DUMMY_REG_997 = 997; +constexpr u32 TODO_DUMMY_REG_998 = 998; // For sample XML files see the GDB source /gdb/features // GDB also wants the l character at the start // This XML defines what the registers are for this specific ARM device -static const char* target_xml = +constexpr char target_xml[] = R"(l<?xml version="1.0"?> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target version="1.0"> @@ -140,30 +142,28 @@ static const char* target_xml = </target> )"; -namespace GDBStub { - -static int gdbserver_socket = -1; +int gdbserver_socket = -1; -static u8 command_buffer[GDB_BUFFER_SIZE]; -static u32 command_length; +u8 command_buffer[GDB_BUFFER_SIZE]; +u32 command_length; -static u32 latest_signal = 0; -static bool memory_break = false; +u32 latest_signal = 0; +bool memory_break = false; -static Kernel::Thread* current_thread = nullptr; -static u32 current_core = 0; +Kernel::Thread* current_thread = nullptr; +u32 current_core = 0; // Binding to a port within the reserved ports range (0-1023) requires root permissions, // so default to a port outside of that range. -static u16 gdbstub_port = 24689; +u16 gdbstub_port = 24689; -static bool halt_loop = true; -static bool step_loop = false; -static bool send_trap = false; +bool halt_loop = true; +bool step_loop = false; +bool send_trap = false; // If set to false, the server will never be started and no // gdbstub-related functions will be executed. -static std::atomic<bool> server_enabled(false); +std::atomic<bool> server_enabled(false); #ifdef _WIN32 WSADATA InitData; @@ -171,23 +171,26 @@ WSADATA InitData; struct Breakpoint { bool active; - PAddr addr; + VAddr addr; u64 len; + std::array<u8, 4> inst; }; -static std::map<u64, Breakpoint> breakpoints_execute; -static std::map<u64, Breakpoint> breakpoints_read; -static std::map<u64, Breakpoint> breakpoints_write; +using BreakpointMap = std::map<VAddr, Breakpoint>; +BreakpointMap breakpoints_execute; +BreakpointMap breakpoints_read; +BreakpointMap breakpoints_write; struct Module { std::string name; - PAddr beg; - PAddr end; + VAddr beg; + VAddr end; }; -static std::vector<Module> modules; +std::vector<Module> modules; +} // Anonymous namespace -void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext) { +void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) { Module module; if (add_elf_ext) { Common::SplitPath(name, nullptr, &module.name, nullptr); @@ -418,11 +421,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) { } /** - * Get the list of breakpoints for a given breakpoint type. + * Get the map of breakpoints for a given breakpoint type. * - * @param type Type of breakpoint list. + * @param type Type of breakpoint map. */ -static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { +static BreakpointMap& GetBreakpointMap(BreakpointType type) { switch (type) { case BreakpointType::Execute: return breakpoints_execute; @@ -441,20 +444,24 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { * @param type Type of breakpoint. * @param addr Address of breakpoint. */ -static void RemoveBreakpoint(BreakpointType type, PAddr addr) { - std::map<u64, Breakpoint>& p = GetBreakpointList(type); +static void RemoveBreakpoint(BreakpointType type, VAddr addr) { + BreakpointMap& p = GetBreakpointMap(type); - auto bp = p.find(static_cast<u64>(addr)); - if (bp != p.end()) { - LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", - bp->second.len, bp->second.addr, static_cast<int>(type)); - p.erase(static_cast<u64>(addr)); + const auto bp = p.find(addr); + if (bp == p.end()) { + return; } + + LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", + bp->second.len, bp->second.addr, static_cast<int>(type)); + Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size()); + Core::System::GetInstance().InvalidateCpuInstructionCaches(); + p.erase(addr); } -BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) { - std::map<u64, Breakpoint>& p = GetBreakpointList(type); - auto next_breakpoint = p.lower_bound(static_cast<u64>(addr)); +BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) { + const BreakpointMap& p = GetBreakpointMap(type); + const auto next_breakpoint = p.lower_bound(addr); BreakpointAddress breakpoint; if (next_breakpoint != p.end()) { @@ -468,36 +475,38 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) return breakpoint; } -bool CheckBreakpoint(PAddr addr, BreakpointType type) { +bool CheckBreakpoint(VAddr addr, BreakpointType type) { if (!IsConnected()) { return false; } - std::map<u64, Breakpoint>& p = GetBreakpointList(type); + const BreakpointMap& p = GetBreakpointMap(type); + const auto bp = p.find(addr); - auto bp = p.find(static_cast<u64>(addr)); - if (bp != p.end()) { - u64 len = bp->second.len; + if (bp == p.end()) { + return false; + } - // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints - // no matter if it's a 4-byte or 2-byte instruction. When you execute a - // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on - // two instructions instead of the single instruction you placed the breakpoint - // on. So, as a way to make sure that execution breakpoints are only breaking - // on the instruction that was specified, set the length of an execution - // breakpoint to 1. This should be fine since the CPU should never begin executing - // an instruction anywhere except the beginning of the instruction. - if (type == BreakpointType::Execute) { - len = 1; - } + u64 len = bp->second.len; - if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { - LOG_DEBUG(Debug_GDBStub, - "Found breakpoint type {} @ {:016X}, range: {:016X}" - " - {:016X} ({:X} bytes)", - static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); - return true; - } + // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints + // no matter if it's a 4-byte or 2-byte instruction. When you execute a + // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on + // two instructions instead of the single instruction you placed the breakpoint + // on. So, as a way to make sure that execution breakpoints are only breaking + // on the instruction that was specified, set the length of an execution + // breakpoint to 1. This should be fine since the CPU should never begin executing + // an instruction anywhere except the beginning of the instruction. + if (type == BreakpointType::Execute) { + len = 1; + } + + if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { + LOG_DEBUG(Debug_GDBStub, + "Found breakpoint type {} @ {:016X}, range: {:016X}" + " - {:016X} ({:X} bytes)", + static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); + return true; } return false; @@ -931,6 +940,7 @@ static void WriteMemory() { GdbHexToMem(data.data(), len_pos + 1, len); Memory::WriteBlock(addr, data.data(), len); + Core::System::GetInstance().InvalidateCpuInstructionCaches(); SendReply("OK"); } @@ -950,6 +960,7 @@ static void Step() { step_loop = true; halt_loop = true; send_trap = true; + Core::System::GetInstance().InvalidateCpuInstructionCaches(); } /// Tell the CPU if we hit a memory breakpoint. @@ -966,6 +977,7 @@ static void Continue() { memory_break = false; step_loop = false; halt_loop = false; + Core::System::GetInstance().InvalidateCpuInstructionCaches(); } /** @@ -975,13 +987,17 @@ static void Continue() { * @param addr Address of breakpoint. * @param len Length of breakpoint. */ -static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { - std::map<u64, Breakpoint>& p = GetBreakpointList(type); +static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) { + BreakpointMap& p = GetBreakpointMap(type); Breakpoint breakpoint; breakpoint.active = true; breakpoint.addr = addr; breakpoint.len = len; + Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size()); + static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}}; + Memory::WriteBlock(addr, btrap.data(), btrap.size()); + Core::System::GetInstance().InvalidateCpuInstructionCaches(); p.insert({addr, breakpoint}); LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", @@ -1015,7 +1031,7 @@ static void AddBreakpoint() { auto start_offset = command_buffer + 3; auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); - PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); + VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); start_offset = addr_pos + 1; u64 len = @@ -1064,7 +1080,7 @@ static void RemoveBreakpoint() { auto start_offset = command_buffer + 3; auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); - PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); + VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index a6b50c26c..5a36524b2 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h @@ -22,7 +22,7 @@ enum class BreakpointType { }; struct BreakpointAddress { - PAddr address; + VAddr address; BreakpointType type; }; @@ -53,7 +53,7 @@ bool IsServerEnabled(); bool IsConnected(); /// Register module. -void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext = true); +void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true); /** * Signal to the gdbstub server that it should halt CPU execution. @@ -74,7 +74,7 @@ void HandlePacket(); * @param addr Address to search from. * @param type Type of breakpoint. */ -BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointType type); +BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type); /** * Check if a breakpoint of the specified type exists at the given address. @@ -82,7 +82,7 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointTy * @param addr Address of breakpoint. * @param type Type of breakpoint. */ -bool CheckBreakpoint(PAddr addr, GDBStub::BreakpointType type); +bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type); /// If set to true, the CPU will halt at the beginning of the next CPU loop. bool GetCpuHaltFlag(); diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 7a17ed162..03a954a9f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -32,9 +32,8 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) { } // Gets the threads waiting on an address. -static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, - VAddr address) { - auto RetrieveWaitingThreads = +static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) { + const auto RetrieveWaitingThreads = [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); auto& thread_list = scheduler->GetThreadList(); @@ -45,16 +44,20 @@ static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_t } }; - // Retrieve a list of all threads that are waiting for this address. - RetrieveWaitingThreads(0, waiting_threads, address); - RetrieveWaitingThreads(1, waiting_threads, address); - RetrieveWaitingThreads(2, waiting_threads, address); - RetrieveWaitingThreads(3, waiting_threads, address); + // Retrieve all threads that are waiting for this address. + std::vector<SharedPtr<Thread>> threads; + RetrieveWaitingThreads(0, threads, address); + RetrieveWaitingThreads(1, threads, address); + RetrieveWaitingThreads(2, threads, address); + RetrieveWaitingThreads(3, threads, address); + // Sort them by priority, such that the highest priority ones come first. - std::sort(waiting_threads.begin(), waiting_threads.end(), + std::sort(threads.begin(), threads.end(), [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { return lhs->current_priority < rhs->current_priority; }); + + return threads; } // Wake up num_to_wake (or all) threads in a vector. @@ -76,9 +79,7 @@ static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num // Signals an address being waited on. ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { - // Get threads waiting on the address. - std::vector<SharedPtr<Thread>> waiting_threads; - GetThreadsWaitingOnAddress(waiting_threads, address); + std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); WakeThreads(waiting_threads, num_to_wake); return RESULT_SUCCESS; @@ -110,12 +111,11 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu } // Get threads waiting on the address. - std::vector<SharedPtr<Thread>> waiting_threads; - GetThreadsWaitingOnAddress(waiting_threads, address); + std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); // Determine the modified value depending on the waiting count. s32 updated_value; - if (waiting_threads.size() == 0) { + if (waiting_threads.empty()) { updated_value = value - 1; } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { updated_value = value + 1; diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 7933c105c..134e41ebc 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -14,8 +14,8 @@ namespace Kernel { -ClientPort::ClientPort() {} -ClientPort::~ClientPort() {} +ClientPort::ClientPort() = default; +ClientPort::~ClientPort() = default; ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call @@ -40,4 +40,12 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { return MakeResult(std::get<SharedPtr<ClientSession>>(sessions)); } +void ClientPort::ConnectionClosed() { + if (active_sessions == 0) { + return; + } + + --active_sessions; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index b42c94bde..b1269ea5c 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -37,14 +37,20 @@ public: */ ResultVal<SharedPtr<ClientSession>> Connect(); - SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. - u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have - u32 active_sessions; ///< Number of currently open sessions to this port - std::string name; ///< Name of client port (optional) + /** + * Signifies that a previously active connection has been closed, + * decreasing the total number of active connections to this port. + */ + void ConnectionClosed(); private: ClientPort(); ~ClientPort() override; + + SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. + u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have + u32 active_sessions = 0; ///< Number of currently open sessions to this port + std::string name; ///< Name of client port (optional) }; } // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 1c99911b2..3c20c05e8 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -31,10 +31,9 @@ public: return HANDLE_TYPE; } - ResetType reset_type; ///< Current ResetType - - bool signaled; ///< Whether the event has already been signaled - std::string name; ///< Name of event (optional) + ResetType GetResetType() const { + return reset_type; + } bool ShouldWait(Thread* thread) const override; void Acquire(Thread* thread) override; @@ -47,6 +46,11 @@ public: private: Event(); ~Event() override; + + ResetType reset_type; ///< Current ResetType + + bool signaled; ///< Whether the event has already been signaled + std::string name; ///< Name of event (optional) }; } // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 5dd1b68d7..82a3fb5a8 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -201,7 +201,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb return RESULT_SUCCESS; } -ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { +ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread) { std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; Memory::ReadBlock(*thread.owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), dst_cmdbuf.size() * sizeof(u32)); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 9ce52db24..f0d07f1b6 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -132,7 +132,7 @@ public: ResultCode PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf, Process& src_process, HandleTable& src_table); /// Writes data from this context back to the requesting process/thread. - ResultCode WriteToOutgoingCommandBuffer(Thread& thread); + ResultCode WriteToOutgoingCommandBuffer(const Thread& thread); u32_le GetCommand() const { return command; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1b0cd0abf..8c19e86d3 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -11,7 +11,7 @@ namespace Kernel { -unsigned int Object::next_object_id; +std::atomic<u32> Object::next_object_id{0}; /// Initialize the kernel void Init() { diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 83df68dfd..526ac9cc3 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -4,6 +4,7 @@ #pragma once +#include <atomic> #include <string> #include <utility> @@ -42,8 +43,8 @@ public: virtual ~Object(); /// Returns a unique identifier for the object. For debugging purposes only. - unsigned int GetObjectId() const { - return object_id; + u32 GetObjectId() const { + return object_id.load(std::memory_order_relaxed); } virtual std::string GetTypeName() const { @@ -61,23 +62,23 @@ public: bool IsWaitable() const; public: - static unsigned int next_object_id; + static std::atomic<u32> next_object_id; private: friend void intrusive_ptr_add_ref(Object*); friend void intrusive_ptr_release(Object*); - unsigned int ref_count = 0; - unsigned int object_id = next_object_id++; + std::atomic<u32> ref_count{0}; + std::atomic<u32> object_id{next_object_id++}; }; // Special functions used by boost::instrusive_ptr to do automatic ref-counting inline void intrusive_ptr_add_ref(Object* object) { - ++object->ref_count; + object->ref_count.fetch_add(1, std::memory_order_relaxed); } inline void intrusive_ptr_release(Object* object) { - if (--object->ref_count == 0) { + if (object->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) { delete object; } } diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 94065c736..e770b9103 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -25,7 +25,7 @@ Scheduler::~Scheduler() { } } -bool Scheduler::HaveReadyThreads() { +bool Scheduler::HaveReadyThreads() const { std::lock_guard<std::mutex> lock(scheduler_mutex); return ready_queue.get_first() != nullptr; } diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 1a4ee8f36..6a61ef64e 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -21,7 +21,7 @@ public: ~Scheduler(); /// Returns whether there are any threads that are ready to run. - bool HaveReadyThreads(); + bool HaveReadyThreads() const; /// Reschedules to the next available thread (call after current thread is suspended) void Reschedule(); diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 60370e9ec..d09ca5992 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -27,7 +27,7 @@ ServerSession::~ServerSession() { // Decrease the port's connection count. if (parent->port) - parent->port->active_sessions--; + parent->port->ConnectionClosed(); // TODO(Subv): Wake up all the ClientSession's waiting threads and set // the SendSyncRequest result to 0xC920181A. @@ -71,6 +71,14 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con const u32 object_id{context.GetDomainMessageHeader()->object_id}; switch (domain_message_header->command) { case IPC::DomainMessageHeader::CommandType::SendMessage: + if (object_id > domain_request_handlers.size()) { + LOG_CRITICAL(IPC, + "object_id {} is too big! This probably means a recent service call " + "to {} needed to return a new interface!", + object_id, name); + UNREACHABLE(); + return RESULT_SUCCESS; // Ignore error if asserts are off + } return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5db2db687..b24f409b3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -532,7 +532,6 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread)); *out_handle = thread->guest_handle; - Core::System::GetInstance().PrepareReschedule(); Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); LOG_TRACE(Kernel_SVC, @@ -706,8 +705,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); auto owner = g_handle_table.Get<Thread>(owner_handle); ASSERT(owner); - ASSERT(thread->status != ThreadStatus::Running); - thread->status = ThreadStatus::WaitMutex; + ASSERT(thread->status == ThreadStatus::WaitMutex); thread->wakeup_callback = nullptr; owner->AddMutexWaiter(thread); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index b9022feae..a1a7867ce 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -23,6 +23,7 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" +#include "core/hle/lock.h" #include "core/hle/result.h" #include "core/memory.h" @@ -104,6 +105,10 @@ void ExitCurrentThread() { */ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { const auto proper_handle = static_cast<Handle>(thread_handle); + + // Lock the global kernel mutex when we enter the kernel HLE. + std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); + SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle); if (thread == nullptr) { LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); @@ -155,8 +160,10 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { if (nanoseconds == -1) return; - CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(nanoseconds), ThreadWakeupEventType, - callback_handle); + // This function might be called from any thread so we have to be cautious and use the + // thread-safe version of ScheduleEvent. + CoreTiming::ScheduleEventThreadsafe(CoreTiming::nsToCycles(nanoseconds), ThreadWakeupEventType, + callback_handle); } void Thread::CancelWakeupTimer() { @@ -419,12 +426,33 @@ VAddr Thread::GetCommandBufferAddress() const { } void Thread::AddMutexWaiter(SharedPtr<Thread> thread) { + if (thread->lock_owner == this) { + // If the thread is already waiting for this thread to release the mutex, ensure that the + // waiters list is consistent and return without doing anything. + auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); + ASSERT(itr != wait_mutex_threads.end()); + return; + } + + // A thread can't wait on two different mutexes at the same time. + ASSERT(thread->lock_owner == nullptr); + + // Ensure that the thread is not already in the list of mutex waiters + auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); + ASSERT(itr == wait_mutex_threads.end()); + thread->lock_owner = this; wait_mutex_threads.emplace_back(std::move(thread)); UpdatePriority(); } void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) { + ASSERT(thread->lock_owner == this); + + // Ensure that the thread is in the list of mutex waiters + auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); + ASSERT(itr != wait_mutex_threads.end()); + boost::remove_erase(wait_mutex_threads, thread); thread->lock_owner = nullptr; UpdatePriority(); diff --git a/src/core/hle/romfs.cpp b/src/core/hle/romfs.cpp deleted file mode 100644 index 3157df71d..000000000 --- a/src/core/hle/romfs.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <cstring> -#include "common/swap.h" -#include "core/hle/romfs.h" - -namespace RomFS { - -struct Header { - u32_le header_length; - u32_le dir_hash_table_offset; - u32_le dir_hash_table_length; - u32_le dir_table_offset; - u32_le dir_table_length; - u32_le file_hash_table_offset; - u32_le file_hash_table_length; - u32_le file_table_offset; - u32_le file_table_length; - u32_le data_offset; -}; - -static_assert(sizeof(Header) == 0x28, "Header has incorrect size"); - -struct DirectoryMetadata { - u32_le parent_dir_offset; - u32_le next_dir_offset; - u32_le first_child_dir_offset; - u32_le first_file_offset; - u32_le same_hash_next_dir_offset; - u32_le name_length; // in bytes - // followed by directory name -}; - -static_assert(sizeof(DirectoryMetadata) == 0x18, "DirectoryMetadata has incorrect size"); - -struct FileMetadata { - u32_le parent_dir_offset; - u32_le next_file_offset; - u64_le data_offset; - u64_le data_length; - u32_le same_hash_next_file_offset; - u32_le name_length; // in bytes - // followed by file name -}; - -static_assert(sizeof(FileMetadata) == 0x20, "FileMetadata has incorrect size"); - -static bool MatchName(const u8* buffer, u32 name_length, const std::u16string& name) { - std::vector<char16_t> name_buffer(name_length / sizeof(char16_t)); - std::memcpy(name_buffer.data(), buffer, name_length); - return name == std::u16string(name_buffer.begin(), name_buffer.end()); -} - -const u8* GetFilePointer(const u8* romfs, const std::vector<std::u16string>& path) { - constexpr u32 INVALID_FIELD = 0xFFFFFFFF; - - // Split path into directory names and file name - std::vector<std::u16string> dir_names = path; - dir_names.pop_back(); - const std::u16string& file_name = path.back(); - - Header header; - std::memcpy(&header, romfs, sizeof(header)); - - // Find directories of each level - DirectoryMetadata dir; - const u8* current_dir = romfs + header.dir_table_offset; - std::memcpy(&dir, current_dir, sizeof(dir)); - for (const std::u16string& dir_name : dir_names) { - u32 child_dir_offset; - child_dir_offset = dir.first_child_dir_offset; - while (true) { - if (child_dir_offset == INVALID_FIELD) { - return nullptr; - } - const u8* current_child_dir = romfs + header.dir_table_offset + child_dir_offset; - std::memcpy(&dir, current_child_dir, sizeof(dir)); - if (MatchName(current_child_dir + sizeof(dir), dir.name_length, dir_name)) { - current_dir = current_child_dir; - break; - } - child_dir_offset = dir.next_dir_offset; - } - } - - // Find the file - FileMetadata file; - u32 file_offset = dir.first_file_offset; - while (file_offset != INVALID_FIELD) { - const u8* current_file = romfs + header.file_table_offset + file_offset; - std::memcpy(&file, current_file, sizeof(file)); - if (MatchName(current_file + sizeof(file), file.name_length, file_name)) { - return romfs + header.data_offset + file.data_offset; - } - file_offset = file.next_file_offset; - } - return nullptr; -} - -} // namespace RomFS diff --git a/src/core/hle/romfs.h b/src/core/hle/romfs.h deleted file mode 100644 index ee9f29760..000000000 --- a/src/core/hle/romfs.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <string> -#include <vector> -#include "common/common_types.h" - -namespace RomFS { - -/** - * Gets the pointer to a file in a RomFS image. - * @param romfs The pointer to the RomFS image - * @param path A vector containing the directory names and file name of the path to the file - * @return the pointer to the file - * @todo reimplement this with a full RomFS manager - */ -const u8* GetFilePointer(const u8* romfs, const std::vector<std::u16string>& path); - -} // namespace RomFS diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 6d15b46ed..f3c5b1b9c 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -42,7 +42,7 @@ public: {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, {10, nullptr, "GetImageSize"}, - {11, nullptr, "LoadImage"}, + {11, &IProfile::LoadImage, "LoadImage"}, }; RegisterHandlers(functions); } @@ -83,6 +83,27 @@ private: rb.PushRaw(profile_base); } + void LoadImage(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + // smallest jpeg https://github.com/mathiasbynens/small/blob/master/jpeg.jpg + // TODO(mailwl): load actual profile image from disk, width 256px, max size 0x20000 + const u32 jpeg_size = 107; + static const std::array<u8, jpeg_size> jpeg{ + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x08, 0x06, 0x06, 0x05, 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, + 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e, 0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, + 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13, 0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, + 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x11, 0x00, + 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, + 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9, + }; + ctx.WriteBuffer(jpeg.data(), jpeg_size); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(jpeg_size); + } + u128 user_id; ///< The user id this profile refers to. }; @@ -119,6 +140,13 @@ private: } }; +void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(1); +} + void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index 0a01d954c..88cabaa01 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -14,6 +14,7 @@ public: public: explicit Interface(std::shared_ptr<Module> module, const char* name); + void GetUserCount(Kernel::HLERequestContext& ctx); void GetUserExistence(Kernel::HLERequestContext& ctx); void ListAllUsers(Kernel::HLERequestContext& ctx); void ListOpenUsers(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 9ffb40b22..8b2a71f37 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp @@ -8,7 +8,7 @@ namespace Service::Account { ACC_SU::ACC_SU(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "acc:su") { static const FunctionInfo functions[] = { - {0, nullptr, "GetUserCount"}, + {0, &ACC_SU::GetUserCount, "GetUserCount"}, {1, &ACC_SU::GetUserExistence, "GetUserExistence"}, {2, &ACC_SU::ListAllUsers, "ListAllUsers"}, {3, &ACC_SU::ListOpenUsers, "ListOpenUsers"}, diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index 44e21ac09..d84c8b2e1 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -8,7 +8,7 @@ namespace Service::Account { ACC_U0::ACC_U0(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "acc:u0") { static const FunctionInfo functions[] = { - {0, nullptr, "GetUserCount"}, + {0, &ACC_U0::GetUserCount, "GetUserCount"}, {1, &ACC_U0::GetUserExistence, "GetUserExistence"}, {2, &ACC_U0::ListAllUsers, "ListAllUsers"}, {3, &ACC_U0::ListOpenUsers, "ListOpenUsers"}, diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index d101d4e0d..0ceaf06b5 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp @@ -8,7 +8,7 @@ namespace Service::Account { ACC_U1::ACC_U1(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "acc:u1") { static const FunctionInfo functions[] = { - {0, nullptr, "GetUserCount"}, + {0, &ACC_U1::GetUserCount, "GetUserCount"}, {1, &ACC_U1::GetUserExistence, "GetUserExistence"}, {2, &ACC_U1::ListAllUsers, "ListAllUsers"}, {3, &ACC_U1::ListOpenUsers, "ListOpenUsers"}, diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9404d6b8c..762763463 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -136,7 +136,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"}, {17, nullptr, "SetControllerFirmwareUpdateSection"}, {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"}, - {19, nullptr, "SetScreenShotImageOrientation"}, + {19, &ISelfController::SetScreenShotImageOrientation, "SetScreenShotImageOrientation"}, {20, nullptr, "SetDesirableKeyboardLayout"}, {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, {41, nullptr, "IsSystemBufferSharingEnabled"}, @@ -254,6 +254,13 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& LOG_WARNING(Service_AM, "(STUBBED) called"); } +void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + + LOG_WARNING(Service_AM, "(STUBBED) called"); +} + void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { // TODO(Subv): Find out how AM determines the display to use, for now just create the layer // in the Default display. diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 8f4f98346..862f338ac 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -83,6 +83,7 @@ private: void LockExit(Kernel::HLERequestContext& ctx); void UnlockExit(Kernel::HLERequestContext& ctx); void GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx); + void SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx); void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx); void SetScreenShotPermission(Kernel::HLERequestContext& ctx); void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 7a185c6c8..4109cb7f7 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -13,6 +13,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { auto module_ = std::make_shared<Module>(); std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager); + std::make_shared<APM_Sys>()->InstallAsService(service_manager); } } // namespace Service::APM diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index ce943d829..4cd8132f5 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -74,6 +74,31 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISession>(); + + LOG_DEBUG(Service_APM, "called"); +} + +APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestPerformanceMode"}, + {1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"}, + {2, nullptr, "GetThrottlingState"}, + {3, nullptr, "GetLastThrottlingState"}, + {4, nullptr, "ClearLastThrottlingState"}, + {5, nullptr, "LoadAndApplySettings"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<ISession>(); + + LOG_DEBUG(Service_APM, "called"); } } // namespace Service::APM diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h index fa68c7d93..d14264ad7 100644 --- a/src/core/hle/service/apm/interface.h +++ b/src/core/hle/service/apm/interface.h @@ -19,4 +19,12 @@ private: std::shared_ptr<Module> apm; }; +class APM_Sys final : public ServiceFramework<APM_Sys> { +public: + explicit APM_Sys(); + +private: + void GetPerformanceEvent(Kernel::HLERequestContext& ctx); +}; + } // namespace Service::APM diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp index 57b934dd6..bf8d40157 100644 --- a/src/core/hle/service/audio/audout_a.cpp +++ b/src/core/hle/service/audio/audout_a.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - #include "core/hle/service/audio/audout_a.h" namespace Service::Audio { diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index b317027b6..ce709ccf4 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -4,6 +4,8 @@ #include <array> #include <vector> + +#include "audio_core/codec.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" @@ -26,7 +28,7 @@ constexpr int DefaultSampleRate{48000}; class IAudioOut final : public ServiceFramework<IAudioOut> { public: IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core) - : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) { + : ServiceFramework("IAudioOut"), audio_core(audio_core), audio_params(audio_params) { static const FunctionInfo functions[] = { {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, @@ -48,7 +50,7 @@ public: buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, - [=]() { buffer_event->Signal(); }); + "IAudioOut", [=]() { buffer_event->Signal(); }); } private: @@ -111,10 +113,10 @@ private: std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer)); const u64 tag{rp.Pop<u64>()}; - std::vector<u8> data(audio_buffer.buffer_size); - Memory::ReadBlock(audio_buffer.buffer, data.data(), data.size()); + std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16)); + Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); - if (!audio_core.QueueBuffer(stream, tag, std::move(data))) { + if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded)); } @@ -200,7 +202,7 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u32>(DefaultSampleRate); rb.Push<u32>(params.channel_count); - rb.Push<u32>(static_cast<u32>(PcmFormat::Int16)); + rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16)); rb.Push<u32>(static_cast<u32>(AudioState::Stopped)); rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); } diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h index e5c2184d5..fd491f65d 100644 --- a/src/core/hle/service/audio/audout_u.h +++ b/src/core/hle/service/audio/audout_u.h @@ -38,16 +38,6 @@ private: void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); - - enum class PcmFormat : u32 { - Invalid = 0, - Int8 = 1, - Int16 = 2, - Int24 = 3, - Int32 = 4, - PcmFloat = 5, - Adpcm = 6, - }; }; } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 6aed9e2fa..9e75eb3a6 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -15,17 +15,14 @@ namespace Service::Audio { -/// TODO(bunnei): Find a proper value for the audio_ticks -constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)}; - class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { public: - explicit IAudioRenderer(AudioRendererParameter audren_params) - : ServiceFramework("IAudioRenderer"), worker_params(audren_params) { + explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params) + : ServiceFramework("IAudioRenderer") { static const FunctionInfo functions[] = { - {0, nullptr, "GetAudioRendererSampleRate"}, - {1, nullptr, "GetAudioRendererSampleCount"}, - {2, nullptr, "GetAudioRendererMixBufferCount"}, + {0, &IAudioRenderer::GetAudioRendererSampleRate, "GetAudioRendererSampleRate"}, + {1, &IAudioRenderer::GetAudioRendererSampleCount, "GetAudioRendererSampleCount"}, + {2, &IAudioRenderer::GetAudioRendererMixBufferCount, "GetAudioRendererMixBufferCount"}, {3, nullptr, "GetAudioRendererState"}, {4, &IAudioRenderer::RequestUpdateAudioRenderer, "RequestUpdateAudioRenderer"}, {5, &IAudioRenderer::StartAudioRenderer, "StartAudioRenderer"}, @@ -39,21 +36,8 @@ public: RegisterHandlers(functions); system_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioRenderer:SystemEvent"); - - // Register event callback to update the Audio Buffer - audio_event = CoreTiming::RegisterEvent( - "IAudioRenderer::UpdateAudioCallback", [this](u64 userdata, int cycles_late) { - UpdateAudioCallback(); - CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event); - }); - - // Start the audio event - CoreTiming::ScheduleEvent(audio_ticks, audio_event); - voice_status_list.resize(worker_params.voice_count); - } - ~IAudioRenderer() { - CoreTiming::UnscheduleEvent(audio_event, 0); + Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); + renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event); } private: @@ -61,61 +45,31 @@ private: system_event->Signal(); } - void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { - UpdateDataHeader config{}; - auto buf = ctx.ReadBuffer(); - std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader)); - u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); - - std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); - std::memcpy(mem_pool_info.data(), - buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, - memory_pool_count * sizeof(MemoryPoolInfo)); - - std::vector<VoiceInfo> voice_info(worker_params.voice_count); - std::memcpy(voice_info.data(), - buf.data() + sizeof(UpdateDataHeader) + config.behavior_size + - config.memory_pools_size + config.voice_resource_size, - worker_params.voice_count * sizeof(VoiceInfo)); - - UpdateDataHeader response_data{worker_params}; - - ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); - - std::vector<u8> output(response_data.total_size); - std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader)); - std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); - for (unsigned i = 0; i < memory_pool.size(); i++) { - if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach) - memory_pool[i].state = MemoryPoolStates::Attached; - else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach) - memory_pool[i].state = MemoryPoolStates::Detached; - } - std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), - response_data.memory_pools_size); - - for (unsigned i = 0; i < voice_info.size(); i++) { - if (voice_info[i].is_new) { - voice_status_list[i].played_sample_count = 0; - voice_status_list[i].wave_buffer_consumed = 0; - } else if (voice_info[i].play_state == (u8)PlayStates::Started) { - for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) { - voice_status_list[i].played_sample_count += - (voice_info[i].wave_buffer[buff_idx].end_sample_offset - - voice_info[i].wave_buffer[buff_idx].start_sample_offset) / - 2; - voice_status_list[i].wave_buffer_consumed++; - } - } - } - std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size, - voice_status_list.data(), response_data.voices_size); + void GetAudioRendererSampleRate(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(renderer->GetSampleRate()); + LOG_DEBUG(Service_Audio, "called"); + } + + void GetAudioRendererSampleCount(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(renderer->GetSampleCount()); + LOG_DEBUG(Service_Audio, "called"); + } - ctx.WriteBuffer(output); + void GetAudioRendererMixBufferCount(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(renderer->GetMixBufferCount()); + LOG_DEBUG(Service_Audio, "called"); + } + void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { + ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer())); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); } @@ -136,8 +90,6 @@ private: } void QuerySystemEvent(Kernel::HLERequestContext& ctx) { - // system_event->Signal(); - IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(system_event); @@ -145,131 +97,8 @@ private: LOG_WARNING(Service_Audio, "(STUBBED) called"); } - enum class MemoryPoolStates : u32 { // Should be LE - Invalid = 0x0, - Unknown = 0x1, - RequestDetach = 0x2, - Detached = 0x3, - RequestAttach = 0x4, - Attached = 0x5, - Released = 0x6, - }; - - enum class PlayStates : u8 { - Started = 0, - Stopped = 1, - }; - - struct MemoryPoolEntry { - MemoryPoolStates state; - u32_le unknown_4; - u32_le unknown_8; - u32_le unknown_c; - }; - static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); - - struct MemoryPoolInfo { - u64_le pool_address; - u64_le pool_size; - MemoryPoolStates pool_state; - INSERT_PADDING_WORDS(3); // Unknown - }; - static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); - - struct UpdateDataHeader { - UpdateDataHeader() {} - - explicit UpdateDataHeader(const AudioRendererParameter& config) { - revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision - behavior_size = 0xb0; - memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; - voices_size = config.voice_count * 0x10; - voice_resource_size = 0x0; - effects_size = config.effect_count * 0x10; - mixes_size = 0x0; - sinks_size = config.sink_count * 0x20; - performance_manager_size = 0x10; - total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + - voices_size + effects_size + sinks_size + performance_manager_size; - } - - u32_le revision; - u32_le behavior_size; - u32_le memory_pools_size; - u32_le voices_size; - u32_le voice_resource_size; - u32_le effects_size; - u32_le mixes_size; - u32_le sinks_size; - u32_le performance_manager_size; - INSERT_PADDING_WORDS(6); - u32_le total_size; - }; - static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); - - struct BiquadFilter { - u8 enable; - INSERT_PADDING_BYTES(1); - s16_le numerator[3]; - s16_le denominator[2]; - }; - static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); - - struct WaveBuffer { - u64_le buffer_addr; - u64_le buffer_sz; - s32_le start_sample_offset; - s32_le end_sample_offset; - u8 loop; - u8 end_of_stream; - u8 sent_to_server; - INSERT_PADDING_BYTES(5); - u64 context_addr; - u64 context_sz; - INSERT_PADDING_BYTES(8); - }; - static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); - - struct VoiceInfo { - u32_le id; - u32_le node_id; - u8 is_new; - u8 is_in_use; - u8 play_state; - u8 sample_format; - u32_le sample_rate; - u32_le priority; - u32_le sorting_order; - u32_le channel_count; - float_le pitch; - float_le volume; - BiquadFilter biquad_filter[2]; - u32_le wave_buffer_count; - u16_le wave_buffer_head; - INSERT_PADDING_BYTES(6); - u64_le additional_params_addr; - u64_le additional_params_sz; - u32_le mix_id; - u32_le splitter_info_id; - WaveBuffer wave_buffer[4]; - u32_le voice_channel_resource_ids[6]; - INSERT_PADDING_BYTES(24); - }; - static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); - - struct VoiceOutStatus { - u64_le played_sample_count; - u32_le wave_buffer_consumed; - INSERT_PADDING_WORDS(1); - }; - static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); - - /// This is used to trigger the audio event callback. - CoreTiming::EventType* audio_event; - Kernel::SharedPtr<Kernel::Event> system_event; - AudioRendererParameter worker_params; - std::vector<VoiceOutStatus> voice_status_list; + std::unique_ptr<AudioCore::AudioRenderer> renderer; }; class IAudioDevice final : public ServiceFramework<IAudioDevice> { @@ -361,14 +190,15 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") { {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"}, {2, &AudRenU::GetAudioDevice, "GetAudioDevice"}, {3, nullptr, "OpenAudioRendererAuto"}, - {4, nullptr, "GetAudioDeviceServiceWithRevisionInfo"}, + {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, + "GetAudioDeviceServiceWithRevisionInfo"}, }; RegisterHandlers(functions); } void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw<AudioRendererParameter>(); + auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -379,9 +209,9 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw<AudioRendererParameter>(); + auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); - u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); + u64 buffer_sz = Common::AlignUp(4 * params.mix_buffer_count, 0x40); buffer_sz += params.unknown_c * 1024; buffer_sz += 0x940 * (params.unknown_c + 1); buffer_sz += 0x3F0 * params.voice_count; @@ -389,7 +219,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10); buffer_sz += Common::AlignUp((0x3C0 * (params.sink_count + params.unknown_c) + 4 * params.sample_count) * - (params.unknown_8 + 6), + (params.mix_buffer_count + 6), 0x40); if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) { @@ -445,6 +275,16 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Audio, "called"); } +void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<Audio::IAudioDevice>(); + + LOG_WARNING(Service_Audio, "(STUBBED) called"); // TODO(ogniK): Figure out what is different + // based on the current revision +} + bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap switch (feature) { diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index b9b81db4f..8600ac6e4 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -4,6 +4,7 @@ #pragma once +#include "audio_core/audio_renderer.h" #include "core/hle/service/service.h" namespace Kernel { @@ -12,24 +13,6 @@ class HLERequestContext; namespace Service::Audio { -struct AudioRendererParameter { - u32_le sample_rate; - u32_le sample_count; - u32_le unknown_8; - u32_le unknown_c; - u32_le voice_count; - u32_le sink_count; - u32_le effect_count; - u32_le unknown_1c; - u8 unknown_20; - INSERT_PADDING_BYTES(3); - u32_le splitter_count; - u32_le unknown_2c; - INSERT_PADDING_WORDS(1); - u32_le revision; -}; -static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size"); - class AudRenU final : public ServiceFramework<AudRenU> { public: explicit AudRenU(); @@ -39,6 +22,7 @@ private: void OpenAudioRenderer(Kernel::HLERequestContext& ctx); void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); void GetAudioDevice(Kernel::HLERequestContext& ctx); + void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); enum class AudioFeatures : u32 { Splitter, diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index e17d637e4..5e416cde2 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -59,7 +59,7 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const { std::string path(FileUtil::SanitizePath(path_)); auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); - if (path == "/" || path == "\\") { + if (path.empty()) { // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... return RESULT_SUCCESS; } @@ -281,15 +281,15 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { return sdmc_factory->Open(); } -void RegisterFileSystems() { +void RegisterFileSystems(const FileSys::VirtualFilesystem& vfs) { romfs_factory = nullptr; save_data_factory = nullptr; sdmc_factory = nullptr; - auto nand_directory = std::make_shared<FileSys::RealVfsDirectory>( - FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite); - auto sd_directory = std::make_shared<FileSys::RealVfsDirectory>( - FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::ReadWrite); + auto nand_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), + FileSys::Mode::ReadWrite); + auto sd_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), + FileSys::Mode::ReadWrite); auto savedata = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory)); save_data_factory = std::move(savedata); @@ -298,8 +298,8 @@ void RegisterFileSystems() { sdmc_factory = std::move(sdcard); } -void InstallInterfaces(SM::ServiceManager& service_manager) { - RegisterFileSystems(); +void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs) { + RegisterFileSystems(vfs); std::make_shared<FSP_LDR>()->InstallAsService(service_manager); std::make_shared<FSP_PR>()->InstallAsService(service_manager); std::make_shared<FSP_SRV>()->InstallAsService(service_manager); diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index d4483daa5..462c13f20 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -36,7 +36,7 @@ ResultVal<FileSys::VirtualDir> OpenSDMC(); // ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenBIS(); /// Registers all Filesystem services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); +void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs); // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of // pointers and booleans. This makes using a VfsDirectory with switch services much easier and diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e7ffb6bd1..1470f9017 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -193,13 +193,10 @@ private: template <typename T> static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data, FileSys::EntryType type) { + entries.reserve(entries.size() + new_data.size()); + for (const auto& new_entry : new_data) { - FileSys::Entry entry; - entry.filename[0] = '\0'; - std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); - entry.type = type; - entry.file_size = new_entry->GetSize(); - entries.emplace_back(std::move(entry)); + entries.emplace_back(new_entry->GetName(), type, new_entry->GetSize()); } } diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index fb4d89068..f2b0e509a 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -9,10 +9,110 @@ namespace Service::Friend { +class IFriendService final : public ServiceFramework<IFriendService> { +public: + IFriendService() : ServiceFramework("IFriendService") { + static const FunctionInfo functions[] = { + {0, nullptr, "GetCompletionEvent"}, + {1, nullptr, "Cancel"}, + {10100, nullptr, "GetFriendListIds"}, + {10101, nullptr, "GetFriendList"}, + {10102, nullptr, "UpdateFriendInfo"}, + {10110, nullptr, "GetFriendProfileImage"}, + {10200, nullptr, "SendFriendRequestForApplication"}, + {10211, nullptr, "AddFacedFriendRequestForApplication"}, + {10400, nullptr, "GetBlockedUserListIds"}, + {10500, nullptr, "GetProfileList"}, + {10600, nullptr, "DeclareOpenOnlinePlaySession"}, + {10601, &IFriendService::DeclareCloseOnlinePlaySession, + "DeclareCloseOnlinePlaySession"}, + {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"}, + {10700, nullptr, "GetPlayHistoryRegistrationKey"}, + {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, + {10702, nullptr, "AddPlayHistory"}, + {11000, nullptr, "GetProfileImageUrl"}, + {20100, nullptr, "GetFriendCount"}, + {20101, nullptr, "GetNewlyFriendCount"}, + {20102, nullptr, "GetFriendDetailedInfo"}, + {20103, nullptr, "SyncFriendList"}, + {20104, nullptr, "RequestSyncFriendList"}, + {20110, nullptr, "LoadFriendSetting"}, + {20200, nullptr, "GetReceivedFriendRequestCount"}, + {20201, nullptr, "GetFriendRequestList"}, + {20300, nullptr, "GetFriendCandidateList"}, + {20301, nullptr, "GetNintendoNetworkIdInfo"}, + {20302, nullptr, "GetSnsAccountLinkage"}, + {20303, nullptr, "GetSnsAccountProfile"}, + {20304, nullptr, "GetSnsAccountFriendList"}, + {20400, nullptr, "GetBlockedUserList"}, + {20401, nullptr, "SyncBlockedUserList"}, + {20500, nullptr, "GetProfileExtraList"}, + {20501, nullptr, "GetRelationship"}, + {20600, nullptr, "GetUserPresenceView"}, + {20700, nullptr, "GetPlayHistoryList"}, + {20701, nullptr, "GetPlayHistoryStatistics"}, + {20800, nullptr, "LoadUserSetting"}, + {20801, nullptr, "SyncUserSetting"}, + {20900, nullptr, "RequestListSummaryOverlayNotification"}, + {21000, nullptr, "GetExternalApplicationCatalog"}, + {30100, nullptr, "DropFriendNewlyFlags"}, + {30101, nullptr, "DeleteFriend"}, + {30110, nullptr, "DropFriendNewlyFlag"}, + {30120, nullptr, "ChangeFriendFavoriteFlag"}, + {30121, nullptr, "ChangeFriendOnlineNotificationFlag"}, + {30200, nullptr, "SendFriendRequest"}, + {30201, nullptr, "SendFriendRequestWithApplicationInfo"}, + {30202, nullptr, "CancelFriendRequest"}, + {30203, nullptr, "AcceptFriendRequest"}, + {30204, nullptr, "RejectFriendRequest"}, + {30205, nullptr, "ReadFriendRequest"}, + {30210, nullptr, "GetFacedFriendRequestRegistrationKey"}, + {30211, nullptr, "AddFacedFriendRequest"}, + {30212, nullptr, "CancelFacedFriendRequest"}, + {30213, nullptr, "GetFacedFriendRequestProfileImage"}, + {30214, nullptr, "GetFacedFriendRequestProfileImageFromPath"}, + {30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"}, + {30216, nullptr, "ResendFacedFriendRequest"}, + {30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"}, + {30300, nullptr, "GetSnsAccountLinkPageUrl"}, + {30301, nullptr, "UnlinkSnsAccount"}, + {30400, nullptr, "BlockUser"}, + {30401, nullptr, "BlockUserWithApplicationInfo"}, + {30402, nullptr, "UnblockUser"}, + {30500, nullptr, "GetProfileExtraFromFriendCode"}, + {30700, nullptr, "DeletePlayHistory"}, + {30810, nullptr, "ChangePresencePermission"}, + {30811, nullptr, "ChangeFriendRequestReception"}, + {30812, nullptr, "ChangePlayLogPermission"}, + {30820, nullptr, "IssueFriendCode"}, + {30830, nullptr, "ClearPlayLog"}, + {49900, nullptr, "DeleteNetworkServiceAccountCache"}, + }; + + RegisterHandlers(functions); + } + +private: + void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) { + // Stub used by Splatoon 2 + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + void UpdateUserPresence(Kernel::HLERequestContext& ctx) { + // Stub used by Retro City Rampage + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } +}; + void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Friend, "(STUBBED) called"); + rb.PushIpcInterface<IFriendService>(); + LOG_DEBUG(Service_ACC, "called"); } Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ed53f96c5..970942d3f 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -291,6 +291,7 @@ private: class Hid final : public ServiceFramework<Hid> { public: Hid() : ServiceFramework("hid") { + // clang-format off static const FunctionInfo functions[] = { {0, &Hid::CreateAppletResource, "CreateAppletResource"}, {1, &Hid::ActivateDebugPad, "ActivateDebugPad"}, @@ -333,14 +334,13 @@ public: {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"}, {103, &Hid::ActivateNpad, "ActivateNpad"}, {104, nullptr, "DeactivateNpad"}, - {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, - "AcquireNpadStyleSetUpdateEventHandle"}, - {107, nullptr, "DisconnectNpad"}, + {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, + {107, &Hid::DisconnectNpad, "DisconnectNpad"}, {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, + {109, nullptr, "ActivateNpadWithRevision"}, {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, - {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, - "SetNpadJoyAssignmentModeSingleByDefault"}, + {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, @@ -397,6 +397,8 @@ public: {1000, nullptr, "SetNpadCommunicationMode"}, {1001, nullptr, "GetNpadCommunicationMode"}, }; + // clang-format on + RegisterHandlers(functions); event = Kernel::Event::Create(Kernel::ResetType::OneShot, "hid:EventHandle"); @@ -456,7 +458,7 @@ private: } void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); // TODO (Hexagon12): Properly implement reading gyroscope values from controllers. rb.Push(true); @@ -495,6 +497,12 @@ private: LOG_WARNING(Service_HID, "(STUBBED) called"); } + void DisconnectNpad(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index 08f45b78a..7b91bb258 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -9,42 +9,63 @@ namespace Service::MM { -void InstallInterfaces(SM::ServiceManager& service_manager) { - std::make_shared<MM_U>()->InstallAsService(service_manager); -} +class MM_U final : public ServiceFramework<MM_U> { +public: + explicit MM_U() : ServiceFramework{"mm:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &MM_U::Initialize, "InitializeOld"}, + {1, &MM_U::Finalize, "FinalizeOld"}, + {2, &MM_U::SetAndWait, "SetAndWaitOld"}, + {3, &MM_U::Get, "GetOld"}, + {4, &MM_U::Initialize, "Initialize"}, + {5, &MM_U::Finalize, "Finalize"}, + {6, &MM_U::SetAndWait, "SetAndWait"}, + {7, &MM_U::Get, "Get"}, + }; + // clang-format on -void MM_U::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_MM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} + RegisterHandlers(functions); + } -void MM_U::SetAndWait(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - min = rp.Pop<u32>(); - max = rp.Pop<u32>(); - current = min; +private: + void Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_MM, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } - LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} + void Finalize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_MM, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } -void MM_U::Get(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_MM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(current); -} + void SetAndWait(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + min = rp.Pop<u32>(); + max = rp.Pop<u32>(); + current = min; -MM_U::MM_U() : ServiceFramework("mm:u") { - static const FunctionInfo functions[] = { - {0, nullptr, "InitializeOld"}, {1, nullptr, "FinalizeOld"}, - {2, nullptr, "SetAndWaitOld"}, {3, nullptr, "GetOld"}, - {4, &MM_U::Initialize, "Initialize"}, {5, nullptr, "Finalize"}, - {6, &MM_U::SetAndWait, "SetAndWait"}, {7, &MM_U::Get, "Get"}, - }; - RegisterHandlers(functions); + LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + void Get(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_MM, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(current); + } + + u32 min{0}; + u32 max{0}; + u32 current{0}; +}; + +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<MM_U>()->InstallAsService(service_manager); } } // namespace Service::MM diff --git a/src/core/hle/service/mm/mm_u.h b/src/core/hle/service/mm/mm_u.h index 79eeedf9c..5439fa653 100644 --- a/src/core/hle/service/mm/mm_u.h +++ b/src/core/hle/service/mm/mm_u.h @@ -8,21 +8,6 @@ namespace Service::MM { -class MM_U final : public ServiceFramework<MM_U> { -public: - MM_U(); - ~MM_U() = default; - -private: - void Initialize(Kernel::HLERequestContext& ctx); - void SetAndWait(Kernel::HLERequestContext& ctx); - void Get(Kernel::HLERequestContext& ctx); - - u32 min{0}; - u32 max{0}; - u32 current{0}; -}; - /// Registers all MM services with the specified service manager. void InstallInterfaces(SM::ServiceManager& service_manager); diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 2b74e6a33..8bc49935a 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -7,8 +7,8 @@ #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" #include "core/hle/service/nvdrv/devices/nvmap.h" +#include "video_core/gpu.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Service::Nvidia::Devices { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 4b601781f..be2b79256 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -2,14 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" #include "core/hle/service/nvdrv/devices/nvmap.h" +#include "video_core/memory_manager.h" +#include "video_core/rasterizer_interface.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Service::Nvidia::Devices { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 671b092e1..5685eb2be 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -2,6 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstdlib> +#include <cstring> + #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 090261a60..6b496e9fe 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -5,8 +5,6 @@ #pragma once #include <array> -#include <cstdlib> -#include <cstring> #include <vector> #include "common/common_types.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 010072a5b..ae421247d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 5a1123ad2..4cdf7f613 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> -#include <map> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" +#include "core/memory.h" +#include "video_core/gpu.h" +#include "video_core/memory_manager.h" namespace Service::Nvidia::Devices { @@ -145,7 +147,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp } params.fence_out.id = 0; params.fence_out.value = 0; - std::memcpy(output.data(), ¶ms, output.size()); + std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index aa8df2e6e..650ed8fbc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -6,6 +6,7 @@ #include <memory> #include <vector> +#include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index b51c73ee8..364619e67 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> + #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 0192aecdd..6ad74421b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -4,11 +4,9 @@ #pragma once -#include <array> -#include <cstdlib> -#include <cstring> #include <vector> #include "common/common_types.h" +#include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service::Nvidia::Devices { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp new file mode 100644 index 000000000..51f01077b --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -0,0 +1,34 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <cstring> + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" + +namespace Service::Nvidia::Devices { + +u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { + LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", + command.raw, input.size(), output.size()); + + switch (static_cast<IoctlCommand>(command.raw)) { + case IoctlCommand::IocSetNVMAPfdCommand: + return SetNVMAPfd(input, output); + } + + UNIMPLEMENTED_MSG("Unimplemented ioctl"); + return 0; +} + +u32 nvhost_nvjpg::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { + IoctlSetNvmapFD params{}; + std::memcpy(¶ms, input.data(), input.size()); + LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); + nvmap_fd = params.nvmap_fd; + return 0; +} + +} // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h new file mode 100644 index 000000000..2b0eb43ee --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h @@ -0,0 +1,36 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include "common/common_types.h" +#include "common/swap.h" +#include "core/hle/service/nvdrv/devices/nvdevice.h" + +namespace Service::Nvidia::Devices { + +class nvhost_nvjpg final : public nvdevice { +public: + nvhost_nvjpg() = default; + ~nvhost_nvjpg() override = default; + + u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; + +private: + enum class IoctlCommand : u32_le { + IocSetNVMAPfdCommand = 0x40044801, + }; + + struct IoctlSetNvmapFD { + u32_le nvmap_fd; + }; + static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); + + u32_le nvmap_fd{}; + + u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); +}; + +} // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp new file mode 100644 index 000000000..fcb488d50 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -0,0 +1,34 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <cstring> + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/hle/service/nvdrv/devices/nvhost_vic.h" + +namespace Service::Nvidia::Devices { + +u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { + LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", + command.raw, input.size(), output.size()); + + switch (static_cast<IoctlCommand>(command.raw)) { + case IoctlCommand::IocSetNVMAPfdCommand: + return SetNVMAPfd(input, output); + } + + UNIMPLEMENTED_MSG("Unimplemented ioctl"); + return 0; +} + +u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { + IoctlSetNvmapFD params{}; + std::memcpy(¶ms, input.data(), input.size()); + LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); + nvmap_fd = params.nvmap_fd; + return 0; +} + +} // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h new file mode 100644 index 000000000..c7d681e52 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -0,0 +1,36 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include "common/common_types.h" +#include "common/swap.h" +#include "core/hle/service/nvdrv/devices/nvdevice.h" + +namespace Service::Nvidia::Devices { + +class nvhost_vic final : public nvdevice { +public: + nvhost_vic() = default; + ~nvhost_vic() override = default; + + u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; + +private: + enum class IoctlCommand : u32_le { + IocSetNVMAPfdCommand = 0x40044801, + }; + + struct IoctlSetNvmapFD { + u32_le nvmap_fd; + }; + static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); + + u32_le nvmap_fd{}; + + u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); +}; + +} // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 724eeb139..e9305bfb3 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include <algorithm> -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 959b5ba29..1c3529bb6 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h @@ -5,7 +5,6 @@ #pragma once #include <memory> -#include <string> #include "core/hle/kernel/event.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 1555ea806..2de39822f 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -12,23 +12,24 @@ #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" +#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" +#include "core/hle/service/nvdrv/devices/nvhost_vic.h" #include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/hle/service/nvdrv/interface.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/nvmemp.h" +#include "core/hle/service/nvflinger/nvflinger.h" namespace Service::Nvidia { -std::weak_ptr<Module> nvdrv; - -void InstallInterfaces(SM::ServiceManager& service_manager) { +void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger) { auto module_ = std::make_shared<Module>(); std::make_shared<NVDRV>(module_, "nvdrv")->InstallAsService(service_manager); std::make_shared<NVDRV>(module_, "nvdrv:a")->InstallAsService(service_manager); std::make_shared<NVDRV>(module_, "nvdrv:s")->InstallAsService(service_manager); std::make_shared<NVDRV>(module_, "nvdrv:t")->InstallAsService(service_manager); std::make_shared<NVMEMP>()->InstallAsService(service_manager); - nvdrv = module_; + nvflinger.SetNVDrvInstance(module_); } Module::Module() { @@ -40,6 +41,8 @@ Module::Module() { devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); devices["/dev/nvhost-ctrl"] = std::make_shared<Devices::nvhost_ctrl>(); devices["/dev/nvhost-nvdec"] = std::make_shared<Devices::nvhost_nvdec>(); + devices["/dev/nvhost-nvjpg"] = std::make_shared<Devices::nvhost_nvjpg>(); + devices["/dev/nvhost-vic"] = std::make_shared<Devices::nvhost_vic>(); } u32 Module::Open(const std::string& device_name) { @@ -54,7 +57,7 @@ u32 Module::Open(const std::string& device_name) { return fd; } -u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) { +u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) { auto itr = open_files.find(fd); ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 184f3c9fc..99eb1128a 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -10,6 +10,10 @@ #include "common/common_types.h" #include "core/hle/service/service.h" +namespace Service::NVFlinger { +class NVFlinger; +} + namespace Service::Nvidia { namespace Devices { @@ -56,8 +60,6 @@ private: }; /// Registers all NVDRV services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager); - -extern std::weak_ptr<Module> nvdrv; +void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger); } // namespace Service::Nvidia diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp index 9ca6e5512..0e8e21bad 100644 --- a/src/core/hle/service/nvdrv/nvmemp.cpp +++ b/src/core/hle/service/nvdrv/nvmemp.cpp @@ -4,8 +4,6 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "core/hle/ipc_helpers.h" -#include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/nvmemp.h" namespace Service::Nvidia { diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index adf180509..ef5713a71 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -16,7 +16,7 @@ BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { Kernel::Event::Create(Kernel::ResetType::Sticky, "BufferQueue NativeHandle"); } -void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { +void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { Buffer buffer{}; buffer.slot = slot; buffer.igbp_buffer = igbp_buffer; diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 004170538..db2e17c0c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -6,6 +6,7 @@ #include <vector> #include <boost/optional.hpp> +#include "common/common_funcs.h" #include "common/math_util.h" #include "common/swap.h" #include "core/hle/kernel/event.h" @@ -72,7 +73,7 @@ public: MathUtil::Rectangle<int> crop_rect; }; - void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); + void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); boost::optional<u32> DequeueBuffer(u32 width, u32 height); const IGBPBuffer& RequestBuffer(u32 slot) const; void QueueBuffer(u32 slot, BufferTransformFlags transform, diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 0bf51062c..a26a5f812 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -3,8 +3,11 @@ // Refer to the license.txt file included. #include <algorithm> +#include <boost/optional.hpp> #include "common/alignment.h" +#include "common/assert.h" +#include "common/logging/log.h" #include "common/microprofile.h" #include "common/scope_exit.h" #include "core/core.h" @@ -31,7 +34,7 @@ NVFlinger::NVFlinger() { // Schedule the screen composition events composition_event = - CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { + CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) { Compose(); CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); }); @@ -43,7 +46,11 @@ NVFlinger::~NVFlinger() { CoreTiming::UnscheduleEvent(composition_event, 0); } -u64 NVFlinger::OpenDisplay(const std::string& name) { +void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { + nvdrv = std::move(instance); +} + +u64 NVFlinger::OpenDisplay(std::string_view name) { LOG_WARNING(Service, "Opening display {}", name); // TODO(Subv): Currently we only support the Default display. @@ -138,9 +145,6 @@ void NVFlinger::Compose() { auto& igbp_buffer = buffer->igbp_buffer; // Now send the buffer to the GPU for drawing. - auto nvdrv = Nvidia::nvdrv.lock(); - ASSERT(nvdrv); - // TODO(Subv): Support more than just disp0. The display device selection is probably based // on which display we're drawing (Default, Internal, External, etc) auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0"); diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 2c908297b..f7112949f 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -5,13 +5,21 @@ #pragma once #include <memory> -#include <boost/optional.hpp> +#include <string> +#include <string_view> +#include <vector> + +#include "common/common_types.h" #include "core/hle/kernel/event.h" namespace CoreTiming { struct EventType; } +namespace Service::Nvidia { +class Module; +} + namespace Service::NVFlinger { class BufferQueue; @@ -40,8 +48,11 @@ public: NVFlinger(); ~NVFlinger(); + /// Sets the NVDrv module instance to use to send buffers to the GPU. + void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); + /// Opens the specified display and returns the id. - u64 OpenDisplay(const std::string& name); + u64 OpenDisplay(std::string_view name); /// Creates a layer on the specified display and returns the layer id. u64 CreateLayer(u64 display_id); @@ -66,6 +77,8 @@ private: /// Returns the layer identified by the specified id in the desired display. Layer& GetLayer(u64 display_id, u64 layer_id); + std::shared_ptr<Nvidia::Module> nvdrv; + std::vector<Display> displays; std::vector<std::shared_ptr<BufferQueue>> buffer_queues; diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 31ea79773..11951adaf 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -63,6 +63,7 @@ #include "core/hle/service/spl/module.h" #include "core/hle/service/ssl/ssl.h" #include "core/hle/service/time/time.h" +#include "core/hle/service/usb/usb.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/wlan/wlan.h" @@ -197,7 +198,7 @@ void AddNamedPort(std::string name, SharedPtr<ClientPort> port) { } /// Initialize ServiceManager -void Init(std::shared_ptr<SM::ServiceManager>& sm) { +void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) { // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it // here and pass it into the respective InstallInterfaces functions. auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(); @@ -220,7 +221,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { EUPLD::InstallInterfaces(*sm); Fatal::InstallInterfaces(*sm); FGM::InstallInterfaces(*sm); - FileSystem::InstallInterfaces(*sm); + FileSystem::InstallInterfaces(*sm, rfs); Friend::InstallInterfaces(*sm); GRC::InstallInterfaces(*sm); HID::InstallInterfaces(*sm); @@ -237,7 +238,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { NIFM::InstallInterfaces(*sm); NIM::InstallInterfaces(*sm); NS::InstallInterfaces(*sm); - Nvidia::InstallInterfaces(*sm); + Nvidia::InstallInterfaces(*sm, *nv_flinger); PCIe::InstallInterfaces(*sm); PCTL::InstallInterfaces(*sm); PCV::InstallInterfaces(*sm); @@ -249,6 +250,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { SPL::InstallInterfaces(*sm); SSL::InstallInterfaces(*sm); Time::InstallInterfaces(*sm); + USB::InstallInterfaces(*sm); VI::InstallInterfaces(*sm, nv_flinger); WLAN::InstallInterfaces(*sm); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 046c5e18d..cd9c74f3d 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -22,6 +22,10 @@ class ServerSession; class HLERequestContext; } // namespace Kernel +namespace FileSys { +class VfsFilesystem; +} + namespace Service { namespace SM { @@ -177,7 +181,8 @@ private: }; /// Initialize ServiceManager -void Init(std::shared_ptr<SM::ServiceManager>& sm); +void Init(std::shared_ptr<SM::ServiceManager>& sm, + const std::shared_ptr<FileSys::VfsFilesystem>& vfs); /// Shutdown ServiceManager void Shutdown(); diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 37b58bb77..2172c681b 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -80,8 +80,8 @@ public: {5, nullptr, "GetTimeZoneRuleVersion"}, {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, - {200, nullptr, "ToPosixTime"}, - {201, nullptr, "ToPosixTimeWithMyRule"}, + {201, nullptr, "ToPosixTime"}, + {202, nullptr, "ToPosixTimeWithMyRule"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp new file mode 100644 index 000000000..e7fb5a419 --- /dev/null +++ b/src/core/hle/service/usb/usb.cpp @@ -0,0 +1,238 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" +#include "core/hle/service/usb/usb.h" + +namespace Service::USB { + +class IDsInterface final : public ServiceFramework<IDsInterface> { +public: + explicit IDsInterface() : ServiceFramework{"IDsInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetDsEndpoint"}, + {1, nullptr, "GetSetupEvent"}, + {2, nullptr, "Unknown"}, + {3, nullptr, "EnableInterface"}, + {4, nullptr, "DisableInterface"}, + {5, nullptr, "CtrlInPostBufferAsync"}, + {6, nullptr, "CtrlOutPostBufferAsync"}, + {7, nullptr, "GetCtrlInCompletionEvent"}, + {8, nullptr, "GetCtrlInReportData"}, + {9, nullptr, "GetCtrlOutCompletionEvent"}, + {10, nullptr, "GetCtrlOutReportData"}, + {11, nullptr, "StallCtrl"}, + {12, nullptr, "AppendConfigurationData"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_DS final : public ServiceFramework<USB_DS> { +public: + explicit USB_DS() : ServiceFramework{"usb:ds"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindDevice"}, + {1, nullptr, "BindClientProcess"}, + {2, nullptr, "GetDsInterface"}, + {3, nullptr, "GetStateChangeEvent"}, + {4, nullptr, "GetState"}, + {5, nullptr, "ClearDeviceData"}, + {6, nullptr, "AddUsbStringDescriptor"}, + {7, nullptr, "DeleteUsbStringDescriptor"}, + {8, nullptr, "SetUsbDeviceDescriptor"}, + {9, nullptr, "SetBinaryObjectStore"}, + {10, nullptr, "Enable"}, + {11, nullptr, "Disable"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IClientEpSession final : public ServiceFramework<IClientEpSession> { +public: + explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "PostBufferAsync"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "Unknown7"}, + {8, nullptr, "Unknown8"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IClientIfSession final : public ServiceFramework<IClientIfSession> { +public: + explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "CtrlXferAsync"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "GetCtrlXferReport"}, + {8, nullptr, "Unknown7"}, + {9, nullptr, "GetClientEpSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_HS final : public ServiceFramework<USB_HS> { +public: + explicit USB_HS() : ServiceFramework{"usb:hs"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindClientProcess"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {3, nullptr, "Unknown3"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "GetInterfaceStateChangeEvent"}, + {7, nullptr, "GetClientIfSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IPdSession final : public ServiceFramework<IPdSession> { +public: + explicit IPdSession() : ServiceFramework{"IPdSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindNoticeEvent"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "GetStatus"}, + {3, nullptr, "GetNotice"}, + {4, nullptr, "Unknown2"}, + {5, nullptr, "Unknown3"}, + {6, nullptr, "ReplyPowerRequest"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_PD final : public ServiceFramework<USB_PD> { +public: + explicit USB_PD() : ServiceFramework{"usb:pd"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &USB_PD::GetPdSession, "GetPdSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetPdSession(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IPdSession>(); + + LOG_DEBUG(Service_USB, "called"); + } +}; + +class IPdCradleSession final : public ServiceFramework<IPdCradleSession> { +public: + explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "VdmUserWrite"}, + {1, nullptr, "VdmUserRead"}, + {2, nullptr, "Vdm20Init"}, + {3, nullptr, "GetFwType"}, + {4, nullptr, "GetFwRevision"}, + {5, nullptr, "GetManufacturerId"}, + {6, nullptr, "GetDeviceId"}, + {7, nullptr, "Unknown1"}, + {8, nullptr, "Unknown2"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_PD_C final : public ServiceFramework<USB_PD_C> { +public: + explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetPdCradleSession(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IPdCradleSession>(); + + LOG_DEBUG(Service_USB, "called"); + } +}; + +class USB_PM final : public ServiceFramework<USB_PM> { +public: + explicit USB_PM() : ServiceFramework{"usb:pm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<USB_DS>()->InstallAsService(sm); + std::make_shared<USB_HS>()->InstallAsService(sm); + std::make_shared<USB_PD>()->InstallAsService(sm); + std::make_shared<USB_PD_C>()->InstallAsService(sm); + std::make_shared<USB_PM>()->InstallAsService(sm); +} + +} // namespace Service::USB diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h new file mode 100644 index 000000000..970a11fe8 --- /dev/null +++ b/src/core/hle/service/usb/usb.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::USB { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::USB diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index b0277a875..de05f21d8 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -7,6 +7,7 @@ #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" @@ -17,8 +18,54 @@ namespace Loader { -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) - : AppLoader(std::move(file)) {} +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_) + : AppLoader(std::move(file_)) { + const auto dir = file->GetContainingDirectory(); + + // Icon + FileSys::VirtualFile icon_file = nullptr; + for (const auto& language : FileSys::LANGUAGE_NAMES) { + icon_file = dir->GetFile("icon_" + std::string(language) + ".dat"); + if (icon_file != nullptr) { + icon_data = icon_file->ReadAllBytes(); + break; + } + } + + if (icon_data.empty()) { + // Any png, jpeg, or bmp file + const auto& files = dir->GetFiles(); + const auto icon_iter = + std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { + return file->GetExtension() == "png" || file->GetExtension() == "jpg" || + file->GetExtension() == "bmp" || file->GetExtension() == "jpeg"; + }); + if (icon_iter != files.end()) + icon_data = (*icon_iter)->ReadAllBytes(); + } + + // Metadata + FileSys::VirtualFile nacp_file = dir->GetFile("control.nacp"); + if (nacp_file == nullptr) { + const auto& files = dir->GetFiles(); + const auto nacp_iter = + std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { + return file->GetExtension() == "nacp"; + }); + if (nacp_iter != files.end()) + nacp_file = *nacp_iter; + } + + if (nacp_file != nullptr) { + FileSys::NACP nacp(nacp_file); + title_id = nacp.GetTitleId(); + name = nacp.GetApplicationName(); + } +} + +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( + FileSys::VirtualDir directory) + : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {} FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { @@ -34,10 +81,15 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( return ResultStatus::ErrorAlreadyLoaded; } - const FileSys::VirtualDir dir = file->GetContainingDirectory(); + if (dir == nullptr) { + if (file == nullptr) + return ResultStatus::ErrorNullFile; + dir = file->GetContainingDirectory(); + } + const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); if (npdm == nullptr) - return ResultStatus::ErrorInvalidFormat; + return ResultStatus::ErrorMissingNPDM; ResultStatus result = metadata.Load(npdm); if (result != ResultStatus::Success) { @@ -47,7 +99,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) { - return ResultStatus::ErrorUnsupportedArch; + return ResultStatus::Error32BitISA; } // Load NSO modules @@ -91,9 +143,30 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { if (romfs == nullptr) - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoRomFS; dir = romfs; return ResultStatus::Success; } +ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) { + if (icon_data.empty()) + return ResultStatus::ErrorNoIcon; + buffer = icon_data; + return ResultStatus::Success; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) { + if (name.empty()) + return ResultStatus::ErrorNoControl; + out_program_id = title_id; + return ResultStatus::Success; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { + if (name.empty()) + return ResultStatus::ErrorNoControl; + title = name; + return ResultStatus::Success; +} + } // namespace Loader diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 7319ba6ea..b20804f75 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader { public: explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); + // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' + explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory); + /** * Returns the type of the file * @param file std::shared_ptr<VfsFile> open file @@ -36,10 +39,18 @@ public: ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; + ResultStatus ReadIcon(std::vector<u8>& buffer) override; + ResultStatus ReadProgramId(u64& out_program_id) override; + ResultStatus ReadTitle(std::string& title) override; private: FileSys::ProgramMetadata metadata; FileSys::VirtualFile romfs; + FileSys::VirtualDir dir; + + std::vector<u8> icon_data; + std::string name; + u64 title_id{}; }; } // namespace Loader diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index a7133f5a6..401cad3ab 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -390,7 +390,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) { std::vector<u8> buffer = file->ReadAllBytes(); if (buffer.size() != file->GetSize()) - return ResultStatus::Error; + return ResultStatus::ErrorIncorrectELFFileSize; ElfReader elf_reader(&buffer[0]); SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 57e6c0365..1f2f31535 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -43,10 +43,6 @@ FileType IdentifyFile(FileSys::VirtualFile file) { return FileType::Unknown; } -FileType IdentifyFile(const std::string& file_name) { - return IdentifyFile(std::make_shared<FileSys::RealVfsFile>(file_name)); -} - FileType GuessFromFilename(const std::string& name) { if (name == "main") return FileType::DeconstructedRomDirectory; @@ -68,7 +64,7 @@ FileType GuessFromFilename(const std::string& name) { return FileType::Unknown; } -const char* GetFileTypeString(FileType type) { +std::string GetFileTypeString(FileType type) { switch (type) { case FileType::ELF: return "ELF"; @@ -90,6 +86,55 @@ const char* GetFileTypeString(FileType type) { return "unknown"; } +constexpr std::array<const char*, 36> RESULT_MESSAGES{ + "The operation completed successfully.", + "The loader requested to load is already loaded.", + "The operation is not implemented.", + "The loader is not initialized properly.", + "The NPDM file has a bad header.", + "The NPDM has a bad ACID header.", + "The NPDM has a bad ACI header,", + "The NPDM file has a bad file access control.", + "The NPDM has a bad file access header.", + "The PFS/HFS partition has a bad header.", + "The PFS/HFS partition has incorrect size as determined by the header.", + "The NCA file has a bad header.", + "The general keyfile could not be found.", + "The NCA Header key could not be found.", + "The NCA Header key is incorrect or the header is invalid.", + "Support for NCA2-type NCAs is not implemented.", + "Support for NCA0-type NCAs is not implemented.", + "The titlekey for this Rights ID could not be found.", + "The titlekek for this crypto revision could not be found.", + "The Rights ID in the header is invalid.", + "The key area key for this application type and crypto revision could not be found.", + "The key area key is incorrect or the section header is invalid.", + "The titlekey and/or titlekek is incorrect or the section header is invalid.", + "The XCI file is missing a Program-type NCA.", + "The NCA file is not an application.", + "The ExeFS partition could not be found.", + "The XCI file has a bad header.", + "The XCI file is missing a partition.", + "The file could not be found or does not exist.", + "The game is missing a program metadata file (main.npdm).", + "The game uses the currently-unimplemented 32-bit architecture.", + "The RomFS could not be found.", + "The ELF file has incorrect size as determined by the header.", + "There was a general error loading the NRO into emulated memory.", + "There is no icon available.", + "There is no control data available.", +}; + +std::string GetMessageForResultStatus(ResultStatus status) { + return GetMessageForResultStatus(static_cast<u16>(status)); +} + +std::string GetMessageForResultStatus(u16 status) { + if (status >= 36) + return ""; + return RESULT_MESSAGES[status]; +} + /** * Get a loader for a file with a specific type * @param file The file to load diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index e69ab85ef..285363549 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -43,14 +43,6 @@ enum class FileType { FileType IdentifyFile(FileSys::VirtualFile file); /** - * Identifies the type of a bootable file based on the magic value in its header. - * @param file_name path to file - * @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine - * a filetype, and will never return FileType::Error. - */ -FileType IdentifyFile(const std::string& file_name); - -/** * Guess the type of a bootable file from its name * @param name String name of bootable file * @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine @@ -61,23 +53,51 @@ FileType GuessFromFilename(const std::string& name); /** * Convert a FileType into a string which can be displayed to the user. */ -const char* GetFileTypeString(FileType type); +std::string GetFileTypeString(FileType type); /// Return type for functions in Loader namespace -enum class ResultStatus { +enum class ResultStatus : u16 { Success, - Error, - ErrorInvalidFormat, - ErrorNotImplemented, - ErrorNotLoaded, - ErrorNotUsed, ErrorAlreadyLoaded, - ErrorMemoryAllocationFailed, - ErrorMissingKeys, - ErrorDecrypting, - ErrorUnsupportedArch, + ErrorNotImplemented, + ErrorNotInitialized, + ErrorBadNPDMHeader, + ErrorBadACIDHeader, + ErrorBadACIHeader, + ErrorBadFileAccessControl, + ErrorBadFileAccessHeader, + ErrorBadPFSHeader, + ErrorIncorrectPFSFileSize, + ErrorBadNCAHeader, + ErrorMissingProductionKeyFile, + ErrorMissingHeaderKey, + ErrorIncorrectHeaderKey, + ErrorNCA2, + ErrorNCA0, + ErrorMissingTitlekey, + ErrorMissingTitlekek, + ErrorInvalidRightsID, + ErrorMissingKeyAreaKey, + ErrorIncorrectKeyAreaKey, + ErrorIncorrectTitlekeyOrTitlekek, + ErrorXCIMissingProgramNCA, + ErrorNCANotProgram, + ErrorNoExeFS, + ErrorBadXCIHeader, + ErrorXCIMissingPartition, + ErrorNullFile, + ErrorMissingNPDM, + Error32BitISA, + ErrorNoRomFS, + ErrorIncorrectELFFileSize, + ErrorLoadingNRO, + ErrorNoIcon, + ErrorNoControl, }; +std::string GetMessageForResultStatus(ResultStatus status); +std::string GetMessageForResultStatus(u16 status); + /// Interface for loading an application class AppLoader : NonCopyable { public: diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index a1f8235d1..8498cc94b 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -22,7 +22,8 @@ namespace Loader { -AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} +AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_) + : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {} FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { FileSys::NCA nca(file); @@ -39,53 +40,24 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { return ResultStatus::ErrorAlreadyLoaded; } - nca = std::make_unique<FileSys::NCA>(file); - ResultStatus result = nca->GetStatus(); + const auto result = nca->GetStatus(); if (result != ResultStatus::Success) { return result; } if (nca->GetType() != FileSys::NCAContentType::Program) - return ResultStatus::ErrorInvalidFormat; + return ResultStatus::ErrorNCANotProgram; - auto exefs = nca->GetExeFS(); + const auto exefs = nca->GetExeFS(); if (exefs == nullptr) - return ResultStatus::ErrorInvalidFormat; + return ResultStatus::ErrorNoExeFS; - result = metadata.Load(exefs->GetFile("main.npdm")); - if (result != ResultStatus::Success) { - return result; - } - metadata.Print(); - - const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; - if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) { - return ResultStatus::ErrorUnsupportedArch; - } - - VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; - for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", - "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { - const VAddr load_addr = next_load_addr; - - next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr); - if (next_load_addr) { - LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); - // Register module with GDBStub - GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); - } else { - next_load_addr = load_addr; - } - } + directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs); - process->program_id = metadata.GetTitleID(); - process->svc_access_mask.set(); - process->address_mappings = default_address_mappings; - process->resource_limit = - Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(), - metadata.GetMainThreadStackSize()); + const auto load_result = directory_loader->Load(process); + if (load_result != ResultStatus::Success) + return load_result; if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); @@ -97,16 +69,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { if (nca == nullptr) - return ResultStatus::ErrorNotLoaded; + return ResultStatus::ErrorNotInitialized; if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoRomFS; dir = nca->GetRomFS(); return ResultStatus::Success; } ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { - if (nca == nullptr) - return ResultStatus::ErrorNotLoaded; + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + return ResultStatus::ErrorNotInitialized; out_program_id = nca->GetTitleId(); return ResultStatus::Success; } diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index e14d618b3..7f7d8ea0b 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -10,6 +10,7 @@ #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/object.h" #include "core/loader/loader.h" +#include "deconstructed_rom_directory.h" namespace Loader { @@ -32,7 +33,6 @@ public: ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; - ResultStatus ReadProgramId(u64& out_program_id) override; ~AppLoader_NCA(); @@ -40,7 +40,9 @@ public: private: FileSys::ProgramMetadata metadata; + FileSys::NCAHeader header; std::unique_ptr<FileSys::NCA> nca; + std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader; }; } // namespace Loader diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index dc053cdad..908d91eab 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -182,7 +182,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR}; if (!LoadNro(file, base_addr)) { - return ResultStatus::ErrorInvalidFormat; + return ResultStatus::ErrorLoadingNRO; } process->svc_access_mask.set(); @@ -197,7 +197,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { if (icon_data.empty()) { - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoIcon; } buffer = icon_data; @@ -206,7 +206,7 @@ ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) { if (nacp == nullptr) { - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoControl; } out_program_id = nacp->GetTitleId(); @@ -215,7 +215,7 @@ ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) { ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) { if (romfs == nullptr) { - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoRomFS; } dir = romfs; @@ -224,7 +224,7 @@ ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) { ResultStatus AppLoader_NRO::ReadTitle(std::string& title) { if (nacp == nullptr) { - return ResultStatus::ErrorNotUsed; + return ResultStatus::ErrorNoControl; } title = nacp->GetApplicationName(); diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index eb4dee2c2..5d67fb186 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -26,7 +26,25 @@ namespace Loader { AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), nca_loader(std::make_unique<AppLoader_NCA>( - xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {} + xci->GetNCAFileByType(FileSys::NCAContentType::Program))) { + if (xci->GetStatus() != ResultStatus::Success) + return; + const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); + if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) + return; + const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS()); + if (romfs == nullptr) + return; + for (const auto& language : FileSys::LANGUAGE_NAMES) { + icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat"); + if (icon_file != nullptr) + break; + } + const auto nacp_raw = romfs->GetFile("control.nacp"); + if (nacp_raw == nullptr) + return; + nacp_file = std::make_shared<FileSys::NACP>(nacp_raw); +} AppLoader_XCI::~AppLoader_XCI() = default; @@ -48,10 +66,13 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { return ResultStatus::ErrorAlreadyLoaded; } + if (xci->GetStatus() != ResultStatus::Success) + return xci->GetStatus(); + if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { if (!Core::Crypto::KeyManager::KeyFileExists(false)) - return ResultStatus::ErrorMissingKeys; - return ResultStatus::ErrorDecrypting; + return ResultStatus::ErrorMissingProductionKeyFile; + return ResultStatus::ErrorXCIMissingProgramNCA; } auto result = nca_loader->Load(process); @@ -71,4 +92,17 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) { return nca_loader->ReadProgramId(out_program_id); } +ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) { + if (icon_file == nullptr) + return ResultStatus::ErrorNoControl; + buffer = icon_file->ReadAllBytes(); + return ResultStatus::Success; +} + +ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { + if (nacp_file == nullptr) + return ResultStatus::ErrorNoControl; + title = nacp_file->GetApplicationName(); + return ResultStatus::Success; +} } // namespace Loader diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 0dbcfbdf8..973833050 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -33,12 +33,17 @@ public: ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; ResultStatus ReadProgramId(u64& out_program_id) override; + ResultStatus ReadIcon(std::vector<u8>& buffer) override; + ResultStatus ReadTitle(std::string& title) override; private: FileSys::ProgramMetadata metadata; std::unique_ptr<FileSys::XCI> xci; std::unique_ptr<AppLoader_NCA> nca_loader; + + FileSys::VirtualFile icon_file; + std::shared_ptr<FileSys::NACP> nacp_file; }; } // namespace Loader diff --git a/src/core/memory.h b/src/core/memory.h index b5d885b8a..b7fb3b9ed 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -140,10 +140,10 @@ void SetCurrentPageTable(PageTable* page_table); PageTable* GetCurrentPageTable(); /// Determines if the given VAddr is valid for the specified process. -bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); -bool IsValidVirtualAddress(const VAddr addr); +bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); +bool IsValidVirtualAddress(VAddr vaddr); /// Determines if the given VAddr is a kernel address -bool IsKernelVirtualAddress(const VAddr addr); +bool IsKernelVirtualAddress(VAddr vaddr); u8 Read8(VAddr addr); u16 Read16(VAddr addr); @@ -155,18 +155,17 @@ void Write16(VAddr addr, u16 data); void Write32(VAddr addr, u32 data); void Write64(VAddr addr, u64 data); -void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, - size_t size); -void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); -void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, +void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, size_t size); +void ReadBlock(VAddr src_addr, void* dest_buffer, size_t size); +void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, size_t size); -void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); -void ZeroBlock(const VAddr dest_addr, const size_t size); +void WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size); +void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, size_t size); void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); -u8* GetPointer(VAddr virtual_address); +u8* GetPointer(VAddr vaddr); -std::string ReadCString(VAddr virtual_address, std::size_t max_length); +std::string ReadCString(VAddr vaddr, std::size_t max_length); enum class FlushMode { /// Write back modified surfaces to RAM @@ -180,7 +179,7 @@ enum class FlushMode { /** * Mark each page touching the region as cached. */ -void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); +void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached); /** * Flushes and invalidates any externally cached rasterizer resources touching the given virtual diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 5f53b16d3..8e09b9b63 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -40,22 +40,21 @@ void PerfStats::EndGameFrame() { game_frames += 1; } -PerfStats::Results PerfStats::GetAndResetStats(u64 current_system_time_us) { +PerfStats::Results PerfStats::GetAndResetStats(microseconds current_system_time_us) { std::lock_guard<std::mutex> lock(object_mutex); - auto now = Clock::now(); + const auto now = Clock::now(); // Walltime elapsed since stats were reset - auto interval = duration_cast<DoubleSecs>(now - reset_point).count(); + const auto interval = duration_cast<DoubleSecs>(now - reset_point).count(); - auto system_us_per_second = - static_cast<double>(current_system_time_us - reset_point_system_us) / interval; + const auto system_us_per_second = (current_system_time_us - reset_point_system_us) / interval; Results results{}; results.system_fps = static_cast<double>(system_frames) / interval; results.game_fps = static_cast<double>(game_frames) / interval; results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() / static_cast<double>(system_frames); - results.emulation_speed = system_us_per_second / 1'000'000.0; + results.emulation_speed = system_us_per_second.count() / 1'000'000.0; // Reset counters reset_point = now; @@ -74,10 +73,10 @@ double PerfStats::GetLastFrameTimeScale() { return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; } -void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) { +void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher // values increase the time needed to recover and limit framerate again after spikes. - constexpr microseconds MAX_LAG_TIME_US = 25ms; + constexpr microseconds MAX_LAG_TIME_US = 25us; if (!Settings::values.toggle_framelimit) { return; @@ -85,7 +84,7 @@ void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) { auto now = Clock::now(); - frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us); + frame_limiting_delta_err += current_system_time_us - previous_system_time_us; frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime); frame_limiting_delta_err = std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US); diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 362b205c8..6e4619701 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -33,7 +33,7 @@ public: void EndSystemFrame(); void EndGameFrame(); - Results GetAndResetStats(u64 current_system_time_us); + Results GetAndResetStats(std::chrono::microseconds current_system_time_us); /** * Gets the ratio between walltime and the emulated time of the previous system frame. This is @@ -47,7 +47,7 @@ private: /// Point when the cumulative counters were reset Clock::time_point reset_point = Clock::now(); /// System time when the cumulative counters were reset - u64 reset_point_system_us = 0; + std::chrono::microseconds reset_point_system_us{0}; /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset Clock::duration accumulated_frametime = Clock::duration::zero(); @@ -68,11 +68,11 @@ class FrameLimiter { public: using Clock = std::chrono::high_resolution_clock; - void DoFrameLimiting(u64 current_system_time_us); + void DoFrameLimiting(std::chrono::microseconds current_system_time_us); private: /// Emulated system time (in microseconds) at the last limiter invocation - u64 previous_system_time_us = 0; + std::chrono::microseconds previous_system_time_us{0}; /// Walltime at the last limiter invocation Clock::time_point previous_walltime = Clock::now(); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index a4623223d..0da159559 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -7,22 +7,18 @@ #include "core/hle/service/hid/hid.h" #include "core/settings.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Settings { Values values = {}; void Apply() { - GDBStub::SetServerPort(values.gdbstub_port); GDBStub::ToggleServer(values.use_gdbstub); - VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; - auto& system_instance = Core::System::GetInstance(); if (system_instance.IsPoweredOn()) { - system_instance.Renderer().UpdateCurrentFramebufferLayout(); + system_instance.Renderer().RefreshBaseSettings(); } Service::HID::ReloadInputDevices(); diff --git a/src/tests/common/param_package.cpp b/src/tests/common/param_package.cpp index 19d372236..4c0f9654f 100644 --- a/src/tests/common/param_package.cpp +++ b/src/tests/common/param_package.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <catch.hpp> +#include <catch2/catch.hpp> #include <math.h> #include "common/param_package.h" diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index fcaa30990..2242c14cf 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include <catch.hpp> +#include <catch2/catch.hpp> #include <array> #include <bitset> diff --git a/src/tests/glad.cpp b/src/tests/glad.cpp index b0b016440..1797c0e3d 100644 --- a/src/tests/glad.cpp +++ b/src/tests/glad.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <catch.hpp> +#include <catch2/catch.hpp> #include <glad/glad.h> // This is not an actual test, but a work-around for issue #2183. diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 73978676f..275b430d9 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #define CATCH_CONFIG_MAIN -#include <catch.hpp> +#include <catch2/catch.hpp> // Catch provides the main function since we've given it the // CATCH_CONFIG_MAIN preprocessor directive. diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 31ea3adad..dc485e811 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -29,10 +29,10 @@ enum class BufferMethods { }; void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { - LOG_WARNING(HW_GPU, - "Processing method {:08X} on subchannel {} value " - "{:08X} remaining params {}", - method, subchannel, value, remaining_params); + LOG_TRACE(HW_GPU, + "Processing method {:08X} on subchannel {} value " + "{:08X} remaining params {}", + method, subchannel, value, remaining_params); if (method == static_cast<u32>(BufferMethods::BindObject)) { // Bind the current subchannel to the desired engine id. diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h index f7214ffec..a01153e0b 100644 --- a/src/video_core/command_processor.h +++ b/src/video_core/command_processor.h @@ -30,8 +30,7 @@ union CommandHeader { BitField<29, 3, SubmissionMode> mode; }; -static_assert(std::is_standard_layout<CommandHeader>::value == true, - "CommandHeader does not use standard layout"); +static_assert(std::is_standard_layout_v<CommandHeader>, "CommandHeader is not standard layout"); static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); } // namespace Tegra diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a235b543e..a46ed4bd7 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -23,12 +23,17 @@ Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {} void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { - auto macro_code = uploaded_macros.find(method); + // Reset the current macro. + executing_macro = 0; + // The requested macro must have been uploaded already. - ASSERT_MSG(macro_code != uploaded_macros.end(), "Macro %08X was not uploaded", method); + auto macro_code = uploaded_macros.find(method); + if (macro_code == uploaded_macros.end()) { + LOG_ERROR(HW_GPU, "Macro {:04X} was not uploaded", method); + return; + } - // Reset the current macro and execute it. - executing_macro = 0; + // Execute the current macro. macro_interpreter.Execute(macro_code->second, std::move(parameters)); } @@ -238,6 +243,8 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { auto& buffer = shader.const_buffers[bind_data.index]; + ASSERT(bind_data.index < Regs::MaxConstBuffers); + buffer.enabled = bind_data.valid.Value() != 0; buffer.index = bind_data.index; buffer.address = regs.const_buffer.BufferAddress(); @@ -285,8 +292,6 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { // TODO(Subv): Different data types for separate components are not supported ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); - // TODO(Subv): Only UNORM formats are supported for now. - ASSERT(r_type == Texture::ComponentType::UNORM); return tic_entry; } diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 4d0ff96a5..1b30ce018 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -44,7 +44,7 @@ public: static constexpr size_t MaxShaderProgram = 6; static constexpr size_t MaxShaderStage = 5; // Maximum number of const buffers per shader stage. - static constexpr size_t MaxConstBuffers = 16; + static constexpr size_t MaxConstBuffers = 18; enum class QueryMode : u32 { Write = 0, @@ -93,6 +93,7 @@ public: struct VertexAttribute { enum class Size : u32 { + Invalid = 0x0, Size_32_32_32_32 = 0x01, Size_32_32_32 = 0x02, Size_16_16_16_16 = 0x03, @@ -257,6 +258,10 @@ public: bool IsNormalized() const { return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); } + + bool IsValid() const { + return size != Size::Invalid; + } }; enum class PrimitiveTopology : u32 { @@ -352,6 +357,27 @@ public: OneMinusConstantColor = 0x62, ConstantAlpha = 0x63, OneMinusConstantAlpha = 0x64, + + // These values are used by Nouveau and some games. + ZeroGL = 0x4000, + OneGL = 0x4001, + SourceColorGL = 0x4300, + OneMinusSourceColorGL = 0x4301, + SourceAlphaGL = 0x4302, + OneMinusSourceAlphaGL = 0x4303, + DestAlphaGL = 0x4304, + OneMinusDestAlphaGL = 0x4305, + DestColorGL = 0x4306, + OneMinusDestColorGL = 0x4307, + SourceAlphaSaturateGL = 0x4308, + ConstantColorGL = 0xc001, + OneMinusConstantColorGL = 0xc002, + ConstantAlphaGL = 0xc003, + OneMinusConstantAlphaGL = 0xc004, + Source1ColorGL = 0xc900, + OneMinusSource1ColorGL = 0xc901, + Source1AlphaGL = 0xc902, + OneMinusSource1AlphaGL = 0xc903, }; u32 separate_alpha; diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c7e3fb4b1..2526ebf28 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -74,6 +74,7 @@ union Attribute { enum class Index : u64 { Position = 7, Attribute_0 = 8, + Attribute_31 = 39, // This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval // shader. @@ -199,6 +200,14 @@ enum class IMinMaxExchange : u64 { XHi = 3, }; +enum class XmadMode : u64 { + None = 0, + CLo = 1, + CHi = 2, + CSfu = 3, + CBcc = 4, +}; + enum class FlowCondition : u64 { Always = 0xF, Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? @@ -254,20 +263,15 @@ union Instruction { BitField<56, 1, u64> invert_b; } lop32i; - float GetImm20_19() const { - float result{}; + u32 GetImm20_19() const { u32 imm{static_cast<u32>(imm20_19)}; imm <<= 12; imm |= negate_imm ? 0x80000000 : 0; - std::memcpy(&result, &imm, sizeof(imm)); - return result; + return imm; } - float GetImm20_32() const { - float result{}; - s32 imm{static_cast<s32>(imm20_32)}; - std::memcpy(&result, &imm, sizeof(imm)); - return result; + u32 GetImm20_32() const { + return static_cast<u32>(imm20_32); } s32 GetSignedImm20_20() const { @@ -461,6 +465,18 @@ union Instruction { } bra; union { + BitField<20, 16, u64> imm20_16; + BitField<36, 1, u64> product_shift_left; + BitField<37, 1, u64> merge_37; + BitField<48, 1, u64> sign_a; + BitField<49, 1, u64> sign_b; + BitField<50, 3, XmadMode> mode; + BitField<52, 1, u64> high_b; + BitField<53, 1, u64> high_a; + BitField<56, 1, u64> merge_56; + } xmad; + + union { BitField<20, 14, u64> offset; BitField<34, 5, u64> index; } cbuf34; @@ -480,8 +496,7 @@ union Instruction { u64 value; }; static_assert(sizeof(Instruction) == 0x8, "Incorrect structure size"); -static_assert(std::is_standard_layout<Instruction>::value, - "Structure does not have standard layout"); +static_assert(std::is_standard_layout_v<Instruction>, "Instruction is not standard layout"); class OpCode { public: @@ -598,9 +613,17 @@ public: IntegerSetPredicate, PredicateSetPredicate, Conversion, + Xmad, Unknown, }; + /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be + /// conditionally executed). + static bool IsPredicatedInstruction(Id opcode) { + // TODO(Subv): Add the rest of unpredicated instructions. + return opcode != Id::SSY; + } + class Matcher { public: Matcher(const char* const name, u16 mask, u16 expected, OpCode::Id id, OpCode::Type type) @@ -780,10 +803,10 @@ private: INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"), INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), - INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"), - INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"), - INST("010100010-------", Id::XMAD_RC, Type::Arithmetic, "XMAD_RC"), - INST("0101101100------", Id::XMAD_RR, Type::Arithmetic, "XMAD_RR"), + INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), + INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), + INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), + INST("0101101100------", Id::XMAD_RR, Type::Xmad, "XMAD_RR"), }; #undef INST std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index b2a83ce0b..5a593c1f7 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/assert.h" #include "video_core/engines/fermi_2d.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_compute.h" @@ -11,6 +12,15 @@ namespace Tegra { +u32 FramebufferConfig::BytesPerPixel(PixelFormat format) { + switch (format) { + case PixelFormat::ABGR8: + return 4; + } + + UNREACHABLE(); +} + GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { memory_manager = std::make_unique<MemoryManager>(); maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager); @@ -34,18 +44,59 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { switch (format) { case RenderTargetFormat::RGBA32_FLOAT: + case RenderTargetFormat::RGBA32_UINT: return 16; + case RenderTargetFormat::RGBA16_UINT: + case RenderTargetFormat::RGBA16_UNORM: case RenderTargetFormat::RGBA16_FLOAT: case RenderTargetFormat::RG32_FLOAT: + case RenderTargetFormat::RG32_UINT: return 8; case RenderTargetFormat::RGBA8_UNORM: + case RenderTargetFormat::RGBA8_SNORM: + case RenderTargetFormat::RGBA8_SRGB: case RenderTargetFormat::RGB10_A2_UNORM: case RenderTargetFormat::BGRA8_UNORM: + case RenderTargetFormat::RG16_UNORM: + case RenderTargetFormat::RG16_SNORM: + case RenderTargetFormat::RG16_UINT: + case RenderTargetFormat::RG16_SINT: + case RenderTargetFormat::RG16_FLOAT: case RenderTargetFormat::R32_FLOAT: + case RenderTargetFormat::R11G11B10_FLOAT: + case RenderTargetFormat::R32_UINT: return 4; + case RenderTargetFormat::R16_UNORM: + case RenderTargetFormat::R16_SNORM: + case RenderTargetFormat::R16_UINT: + case RenderTargetFormat::R16_SINT: + case RenderTargetFormat::R16_FLOAT: + case RenderTargetFormat::RG8_UNORM: + case RenderTargetFormat::RG8_SNORM: + return 2; + case RenderTargetFormat::R8_UNORM: + case RenderTargetFormat::R8_UINT: + return 1; default: UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); } } +u32 DepthFormatBytesPerPixel(DepthFormat format) { + switch (format) { + case DepthFormat::Z32_S8_X24_FLOAT: + return 8; + case DepthFormat::Z32_FLOAT: + case DepthFormat::S8_Z24_UNORM: + case DepthFormat::Z24_X8_UNORM: + case DepthFormat::Z24_S8_UNORM: + case DepthFormat::Z24_C8_UNORM: + return 4; + case DepthFormat::Z16_UNORM: + return 2; + default: + UNIMPLEMENTED_MSG("Unimplemented Depth format {}", static_cast<u32>(format)); + } +} + } // namespace Tegra diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 440505c9d..97dcccb92 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -6,7 +6,6 @@ #include <memory> #include <unordered_map> -#include <vector> #include "common/common_types.h" #include "core/hle/service/nvflinger/buffer_queue.h" #include "video_core/memory_manager.h" @@ -21,21 +20,34 @@ enum class RenderTargetFormat : u32 { NONE = 0x0, RGBA32_FLOAT = 0xC0, RGBA32_UINT = 0xC2, + RGBA16_UNORM = 0xC6, + RGBA16_UINT = 0xC9, RGBA16_FLOAT = 0xCA, RG32_FLOAT = 0xCB, + RG32_UINT = 0xCD, BGRA8_UNORM = 0xCF, RGB10_A2_UNORM = 0xD1, RGBA8_UNORM = 0xD5, RGBA8_SRGB = 0xD6, + RGBA8_SNORM = 0xD7, RG16_UNORM = 0xDA, RG16_SNORM = 0xDB, RG16_SINT = 0xDC, RG16_UINT = 0xDD, RG16_FLOAT = 0xDE, R11G11B10_FLOAT = 0xE0, + R32_UINT = 0xE4, R32_FLOAT = 0xE5, + B5G6R5_UNORM = 0xE8, + RG8_UNORM = 0xEA, + RG8_SNORM = 0xEB, + R16_UNORM = 0xEE, + R16_SNORM = 0xEF, + R16_SINT = 0xF0, + R16_UINT = 0xF1, R16_FLOAT = 0xF2, R8_UNORM = 0xF3, + R8_UINT = 0xF6, }; enum class DepthFormat : u32 { @@ -51,6 +63,9 @@ enum class DepthFormat : u32 { /// Returns the number of bytes per pixel of each rendertarget format. u32 RenderTargetBytesPerPixel(RenderTargetFormat format); +/// Returns the number of bytes per pixel of each depth format. +u32 DepthFormatBytesPerPixel(DepthFormat format); + class DebugContext; /** @@ -64,14 +79,7 @@ struct FramebufferConfig { /** * Returns the number of bytes per pixel. */ - static u32 BytesPerPixel(PixelFormat format) { - switch (format) { - case PixelFormat::ABGR8: - return 4; - } - - UNREACHABLE(); - } + static u32 BytesPerPixel(PixelFormat format); VAddr address; u32 offset; diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 3ca350243..afd86a83a 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -4,18 +4,23 @@ #include <memory> #include "core/frontend/emu_window.h" +#include "core/settings.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_rasterizer.h" namespace VideoCore { -RendererBase::RendererBase(EmuWindow& window) : render_window{window} {} +RendererBase::RendererBase(Core::Frontend::EmuWindow& window) : render_window{window} { + RefreshBaseSettings(); +} + RendererBase::~RendererBase() = default; -void RendererBase::UpdateCurrentFramebufferLayout() { - const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout(); +void RendererBase::RefreshBaseSettings() { + RefreshRasterizerSetting(); + UpdateCurrentFramebufferLayout(); - render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height); + renderer_settings.use_framelimiter = Settings::values.toggle_framelimit; } void RendererBase::RefreshRasterizerSetting() { @@ -24,4 +29,10 @@ void RendererBase::RefreshRasterizerSetting() { } } +void RendererBase::UpdateCurrentFramebufferLayout() { + const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout(); + + render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height); +} + } // namespace VideoCore diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 235de23a1..d9f16b8e6 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -4,23 +4,26 @@ #pragma once +#include <atomic> #include <memory> #include <boost/optional.hpp> -#include "common/assert.h" #include "common/common_types.h" #include "video_core/gpu.h" #include "video_core/rasterizer_interface.h" +namespace Core::Frontend { class EmuWindow; +} namespace VideoCore { +struct RendererSettings { + std::atomic_bool use_framelimiter{false}; +}; + class RendererBase : NonCopyable { public: - /// Used to reference a framebuffer - enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; - - explicit RendererBase(EmuWindow& window); + explicit RendererBase(Core::Frontend::EmuWindow& window); virtual ~RendererBase(); /// Swap buffers (render frame) @@ -32,9 +35,6 @@ public: /// Shutdown the renderer virtual void ShutDown() = 0; - /// Updates the framebuffer layout of the contained render window handle. - void UpdateCurrentFramebufferLayout(); - // Getter/setter functions: // ------------------------ @@ -54,13 +54,23 @@ public: return *rasterizer; } - void RefreshRasterizerSetting(); + /// Refreshes the settings common to all renderers + void RefreshBaseSettings(); protected: - EmuWindow& render_window; ///< Reference to the render window handle. + /// Refreshes settings specific to the rasterizer. + void RefreshRasterizerSetting(); + + Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. std::unique_ptr<RasterizerInterface> rasterizer; f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer int m_current_frame = 0; ///< Current frame, should be set by the renderer + + RendererSettings renderer_settings; + +private: + /// Updates the framebuffer layout of the contained render window handle. + void UpdateCurrentFramebufferLayout(); }; } // namespace VideoCore diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c2a931469..52a649e2f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -36,30 +36,21 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); -RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} { +RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) + : emu_window{window}, stream_buffer(GL_ARRAY_BUFFER, STREAM_BUFFER_SIZE) { // Create sampler objects for (size_t i = 0; i < texture_samplers.size(); ++i) { texture_samplers[i].Create(); state.texture_units[i].sampler = texture_samplers[i].sampler.handle; } - // Create SSBOs - for (size_t stage = 0; stage < ssbos.size(); ++stage) { - for (size_t buffer = 0; buffer < ssbos[stage].size(); ++buffer) { - ssbos[stage][buffer].Create(); - state.draw.const_buffers[stage][buffer].ssbo = ssbos[stage][buffer].handle; - } - } - GLint ext_num; glGetIntegerv(GL_NUM_EXTENSIONS, &ext_num); for (GLint i = 0; i < ext_num; i++) { const std::string_view extension{ reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i))}; - if (extension == "GL_ARB_buffer_storage") { - has_ARB_buffer_storage = true; - } else if (extension == "GL_ARB_direct_state_access") { + if (extension == "GL_ARB_direct_state_access") { has_ARB_direct_state_access = true; } else if (extension == "GL_ARB_separate_shader_objects") { has_ARB_separate_shader_objects = true; @@ -86,47 +77,31 @@ RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} { hw_vao.Create(); - stream_buffer = OGLStreamBuffer::MakeBuffer(has_ARB_buffer_storage, GL_ARRAY_BUFFER); - stream_buffer->Create(STREAM_BUFFER_SIZE, STREAM_BUFFER_SIZE / 2); - state.draw.vertex_buffer = stream_buffer->GetHandle(); + state.draw.vertex_buffer = stream_buffer.GetHandle(); shader_program_manager = std::make_unique<GLShader::ProgramManager>(); state.draw.shader_program = 0; state.draw.vertex_array = hw_vao.handle; state.Apply(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle()); - - for (unsigned index = 0; index < uniform_buffers.size(); ++index) { - auto& buffer = uniform_buffers[index]; - buffer.Create(); - glBindBuffer(GL_UNIFORM_BUFFER, buffer.handle); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::MaxwellUniformData), nullptr, - GL_STREAM_COPY); - glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer.handle); - } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle()); glEnable(GL_BLEND); + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); + LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); } -RasterizerOpenGL::~RasterizerOpenGL() { - if (stream_buffer != nullptr) { - state.draw.vertex_buffer = stream_buffer->GetHandle(); - state.Apply(); - stream_buffer->Release(); - } -} +RasterizerOpenGL::~RasterizerOpenGL() {} std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_VAO); const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; - const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager; state.draw.vertex_array = hw_vao.handle; - state.draw.vertex_buffer = stream_buffer->GetHandle(); + state.draw.vertex_buffer = stream_buffer.GetHandle(); state.Apply(); // Upload all guest vertex arrays sequentially to our buffer @@ -141,16 +116,15 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, ASSERT(end > start); u64 size = end - start + 1; - // Copy vertex array data - Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size); + GLintptr vertex_buffer_offset; + std::tie(array_ptr, buffer_offset, vertex_buffer_offset) = + UploadMemory(array_ptr, buffer_offset, start, size); // Bind the vertex array to the buffer at the current offset. - glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); + glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, + vertex_array.stride); ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); - - array_ptr += size; - buffer_offset += size; } // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. @@ -161,11 +135,16 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, // assume every shader uses them all. for (unsigned index = 0; index < 16; ++index) { auto& attrib = regs.vertex_attrib_format[index]; - LOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", + + // Ignore invalid attributes. + if (!attrib.IsValid()) + continue; + + auto& buffer = regs.vertex_array[attrib.buffer]; + LOG_TRACE(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), attrib.offset.Value(), attrib.IsNormalized()); - auto& buffer = regs.vertex_array[attrib.buffer]; ASSERT(buffer.IsEnabled()); glEnableVertexAttribArray(index); @@ -196,22 +175,12 @@ static GLShader::ProgramCode GetShaderProgramCode(Maxwell::ShaderProgram program return program_code; } -void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { - // Helper function for uploading uniform data - const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { - if (has_ARB_direct_state_access) { - glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size); - } else { - glBindBuffer(GL_COPY_WRITE_BUFFER, handle); - glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); - } - }; - +std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); // Next available bindpoints to use when uploading the const buffers and textures to the GLSL // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. - u32 current_constbuffer_bindpoint = uniform_buffers.size(); + u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; u32 current_texture_bindpoint = 0; for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { @@ -223,22 +192,21 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { continue; } + std::tie(buffer_ptr, buffer_offset) = + AlignBuffer(buffer_ptr, buffer_offset, static_cast<size_t>(uniform_buffer_alignment)); + const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 GLShader::MaxwellUniformData ubo{}; ubo.SetFromRegs(gpu.state.shader_stages[stage]); std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); - // Flush the buffer so that the GPU can see the data we just wrote. - glFlushMappedBufferRange(GL_ARRAY_BUFFER, buffer_offset, sizeof(ubo)); + // Bind the buffer + glBindBufferRange(GL_UNIFORM_BUFFER, stage, stream_buffer.GetHandle(), buffer_offset, + sizeof(ubo)); - // Upload uniform data as one UBO per stage - const GLintptr ubo_offset = buffer_offset; - copy_buffer(uniform_buffers[stage].handle, ubo_offset, - sizeof(GLShader::MaxwellUniformData)); - - buffer_ptr += sizeof(GLShader::MaxwellUniformData); - buffer_offset += sizeof(GLShader::MaxwellUniformData); + buffer_ptr += sizeof(ubo); + buffer_offset += sizeof(ubo); GLShader::ShaderSetup setup{GetShaderProgramCode(program)}; GLShader::ShaderEntries shader_resources; @@ -277,9 +245,9 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { static_cast<Maxwell::ShaderStage>(stage)); // Configure the const buffers for this shader stage. - current_constbuffer_bindpoint = - SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), gl_stage_program, - current_constbuffer_bindpoint, shader_resources.const_buffer_entries); + std::tie(buffer_ptr, buffer_offset, current_constbuffer_bindpoint) = SetupConstBuffers( + buffer_ptr, buffer_offset, static_cast<Maxwell::ShaderStage>(stage), gl_stage_program, + current_constbuffer_bindpoint, shader_resources.const_buffer_entries); // Configure the textures for this shader stage. current_texture_bindpoint = @@ -294,6 +262,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { } shader_program_manager->UseTrivialGeometryShader(); + + return {buffer_ptr, buffer_offset}; } size_t RasterizerOpenGL::CalculateVertexArraysSize() const { @@ -324,11 +294,14 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c bool using_depth_fb) { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; + if (regs.rt[0].format == Tegra::RenderTargetFormat::NONE) { + LOG_ERROR(HW_GPU, "RenderTargetFormat is not configured"); + using_color_fb = false; + } + // TODO(bunnei): Implement this const bool has_stencil = false; - const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; - const bool write_color_fb = state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; @@ -341,9 +314,10 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c Surface depth_surface; MathUtil::Rectangle<u32> surfaces_rect; std::tie(color_surface, depth_surface, surfaces_rect) = - res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect); + res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb); - MathUtil::Rectangle<u32> draw_rect{ + const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; + const MathUtil::Rectangle<u32> draw_rect{ static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left, surfaces_rect.left, surfaces_rect.right)), // Left static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top, @@ -423,6 +397,31 @@ void RasterizerOpenGL::Clear() { } } +std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, + size_t alignment) { + // Align the offset, not the mapped pointer + GLintptr offset_aligned = + static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment)); + return {buffer_ptr + (offset_aligned - buffer_offset), offset_aligned}; +} + +std::tuple<u8*, GLintptr, GLintptr> RasterizerOpenGL::UploadMemory(u8* buffer_ptr, + GLintptr buffer_offset, + Tegra::GPUVAddr gpu_addr, + size_t size, size_t alignment) { + std::tie(buffer_ptr, buffer_offset) = AlignBuffer(buffer_ptr, buffer_offset, alignment); + GLintptr uploaded_offset = buffer_offset; + + const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager; + const boost::optional<VAddr> cpu_addr{memory_manager->GpuToCpuAddress(gpu_addr)}; + Memory::ReadBlock(*cpu_addr, buffer_ptr, size); + + buffer_ptr += size; + buffer_offset += size; + + return {buffer_ptr, buffer_offset, uploaded_offset}; +} + void RasterizerOpenGL::DrawArrays() { if (accelerate_draw == AccelDraw::Disabled) return; @@ -447,7 +446,7 @@ void RasterizerOpenGL::DrawArrays() { const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count}; - state.draw.vertex_buffer = stream_buffer->GetHandle(); + state.draw.vertex_buffer = stream_buffer.GetHandle(); state.Apply(); size_t buffer_size = CalculateVertexArraysSize(); @@ -457,41 +456,31 @@ void RasterizerOpenGL::DrawArrays() { } // Uniform space for the 5 shader stages - buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + - sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; + buffer_size = + Common::AlignUp<size_t>(buffer_size, 4) + + (sizeof(GLShader::MaxwellUniformData) + uniform_buffer_alignment) * Maxwell::MaxShaderStage; + + // Add space for at least 18 constant buffers + buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment); u8* buffer_ptr; GLintptr buffer_offset; - std::tie(buffer_ptr, buffer_offset) = - stream_buffer->Map(static_cast<GLsizeiptr>(buffer_size), 4); + std::tie(buffer_ptr, buffer_offset, std::ignore) = + stream_buffer.Map(static_cast<GLsizeiptr>(buffer_size), 4); + u8* buffer_ptr_base = buffer_ptr; - u8* offseted_buffer; - std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); - - offseted_buffer = - reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); - buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); + std::tie(buffer_ptr, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); // If indexed mode, copy the index buffer GLintptr index_buffer_offset = 0; if (is_indexed) { - const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager; - const boost::optional<VAddr> index_data_addr{ - memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; - Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size); - - index_buffer_offset = buffer_offset; - offseted_buffer += index_buffer_size; - buffer_offset += index_buffer_size; + std::tie(buffer_ptr, buffer_offset, index_buffer_offset) = UploadMemory( + buffer_ptr, buffer_offset, regs.index_array.StartAddress(), index_buffer_size); } - offseted_buffer = - reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); - buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); - - SetupShaders(offseted_buffer, buffer_offset); + std::tie(buffer_ptr, buffer_offset) = SetupShaders(buffer_ptr, buffer_offset); - stream_buffer->Unmap(); + stream_buffer.Unmap(buffer_ptr - buffer_ptr_base); shader_program_manager->ApplyTo(state); state.Apply(); @@ -638,32 +627,22 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr } } -u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint program, - u32 current_bindpoint, - const std::vector<GLShader::ConstBufferEntry>& entries) { +std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers( + u8* buffer_ptr, GLintptr buffer_offset, Maxwell::ShaderStage stage, GLuint program, + u32 current_bindpoint, const std::vector<GLShader::ConstBufferEntry>& entries) { const auto& gpu = Core::System::GetInstance().GPU(); const auto& maxwell3d = gpu.Maxwell3D(); - // Reset all buffer draw state for this stage. - for (auto& buffer : state.draw.const_buffers[static_cast<size_t>(stage)]) { - buffer.bindpoint = 0; - buffer.enabled = false; - } - // Upload only the enabled buffers from the 16 constbuffers of each shader stage const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<size_t>(stage)]; for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { const auto& used_buffer = entries[bindpoint]; const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()]; - auto& buffer_draw_state = - state.draw.const_buffers[static_cast<size_t>(stage)][used_buffer.GetIndex()]; - - ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer"); - buffer_draw_state.enabled = true; - buffer_draw_state.bindpoint = current_bindpoint + bindpoint; - boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); + if (!buffer.enabled) { + continue; + } size_t size = 0; @@ -686,25 +665,26 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr size = Common::AlignUp(size, sizeof(GLvec4)); ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); - std::vector<u8> data(size); - Memory::ReadBlock(*addr, data.data(), data.size()); + GLintptr const_buffer_offset; + std::tie(buffer_ptr, buffer_offset, const_buffer_offset) = + UploadMemory(buffer_ptr, buffer_offset, buffer.address, size, + static_cast<size_t>(uniform_buffer_alignment)); - glBindBuffer(GL_UNIFORM_BUFFER, buffer_draw_state.ssbo); - glBufferData(GL_UNIFORM_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBufferRange(GL_UNIFORM_BUFFER, current_bindpoint + bindpoint, + stream_buffer.GetHandle(), const_buffer_offset, size); // Now configure the bindpoint of the buffer inside the shader const std::string buffer_name = used_buffer.GetName(); const GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, buffer_name.c_str()); if (index != GL_INVALID_INDEX) { - glUniformBlockBinding(program, index, buffer_draw_state.bindpoint); + glUniformBlockBinding(program, index, current_bindpoint + bindpoint); } } state.Apply(); - return current_bindpoint + static_cast<u32>(entries.size()); + return {buffer_ptr, buffer_offset, current_bindpoint + static_cast<u32>(entries.size())}; } u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program, u32 current_unit, @@ -804,9 +784,7 @@ void RasterizerOpenGL::SyncClipCoef() { void RasterizerOpenGL::SyncCullMode() { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; - // TODO(bunnei): Enable the below once more things work - until then, this may hide regressions - // state.cull.enabled = regs.cull.enabled != 0; - state.cull.enabled = false; + state.cull.enabled = regs.cull.enabled != 0; if (state.cull.enabled) { state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 6d6d85cc1..74307f626 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -7,6 +7,7 @@ #include <array> #include <cstddef> #include <memory> +#include <tuple> #include <utility> #include <vector> #include <glad/glad.h> @@ -21,12 +22,15 @@ #include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" -class EmuWindow; struct ScreenInfo; +namespace Core::Frontend { +class EmuWindow; +} + class RasterizerOpenGL : public VideoCore::RasterizerInterface { public: - explicit RasterizerOpenGL(EmuWindow& renderer); + explicit RasterizerOpenGL(Core::Frontend::EmuWindow& renderer); ~RasterizerOpenGL() override; void DrawArrays() override; @@ -97,9 +101,10 @@ private: * @param entries Vector describing the buffers that are actually used in the guest shader. * @returns The next available bindpoint for use in the next shader stage. */ - u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, GLuint program, - u32 current_bindpoint, - const std::vector<GLShader::ConstBufferEntry>& entries); + std::tuple<u8*, GLintptr, u32> SetupConstBuffers( + u8* buffer_ptr, GLintptr buffer_offset, Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, + GLuint program, u32 current_bindpoint, + const std::vector<GLShader::ConstBufferEntry>& entries); /* * Configures the current textures to use for the draw command. @@ -136,7 +141,6 @@ private: /// Syncs the blend state to match the guest state void SyncBlendState(); - bool has_ARB_buffer_storage = false; bool has_ARB_direct_state_access = false; bool has_ARB_separate_shader_objects = false; bool has_ARB_vertex_attrib_binding = false; @@ -145,29 +149,31 @@ private: RasterizerCacheOpenGL res_cache; - EmuWindow& emu_window; + Core::Frontend::EmuWindow& emu_window; std::unique_ptr<GLShader::ProgramManager> shader_program_manager; OGLVertexArray sw_vao; OGLVertexArray hw_vao; std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; - std::array<std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers>, - Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> - ssbos; static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; - std::unique_ptr<OGLStreamBuffer> stream_buffer; + OGLStreamBuffer stream_buffer; OGLBuffer uniform_buffer; OGLFramebuffer framebuffer; + GLint uniform_buffer_alignment; size_t CalculateVertexArraysSize() const; std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); - std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; + std::pair<u8*, GLintptr> SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); + + std::pair<u8*, GLintptr> AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, size_t alignment); - void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); + std::tuple<u8*, GLintptr, GLintptr> UploadMemory(u8* buffer_ptr, GLintptr buffer_offset, + Tegra::GPUVAddr gpu_addr, size_t size, + size_t alignment = 4); enum class AccelDraw { Disabled, Arrays, Indexed }; AccelDraw accelerate_draw = AccelDraw::Disabled; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index c8f0c4e28..5d58ebd4f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -46,6 +46,8 @@ struct FormatTuple { params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); params.unaligned_height = config.tic.Height(); params.size_in_bytes = params.SizeInBytes(); + params.cache_width = Common::AlignUp(params.width, 16); + params.cache_height = Common::AlignUp(params.height, 16); return params; } @@ -63,6 +65,8 @@ struct FormatTuple { params.height = config.height; params.unaligned_height = config.height; params.size_in_bytes = params.SizeInBytes(); + params.cache_width = Common::AlignUp(params.width, 16); + params.cache_height = Common::AlignUp(params.height, 16); return params; } @@ -82,17 +86,23 @@ struct FormatTuple { params.height = zeta_height; params.unaligned_height = zeta_height; params.size_in_bytes = params.SizeInBytes(); + params.cache_width = Common::AlignUp(params.width, 16); + params.cache_height = Common::AlignUp(params.height, 16); return params; } static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ - {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U + {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, false}, // A2B10G10R10 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8 + {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // R8UI {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F + {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RGBA16U + {GL_RGBA16UI, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RGBA16UI {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float, false}, // R11FG11FB10F {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI @@ -103,7 +113,10 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXT45 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 - {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, + {GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, + true}, // DXN2UNORM + {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_INT, ComponentType::SNorm, true}, // DXN2SNORM + {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // BC7U {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8 @@ -113,6 +126,9 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16UNORM + {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S + {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI + {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I {GL_RG16, GL_RG, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RG16 {GL_RG16F, GL_RG, GL_HALF_FLOAT, ComponentType::Float, false}, // RG16F {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI @@ -120,6 +136,10 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 + {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // RG8U + {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S + {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI + {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI // DepthStencil formats {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, @@ -174,69 +194,121 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { return {0, actual_height, width, 0}; } +/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN +static bool IsFormatBCn(PixelFormat format) { + switch (format) { + case PixelFormat::DXT1: + case PixelFormat::DXT23: + case PixelFormat::DXT45: + case PixelFormat::DXN1: + case PixelFormat::DXN2SNORM: + case PixelFormat::DXN2UNORM: + case PixelFormat::BC7U: + return true; + } + return false; +} + template <bool morton_to_gl, PixelFormat format> -void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr addr) { +void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, + Tegra::GPUVAddr addr) { constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); const auto& gpu = Core::System::GetInstance().GPU(); if (morton_to_gl) { - if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { - auto data = Tegra::Texture::UnswizzleTexture( - *gpu.memory_manager->GpuToCpuAddress(addr), - SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); - std::memcpy(gl_buffer, data.data(), data.size()); - } else { - auto data = Tegra::Texture::UnswizzleDepthTexture( - *gpu.memory_manager->GpuToCpuAddress(addr), - SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height); - std::memcpy(gl_buffer, data.data(), data.size()); - } + // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual + // pixel values. + const u32 tile_size{IsFormatBCn(format) ? 4U : 1U}; + const std::vector<u8> data = + Tegra::Texture::UnswizzleTexture(*gpu.memory_manager->GpuToCpuAddress(addr), tile_size, + bytes_per_pixel, stride, height, block_height); + const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; + gl_buffer.assign(data.begin(), data.begin() + size_to_copy); } else { // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should // check the configuration for this and perform more generic un/swizzle LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); VideoCore::MortonCopyPixels128( stride, height, bytes_per_pixel, gl_bytes_per_pixel, - Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(addr)), gl_buffer, + Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(addr)), gl_buffer.data(), morton_to_gl); } } -static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), +static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr), SurfaceParams::MaxPixelFormat> morton_to_gl_fns = { - MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, - MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::A1B5G5R5>, - MortonCopy<true, PixelFormat::R8>, MortonCopy<true, PixelFormat::RGBA16F>, - MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, - MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, - MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, - MortonCopy<true, PixelFormat::BC7U>, MortonCopy<true, PixelFormat::ASTC_2D_4X4>, - MortonCopy<true, PixelFormat::G8R8>, MortonCopy<true, PixelFormat::BGRA8>, - MortonCopy<true, PixelFormat::RGBA32F>, MortonCopy<true, PixelFormat::RG32F>, - MortonCopy<true, PixelFormat::R32F>, MortonCopy<true, PixelFormat::R16F>, - MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, - MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, - MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, - MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>, - MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>, - MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, + // clang-format off + MortonCopy<true, PixelFormat::ABGR8U>, + MortonCopy<true, PixelFormat::ABGR8S>, + MortonCopy<true, PixelFormat::B5G6R5>, + MortonCopy<true, PixelFormat::A2B10G10R10>, + MortonCopy<true, PixelFormat::A1B5G5R5>, + MortonCopy<true, PixelFormat::R8>, + MortonCopy<true, PixelFormat::R8UI>, + MortonCopy<true, PixelFormat::RGBA16F>, + MortonCopy<true, PixelFormat::RGBA16U>, + MortonCopy<true, PixelFormat::RGBA16UI>, + MortonCopy<true, PixelFormat::R11FG11FB10F>, + MortonCopy<true, PixelFormat::RGBA32UI>, + MortonCopy<true, PixelFormat::DXT1>, + MortonCopy<true, PixelFormat::DXT23>, + MortonCopy<true, PixelFormat::DXT45>, + MortonCopy<true, PixelFormat::DXN1>, + MortonCopy<true, PixelFormat::DXN2UNORM>, + MortonCopy<true, PixelFormat::DXN2SNORM>, + MortonCopy<true, PixelFormat::BC7U>, + MortonCopy<true, PixelFormat::ASTC_2D_4X4>, + MortonCopy<true, PixelFormat::G8R8>, + MortonCopy<true, PixelFormat::BGRA8>, + MortonCopy<true, PixelFormat::RGBA32F>, + MortonCopy<true, PixelFormat::RG32F>, + MortonCopy<true, PixelFormat::R32F>, + MortonCopy<true, PixelFormat::R16F>, + MortonCopy<true, PixelFormat::R16UNORM>, + MortonCopy<true, PixelFormat::R16S>, + MortonCopy<true, PixelFormat::R16UI>, + MortonCopy<true, PixelFormat::R16I>, + MortonCopy<true, PixelFormat::RG16>, + MortonCopy<true, PixelFormat::RG16F>, + MortonCopy<true, PixelFormat::RG16UI>, + MortonCopy<true, PixelFormat::RG16I>, + MortonCopy<true, PixelFormat::RG16S>, + MortonCopy<true, PixelFormat::RGB32F>, + MortonCopy<true, PixelFormat::SRGBA8>, + MortonCopy<true, PixelFormat::RG8U>, + MortonCopy<true, PixelFormat::RG8S>, + MortonCopy<true, PixelFormat::RG32UI>, + MortonCopy<true, PixelFormat::R32UI>, + MortonCopy<true, PixelFormat::Z24S8>, + MortonCopy<true, PixelFormat::S8Z24>, + MortonCopy<true, PixelFormat::Z32F>, + MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>, + // clang-format on }; -static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), +static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr), SurfaceParams::MaxPixelFormat> gl_to_morton_fns = { - MortonCopy<false, PixelFormat::ABGR8>, + // clang-format off + MortonCopy<false, PixelFormat::ABGR8U>, + MortonCopy<false, PixelFormat::ABGR8S>, MortonCopy<false, PixelFormat::B5G6R5>, MortonCopy<false, PixelFormat::A2B10G10R10>, MortonCopy<false, PixelFormat::A1B5G5R5>, MortonCopy<false, PixelFormat::R8>, + MortonCopy<false, PixelFormat::R8UI>, MortonCopy<false, PixelFormat::RGBA16F>, + MortonCopy<false, PixelFormat::RGBA16U>, + MortonCopy<false, PixelFormat::RGBA16UI>, MortonCopy<false, PixelFormat::R11FG11FB10F>, MortonCopy<false, PixelFormat::RGBA32UI>, - // TODO(Subv): Swizzling DXT1/DXT23/DXT45/DXN1/BC7U/ASTC_2D_4X4 formats is not supported + // TODO(Subv): Swizzling DXT1/DXT23/DXT45/DXN1/DXN2/BC7U/ASTC_2D_4X4 formats is not + // supported + nullptr, + nullptr, nullptr, nullptr, nullptr, @@ -250,6 +322,9 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), MortonCopy<false, PixelFormat::R32F>, MortonCopy<false, PixelFormat::R16F>, MortonCopy<false, PixelFormat::R16UNORM>, + MortonCopy<false, PixelFormat::R16S>, + MortonCopy<false, PixelFormat::R16UI>, + MortonCopy<false, PixelFormat::R16I>, MortonCopy<false, PixelFormat::RG16>, MortonCopy<false, PixelFormat::RG16F>, MortonCopy<false, PixelFormat::RG16UI>, @@ -257,11 +332,16 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), MortonCopy<false, PixelFormat::RG16S>, MortonCopy<false, PixelFormat::RGB32F>, MortonCopy<false, PixelFormat::SRGBA8>, + MortonCopy<false, PixelFormat::RG8U>, + MortonCopy<false, PixelFormat::RG8S>, + MortonCopy<false, PixelFormat::RG32UI>, + MortonCopy<false, PixelFormat::R32UI>, MortonCopy<false, PixelFormat::Z24S8>, MortonCopy<false, PixelFormat::S8Z24>, MortonCopy<false, PixelFormat::Z32F>, MortonCopy<false, PixelFormat::Z16>, MortonCopy<false, PixelFormat::Z32FS8>, + // clang-format on }; // Allocate an uninitialized texture of appropriate size and format for the surface @@ -441,22 +521,24 @@ MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64 void CachedSurface::LoadGLBuffer() { ASSERT(params.type != SurfaceType::Fill); - u8* const texture_src_data = Memory::GetPointer(params.GetCpuAddr()); + const u8* const texture_src_data = Memory::GetPointer(params.GetCpuAddr()); ASSERT(texture_src_data); - gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); + const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format); + const u32 copy_size = params.width * params.height * bytes_per_pixel; MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); - if (!params.is_tiled) { - const u32 bytes_per_pixel{params.GetFormatBpp() >> 3}; + if (params.is_tiled) { + gl_buffer.resize(copy_size); - std::memcpy(gl_buffer.data(), texture_src_data, - bytes_per_pixel * params.width * params.height); - } else { morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( - params.width, params.block_height, params.height, gl_buffer.data(), params.addr); + params.width, params.block_height, params.height, gl_buffer, params.addr); + } else { + const u8* const texture_src_data_end = texture_src_data + copy_size; + + gl_buffer.assign(texture_src_data, texture_src_data_end); } ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer, params.pixel_format, params.width, params.height); @@ -479,7 +561,7 @@ void CachedSurface::FlushGLBuffer() { std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes); } else { gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( - params.width, params.block_height, params.height, gl_buffer.data(), params.addr); + params.width, params.block_height, params.height, gl_buffer, params.addr); } } @@ -594,8 +676,8 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu return GetSurface(SurfaceParams::CreateForTexture(config)); } -SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( - bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { +SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool using_color_fb, + bool using_depth_fb) { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; // TODO(bunnei): This is hard corded to use just the first render buffer @@ -680,12 +762,12 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) { // If use_accurate_framebuffers is enabled, always load from memory FlushSurface(surface); UnregisterSurface(surface); - } else if (surface->GetSurfaceParams() != params) { - // If surface parameters changed, recreate the surface from the old one - return RecreateSurface(surface, params); - } else { + } else if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { // Use the cached surface as-is return surface; + } else { + // If surface parameters changed, recreate the surface from the old one + return RecreateSurface(surface, params); } } @@ -751,10 +833,12 @@ void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr /*addr*/, size_t /*size* } void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, size_t size) { - for (const auto& pair : surface_cache) { - const auto& surface{pair.second}; + for (auto iter = surface_cache.cbegin(); iter != surface_cache.cend();) { + const auto& surface{iter->second}; const auto& params{surface->GetSurfaceParams()}; + ++iter; + if (params.IsOverlappingRegion(addr, size)) { UnregisterSurface(surface); } diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 4e1e18d9c..36a41522b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -9,6 +9,7 @@ #include <memory> #include <vector> #include <boost/icl/interval_map.hpp> + #include "common/common_types.h" #include "common/math_util.h" #include "video_core/engines/maxwell_3d.h" @@ -22,43 +23,56 @@ using PageMap = boost::icl::interval_map<u64, int>; struct SurfaceParams { enum class PixelFormat { - ABGR8 = 0, - B5G6R5 = 1, - A2B10G10R10 = 2, - A1B5G5R5 = 3, - R8 = 4, - RGBA16F = 5, - R11FG11FB10F = 6, - RGBA32UI = 7, - DXT1 = 8, - DXT23 = 9, - DXT45 = 10, - DXN1 = 11, // This is also known as BC4 - BC7U = 12, - ASTC_2D_4X4 = 13, - G8R8 = 14, - BGRA8 = 15, - RGBA32F = 16, - RG32F = 17, - R32F = 18, - R16F = 19, - R16UNORM = 20, - RG16 = 21, - RG16F = 22, - RG16UI = 23, - RG16I = 24, - RG16S = 25, - RGB32F = 26, - SRGBA8 = 27, + ABGR8U = 0, + ABGR8S = 1, + B5G6R5 = 2, + A2B10G10R10 = 3, + A1B5G5R5 = 4, + R8 = 5, + R8UI = 6, + RGBA16F = 7, + RGBA16U = 8, + RGBA16UI = 9, + R11FG11FB10F = 10, + RGBA32UI = 11, + DXT1 = 12, + DXT23 = 13, + DXT45 = 14, + DXN1 = 15, // This is also known as BC4 + DXN2UNORM = 16, + DXN2SNORM = 17, + BC7U = 18, + ASTC_2D_4X4 = 19, + G8R8 = 20, + BGRA8 = 21, + RGBA32F = 22, + RG32F = 23, + R32F = 24, + R16F = 25, + R16UNORM = 26, + R16S = 27, + R16UI = 28, + R16I = 29, + RG16 = 30, + RG16F = 31, + RG16UI = 32, + RG16I = 33, + RG16S = 34, + RGB32F = 35, + SRGBA8 = 36, + RG8U = 37, + RG8S = 38, + RG32UI = 39, + R32UI = 40, MaxColorFormat, // DepthStencil formats - Z24S8 = 28, - S8Z24 = 29, - Z32F = 30, - Z16 = 31, - Z32FS8 = 32, + Z24S8 = 41, + S8Z24 = 42, + Z32F = 43, + Z16 = 44, + Z32FS8 = 45, MaxDepthStencilFormat, @@ -96,18 +110,24 @@ struct SurfaceParams { return 0; constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ - 1, // ABGR8 + 1, // ABGR8U + 1, // ABGR8S 1, // B5G6R5 1, // A2B10G10R10 1, // A1B5G5R5 1, // R8 + 1, // R8UI 1, // RGBA16F + 1, // RGBA16U + 1, // RGBA16UI 1, // R11FG11FB10F 1, // RGBA32UI 4, // DXT1 4, // DXT23 4, // DXT45 4, // DXN1 + 4, // DXN2UNORM + 4, // DXN2SNORM 4, // BC7U 4, // ASTC_2D_4X4 1, // G8R8 @@ -117,6 +137,9 @@ struct SurfaceParams { 1, // R32F 1, // R16F 1, // R16UNORM + 1, // R16S + 1, // R16UI + 1, // R16I 1, // RG16 1, // RG16F 1, // RG16UI @@ -124,6 +147,10 @@ struct SurfaceParams { 1, // RG16S 1, // RGB32F 1, // SRGBA8 + 1, // RG8U + 1, // RG8S + 1, // RG32UI + 1, // R32UI 1, // Z24S8 1, // S8Z24 1, // Z32F @@ -140,18 +167,24 @@ struct SurfaceParams { return 0; constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ - 32, // ABGR8 + 32, // ABGR8U + 32, // ABGR8S 16, // B5G6R5 32, // A2B10G10R10 16, // A1B5G5R5 8, // R8 + 8, // R8UI 64, // RGBA16F + 64, // RGBA16U + 64, // RGBA16UI 32, // R11FG11FB10F 128, // RGBA32UI 64, // DXT1 128, // DXT23 128, // DXT45 64, // DXN1 + 128, // DXN2UNORM + 128, // DXN2SNORM 128, // BC7U 32, // ASTC_2D_4X4 16, // G8R8 @@ -161,6 +194,9 @@ struct SurfaceParams { 32, // R32F 16, // R16F 16, // R16UNORM + 16, // R16S + 16, // R16UI + 16, // R16I 32, // RG16 32, // RG16F 32, // RG16UI @@ -168,6 +204,10 @@ struct SurfaceParams { 32, // RG16S 96, // RGB32F 32, // SRGBA8 + 16, // RG8U + 16, // RG8S + 64, // RG32UI + 32, // R32UI 32, // Z24S8 32, // S8Z24 32, // Z32F @@ -203,26 +243,37 @@ struct SurfaceParams { static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { switch (format) { + // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the + // gamma. case Tegra::RenderTargetFormat::RGBA8_SRGB: - return PixelFormat::SRGBA8; case Tegra::RenderTargetFormat::RGBA8_UNORM: - return PixelFormat::ABGR8; + return PixelFormat::ABGR8U; + case Tegra::RenderTargetFormat::RGBA8_SNORM: + return PixelFormat::ABGR8S; case Tegra::RenderTargetFormat::BGRA8_UNORM: return PixelFormat::BGRA8; case Tegra::RenderTargetFormat::RGB10_A2_UNORM: return PixelFormat::A2B10G10R10; case Tegra::RenderTargetFormat::RGBA16_FLOAT: return PixelFormat::RGBA16F; + case Tegra::RenderTargetFormat::RGBA16_UNORM: + return PixelFormat::RGBA16U; + case Tegra::RenderTargetFormat::RGBA16_UINT: + return PixelFormat::RGBA16UI; case Tegra::RenderTargetFormat::RGBA32_FLOAT: return PixelFormat::RGBA32F; case Tegra::RenderTargetFormat::RG32_FLOAT: return PixelFormat::RG32F; case Tegra::RenderTargetFormat::R11G11B10_FLOAT: return PixelFormat::R11FG11FB10F; + case Tegra::RenderTargetFormat::B5G6R5_UNORM: + return PixelFormat::B5G6R5; case Tegra::RenderTargetFormat::RGBA32_UINT: return PixelFormat::RGBA32UI; case Tegra::RenderTargetFormat::R8_UNORM: return PixelFormat::R8; + case Tegra::RenderTargetFormat::R8_UINT: + return PixelFormat::R8UI; case Tegra::RenderTargetFormat::RG16_FLOAT: return PixelFormat::RG16F; case Tegra::RenderTargetFormat::RG16_UINT: @@ -233,10 +284,26 @@ struct SurfaceParams { return PixelFormat::RG16; case Tegra::RenderTargetFormat::RG16_SNORM: return PixelFormat::RG16S; + case Tegra::RenderTargetFormat::RG8_UNORM: + return PixelFormat::RG8U; + case Tegra::RenderTargetFormat::RG8_SNORM: + return PixelFormat::RG8S; case Tegra::RenderTargetFormat::R16_FLOAT: return PixelFormat::R16F; + case Tegra::RenderTargetFormat::R16_UNORM: + return PixelFormat::R16UNORM; + case Tegra::RenderTargetFormat::R16_SNORM: + return PixelFormat::R16S; + case Tegra::RenderTargetFormat::R16_UINT: + return PixelFormat::R16UI; + case Tegra::RenderTargetFormat::R16_SINT: + return PixelFormat::R16I; case Tegra::RenderTargetFormat::R32_FLOAT: return PixelFormat::R32F; + case Tegra::RenderTargetFormat::R32_UINT: + return PixelFormat::R32UI; + case Tegra::RenderTargetFormat::RG32_UINT: + return PixelFormat::RG32UI; default: LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); UNREACHABLE(); @@ -248,7 +315,15 @@ struct SurfaceParams { // TODO(Subv): Properly implement this switch (format) { case Tegra::Texture::TextureFormat::A8R8G8B8: - return PixelFormat::ABGR8; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::ABGR8U; + case Tegra::Texture::ComponentType::SNORM: + return PixelFormat::ABGR8S; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::B5G6R5: return PixelFormat::B5G6R5; case Tegra::Texture::TextureFormat::A2B10G10R10: @@ -256,7 +331,15 @@ struct SurfaceParams { case Tegra::Texture::TextureFormat::A1B5G5R5: return PixelFormat::A1B5G5R5; case Tegra::Texture::TextureFormat::R8: - return PixelFormat::R8; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::R8; + case Tegra::Texture::ComponentType::UINT: + return PixelFormat::R8UI; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::G8R8: return PixelFormat::G8R8; case Tegra::Texture::TextureFormat::R16_G16_B16_A16: @@ -274,7 +357,15 @@ struct SurfaceParams { static_cast<u32>(component_type)); UNREACHABLE(); case Tegra::Texture::TextureFormat::R32_G32: - return PixelFormat::RG32F; + switch (component_type) { + case Tegra::Texture::ComponentType::FLOAT: + return PixelFormat::RG32F; + case Tegra::Texture::ComponentType::UINT: + return PixelFormat::RG32UI; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::R32_G32_B32: return PixelFormat::RGB32F; case Tegra::Texture::TextureFormat::R16: @@ -283,12 +374,26 @@ struct SurfaceParams { return PixelFormat::R16F; case Tegra::Texture::ComponentType::UNORM: return PixelFormat::R16UNORM; + case Tegra::Texture::ComponentType::SNORM: + return PixelFormat::R16S; + case Tegra::Texture::ComponentType::UINT: + return PixelFormat::R16UI; + case Tegra::Texture::ComponentType::SINT: + return PixelFormat::R16I; } LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type)); UNREACHABLE(); case Tegra::Texture::TextureFormat::R32: - return PixelFormat::R32F; + switch (component_type) { + case Tegra::Texture::ComponentType::FLOAT: + return PixelFormat::R32F; + case Tegra::Texture::ComponentType::UINT: + return PixelFormat::R32UI; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::ZF32: return PixelFormat::Z32F; case Tegra::Texture::TextureFormat::Z24S8: @@ -301,6 +406,16 @@ struct SurfaceParams { return PixelFormat::DXT45; case Tegra::Texture::TextureFormat::DXN1: return PixelFormat::DXN1; + case Tegra::Texture::TextureFormat::DXN2: + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::DXN2UNORM; + case Tegra::Texture::ComponentType::SNORM: + return PixelFormat::DXN2SNORM; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::BC7U: return PixelFormat::BC7U; case Tegra::Texture::TextureFormat::ASTC_2D_4X4: @@ -328,89 +443,6 @@ struct SurfaceParams { } } - static Tegra::Texture::TextureFormat TextureFormatFromPixelFormat(PixelFormat format) { - // TODO(Subv): Properly implement this - switch (format) { - case PixelFormat::ABGR8: - case PixelFormat::SRGBA8: - return Tegra::Texture::TextureFormat::A8R8G8B8; - case PixelFormat::B5G6R5: - return Tegra::Texture::TextureFormat::B5G6R5; - case PixelFormat::A2B10G10R10: - return Tegra::Texture::TextureFormat::A2B10G10R10; - case PixelFormat::A1B5G5R5: - return Tegra::Texture::TextureFormat::A1B5G5R5; - case PixelFormat::R8: - return Tegra::Texture::TextureFormat::R8; - case PixelFormat::G8R8: - return Tegra::Texture::TextureFormat::G8R8; - case PixelFormat::RGBA16F: - return Tegra::Texture::TextureFormat::R16_G16_B16_A16; - case PixelFormat::R11FG11FB10F: - return Tegra::Texture::TextureFormat::BF10GF11RF11; - case PixelFormat::RGBA32UI: - return Tegra::Texture::TextureFormat::R32_G32_B32_A32; - case PixelFormat::DXT1: - return Tegra::Texture::TextureFormat::DXT1; - case PixelFormat::DXT23: - return Tegra::Texture::TextureFormat::DXT23; - case PixelFormat::DXT45: - return Tegra::Texture::TextureFormat::DXT45; - case PixelFormat::DXN1: - return Tegra::Texture::TextureFormat::DXN1; - case PixelFormat::BC7U: - return Tegra::Texture::TextureFormat::BC7U; - case PixelFormat::ASTC_2D_4X4: - return Tegra::Texture::TextureFormat::ASTC_2D_4X4; - case PixelFormat::BGRA8: - // TODO(bunnei): This is fine for unswizzling (since we just need the right component - // sizes), but could be a bug if we used this function in different ways. - return Tegra::Texture::TextureFormat::A8R8G8B8; - case PixelFormat::RGBA32F: - return Tegra::Texture::TextureFormat::R32_G32_B32_A32; - case PixelFormat::RGB32F: - return Tegra::Texture::TextureFormat::R32_G32_B32; - case PixelFormat::RG32F: - return Tegra::Texture::TextureFormat::R32_G32; - case PixelFormat::R32F: - return Tegra::Texture::TextureFormat::R32; - case PixelFormat::R16F: - case PixelFormat::R16UNORM: - return Tegra::Texture::TextureFormat::R16; - case PixelFormat::Z32F: - return Tegra::Texture::TextureFormat::ZF32; - case PixelFormat::Z24S8: - return Tegra::Texture::TextureFormat::Z24S8; - case PixelFormat::RG16F: - case PixelFormat::RG16: - case PixelFormat::RG16UI: - case PixelFormat::RG16I: - case PixelFormat::RG16S: - return Tegra::Texture::TextureFormat::R16_G16; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); - UNREACHABLE(); - } - } - - static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) { - switch (format) { - case PixelFormat::S8Z24: - return Tegra::DepthFormat::S8_Z24_UNORM; - case PixelFormat::Z24S8: - return Tegra::DepthFormat::Z24_S8_UNORM; - case PixelFormat::Z32F: - return Tegra::DepthFormat::Z32_FLOAT; - case PixelFormat::Z16: - return Tegra::DepthFormat::Z16_UNORM; - case PixelFormat::Z32FS8: - return Tegra::DepthFormat::Z32_S8_X24_FLOAT; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); - UNREACHABLE(); - } - } - static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { // TODO(Subv): Implement more component types switch (type) { @@ -439,8 +471,15 @@ struct SurfaceParams { case Tegra::RenderTargetFormat::RGB10_A2_UNORM: case Tegra::RenderTargetFormat::R8_UNORM: case Tegra::RenderTargetFormat::RG16_UNORM: + case Tegra::RenderTargetFormat::R16_UNORM: + case Tegra::RenderTargetFormat::B5G6R5_UNORM: + case Tegra::RenderTargetFormat::RG8_UNORM: + case Tegra::RenderTargetFormat::RGBA16_UNORM: return ComponentType::UNorm; + case Tegra::RenderTargetFormat::RGBA8_SNORM: case Tegra::RenderTargetFormat::RG16_SNORM: + case Tegra::RenderTargetFormat::R16_SNORM: + case Tegra::RenderTargetFormat::RG8_SNORM: return ComponentType::SNorm; case Tegra::RenderTargetFormat::RGBA16_FLOAT: case Tegra::RenderTargetFormat::R11G11B10_FLOAT: @@ -451,9 +490,15 @@ struct SurfaceParams { case Tegra::RenderTargetFormat::R32_FLOAT: return ComponentType::Float; case Tegra::RenderTargetFormat::RGBA32_UINT: + case Tegra::RenderTargetFormat::RGBA16_UINT: case Tegra::RenderTargetFormat::RG16_UINT: + case Tegra::RenderTargetFormat::R8_UINT: + case Tegra::RenderTargetFormat::R16_UINT: + case Tegra::RenderTargetFormat::RG32_UINT: + case Tegra::RenderTargetFormat::R32_UINT: return ComponentType::UInt; case Tegra::RenderTargetFormat::RG16_SINT: + case Tegra::RenderTargetFormat::R16_SINT: return ComponentType::SInt; default: LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); @@ -464,7 +509,7 @@ struct SurfaceParams { static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { switch (format) { case Tegra::FramebufferConfig::PixelFormat::ABGR8: - return PixelFormat::ABGR8; + return PixelFormat::ABGR8U; default: LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); UNREACHABLE(); @@ -546,6 +591,12 @@ struct SurfaceParams { return !operator==(other); } + /// Checks if surfaces are compatible for caching + bool IsCompatibleSurface(const SurfaceParams& other) const { + return std::tie(pixel_format, type, cache_width, cache_height) == + std::tie(other.pixel_format, other.type, other.cache_width, other.cache_height); + } + Tegra::GPUVAddr addr; bool is_tiled; u32 block_height; @@ -556,6 +607,10 @@ struct SurfaceParams { u32 height; u32 unaligned_height; size_t size_in_bytes; + + // Parameters used for caching only + u32 cache_width; + u32 cache_height; }; class CachedSurface final { @@ -600,8 +655,7 @@ public: Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); /// Get the color and depth surfaces based on the framebuffer configuration - SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, - const MathUtil::Rectangle<s32>& viewport); + SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb); /// Flushes the surface to Switch memory void FlushSurface(const Surface& surface); diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e3217db81..6834d7085 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -141,6 +141,15 @@ private: ExitMethod jmp = Scan(target, end, labels); return exit_method = ParallelExit(no_jmp, jmp); } + case OpCode::Id::SSY: { + // The SSY instruction uses a similar encoding as the BRA instruction. + ASSERT_MSG(instr.bra.constant_buffer == 0, + "Constant buffer SSY is not supported"); + u32 target = offset + instr.bra.GetBranchTarget(); + labels.insert(target); + // Continue scanning for an exit method. + break; + } } } } @@ -347,9 +356,14 @@ public: * @param reg The register to use as the source value. */ void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { - std::string dest = GetOutputAttribute(attribute) + GetSwizzle(elem); + std::string dest = GetOutputAttribute(attribute); std::string src = GetRegisterAsFloat(reg); - shader.AddLine(dest + " = " + src + ';'); + + if (!dest.empty()) { + // Can happen with unknown/unimplemented output attributes, in which case we ignore the + // instruction for now. + shader.AddLine(dest + GetSwizzle(elem) + " = " + src + ';'); + } } /// Generates code representing a uniform (C buffer) register, interpreted as the input type. @@ -362,6 +376,8 @@ public: return value; } else if (type == GLSLRegister::Type::Integer) { return "floatBitsToInt(" + value + ')'; + } else if (type == GLSLRegister::Type::UnsignedInteger) { + return "floatBitsToUint(" + value + ')'; } else { UNREACHABLE(); } @@ -507,6 +523,8 @@ private: /// Build the GLSL register list. void BuildRegisterList() { + regs.reserve(Register::NumRegisters); + for (size_t index = 0; index < Register::NumRegisters; ++index) { regs.emplace_back(index, suffix); } @@ -526,14 +544,17 @@ private: default: const u32 index{static_cast<u32>(attribute) - static_cast<u32>(Attribute::Index::Attribute_0)}; - if (attribute >= Attribute::Index::Attribute_0) { + if (attribute >= Attribute::Index::Attribute_0 && + attribute <= Attribute::Index::Attribute_31) { declr_input_attribute.insert(attribute); return "input_attribute_" + std::to_string(index); } - LOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", index); + LOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", static_cast<u32>(attribute)); UNREACHABLE(); } + + return "vec4(0, 0, 0, 0)"; } /// Generates code representing an output attribute register. @@ -551,6 +572,7 @@ private: LOG_CRITICAL(HW_GPU, "Unhandled output attribute: {}", index); UNREACHABLE(); + return {}; } } @@ -602,12 +624,12 @@ private: /// Generates code representing a 19-bit immediate value static std::string GetImmediate19(const Instruction& instr) { - return std::to_string(instr.alu.GetImm20_19()); + return fmt::format("uintBitsToFloat({})", instr.alu.GetImm20_19()); } /// Generates code representing a 32-bit immediate value static std::string GetImmediate32(const Instruction& instr) { - return std::to_string(instr.alu.GetImm20_32()); + return fmt::format("uintBitsToFloat({})", instr.alu.GetImm20_32()); } /// Generates code representing a texture sampler. @@ -650,16 +672,17 @@ private: * @param instr Instruction to generate the if condition for. * @returns string containing the predicate condition. */ - std::string GetPredicateCondition(u64 index, bool negate) const { + std::string GetPredicateCondition(u64 index, bool negate) { using Tegra::Shader::Pred; std::string variable; // Index 7 is used as an 'Always True' condition. - if (index == static_cast<u64>(Pred::UnusedIndex)) + if (index == static_cast<u64>(Pred::UnusedIndex)) { variable = "true"; - else + } else { variable = 'p' + std::to_string(index) + '_' + suffix; - + declr_predicates.insert(variable); + } if (negate) { return "!(" + variable + ')'; } @@ -818,7 +841,11 @@ private: ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, "NeverExecute predicate not implemented"); - if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { + // Some instructions (like SSY) don't have a predicate field, they are always + // unconditionally executed. + bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->GetId()); + + if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { shader.AddLine("if (" + GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) + ')'); @@ -1605,6 +1632,99 @@ private: } break; } + case OpCode::Type::Xmad: { + ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented"); + ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented"); + + std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)}; + std::string op_b; + std::string op_c; + + // TODO(bunnei): Needs to be fixed once op_a or op_b is signed + ASSERT_MSG(instr.xmad.sign_a == instr.xmad.sign_b, "Unimplemented"); + const bool is_signed{instr.xmad.sign_a == 1}; + + bool is_merge{}; + switch (opcode->GetId()) { + case OpCode::Id::XMAD_CR: { + is_merge = instr.xmad.merge_56; + op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, + instr.xmad.sign_b ? GLSLRegister::Type::Integer + : GLSLRegister::Type::UnsignedInteger); + op_c += regs.GetRegisterAsInteger(instr.gpr39, 0, is_signed); + break; + } + case OpCode::Id::XMAD_RR: { + is_merge = instr.xmad.merge_37; + op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.xmad.sign_b); + op_c += regs.GetRegisterAsInteger(instr.gpr39, 0, is_signed); + break; + } + case OpCode::Id::XMAD_RC: { + op_b += regs.GetRegisterAsInteger(instr.gpr39, 0, instr.xmad.sign_b); + op_c += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, + is_signed ? GLSLRegister::Type::Integer + : GLSLRegister::Type::UnsignedInteger); + break; + } + case OpCode::Id::XMAD_IMM: { + is_merge = instr.xmad.merge_37; + op_b += std::to_string(instr.xmad.imm20_16); + op_c += regs.GetRegisterAsInteger(instr.gpr39, 0, is_signed); + break; + } + default: { + LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->GetName()); + UNREACHABLE(); + } + } + + // TODO(bunnei): Ensure this is right with signed operands + if (instr.xmad.high_a) { + op_a = "((" + op_a + ") >> 16)"; + } else { + op_a = "((" + op_a + ") & 0xFFFF)"; + } + + std::string src2 = '(' + op_b + ')'; // Preserve original source 2 + if (instr.xmad.high_b) { + op_b = '(' + src2 + " >> 16)"; + } else { + op_b = '(' + src2 + " & 0xFFFF)"; + } + + std::string product = '(' + op_a + " * " + op_b + ')'; + if (instr.xmad.product_shift_left) { + product = '(' + product + " << 16)"; + } + + switch (instr.xmad.mode) { + case Tegra::Shader::XmadMode::None: + break; + case Tegra::Shader::XmadMode::CLo: + op_c = "((" + op_c + ") & 0xFFFF)"; + break; + case Tegra::Shader::XmadMode::CHi: + op_c = "((" + op_c + ") >> 16)"; + break; + case Tegra::Shader::XmadMode::CBcc: + op_c = "((" + op_c + ") + (" + src2 + "<< 16))"; + break; + default: { + LOG_CRITICAL(HW_GPU, "Unhandled XMAD mode: {}", + static_cast<u32>(instr.xmad.mode.Value())); + UNREACHABLE(); + } + } + + std::string sum{'(' + product + " + " + op_c + ')'}; + if (is_merge) { + sum = "((" + sum + " & 0xFFFF) | (" + src2 + "<< 16))"; + } + + regs.SetRegisterToInteger(instr.gpr0, is_signed, 0, sum, 1, 1); + break; + } default: { switch (opcode->GetId()) { case OpCode::Id::EXIT: { @@ -1642,7 +1762,15 @@ private: } case OpCode::Id::KIL: { ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); + + // Enclose "discard" in a conditional, so that GLSL compilation does not complain + // about unexecuted instructions that may follow this. + shader.AddLine("if (true) {"); + ++shader.scope; shader.AddLine("discard;"); + --shader.scope; + shader.AddLine("}"); + break; } case OpCode::Id::BRA: { @@ -1658,16 +1786,25 @@ private: break; } case OpCode::Id::SSY: { - // The SSY opcode tells the GPU where to re-converge divergent execution paths, we - // can ignore this when generating GLSL code. + // The SSY opcode tells the GPU where to re-converge divergent execution paths, it + // sets the target of the jump that the SYNC instruction will make. The SSY opcode + // has a similar structure to the BRA opcode. + ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); + + u32 target = offset + instr.bra.GetBranchTarget(); + shader.AddLine("ssy_target = " + std::to_string(target) + "u;"); break; } - case OpCode::Id::SYNC: + case OpCode::Id::SYNC: { + // The SYNC opcode jumps to the address previously set by the SSY opcode ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); + shader.AddLine("{ jmp_to = ssy_target; break; }"); + break; + } case OpCode::Id::DEPBAR: { - // TODO(Subv): Find out if we actually have to care about these instructions or if + // TODO(Subv): Find out if we actually have to care about this instruction or if // the GLSL compiler takes care of that for us. - LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed"); + LOG_WARNING(HW_GPU, "DEPBAR instruction is stubbed"); break; } default: { @@ -1681,7 +1818,7 @@ private: } // Close the predicate condition scope. - if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { + if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { --shader.scope; shader.AddLine('}'); } @@ -1732,6 +1869,7 @@ private: } else { labels.insert(subroutine.begin); shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); + shader.AddLine("uint ssy_target = 0u;"); shader.AddLine("while (true) {"); ++shader.scope; @@ -1747,7 +1885,7 @@ private: u32 compile_end = CompileRange(label, next_label); if (compile_end > next_label && compile_end != PROGRAM_END) { // This happens only when there is a label inside a IF/LOOP block - shader.AddLine("{ jmp_to = " + std::to_string(compile_end) + "u; break; }"); + shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); labels.emplace(compile_end); } diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 68bacd4c5..1d1975179 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -203,21 +203,6 @@ void OpenGLState::Apply() const { } } - // Constbuffers - for (std::size_t stage = 0; stage < draw.const_buffers.size(); ++stage) { - for (std::size_t buffer_id = 0; buffer_id < draw.const_buffers[stage].size(); ++buffer_id) { - const auto& current = cur_state.draw.const_buffers[stage][buffer_id]; - const auto& new_state = draw.const_buffers[stage][buffer_id]; - - if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || - current.ssbo != new_state.ssbo) { - if (new_state.enabled) { - glBindBufferBase(GL_UNIFORM_BUFFER, new_state.bindpoint, new_state.ssbo); - } - } - } - } - // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 24b1d956b..bdb02ba25 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -7,6 +7,10 @@ #include <array> #include <glad/glad.h> +#include "video_core/engines/maxwell_3d.h" + +using Regs = Tegra::Engines::Maxwell3D::Regs; + namespace TextureUnits { struct TextureUnit { @@ -115,12 +119,6 @@ public: GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING GLuint shader_program; // GL_CURRENT_PROGRAM GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING - struct ConstBufferConfig { - bool enabled = false; - GLuint bindpoint; - GLuint ssbo; - }; - std::array<std::array<ConstBufferConfig, 16>, 5> const_buffers{}; } draw; struct { diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp index a2713e9f0..03a8ed8b7 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp +++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp @@ -9,174 +9,91 @@ #include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" -class OrphanBuffer : public OGLStreamBuffer { -public: - explicit OrphanBuffer(GLenum target) : OGLStreamBuffer(target) {} - ~OrphanBuffer() override; - -private: - void Create(size_t size, size_t sync_subdivide) override; - void Release() override; - - std::pair<u8*, GLintptr> Map(size_t size, size_t alignment) override; - void Unmap() override; - - std::vector<u8> data; -}; - -class StorageBuffer : public OGLStreamBuffer { -public: - explicit StorageBuffer(GLenum target) : OGLStreamBuffer(target) {} - ~StorageBuffer() override; - -private: - void Create(size_t size, size_t sync_subdivide) override; - void Release() override; - - std::pair<u8*, GLintptr> Map(size_t size, size_t alignment) override; - void Unmap() override; - - struct Fence { - OGLSync sync; - size_t offset; - }; - std::deque<Fence> head; - std::deque<Fence> tail; - - u8* mapped_ptr; -}; - -OGLStreamBuffer::OGLStreamBuffer(GLenum target) { - gl_target = target; -} - -GLuint OGLStreamBuffer::GetHandle() const { - return gl_buffer.handle; -} +OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent) + : gl_target(target), buffer_size(size) { + gl_buffer.Create(); + glBindBuffer(gl_target, gl_buffer.handle); -std::unique_ptr<OGLStreamBuffer> OGLStreamBuffer::MakeBuffer(bool storage_buffer, GLenum target) { - if (storage_buffer) { - return std::make_unique<StorageBuffer>(target); + GLsizeiptr allocate_size = size; + if (target == GL_ARRAY_BUFFER) { + // 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<byte> attributes in the + // vertex array. Doubling the allocation size for the vertex buffer seems to avoid the + // crash. + allocate_size *= 2; } - return std::make_unique<OrphanBuffer>(target); -} -OrphanBuffer::~OrphanBuffer() { - Release(); + if (GLAD_GL_ARB_buffer_storage) { + persistent = true; + coherent = prefer_coherent; + GLbitfield flags = + GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); + glBufferStorage(gl_target, allocate_size, nullptr, flags); + mapped_ptr = static_cast<u8*>(glMapBufferRange( + gl_target, 0, buffer_size, flags | (coherent ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT))); + } else { + glBufferData(gl_target, allocate_size, nullptr, GL_STREAM_DRAW); + } } -void OrphanBuffer::Create(size_t size, size_t /*sync_subdivide*/) { - buffer_pos = 0; - buffer_size = size; - data.resize(buffer_size); - - if (gl_buffer.handle == 0) { - gl_buffer.Create(); +OGLStreamBuffer::~OGLStreamBuffer() { + if (persistent) { glBindBuffer(gl_target, gl_buffer.handle); + glUnmapBuffer(gl_target); } - - glBufferData(gl_target, static_cast<GLsizeiptr>(buffer_size), nullptr, GL_STREAM_DRAW); -} - -void OrphanBuffer::Release() { gl_buffer.Release(); } -std::pair<u8*, GLintptr> OrphanBuffer::Map(size_t size, size_t alignment) { - buffer_pos = Common::AlignUp(buffer_pos, alignment); - - if (buffer_pos + size > buffer_size) { - Create(std::max(buffer_size, size), 0); - } - - mapped_size = size; - return std::make_pair(&data[buffer_pos], static_cast<GLintptr>(buffer_pos)); -} - -void OrphanBuffer::Unmap() { - glBufferSubData(gl_target, static_cast<GLintptr>(buffer_pos), - static_cast<GLsizeiptr>(mapped_size), &data[buffer_pos]); - buffer_pos += mapped_size; -} - -StorageBuffer::~StorageBuffer() { - Release(); +GLuint OGLStreamBuffer::GetHandle() const { + return gl_buffer.handle; } -void StorageBuffer::Create(size_t size, size_t sync_subdivide) { - if (gl_buffer.handle != 0) - return; - - buffer_pos = 0; - buffer_size = size; - buffer_sync_subdivide = std::max<size_t>(sync_subdivide, 1); - - gl_buffer.Create(); - glBindBuffer(gl_target, gl_buffer.handle); - - glBufferStorage(gl_target, static_cast<GLsizeiptr>(buffer_size), nullptr, - GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); - mapped_ptr = reinterpret_cast<u8*>( - glMapBufferRange(gl_target, 0, static_cast<GLsizeiptr>(buffer_size), - GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT)); +GLsizeiptr OGLStreamBuffer::GetSize() const { + return buffer_size; } -void StorageBuffer::Release() { - if (gl_buffer.handle == 0) - return; - - glUnmapBuffer(gl_target); - - gl_buffer.Release(); - head.clear(); - tail.clear(); -} - -std::pair<u8*, GLintptr> StorageBuffer::Map(size_t size, size_t alignment) { +std::tuple<u8*, GLintptr, bool> OGLStreamBuffer::Map(GLsizeiptr size, GLintptr alignment) { ASSERT(size <= buffer_size); + ASSERT(alignment <= buffer_size); + mapped_size = size; - OGLSync sync; - - buffer_pos = Common::AlignUp(buffer_pos, alignment); - size_t effective_offset = Common::AlignDown(buffer_pos, buffer_sync_subdivide); - - if (!head.empty() && - (effective_offset > head.back().offset || buffer_pos + size > buffer_size)) { - ASSERT(head.back().sync.handle == 0); - head.back().sync.Create(); + if (alignment > 0) { + buffer_pos = Common::AlignUp<size_t>(buffer_pos, alignment); } + bool invalidate = false; if (buffer_pos + size > buffer_size) { - if (!tail.empty()) { - std::swap(sync, tail.back().sync); - tail.clear(); - } - std::swap(tail, head); buffer_pos = 0; - effective_offset = 0; - } + invalidate = true; - while (!tail.empty() && buffer_pos + size > tail.front().offset) { - std::swap(sync, tail.front().sync); - tail.pop_front(); + if (persistent) { + glUnmapBuffer(gl_target); + } } - if (sync.handle != 0) { - glClientWaitSync(sync.handle, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); - sync.Release(); + if (invalidate | !persistent) { + GLbitfield flags = GL_MAP_WRITE_BIT | (persistent ? GL_MAP_PERSISTENT_BIT : 0) | + (coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT) | + (invalidate ? GL_MAP_INVALIDATE_BUFFER_BIT : GL_MAP_UNSYNCHRONIZED_BIT); + mapped_ptr = static_cast<u8*>( + glMapBufferRange(gl_target, buffer_pos, buffer_size - buffer_pos, flags)); + mapped_offset = buffer_pos; } - if (head.empty() || effective_offset > head.back().offset) { - head.emplace_back(); - head.back().offset = effective_offset; + return std::make_tuple(mapped_ptr + buffer_pos - mapped_offset, buffer_pos, invalidate); +} + +void OGLStreamBuffer::Unmap(GLsizeiptr size) { + ASSERT(size <= mapped_size); + + if (!coherent && size > 0) { + glFlushMappedBufferRange(gl_target, buffer_pos - mapped_offset, size); } - mapped_size = size; - return std::make_pair(&mapped_ptr[buffer_pos], static_cast<GLintptr>(buffer_pos)); -} + if (!persistent) { + glUnmapBuffer(gl_target); + } -void StorageBuffer::Unmap() { - glFlushMappedBufferRange(gl_target, static_cast<GLintptr>(buffer_pos), - static_cast<GLsizeiptr>(mapped_size)); - buffer_pos += mapped_size; + buffer_pos += size; } diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_stream_buffer.h index e78dc5784..45592daaf 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.h +++ b/src/video_core/renderer_opengl/gl_stream_buffer.h @@ -2,35 +2,41 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - -#include <memory> +#include <tuple> #include <glad/glad.h> #include "common/common_types.h" #include "video_core/renderer_opengl/gl_resource_manager.h" class OGLStreamBuffer : private NonCopyable { public: - explicit OGLStreamBuffer(GLenum target); - virtual ~OGLStreamBuffer() = default; - -public: - static std::unique_ptr<OGLStreamBuffer> MakeBuffer(bool storage_buffer, GLenum target); - - virtual void Create(size_t size, size_t sync_subdivide) = 0; - virtual void Release() {} + explicit OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent = false); + ~OGLStreamBuffer(); GLuint GetHandle() const; + GLsizeiptr GetSize() const; + + /* + * Allocates a linear chunk of memory in the GPU buffer with at least "size" bytes + * and the optional alignment requirement. + * If the buffer is full, the whole buffer is reallocated which invalidates old chunks. + * The return values are the pointer to the new chunk, the offset within the buffer, + * and the invalidation flag for previous chunks. + * The actual used size must be specified on unmapping the chunk. + */ + std::tuple<u8*, GLintptr, bool> Map(GLsizeiptr size, GLintptr alignment = 0); - virtual std::pair<u8*, GLintptr> Map(size_t size, size_t alignment) = 0; - virtual void Unmap() = 0; + void Unmap(GLsizeiptr size); -protected: +private: OGLBuffer gl_buffer; GLenum gl_target; - size_t buffer_pos = 0; - size_t buffer_size = 0; - size_t buffer_sync_subdivide = 0; - size_t mapped_size = 0; + bool coherent = false; + bool persistent = false; + + GLintptr buffer_pos = 0; + GLsizeiptr buffer_size = 0; + GLintptr mapped_offset = 0; + GLsizeiptr mapped_size = 0; + u8* mapped_ptr = nullptr; }; diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 16b1bd606..83ea0cfc0 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -27,9 +27,12 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { case Maxwell::VertexAttribute::Type::UnsignedNorm: { switch (attrib.size) { + case Maxwell::VertexAttribute::Size::Size_8: + case Maxwell::VertexAttribute::Size::Size_8_8: case Maxwell::VertexAttribute::Size::Size_8_8_8_8: return GL_UNSIGNED_BYTE; case Maxwell::VertexAttribute::Size::Size_16_16: + case Maxwell::VertexAttribute::Size::Size_16_16_16_16: return GL_UNSIGNED_SHORT; case Maxwell::VertexAttribute::Size::Size_10_10_10_2: return GL_UNSIGNED_INT_2_10_10_10_REV; @@ -43,6 +46,9 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { case Maxwell::VertexAttribute::Type::SignedNorm: { switch (attrib.size) { + case Maxwell::VertexAttribute::Size::Size_32_32_32: + return GL_INT; + case Maxwell::VertexAttribute::Size::Size_8_8: case Maxwell::VertexAttribute::Size::Size_8_8_8_8: return GL_BYTE; case Maxwell::VertexAttribute::Size::Size_16_16: @@ -84,6 +90,10 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) { switch (topology) { + case Maxwell::PrimitiveTopology::Points: + return GL_POINTS; + case Maxwell::PrimitiveTopology::LineStrip: + return GL_LINE_STRIP; case Maxwell::PrimitiveTopology::Triangles: return GL_TRIANGLES; case Maxwell::PrimitiveTopology::TriangleStrip: @@ -149,42 +159,61 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { switch (factor) { case Maxwell::Blend::Factor::Zero: + case Maxwell::Blend::Factor::ZeroGL: return GL_ZERO; case Maxwell::Blend::Factor::One: + case Maxwell::Blend::Factor::OneGL: return GL_ONE; case Maxwell::Blend::Factor::SourceColor: + case Maxwell::Blend::Factor::SourceColorGL: return GL_SRC_COLOR; case Maxwell::Blend::Factor::OneMinusSourceColor: + case Maxwell::Blend::Factor::OneMinusSourceColorGL: return GL_ONE_MINUS_SRC_COLOR; case Maxwell::Blend::Factor::SourceAlpha: + case Maxwell::Blend::Factor::SourceAlphaGL: return GL_SRC_ALPHA; case Maxwell::Blend::Factor::OneMinusSourceAlpha: + case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: return GL_ONE_MINUS_SRC_ALPHA; case Maxwell::Blend::Factor::DestAlpha: + case Maxwell::Blend::Factor::DestAlphaGL: return GL_DST_ALPHA; case Maxwell::Blend::Factor::OneMinusDestAlpha: + case Maxwell::Blend::Factor::OneMinusDestAlphaGL: return GL_ONE_MINUS_DST_ALPHA; case Maxwell::Blend::Factor::DestColor: + case Maxwell::Blend::Factor::DestColorGL: return GL_DST_COLOR; case Maxwell::Blend::Factor::OneMinusDestColor: + case Maxwell::Blend::Factor::OneMinusDestColorGL: return GL_ONE_MINUS_DST_COLOR; case Maxwell::Blend::Factor::SourceAlphaSaturate: + case Maxwell::Blend::Factor::SourceAlphaSaturateGL: return GL_SRC_ALPHA_SATURATE; case Maxwell::Blend::Factor::Source1Color: + case Maxwell::Blend::Factor::Source1ColorGL: return GL_SRC1_COLOR; case Maxwell::Blend::Factor::OneMinusSource1Color: + case Maxwell::Blend::Factor::OneMinusSource1ColorGL: return GL_ONE_MINUS_SRC1_COLOR; case Maxwell::Blend::Factor::Source1Alpha: + case Maxwell::Blend::Factor::Source1AlphaGL: return GL_SRC1_ALPHA; case Maxwell::Blend::Factor::OneMinusSource1Alpha: + case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: return GL_ONE_MINUS_SRC1_ALPHA; case Maxwell::Blend::Factor::ConstantColor: + case Maxwell::Blend::Factor::ConstantColorGL: return GL_CONSTANT_COLOR; case Maxwell::Blend::Factor::OneMinusConstantColor: + case Maxwell::Blend::Factor::OneMinusConstantColorGL: return GL_ONE_MINUS_CONSTANT_COLOR; case Maxwell::Blend::Factor::ConstantAlpha: + case Maxwell::Blend::Factor::ConstantAlphaGL: return GL_CONSTANT_ALPHA; case Maxwell::Blend::Factor::OneMinusConstantAlpha: + case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: return GL_ONE_MINUS_CONSTANT_ALPHA; } LOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor)); diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index bf9131193..95f1aa0fe 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -18,7 +18,6 @@ #include "core/tracer/recorder.h" #include "video_core/renderer_opengl/renderer_opengl.h" #include "video_core/utils.h" -#include "video_core/video_core.h" static const char vertex_shader[] = R"( #version 150 core @@ -92,7 +91,8 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons return matrix; } -ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} { +ScopeAcquireGLContext::ScopeAcquireGLContext(Core::Frontend::EmuWindow& emu_window_) + : emu_window{emu_window_} { if (Settings::values.use_multi_core) { emu_window.MakeCurrent(); } @@ -103,7 +103,9 @@ ScopeAcquireGLContext::~ScopeAcquireGLContext() { } } -RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {} +RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window) + : VideoCore::RendererBase{window} {} + RendererOpenGL::~RendererOpenGL() = default; /// Swap buffers (render frame) @@ -430,7 +432,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum break; case GL_DEBUG_SEVERITY_NOTIFICATION: case GL_DEBUG_SEVERITY_LOW: - LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message); + LOG_TRACE(Render_OpenGL, format, str_source, str_type, id, message); break; } } diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 428afa3b7..a5eab6997 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -12,7 +12,9 @@ #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" +namespace Core::Frontend { class EmuWindow; +} /// Structure used for storing information about the textures for the Switch screen struct TextureInfo { @@ -34,16 +36,16 @@ struct ScreenInfo { /// Helper class to acquire/release OpenGL context within a given scope class ScopeAcquireGLContext : NonCopyable { public: - explicit ScopeAcquireGLContext(EmuWindow& window); + explicit ScopeAcquireGLContext(Core::Frontend::EmuWindow& window); ~ScopeAcquireGLContext(); private: - EmuWindow& emu_window; + Core::Frontend::EmuWindow& emu_window; }; class RendererOpenGL : public VideoCore::RendererBase { public: - explicit RendererOpenGL(EmuWindow& window); + explicit RendererOpenGL(Core::Frontend::EmuWindow& window); ~RendererOpenGL() override; /// Swap buffers (render frame) diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 65db84ad3..70746a34e 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -54,6 +54,7 @@ u32 BytesPerPixel(TextureFormat format) { return 8; case TextureFormat::DXT23: case TextureFormat::DXT45: + case TextureFormat::DXN2: case TextureFormat::BC7U: // In this case a 'pixel' actually refers to a 4x4 tile. return 16; @@ -85,87 +86,11 @@ u32 BytesPerPixel(TextureFormat format) { } } -static u32 DepthBytesPerPixel(DepthFormat format) { - switch (format) { - case DepthFormat::Z16_UNORM: - return 2; - case DepthFormat::S8_Z24_UNORM: - case DepthFormat::Z24_S8_UNORM: - case DepthFormat::Z32_FLOAT: - return 4; - case DepthFormat::Z32_S8_X24_FLOAT: - return 8; - default: - UNIMPLEMENTED_MSG("Format not implemented"); - break; - } -} - -std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, - u32 block_height) { - u8* data = Memory::GetPointer(address); - u32 bytes_per_pixel = BytesPerPixel(format); - +std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, + u32 height, u32 block_height) { std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); - - switch (format) { - case TextureFormat::DXT1: - case TextureFormat::DXT23: - case TextureFormat::DXT45: - case TextureFormat::DXN1: - case TextureFormat::BC7U: - // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel - // values. - CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, - unswizzled_data.data(), true, block_height); - break; - case TextureFormat::A8R8G8B8: - case TextureFormat::A2B10G10R10: - case TextureFormat::A1B5G5R5: - case TextureFormat::B5G6R5: - case TextureFormat::R8: - case TextureFormat::G8R8: - case TextureFormat::R16_G16_B16_A16: - case TextureFormat::R32_G32_B32_A32: - case TextureFormat::R32_G32: - case TextureFormat::R32: - case TextureFormat::R16: - case TextureFormat::R16_G16: - case TextureFormat::BF10GF11RF11: - case TextureFormat::ASTC_2D_4X4: - case TextureFormat::R32_G32_B32: - CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, - unswizzled_data.data(), true, block_height); - break; - default: - UNIMPLEMENTED_MSG("Format not implemented"); - break; - } - - return unswizzled_data; -} - -std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height, - u32 block_height) { - u8* data = Memory::GetPointer(address); - u32 bytes_per_pixel = DepthBytesPerPixel(format); - - std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); - - switch (format) { - case DepthFormat::Z16_UNORM: - case DepthFormat::S8_Z24_UNORM: - case DepthFormat::Z24_S8_UNORM: - case DepthFormat::Z32_FLOAT: - case DepthFormat::Z32_S8_X24_FLOAT: - CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, - unswizzled_data.data(), true, block_height); - break; - default: - UNIMPLEMENTED_MSG("Format not implemented"); - break; - } - + CopySwizzledData(width / tile_size, height / tile_size, bytes_per_pixel, bytes_per_pixel, + Memory::GetPointer(address), unswizzled_data.data(), true, block_height); return unswizzled_data; } @@ -179,6 +104,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat case TextureFormat::DXT23: case TextureFormat::DXT45: case TextureFormat::DXN1: + case TextureFormat::DXN2: case TextureFormat::BC7U: case TextureFormat::ASTC_2D_4X4: case TextureFormat::A8R8G8B8: diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 73a4924d1..1f7b731be 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -13,8 +13,8 @@ namespace Tegra::Texture { /** * Unswizzles a swizzled texture without changing its format. */ -std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, - u32 block_height = TICEntry::DefaultBlockHeight); +std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, + u32 height, u32 block_height = TICEntry::DefaultBlockHeight); /** * Unswizzles a swizzled depth texture without changing its format. diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 5085ef96b..6780d1c16 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -9,9 +9,7 @@ namespace VideoCore { -std::atomic<bool> g_toggle_framelimit_enabled; - -std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) { +std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window) { return std::make_unique<RendererOpenGL>(emu_window); } diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 7c01c0b8d..f79f85dfe 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -4,27 +4,22 @@ #pragma once -#include <atomic> #include <memory> +namespace Core::Frontend { class EmuWindow; +} namespace VideoCore { class RendererBase; -enum class Renderer { Software, OpenGL }; - -// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from -// qt ui) -extern std::atomic<bool> g_toggle_framelimit_enabled; - /** * Creates a renderer instance. * * @note The returned renderer instance is simply allocated. Its Init() * function still needs to be called to fully complete its setup. */ -std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window); +std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window); } // namespace VideoCore diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 475556806..46ed232d8 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -17,6 +17,8 @@ add_executable(yuzu configuration/configure_debug.h configuration/configure_dialog.cpp configuration/configure_dialog.h + configuration/configure_gamelist.cpp + configuration/configure_gamelist.h configuration/configure_general.cpp configuration/configure_general.h configuration/configure_graphics.cpp @@ -59,6 +61,7 @@ set(UIS configuration/configure.ui configuration/configure_audio.ui configuration/configure_debug.ui + configuration/configure_gamelist.ui configuration/configure_general.ui configuration/configure_graphics.ui configuration/configure_input.ui diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index 39ed3bccf..a81ad2888 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -15,4 +15,4 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDia Common::g_scm_desc, QString(Common::g_build_date).left(10))); } -AboutDialog::~AboutDialog() {} +AboutDialog::~AboutDialog() = default; diff --git a/src/yuzu/about_dialog.h b/src/yuzu/about_dialog.h index 2eb6e28f5..18e8c11a7 100644 --- a/src/yuzu/about_dialog.h +++ b/src/yuzu/about_dialog.h @@ -16,7 +16,7 @@ class AboutDialog : public QDialog { public: explicit AboutDialog(QWidget* parent); - ~AboutDialog(); + ~AboutDialog() override; private: std::unique_ptr<Ui::AboutDialog> ui; diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 130bc613b..f133bfadf 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -101,12 +101,12 @@ signals: void ErrorThrown(Core::System::ResultStatus, std::string); }; -class GRenderWindow : public QWidget, public EmuWindow { +class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow { Q_OBJECT public: GRenderWindow(QWidget* parent, EmuThread* emu_thread); - ~GRenderWindow(); + ~GRenderWindow() override; // EmuWindow implementation void SwapBuffers() override; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index bf469ee73..0bd46dbac 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -122,6 +122,13 @@ void Config::ReadValues() { qt_config->beginGroup("UI"); UISettings::values.theme = qt_config->value("theme", UISettings::themes[0].second).toString(); + qt_config->beginGroup("UIGameList"); + UISettings::values.show_unknown = qt_config->value("show_unknown", true).toBool(); + UISettings::values.icon_size = qt_config->value("icon_size", 48).toUInt(); + UISettings::values.row_1_text_id = qt_config->value("row_1_text_id", 0).toUInt(); + UISettings::values.row_2_text_id = qt_config->value("row_2_text_id", 3).toUInt(); + qt_config->endGroup(); + qt_config->beginGroup("UILayout"); UISettings::values.geometry = qt_config->value("geometry").toByteArray(); UISettings::values.state = qt_config->value("state").toByteArray(); @@ -234,6 +241,13 @@ void Config::SaveValues() { qt_config->beginGroup("UI"); qt_config->setValue("theme", UISettings::values.theme); + qt_config->beginGroup("UIGameList"); + qt_config->setValue("show_unknown", UISettings::values.show_unknown); + qt_config->setValue("icon_size", UISettings::values.icon_size); + qt_config->setValue("row_1_text_id", UISettings::values.row_1_text_id); + qt_config->setValue("row_2_text_id", UISettings::values.row_2_text_id); + qt_config->endGroup(); + qt_config->beginGroup("UILayout"); qt_config->setValue("geometry", UISettings::values.geometry); qt_config->setValue("state", UISettings::values.state); diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui index c8e0b88af..20f120134 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui @@ -24,6 +24,11 @@ <string>General</string> </attribute> </widget> + <widget class="ConfigureGameList" name="gameListTab"> + <attribute name="title"> + <string>Game List</string> + </attribute> + </widget> <widget class="ConfigureSystem" name="systemTab"> <attribute name="title"> <string>System</string> @@ -67,6 +72,12 @@ <header>configuration/configure_general.h</header> <container>1</container> </customwidget> + <customwidget> + <class>ConfigureGameList</class> + <extends>QWidget</extends> + <header>configuration/configure_gamelist.h</header> + <container>1</container> + </customwidget> <customwidget> <class>ConfigureSystem</class> <extends>QWidget</extends> diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 7fd07539a..45d84f19a 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -24,7 +24,7 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::Co }); } -ConfigureDebug::~ConfigureDebug() {} +ConfigureDebug::~ConfigureDebug() = default; void ConfigureDebug::setConfiguration() { ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 118e91cf1..5ae7276bd 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -23,13 +23,6 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> - <widget class="QLabel" name="label_1"> - <property name="text"> - <string>The GDB Stub only works correctly when the CPU JIT is off.</string> - </property> - </widget> - </item> - <item> <layout class="QHBoxLayout" name="horizontalLayout_1"> <item> <widget class="QCheckBox" name="toggle_gdbstub"> diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index f66abf870..daa4cc0d9 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -6,18 +6,22 @@ #include "ui_configure.h" #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_dialog.h" +#include "yuzu/hotkeys.h" -ConfigureDialog::ConfigureDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ConfigureDialog) { +ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry) + : QDialog(parent), ui(new Ui::ConfigureDialog) { ui->setupUi(this); + ui->generalTab->PopulateHotkeyList(registry); this->setConfiguration(); } -ConfigureDialog::~ConfigureDialog() {} +ConfigureDialog::~ConfigureDialog() = default; void ConfigureDialog::setConfiguration() {} void ConfigureDialog::applyConfiguration() { ui->generalTab->applyConfiguration(); + ui->gameListTab->applyConfiguration(); ui->systemTab->applyConfiguration(); ui->inputTab->applyConfiguration(); ui->graphicsTab->applyConfiguration(); diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 21fa1f501..bbbdacc29 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -7,6 +7,8 @@ #include <memory> #include <QDialog> +class HotkeyRegistry; + namespace Ui { class ConfigureDialog; } @@ -15,7 +17,7 @@ class ConfigureDialog : public QDialog { Q_OBJECT public: - explicit ConfigureDialog(QWidget* parent); + explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); ~ConfigureDialog(); void applyConfiguration(); diff --git a/src/yuzu/configuration/configure_gamelist.cpp b/src/yuzu/configuration/configure_gamelist.cpp new file mode 100644 index 000000000..1ae3423cf --- /dev/null +++ b/src/yuzu/configuration/configure_gamelist.cpp @@ -0,0 +1,63 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/core.h" +#include "core/settings.h" +#include "ui_configure_gamelist.h" +#include "ui_settings.h" +#include "yuzu/configuration/configure_gamelist.h" + +ConfigureGameList::ConfigureGameList(QWidget* parent) + : QWidget(parent), ui(new Ui::ConfigureGameList) { + ui->setupUi(this); + + static const std::vector<std::pair<u32, std::string>> default_icon_sizes{ + std::make_pair(0, "None"), std::make_pair(32, "Small"), + std::make_pair(64, "Standard"), std::make_pair(128, "Large"), + std::make_pair(256, "Full Size"), + }; + + for (const auto& size : default_icon_sizes) { + ui->icon_size_combobox->addItem(QString::fromStdString(size.second + " (" + + std::to_string(size.first) + "x" + + std::to_string(size.first) + ")"), + size.first); + } + + static const std::vector<std::string> row_text_names{ + "Filename", + "Filetype", + "Title ID", + "Title Name", + }; + + for (size_t i = 0; i < row_text_names.size(); ++i) { + ui->row_1_text_combobox->addItem(QString::fromStdString(row_text_names[i]), + QVariant::fromValue(i)); + ui->row_2_text_combobox->addItem(QString::fromStdString(row_text_names[i]), + QVariant::fromValue(i)); + } + + this->setConfiguration(); +} + +ConfigureGameList::~ConfigureGameList() {} + +void ConfigureGameList::setConfiguration() { + ui->show_unknown->setChecked(UISettings::values.show_unknown); + ui->icon_size_combobox->setCurrentIndex( + ui->icon_size_combobox->findData(UISettings::values.icon_size)); + ui->row_1_text_combobox->setCurrentIndex( + ui->row_1_text_combobox->findData(UISettings::values.row_1_text_id)); + ui->row_2_text_combobox->setCurrentIndex( + ui->row_2_text_combobox->findData(UISettings::values.row_2_text_id)); +} + +void ConfigureGameList::applyConfiguration() { + UISettings::values.show_unknown = ui->show_unknown->isChecked(); + UISettings::values.icon_size = ui->icon_size_combobox->currentData().toUInt(); + UISettings::values.row_1_text_id = ui->row_1_text_combobox->currentData().toUInt(); + UISettings::values.row_2_text_id = ui->row_2_text_combobox->currentData().toUInt(); + Settings::Apply(); +} diff --git a/src/yuzu/configuration/configure_gamelist.h b/src/yuzu/configuration/configure_gamelist.h new file mode 100644 index 000000000..94fba6373 --- /dev/null +++ b/src/yuzu/configuration/configure_gamelist.h @@ -0,0 +1,28 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <QWidget> + +namespace Ui { +class ConfigureGameList; +} + +class ConfigureGameList : public QWidget { + Q_OBJECT + +public: + explicit ConfigureGameList(QWidget* parent = nullptr); + ~ConfigureGameList(); + + void applyConfiguration(); + +private: + void setConfiguration(); + +private: + std::unique_ptr<Ui::ConfigureGameList> ui; +}; diff --git a/src/yuzu/configuration/configure_gamelist.ui b/src/yuzu/configuration/configure_gamelist.ui new file mode 100644 index 000000000..7471fdb60 --- /dev/null +++ b/src/yuzu/configuration/configure_gamelist.ui @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConfigureGameList</class> + <widget class="QWidget" name="ConfigureGeneral"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>300</width> + <height>377</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="HorizontalLayout"> + <item> + <layout class="QVBoxLayout" name="VerticalLayout"> + <item> + <widget class="QGroupBox" name="GeneralGroupBox"> + <property name="title"> + <string>General</string> + </property> + <layout class="QHBoxLayout" name="GeneralHorizontalLayout"> + <item> + <layout class="QVBoxLayout" name="GeneralVerticalLayout"> + <item> + <widget class="QCheckBox" name="show_unknown"> + <property name="text"> + <string>Show files with type 'Unknown'</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="IconSizeGroupBox"> + <property name="title"> + <string>Icon Size</string> + </property> + <layout class="QHBoxLayout" name="icon_size_qhbox_layout"> + <item> + <layout class="QVBoxLayout" name="icon_size_qvbox_layout"> + <item> + <layout class="QHBoxLayout" name="icon_size_qhbox_layout_2"> + <item> + <widget class="QLabel" name="icon_size_label"> + <property name="text"> + <string>Icon Size:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="icon_size_combobox"/> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="RowGroupBox"> + <property name="title"> + <string>Row Text</string> + </property> + <layout class="QHBoxLayout" name="RowHorizontalLayout"> + <item> + <layout class="QVBoxLayout" name="RowVerticalLayout"> + <item> + <layout class="QHBoxLayout" name="row_1_qhbox_layout"> + <item> + <widget class="QLabel" name="row_1_label"> + <property name="text"> + <string>Row 1 Text:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="row_1_text_combobox"/> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="row_2_qhbox_layout"> + <item> + <widget class="QLabel" name="row_2_label"> + <property name="text"> + <string>Row 2 Text:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="row_2_text_combobox"/> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index cb7d3f8bf..d8caee1e8 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -24,7 +24,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent) ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); } -ConfigureGeneral::~ConfigureGeneral() {} +ConfigureGeneral::~ConfigureGeneral() = default; void ConfigureGeneral::setConfiguration() { ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan); @@ -35,6 +35,10 @@ void ConfigureGeneral::setConfiguration() { ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); } +void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) { + ui->widget->Populate(registry); +} + void ConfigureGeneral::applyConfiguration() { UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked(); UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h index 447552d8c..4770034cc 100644 --- a/src/yuzu/configuration/configure_general.h +++ b/src/yuzu/configuration/configure_general.h @@ -7,6 +7,8 @@ #include <memory> #include <QWidget> +class HotkeyRegistry; + namespace Ui { class ConfigureGeneral; } @@ -18,11 +20,11 @@ public: explicit ConfigureGeneral(QWidget* parent = nullptr); ~ConfigureGeneral(); + void PopulateHotkeyList(const HotkeyRegistry& registry); void applyConfiguration(); private: void setConfiguration(); -private: std::unique_ptr<Ui::ConfigureGeneral> ui; }; diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 3379b7963..4afe0f81b 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -14,7 +14,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) this->setConfiguration(); } -ConfigureGraphics::~ConfigureGraphics() {} +ConfigureGraphics::~ConfigureGraphics() = default; enum class Resolution : int { Auto, diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 9be2c939c..e9ed9c38f 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -35,7 +35,7 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui:: this->setConfiguration(); } -ConfigureSystem::~ConfigureSystem() {} +ConfigureSystem::~ConfigureSystem() = default; void ConfigureSystem::setConfiguration() { enabled = !Core::System::GetInstance().IsPoweredOn(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index ff3efcdaa..e037223c2 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -34,7 +34,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) : QLabel(parent), surface_widget(surface_widget_) {} -SurfacePicture::~SurfacePicture() {} + +SurfacePicture::~SurfacePicture() = default; void SurfacePicture::mousePressEvent(QMouseEvent* event) { // Only do something while the left mouse button is held down @@ -382,8 +383,10 @@ void GraphicsSurfaceWidget::OnUpdate() { QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); - auto unswizzled_data = - Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); + // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. + // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. + auto unswizzled_data = Tegra::Texture::UnswizzleTexture( + *address, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, surface_height); auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, surface_width, surface_height); diff --git a/src/yuzu/debugger/graphics/graphics_surface.h b/src/yuzu/debugger/graphics/graphics_surface.h index 58f9db465..323e39d94 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.h +++ b/src/yuzu/debugger/graphics/graphics_surface.h @@ -22,11 +22,11 @@ class SurfacePicture : public QLabel { public: explicit SurfacePicture(QWidget* parent = nullptr, GraphicsSurfaceWidget* surface_widget = nullptr); - ~SurfacePicture(); + ~SurfacePicture() override; protected slots: - virtual void mouseMoveEvent(QMouseEvent* event); - virtual void mousePressEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; private: GraphicsSurfaceWidget* surface_widget; diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f5a5697a0..d0926d723 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -14,7 +14,7 @@ #include "core/hle/kernel/timer.h" #include "core/hle/kernel/wait_object.h" -WaitTreeItem::~WaitTreeItem() {} +WaitTreeItem::~WaitTreeItem() = default; QColor WaitTreeItem::GetColor() const { return QColor(Qt::GlobalColor::black); @@ -316,7 +316,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { list.push_back(std::make_unique<WaitTreeText>( tr("reset type = %1") - .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).reset_type)))); + .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType())))); return list; } diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 6cbce6856..513b3c45d 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -25,11 +25,13 @@ class WaitTreeThread; class WaitTreeItem : public QObject { Q_OBJECT public: + ~WaitTreeItem() override; + virtual bool IsExpandable() const; virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const; virtual QString GetText() const = 0; virtual QColor GetColor() const; - virtual ~WaitTreeItem(); + void Expand(); WaitTreeItem* Parent() const; const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const; diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 71e24a9e2..85cb12594 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -9,9 +9,13 @@ #include <QKeyEvent> #include <QMenu> #include <QThreadPool> +#include <boost/container/flat_map.hpp> #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" +#include "core/file_sys/romfs.h" #include "core/file_sys/vfs_real.h" #include "core/loader/loader.h" #include "game_list.h" @@ -162,15 +166,15 @@ void GameList::onTextChanged(const QString& newText) { } search_field->setFilterResult(rowCount, rowCount); } else { - QStandardItem* child_file; - QString file_path, file_name, file_title, file_programmid; int result_count = 0; for (int i = 0; i < rowCount; ++i) { - child_file = item_model->item(i, 0); - file_path = child_file->data(GameListItemPath::FullPathRole).toString().toLower(); - file_name = file_path.mid(file_path.lastIndexOf("/") + 1); - file_title = child_file->data(GameListItemPath::TitleRole).toString().toLower(); - file_programmid = + const QStandardItem* child_file = item_model->item(i, 0); + const QString file_path = + child_file->data(GameListItemPath::FullPathRole).toString().toLower(); + QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1); + const QString file_title = + child_file->data(GameListItemPath::TitleRole).toString().toLower(); + const QString file_programmid = child_file->data(GameListItemPath::ProgramIdRole).toString().toLower(); // Only items which filename in combination with its title contains all words @@ -194,7 +198,8 @@ void GameList::onFilterCloseClicked() { main_window->filterBarSetChecked(false); } -GameList::GameList(GMainWindow* parent) : QWidget{parent} { +GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) + : QWidget{parent}, vfs(std::move(vfs)) { watcher = new QFileSystemWatcher(this); connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); @@ -258,18 +263,20 @@ void GameList::AddEntry(const QList<QStandardItem*>& entry_items) { void GameList::ValidateEntry(const QModelIndex& item) { // We don't care about the individual QStandardItem that was selected, but its row. - int row = item_model->itemFromIndex(item)->row(); - QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); - QString file_path = child_file->data(GameListItemPath::FullPathRole).toString(); + const int row = item_model->itemFromIndex(item)->row(); + const QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); + const QString file_path = child_file->data(GameListItemPath::FullPathRole).toString(); if (file_path.isEmpty()) return; - std::string std_file_path(file_path.toStdString()); - if (!FileUtil::Exists(std_file_path)) + + if (!QFileInfo::exists(file_path)) return; - if (FileUtil::IsDirectory(std_file_path)) { - QDir dir(std_file_path.c_str()); - QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); + + const QFileInfo file_info{file_path}; + if (file_info.isDir()) { + const QDir dir{file_path}; + const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); if (matching_main.size() == 1) { emit GameChosen(dir.path() + DIR_SEP + matching_main[0]); } @@ -336,7 +343,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { emit ShouldCancelWorker(); - GameListWorker* worker = new GameListWorker(dir_path, deep_scan); + GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan); connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating, @@ -368,21 +375,23 @@ void GameList::LoadInterfaceLayout() { const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci"}; static bool HasSupportedFileExtension(const std::string& file_name) { - QFileInfo file = QFileInfo(file_name.c_str()); + const QFileInfo file = QFileInfo(QString::fromStdString(file_name)); return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); } static bool IsExtractedNCAMain(const std::string& file_name) { - return QFileInfo(file_name.c_str()).fileName() == "main"; + return QFileInfo(QString::fromStdString(file_name)).fileName() == "main"; } static QString FormatGameName(const std::string& physical_name) { - QFileInfo file_info(physical_name.c_str()); + const QString physical_name_as_qstring = QString::fromStdString(physical_name); + const QFileInfo file_info(physical_name_as_qstring); + if (IsExtractedNCAMain(physical_name)) { return file_info.dir().path(); - } else { - return QString::fromStdString(physical_name); } + + return physical_name_as_qstring; } void GameList::RefreshGameDirectory() { @@ -394,8 +403,32 @@ void GameList::RefreshGameDirectory() { } void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) { - const auto callback = [this, recursion](u64* num_entries_out, const std::string& directory, - const std::string& virtual_name) -> bool { + boost::container::flat_map<u64, std::shared_ptr<FileSys::NCA>> nca_control_map; + + const auto nca_control_callback = + [this, &nca_control_map](u64* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { + std::string physical_name = directory + DIR_SEP + virtual_name; + + if (stop_processing) + return false; // Breaks the callback loop. + + bool is_dir = FileUtil::IsDirectory(physical_name); + QFileInfo file_info(physical_name.c_str()); + if (!is_dir && file_info.suffix().toStdString() == "nca") { + auto nca = + std::make_shared<FileSys::NCA>(vfs->OpenFile(physical_name, FileSys::Mode::Read)); + if (nca->GetType() == FileSys::NCAContentType::Control) + nca_control_map.insert_or_assign(nca->GetTitleId(), nca); + } + return true; + }; + + FileUtil::ForeachDirectoryEntry(nullptr, dir_path, nca_control_callback); + + const auto callback = [this, recursion, + &nca_control_map](u64* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { std::string physical_name = directory + DIR_SEP + virtual_name; if (stop_processing) @@ -405,18 +438,48 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign if (!is_dir && (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { std::unique_ptr<Loader::AppLoader> loader = - Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(physical_name)); - if (!loader) + Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read)); + if (!loader || ((loader->GetFileType() == Loader::FileType::Unknown || + loader->GetFileType() == Loader::FileType::Error) && + !UISettings::values.show_unknown)) return true; - std::vector<u8> smdh; - loader->ReadIcon(smdh); - - u64 program_id = 0; - loader->ReadProgramId(program_id); + std::vector<u8> icon; + const auto res1 = loader->ReadIcon(icon); + + u64 program_id; + const auto res2 = loader->ReadProgramId(program_id); + + std::string name = " "; + const auto res3 = loader->ReadTitle(name); + + if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success && + res2 == Loader::ResultStatus::Success) { + // Use from metadata pool. + if (nca_control_map.find(program_id) != nca_control_map.end()) { + const auto nca = nca_control_map[program_id]; + const auto control_dir = FileSys::ExtractRomFS(nca->GetRomFS()); + + const auto nacp_file = control_dir->GetFile("control.nacp"); + FileSys::NACP nacp(nacp_file); + name = nacp.GetApplicationName(); + + FileSys::VirtualFile icon_file = nullptr; + for (const auto& language : FileSys::LANGUAGE_NAMES) { + icon_file = control_dir->GetFile("icon_" + std::string(language) + ".dat"); + if (icon_file != nullptr) { + icon = icon_file->ReadAllBytes(); + break; + } + } + } + } emit EntryReady({ - new GameListItemPath(FormatGameName(physical_name), smdh, program_id), + new GameListItemPath( + FormatGameName(physical_name), icon, QString::fromStdString(name), + QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), + program_id), new GameListItem( QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(FileUtil::GetSize(physical_name)), diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 3bc14f07f..afe624b32 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -59,7 +59,7 @@ public: QToolButton* button_filter_close = nullptr; }; - explicit GameList(GMainWindow* parent = nullptr); + explicit GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent = nullptr); ~GameList() override; void clearFilter(); @@ -90,6 +90,7 @@ private: void PopupContextMenu(const QPoint& menu_location); void RefreshGameDirectory(); + FileSys::VirtualFilesystem vfs; SearchField* search_field; GMainWindow* main_window = nullptr; QVBoxLayout* layout = nullptr; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index a758b77aa..8fe5e8b80 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -4,12 +4,15 @@ #pragma once +#include <array> #include <atomic> +#include <utility> #include <QImage> #include <QRunnable> #include <QStandardItem> #include <QString> #include "common/string_util.h" +#include "ui_settings.h" #include "yuzu/util/util.h" /** @@ -17,8 +20,7 @@ * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24) * @return QPixmap default icon */ -static QPixmap GetDefaultIcon(bool large) { - int size = large ? 48 : 24; +static QPixmap GetDefaultIcon(u32 size) { QPixmap icon(size, size); icon.fill(Qt::transparent); return icon; @@ -27,9 +29,8 @@ static QPixmap GetDefaultIcon(bool large) { class GameListItem : public QStandardItem { public: - GameListItem() : QStandardItem() {} - GameListItem(const QString& string) : QStandardItem(string) {} - virtual ~GameListItem() override {} + GameListItem() = default; + explicit GameListItem(const QString& string) : QStandardItem(string) {} }; /** @@ -39,17 +40,29 @@ public: * If this class receives valid SMDH data, it will also display game icons and titles. */ class GameListItemPath : public GameListItem { - public: static const int FullPathRole = Qt::UserRole + 1; static const int TitleRole = Qt::UserRole + 2; static const int ProgramIdRole = Qt::UserRole + 3; + static const int FileTypeRole = Qt::UserRole + 4; - GameListItemPath() : GameListItem() {} - GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) - : GameListItem() { + GameListItemPath() = default; + GameListItemPath(const QString& game_path, const std::vector<u8>& picture_data, + const QString& game_name, const QString& game_type, u64 program_id) { setData(game_path, FullPathRole); + setData(game_name, TitleRole); setData(qulonglong(program_id), ProgramIdRole); + setData(game_type, FileTypeRole); + + const u32 size = UISettings::values.icon_size; + + QPixmap picture; + if (!picture.loadFromData(picture_data.data(), static_cast<u32>(picture_data.size()))) { + picture = GetDefaultIcon(size); + } + picture = picture.scaled(size, size); + + setData(picture, Qt::DecorationRole); } QVariant data(int role) const override { @@ -57,11 +70,26 @@ public: std::string filename; Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename, nullptr); - QString title = data(TitleRole).toString(); - return QString::fromStdString(filename) + (title.isEmpty() ? "" : "\n " + title); - } else { - return GameListItem::data(role); + + const std::array<QString, 4> row_data{{ + QString::fromStdString(filename), + data(FileTypeRole).toString(), + QString::fromStdString(fmt::format("0x{:016X}", data(ProgramIdRole).toULongLong())), + data(TitleRole).toString(), + }}; + + const auto& row1 = row_data.at(UISettings::values.row_1_text_id); + const auto& row2 = row_data.at(UISettings::values.row_2_text_id); + + if (row1.isEmpty() || row1 == row2) + return row2; + if (row2.isEmpty()) + return row1; + + return row1 + "\n " + row2; } + + return GameListItem::data(role); } }; @@ -75,8 +103,8 @@ class GameListItemSize : public GameListItem { public: static const int SizeRole = Qt::UserRole + 1; - GameListItemSize() : GameListItem() {} - GameListItemSize(const qulonglong size_bytes) : GameListItem() { + GameListItemSize() = default; + explicit GameListItemSize(const qulonglong size_bytes) { setData(size_bytes, SizeRole); } @@ -110,8 +138,8 @@ class GameListWorker : public QObject, public QRunnable { Q_OBJECT public: - GameListWorker(QString dir_path, bool deep_scan) - : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} + GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan) + : vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan) {} public slots: /// Starts the processing of directory tree information. @@ -134,6 +162,7 @@ signals: void Finished(QStringList watch_list); private: + FileSys::VirtualFilesystem vfs; QStringList watch_list; QString dir_path; bool deep_scan; diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index 61acb38ee..dce399774 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp @@ -10,58 +10,53 @@ #include "yuzu/hotkeys.h" #include "yuzu/ui_settings.h" -struct Hotkey { - Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} +HotkeyRegistry::HotkeyRegistry() = default; +HotkeyRegistry::~HotkeyRegistry() = default; - QKeySequence keyseq; - QShortcut* shortcut; - Qt::ShortcutContext context; -}; - -typedef std::map<QString, Hotkey> HotkeyMap; -typedef std::map<QString, HotkeyMap> HotkeyGroupMap; - -HotkeyGroupMap hotkey_groups; - -void SaveHotkeys() { - UISettings::values.shortcuts.clear(); - for (auto group : hotkey_groups) { - for (auto hotkey : group.second) { - UISettings::values.shortcuts.emplace_back( - UISettings::Shortcut(group.first + "/" + hotkey.first, - UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), - hotkey.second.context))); - } - } -} - -void LoadHotkeys() { +void HotkeyRegistry::LoadHotkeys() { // Make sure NOT to use a reference here because it would become invalid once we call // beginGroup() for (auto shortcut : UISettings::values.shortcuts) { - QStringList cat = shortcut.first.split("/"); + const QStringList cat = shortcut.first.split('/'); Q_ASSERT(cat.size() >= 2); // RegisterHotkey assigns default keybindings, so use old values as default parameters Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; if (!shortcut.second.first.isEmpty()) { hk.keyseq = QKeySequence::fromString(shortcut.second.first); - hk.context = (Qt::ShortcutContext)shortcut.second.second; + hk.context = static_cast<Qt::ShortcutContext>(shortcut.second.second); } if (hk.shortcut) hk.shortcut->setKey(hk.keyseq); } } -void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, - Qt::ShortcutContext default_context) { - if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) { - hotkey_groups[group][action].keyseq = default_keyseq; - hotkey_groups[group][action].context = default_context; +void HotkeyRegistry::SaveHotkeys() { + UISettings::values.shortcuts.clear(); + for (const auto& group : hotkey_groups) { + for (const auto& hotkey : group.second) { + UISettings::values.shortcuts.emplace_back( + UISettings::Shortcut(group.first + '/' + hotkey.first, + UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), + hotkey.second.context))); + } } } -QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) { +void HotkeyRegistry::RegisterHotkey(const QString& group, const QString& action, + const QKeySequence& default_keyseq, + Qt::ShortcutContext default_context) { + auto& hotkey_group = hotkey_groups[group]; + if (hotkey_group.find(action) != hotkey_group.end()) { + return; + } + + auto& hotkey_action = hotkey_groups[group][action]; + hotkey_action.keyseq = default_keyseq; + hotkey_action.context = default_context; +} + +QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) { Hotkey& hk = hotkey_groups[group][action]; if (!hk.shortcut) @@ -72,10 +67,12 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { ui.setupUi(this); +} - for (auto group : hotkey_groups) { +void GHotkeysDialog::Populate(const HotkeyRegistry& registry) { + for (const auto& group : registry.hotkey_groups) { QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); - for (auto hotkey : group.second) { + for (const auto& hotkey : group.second) { QStringList columns; columns << hotkey.first << hotkey.second.keyseq.toString(); QTreeWidgetItem* item = new QTreeWidgetItem(columns); diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h index a4ccc193b..f38e6c002 100644 --- a/src/yuzu/hotkeys.h +++ b/src/yuzu/hotkeys.h @@ -4,6 +4,7 @@ #pragma once +#include <map> #include "ui_hotkeys.h" class QDialog; @@ -11,47 +12,69 @@ class QKeySequence; class QSettings; class QShortcut; -/** - * Register a hotkey. - * - * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") - * @param action Name of the action (e.g. "Start Emulation", "Load Image") - * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings - * file before - * @param default_context Default context to assign if the hotkey wasn't present in the settings - * file before - * @warning Both the group and action strings will be displayed in the hotkey settings dialog - */ -void RegisterHotkey(const QString& group, const QString& action, - const QKeySequence& default_keyseq = QKeySequence(), - Qt::ShortcutContext default_context = Qt::WindowShortcut); - -/** - * Returns a QShortcut object whose activated() signal can be connected to other QObjects' slots. - * - * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger"). - * @param action Name of the action (e.g. "Start Emulation", "Load Image"). - * @param widget Parent widget of the returned QShortcut. - * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut - * will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent. - */ -QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); - -/** - * Saves all registered hotkeys to the settings file. - * - * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a - * settings group will be created to store the key sequence and the hotkey context. - */ -void SaveHotkeys(); - -/** - * Loads hotkeys from the settings file. - * - * @note Yet unregistered hotkeys which are present in the settings will automatically be - * registered. - */ -void LoadHotkeys(); +class HotkeyRegistry final { +public: + friend class GHotkeysDialog; + + explicit HotkeyRegistry(); + ~HotkeyRegistry(); + + /** + * Loads hotkeys from the settings file. + * + * @note Yet unregistered hotkeys which are present in the settings will automatically be + * registered. + */ + void LoadHotkeys(); + + /** + * Saves all registered hotkeys to the settings file. + * + * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a + * settings group will be created to store the key sequence and the hotkey context. + */ + void SaveHotkeys(); + + /** + * Returns a QShortcut object whose activated() signal can be connected to other QObjects' + * slots. + * + * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger"). + * @param action Name of the action (e.g. "Start Emulation", "Load Image"). + * @param widget Parent widget of the returned QShortcut. + * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut + * will be the same. Thus, you shouldn't rely on the caller really being the + * QShortcut's parent. + */ + QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); + + /** + * Register a hotkey. + * + * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") + * @param action Name of the action (e.g. "Start Emulation", "Load Image") + * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the + * settings file before + * @param default_context Default context to assign if the hotkey wasn't present in the settings + * file before + * @warning Both the group and action strings will be displayed in the hotkey settings dialog + */ + void RegisterHotkey(const QString& group, const QString& action, + const QKeySequence& default_keyseq = {}, + Qt::ShortcutContext default_context = Qt::WindowShortcut); + +private: + struct Hotkey { + QKeySequence keyseq; + QShortcut* shortcut = nullptr; + Qt::ShortcutContext context = Qt::WindowShortcut; + }; + + using HotkeyMap = std::map<QString, Hotkey>; + using HotkeyGroupMap = std::map<QString, HotkeyMap>; + + HotkeyGroupMap hotkey_groups; +}; class GHotkeysDialog : public QWidget { Q_OBJECT @@ -59,6 +82,8 @@ class GHotkeysDialog : public QWidget { public: explicit GHotkeysDialog(QWidget* parent = nullptr); + void Populate(const HotkeyRegistry& registry); + private: Ui::hotkeys ui; }; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e28679cd1..94fb8ae6a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -24,6 +24,7 @@ #include "common/string_util.h" #include "core/core.h" #include "core/crypto/key_manager.h" +#include "core/file_sys/vfs_real.h" #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" #include "core/settings.h" @@ -81,7 +82,11 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) { void GMainWindow::ShowCallouts() {} -GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { +const int GMainWindow::max_recent_files_item; + +GMainWindow::GMainWindow() + : config(new Config()), emu_thread(nullptr), + vfs(std::make_shared<FileSys::RealVfsFilesystem>()) { debug_context = Tegra::DebugContext::Construct(); @@ -130,7 +135,7 @@ void GMainWindow::InitializeWidgets() { render_window = new GRenderWindow(this, emu_thread.get()); render_window->hide(); - game_list = new GameList(this); + game_list = new GameList(vfs, this); ui.horizontalLayout->addWidget(game_list); // Create status bar @@ -206,43 +211,46 @@ void GMainWindow::InitializeRecentFileMenuActions() { } void GMainWindow::InitializeHotkeys() { - RegisterHotkey("Main Window", "Load File", QKeySequence::Open); - RegisterHotkey("Main Window", "Start Emulation"); - RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4)); - RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); - RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), - Qt::ApplicationShortcut); - RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"), - Qt::ApplicationShortcut); - LoadHotkeys(); - - connect(GetHotkey("Main Window", "Load File", this), &QShortcut::activated, this, - &GMainWindow::OnMenuLoadFile); - connect(GetHotkey("Main Window", "Start Emulation", this), &QShortcut::activated, this, - &GMainWindow::OnStartGame); - connect(GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated, this, [&] { - if (emulation_running) { - if (emu_thread->IsRunning()) { - OnPauseGame(); - } else { - OnStartGame(); - } - } - }); - connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activated, - ui.action_Fullscreen, &QAction::trigger); - connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activatedAmbiguously, - ui.action_Fullscreen, &QAction::trigger); - connect(GetHotkey("Main Window", "Exit Fullscreen", this), &QShortcut::activated, this, [&] { - if (emulation_running) { - ui.action_Fullscreen->setChecked(false); - ToggleFullscreen(); - } - }); - connect(GetHotkey("Main Window", "Toggle Speed Limit", this), &QShortcut::activated, this, [&] { - Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit; - UpdateStatusBar(); - }); + hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open); + hotkey_registry.RegisterHotkey("Main Window", "Start Emulation"); + hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4)); + hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); + hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), + Qt::ApplicationShortcut); + hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"), + Qt::ApplicationShortcut); + hotkey_registry.LoadHotkeys(); + + connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated, + this, &GMainWindow::OnMenuLoadFile); + connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this), + &QShortcut::activated, this, &GMainWindow::OnStartGame); + connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated, + this, [&] { + if (emulation_running) { + if (emu_thread->IsRunning()) { + OnPauseGame(); + } else { + OnStartGame(); + } + } + }); + connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window), + &QShortcut::activated, ui.action_Fullscreen, &QAction::trigger); + connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window), + &QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger); + connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this), + &QShortcut::activated, this, [&] { + if (emulation_running) { + ui.action_Fullscreen->setChecked(false); + ToggleFullscreen(); + } + }); + connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this), + &QShortcut::activated, this, [&] { + Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit; + UpdateStatusBar(); + }); } void GMainWindow::SetDefaultUIGeometry() { @@ -321,7 +329,8 @@ void GMainWindow::ConnectMenuEvents() { connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); // Fullscreen - ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key()); + ui.action_Fullscreen->setShortcut( + hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key()); connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); // Help @@ -400,6 +409,7 @@ bool GMainWindow::LoadROM(const QString& filename) { } Core::System& system{Core::System::GetInstance()}; + system.SetFilesystem(vfs); system.SetGPUDebugContext(debug_context); @@ -414,67 +424,11 @@ bool GMainWindow::LoadROM(const QString& filename) { QMessageBox::critical(this, tr("Error while loading ROM!"), tr("The ROM format is not supported.")); break; - case Core::System::ResultStatus::ErrorUnsupportedArch: - LOG_CRITICAL(Frontend, "Unsupported architecture detected!", filename.toStdString()); - QMessageBox::critical(this, tr("Error while loading ROM!"), - tr("The ROM uses currently unusable 32-bit architecture")); - break; case Core::System::ResultStatus::ErrorSystemMode: LOG_CRITICAL(Frontend, "Failed to load ROM!"); QMessageBox::critical(this, tr("Error while loading ROM!"), tr("Could not determine the system mode.")); break; - - case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: { - const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false); - const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true); - - std::string file_text; - - if (!reg_found && !title_found) { - file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be " - "found. You will need to dump your keys from your switch to continue."; - } else if (reg_found && title_found) { - file_text = - "Both key files were found in your config directory, but the correct key could" - "not be found. You may be missing a titlekey or general key, depending on " - "the game."; - } else if (reg_found) { - file_text = - "The regular keys file (prod.keys/dev.keys) was found in your config, but the " - "titlekeys file (title.keys) was not. You are either missing the correct " - "titlekey or missing a general key required to decrypt the game."; - } else { - file_text = "The title keys file (title.keys) was found in your config, but " - "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, " - "having the titlekey is not enough, you need additional general keys " - "to properly decrypt the game. You should double-check to make sure " - "your keys are correct."; - } - - QMessageBox::critical( - this, tr("Error while loading ROM!"), - tr(("The game you are trying to load is encrypted and the required keys to load " - "the game could not be found in your configuration. " + - file_text + " Please refer to the yuzu wiki for help.") - .c_str())); - break; - } - case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: { - QMessageBox::critical( - this, tr("Error while loading ROM!"), - tr("There was a general error while decrypting the game. This means that the keys " - "necessary were found, but were either incorrect, the game itself was not a " - "valid game or the game uses an unhandled cryptographic scheme. Please double " - "check that you have the correct " - "keys.")); - break; - } - case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: - QMessageBox::critical(this, tr("Error while loading ROM!"), - tr("The ROM format is not supported.")); - break; - case Core::System::ResultStatus::ErrorVideoCore: QMessageBox::critical( this, tr("An error occurred initializing the video core."), @@ -489,9 +443,23 @@ bool GMainWindow::LoadROM(const QString& filename) { break; default: - QMessageBox::critical( - this, tr("Error while loading ROM!"), - tr("An unknown error occurred. Please see the log for more details.")); + if (static_cast<u32>(result) > + static_cast<u32>(Core::System::ResultStatus::ErrorLoader)) { + LOG_CRITICAL(Frontend, "Failed to load ROM!"); + const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); + const u16 error_id = static_cast<u16>(result) - loader_id; + QMessageBox::critical( + this, tr("Error while loading ROM!"), + QString::fromStdString(fmt::format( + "While attempting to load the ROM requested, an error occured. Please " + "refer to the yuzu wiki for more information or the yuzu discord for " + "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", + loader_id, error_id, Loader::GetMessageForResultStatus(error_id)))); + } else { + QMessageBox::critical( + this, tr("Error while loading ROM!"), + tr("An unknown error occurred. Please see the log for more details.")); + } break; } return false; @@ -579,11 +547,11 @@ void GMainWindow::StoreRecentFile(const QString& filename) { } void GMainWindow::UpdateRecentFiles() { - unsigned int num_recent_files = - std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item)); + const int num_recent_files = + std::min(UISettings::values.recent_files.size(), max_recent_files_item); - for (unsigned int i = 0; i < num_recent_files; i++) { - QString text = QString("&%1. %2").arg(i + 1).arg( + for (int i = 0; i < num_recent_files; i++) { + const QString text = QString("&%1. %2").arg(i + 1).arg( QFileInfo(UISettings::values.recent_files[i]).fileName()); actions_recent_files[i]->setText(text); actions_recent_files[i]->setData(UISettings::values.recent_files[i]); @@ -595,12 +563,8 @@ void GMainWindow::UpdateRecentFiles() { actions_recent_files[j]->setVisible(false); } - // Grey out the recent files menu if the list is empty - if (num_recent_files == 0) { - ui.menu_recent_files->setEnabled(false); - } else { - ui.menu_recent_files->setEnabled(true); - } + // Enable the recent files menu if the list isn't empty + ui.menu_recent_files->setEnabled(num_recent_files != 0); } void GMainWindow::OnGameListLoadFile(QString game_path) { @@ -631,9 +595,15 @@ void GMainWindow::OnMenuLoadFile() { } void GMainWindow::OnMenuLoadFolder() { - QDir dir = QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); + const QString dir_path = + QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); + + if (dir_path.isNull()) { + return; + } - QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); + const QDir dir{dir_path}; + const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); if (matching_main.size() == 1) { BootGame(dir.path() + DIR_SEP + matching_main[0]); } else { @@ -654,9 +624,8 @@ void GMainWindow::OnMenuRecentFile() { QAction* action = qobject_cast<QAction*>(sender()); assert(action); - QString filename = action->data().toString(); - QFileInfo file_info(filename); - if (file_info.exists()) { + const QString filename = action->data().toString(); + if (QFileInfo::exists(filename)) { BootGame(filename); } else { // Display an error message and remove the file from the list. @@ -754,13 +723,14 @@ void GMainWindow::ToggleWindowMode() { } void GMainWindow::OnConfigure() { - ConfigureDialog configureDialog(this); + ConfigureDialog configureDialog(this, hotkey_registry); auto old_theme = UISettings::values.theme; auto result = configureDialog.exec(); if (result == QDialog::Accepted) { configureDialog.applyConfiguration(); if (UISettings::values.theme != old_theme) UpdateUITheme(); + game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); config->Save(); } } @@ -893,7 +863,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) { UISettings::values.first_start = false; game_list->SaveInterfaceLayout(); - SaveHotkeys(); + hotkey_registry.SaveHotkeys(); // Shutdown session if the emu thread is active... if (emu_thread != nullptr) @@ -947,15 +917,14 @@ void GMainWindow::UpdateUITheme() { QStringList theme_paths(default_theme_paths); if (UISettings::values.theme != UISettings::themes[0].second && !UISettings::values.theme.isEmpty()) { - QString theme_uri(":" + UISettings::values.theme + "/style.qss"); + const QString theme_uri(":" + UISettings::values.theme + "/style.qss"); QFile f(theme_uri); - if (!f.exists()) { - LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found"); - } else { - f.open(QFile::ReadOnly | QFile::Text); + if (f.open(QFile::ReadOnly | QFile::Text)) { QTextStream ts(&f); qApp->setStyleSheet(ts.readAll()); GMainWindow::setStyleSheet(ts.readAll()); + } else { + LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found"); } theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme}); QIcon::setThemeName(":/icons/" + UISettings::values.theme); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 074bba3f9..74487c58c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -9,6 +9,7 @@ #include <QTimer> #include "core/core.h" #include "ui_main.h" +#include "yuzu/hotkeys.h" class Config; class EmuThread; @@ -43,7 +44,7 @@ public: void filterBarSetChecked(bool state); void UpdateUITheme(); GMainWindow(); - ~GMainWindow(); + ~GMainWindow() override; signals: @@ -160,6 +161,9 @@ private: bool emulation_running = false; std::unique_ptr<EmuThread> emu_thread; + // FS + FileSys::VirtualFilesystem vfs; + // Debugger panes ProfilerWidget* profilerWidget; MicroProfileDialog* microProfileDialog; @@ -172,6 +176,8 @@ private: // stores default icon theme search paths for the platform QStringList default_theme_paths; + HotkeyRegistry hotkey_registry; + protected: void dropEvent(QDropEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override; diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h index 2286c2559..051494bc5 100644 --- a/src/yuzu/ui_settings.h +++ b/src/yuzu/ui_settings.h @@ -54,6 +54,12 @@ struct Values { // logging bool show_console; + + // Game List + bool show_unknown; + uint32_t icon_size; + uint8_t row_1_text_id; + uint8_t row_2_text_id; }; extern Values values; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 1d835c3c6..d34902109 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -10,7 +10,7 @@ struct SDL_Window; -class EmuWindow_SDL2 : public EmuWindow { +class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { public: explicit EmuWindow_SDL2(bool fullscreen); ~EmuWindow_SDL2(); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index d637dbd0c..e44a98311 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -161,6 +161,7 @@ int main(int argc, char** argv) { } Core::System& system{Core::System::GetInstance()}; + system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); SCOPE_EXIT({ system.Shutdown(); }); @@ -173,19 +174,6 @@ int main(int argc, char** argv) { case Core::System::ResultStatus::ErrorLoader: LOG_CRITICAL(Frontend, "Failed to load ROM!"); return -1; - case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: - LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required " - "could not be found. Please refer to the yuzu wiki for help"); - return -1; - case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: - LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a " - "general error while decrypting. This could mean that the keys are " - "incorrect, game is invalid or game uses an unsupported method of " - "crypto. Please double-check your keys"); - return -1; - case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: - LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); - return -1; case Core::System::ResultStatus::ErrorNotInitialized: LOG_CRITICAL(Frontend, "CPUCore not initialized"); return -1; @@ -197,6 +185,17 @@ int main(int argc, char** argv) { return -1; case Core::System::ResultStatus::Success: break; // Expected case + default: + if (static_cast<u32>(load_result) > + static_cast<u32>(Core::System::ResultStatus::ErrorLoader)) { + const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); + const u16 error_id = static_cast<u16>(load_result) - loader_id; + LOG_CRITICAL(Frontend, + "While attempting to load the ROM requested, an error occured. Please " + "refer to the yuzu wiki for more information or the yuzu discord for " + "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", + loader_id, error_id, Loader::GetMessageForResultStatus(error_id)); + } } Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); |