diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..bb2726e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_size = 4 +indent_style = space + +[{Makefile.am,*.mk}] +indent_size = 8 +indent_style = tab + +[{meson.build,meson_options.txt}] +indent_size = 2 +indent_style = space diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..bde630d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,123 @@ +# vim: set expandtab shiftwidth=2 tabstop=2 textwidth=0: + +variables: + UBUNTU_TAG: "2019-12-05-01" + UBUNTU_VERSION: "18.04" + UBUNTU_CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE/ubuntu/$UBUNTU_VERSION:$UBUNTU_TAG" + UBUNTU_EXEC: "bash .gitlab-ci/ubuntu_install.sh" + +# Include the templates to create an image to run the tests. +include: + - project: 'wayland/ci-templates' + ref: b4b098a707c8f39d18f1a98d4bcbe65372ff9e17 + file: '/templates/ubuntu.yml' + +stages: + - containers-build + - build + +# CONTAINERS creation stage +container_build: + extends: .ubuntu@container-ifnot-exists + stage: containers-build + variables: + GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image + +build-distcheck: + stage: build + image: $UBUNTU_CONTAINER_IMAGE + script: + - bash .gitlab-ci/run_distcheck.sh + artifacts: + paths: + - build/libglvnd-*.tar.gz + +# This is a common definition for testing the other types of dispatch stubs. +# We only need to do these for changes that might affect something specific to +# those stub types. +.build-check: + stage: build + image: $UBUNTU_CONTAINER_IMAGE + only: + changes: + - src/GLdispatch/vnd-glapi/** + - src/util/glvnd_genentry.* + - tests/** + - .gitlab-ci.yml + - .gitlab-ci/** + +.build-check-at: + extends: + - .build-check + script: + - bash .gitlab-ci/run_build.sh + +.build-check-meson: + extends: + - .build-check + script: + - bash .gitlab-ci/run_meson.sh + artifacts: + when: always + paths: + - build/meson-logs/*.txt + +build-i386: + extends: + - .build-check-at + variables: + CONFIGURE_OPTIONS: --build=i686-pc-linux-gnu CFLAGS=-m32 + +build-i386-meson: + extends: + - .build-check-meson + variables: + CONFIGURE_OPTIONS: --cross-file .gitlab-ci/i686-linux-gnu + +build-x86-64-tsd: + extends: + - .build-check-at + variables: + CONFIGURE_OPTIONS: --disable-tls + +build-x86_64-tsd-meson: + extends: + - .build-check-meson + variables: + CONFIGURE_OPTIONS: -Dtls=disabled + +build-i386-tsd: + extends: + - .build-check-at + variables: + CONFIGURE_OPTIONS: --build=i686-pc-linux-gnu CFLAGS=-m32 --disable-tls + +build-i386-tsd-meson: + extends: + - .build-check-meson + variables: + CONFIGURE_OPTIONS: -Dtls=disabled --cross-file .gitlab-ci/i686-linux-gnu + +build-pure-c-tls: + extends: + - .build-check-at + variables: + CONFIGURE_OPTIONS: --disable-asm + +build-pure-c-tls-meson: + extends: + - .build-check-meson + variables: + CONFIGURE_OPTIONS: -Dasm=disabled + +build-pure-c-tsd: + extends: + - .build-check-at + variables: + CONFIGURE_OPTIONS: --disable-asm --disable-tls + +build-pure-c-tld-meson: + extends: + - .build-check-meson + variables: + CONFIGURE_OPTIONS: -Dasm=disabled -Dtls=disabled diff --git a/.gitlab-ci/i686-linux-gnu b/.gitlab-ci/i686-linux-gnu new file mode 100644 index 0000000..4f86880 --- /dev/null +++ b/.gitlab-ci/i686-linux-gnu @@ -0,0 +1,19 @@ +[binaries] +c = '/usr/bin/gcc' +cpp = '/usr/bin/g++' +ar = '/usr/bin/ar' +strip = '/usr/bin/strip' +pkgconfig = '/usr/bin/i686-linux-gnu-pkg-config' + +[properties] +c_args = ['-m32'] +c_link_args = ['-m32'] +cpp_args = ['-m32'] +cpp_link_args = ['-m32'] +needs_exe_wrapper = false + +[host_machine] +system = 'linux' +cpu_family = 'x86' +cpu = 'i686' +endian = 'little' diff --git a/.gitlab-ci/run_build.sh b/.gitlab-ci/run_build.sh new file mode 100644 index 0000000..bab5c9e --- /dev/null +++ b/.gitlab-ci/run_build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e +set -o xtrace + +./autogen.sh + +mkdir build +cd build +../configure --enable-werror $CONFIGURE_OPTIONS + +make V=1 VERBOSE=1 + +xvfb-run --auto-servernum make check V=1 VERBOSE=1 + diff --git a/.gitlab-ci/run_distcheck.sh b/.gitlab-ci/run_distcheck.sh new file mode 100644 index 0000000..692ec07 --- /dev/null +++ b/.gitlab-ci/run_distcheck.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e +set -o xtrace + +./autogen.sh + +mkdir build +cd build +../configure + +xvfb-run --auto-servernum make distcheck V=1 VERBOSE=1 + +# If make distcheck failed don't even bother with the meson check, the tarball +# may be invalid and it's just a waste +if [ $RESULT -ne 0 ]; then + exit $RESULT +fi + +# Also check that the meson build works from the dist tarball + +# We don't have a good way to know what the name of the archive will be (since +# it has the version in it). Therefore, write the tarball to a place we know +# the name of and work from there. +mkdir libglvnd +tar -xf libglvnd-*.tar.gz -C libglvnd --strip-components 1 +pushd libglvnd +meson builddir --auto-features=enabled +xvfb-run --auto-servernum ninja -C builddir test +popd + diff --git a/.gitlab-ci/run_meson.sh b/.gitlab-ci/run_meson.sh new file mode 100644 index 0000000..7ed034d --- /dev/null +++ b/.gitlab-ci/run_meson.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e +set -o xtrace + +# Running a unity build (sometimes called a jumbo build) is both a useful thing +# to test and reduces compile time. +# +# Enable all auto-features to ensure that we're properly testing all optional +# dependencies. +meson build -Dwerror=true --unity=on --auto-features=enabled $CONFIGURE_OPTIONS +ninja -C build + +xvfb-run --auto-servernum ninja -C build test diff --git a/.gitlab-ci/ubuntu_install.sh b/.gitlab-ci/ubuntu_install.sh new file mode 100644 index 0000000..97e374c --- /dev/null +++ b/.gitlab-ci/ubuntu_install.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e +set -o xtrace + +export DEBIAN_FRONTEND=noninteractive + +dpkg --add-architecture i386 + +apt-get update +apt-get install -y --no-remove --no-install-recommends \ + autoconf \ + automake \ + gcc-multilib \ + libtool \ + libx11-dev \ + libx11-dev:i386 \ + libxext-dev \ + libxext-dev:i386 \ + ninja-build \ + pkg-config \ + pkg-config-i686-linux-gnu \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-wheel \ + x11proto-gl-dev \ + xvfb + +# We need a version of meson later than the 0.45 in ubuntu 18.04 +pip3 install meson \ No newline at end of file diff --git a/Makefile.am b/Makefile.am index 44607b1..721e476 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,11 @@ SUBDIRS = src tests include ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = autogen.sh README.md +EXTRA_DIST = \ + autogen.sh \ + README.md \ + bin/symbols-check.py \ + meson.build \ + meson_options.txt pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libglvnd.pc diff --git a/README.md b/README.md index b05d673..f366f68 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ Both GLX and EGL are supported, in any combination with OpenGL and OpenGL ES. libglvnd was originally described in Andy Ritger's OpenGL ABI proposal [1]. +The official repository for libglvnd is hosted on FreeDesktop.org's GitLab: +https://gitlab.freedesktop.org/glvnd/libglvnd + Building the library ---------------------- @@ -24,6 +27,16 @@ On Debian and derivatives, run: Run `./autogen.sh`, then run `./configure` and `make`. +Alternatively you can use meson and ninja, which is much faster but should be +otherwise the same (You will need packages from above too): + + sudo apt-get install ninja-build meson + meson builddir + ninja -C builddir + +Meson 0.48.0 is currently required, if your distro doesn't have meson 0.48 in +the repos you can try the methods suggested +[here](https://mesonbuild.com/Getting-meson.html). Code overview ------------- diff --git a/bin/symbols-check.py b/bin/symbols-check.py new file mode 100644 index 0000000..1548638 --- /dev/null +++ b/bin/symbols-check.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# encoding=utf-8 +# Copyright © 2018-2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +import argparse +import os +import platform +import subprocess + +# This list contains symbols that _might_ be exported for some platforms +PLATFORM_SYMBOLS = [ + '_GLOBAL_OFFSET_TABLE_', + '__bss_end__', + '__bss_start__', + '__bss_start', + '__end__', + '_bss_end__', + '_edata', + '_end', + '_fini', + '_init', +] + + +def get_symbols(nm, lib): + ''' + List all the (non platform-specific) symbols exported by the library + ''' + symbols = [] + platform_name = platform.system() + output = subprocess.check_output([nm, '-gP', lib], + stderr=open(os.devnull, 'w')).decode("ascii") + for line in output.splitlines(): + fields = line.split() + if len(fields) == 2 or fields[1] == 'U': + continue + symbol_name = fields[0] + if platform_name == 'Linux': + if symbol_name in PLATFORM_SYMBOLS: + continue + elif platform_name == 'Darwin': + assert symbol_name[0] == '_' + symbol_name = symbol_name[1:] + symbols.append(symbol_name) + + return symbols + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--symbols-file', + action='store', + required=True, + help='path to file containing symbols') + parser.add_argument('--lib', + action='store', + required=True, + help='path to library') + parser.add_argument('--nm', + action='store', + type=lambda s: s.split()[0], # autotools may pass "nm -B", but we just want nm + required=True, + help='path to binary (or name in $PATH)') + args = parser.parse_args() + + try: + lib_symbols = get_symbols(args.nm, args.lib) + except: + # We can't run this test, but we haven't technically failed it either + # Return the GNU "skip" error code + exit(77) + mandatory_symbols = [] + optional_symbols = [] + with open(args.symbols_file) as symbols_file: + qualifier_optional = '(optional)' + for line in symbols_file.readlines(): + + # Strip comments + line = line.split('#')[0] + line = line.strip() + if not line: + continue + + # Line format: + # [qualifier] symbol + qualifier = None + symbol = None + + fields = line.split() + if len(fields) == 1: + symbol = fields[0] + elif len(fields) == 2: + qualifier = fields[0] + symbol = fields[1] + else: + print(args.symbols_file + ': invalid format: ' + line) + exit(1) + + # The only supported qualifier is 'optional', which means the + # symbol doesn't have to be exported by the library + if qualifier and not qualifier == qualifier_optional: + print(args.symbols_file + ': invalid qualifier: ' + qualifier) + exit(1) + + if qualifier == qualifier_optional: + optional_symbols.append(symbol) + else: + mandatory_symbols.append(symbol) + + unknown_symbols = [] + for symbol in lib_symbols: + if symbol in mandatory_symbols: + continue + if symbol in optional_symbols: + continue + if symbol[:2] == '_Z': + # Ignore random C++ symbols + #TODO: figure out if there's any way to avoid exporting them in the first place + continue + unknown_symbols.append(symbol) + + missing_symbols = [ + sym for sym in mandatory_symbols if sym not in lib_symbols + ] + + for symbol in unknown_symbols: + print(args.lib + ': unknown symbol exported: ' + symbol) + + for symbol in missing_symbols: + print(args.lib + ': missing symbol: ' + symbol) + + if unknown_symbols or missing_symbols: + exit(1) + exit(0) + + +if __name__ == '__main__': + main() diff --git a/configure.ac b/configure.ac index faa0379..1ec9cfc 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl configure.ac dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) -AC_INIT([libglvnd], [1.2.0], [kbrenneman@nvidia.com]) +AC_INIT([libglvnd], [1.3.2], [kbrenneman@nvidia.com]) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_HEADERS([config.h]) @@ -28,6 +28,16 @@ AC_PROG_MAKE_SET AC_PROG_LIBTOOL AC_PROG_MKDIR_P PKG_PROG_PKG_CONFIG +AC_PROG_NM + +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [Build with -Werror @<:@default=disabled@:>@])], + [enable_werror=$enableval], + [enable_werror=no]) +if test "x$enable_werror" = xyes; then + CFLAGS="$CFLAGS -Werror" +fi # The tarball from "make dist" already contains all of the generated files. If # we're building from that, then we won't need Python. @@ -70,13 +80,19 @@ if test "x$enable_x11" != "xyes" -a "x$enable_glx" = "xyes" ; then AC_MSG_ERROR([Can't build GLX without X11.]) fi -AC_ARG_ENABLE([gles], - [AS_HELP_STRING([--disable-gles], - [Do not build the libGLES*.so libraries @<:@default=enabled@:>@])], - [enable_gles="$enableval"], - [enable_gles=yes] -) -AM_CONDITIONAL([ENABLE_GLES], [test "x$enable_gles" = "xyes"]) +AC_ARG_ENABLE([gles1], + [AS_HELP_STRING([--disable-gles1], + [disable support for OpenGL ES 1.x API @<:@default=enabled@:>@])], + [enable_gles1="$enableval"], + [enable_gles1=yes]) +AM_CONDITIONAL([ENABLE_GLES1], [test "x$enable_gles1" = "xyes"]) + +AC_ARG_ENABLE([gles2], + [AS_HELP_STRING([--disable-gles2], + [disable support for OpenGL ES 2.x and 3.x API @<:@default=enabled@:>@])], + [enable_gles2="$enableval"], + [enable_gles2=yes]) +AM_CONDITIONAL([ENABLE_GLES2], [test "x$enable_gles2" = "xyes"]) AC_ARG_ENABLE([headers], [AS_HELP_STRING([--disable-headers], @@ -87,7 +103,8 @@ AC_ARG_ENABLE([headers], AM_CONDITIONAL([ENABLE_GL_HEADERS], [test "x$enable_headers" = "xyes"]) AM_CONDITIONAL([ENABLE_EGL_HEADERS], [test "x$enable_headers" = "xyes" -a "x$enable_egl" = "xyes"]) AM_CONDITIONAL([ENABLE_GLX_HEADERS], [test "x$enable_headers" = "xyes" -a "x$enable_glx" = "xyes"]) -AM_CONDITIONAL([ENABLE_GLES_HEADERS], [test "x$enable_headers" = "xyes" -a "x$enable_gles" = "xyes"]) +AM_CONDITIONAL([ENABLE_GLES1_HEADERS], [test "x$enable_headers" = "xyes" -a "x$enable_gles1" = "xyes"]) +AM_CONDITIONAL([ENABLE_GLES2_HEADERS], [test "x$enable_headers" = "xyes" -a "x$enable_gles2" = "xyes"]) dnl dnl Arch/platform-specific settings. Copied from mesa @@ -129,13 +146,20 @@ if test "x$enable_asm" = xyes; then asm_arch=aarch64 ;; powerpc64le) - asm_arch=ppc64le + asm_arch=ppc64 ;; + powerpc64) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #if !defined(_CALL_ELF) || (_CALL_ELF) == 1 + # error "ELFv1 ABI" + #endif + ])], + [asm_arch=ppc64],[]) esac case "$asm_arch" in x86) - DEFINES="$DEFINES -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM" + DEFINES="$DEFINES -DUSE_X86_ASM" AC_MSG_RESULT([yes, x86]) ;; x86_64) @@ -150,9 +174,9 @@ if test "x$enable_asm" = xyes; then DEFINES="$DEFINES -DUSE_AARCH64_ASM" AC_MSG_RESULT([yes, aarch64]) ;; - ppc64le) - DEFINES="$DEFINES -DUSE_PPC64LE_ASM" - AC_MSG_RESULT([yes, ppc64le]) + ppc64) + DEFINES="$DEFINES -DUSE_PPC64_ASM" + AC_MSG_RESULT([yes, ppc64]) ;; *) AC_MSG_RESULT([no, platform '$host_cpu' not supported]) @@ -232,13 +256,13 @@ xaarch64) gldispatch_entry_type=aarch64_tsd gldispatch_use_tls=no ;; -xppc64le) - # For ppc64le, allow both the TLS and TSD stubs for now. +xppc64) + # For ppc64, allow both the TLS and TSD stubs for now. if test "x$HAVE_INIT_TLS" = "xyes" ; then - gldispatch_entry_type=ppc64le_tls + gldispatch_entry_type=ppc64_tls gldispatch_use_tls=yes else - gldispatch_entry_type=ppc64le_tsd + gldispatch_entry_type=ppc64_tsd gldispatch_use_tls=no fi ;; @@ -258,12 +282,15 @@ AM_CONDITIONAL([GLDISPATCH_TYPE_X86_TLS], [test "x$gldispatch_entry_type" = "xx8 AM_CONDITIONAL([GLDISPATCH_TYPE_X86_TSD], [test "x$gldispatch_entry_type" = "xx86_tsd"]) AM_CONDITIONAL([GLDISPATCH_TYPE_X86_64_TLS], [test "x$gldispatch_entry_type" = "xx86_64_tls"]) AM_CONDITIONAL([GLDISPATCH_TYPE_X86_64_TSD], [test "x$gldispatch_entry_type" = "xx86_64_tsd"]) -AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64LE_TLS], [test "x$gldispatch_entry_type" = "xppc64le_tls"]) -AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64LE_TSD], [test "x$gldispatch_entry_type" = "xppc64le_tsd"]) +AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64_TLS], [test "x$gldispatch_entry_type" = "xppc64_tls"]) +AM_CONDITIONAL([GLDISPATCH_TYPE_PPC64_TSD], [test "x$gldispatch_entry_type" = "xppc64_tsd"]) AM_CONDITIONAL([GLDISPATCH_TYPE_ARMV7_TSD], [test "x$gldispatch_entry_type" = "xarmv7_tsd"]) AM_CONDITIONAL([GLDISPATCH_TYPE_AARCH64_TSD], [test "x$gldispatch_entry_type" = "xaarch64_tsd"]) AM_CONDITIONAL([GLDISPATCH_TYPE_PURE_C], [test "x$gldispatch_entry_type" = "xpure_c"]) +AS_IF([test "x$gldispatch_entry_type" != "xpure_c"], + [AC_DEFINE([USE_DISPATCH_ASM], 1, + [Define to 1 if libGLdispatch and libGLX should use assembly dispatch functions.])]) AC_MSG_CHECKING([for constructor attributes]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ @@ -356,9 +383,13 @@ AS_IF([test "x$GLDISPATCH_PAGE_SIZE" != "x"], [AC_DEFINE_UNQUOTED([GLDISPATCH_PAGE_SIZE], [$GLDISPATCH_PAGE_SIZE], [Page size to align static dispatch stubs.])]) +# Set EGL_NO_X11 unconditionally. Libglvnd doesn't make any assumptions about +# native display or drawable types, so we don't need X11-specific typedefs for +# them. +DEFINES="$DEFINES -DEGL_NO_X11" dnl default CFLAGS -CFLAGS="$CFLAGS -Wall -Werror -include config.h -fvisibility=hidden $DEFINES" +CFLAGS="$CFLAGS -Wall -include config.h -fvisibility=hidden $DEFINES" AC_CONFIG_FILES([Makefile libglvnd.pc diff --git a/include/EGL/egl.h b/include/EGL/egl.h index 40c04df..959f175 100644 --- a/include/EGL/egl.h +++ b/include/EGL/egl.h @@ -33,7 +33,7 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: cb927ca98d $ on $Git commit date: 2019-08-08 01:05:38 -0700 $ +** Khronos $Git commit SHA1: b5409265f3 $ on $Git commit date: 2020-02-20 08:24:34 -0800 $ */ #include @@ -42,7 +42,7 @@ extern "C" { #define EGL_EGL_PROTOTYPES 1 #endif -/* Generated on date 20190808 */ +/* Generated on date 20200220 */ /* Generated C header for: * API: egl diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h index 4e9c0dc..a1e5e94 100644 --- a/include/EGL/eglext.h +++ b/include/EGL/eglext.h @@ -33,12 +33,12 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: cb927ca98d $ on $Git commit date: 2019-08-08 01:05:38 -0700 $ +** Khronos $Git commit SHA1: b5409265f3 $ on $Git commit date: 2020-02-20 08:24:34 -0800 $ */ #include -#define EGL_EGLEXT_VERSION 20190808 +#define EGL_EGLEXT_VERSION 20200220 /* Generated C header for: * API: egl @@ -443,9 +443,9 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, #ifndef EGL_KHR_swap_buffers_with_damage #define EGL_KHR_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_KHR_swap_buffers_with_damage */ @@ -598,6 +598,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_FIXED_SIZE_ANGLE 0x3201 #endif /* EGL_ANGLE_window_fixed_size */ +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + #ifndef EGL_ARM_implicit_external_sync #define EGL_ARM_implicit_external_sync 1 #define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A @@ -917,9 +923,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_EXT_swap_buffers_with_damage */ @@ -1362,6 +1368,40 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + #ifdef __cplusplus } #endif diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h index 29ab288..eaac469 100644 --- a/include/EGL/eglplatform.h +++ b/include/EGL/eglplatform.h @@ -116,6 +116,12 @@ typedef intptr_t EGLNativeDisplayType; typedef intptr_t EGLNativePixmapType; typedef intptr_t EGLNativeWindowType; +#elif defined(__unix__) && defined(EGL_NO_X11) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + #elif defined(__unix__) || defined(USE_X11) /* X11 (tentative) */ @@ -140,6 +146,12 @@ typedef void *EGLNativeDisplayType; typedef khronos_uintptr_t EGLNativePixmapType; typedef khronos_uintptr_t EGLNativeWindowType; +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + #else #error "Platform not recognized" #endif diff --git a/include/GL/gl.h b/include/GL/gl.h index 3f8cb62..2518dfb 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -27,40 +27,24 @@ #ifndef __gl_h_ #define __gl_h_ -#if defined(USE_MGL_NAMESPACE) -#include "gl_mangle.h" -#endif - - /********************************************************************** - * Begin system-specific stuff. Do not do any of this when building - * for SciTech SNAP, as this is all done before this header file is - * included. + * Begin system-specific stuff. */ -#if !defined(__SCITECH_SNAP__) - -#if defined(__BEOS__) -#include /* to get some BeOS-isms */ -#endif - -#if !defined(OPENSTEP) && (defined(NeXT) || defined(NeXT_PDO)) -#define OPENSTEP -#endif #if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) #define __WIN32__ #endif -#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) +#if defined(__WIN32__) && !defined(__CYGWIN__) # if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ # define GLAPI __declspec(dllexport) # elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ # define GLAPI __declspec(dllimport) # else /* for use with static link lib build of Win32 edition only */ # define GLAPI extern -# endif /* _STATIC_MESA support */ +# endif # if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ -# define GLAPIENTRY +# define GLAPIENTRY # else # define GLAPIENTRY __stdcall # endif @@ -72,10 +56,6 @@ # define GLAPIENTRY #endif /* WIN32 && !CYGWIN */ -#if (defined(__BEOS__) && defined(__POWERPC__)) || defined(__QUICKDRAW__) -# define PRAGMA_EXPORT_SUPPORTED 1 -#endif - /* * WINDOWS: Include windows.h here to define APIENTRY. * It is also useful when applications include this file by @@ -91,10 +71,6 @@ #include #endif -#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED -#pragma import on -#endif - #ifndef GLAPI #define GLAPI extern #endif @@ -116,15 +92,6 @@ #define GLAPIENTRYP GLAPIENTRY * #endif -#ifdef CENTERLINE_CLPP -#define signed -#endif - -#if defined(PRAGMA_EXPORT_SUPPORTED) -#pragma export on -#endif - -#endif /* !__SCITECH_SNAP__ */ /* * End system-specific stuff. **********************************************************************/ @@ -718,7 +685,7 @@ typedef double GLclampd; /* double precision float in [0,1] */ #define GL_LIST_BIT 0x00020000 #define GL_TEXTURE_BIT 0x00040000 #define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0x000FFFFF +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF /* OpenGL 1.1 */ @@ -1738,6 +1705,7 @@ GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, + /* * OpenGL 1.3 */ @@ -2085,26 +2053,6 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLsh -#if GL_ARB_shader_objects - -#ifndef GL_MESA_shader_debug -#define GL_MESA_shader_debug 1 - -#define GL_DEBUG_OBJECT_MESA 0x8759 -#define GL_DEBUG_PRINT_MESA 0x875A -#define GL_DEBUG_ASSERT_MESA 0x875B - -GLAPI GLhandleARB GLAPIENTRY glCreateDebugObjectMESA (void); -GLAPI void GLAPIENTRY glClearDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType); -GLAPI void GLAPIENTRY glGetDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType, GLsizei maxLength, - GLsizei *length, GLcharARB *debugLog); -GLAPI GLsizei GLAPIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logType, GLenum shaderType); - -#endif /* GL_MESA_shader_debug */ - -#endif /* GL_ARB_shader_objects */ - - /* * ???. GL_MESA_packed_depth_stencil * XXX obsolete @@ -2121,60 +2069,6 @@ GLAPI GLsizei GLAPIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logTyp #endif /* GL_MESA_packed_depth_stencil */ -#ifndef GL_MESA_program_debug -#define GL_MESA_program_debug 1 - -#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8bb0 -#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8bb1 -#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2 -#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3 -#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8bb4 -#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8bb5 -#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8bb6 -#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8bb7 - -typedef void (*GLprogramcallbackMESA)(GLenum target, GLvoid *data); - -GLAPI void GLAPIENTRY glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, GLvoid *data); - -GLAPI void GLAPIENTRY glGetProgramRegisterfvMESA(GLenum target, GLsizei len, const GLubyte *name, GLfloat *v); - -#endif /* GL_MESA_program_debug */ - - -#ifndef GL_MESA_texture_array -#define GL_MESA_texture_array 1 - -/* GL_MESA_texture_array uses the same enum values as GL_EXT_texture_array. - */ -#ifndef GL_EXT_texture_array - -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferTextureLayerEXT(GLenum target, - GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif /* GL_GLEXT_PROTOTYPES */ - -#if 0 -/* (temporarily) disabled because of collision with typedef in glext.h - * that happens if apps include both gl.h and glext.h - */ -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, - GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif - -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#endif - -#endif - - #ifndef GL_ATI_blend_equation_separate #define GL_ATI_blend_equation_separate 1 @@ -2186,27 +2080,20 @@ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLen #endif /* GL_ATI_blend_equation_separate */ -/** - ** NOTE!!!!! If you add new functions to this file, or update - ** glext.h be sure to regenerate the gl_mangle.h file. See comments - ** in that file for details. - **/ - - - -/********************************************************************** - * Begin system-specific stuff - */ -#if defined(PRAGMA_EXPORT_SUPPORTED) -#pragma export off +/* GL_OES_EGL_image */ +#if !defined(GL_OES_EGL_image) && !defined(GL_EXT_EGL_image_storage) +typedef void* GLeglImageOES; #endif -#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED -#pragma import off +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); #endif -/* - * End system-specific stuff - **********************************************************************/ #ifdef __cplusplus diff --git a/include/GLES3/gl3ext.h b/include/GLES3/gl3ext.h new file mode 100644 index 0000000..484ea17 --- /dev/null +++ b/include/GLES3/gl3ext.h @@ -0,0 +1,9 @@ +#ifndef __gl3ext_h_ +#define __gl3ext_h_ + +/* + * This file is intentionally empty and is provided for source compatibility + * with Mesa. + */ + +#endif /* __gl3ext_h_ */ diff --git a/include/Makefile.am b/include/Makefile.am index 1e33d2d..800ed55 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -17,16 +17,21 @@ GL_HEADER_FILES = \ GL/glext.h \ KHR/khrplatform.h -GLES_HEADER_FILES = \ +GLES1_HEADER_FILES = \ GLES/egl.h \ GLES/gl.h \ GLES/glext.h \ - GLES/glplatform.h \ + GLES/glplatform.h + +GLES2_HEADER_FILES = \ GLES2/gl2ext.h \ GLES2/gl2.h \ - GLES2/gl2platform.h \ + GLES2/gl2platform.h + +GLES3_HEADER_FILES = \ GLES3/gl31.h \ GLES3/gl32.h \ + GLES3/gl3ext.h \ GLES3/gl3.h \ GLES3/gl3platform.h @@ -39,16 +44,24 @@ EGL_HEADER_FILES = \ EGL/eglext.h \ EGL/eglplatform.h -if ENABLE_EGL_HEADERS +if ENABLE_GL_HEADERS nobase_include_HEADERS += $(GL_HEADER_FILES) else noinst_HEADERS += $(GL_HEADER_FILES) endif -if ENABLE_GLES_HEADERS -nobase_include_HEADERS += $(GLES_HEADER_FILES) +if ENABLE_GLES1_HEADERS +nobase_include_HEADERS += $(GLES1_HEADER_FILES) +else +noinst_HEADERS += $(GLES1_HEADER_FILES) +endif + +if ENABLE_GLES2_HEADERS +nobase_include_HEADERS += $(GLES2_HEADER_FILES) +nobase_include_HEADERS += $(GLES3_HEADER_FILES) else -noinst_HEADERS += $(GLES_HEADER_FILES) +noinst_HEADERS += $(GLES2_HEADER_FILES) +noinst_HEADERS += $(GLES3_HEADER_FILES) endif if ENABLE_GLX_HEADERS @@ -63,3 +76,4 @@ else noinst_HEADERS += $(EGL_HEADER_FILES) endif +EXTRA_DIST = meson.build \ No newline at end of file diff --git a/include/glvnd/GLdispatchABI.h b/include/glvnd/GLdispatchABI.h index fdbbe71..8b8a689 100644 --- a/include/glvnd/GLdispatchABI.h +++ b/include/glvnd/GLdispatchABI.h @@ -95,9 +95,14 @@ enum { __GLDISPATCH_STUB_X32, /*! - * Used for stubs on PPC64LE systems. + * Used for stubs on PPC64 systems. */ - __GLDISPATCH_STUB_PPC64LE, + __GLDISPATCH_STUB_PPC64, + + /*! + * Used for stubs on PPC64LE systems. Same as PPC64, for compatibility. + */ + __GLDISPATCH_STUB_PPC64LE = __GLDISPATCH_STUB_PPC64, }; /*! diff --git a/include/meson.build b/include/meson.build new file mode 100644 index 0000000..4f329c4 --- /dev/null +++ b/include/meson.build @@ -0,0 +1,96 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +inc_include = include_directories('.') + +install_headers( + 'glvnd/GLdispatchABI.h', + 'glvnd/libglxabi.h', + 'glvnd/libeglabi.h', + subdir : 'glvnd' +) + +_headers = get_option('headers') + +if _headers + install_headers( + 'GL/gl.h', + 'GL/glcorearb.h', + 'GL/glext.h', + subdir : 'GL', + ) + + install_headers( + 'KHR/khrplatform.h', + subdir : 'KHR', + ) +endif + +if with_glx and _headers + install_headers( + 'GL/glx.h', + 'GL/glxext.h', + subdir : 'GL', + ) +endif + +if get_option('gles1') and _headers + install_headers( + 'GLES/egl.h', + 'GLES/gl.h', + 'GLES/glext.h', + 'GLES/glplatform.h', + subdir : 'GLES' + ) +endif + +if get_option('gles2') and _headers + install_headers( + 'GLES2/gl2ext.h', + 'GLES2/gl2.h', + 'GLES2/gl2platform.h', + subdir : 'GLES2', + ) + install_headers( + 'GLES3/gl31.h', + 'GLES3/gl32.h', + 'GLES3/gl3.h', + 'GLES3/gl3ext.h', + 'GLES3/gl3platform.h', + subdir : 'GLES3', + ) +endif + +if get_option('egl') and _headers + install_headers( + 'EGL/egl.h', + 'EGL/eglext.h', + 'EGL/eglplatform.h', + subdir : 'EGL', + ) +endif + diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..f521575 --- /dev/null +++ b/meson.build @@ -0,0 +1,216 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +project( + 'glvnd', + 'c', + version : '1.3.2', + meson_version : '>= 0.48', + default_options : ['c_std=gnu99'] +) + +dep_null = dependency('', required : false) +cc = meson.get_compiler('c') +prog_py = import('python').find_installation() +files_symbols_check = files('bin/symbols-check.py') +prog_nm = find_program('nm') + +message('Host CPU family: @0@'.format(host_machine.cpu_family())) +message('Host CPU: @0@'.format(host_machine.cpu())) + +with_asm = get_option('asm') +use_asm = false +if not with_asm.disabled() + use_asm = true + if (host_machine.cpu_family() == 'x86' and + ['gnu', 'freebsd', 'dragonfly', 'linux', + 'netbsd'].contains(host_machine.system())) + add_project_arguments('-DUSE_X86_ASM', language : 'c') + elif (host_machine.cpu_family() == 'x86_64' and + ['freebsd', 'dragonfly', 'linux', + 'netbsd'].contains(host_machine.system())) + add_project_arguments('-DUSE_X86_64_ASM', language : 'c') + elif host_machine.cpu_family() == 'arm' + # Try to figure out if we're targeting an ARMv7 or something older like + # armel. Note that host_machine.cpu() won't help here -- it might still + # return "armv7l" or "armv8l". Instead, try checking for compiler macros. + if ['gcc', 'clang'].contains(cc.get_id()) + is_armv7 = cc.compiles(''' +#if !(defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7S__) \ + || (defined(__ARM_ARCH) && __ARM_ARCH >= 7)) +#error "Not ARM7" +#endif + ''', name : 'ARMv7 macros') + else + is_armv7 = true + endif + if is_armv7 + add_project_arguments('-DUSE_ARMV7_ASM', language : 'c') + else + use_asm = false + endif + elif host_machine.cpu_family() == 'aarch64' + add_project_arguments('-DUSE_AARCH64_ASM', language : 'c') + elif host_machine.cpu_family() == 'ppc64' and cc.get_define('_CALL_ELF') == '2' + add_project_arguments('-DUSE_PPC64_ASM', language : 'c') + elif with_asm.enabled() + error('No ASM available for @0@ (@1@ endian)'.format(host_machine.system(), host_machine.endian())) + else + use_asm = false + endif +endif + +if use_asm + add_project_arguments('-DUSE_DISPATCH_ASM', language : 'c') +endif + +dep_dl = cc.find_library('dl', required : false) +dep_m = cc.find_library('m', required : false) +dep_threads = dependency('threads') +dep_x11 = dependency('x11', required : get_option('x11')) +dep_x11_headers = dep_x11.partial_dependency(compile_args : true, includes : true) +if dep_x11.found() + add_project_arguments('-DUSE_X11', language : ['c']) +endif + +dep_xext = dep_null +dep_glproto = dep_null +with_glx = false +if get_option('glx').enabled() and not dep_x11.found() + error('Cannot build GLX support without X11.') +elif not get_option('glx').disabled() and dep_x11.found() + dep_xext = dependency('xext', required : get_option('glx')) + dep_glproto = dependency('glproto', required : get_option('glx')) + with_glx = true +endif +dep_glx = [dep_xext, dep_glproto] + +if cc.compiles('typeof(int *);', name : 'typeof') + add_project_arguments('-DHAVE_TYPEOF', language : ['c']) +endif + +with_tls = get_option('tls') +have_tls = false +if not with_tls.disabled() + have_tls = cc.compiles( + '__thread int foo __attribute__((tls_model("initial-exec")));', + name : 'initial-exec TLS', + ) +endif + +if have_tls + add_project_arguments('-DGLDISPATCH_USE_TLS', language : ['c']) +endif + +gl_dispatch_type = 'pure_c' +if use_asm + if host_machine.cpu_family().startswith('x86') + gl_dispatch_type = '@0@_@1@'.format( + host_machine.cpu_family(), + have_tls ? 'tls' : 'tsd', + ) + elif host_machine.cpu_family() == 'arm' + gl_dispatch_type = 'armv7_tsd' + elif host_machine.cpu_family() == 'aarch64' + gl_dispatch_type = 'aarch64_tsd' + elif host_machine.cpu_family() == 'ppc64' + gl_dispatch_type = 'ppc64_@0@'.format(have_tls ? 'tls' : 'tsd') + endif +endif +message('Using dispatch stub type: @0@'.format(gl_dispatch_type)) + +if cc.has_function_attribute('constructor') + add_project_arguments('-DUSE_ATTRIBUTE_CONSTRUCTOR', language : ['c']) +endif + +if cc.compiles(''' + #include + void foo(void) + { + pthread_rwlock_t lock; + pthread_rwlock_init(&lock, NULL); + }''', + name : 'pthread rwlock') + add_project_arguments('-DHAVE_PTHREAD_RWLOCK', language : ['c']) +endif + +if cc.compiles(''' + int foo(int volatile *val, int oldVal, int newVal) + { + return __sync_add_and_fetch(val, 1); + return __sync_lock_test_and_set(val, newVal); + return __sync_val_compare_and_swap(val, oldVal, newVal); + }''', + name : 'sync intrinsics') + add_project_arguments('-DHAVE_SYNC_INTRINSICS', language : ['c']) +endif + +if cc.has_function('mincore') + add_project_arguments('-DHAVE_MINCORE', language : ['c']) +endif + +if cc.has_header_symbol('dlfcn.h', 'RTLD_NOLOAD') + add_project_arguments('-DHAVE_RTLD_NOLOAD', language : ['c']) +endif + +if cc.has_member('struct dirent', 'd_type', prefix : '#include ') + add_project_arguments('-DHAVE_DIRENT_DTYPE', language : ['c']) +endif + +_p = get_option('dispatch-page-size') +if _p != 0 + add_project_arguments('-DGLDISPATCH_PAGE_SIZE=' + _p, language : ['c']) +endif + +# Set EGL_NO_X11 unconditionally, Libglvnd doesn't make any assumptions about +# native display or drawable types, so we don't need X11-specific typedefs for +# them +add_project_arguments('-DEGL_NO_X11', language : ['c']) + +pkg = import('pkgconfig') + +subdir('include') +subdir('src') +subdir('tests') + +pkg.generate( + name : 'libglvnd', + description : 'Vendor-neutral OpenGL dispatch library vendor interface', + version : meson.project_version(), + variables : [ + # Drivers can use these to know where to install the JSON files to tell + # libglvnd to load them. Meson doesn't have a separate datarootdir option, + # so juse use datadir for both of these. + 'datarootdir=${prefix}/' + get_option('datadir'), + 'datadir=${prefix}/' + get_option('datadir'), + ] +) + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..8275770 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,77 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +option( + 'asm', + type : 'feature', + description : 'Use ASM when compiling.' +) +option( + 'x11', + type : 'feature', + description : 'Support the X11 window system.' +) +option( + 'egl', + type : 'boolean', + value : true, + description : 'Support the EGL platform.' +) +option( + 'glx', + type : 'feature', + description : 'Support the GLX platform.' +) +option( + 'gles1', + type : 'boolean', + value : true, + description : 'Support OpenGL ES 1.x.' +) +option( + 'gles2', + type : 'boolean', + value : true, + description : 'Support OpenGL ES 2.x and 3.x.' +) +option( + 'tls', + type : 'feature', + description : 'Use Thread Local Storage.' +) +option( + 'dispatch-page-size', + type : 'integer', + value : 0, + description : 'Page size to align static dispatch stubs.' +) +option( + 'headers', + type : 'boolean', + value : true, + description : 'Install headers for enabled APIs.' +) diff --git a/src/EGL/Makefile.am b/src/EGL/Makefile.am index 5bb7902..6e35da2 100644 --- a/src/EGL/Makefile.am +++ b/src/EGL/Makefile.am @@ -95,10 +95,10 @@ CLEANFILES = $(BUILT_SOURCES) GENERATE_DISPATCH_SCRIPT = $(top_srcdir)/src/generate/gen_egl_dispatch.py GENERATE_LIST_FILES = \ - $(top_srcdir)/src/generate/eglFunctionList.py \ $(top_srcdir)/src/generate/xml/egl.xml GENERATE_DEPS = \ + $(top_srcdir)/src/generate/eglFunctionList.py \ $(top_srcdir)/src/generate/genCommon.py \ $(GENERATE_DISPATCH_SCRIPT) \ $(GENERATE_LIST_FILES) @@ -110,5 +110,18 @@ g_egldispatchstubs.h : $(GENERATE_DEPS) $(AM_V_GEN)$(PYTHON) $(GENERATE_DISPATCH_SCRIPT) header $(GENERATE_LIST_FILES) > $@ endif +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = egl-symbol-check.sh + +EXTRA_DIST = \ + egl-symbol-check.sh \ + egl.symbols \ + meson.build + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = egl.pc + diff --git a/src/EGL/egl-symbol-check.sh b/src/EGL/egl-symbol-check.sh new file mode 100755 index 0000000..35eb2ac --- /dev/null +++ b/src/EGL/egl-symbol-check.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test "${PYTHON}" = ":" && exit 77 +test "x${NM}" = "x" && exit 77 + +exec "${PYTHON}" "${TOP_SRCDIR}/bin/symbols-check.py" \ + --nm "${NM}" \ + --lib "${TOP_BUILDDIR}/src/EGL/.libs/libEGL.so" \ + --symbols-file "${TOP_SRCDIR}/src/EGL/egl.symbols" diff --git a/src/EGL/egl.symbols b/src/EGL/egl.symbols new file mode 100644 index 0000000..f1e71bd --- /dev/null +++ b/src/EGL/egl.symbols @@ -0,0 +1,44 @@ +eglBindAPI +eglBindTexImage +eglChooseConfig +eglClientWaitSync +eglCopyBuffers +eglCreateContext +eglCreateImage +eglCreatePbufferFromClientBuffer +eglCreatePbufferSurface +eglCreatePixmapSurface +eglCreatePlatformPixmapSurface +eglCreatePlatformWindowSurface +eglCreateSync +eglCreateWindowSurface +eglDestroyContext +eglDestroyImage +eglDestroySurface +eglDestroySync +eglGetConfigAttrib +eglGetConfigs +eglGetCurrentContext +eglGetCurrentDisplay +eglGetCurrentSurface +eglGetDisplay +eglGetError +eglGetPlatformDisplay +eglGetProcAddress +eglGetSyncAttrib +eglInitialize +eglMakeCurrent +eglQueryAPI +eglQueryContext +eglQueryString +eglQuerySurface +eglReleaseTexImage +eglReleaseThread +eglSurfaceAttrib +eglSwapBuffers +eglSwapInterval +eglTerminate +eglWaitClient +eglWaitGL +eglWaitNative +eglWaitSync diff --git a/src/EGL/meson.build b/src/EGL/meson.build new file mode 100644 index 0000000..363bd3b --- /dev/null +++ b/src/EGL/meson.build @@ -0,0 +1,78 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libegl_dispatch_stubs = static_library( + 'egl_dispatch_stubs', + ['egldispatchstubs.c', g_egldispatchstubs_c, g_egldispatchstubs_h], + include_directories : inc_include, + gnu_symbol_visibility : 'hidden', +) + +libEGL = shared_library( + 'EGL', + [ + 'libegl.c', + 'libeglcurrent.c', + 'libeglmapping.c', + 'libeglvendor.c', + 'libeglerror.c', + ], + c_args : [ + '-DDEFAULT_EGL_VENDOR_CONFIG_DIRS="@0@/glvnd/egl_vendor.d:@1@/glvnd/egl_vendor.d"'.format( + join_paths(get_option('prefix'), get_option('sysconfdir')), + join_paths(get_option('prefix'), get_option('datadir'))), + ], + include_directories : inc_include, + link_args : '-Wl,-Bsymbolic', + link_with : libegl_dispatch_stubs, + dependencies : [ + dep_threads, dep_dl, dep_m, dep_x11_headers, idep_trace, idep_glvnd_pthread, + idep_utils_misc, idep_cjson, idep_winsys_dispatch, idep_gldispatch, + ], + version : '1.1.0', + install : true, + gnu_symbol_visibility : 'hidden', +) + +pkg.generate( + libEGL, + filebase : 'egl', + description : 'EGL library and headers', + version : '1.5', +) + +test( + 'EGL symbols check', + prog_py, + args : [ + files_symbols_check, + '--nm', prog_nm.path(), + '--lib', libEGL, + '--symbols-file', files('egl.symbols'), + ], + suite : ['egl', 'symbols'], +) diff --git a/src/GL/Makefile.am b/src/GL/Makefile.am index 225fdcb..36788f6 100644 --- a/src/GL/Makefile.am +++ b/src/GL/Makefile.am @@ -54,6 +54,13 @@ g_libglglxwrapper.c : $(glapi_gen_libglglxstubs_deps) $(AM_V_GEN)$(PYTHON) $(PYTHON_FLAGS) $(glapi_gen_libglglxstubs_script) $(glapi_gen_glx_xml) > $@ endif +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = gl-symbol-check.sh + libGL_la_CFLAGS = \ -I$(top_srcdir)/include @@ -73,3 +80,8 @@ libGL_la_LIBADD += @LIB_DL@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gl.pc + +EXTRA_DIST = \ + gl-symbol-check.sh \ + gl.symbols \ + meson.build diff --git a/src/GL/gl-symbol-check.sh b/src/GL/gl-symbol-check.sh new file mode 100755 index 0000000..1ebb5e3 --- /dev/null +++ b/src/GL/gl-symbol-check.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test "${PYTHON}" = ":" && exit 77 +test "x${NM}" = "x" && exit 77 + +exec "${PYTHON}" "${TOP_SRCDIR}/bin/symbols-check.py" \ + --nm "${NM}" \ + --lib "${TOP_BUILDDIR}/src/GL/.libs/libGL.so" \ + --symbols-file "${TOP_SRCDIR}/src/GL/gl.symbols" diff --git a/src/GL/gl.symbols b/src/GL/gl.symbols new file mode 100644 index 0000000..d3e3979 --- /dev/null +++ b/src/GL/gl.symbols @@ -0,0 +1,3470 @@ +glAccum +glAccumxOES +glAcquireKeyedMutexWin32EXT +glActiveProgramEXT +glActiveShaderProgram +glActiveShaderProgramEXT +glActiveStencilFaceEXT +glActiveTexture +glActiveTextureARB +glActiveVaryingNV +glAlphaFragmentOp1ATI +glAlphaFragmentOp2ATI +glAlphaFragmentOp3ATI +glAlphaFunc +glAlphaFuncQCOM +glAlphaFuncx +glAlphaFuncxOES +glAlphaToCoverageDitherControlNV +glApplyFramebufferAttachmentCMAAINTEL +glApplyTextureEXT +glAreProgramsResidentNV +glAreTexturesResident +glAreTexturesResidentEXT +glArrayElement +glArrayElementEXT +glArrayObjectATI +glAsyncCopyBufferSubDataNVX +glAsyncCopyImageSubDataNVX +glAsyncMarkerSGIX +glAttachObjectARB +glAttachShader +glBegin +glBeginConditionalRender +glBeginConditionalRenderNV +glBeginConditionalRenderNVX +glBeginFragmentShaderATI +glBeginOcclusionQueryNV +glBeginPerfMonitorAMD +glBeginPerfQueryINTEL +glBeginQuery +glBeginQueryARB +glBeginQueryEXT +glBeginQueryIndexed +glBeginTransformFeedback +glBeginTransformFeedbackEXT +glBeginTransformFeedbackNV +glBeginVertexShaderEXT +glBeginVideoCaptureNV +glBindANCCaptureStreamBufferNVX +glBindAttribLocation +glBindAttribLocationARB +glBindBuffer +glBindBufferARB +glBindBufferBase +glBindBufferBaseEXT +glBindBufferBaseNV +glBindBufferOffsetEXT +glBindBufferOffsetNV +glBindBufferRange +glBindBufferRangeEXT +glBindBufferRangeNV +glBindBuffersBase +glBindBuffersRange +glBindFragDataLocation +glBindFragDataLocationEXT +glBindFragDataLocationIndexed +glBindFragDataLocationIndexedEXT +glBindFragmentShaderATI +glBindFramebuffer +glBindFramebufferEXT +glBindFramebufferOES +glBindImageTexture +glBindImageTextureEXT +glBindImageTextures +glBindLightParameterEXT +glBindMaterialParameterEXT +glBindMultiTextureEXT +glBindParameterEXT +glBindProgramARB +glBindProgramNV +glBindProgramPipeline +glBindProgramPipelineEXT +glBindRenderbuffer +glBindRenderbufferEXT +glBindRenderbufferOES +glBindSampler +glBindSamplers +glBindShadingRateImageNV +glBindTexGenParameterEXT +glBindTexture +glBindTextureEXT +glBindTextures +glBindTextureUnit +glBindTextureUnitParameterEXT +glBindTransformFeedback +glBindTransformFeedbackEXT +glBindTransformFeedbackNV +glBindVertexArray +glBindVertexArrayAPPLE +glBindVertexArrayOES +glBindVertexBuffer +glBindVertexBuffers +glBindVertexShaderEXT +glBindVideoCaptureStreamBufferNV +glBindVideoCaptureStreamTextureNV +glBinormal3bEXT +glBinormal3bvEXT +glBinormal3dEXT +glBinormal3dvEXT +glBinormal3fEXT +glBinormal3fvEXT +glBinormal3iEXT +glBinormal3ivEXT +glBinormal3sEXT +glBinormal3svEXT +glBinormalPointerEXT +glBitmap +glBitmapxOES +glBlendBarrier +glBlendBarrierKHR +glBlendBarrierNV +glBlendColor +glBlendColorEXT +glBlendColorxOES +glBlendEquation +glBlendEquationEXT +glBlendEquationi +glBlendEquationiARB +glBlendEquationiEXT +glBlendEquationIndexedAMD +glBlendEquationiOES +glBlendEquationOES +glBlendEquationSeparate +glBlendEquationSeparateEXT +glBlendEquationSeparatei +glBlendEquationSeparateiARB +glBlendEquationSeparateiEXT +glBlendEquationSeparateIndexedAMD +glBlendEquationSeparateiOES +glBlendEquationSeparateOES +glBlendFunc +glBlendFunci +glBlendFunciARB +glBlendFunciEXT +glBlendFuncIndexedAMD +glBlendFunciOES +glBlendFuncSeparate +glBlendFuncSeparateEXT +glBlendFuncSeparatei +glBlendFuncSeparateiARB +glBlendFuncSeparateiEXT +glBlendFuncSeparateIndexedAMD +glBlendFuncSeparateINGR +glBlendFuncSeparateiOES +glBlendFuncSeparateOES +glBlendParameteriNV +glBlitFramebuffer +glBlitFramebufferANGLE +glBlitFramebufferEXT +glBlitFramebufferNV +glBlitNamedFramebuffer +glBufferAddressRangeNV +glBufferAttachMemoryNV +glBufferData +glBufferDataARB +glBufferDataSysmem +glBufferPageCommitmentARB +glBufferParameteriAPPLE +glBufferStorage +glBufferStorageEXT +glBufferStorageExternalEXT +glBufferStorageMemEXT +glBufferSubData +glBufferSubDataARB +glCallCommandListNV +glCallList +glCallLists +glCheckFramebufferStatus +glCheckFramebufferStatusEXT +glCheckFramebufferStatusOES +glCheckNamedFramebufferStatus +glCheckNamedFramebufferStatusEXT +glClampColor +glClampColorARB +glClear +glClearAccum +glClearAccumxOES +glClearBufferData +glClearBufferfi +glClearBufferfv +glClearBufferiv +glClearBufferSubData +glClearBufferuiv +glClearColor +glClearColorIiEXT +glClearColorIuiEXT +glClearColorx +glClearColorxOES +glClearDepth +glClearDepthdNV +glClearDepthf +glClearDepthfOES +glClearDepthx +glClearDepthxOES +glClearIndex +glClearNamedBufferData +glClearNamedBufferDataEXT +glClearNamedBufferSubData +glClearNamedBufferSubDataEXT +glClearNamedFramebufferfi +glClearNamedFramebufferfv +glClearNamedFramebufferiv +glClearNamedFramebufferuiv +glClearPixelLocalStorageuiEXT +glClearStencil +glClearTexImage +glClearTexImageEXT +glClearTexSubImage +glClearTexSubImageEXT +glClientActiveTexture +glClientActiveTextureARB +glClientActiveVertexStreamATI +glClientAttribDefaultEXT +glClientWaitSemaphoreui64NVX +glClientWaitSync +glClientWaitSyncAPPLE +glClientWaitSyncValueuiNVX +glClipControl +glClipControlEXT +glClipPlane +glClipPlanef +glClipPlanefIMG +glClipPlanefOES +glClipPlanex +glClipPlanexIMG +glClipPlanexOES +glColor3b +glColor3bv +glColor3d +glColor3dv +glColor3f +glColor3fv +glColor3fVertex3fSUN +glColor3fVertex3fvSUN +glColor3hNV +glColor3hvNV +glColor3i +glColor3iv +glColor3s +glColor3sv +glColor3ub +glColor3ubv +glColor3ui +glColor3uiv +glColor3us +glColor3usv +glColor3x +glColor3xOES +glColor3xvOES +glColor4b +glColor4bv +glColor4d +glColor4dv +glColor4f +glColor4fNormal3fVertex3fSUN +glColor4fNormal3fVertex3fvSUN +glColor4fv +glColor4hNV +glColor4hvNV +glColor4i +glColor4iv +glColor4s +glColor4sv +glColor4ub +glColor4ubv +glColor4ubVertex2fSUN +glColor4ubVertex2fvSUN +glColor4ubVertex3fSUN +glColor4ubVertex3fvSUN +glColor4ui +glColor4uiv +glColor4us +glColor4usv +glColor4x +glColor4xOES +glColor4xvOES +glColorFormatNV +glColorFragmentOp1ATI +glColorFragmentOp2ATI +glColorFragmentOp3ATI +glColorMask +glColorMaski +glColorMaskiEXT +glColorMaskIndexedEXT +glColorMaskiOES +glColorMaterial +glColorP3ui +glColorP3uiv +glColorP4ui +glColorP4uiv +glColorPointer +glColorPointerEXT +glColorPointerListIBM +glColorPointervINTEL +glColorSubTable +glColorSubTableEXT +glColorTable +glColorTableEXT +glColorTableParameterfv +glColorTableParameterfvSGI +glColorTableParameteriv +glColorTableParameterivSGI +glColorTableSGI +glCombinerInputNV +glCombinerOutputNV +glCombinerParameterfNV +glCombinerParameterfvNV +glCombinerParameteriNV +glCombinerParameterivNV +glCombinerStageParameterfvNV +glCommandListSegmentsNV +glCompileCommandListNV +glCompileShader +glCompileShaderARB +glCompileShaderIncludeARB +glCompressedMultiTexImage1DEXT +glCompressedMultiTexImage2DEXT +glCompressedMultiTexImage3DEXT +glCompressedMultiTexSubImage1DEXT +glCompressedMultiTexSubImage2DEXT +glCompressedMultiTexSubImage3DEXT +glCompressedTexImage1D +glCompressedTexImage1DARB +glCompressedTexImage2D +glCompressedTexImage2DARB +glCompressedTexImage3D +glCompressedTexImage3DARB +glCompressedTexImage3DNV +glCompressedTexImage3DOES +glCompressedTexSubImage1D +glCompressedTexSubImage1DARB +glCompressedTexSubImage2D +glCompressedTexSubImage2DARB +glCompressedTexSubImage3D +glCompressedTexSubImage3DARB +glCompressedTexSubImage3DNV +glCompressedTexSubImage3DOES +glCompressedTextureImage1DEXT +glCompressedTextureImage2DEXT +glCompressedTextureImage3DEXT +glCompressedTextureSubImage1D +glCompressedTextureSubImage1DEXT +glCompressedTextureSubImage2D +glCompressedTextureSubImage2DEXT +glCompressedTextureSubImage3D +glCompressedTextureSubImage3DEXT +glConservativeRasterParameterfNV +glConservativeRasterParameteriNV +glConvolutionFilter1D +glConvolutionFilter1DEXT +glConvolutionFilter2D +glConvolutionFilter2DEXT +glConvolutionParameterf +glConvolutionParameterfEXT +glConvolutionParameterfv +glConvolutionParameterfvEXT +glConvolutionParameteri +glConvolutionParameteriEXT +glConvolutionParameteriv +glConvolutionParameterivEXT +glConvolutionParameterxOES +glConvolutionParameterxvOES +glCopyBufferSubData +glCopyBufferSubDataNV +glCopyColorSubTable +glCopyColorSubTableEXT +glCopyColorTable +glCopyColorTableSGI +glCopyConvolutionFilter1D +glCopyConvolutionFilter1DEXT +glCopyConvolutionFilter2D +glCopyConvolutionFilter2DEXT +glCopyImageSubData +glCopyImageSubDataEXT +glCopyImageSubDataNV +glCopyImageSubDataOES +glCopyMultiTexImage1DEXT +glCopyMultiTexImage2DEXT +glCopyMultiTexSubImage1DEXT +glCopyMultiTexSubImage2DEXT +glCopyMultiTexSubImage3DEXT +glCopyNamedBufferSubData +glCopyPathNV +glCopyPixels +glCopyTexImage1D +glCopyTexImage1DEXT +glCopyTexImage2D +glCopyTexImage2DEXT +glCopyTexSubImage1D +glCopyTexSubImage1DEXT +glCopyTexSubImage2D +glCopyTexSubImage2DEXT +glCopyTexSubImage3D +glCopyTexSubImage3DEXT +glCopyTexSubImage3DNV +glCopyTexSubImage3DOES +glCopyTextureImage1DEXT +glCopyTextureImage2DEXT +glCopyTextureLevelsAPPLE +glCopyTextureSubImage1D +glCopyTextureSubImage1DEXT +glCopyTextureSubImage2D +glCopyTextureSubImage2DEXT +glCopyTextureSubImage3D +glCopyTextureSubImage3DEXT +glCoverageMaskNV +glCoverageModulationNV +glCoverageModulationTableNV +glCoverageOperationNV +glCoverFillPathInstancedNV +glCoverFillPathNV +glCoverStrokePathInstancedNV +glCoverStrokePathNV +glCreateBuffers +glCreateCommandListsNV +glCreateFramebuffers +glCreateMemoryObjectsEXT +glCreatePerfQueryINTEL +glCreateProgram +glCreateProgramObjectARB +glCreateProgramPipelines +glCreateProgressFenceNVX +glCreateQueries +glCreateRenderbuffers +glCreateSamplers +glCreateShader +glCreateShaderObjectARB +glCreateShaderProgramEXT +glCreateShaderProgramv +glCreateShaderProgramvEXT +glCreateStatesNV +glCreateSyncFromCLeventARB +glCreateTextures +glCreateTransformFeedbacks +glCreateVertexArrays +glCullFace +glCullParameterdvEXT +glCullParameterfvEXT +glCurrentPaletteMatrixARB +glCurrentPaletteMatrixOES +glDebugMessageCallback +glDebugMessageCallbackAMD +glDebugMessageCallbackARB +glDebugMessageCallbackKHR +glDebugMessageCallbackOES +glDebugMessageControl +glDebugMessageControlARB +glDebugMessageControlKHR +glDebugMessageControlOES +glDebugMessageEnableAMD +glDebugMessageInsert +glDebugMessageInsertAMD +glDebugMessageInsertARB +glDebugMessageInsertKHR +glDebugMessageInsertOES +glDeformationMap3dSGIX +glDeformationMap3fSGIX +glDeformSGIX +glDeleteAsyncMarkersSGIX +glDeleteBuffers +glDeleteBuffersARB +glDeleteCommandListsNV +glDeleteFencesAPPLE +glDeleteFencesNV +glDeleteFragmentShaderATI +glDeleteFramebuffers +glDeleteFramebuffersEXT +glDeleteFramebuffersOES +glDeleteLists +glDeleteMemoryObjectsEXT +glDeleteNamedStringARB +glDeleteNamesAMD +glDeleteObjectARB +glDeleteOcclusionQueriesNV +glDeletePathsNV +glDeletePerfMonitorsAMD +glDeletePerfQueryINTEL +glDeleteProgram +glDeleteProgramPipelines +glDeleteProgramPipelinesEXT +glDeleteProgramsARB +glDeleteProgramsNV +glDeleteQueries +glDeleteQueriesARB +glDeleteQueriesEXT +glDeleteQueryResourceTagNV +glDeleteRenderbuffers +glDeleteRenderbuffersEXT +glDeleteRenderbuffersOES +glDeleteSamplers +glDeleteSemaphoresEXT +glDeleteShader +glDeleteStatesNV +glDeleteSync +glDeleteSyncAPPLE +glDeleteTextures +glDeleteTexturesEXT +glDeleteTransformFeedbacks +glDeleteTransformFeedbacksEXT +glDeleteTransformFeedbacksNV +glDeleteVertexArrays +glDeleteVertexArraysAPPLE +glDeleteVertexArraysOES +glDeleteVertexShaderEXT +glDepthBoundsdNV +glDepthBoundsEXT +glDepthFunc +glDepthMask +glDepthRange +glDepthRangeArraydvNV +glDepthRangeArrayfvNV +glDepthRangeArrayfvOES +glDepthRangeArrayv +glDepthRangedNV +glDepthRangef +glDepthRangefOES +glDepthRangeIndexed +glDepthRangeIndexeddNV +glDepthRangeIndexedfNV +glDepthRangeIndexedfOES +glDepthRangex +glDepthRangexOES +glDetachObjectARB +glDetachShader +glDetailTexFuncSGIS +glDevtoolsCorrelationIdNVX +glDevtoolsInvokeStreamedCallbackNVX +glDisable +glDisableClientState +glDisableClientStateiEXT +glDisableClientStateIndexedEXT +glDisableDriverControlQCOM +glDisablei +glDisableiEXT +glDisableIndexedEXT +glDisableiNV +glDisableiOES +glDisableVariantClientStateEXT +glDisableVertexArrayAttrib +glDisableVertexArrayAttribEXT +glDisableVertexArrayEXT +glDisableVertexAttribAPPLE +glDisableVertexAttribArray +glDisableVertexAttribArrayARB +glDiscardFramebufferEXT +glDispatchCompute +glDispatchComputeGroupSizeARB +glDispatchComputeIndirect +glDrawArrays +glDrawArraysEXT +glDrawArraysIndirect +glDrawArraysInstanced +glDrawArraysInstancedANGLE +glDrawArraysInstancedARB +glDrawArraysInstancedBaseInstance +glDrawArraysInstancedBaseInstanceEXT +glDrawArraysInstancedEXT +glDrawArraysInstancedNV +glDrawBuffer +glDrawBuffers +glDrawBuffersARB +glDrawBuffersATI +glDrawBuffersEXT +glDrawBuffersIndexedEXT +glDrawBuffersNV +glDrawCommandsAddressNV +glDrawCommandsNV +glDrawCommandsStatesAddressNV +glDrawCommandsStatesNV +glDrawElementArrayAPPLE +glDrawElementArrayATI +glDrawElements +glDrawElementsBaseVertex +glDrawElementsBaseVertexEXT +glDrawElementsBaseVertexOES +glDrawElementsIndirect +glDrawElementsInstanced +glDrawElementsInstancedANGLE +glDrawElementsInstancedARB +glDrawElementsInstancedBaseInstance +glDrawElementsInstancedBaseInstanceEXT +glDrawElementsInstancedBaseVertex +glDrawElementsInstancedBaseVertexBaseInstance +glDrawElementsInstancedBaseVertexBaseInstanceEXT +glDrawElementsInstancedBaseVertexEXT +glDrawElementsInstancedBaseVertexOES +glDrawElementsInstancedEXT +glDrawElementsInstancedNV +glDrawMeshArraysSUN +glDrawMeshNV +glDrawMeshTasksIndirectNV +glDrawMeshTasksNV +glDrawPixels +glDrawRangeElementArrayAPPLE +glDrawRangeElementArrayATI +glDrawRangeElements +glDrawRangeElementsBaseVertex +glDrawRangeElementsBaseVertexEXT +glDrawRangeElementsBaseVertexOES +glDrawRangeElementsEXT +glDrawTexfOES +glDrawTexfvOES +glDrawTexiOES +glDrawTexivOES +glDrawTexsOES +glDrawTexsvOES +glDrawTextureNV +glDrawTexxOES +glDrawTexxvOES +glDrawTransformFeedback +glDrawTransformFeedbackEXT +glDrawTransformFeedbackInstanced +glDrawTransformFeedbackInstancedEXT +glDrawTransformFeedbackNV +glDrawTransformFeedbackStream +glDrawTransformFeedbackStreamInstanced +glDrawVkImageNV +glEdgeFlag +glEdgeFlagFormatNV +glEdgeFlagPointer +glEdgeFlagPointerEXT +glEdgeFlagPointerListIBM +glEdgeFlagv +glEGLImageTargetRenderbufferStorageOES +glEGLImageTargetTexStorageEXT +glEGLImageTargetTexture2DOES +glEGLImageTargetTextureStorageEXT +glElementPointerAPPLE +glElementPointerATI +glEnable +glEnableClientState +glEnableClientStateiEXT +glEnableClientStateIndexedEXT +glEnableDriverControlQCOM +glEnablei +glEnableiEXT +glEnableIndexedEXT +glEnableiNV +glEnableiOES +glEnableVariantClientStateEXT +glEnableVertexArrayAttrib +glEnableVertexArrayAttribEXT +glEnableVertexArrayEXT +glEnableVertexAttribAPPLE +glEnableVertexAttribArray +glEnableVertexAttribArrayARB +glEnd +glEndConditionalRender +glEndConditionalRenderNV +glEndConditionalRenderNVX +glEndFragmentShaderATI +glEndList +glEndOcclusionQueryNV +glEndPerfMonitorAMD +glEndPerfQueryINTEL +glEndQuery +glEndQueryARB +glEndQueryEXT +glEndQueryIndexed +glEndTilingQCOM +glEndTransformFeedback +glEndTransformFeedbackEXT +glEndTransformFeedbackNV +glEndVertexShaderEXT +glEndVideoCaptureNV +glEvalCoord1d +glEvalCoord1dv +glEvalCoord1f +glEvalCoord1fv +glEvalCoord1xOES +glEvalCoord1xvOES +glEvalCoord2d +glEvalCoord2dv +glEvalCoord2f +glEvalCoord2fv +glEvalCoord2xOES +glEvalCoord2xvOES +glEvalMapsNV +glEvalMesh1 +glEvalMesh2 +glEvalPoint1 +glEvalPoint2 +glEvaluateDepthValuesARB +glExecuteProgramNV +glExtGetBufferPointervQCOM +glExtGetBuffersQCOM +glExtGetFramebuffersQCOM +glExtGetProgramBinarySourceQCOM +glExtGetProgramsQCOM +glExtGetRenderbuffersQCOM +glExtGetShadersQCOM +glExtGetTexLevelParameterivQCOM +glExtGetTexSubImageQCOM +glExtGetTexturesQCOM +glExtIsProgramBinaryQCOM +glExtractComponentEXT +glExtTexObjectStateOverrideiQCOM +glFeedbackBuffer +glFeedbackBufferxOES +glFenceSync +glFenceSyncAPPLE +glFenceValueuiNVX +glFinalCombinerInputNV +glFinish +glFinishAsyncSGIX +glFinishFenceAPPLE +glFinishFenceNV +glFinishObjectAPPLE +glFinishTextureSUNX +glFlush +glFlushMappedBufferRange +glFlushMappedBufferRangeAPPLE +glFlushMappedBufferRangeEXT +glFlushMappedNamedBufferRange +glFlushMappedNamedBufferRangeEXT +glFlushPixelDataRangeNV +glFlushRasterSGIX +glFlushStaticDataIBM +glFlushVertexArrayRangeAPPLE +glFlushVertexArrayRangeNV +glFogCoordd +glFogCoorddEXT +glFogCoorddv +glFogCoorddvEXT +glFogCoordf +glFogCoordfEXT +glFogCoordFormatNV +glFogCoordfv +glFogCoordfvEXT +glFogCoordhNV +glFogCoordhvNV +glFogCoordPointer +glFogCoordPointerEXT +glFogCoordPointerListIBM +glFogf +glFogFuncSGIS +glFogfv +glFogi +glFogiv +glFogx +glFogxOES +glFogxv +glFogxvOES +glFragmentColorMaterialSGIX +glFragmentCoverageColorNV +glFragmentLightfSGIX +glFragmentLightfvSGIX +glFragmentLightiSGIX +glFragmentLightivSGIX +glFragmentLightModelfSGIX +glFragmentLightModelfvSGIX +glFragmentLightModeliSGIX +glFragmentLightModelivSGIX +glFragmentMaterialfSGIX +glFragmentMaterialfvSGIX +glFragmentMaterialiSGIX +glFragmentMaterialivSGIX +glFramebufferDrawBufferEXT +glFramebufferDrawBuffersEXT +glFramebufferFetchBarrierEXT +glFramebufferFetchBarrierQCOM +glFramebufferFoveationConfigQCOM +glFramebufferFoveationParametersQCOM +glFramebufferParameteri +glFramebufferParameteriMESA +glFramebufferPixelLocalStorageSizeEXT +glFramebufferReadBufferEXT +glFramebufferRenderbuffer +glFramebufferRenderbufferEXT +glFramebufferRenderbufferOES +glFramebufferSampleLocationsfvARB +glFramebufferSampleLocationsfvNV +glFramebufferSamplePositionsfvAMD +glFramebufferTexture +glFramebufferTexture1D +glFramebufferTexture1DEXT +glFramebufferTexture2D +glFramebufferTexture2DDownsampleIMG +glFramebufferTexture2DEXT +glFramebufferTexture2DMultisampleEXT +glFramebufferTexture2DMultisampleIMG +glFramebufferTexture2DOES +glFramebufferTexture3D +glFramebufferTexture3DEXT +glFramebufferTexture3DOES +glFramebufferTextureARB +glFramebufferTextureEXT +glFramebufferTextureFaceARB +glFramebufferTextureFaceEXT +glFramebufferTextureLayer +glFramebufferTextureLayerARB +glFramebufferTextureLayerDownsampleIMG +glFramebufferTextureLayerEXT +glFramebufferTextureLayerNV +glFramebufferTextureMultisampleMultiviewOVR +glFramebufferTextureMultiviewOVR +glFramebufferTextureOES +glFrameTerminatorGREMEDY +glFrameZoomSGIX +glFreeObjectBufferATI +glFrontFace +glFrustum +glFrustumf +glFrustumfOES +glFrustumx +glFrustumxOES +glGenAsyncMarkersSGIX +glGenBuffers +glGenBuffersARB +glGenerateMipmap +glGenerateMipmapEXT +glGenerateMipmapOES +glGenerateMultiTexMipmapEXT +glGenerateTextureMipmap +glGenerateTextureMipmapEXT +glGenFencesAPPLE +glGenFencesNV +glGenFragmentShadersATI +glGenFramebuffers +glGenFramebuffersEXT +glGenFramebuffersOES +glGenLists +glGenNamesAMD +glGenOcclusionQueriesNV +glGenPathsNV +glGenPerfMonitorsAMD +glGenProgramPipelines +glGenProgramPipelinesEXT +glGenProgramsARB +glGenProgramsNV +glGenQueries +glGenQueriesARB +glGenQueriesEXT +glGenQueryResourceTagNV +glGenRenderbuffers +glGenRenderbuffersEXT +glGenRenderbuffersOES +glGenSamplers +glGenSemaphoresEXT +glGenSymbolsEXT +glGenTextures +glGenTexturesEXT +glGenTransformFeedbacks +glGenTransformFeedbacksEXT +glGenTransformFeedbacksNV +glGenVertexArrays +glGenVertexArraysAPPLE +glGenVertexArraysOES +glGenVertexShadersEXT +glGetActiveAtomicCounterBufferiv +glGetActiveAttrib +glGetActiveAttribARB +glGetActiveSubroutineName +glGetActiveSubroutineUniformiv +glGetActiveSubroutineUniformName +glGetActiveUniform +glGetActiveUniformARB +glGetActiveUniformBlockiv +glGetActiveUniformBlockName +glGetActiveUniformName +glGetActiveUniformsiv +glGetActiveVaryingNV +glGetArrayObjectfvATI +glGetArrayObjectivATI +glGetAttachedObjectsARB +glGetAttachedShaders +glGetAttribLocation +glGetAttribLocationARB +glGetBooleanIndexedvEXT +glGetBooleani_v +glGetBooleanv +glGetBufferParameteri64v +glGetBufferParameteriv +glGetBufferParameterivARB +glGetBufferParameterui64vNV +glGetBufferPointerv +glGetBufferPointervARB +glGetBufferPointervOES +glGetBufferSubData +glGetBufferSubDataARB +glGetClipPlane +glGetClipPlanef +glGetClipPlanefOES +glGetClipPlanex +glGetClipPlanexOES +glGetColorTable +glGetColorTableEXT +glGetColorTableParameterfv +glGetColorTableParameterfvEXT +glGetColorTableParameterfvSGI +glGetColorTableParameteriv +glGetColorTableParameterivEXT +glGetColorTableParameterivSGI +glGetColorTableSGI +glGetCombinerInputParameterfvNV +glGetCombinerInputParameterivNV +glGetCombinerOutputParameterfvNV +glGetCombinerOutputParameterivNV +glGetCombinerStageParameterfvNV +glGetCommandHeaderNV +glGetCompressedMultiTexImageEXT +glGetCompressedTexImage +glGetCompressedTexImageARB +glGetCompressedTexImageNV +glGetCompressedTextureImage +glGetCompressedTextureImageEXT +glGetCompressedTextureSubImage +glGetConvolutionFilter +glGetConvolutionFilterEXT +glGetConvolutionParameterfv +glGetConvolutionParameterfvEXT +glGetConvolutionParameteriv +glGetConvolutionParameterivEXT +glGetConvolutionParameterxvOES +glGetCoverageModulationTableNV +glGetDebugMessageLog +glGetDebugMessageLogAMD +glGetDebugMessageLogARB +glGetDebugMessageLogKHR +glGetDebugMessageLogOES +glGetDetailTexFuncSGIS +glGetDoubleIndexedvEXT +glGetDoublei_v +glGetDoublei_vEXT +glGetDoublev +glGetDriverControlsQCOM +glGetDriverControlStringQCOM +glGetError +glGetFenceivNV +glGetFinalCombinerInputParameterfvNV +glGetFinalCombinerInputParameterivNV +glGetFirstPerfQueryIdINTEL +glGetFixedv +glGetFixedvOES +glGetFloatIndexedvEXT +glGetFloati_v +glGetFloati_vEXT +glGetFloati_vNV +glGetFloati_vOES +glGetFloatv +glGetFogFuncSGIS +glGetFragDataIndex +glGetFragDataIndexEXT +glGetFragDataLocation +glGetFragDataLocationEXT +glGetFragmentLightfvSGIX +glGetFragmentLightivSGIX +glGetFragmentMaterialfvSGIX +glGetFragmentMaterialivSGIX +glGetFramebufferAttachmentParameteriv +glGetFramebufferAttachmentParameterivEXT +glGetFramebufferAttachmentParameterivOES +glGetFramebufferParameterfvAMD +glGetFramebufferParameteriv +glGetFramebufferParameterivEXT +glGetFramebufferParameterivMESA +glGetFramebufferPixelLocalStorageSizeEXT +glGetGraphicsResetStatus +glGetGraphicsResetStatusARB +glGetGraphicsResetStatusEXT +glGetGraphicsResetStatusKHR +glGetHandleARB +glGetHistogram +glGetHistogramEXT +glGetHistogramParameterfv +glGetHistogramParameterfvEXT +glGetHistogramParameteriv +glGetHistogramParameterivEXT +glGetHistogramParameterxvOES +glGetImageHandleARB +glGetImageHandleNV +glGetImageTransformParameterfvHP +glGetImageTransformParameterivHP +glGetInfoLogARB +glGetInstrumentsSGIX +glGetInteger64i_v +glGetInteger64v +glGetInteger64vAPPLE +glGetIntegerIndexedvEXT +glGetIntegeri_v +glGetIntegeri_vEXT +glGetIntegerui64i_vNV +glGetIntegerui64vNV +glGetIntegerv +glGetInternalformati64v +glGetInternalformativ +glGetInternalformatSampleivNV +glGetInvariantBooleanvEXT +glGetInvariantFloatvEXT +glGetInvariantIntegervEXT +glGetLightfv +glGetLightiv +glGetLightxOES +glGetLightxv +glGetLightxvOES +glGetListParameterfvSGIX +glGetListParameterivSGIX +glGetLocalConstantBooleanvEXT +glGetLocalConstantFloatvEXT +glGetLocalConstantIntegervEXT +glGetMapAttribParameterfvNV +glGetMapAttribParameterivNV +glGetMapControlPointsNV +glGetMapdv +glGetMapfv +glGetMapiv +glGetMapParameterfvNV +glGetMapParameterivNV +glGetMapxvOES +glGetMaterialfv +glGetMaterialiv +glGetMaterialxOES +glGetMaterialxv +glGetMaterialxvOES +glGetMemoryObjectDetachedResourcesuivNV +glGetMemoryObjectParameterivEXT +glGetMinmax +glGetMinmaxEXT +glGetMinmaxParameterfv +glGetMinmaxParameterfvEXT +glGetMinmaxParameteriv +glGetMinmaxParameterivEXT +glGetMultisamplefv +glGetMultisamplefvNV +glGetMultiTexEnvfvEXT +glGetMultiTexEnvivEXT +glGetMultiTexGendvEXT +glGetMultiTexGenfvEXT +glGetMultiTexGenivEXT +glGetMultiTexImageEXT +glGetMultiTexLevelParameterfvEXT +glGetMultiTexLevelParameterivEXT +glGetMultiTexParameterfvEXT +glGetMultiTexParameterIivEXT +glGetMultiTexParameterIuivEXT +glGetMultiTexParameterivEXT +glGetNamedBufferParameteri64v +glGetNamedBufferParameteri64vEXT +glGetNamedBufferParameteriv +glGetNamedBufferParameterivEXT +glGetNamedBufferParameterui64vNV +glGetNamedBufferPointerv +glGetNamedBufferPointervEXT +glGetNamedBufferSubData +glGetNamedBufferSubDataEXT +glGetNamedFramebufferAttachmentParameteriv +glGetNamedFramebufferAttachmentParameterivEXT +glGetNamedFramebufferParameterfvAMD +glGetNamedFramebufferParameteriv +glGetNamedFramebufferParameterivEXT +glGetNamedProgramivEXT +glGetNamedProgramLocalParameterdvEXT +glGetNamedProgramLocalParameterfvEXT +glGetNamedProgramLocalParameterIivEXT +glGetNamedProgramLocalParameterIuivEXT +glGetNamedProgramStringEXT +glGetNamedRenderbufferParameteriv +glGetNamedRenderbufferParameterivEXT +glGetNamedStringARB +glGetNamedStringivARB +glGetnColorTable +glGetnColorTableARB +glGetnCompressedTexImage +glGetnCompressedTexImageARB +glGetnConvolutionFilter +glGetnConvolutionFilterARB +glGetNextPerfQueryIdINTEL +glGetnHistogram +glGetnHistogramARB +glGetnMapdv +glGetnMapdvARB +glGetnMapfv +glGetnMapfvARB +glGetnMapiv +glGetnMapivARB +glGetnMinmax +glGetnMinmaxARB +glGetnPixelMapfv +glGetnPixelMapfvARB +glGetnPixelMapuiv +glGetnPixelMapuivARB +glGetnPixelMapusv +glGetnPixelMapusvARB +glGetnPolygonStipple +glGetnPolygonStippleARB +glGetnSeparableFilter +glGetnSeparableFilterARB +glGetnTexImage +glGetnTexImageARB +glGetnUniformdv +glGetnUniformdvARB +glGetnUniformfv +glGetnUniformfvARB +glGetnUniformfvEXT +glGetnUniformfvKHR +glGetnUniformi64vARB +glGetnUniformiv +glGetnUniformivARB +glGetnUniformivEXT +glGetnUniformivKHR +glGetnUniformui64vARB +glGetnUniformuiv +glGetnUniformuivARB +glGetnUniformuivKHR +glGetObjectBufferfvATI +glGetObjectBufferivATI +glGetObjectLabel +glGetObjectLabelEXT +glGetObjectLabelKHR +glGetObjectLabelOES +glGetObjectParameterfvARB +glGetObjectParameterivAPPLE +glGetObjectParameterivARB +glGetObjectPtrLabel +glGetObjectPtrLabelKHR +glGetObjectPtrLabelOES +glGetOcclusionQueryivNV +glGetOcclusionQueryuivNV +glGetPathColorGenfvNV +glGetPathColorGenivNV +glGetPathCommandsNV +glGetPathCoordsNV +glGetPathDashArrayNV +glGetPathLengthNV +glGetPathMetricRangeNV +glGetPathMetricsNV +glGetPathParameterfvNV +glGetPathParameterivNV +glGetPathSpacingNV +glGetPathTexGenfvNV +glGetPathTexGenivNV +glGetPerfCounterInfoINTEL +glGetPerfMonitorCounterDataAMD +glGetPerfMonitorCounterInfoAMD +glGetPerfMonitorCountersAMD +glGetPerfMonitorCounterStringAMD +glGetPerfMonitorGroupsAMD +glGetPerfMonitorGroupStringAMD +glGetPerfQueryDataINTEL +glGetPerfQueryIdByNameINTEL +glGetPerfQueryInfoINTEL +glGetPixelMapfv +glGetPixelMapuiv +glGetPixelMapusv +glGetPixelMapxv +glGetPixelTexGenParameterfvSGIS +glGetPixelTexGenParameterivSGIS +glGetPixelTransformParameterfvEXT +glGetPixelTransformParameterivEXT +glGetPointerIndexedvEXT +glGetPointeri_vEXT +glGetPointerv +glGetPointervEXT +glGetPointervKHR +glGetPointervOES +glGetPolygonStipple +glGetProgramBinary +glGetProgramBinaryOES +glGetProgramEnvParameterdvARB +glGetProgramEnvParameterfvARB +glGetProgramEnvParameterIivNV +glGetProgramEnvParameterIuivNV +glGetProgramInfoLog +glGetProgramInterfaceiv +glGetProgramiv +glGetProgramivARB +glGetProgramivNV +glGetProgramLocalParameterdvARB +glGetProgramLocalParameterfvARB +glGetProgramLocalParameterIivNV +glGetProgramLocalParameterIuivNV +glGetProgramNamedParameterdvNV +glGetProgramNamedParameterfvNV +glGetProgramParameterdvNV +glGetProgramParameterfvNV +glGetProgramPipelineInfoLog +glGetProgramPipelineInfoLogEXT +glGetProgramPipelineiv +glGetProgramPipelineivEXT +glGetProgramResourcefvNV +glGetProgramResourceIndex +glGetProgramResourceiv +glGetProgramResourceLocation +glGetProgramResourceLocationIndex +glGetProgramResourceLocationIndexEXT +glGetProgramResourceName +glGetProgramStageiv +glGetProgramStringARB +glGetProgramStringNV +glGetProgramSubroutineParameteruivNV +glGetQueryBufferObjecti64v +glGetQueryBufferObjectiv +glGetQueryBufferObjectui64v +glGetQueryBufferObjectuiv +glGetQueryIndexediv +glGetQueryiv +glGetQueryivARB +glGetQueryivEXT +glGetQueryObjecti64v +glGetQueryObjecti64vEXT +glGetQueryObjectiv +glGetQueryObjectivARB +glGetQueryObjectivEXT +glGetQueryObjectui64v +glGetQueryObjectui64vEXT +glGetQueryObjectui64vNV +glGetQueryObjectuiv +glGetQueryObjectuivARB +glGetQueryObjectuivEXT +glGetRenderbufferParameteriv +glGetRenderbufferParameterivEXT +glGetRenderbufferParameterivOES +glGetSamplerParameterfv +glGetSamplerParameterIiv +glGetSamplerParameterIivEXT +glGetSamplerParameterIivOES +glGetSamplerParameterIuiv +glGetSamplerParameterIuivEXT +glGetSamplerParameterIuivOES +glGetSamplerParameteriv +glGetSemaphoreParameterui64vEXT +glGetSeparableFilter +glGetSeparableFilterEXT +glGetShaderInfoLog +glGetShaderiv +glGetShaderPrecisionFormat +glGetShaderSource +glGetShaderSourceARB +glGetShadingRateImagePaletteNV +glGetShadingRateSampleLocationivNV +glGetSharpenTexFuncSGIS +glGetStageIndexNV +glGetString +glGetStringi +glGetSubroutineIndex +glGetSubroutineUniformLocation +glGetSynciv +glGetSyncivAPPLE +glGetSyncv64NVX +glGetTexBumpParameterfvATI +glGetTexBumpParameterivATI +glGetTexEnvfv +glGetTexEnviv +glGetTexEnvxv +glGetTexEnvxvOES +glGetTexFilterFuncSGIS +glGetTexGendv +glGetTexGenfv +glGetTexGenfvOES +glGetTexGeniv +glGetTexGenivOES +glGetTexGenxvOES +glGetTexImage +glGetTexImageNV +glGetTexLevelParameterfv +glGetTexLevelParameterfvNV +glGetTexLevelParameteriv +glGetTexLevelParameterivNV +glGetTexLevelParameterxvOES +glGetTexParameterfv +glGetTexParameterIiv +glGetTexParameterIivEXT +glGetTexParameterIivOES +glGetTexParameterIuiv +glGetTexParameterIuivEXT +glGetTexParameterIuivOES +glGetTexParameteriv +glGetTexParameterPointervAPPLE +glGetTexParameterxv +glGetTexParameterxvOES +glGetTextureHandleARB +glGetTextureHandleIMG +glGetTextureHandleNV +glGetTextureImage +glGetTextureImageEXT +glGetTextureLevelParameterfv +glGetTextureLevelParameterfvEXT +glGetTextureLevelParameteriv +glGetTextureLevelParameterivEXT +glGetTextureParameterfv +glGetTextureParameterfvEXT +glGetTextureParameterIiv +glGetTextureParameterIivEXT +glGetTextureParameterIuiv +glGetTextureParameterIuivEXT +glGetTextureParameteriv +glGetTextureParameterivEXT +glGetTextureSamplerHandleARB +glGetTextureSamplerHandleIMG +glGetTextureSamplerHandleNV +glGetTextureSubImage +glGetTrackMatrixivNV +glGetTransformFeedbacki64_v +glGetTransformFeedbacki_v +glGetTransformFeedbackiv +glGetTransformFeedbackVarying +glGetTransformFeedbackVaryingEXT +glGetTransformFeedbackVaryingNV +glGetTranslatedShaderSourceANGLE +glGetUniformBlockIndex +glGetUniformBufferSizeEXT +glGetUniformdv +glGetUniformfv +glGetUniformfvARB +glGetUniformi64vARB +glGetUniformi64vNV +glGetUniformIndices +glGetUniformiv +glGetUniformivARB +glGetUniformLocation +glGetUniformLocationARB +glGetUniformOffsetEXT +glGetUniformSubroutineuiv +glGetUniformui64vARB +glGetUniformui64vNV +glGetUniformuiv +glGetUniformuivEXT +glGetUnsignedBytei_vEXT +glGetUnsignedBytevEXT +glGetVariantArrayObjectfvATI +glGetVariantArrayObjectivATI +glGetVariantBooleanvEXT +glGetVariantFloatvEXT +glGetVariantIntegervEXT +glGetVariantPointervEXT +glGetVaryingLocationNV +glGetVertexArrayIndexed64iv +glGetVertexArrayIndexediv +glGetVertexArrayIntegeri_vEXT +glGetVertexArrayIntegervEXT +glGetVertexArrayiv +glGetVertexArrayPointeri_vEXT +glGetVertexArrayPointervEXT +glGetVertexAttribArrayObjectfvATI +glGetVertexAttribArrayObjectivATI +glGetVertexAttribdv +glGetVertexAttribdvARB +glGetVertexAttribdvNV +glGetVertexAttribfv +glGetVertexAttribfvARB +glGetVertexAttribfvNV +glGetVertexAttribIiv +glGetVertexAttribIivEXT +glGetVertexAttribIuiv +glGetVertexAttribIuivEXT +glGetVertexAttribiv +glGetVertexAttribivARB +glGetVertexAttribivNV +glGetVertexAttribLdv +glGetVertexAttribLdvEXT +glGetVertexAttribLi64vNV +glGetVertexAttribLui64vARB +glGetVertexAttribLui64vNV +glGetVertexAttribPointerv +glGetVertexAttribPointervARB +glGetVertexAttribPointervNV +glGetVideoCaptureANCStreamivNVX +glGetVideoCaptureivNV +glGetVideoCaptureStreamdvNV +glGetVideoCaptureStreamfvNV +glGetVideoCaptureStreamivNV +glGetVideoi64vNV +glGetVideoivNV +glGetVideoui64vNV +glGetVideouivNV +glGetVkProcAddrNV +glGlobalAlphaFactorbSUN +glGlobalAlphaFactordSUN +glGlobalAlphaFactorfSUN +glGlobalAlphaFactoriSUN +glGlobalAlphaFactorsSUN +glGlobalAlphaFactorubSUN +glGlobalAlphaFactoruiSUN +glGlobalAlphaFactorusSUN +glGpuSyncAcquireNVX +glGpuSyncCreateNVX +glGpuSyncDestroyNVX +glGpuSyncReleaseNVX +glHint +glHintPGI +glHistogram +glHistogramEXT +glIglooInterfaceSGIX +glImageTransformParameterfHP +glImageTransformParameterfvHP +glImageTransformParameteriHP +glImageTransformParameterivHP +glImportMemoryFdEXT +glImportMemoryWin32HandleEXT +glImportMemoryWin32NameEXT +glImportSemaphoreFdEXT +glImportSemaphoreWin32HandleEXT +glImportSemaphoreWin32NameEXT +glImportSyncEXT +glIndexd +glIndexdv +glIndexf +glIndexFormatNV +glIndexFuncEXT +glIndexfv +glIndexi +glIndexiv +glIndexMask +glIndexMaterialEXT +glIndexPointer +glIndexPointerEXT +glIndexPointerListIBM +glIndexs +glIndexsv +glIndexub +glIndexubv +glIndexxOES +glIndexxvOES +glInitNames +glInsertComponentEXT +glInsertEventMarkerEXT +glInstrumentsBufferSGIX +glInterleavedArrays +glInterpolatePathsNV +glInvalidateBufferData +glInvalidateBufferSubData +glInvalidateFramebuffer +glInvalidateNamedFramebufferData +glInvalidateNamedFramebufferSubData +glInvalidateSubFramebuffer +glInvalidateTexImage +glInvalidateTexSubImage +glIsAsyncMarkerSGIX +glIsBuffer +glIsBufferARB +glIsBufferResidentNV +glIsCommandListNV +glIsEnabled +glIsEnabledi +glIsEnablediEXT +glIsEnabledIndexedEXT +glIsEnablediNV +glIsEnablediOES +glIsFenceAPPLE +glIsFenceNV +glIsFramebuffer +glIsFramebufferEXT +glIsFramebufferOES +glIsImageHandleResidentARB +glIsImageHandleResidentNV +glIsList +glIsMemoryObjectEXT +glIsNameAMD +glIsNamedBufferResidentNV +glIsNamedStringARB +glIsObjectBufferATI +glIsOcclusionQueryNV +glIsPathNV +glIsPointInFillPathNV +glIsPointInStrokePathNV +glIsProgram +glIsProgramARB +glIsProgramNV +glIsProgramPipeline +glIsProgramPipelineEXT +glIsQuery +glIsQueryARB +glIsQueryEXT +glIsRenderbuffer +glIsRenderbufferEXT +glIsRenderbufferOES +glIsSampler +glIsSemaphoreEXT +glIsShader +glIsStateNV +glIsSync +glIsSyncAPPLE +glIsTexture +glIsTextureEXT +glIsTextureHandleResidentARB +glIsTextureHandleResidentNV +glIsTransformFeedback +glIsTransformFeedbackEXT +glIsTransformFeedbackNV +glIsVariantEnabledEXT +glIsVertexArray +glIsVertexArrayAPPLE +glIsVertexArrayOES +glIsVertexAttribEnabledAPPLE +glLabelObjectEXT +glLGPUCopyImageSubDataNVX +glLGPUInterlockNVX +glLGPUNamedBufferSubDataNVX +glLightEnviSGIX +glLightf +glLightfv +glLighti +glLightiv +glLightModelf +glLightModelfv +glLightModeli +glLightModeliv +glLightModelx +glLightModelxOES +glLightModelxv +glLightModelxvOES +glLightx +glLightxOES +glLightxv +glLightxvOES +glLineStipple +glLineWidth +glLineWidthx +glLineWidthxOES +glLinkProgram +glLinkProgramARB +glListBase +glListDrawCommandsStatesClientNV +glListParameterfSGIX +glListParameterfvSGIX +glListParameteriSGIX +glListParameterivSGIX +glLoadIdentity +glLoadIdentityDeformationMapSGIX +glLoadMatrixd +glLoadMatrixf +glLoadMatrixx +glLoadMatrixxOES +glLoadName +glLoadPaletteFromModelViewMatrixOES +glLoadProgramNV +glLoadTransformEXT +glLoadTransposeMatrixd +glLoadTransposeMatrixdARB +glLoadTransposeMatrixf +glLoadTransposeMatrixfARB +glLoadTransposeMatrixxOES +glLockArraysEXT +glLogicOp +glMakeBufferNonResidentNV +glMakeBufferResidentNV +glMakeImageHandleNonResidentARB +glMakeImageHandleNonResidentNV +glMakeImageHandleResidentARB +glMakeImageHandleResidentNV +glMakeNamedBufferNonResidentNV +glMakeNamedBufferResidentNV +glMakeTextureHandleNonResidentARB +glMakeTextureHandleNonResidentNV +glMakeTextureHandleResidentARB +glMakeTextureHandleResidentNV +glMap1d +glMap1f +glMap1xOES +glMap2d +glMap2f +glMap2xOES +glMapBuffer +glMapBufferARB +glMapBufferOES +glMapBufferRange +glMapBufferRangeEXT +glMapControlPointsNV +glMapGrid1d +glMapGrid1f +glMapGrid1xOES +glMapGrid2d +glMapGrid2f +glMapGrid2xOES +glMapNamedBuffer +glMapNamedBufferEXT +glMapNamedBufferRange +glMapNamedBufferRangeEXT +glMapObjectBufferATI +glMapParameterfvNV +glMapParameterivNV +glMapTexture2DINTEL +glMapVertexAttrib1dAPPLE +glMapVertexAttrib1fAPPLE +glMapVertexAttrib2dAPPLE +glMapVertexAttrib2fAPPLE +glMaterialf +glMaterialfv +glMateriali +glMaterialiv +glMaterialx +glMaterialxOES +glMaterialxv +glMaterialxvOES +glMatrixFrustumEXT +glMatrixIndexPointerARB +glMatrixIndexPointerOES +glMatrixIndexubvARB +glMatrixIndexuivARB +glMatrixIndexusvARB +glMatrixLoad3x2fNV +glMatrixLoad3x3fNV +glMatrixLoaddEXT +glMatrixLoadfEXT +glMatrixLoadIdentityEXT +glMatrixLoadTranspose3x3fNV +glMatrixLoadTransposedEXT +glMatrixLoadTransposefEXT +glMatrixMode +glMatrixMult3x2fNV +glMatrixMult3x3fNV +glMatrixMultdEXT +glMatrixMultfEXT +glMatrixMultTranspose3x3fNV +glMatrixMultTransposedEXT +glMatrixMultTransposefEXT +glMatrixOrthoEXT +glMatrixPopEXT +glMatrixPushEXT +glMatrixRotatedEXT +glMatrixRotatefEXT +glMatrixScaledEXT +glMatrixScalefEXT +glMatrixTranslatedEXT +glMatrixTranslatefEXT +glMaxShaderCompilerThreadsARB +glMaxShaderCompilerThreadsKHR +glMemoryBarrier +glMemoryBarrierByRegion +glMemoryBarrierEXT +glMemoryObjectParameterivEXT +glMinmax +glMinmaxEXT +glMinSampleShading +glMinSampleShadingARB +glMinSampleShadingOES +glMulticastBarrierNV +glMulticastBlitFramebufferNV +glMulticastBufferSubDataNV +glMulticastCopyBufferSubDataNV +glMulticastCopyImageSubDataNV +glMulticastFramebufferSampleLocationsfvNV +glMulticastGetQueryObjecti64vNV +glMulticastGetQueryObjectivNV +glMulticastGetQueryObjectui64vNV +glMulticastGetQueryObjectuivNV +glMulticastScissorArrayvNVX +glMulticastViewportArrayvNVX +glMulticastViewportPositionWScaleNVX +glMulticastWaitSyncNV +glMultiDrawArrays +glMultiDrawArraysEXT +glMultiDrawArraysIndirect +glMultiDrawArraysIndirectAMD +glMultiDrawArraysIndirectBindlessCountNV +glMultiDrawArraysIndirectBindlessNV +glMultiDrawArraysIndirectCount +glMultiDrawArraysIndirectCountARB +glMultiDrawArraysIndirectEXT +glMultiDrawElementArrayAPPLE +glMultiDrawElements +glMultiDrawElementsBaseVertex +glMultiDrawElementsBaseVertexEXT +glMultiDrawElementsEXT +glMultiDrawElementsIndirect +glMultiDrawElementsIndirectAMD +glMultiDrawElementsIndirectBindlessCountNV +glMultiDrawElementsIndirectBindlessNV +glMultiDrawElementsIndirectCount +glMultiDrawElementsIndirectCountARB +glMultiDrawElementsIndirectEXT +glMultiDrawMeshTasksIndirectCountNV +glMultiDrawMeshTasksIndirectNV +glMultiDrawRangeElementArrayAPPLE +glMultiModeDrawArraysIBM +glMultiModeDrawElementsIBM +glMultiTexBufferEXT +glMultiTexCoord1bOES +glMultiTexCoord1bvOES +glMultiTexCoord1d +glMultiTexCoord1dARB +glMultiTexCoord1dv +glMultiTexCoord1dvARB +glMultiTexCoord1f +glMultiTexCoord1fARB +glMultiTexCoord1fv +glMultiTexCoord1fvARB +glMultiTexCoord1hNV +glMultiTexCoord1hvNV +glMultiTexCoord1i +glMultiTexCoord1iARB +glMultiTexCoord1iv +glMultiTexCoord1ivARB +glMultiTexCoord1s +glMultiTexCoord1sARB +glMultiTexCoord1sv +glMultiTexCoord1svARB +glMultiTexCoord1x +glMultiTexCoord1xOES +glMultiTexCoord1xv +glMultiTexCoord1xvOES +glMultiTexCoord2bOES +glMultiTexCoord2bvOES +glMultiTexCoord2d +glMultiTexCoord2dARB +glMultiTexCoord2dv +glMultiTexCoord2dvARB +glMultiTexCoord2f +glMultiTexCoord2fARB +glMultiTexCoord2fv +glMultiTexCoord2fvARB +glMultiTexCoord2hNV +glMultiTexCoord2hvNV +glMultiTexCoord2i +glMultiTexCoord2iARB +glMultiTexCoord2iv +glMultiTexCoord2ivARB +glMultiTexCoord2s +glMultiTexCoord2sARB +glMultiTexCoord2sv +glMultiTexCoord2svARB +glMultiTexCoord2x +glMultiTexCoord2xOES +glMultiTexCoord2xv +glMultiTexCoord2xvOES +glMultiTexCoord3bOES +glMultiTexCoord3bvOES +glMultiTexCoord3d +glMultiTexCoord3dARB +glMultiTexCoord3dv +glMultiTexCoord3dvARB +glMultiTexCoord3f +glMultiTexCoord3fARB +glMultiTexCoord3fv +glMultiTexCoord3fvARB +glMultiTexCoord3hNV +glMultiTexCoord3hvNV +glMultiTexCoord3i +glMultiTexCoord3iARB +glMultiTexCoord3iv +glMultiTexCoord3ivARB +glMultiTexCoord3s +glMultiTexCoord3sARB +glMultiTexCoord3sv +glMultiTexCoord3svARB +glMultiTexCoord3x +glMultiTexCoord3xOES +glMultiTexCoord3xv +glMultiTexCoord3xvOES +glMultiTexCoord4bOES +glMultiTexCoord4bvOES +glMultiTexCoord4d +glMultiTexCoord4dARB +glMultiTexCoord4dv +glMultiTexCoord4dvARB +glMultiTexCoord4f +glMultiTexCoord4fARB +glMultiTexCoord4fv +glMultiTexCoord4fvARB +glMultiTexCoord4hNV +glMultiTexCoord4hvNV +glMultiTexCoord4i +glMultiTexCoord4iARB +glMultiTexCoord4iv +glMultiTexCoord4ivARB +glMultiTexCoord4s +glMultiTexCoord4sARB +glMultiTexCoord4sv +glMultiTexCoord4svARB +glMultiTexCoord4x +glMultiTexCoord4xOES +glMultiTexCoord4xv +glMultiTexCoord4xvOES +glMultiTexCoordP1ui +glMultiTexCoordP1uiv +glMultiTexCoordP2ui +glMultiTexCoordP2uiv +glMultiTexCoordP3ui +glMultiTexCoordP3uiv +glMultiTexCoordP4ui +glMultiTexCoordP4uiv +glMultiTexCoordPointerEXT +glMultiTexEnvfEXT +glMultiTexEnvfvEXT +glMultiTexEnviEXT +glMultiTexEnvivEXT +glMultiTexGendEXT +glMultiTexGendvEXT +glMultiTexGenfEXT +glMultiTexGenfvEXT +glMultiTexGeniEXT +glMultiTexGenivEXT +glMultiTexImage1DEXT +glMultiTexImage2DEXT +glMultiTexImage3DEXT +glMultiTexParameterfEXT +glMultiTexParameterfvEXT +glMultiTexParameteriEXT +glMultiTexParameterIivEXT +glMultiTexParameterIuivEXT +glMultiTexParameterivEXT +glMultiTexRenderbufferEXT +glMultiTexSubImage1DEXT +glMultiTexSubImage2DEXT +glMultiTexSubImage3DEXT +glMultMatrixd +glMultMatrixf +glMultMatrixx +glMultMatrixxOES +glMultTransformEXT +glMultTransposeMatrixd +glMultTransposeMatrixdARB +glMultTransposeMatrixf +glMultTransposeMatrixfARB +glMultTransposeMatrixxOES +glNamedBufferAttachMemoryNV +glNamedBufferData +glNamedBufferDataEXT +glNamedBufferPageCommitmentARB +glNamedBufferPageCommitmentEXT +glNamedBufferStorage +glNamedBufferStorageEXT +glNamedBufferStorageExternalEXT +glNamedBufferStorageMemEXT +glNamedBufferSubData +glNamedBufferSubDataEXT +glNamedCopyBufferSubDataEXT +glNamedFramebufferDrawBuffer +glNamedFramebufferDrawBuffers +glNamedFramebufferParameteri +glNamedFramebufferParameteriEXT +glNamedFramebufferReadBuffer +glNamedFramebufferRenderbuffer +glNamedFramebufferRenderbufferEXT +glNamedFramebufferSampleLocationsfvARB +glNamedFramebufferSampleLocationsfvNV +glNamedFramebufferSamplePositionsfvAMD +glNamedFramebufferTexture +glNamedFramebufferTexture1DEXT +glNamedFramebufferTexture2DEXT +glNamedFramebufferTexture3DEXT +glNamedFramebufferTextureEXT +glNamedFramebufferTextureFaceEXT +glNamedFramebufferTextureLayer +glNamedFramebufferTextureLayerEXT +glNamedProgramLocalParameter4dEXT +glNamedProgramLocalParameter4dvEXT +glNamedProgramLocalParameter4fEXT +glNamedProgramLocalParameter4fvEXT +glNamedProgramLocalParameterI4iEXT +glNamedProgramLocalParameterI4ivEXT +glNamedProgramLocalParameterI4uiEXT +glNamedProgramLocalParameterI4uivEXT +glNamedProgramLocalParameters4fvEXT +glNamedProgramLocalParametersI4ivEXT +glNamedProgramLocalParametersI4uivEXT +glNamedProgramStringEXT +glNamedRenderbufferStorage +glNamedRenderbufferStorageEXT +glNamedRenderbufferStorageMultisample +glNamedRenderbufferStorageMultisampleAdvancedAMD +glNamedRenderbufferStorageMultisampleCoverageEXT +glNamedRenderbufferStorageMultisampleEXT +glNamedStringARB +glNewList +glNewObjectBufferATI +glNormal3b +glNormal3bv +glNormal3d +glNormal3dv +glNormal3f +glNormal3fv +glNormal3fVertex3fSUN +glNormal3fVertex3fvSUN +glNormal3hNV +glNormal3hvNV +glNormal3i +glNormal3iv +glNormal3s +glNormal3sv +glNormal3x +glNormal3xOES +glNormal3xvOES +glNormalFormatNV +glNormalP3ui +glNormalP3uiv +glNormalPointer +glNormalPointerEXT +glNormalPointerListIBM +glNormalPointervINTEL +glNormalStream3bATI +glNormalStream3bvATI +glNormalStream3dATI +glNormalStream3dvATI +glNormalStream3fATI +glNormalStream3fvATI +glNormalStream3iATI +glNormalStream3ivATI +glNormalStream3sATI +glNormalStream3svATI +glNVENCInterOpFunctionNVX +glObjectLabel +glObjectLabelKHR +glObjectLabelOES +glObjectPtrLabel +glObjectPtrLabelKHR +glObjectPtrLabelOES +glObjectPurgeableAPPLE +glObjectUnpurgeableAPPLE +glOrtho +glOrthof +glOrthofOES +glOrthox +glOrthoxOES +glPassTexCoordATI +glPassThrough +glPassThroughxOES +glPatchParameterfv +glPatchParameterfvEXT +glPatchParameterfvNV +glPatchParameteri +glPatchParameteriEXT +glPatchParameteriNV +glPatchParameteriOES +glPathColorGenNV +glPathCommandsNV +glPathCoordsNV +glPathCoverDepthFuncNV +glPathDashArrayNV +glPathFogGenNV +glPathGlyphIndexArrayNV +glPathGlyphIndexRangeNV +glPathGlyphRangeNV +glPathGlyphsNV +glPathMemoryGlyphIndexArrayNV +glPathParameterfNV +glPathParameterfvNV +glPathParameteriNV +glPathParameterivNV +glPathStencilDepthOffsetNV +glPathStencilFuncNV +glPathStringNV +glPathSubCommandsNV +glPathSubCoordsNV +glPathTexGenNV +glPauseTransformFeedback +glPauseTransformFeedbackEXT +glPauseTransformFeedbackNV +glPixelDataRangeNV +glPixelMapfv +glPixelMapuiv +glPixelMapusv +glPixelMapx +glPixelStoref +glPixelStorei +glPixelStorex +glPixelTexGenParameterfSGIS +glPixelTexGenParameterfvSGIS +glPixelTexGenParameteriSGIS +glPixelTexGenParameterivSGIS +glPixelTexGenSGIX +glPixelTransferf +glPixelTransferi +glPixelTransferxOES +glPixelTransformParameterfEXT +glPixelTransformParameterfvEXT +glPixelTransformParameteriEXT +glPixelTransformParameterivEXT +glPixelZoom +glPixelZoomxOES +glPNTrianglesfATI +glPNTrianglesiATI +glPointAlongPathNV +glPointParameterf +glPointParameterfARB +glPointParameterfEXT +glPointParameterfSGIS +glPointParameterfv +glPointParameterfvARB +glPointParameterfvEXT +glPointParameterfvSGIS +glPointParameteri +glPointParameteriNV +glPointParameteriv +glPointParameterivNV +glPointParameterx +glPointParameterxOES +glPointParameterxv +glPointParameterxvOES +glPointSize +glPointSizePointerOES +glPointSizex +glPointSizexOES +glPollAsyncSGIX +glPollInstrumentsSGIX +glPolygonMode +glPolygonModeNV +glPolygonOffset +glPolygonOffsetClamp +glPolygonOffsetClampEXT +glPolygonOffsetEXT +glPolygonOffsetx +glPolygonOffsetxOES +glPolygonStipple +glPopAttrib +glPopClientAttrib +glPopDebugGroup +glPopDebugGroupKHR +glPopDebugGroupOES +glPopGroupMarkerEXT +glPopMatrix +glPopName +glPresentFrameDualFillNV +glPresentFrameKeyedNV +glPrimitiveBoundingBox +glPrimitiveBoundingBoxARB +glPrimitiveBoundingBoxEXT +glPrimitiveBoundingBoxOES +glPrimitiveRestart +glPrimitiveRestartIndex +glPrimitiveRestartIndexNV +glPrimitiveRestartNV +glPrioritizeTextures +glPrioritizeTexturesEXT +glPrioritizeTexturesxOES +glProgramBinary +glProgramBinaryOES +glProgramBufferParametersfvNV +glProgramBufferParametersIivNV +glProgramBufferParametersIuivNV +glProgramEnvParameter4dARB +glProgramEnvParameter4dvARB +glProgramEnvParameter4fARB +glProgramEnvParameter4fvARB +glProgramEnvParameterI4iNV +glProgramEnvParameterI4ivNV +glProgramEnvParameterI4uiNV +glProgramEnvParameterI4uivNV +glProgramEnvParameters4fvEXT +glProgramEnvParametersI4ivNV +glProgramEnvParametersI4uivNV +glProgramLocalParameter4dARB +glProgramLocalParameter4dvARB +glProgramLocalParameter4fARB +glProgramLocalParameter4fvARB +glProgramLocalParameterI4iNV +glProgramLocalParameterI4ivNV +glProgramLocalParameterI4uiNV +glProgramLocalParameterI4uivNV +glProgramLocalParameters4fvEXT +glProgramLocalParametersI4ivNV +glProgramLocalParametersI4uivNV +glProgramNamedParameter4dNV +glProgramNamedParameter4dvNV +glProgramNamedParameter4fNV +glProgramNamedParameter4fvNV +glProgramParameter4dNV +glProgramParameter4dvNV +glProgramParameter4fNV +glProgramParameter4fvNV +glProgramParameteri +glProgramParameteriARB +glProgramParameteriEXT +glProgramParameters4dvNV +glProgramParameters4fvNV +glProgramPathFragmentInputGenNV +glProgramStringARB +glProgramSubroutineParametersuivNV +glProgramUniform1d +glProgramUniform1dEXT +glProgramUniform1dv +glProgramUniform1dvEXT +glProgramUniform1f +glProgramUniform1fEXT +glProgramUniform1fv +glProgramUniform1fvEXT +glProgramUniform1i +glProgramUniform1i64ARB +glProgramUniform1i64NV +glProgramUniform1i64vARB +glProgramUniform1i64vNV +glProgramUniform1iEXT +glProgramUniform1iv +glProgramUniform1ivEXT +glProgramUniform1ui +glProgramUniform1ui64ARB +glProgramUniform1ui64NV +glProgramUniform1ui64vARB +glProgramUniform1ui64vNV +glProgramUniform1uiEXT +glProgramUniform1uiv +glProgramUniform1uivEXT +glProgramUniform2d +glProgramUniform2dEXT +glProgramUniform2dv +glProgramUniform2dvEXT +glProgramUniform2f +glProgramUniform2fEXT +glProgramUniform2fv +glProgramUniform2fvEXT +glProgramUniform2i +glProgramUniform2i64ARB +glProgramUniform2i64NV +glProgramUniform2i64vARB +glProgramUniform2i64vNV +glProgramUniform2iEXT +glProgramUniform2iv +glProgramUniform2ivEXT +glProgramUniform2ui +glProgramUniform2ui64ARB +glProgramUniform2ui64NV +glProgramUniform2ui64vARB +glProgramUniform2ui64vNV +glProgramUniform2uiEXT +glProgramUniform2uiv +glProgramUniform2uivEXT +glProgramUniform3d +glProgramUniform3dEXT +glProgramUniform3dv +glProgramUniform3dvEXT +glProgramUniform3f +glProgramUniform3fEXT +glProgramUniform3fv +glProgramUniform3fvEXT +glProgramUniform3i +glProgramUniform3i64ARB +glProgramUniform3i64NV +glProgramUniform3i64vARB +glProgramUniform3i64vNV +glProgramUniform3iEXT +glProgramUniform3iv +glProgramUniform3ivEXT +glProgramUniform3ui +glProgramUniform3ui64ARB +glProgramUniform3ui64NV +glProgramUniform3ui64vARB +glProgramUniform3ui64vNV +glProgramUniform3uiEXT +glProgramUniform3uiv +glProgramUniform3uivEXT +glProgramUniform4d +glProgramUniform4dEXT +glProgramUniform4dv +glProgramUniform4dvEXT +glProgramUniform4f +glProgramUniform4fEXT +glProgramUniform4fv +glProgramUniform4fvEXT +glProgramUniform4i +glProgramUniform4i64ARB +glProgramUniform4i64NV +glProgramUniform4i64vARB +glProgramUniform4i64vNV +glProgramUniform4iEXT +glProgramUniform4iv +glProgramUniform4ivEXT +glProgramUniform4ui +glProgramUniform4ui64ARB +glProgramUniform4ui64NV +glProgramUniform4ui64vARB +glProgramUniform4ui64vNV +glProgramUniform4uiEXT +glProgramUniform4uiv +glProgramUniform4uivEXT +glProgramUniformHandleui64ARB +glProgramUniformHandleui64IMG +glProgramUniformHandleui64NV +glProgramUniformHandleui64vARB +glProgramUniformHandleui64vIMG +glProgramUniformHandleui64vNV +glProgramUniformMatrix2dv +glProgramUniformMatrix2dvEXT +glProgramUniformMatrix2fv +glProgramUniformMatrix2fvEXT +glProgramUniformMatrix2x3dv +glProgramUniformMatrix2x3dvEXT +glProgramUniformMatrix2x3fv +glProgramUniformMatrix2x3fvEXT +glProgramUniformMatrix2x4dv +glProgramUniformMatrix2x4dvEXT +glProgramUniformMatrix2x4fv +glProgramUniformMatrix2x4fvEXT +glProgramUniformMatrix3dv +glProgramUniformMatrix3dvEXT +glProgramUniformMatrix3fv +glProgramUniformMatrix3fvEXT +glProgramUniformMatrix3x2dv +glProgramUniformMatrix3x2dvEXT +glProgramUniformMatrix3x2fv +glProgramUniformMatrix3x2fvEXT +glProgramUniformMatrix3x4dv +glProgramUniformMatrix3x4dvEXT +glProgramUniformMatrix3x4fv +glProgramUniformMatrix3x4fvEXT +glProgramUniformMatrix4dv +glProgramUniformMatrix4dvEXT +glProgramUniformMatrix4fv +glProgramUniformMatrix4fvEXT +glProgramUniformMatrix4x2dv +glProgramUniformMatrix4x2dvEXT +glProgramUniformMatrix4x2fv +glProgramUniformMatrix4x2fvEXT +glProgramUniformMatrix4x3dv +glProgramUniformMatrix4x3dvEXT +glProgramUniformMatrix4x3fv +glProgramUniformMatrix4x3fvEXT +glProgramUniformui64NV +glProgramUniformui64vNV +glProgramVertexLimitNV +glProvokingVertex +glProvokingVertexEXT +glPushAttrib +glPushClientAttrib +glPushClientAttribDefaultEXT +glPushDebugGroup +glPushDebugGroupKHR +glPushDebugGroupOES +glPushGroupMarkerEXT +glPushMatrix +glPushName +glQueryCounter +glQueryCounterEXT +glQueryCounterNV +glQueryMatrixxOES +glQueryObjectParameteruiAMD +glQueryResourceNV +glQueryResourceTagNV +glRasterPos2d +glRasterPos2dv +glRasterPos2f +glRasterPos2fv +glRasterPos2i +glRasterPos2iv +glRasterPos2s +glRasterPos2sv +glRasterPos2xOES +glRasterPos2xvOES +glRasterPos3d +glRasterPos3dv +glRasterPos3f +glRasterPos3fv +glRasterPos3i +glRasterPos3iv +glRasterPos3s +glRasterPos3sv +glRasterPos3xOES +glRasterPos3xvOES +glRasterPos4d +glRasterPos4dv +glRasterPos4f +glRasterPos4fv +glRasterPos4i +glRasterPos4iv +glRasterPos4s +glRasterPos4sv +glRasterPos4xOES +glRasterPos4xvOES +glRasterSamplesEXT +glReadBuffer +glReadBufferIndexedEXT +glReadBufferNV +glReadInstrumentsSGIX +glReadnPixels +glReadnPixelsARB +glReadnPixelsEXT +glReadnPixelsKHR +glReadPixels +glRectd +glRectdv +glRectf +glRectfv +glRecti +glRectiv +glRects +glRectsv +glRectxOES +glRectxvOES +glReferencePlaneSGIX +glReleaseKeyedMutexWin32EXT +glReleaseShaderCompiler +glRenderbufferStorage +glRenderbufferStorageEXT +glRenderbufferStorageMultisample +glRenderbufferStorageMultisampleAdvancedAMD +glRenderbufferStorageMultisampleANGLE +glRenderbufferStorageMultisampleAPPLE +glRenderbufferStorageMultisampleCoverageNV +glRenderbufferStorageMultisampleEXT +glRenderbufferStorageMultisampleIMG +glRenderbufferStorageMultisampleNV +glRenderbufferStorageOES +glRenderGpuMaskNV +glRenderMode +glReplacementCodePointerSUN +glReplacementCodeubSUN +glReplacementCodeubvSUN +glReplacementCodeuiColor3fVertex3fSUN +glReplacementCodeuiColor3fVertex3fvSUN +glReplacementCodeuiColor4fNormal3fVertex3fSUN +glReplacementCodeuiColor4fNormal3fVertex3fvSUN +glReplacementCodeuiColor4ubVertex3fSUN +glReplacementCodeuiColor4ubVertex3fvSUN +glReplacementCodeuiNormal3fVertex3fSUN +glReplacementCodeuiNormal3fVertex3fvSUN +glReplacementCodeuiSUN +glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +glReplacementCodeuiTexCoord2fVertex3fSUN +glReplacementCodeuiTexCoord2fVertex3fvSUN +glReplacementCodeuiVertex3fSUN +glReplacementCodeuiVertex3fvSUN +glReplacementCodeuivSUN +glReplacementCodeusSUN +glReplacementCodeusvSUN +glRequestResidentProgramsNV +glResetHistogram +glResetHistogramEXT +glResetMemoryObjectParameterNV +glResetMinmax +glResetMinmaxEXT +glResizeBuffersMESA +glResolveDepthValuesNV +glResolveMultisampleFramebufferAPPLE +glResumeTransformFeedback +glResumeTransformFeedbackEXT +glResumeTransformFeedbackNV +glRotated +glRotatef +glRotatex +glRotatexOES +glSampleCoverage +glSampleCoverageARB +glSampleCoveragex +glSampleCoveragexOES +glSampleMapATI +glSampleMaskEXT +glSampleMaski +glSampleMaskIndexedNV +glSampleMaskSGIS +glSamplePatternEXT +glSamplePatternSGIS +glSamplerParameterf +glSamplerParameterfv +glSamplerParameteri +glSamplerParameterIiv +glSamplerParameterIivEXT +glSamplerParameterIivOES +glSamplerParameterIuiv +glSamplerParameterIuivEXT +glSamplerParameterIuivOES +glSamplerParameteriv +glScaled +glScalef +glScalex +glScalexOES +glScissor +glScissorArrayv +glScissorArrayvNV +glScissorArrayvOES +glScissorExclusiveArrayvNV +glScissorExclusiveNV +glScissorIndexed +glScissorIndexedNV +glScissorIndexedOES +glScissorIndexedv +glScissorIndexedvNV +glScissorIndexedvOES +glSecondaryColor3b +glSecondaryColor3bEXT +glSecondaryColor3bv +glSecondaryColor3bvEXT +glSecondaryColor3d +glSecondaryColor3dEXT +glSecondaryColor3dv +glSecondaryColor3dvEXT +glSecondaryColor3f +glSecondaryColor3fEXT +glSecondaryColor3fv +glSecondaryColor3fvEXT +glSecondaryColor3hNV +glSecondaryColor3hvNV +glSecondaryColor3i +glSecondaryColor3iEXT +glSecondaryColor3iv +glSecondaryColor3ivEXT +glSecondaryColor3s +glSecondaryColor3sEXT +glSecondaryColor3sv +glSecondaryColor3svEXT +glSecondaryColor3ub +glSecondaryColor3ubEXT +glSecondaryColor3ubv +glSecondaryColor3ubvEXT +glSecondaryColor3ui +glSecondaryColor3uiEXT +glSecondaryColor3uiv +glSecondaryColor3uivEXT +glSecondaryColor3us +glSecondaryColor3usEXT +glSecondaryColor3usv +glSecondaryColor3usvEXT +glSecondaryColorFormatNV +glSecondaryColorP3ui +glSecondaryColorP3uiv +glSecondaryColorPointer +glSecondaryColorPointerEXT +glSecondaryColorPointerListIBM +glSelectBuffer +glSelectPerfMonitorCountersAMD +glSemaphoreParameterui64vEXT +glSeparableFilter2D +glSeparableFilter2DEXT +glSetFenceAPPLE +glSetFenceNV +glSetFragmentShaderConstantATI +glSetInvariantEXT +glSetLocalConstantEXT +glSetMultisamplefvAMD +glShadeModel +glShaderBinary +glShaderOp1EXT +glShaderOp2EXT +glShaderOp3EXT +glShaderSource +glShaderSourceARB +glShaderStorageBlockBinding +glShadingRateImageBarrierNV +glShadingRateImagePaletteNV +glShadingRateSampleOrderCustomNV +glShadingRateSampleOrderNV +glSharpenTexFuncSGIS +glSignalSemaphoreEXT +glSignalSemaphoreui64NVX +glSignalVkFenceNV +glSignalVkSemaphoreNV +glSpecializeShader +glSpecializeShaderARB +glSpriteParameterfSGIX +glSpriteParameterfvSGIX +glSpriteParameteriSGIX +glSpriteParameterivSGIX +glStartInstrumentsSGIX +glStartTilingQCOM +glStateCaptureNV +glStencilClearTagEXT +glStencilFillPathInstancedNV +glStencilFillPathNV +glStencilFunc +glStencilFuncSeparate +glStencilFuncSeparateATI +glStencilMask +glStencilMaskSeparate +glStencilOp +glStencilOpSeparate +glStencilOpSeparateATI +glStencilOpValueAMD +glStencilStrokePathInstancedNV +glStencilStrokePathNV +glStencilThenCoverFillPathInstancedNV +glStencilThenCoverFillPathNV +glStencilThenCoverStrokePathInstancedNV +glStencilThenCoverStrokePathNV +glStopInstrumentsSGIX +glStringMarkerGREMEDY +glSubpixelPrecisionBiasNV +glSwizzleEXT +glSyncTextureINTEL +glTagSampleBufferSGIX +glTangent3bEXT +glTangent3bvEXT +glTangent3dEXT +glTangent3dvEXT +glTangent3fEXT +glTangent3fvEXT +glTangent3iEXT +glTangent3ivEXT +glTangent3sEXT +glTangent3svEXT +glTangentPointerEXT +glTbufferMask3DFX +glTessellationFactorAMD +glTessellationModeAMD +glTestFenceAPPLE +glTestFenceNV +glTestObjectAPPLE +glTexAttachMemoryNV +glTexBuffer +glTexBufferARB +glTexBufferEXT +glTexBufferOES +glTexBufferRange +glTexBufferRangeEXT +glTexBufferRangeOES +glTexBumpParameterfvATI +glTexBumpParameterivATI +glTexCoord1bOES +glTexCoord1bvOES +glTexCoord1d +glTexCoord1dv +glTexCoord1f +glTexCoord1fv +glTexCoord1hNV +glTexCoord1hvNV +glTexCoord1i +glTexCoord1iv +glTexCoord1s +glTexCoord1sv +glTexCoord1xOES +glTexCoord1xvOES +glTexCoord2bOES +glTexCoord2bvOES +glTexCoord2d +glTexCoord2dv +glTexCoord2f +glTexCoord2fColor3fVertex3fSUN +glTexCoord2fColor3fVertex3fvSUN +glTexCoord2fColor4fNormal3fVertex3fSUN +glTexCoord2fColor4fNormal3fVertex3fvSUN +glTexCoord2fColor4ubVertex3fSUN +glTexCoord2fColor4ubVertex3fvSUN +glTexCoord2fNormal3fVertex3fSUN +glTexCoord2fNormal3fVertex3fvSUN +glTexCoord2fv +glTexCoord2fVertex3fSUN +glTexCoord2fVertex3fvSUN +glTexCoord2hNV +glTexCoord2hvNV +glTexCoord2i +glTexCoord2iv +glTexCoord2s +glTexCoord2sv +glTexCoord2xOES +glTexCoord2xvOES +glTexCoord3bOES +glTexCoord3bvOES +glTexCoord3d +glTexCoord3dv +glTexCoord3f +glTexCoord3fv +glTexCoord3hNV +glTexCoord3hvNV +glTexCoord3i +glTexCoord3iv +glTexCoord3s +glTexCoord3sv +glTexCoord3xOES +glTexCoord3xvOES +glTexCoord4bOES +glTexCoord4bvOES +glTexCoord4d +glTexCoord4dv +glTexCoord4f +glTexCoord4fColor4fNormal3fVertex4fSUN +glTexCoord4fColor4fNormal3fVertex4fvSUN +glTexCoord4fv +glTexCoord4fVertex4fSUN +glTexCoord4fVertex4fvSUN +glTexCoord4hNV +glTexCoord4hvNV +glTexCoord4i +glTexCoord4iv +glTexCoord4s +glTexCoord4sv +glTexCoord4xOES +glTexCoord4xvOES +glTexCoordFormatNV +glTexCoordP1ui +glTexCoordP1uiv +glTexCoordP2ui +glTexCoordP2uiv +glTexCoordP3ui +glTexCoordP3uiv +glTexCoordP4ui +glTexCoordP4uiv +glTexCoordPointer +glTexCoordPointerEXT +glTexCoordPointerListIBM +glTexCoordPointervINTEL +glTexEnvf +glTexEnvfv +glTexEnvi +glTexEnviv +glTexEnvx +glTexEnvxOES +glTexEnvxv +glTexEnvxvOES +glTexFilterFuncSGIS +glTexGend +glTexGendv +glTexGenf +glTexGenfOES +glTexGenfv +glTexGenfvOES +glTexGeni +glTexGeniOES +glTexGeniv +glTexGenivOES +glTexGenxOES +glTexGenxvOES +glTexImage1D +glTexImage2D +glTexImage2DMultisample +glTexImage2DMultisampleCoverageNV +glTexImage3D +glTexImage3DEXT +glTexImage3DMultisample +glTexImage3DMultisampleCoverageNV +glTexImage3DNV +glTexImage3DOES +glTexImage4DSGIS +glTexPageCommitmentARB +glTexPageCommitmentEXT +glTexParameterf +glTexParameterfv +glTexParameteri +glTexParameterIiv +glTexParameterIivEXT +glTexParameterIivOES +glTexParameterIuiv +glTexParameterIuivEXT +glTexParameterIuivOES +glTexParameteriv +glTexParameterx +glTexParameterxOES +glTexParameterxv +glTexParameterxvOES +glTexRenderbufferNV +glTexStorage1D +glTexStorage1DEXT +glTexStorage2D +glTexStorage2DEXT +glTexStorage2DMultisample +glTexStorage3D +glTexStorage3DEXT +glTexStorage3DMultisample +glTexStorage3DMultisampleOES +glTexStorageMem1DEXT +glTexStorageMem2DEXT +glTexStorageMem2DMultisampleEXT +glTexStorageMem3DEXT +glTexStorageMem3DMultisampleEXT +glTexStorageSparseAMD +glTexSubImage1D +glTexSubImage1DEXT +glTexSubImage2D +glTexSubImage2DEXT +glTexSubImage3D +glTexSubImage3DEXT +glTexSubImage3DNV +glTexSubImage3DOES +glTexSubImage4DSGIS +glTextureAttachMemoryNV +glTextureBarrier +glTextureBarrierNV +glTextureBuffer +glTextureBufferEXT +glTextureBufferRange +glTextureBufferRangeEXT +glTextureColorMaskSGIS +glTextureFoveationParametersQCOM +glTextureImage1DEXT +glTextureImage2DEXT +glTextureImage2DMultisampleCoverageNV +glTextureImage2DMultisampleNV +glTextureImage3DEXT +glTextureImage3DMultisampleCoverageNV +glTextureImage3DMultisampleNV +glTextureLightEXT +glTextureMaterialEXT +glTextureNormalEXT +glTexturePageCommitmentEXT +glTextureParameterf +glTextureParameterfEXT +glTextureParameterfv +glTextureParameterfvEXT +glTextureParameteri +glTextureParameteriEXT +glTextureParameterIiv +glTextureParameterIivEXT +glTextureParameterIuiv +glTextureParameterIuivEXT +glTextureParameteriv +glTextureParameterivEXT +glTextureRangeAPPLE +glTextureRenderbufferEXT +glTextureStorage1D +glTextureStorage1DEXT +glTextureStorage2D +glTextureStorage2DEXT +glTextureStorage2DMultisample +glTextureStorage2DMultisampleEXT +glTextureStorage3D +glTextureStorage3DEXT +glTextureStorage3DMultisample +glTextureStorage3DMultisampleEXT +glTextureStorageMem1DEXT +glTextureStorageMem2DEXT +glTextureStorageMem2DMultisampleEXT +glTextureStorageMem3DEXT +glTextureStorageMem3DMultisampleEXT +glTextureStorageSparseAMD +glTextureSubImage1D +glTextureSubImage1DEXT +glTextureSubImage2D +glTextureSubImage2DEXT +glTextureSubImage3D +glTextureSubImage3DEXT +glTextureView +glTextureViewEXT +glTextureViewOES +glTrackMatrixNV +glTransformFeedbackAttribsNV +glTransformFeedbackBufferBase +glTransformFeedbackBufferRange +glTransformFeedbackStreamAttribsNV +glTransformFeedbackVaryings +glTransformFeedbackVaryingsEXT +glTransformFeedbackVaryingsNV +glTransformPathNV +glTranslated +glTranslatef +glTranslatex +glTranslatexOES +glUniform1d +glUniform1dv +glUniform1f +glUniform1fARB +glUniform1fv +glUniform1fvARB +glUniform1i +glUniform1i64ARB +glUniform1i64NV +glUniform1i64vARB +glUniform1i64vNV +glUniform1iARB +glUniform1iv +glUniform1ivARB +glUniform1ui +glUniform1ui64ARB +glUniform1ui64NV +glUniform1ui64vARB +glUniform1ui64vNV +glUniform1uiEXT +glUniform1uiv +glUniform1uivEXT +glUniform2d +glUniform2dv +glUniform2f +glUniform2fARB +glUniform2fv +glUniform2fvARB +glUniform2i +glUniform2i64ARB +glUniform2i64NV +glUniform2i64vARB +glUniform2i64vNV +glUniform2iARB +glUniform2iv +glUniform2ivARB +glUniform2ui +glUniform2ui64ARB +glUniform2ui64NV +glUniform2ui64vARB +glUniform2ui64vNV +glUniform2uiEXT +glUniform2uiv +glUniform2uivEXT +glUniform3d +glUniform3dv +glUniform3f +glUniform3fARB +glUniform3fv +glUniform3fvARB +glUniform3i +glUniform3i64ARB +glUniform3i64NV +glUniform3i64vARB +glUniform3i64vNV +glUniform3iARB +glUniform3iv +glUniform3ivARB +glUniform3ui +glUniform3ui64ARB +glUniform3ui64NV +glUniform3ui64vARB +glUniform3ui64vNV +glUniform3uiEXT +glUniform3uiv +glUniform3uivEXT +glUniform4d +glUniform4dv +glUniform4f +glUniform4fARB +glUniform4fv +glUniform4fvARB +glUniform4i +glUniform4i64ARB +glUniform4i64NV +glUniform4i64vARB +glUniform4i64vNV +glUniform4iARB +glUniform4iv +glUniform4ivARB +glUniform4ui +glUniform4ui64ARB +glUniform4ui64NV +glUniform4ui64vARB +glUniform4ui64vNV +glUniform4uiEXT +glUniform4uiv +glUniform4uivEXT +glUniformBlockBinding +glUniformBufferEXT +glUniformHandleui64ARB +glUniformHandleui64IMG +glUniformHandleui64NV +glUniformHandleui64vARB +glUniformHandleui64vIMG +glUniformHandleui64vNV +glUniformMatrix2dv +glUniformMatrix2fv +glUniformMatrix2fvARB +glUniformMatrix2x3dv +glUniformMatrix2x3fv +glUniformMatrix2x3fvNV +glUniformMatrix2x4dv +glUniformMatrix2x4fv +glUniformMatrix2x4fvNV +glUniformMatrix3dv +glUniformMatrix3fv +glUniformMatrix3fvARB +glUniformMatrix3x2dv +glUniformMatrix3x2fv +glUniformMatrix3x2fvNV +glUniformMatrix3x4dv +glUniformMatrix3x4fv +glUniformMatrix3x4fvNV +glUniformMatrix4dv +glUniformMatrix4fv +glUniformMatrix4fvARB +glUniformMatrix4x2dv +glUniformMatrix4x2fv +glUniformMatrix4x2fvNV +glUniformMatrix4x3dv +glUniformMatrix4x3fv +glUniformMatrix4x3fvNV +glUniformSubroutinesuiv +glUniformui64NV +glUniformui64vNV +glUnlockArraysEXT +glUnmapBuffer +glUnmapBufferARB +glUnmapBufferOES +glUnmapNamedBuffer +glUnmapNamedBufferEXT +glUnmapObjectBufferATI +glUnmapTexture2DINTEL +glUpdateObjectBufferATI +glUploadGpuMaskNVX +glUseProgram +glUseProgramObjectARB +glUseProgramStages +glUseProgramStagesEXT +glUseShaderProgramEXT +glValidateProgram +glValidateProgramARB +glValidateProgramPipeline +glValidateProgramPipelineEXT +glValidBackBufferHintAutodesk +glVariantArrayObjectATI +glVariantbvEXT +glVariantdvEXT +glVariantfvEXT +glVariantivEXT +glVariantPointerEXT +glVariantsvEXT +glVariantubvEXT +glVariantuivEXT +glVariantusvEXT +glVDPAUFiniNV +glVDPAUGetSurfaceivNV +glVDPAUInitNV +glVDPAUIsSurfaceNV +glVDPAUMapSurfacesNV +glVDPAURegisterOutputSurfaceNV +glVDPAURegisterVideoSurfaceNV +glVDPAURegisterVideoSurfaceWithPictureStructureNV +glVDPAUSurfaceAccessNV +glVDPAUUnmapSurfacesNV +glVDPAUUnregisterSurfaceNV +glVertex2bOES +glVertex2bvOES +glVertex2d +glVertex2dv +glVertex2f +glVertex2fv +glVertex2hNV +glVertex2hvNV +glVertex2i +glVertex2iv +glVertex2s +glVertex2sv +glVertex2xOES +glVertex2xvOES +glVertex3bOES +glVertex3bvOES +glVertex3d +glVertex3dv +glVertex3f +glVertex3fv +glVertex3hNV +glVertex3hvNV +glVertex3i +glVertex3iv +glVertex3s +glVertex3sv +glVertex3xOES +glVertex3xvOES +glVertex4bOES +glVertex4bvOES +glVertex4d +glVertex4dv +glVertex4f +glVertex4fv +glVertex4hNV +glVertex4hvNV +glVertex4i +glVertex4iv +glVertex4s +glVertex4sv +glVertex4xOES +glVertex4xvOES +glVertexArrayAttribBinding +glVertexArrayAttribFormat +glVertexArrayAttribIFormat +glVertexArrayAttribLFormat +glVertexArrayBindingDivisor +glVertexArrayBindVertexBufferEXT +glVertexArrayColorOffsetEXT +glVertexArrayEdgeFlagOffsetEXT +glVertexArrayElementBuffer +glVertexArrayFogCoordOffsetEXT +glVertexArrayIndexOffsetEXT +glVertexArrayMultiTexCoordOffsetEXT +glVertexArrayNormalOffsetEXT +glVertexArrayParameteriAPPLE +glVertexArrayRangeAPPLE +glVertexArrayRangeNV +glVertexArraySecondaryColorOffsetEXT +glVertexArrayTexCoordOffsetEXT +glVertexArrayVertexAttribBindingEXT +glVertexArrayVertexAttribDivisorEXT +glVertexArrayVertexAttribFormatEXT +glVertexArrayVertexAttribIFormatEXT +glVertexArrayVertexAttribIOffsetEXT +glVertexArrayVertexAttribLFormatEXT +glVertexArrayVertexAttribLOffsetEXT +glVertexArrayVertexAttribOffsetEXT +glVertexArrayVertexBindingDivisorEXT +glVertexArrayVertexBuffer +glVertexArrayVertexBuffers +glVertexArrayVertexOffsetEXT +glVertexAttrib1d +glVertexAttrib1dARB +glVertexAttrib1dNV +glVertexAttrib1dv +glVertexAttrib1dvARB +glVertexAttrib1dvNV +glVertexAttrib1f +glVertexAttrib1fARB +glVertexAttrib1fNV +glVertexAttrib1fv +glVertexAttrib1fvARB +glVertexAttrib1fvNV +glVertexAttrib1hNV +glVertexAttrib1hvNV +glVertexAttrib1s +glVertexAttrib1sARB +glVertexAttrib1sNV +glVertexAttrib1sv +glVertexAttrib1svARB +glVertexAttrib1svNV +glVertexAttrib2d +glVertexAttrib2dARB +glVertexAttrib2dNV +glVertexAttrib2dv +glVertexAttrib2dvARB +glVertexAttrib2dvNV +glVertexAttrib2f +glVertexAttrib2fARB +glVertexAttrib2fNV +glVertexAttrib2fv +glVertexAttrib2fvARB +glVertexAttrib2fvNV +glVertexAttrib2hNV +glVertexAttrib2hvNV +glVertexAttrib2s +glVertexAttrib2sARB +glVertexAttrib2sNV +glVertexAttrib2sv +glVertexAttrib2svARB +glVertexAttrib2svNV +glVertexAttrib3d +glVertexAttrib3dARB +glVertexAttrib3dNV +glVertexAttrib3dv +glVertexAttrib3dvARB +glVertexAttrib3dvNV +glVertexAttrib3f +glVertexAttrib3fARB +glVertexAttrib3fNV +glVertexAttrib3fv +glVertexAttrib3fvARB +glVertexAttrib3fvNV +glVertexAttrib3hNV +glVertexAttrib3hvNV +glVertexAttrib3s +glVertexAttrib3sARB +glVertexAttrib3sNV +glVertexAttrib3sv +glVertexAttrib3svARB +glVertexAttrib3svNV +glVertexAttrib4bv +glVertexAttrib4bvARB +glVertexAttrib4d +glVertexAttrib4dARB +glVertexAttrib4dNV +glVertexAttrib4dv +glVertexAttrib4dvARB +glVertexAttrib4dvNV +glVertexAttrib4f +glVertexAttrib4fARB +glVertexAttrib4fNV +glVertexAttrib4fv +glVertexAttrib4fvARB +glVertexAttrib4fvNV +glVertexAttrib4hNV +glVertexAttrib4hvNV +glVertexAttrib4iv +glVertexAttrib4ivARB +glVertexAttrib4Nbv +glVertexAttrib4NbvARB +glVertexAttrib4Niv +glVertexAttrib4NivARB +glVertexAttrib4Nsv +glVertexAttrib4NsvARB +glVertexAttrib4Nub +glVertexAttrib4NubARB +glVertexAttrib4Nubv +glVertexAttrib4NubvARB +glVertexAttrib4Nuiv +glVertexAttrib4NuivARB +glVertexAttrib4Nusv +glVertexAttrib4NusvARB +glVertexAttrib4s +glVertexAttrib4sARB +glVertexAttrib4sNV +glVertexAttrib4sv +glVertexAttrib4svARB +glVertexAttrib4svNV +glVertexAttrib4ubNV +glVertexAttrib4ubv +glVertexAttrib4ubvARB +glVertexAttrib4ubvNV +glVertexAttrib4uiv +glVertexAttrib4uivARB +glVertexAttrib4usv +glVertexAttrib4usvARB +glVertexAttribArrayObjectATI +glVertexAttribBinding +glVertexAttribDivisor +glVertexAttribDivisorANGLE +glVertexAttribDivisorARB +glVertexAttribDivisorEXT +glVertexAttribDivisorNV +glVertexAttribFormat +glVertexAttribFormatNV +glVertexAttribI1i +glVertexAttribI1iEXT +glVertexAttribI1iv +glVertexAttribI1ivEXT +glVertexAttribI1ui +glVertexAttribI1uiEXT +glVertexAttribI1uiv +glVertexAttribI1uivEXT +glVertexAttribI2i +glVertexAttribI2iEXT +glVertexAttribI2iv +glVertexAttribI2ivEXT +glVertexAttribI2ui +glVertexAttribI2uiEXT +glVertexAttribI2uiv +glVertexAttribI2uivEXT +glVertexAttribI3i +glVertexAttribI3iEXT +glVertexAttribI3iv +glVertexAttribI3ivEXT +glVertexAttribI3ui +glVertexAttribI3uiEXT +glVertexAttribI3uiv +glVertexAttribI3uivEXT +glVertexAttribI4bv +glVertexAttribI4bvEXT +glVertexAttribI4i +glVertexAttribI4iEXT +glVertexAttribI4iv +glVertexAttribI4ivEXT +glVertexAttribI4sv +glVertexAttribI4svEXT +glVertexAttribI4ubv +glVertexAttribI4ubvEXT +glVertexAttribI4ui +glVertexAttribI4uiEXT +glVertexAttribI4uiv +glVertexAttribI4uivEXT +glVertexAttribI4usv +glVertexAttribI4usvEXT +glVertexAttribIFormat +glVertexAttribIFormatNV +glVertexAttribIPointer +glVertexAttribIPointerEXT +glVertexAttribL1d +glVertexAttribL1dEXT +glVertexAttribL1dv +glVertexAttribL1dvEXT +glVertexAttribL1i64NV +glVertexAttribL1i64vNV +glVertexAttribL1ui64ARB +glVertexAttribL1ui64NV +glVertexAttribL1ui64vARB +glVertexAttribL1ui64vNV +glVertexAttribL2d +glVertexAttribL2dEXT +glVertexAttribL2dv +glVertexAttribL2dvEXT +glVertexAttribL2i64NV +glVertexAttribL2i64vNV +glVertexAttribL2ui64NV +glVertexAttribL2ui64vNV +glVertexAttribL3d +glVertexAttribL3dEXT +glVertexAttribL3dv +glVertexAttribL3dvEXT +glVertexAttribL3i64NV +glVertexAttribL3i64vNV +glVertexAttribL3ui64NV +glVertexAttribL3ui64vNV +glVertexAttribL4d +glVertexAttribL4dEXT +glVertexAttribL4dv +glVertexAttribL4dvEXT +glVertexAttribL4i64NV +glVertexAttribL4i64vNV +glVertexAttribL4ui64NV +glVertexAttribL4ui64vNV +glVertexAttribLFormat +glVertexAttribLFormatNV +glVertexAttribLPointer +glVertexAttribLPointerEXT +glVertexAttribP1ui +glVertexAttribP1uiv +glVertexAttribP2ui +glVertexAttribP2uiv +glVertexAttribP3ui +glVertexAttribP3uiv +glVertexAttribP4ui +glVertexAttribP4uiv +glVertexAttribParameteriAMD +glVertexAttribPointer +glVertexAttribPointerARB +glVertexAttribPointerNV +glVertexAttribs1dvNV +glVertexAttribs1fvNV +glVertexAttribs1hvNV +glVertexAttribs1svNV +glVertexAttribs2dvNV +glVertexAttribs2fvNV +glVertexAttribs2hvNV +glVertexAttribs2svNV +glVertexAttribs3dvNV +glVertexAttribs3fvNV +glVertexAttribs3hvNV +glVertexAttribs3svNV +glVertexAttribs4dvNV +glVertexAttribs4fvNV +glVertexAttribs4hvNV +glVertexAttribs4svNV +glVertexAttribs4ubvNV +glVertexBindingDivisor +glVertexBlendARB +glVertexBlendEnvfATI +glVertexBlendEnviATI +glVertexFormatNV +glVertexP2ui +glVertexP2uiv +glVertexP3ui +glVertexP3uiv +glVertexP4ui +glVertexP4uiv +glVertexPointer +glVertexPointerEXT +glVertexPointerListIBM +glVertexPointervINTEL +glVertexStream1dATI +glVertexStream1dvATI +glVertexStream1fATI +glVertexStream1fvATI +glVertexStream1iATI +glVertexStream1ivATI +glVertexStream1sATI +glVertexStream1svATI +glVertexStream2dATI +glVertexStream2dvATI +glVertexStream2fATI +glVertexStream2fvATI +glVertexStream2iATI +glVertexStream2ivATI +glVertexStream2sATI +glVertexStream2svATI +glVertexStream3dATI +glVertexStream3dvATI +glVertexStream3fATI +glVertexStream3fvATI +glVertexStream3iATI +glVertexStream3ivATI +glVertexStream3sATI +glVertexStream3svATI +glVertexStream4dATI +glVertexStream4dvATI +glVertexStream4fATI +glVertexStream4fvATI +glVertexStream4iATI +glVertexStream4ivATI +glVertexStream4sATI +glVertexStream4svATI +glVertexWeightfEXT +glVertexWeightfvEXT +glVertexWeighthNV +glVertexWeighthvNV +glVertexWeightPointerEXT +glVideoCaptureNV +glVideoCaptureStreamParameterdvNV +glVideoCaptureStreamParameterfvNV +glVideoCaptureStreamParameterivNV +glViewport +glViewportArrayv +glViewportArrayvNV +glViewportArrayvOES +glViewportIndexedf +glViewportIndexedfNV +glViewportIndexedfOES +glViewportIndexedfv +glViewportIndexedfvNV +glViewportIndexedfvOES +glViewportPositionWScaleNV +glViewportSwizzleNV +glWaitSemaphoreEXT +glWaitSemaphoreui64NVX +glWaitSync +glWaitSyncAPPLE +glWaitSyncValueuiNVX +glWaitVkSemaphoreNV +glWeightbvARB +glWeightdvARB +glWeightfvARB +glWeightivARB +glWeightPathsNV +glWeightPointerARB +glWeightPointerOES +glWeightsvARB +glWeightubvARB +glWeightuivARB +glWeightusvARB +glWindowBackBufferHintAutodesk +glWindowPos2d +glWindowPos2dARB +glWindowPos2dMESA +glWindowPos2dv +glWindowPos2dvARB +glWindowPos2dvMESA +glWindowPos2f +glWindowPos2fARB +glWindowPos2fMESA +glWindowPos2fv +glWindowPos2fvARB +glWindowPos2fvMESA +glWindowPos2i +glWindowPos2iARB +glWindowPos2iMESA +glWindowPos2iv +glWindowPos2ivARB +glWindowPos2ivMESA +glWindowPos2s +glWindowPos2sARB +glWindowPos2sMESA +glWindowPos2sv +glWindowPos2svARB +glWindowPos2svMESA +glWindowPos3d +glWindowPos3dARB +glWindowPos3dMESA +glWindowPos3dv +glWindowPos3dvARB +glWindowPos3dvMESA +glWindowPos3f +glWindowPos3fARB +glWindowPos3fMESA +glWindowPos3fv +glWindowPos3fvARB +glWindowPos3fvMESA +glWindowPos3i +glWindowPos3iARB +glWindowPos3iMESA +glWindowPos3iv +glWindowPos3ivARB +glWindowPos3ivMESA +glWindowPos3s +glWindowPos3sARB +glWindowPos3sMESA +glWindowPos3sv +glWindowPos3svARB +glWindowPos3svMESA +glWindowPos4dMESA +glWindowPos4dvMESA +glWindowPos4fMESA +glWindowPos4fvMESA +glWindowPos4iMESA +glWindowPos4ivMESA +glWindowPos4sMESA +glWindowPos4svMESA +glWindowRectanglesEXT +glWriteMaskEXT +glXAllocateMemoryNV +glXBindChannelToWindowSGIX +glXBindHyperpipeSGIX +glXBindSwapBarrierNV +glXBindSwapBarrierSGIX +glXBindTexImageEXT +glXBindVideoCaptureDeviceNV +glXBindVideoDeviceNV +glXBindVideoImageNV +glXBlitContextFramebufferAMD +glXChannelRectSGIX +glXChannelRectSyncSGIX +glXChooseFBConfig +glXChooseFBConfigSGIX +glXChooseVisual +glXCopyBufferSubDataNV +glXCopyContext +glXCopyImageSubDataNV +glXCopySubBufferMESA +glXCreateAssociatedContextAMD +glXCreateAssociatedContextAttribsAMD +glXCreateContext +glXCreateContextAttribsARB +glXCreateContextWithConfigSGIX +glXCreateGLXPbufferSGIX +glXCreateGLXPixmap +glXCreateGLXPixmapMESA +glXCreateGLXPixmapWithConfigSGIX +glXCreateNewContext +glXCreatePbuffer +glXCreatePixmap +glXCreateWindow +glXCushionSGI +glXDelayBeforeSwapNV +glXDeleteAssociatedContextAMD +glXDestroyContext +glXDestroyGLXPbufferSGIX +glXDestroyGLXPixmap +glXDestroyHyperpipeConfigSGIX +glXDestroyPbuffer +glXDestroyPixmap +glXDestroyWindow +glXEnumerateVideoCaptureDevicesNV +glXEnumerateVideoDevicesNV +glXFreeContextEXT +glXFreeMemoryNV +glXGetAGPOffsetMESA +glXGetClientString +glXGetConfig +glXGetContextGPUIDAMD +glXGetContextIDEXT +glXGetCurrentAssociatedContextAMD +glXGetCurrentContext +glXGetCurrentDisplay +glXGetCurrentDisplayEXT +glXGetCurrentDrawable +glXGetCurrentReadDrawable +glXGetCurrentReadDrawableSGI +glXGetDriverConfig +glXGetFBConfigAttrib +glXGetFBConfigAttribSGIX +glXGetFBConfigFromVisualSGIX +glXGetFBConfigs +glXGetGPUIDsAMD +glXGetGPUInfoAMD +glXGetMscRateOML +glXGetProcAddress +glXGetProcAddressARB +glXGetRefreshRateSGI +glXGetScreenDriver +glXGetSelectedEvent +glXGetSelectedEventSGIX +glXGetSwapIntervalMESA +glXGetSyncValuesOML +glXGetTransparentIndexSUN +glXGetVideoDeviceNV +glXGetVideoInfoNV +glXGetVideoSyncSGI +glXGetVisualFromFBConfig +glXGetVisualFromFBConfigSGIX +glXHyperpipeAttribSGIX +glXHyperpipeConfigSGIX +glXImportContextEXT +glXIsDirect +glXJoinSwapGroupNV +glXJoinSwapGroupSGIX +glXLockVideoCaptureDeviceNV +glXMakeAssociatedContextCurrentAMD +glXMakeContextCurrent +glXMakeCurrent +glXMakeCurrentReadSGI +glXNamedCopyBufferSubDataNV +glXQueryChannelDeltasSGIX +glXQueryChannelRectSGIX +glXQueryContext +glXQueryContextInfoEXT +glXQueryCurrentRendererIntegerMESA +glXQueryCurrentRendererStringMESA +glXQueryDrawable +glXQueryExtension +glXQueryExtensionsString +glXQueryFrameCountNV +glXQueryGLXPbufferSGIX +glXQueryHyperpipeAttribSGIX +glXQueryHyperpipeBestAttribSGIX +glXQueryHyperpipeConfigSGIX +glXQueryHyperpipeNetworkSGIX +glXQueryMaxSwapBarriersSGIX +glXQueryMaxSwapGroupsNV +glXQueryRendererIntegerMESA +glXQueryRendererStringMESA +glXQueryServerString +glXQuerySwapGroupNV +glXQueryVersion +glXQueryVideoCaptureDeviceNV +glXReleaseBuffersMESA +glXReleaseTexImageEXT +glXReleaseVideoCaptureDeviceNV +glXReleaseVideoDeviceNV +glXReleaseVideoImageNV +glXResetFrameCountNV +glXSelectEvent +glXSelectEventSGIX +glXSendPbufferToVideoNV +glXSet3DfxModeMESA +glXSwapBuffers +glXSwapBuffersMscOML +glXSwapIntervalEXT +glXSwapIntervalMESA +glXSwapIntervalSGI +glXUseXFont +glXWaitForMscOML +glXWaitForSbcOML +glXWaitGL +glXWaitVideoSyncSGI +glXWaitX diff --git a/src/GL/libgl.c b/src/GL/libgl.c index 5326016..84b9edb 100644 --- a/src/GL/libgl.c +++ b/src/GL/libgl.c @@ -45,9 +45,6 @@ void __attribute__((constructor)) __libGLInit(void) void _init(void) #endif { - // Fix up the static GL entrypoints, if necessary - entry_init_public(); - __glDispatchInit(); // Register these entrypoints with GLdispatch so they can be overwritten at @@ -62,6 +59,7 @@ void _fini(void) #endif { // Unregister the GLdispatch entrypoints + stub_cleanup(); __glDispatchUnregisterStubCallbacks(patchStubId); __glDispatchFini(); } diff --git a/src/GL/meson.build b/src/GL/meson.build new file mode 100644 index 0000000..6e9c32a --- /dev/null +++ b/src/GL/meson.build @@ -0,0 +1,59 @@ + +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libGL = shared_library( + 'GL', + ['libgl.c', g_libglglxwrapper_c], + include_directories : [inc_include], + link_args : '-Wl,-Bsymbolic', + dependencies : [ + dep_dl, idep_gldispatch, idep_glapi_gl, idep_glx, idep_utils_misc, + ], + version : '1.7.0', + gnu_symbol_visibility : 'hidden', + install : true, +) + +pkg.generate( + libGL, + filebase : 'gl', + description : 'Legacy OpenGL and GLX library and headers.', + version : '1.2', +) + +test( + 'GL symbols check', + prog_py, + args : [ + files_symbols_check, + '--nm', prog_nm.path(), + '--lib', libGL, + '--symbols-file', files('gl.symbols'), + ], + suite : ['symbols'], +) diff --git a/src/GLESv1/Makefile.am b/src/GLESv1/Makefile.am index 88e07bc..969d1c0 100644 --- a/src/GLESv1/Makefile.am +++ b/src/GLESv1/Makefile.am @@ -27,7 +27,7 @@ lib_LTLIBRARIES = libGLESv1_CM.la -libGLESv1_CM_la_SOURCES = +libGLESv1_CM_la_SOURCES = libGLESv1_CM_la_LDFLAGS = -shared \ $(LINKER_FLAG_NO_UNDEFINED) \ -version-info 3:0:2 @@ -40,3 +40,15 @@ libGLESv1_CM_la_LIBADD = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = glesv1_cm.pc + +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = glesv1-symbol-check.sh + +EXTRA_DIST = \ + glesv1-symbol-check.sh \ + glesv1.symbols \ + meson.build diff --git a/src/GLESv1/glesv1-symbol-check.sh b/src/GLESv1/glesv1-symbol-check.sh new file mode 100755 index 0000000..48e217e --- /dev/null +++ b/src/GLESv1/glesv1-symbol-check.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test "${PYTHON}" = ":" && exit 77 +test "x${NM}" = "x" && exit 77 + +exec "${PYTHON}" "${TOP_SRCDIR}/bin/symbols-check.py" \ + --nm "${NM}" \ + --lib "${TOP_BUILDDIR}/src/GLESv1/.libs/libGLESv1_CM.so" \ + --symbols-file "${TOP_SRCDIR}/src/GLESv1/glesv1.symbols" diff --git a/src/GLESv1/glesv1.symbols b/src/GLESv1/glesv1.symbols new file mode 100644 index 0000000..cf4df09 --- /dev/null +++ b/src/GLESv1/glesv1.symbols @@ -0,0 +1,145 @@ +glActiveTexture +glAlphaFunc +glAlphaFuncx +glBindBuffer +glBindTexture +glBlendFunc +glBufferData +glBufferSubData +glClear +glClearColor +glClearColorx +glClearDepthf +glClearDepthx +glClearStencil +glClientActiveTexture +glClipPlanef +glClipPlanex +glColor4f +glColor4ub +glColor4x +glColorMask +glColorPointer +glCompressedTexImage2D +glCompressedTexSubImage2D +glCopyTexImage2D +glCopyTexSubImage2D +glCullFace +glDeleteBuffers +glDeleteTextures +glDepthFunc +glDepthMask +glDepthRangef +glDepthRangex +glDisable +glDisableClientState +glDrawArrays +glDrawElements +glEnable +glEnableClientState +glFinish +glFlush +glFogf +glFogfv +glFogx +glFogxv +glFrontFace +glFrustumf +glFrustumx +glGenBuffers +glGenTextures +glGetBooleanv +glGetBufferParameteriv +glGetClipPlanef +glGetClipPlanex +glGetError +glGetFixedv +glGetFloatv +glGetIntegerv +glGetLightfv +glGetLightxv +glGetMaterialfv +glGetMaterialxv +glGetPointerv +glGetString +glGetTexEnvfv +glGetTexEnviv +glGetTexEnvxv +glGetTexParameterfv +glGetTexParameteriv +glGetTexParameterxv +glHint +glIsBuffer +glIsEnabled +glIsTexture +glLightf +glLightfv +glLightModelf +glLightModelfv +glLightModelx +glLightModelxv +glLightx +glLightxv +glLineWidth +glLineWidthx +glLoadIdentity +glLoadMatrixf +glLoadMatrixx +glLogicOp +glMaterialf +glMaterialfv +glMaterialx +glMaterialxv +glMatrixMode +glMultiTexCoord4f +glMultiTexCoord4x +glMultMatrixf +glMultMatrixx +glNormal3f +glNormal3x +glNormalPointer +glOrthof +glOrthox +glPixelStorei +glPointParameterf +glPointParameterfv +glPointParameterx +glPointParameterxv +glPointSize +glPointSizePointerOES +glPointSizex +glPolygonOffset +glPolygonOffsetx +glPopMatrix +glPushMatrix +glReadPixels +glRotatef +glRotatex +glSampleCoverage +glSampleCoveragex +glScalef +glScalex +glScissor +glShadeModel +glStencilFunc +glStencilMask +glStencilOp +glTexCoordPointer +glTexEnvf +glTexEnvfv +glTexEnvi +glTexEnviv +glTexEnvx +glTexEnvxv +glTexImage2D +glTexParameterf +glTexParameterfv +glTexParameteri +glTexParameteriv +glTexParameterx +glTexParameterxv +glTexSubImage2D +glTranslatef +glTranslatex +glVertexPointer +glViewport diff --git a/src/GLESv1/meson.build b/src/GLESv1/meson.build new file mode 100644 index 0000000..d191aa3 --- /dev/null +++ b/src/GLESv1/meson.build @@ -0,0 +1,56 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libGLESv1 = shared_library( + 'GLESv1_CM', + link_whole : libopengl_main, + dependencies : [ + idep_gldispatch, idep_utils_misc, idep_glapi_glesv1, + ], + version : '1.2.0', + gnu_symbol_visibility : 'hidden', + install : true, +) + +pkg.generate( + libGLESv1, + filebase : 'glesv1_cm', + description : 'OpenGL ES-CM v1 library and headers.', + version : '1.0', +) + +test( + 'GLESv1 symbols check', + prog_py, + args : [ + files_symbols_check, + '--nm', prog_nm.path(), + '--lib', libGLESv1, + '--symbols-file', files('glesv1.symbols'), + ], + suite : ['symbols'], +) diff --git a/src/GLESv2/Makefile.am b/src/GLESv2/Makefile.am index f40e06f..a6c261d 100644 --- a/src/GLESv2/Makefile.am +++ b/src/GLESv2/Makefile.am @@ -27,7 +27,7 @@ lib_LTLIBRARIES = libGLESv2.la -libGLESv2_la_SOURCES = +libGLESv2_la_SOURCES = libGLESv2_la_LDFLAGS = -shared \ $(LINKER_FLAG_NO_UNDEFINED) \ -version-info 3:0:1 @@ -40,3 +40,15 @@ libGLESv2_la_LIBADD = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = glesv2.pc + +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = glesv2-symbol-check.sh + +EXTRA_DIST = \ + glesv2-symbol-check.sh \ + glesv2.symbols \ + meson.build diff --git a/src/GLESv2/glesv2-symbol-check.sh b/src/GLESv2/glesv2-symbol-check.sh new file mode 100755 index 0000000..21f21a3 --- /dev/null +++ b/src/GLESv2/glesv2-symbol-check.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test "${PYTHON}" = ":" && exit 77 +test "x${NM}" = "x" && exit 77 + +exec "${PYTHON}" "${TOP_SRCDIR}/bin/symbols-check.py" \ + --nm "${NM}" \ + --lib "${TOP_BUILDDIR}/src/GLESv2/.libs/libGLESv2.so" \ + --symbols-file "${TOP_SRCDIR}/src/GLESv2/glesv2.symbols" diff --git a/src/GLESv2/glesv2.symbols b/src/GLESv2/glesv2.symbols new file mode 100644 index 0000000..b7d395f --- /dev/null +++ b/src/GLESv2/glesv2.symbols @@ -0,0 +1,358 @@ +glActiveShaderProgram +glActiveTexture +glAttachShader +glBeginQuery +glBeginTransformFeedback +glBindAttribLocation +glBindBuffer +glBindBufferBase +glBindBufferRange +glBindFramebuffer +glBindImageTexture +glBindProgramPipeline +glBindRenderbuffer +glBindSampler +glBindTexture +glBindTransformFeedback +glBindVertexArray +glBindVertexBuffer +glBlendBarrier +glBlendColor +glBlendEquation +glBlendEquationi +glBlendEquationSeparate +glBlendEquationSeparatei +glBlendFunc +glBlendFunci +glBlendFuncSeparate +glBlendFuncSeparatei +glBlitFramebuffer +glBufferData +glBufferSubData +glCheckFramebufferStatus +glClear +glClearBufferfi +glClearBufferfv +glClearBufferiv +glClearBufferuiv +glClearColor +glClearDepthf +glClearStencil +glClientWaitSync +glColorMask +glColorMaski +glCompileShader +glCompressedTexImage2D +glCompressedTexImage3D +glCompressedTexSubImage2D +glCompressedTexSubImage3D +glCopyBufferSubData +glCopyImageSubData +glCopyTexImage2D +glCopyTexSubImage2D +glCopyTexSubImage3D +glCreateProgram +glCreateShader +glCreateShaderProgramv +glCullFace +glDebugMessageCallback +glDebugMessageControl +glDebugMessageInsert +glDeleteBuffers +glDeleteFramebuffers +glDeleteProgram +glDeleteProgramPipelines +glDeleteQueries +glDeleteRenderbuffers +glDeleteSamplers +glDeleteShader +glDeleteSync +glDeleteTextures +glDeleteTransformFeedbacks +glDeleteVertexArrays +glDepthFunc +glDepthMask +glDepthRangef +glDetachShader +glDisable +glDisablei +glDisableVertexAttribArray +glDispatchCompute +glDispatchComputeIndirect +glDrawArrays +glDrawArraysIndirect +glDrawArraysInstanced +glDrawBuffers +glDrawElements +glDrawElementsBaseVertex +glDrawElementsIndirect +glDrawElementsInstanced +glDrawElementsInstancedBaseVertex +glDrawRangeElements +glDrawRangeElementsBaseVertex +glEnable +glEnablei +glEnableVertexAttribArray +glEndQuery +glEndTransformFeedback +glFenceSync +glFinish +glFlush +glFlushMappedBufferRange +glFramebufferParameteri +glFramebufferRenderbuffer +glFramebufferTexture +glFramebufferTexture2D +glFramebufferTextureLayer +glFrontFace +glGenBuffers +glGenerateMipmap +glGenFramebuffers +glGenProgramPipelines +glGenQueries +glGenRenderbuffers +glGenSamplers +glGenTextures +glGenTransformFeedbacks +glGenVertexArrays +glGetActiveAttrib +glGetActiveUniform +glGetActiveUniformBlockiv +glGetActiveUniformBlockName +glGetActiveUniformsiv +glGetAttachedShaders +glGetAttribLocation +glGetBooleani_v +glGetBooleanv +glGetBufferParameteri64v +glGetBufferParameteriv +glGetBufferPointerv +glGetDebugMessageLog +glGetError +glGetFloatv +glGetFragDataLocation +glGetFramebufferAttachmentParameteriv +glGetFramebufferParameteriv +glGetGraphicsResetStatus +glGetInteger64i_v +glGetInteger64v +glGetIntegeri_v +glGetIntegerv +glGetInternalformativ +glGetMultisamplefv +glGetnUniformfv +glGetnUniformiv +glGetnUniformuiv +glGetObjectLabel +glGetObjectPtrLabel +glGetPointerv +glGetProgramBinary +glGetProgramInfoLog +glGetProgramInterfaceiv +glGetProgramiv +glGetProgramPipelineInfoLog +glGetProgramPipelineiv +glGetProgramResourceIndex +glGetProgramResourceiv +glGetProgramResourceLocation +glGetProgramResourceName +glGetQueryiv +glGetQueryObjectuiv +glGetRenderbufferParameteriv +glGetSamplerParameterfv +glGetSamplerParameterIiv +glGetSamplerParameterIuiv +glGetSamplerParameteriv +glGetShaderInfoLog +glGetShaderiv +glGetShaderPrecisionFormat +glGetShaderSource +glGetString +glGetStringi +glGetSynciv +glGetTexLevelParameterfv +glGetTexLevelParameteriv +glGetTexParameterfv +glGetTexParameterIiv +glGetTexParameterIuiv +glGetTexParameteriv +glGetTransformFeedbackVarying +glGetUniformBlockIndex +glGetUniformfv +glGetUniformIndices +glGetUniformiv +glGetUniformLocation +glGetUniformuiv +glGetVertexAttribfv +glGetVertexAttribIiv +glGetVertexAttribIuiv +glGetVertexAttribiv +glGetVertexAttribPointerv +glHint +glInvalidateFramebuffer +glInvalidateSubFramebuffer +glIsBuffer +glIsEnabled +glIsEnabledi +glIsFramebuffer +glIsProgram +glIsProgramPipeline +glIsQuery +glIsRenderbuffer +glIsSampler +glIsShader +glIsSync +glIsTexture +glIsTransformFeedback +glIsVertexArray +glLineWidth +glLinkProgram +glMapBufferRange +glMemoryBarrier +glMemoryBarrierByRegion +glMinSampleShading +glObjectLabel +glObjectPtrLabel +glPatchParameteri +glPauseTransformFeedback +glPixelStorei +glPolygonOffset +glPopDebugGroup +glPrimitiveBoundingBox +glProgramBinary +glProgramParameteri +glProgramUniform1f +glProgramUniform1fv +glProgramUniform1i +glProgramUniform1iv +glProgramUniform1ui +glProgramUniform1uiv +glProgramUniform2f +glProgramUniform2fv +glProgramUniform2i +glProgramUniform2iv +glProgramUniform2ui +glProgramUniform2uiv +glProgramUniform3f +glProgramUniform3fv +glProgramUniform3i +glProgramUniform3iv +glProgramUniform3ui +glProgramUniform3uiv +glProgramUniform4f +glProgramUniform4fv +glProgramUniform4i +glProgramUniform4iv +glProgramUniform4ui +glProgramUniform4uiv +glProgramUniformMatrix2fv +glProgramUniformMatrix2x3fv +glProgramUniformMatrix2x4fv +glProgramUniformMatrix3fv +glProgramUniformMatrix3x2fv +glProgramUniformMatrix3x4fv +glProgramUniformMatrix4fv +glProgramUniformMatrix4x2fv +glProgramUniformMatrix4x3fv +glPushDebugGroup +glReadBuffer +glReadnPixels +glReadPixels +glReleaseShaderCompiler +glRenderbufferStorage +glRenderbufferStorageMultisample +glResumeTransformFeedback +glSampleCoverage +glSampleMaski +glSamplerParameterf +glSamplerParameterfv +glSamplerParameteri +glSamplerParameterIiv +glSamplerParameterIuiv +glSamplerParameteriv +glScissor +glShaderBinary +glShaderSource +glStencilFunc +glStencilFuncSeparate +glStencilMask +glStencilMaskSeparate +glStencilOp +glStencilOpSeparate +glTexBuffer +glTexBufferRange +glTexImage2D +glTexImage3D +glTexParameterf +glTexParameterfv +glTexParameteri +glTexParameterIiv +glTexParameterIuiv +glTexParameteriv +glTexStorage2D +glTexStorage2DMultisample +glTexStorage3D +glTexStorage3DMultisample +glTexSubImage2D +glTexSubImage3D +glTransformFeedbackVaryings +glUniform1f +glUniform1fv +glUniform1i +glUniform1iv +glUniform1ui +glUniform1uiv +glUniform2f +glUniform2fv +glUniform2i +glUniform2iv +glUniform2ui +glUniform2uiv +glUniform3f +glUniform3fv +glUniform3i +glUniform3iv +glUniform3ui +glUniform3uiv +glUniform4f +glUniform4fv +glUniform4i +glUniform4iv +glUniform4ui +glUniform4uiv +glUniformBlockBinding +glUniformMatrix2fv +glUniformMatrix2x3fv +glUniformMatrix2x4fv +glUniformMatrix3fv +glUniformMatrix3x2fv +glUniformMatrix3x4fv +glUniformMatrix4fv +glUniformMatrix4x2fv +glUniformMatrix4x3fv +glUnmapBuffer +glUseProgram +glUseProgramStages +glValidateProgram +glValidateProgramPipeline +glVertexAttrib1f +glVertexAttrib1fv +glVertexAttrib2f +glVertexAttrib2fv +glVertexAttrib3f +glVertexAttrib3fv +glVertexAttrib4f +glVertexAttrib4fv +glVertexAttribBinding +glVertexAttribDivisor +glVertexAttribFormat +glVertexAttribI4i +glVertexAttribI4iv +glVertexAttribI4ui +glVertexAttribI4uiv +glVertexAttribIFormat +glVertexAttribIPointer +glVertexAttribPointer +glVertexBindingDivisor +glViewport +glWaitSync diff --git a/src/GLESv2/meson.build b/src/GLESv2/meson.build new file mode 100644 index 0000000..8b32c48 --- /dev/null +++ b/src/GLESv2/meson.build @@ -0,0 +1,57 @@ + +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libGLESv2 = shared_library( + 'GLESv2', + link_whole : libopengl_main, + dependencies : [ + idep_gldispatch, idep_utils_misc, idep_glapi_glesv2, + ], + version : '2.1.0', + gnu_symbol_visibility : 'hidden', + install : true, +) + +pkg.generate( + libGLESv2, + filebase : 'glesv2', + description : 'OpenGL ES v2/v3 library and headers.', + version : '3.2', +) + +test( + 'GLESv2 symbols check', + prog_py, + args : [ + files_symbols_check, + '--nm', prog_nm.path(), + '--lib', libGLESv2, + '--symbols-file', files('glesv2.symbols'), + ], + suite : ['symbols'], +) diff --git a/src/GLX/Makefile.am b/src/GLX/Makefile.am index d371c96..33a1bc5 100644 --- a/src/GLX/Makefile.am +++ b/src/GLX/Makefile.am @@ -26,6 +26,7 @@ # MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. noinst_HEADERS = \ + glvnd_genentry.h \ libglxabipriv.h \ libglxcurrent.h \ libglxmapping.h \ @@ -57,17 +58,40 @@ libGLX_la_LIBADD += $(XEXT_LIBS) libGLX_la_LIBADD += $(GL_DISPATCH_DIR)/libGLdispatch.la libGLX_la_LIBADD += $(UTIL_DIR)/libtrace.la libGLX_la_LIBADD += $(UTIL_DIR)/libglvnd_pthread.la -libGLX_la_LIBADD += $(UTIL_DIR)/libglvnd_genentry.la libGLX_la_LIBADD += $(UTIL_DIR)/libutils_misc.la libGLX_la_LIBADD += $(UTIL_DIR)/libapp_error_check.la libGLX_la_LIBADD += $(UTIL_DIR)/libwinsys_dispatch.la libGLX_la_LDFLAGS = -shared -Wl,-Bsymbolic -version-info 0 $(LINKER_FLAG_NO_UNDEFINED) +GENERATE_DISPATCH_STUBS_SCRIPT = $(top_srcdir)/src/GLX/gen_glx_stubs.py +EXTRA_DIST = $(GENERATE_DISPATCH_STUBS_SCRIPT) + +if HAVE_PYTHON +g_glx_dispatch_stub_list.h: $(GENERATE_DISPATCH_STUBS_SCRIPT) + $(AM_V_GEN)$(PYTHON) $(GENERATE_DISPATCH_STUBS_SCRIPT) > $@ +BUILT_SOURCES = g_glx_dispatch_stub_list.h +CLEANFILES = $(BUILT_SOURCES) +endif + libGLX_la_SOURCES = \ libglx.c \ libglxmapping.c \ - libglxproto.c + libglxproto.c \ + glvnd_genentry.c \ + g_glx_dispatch_stub_list.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = glx.pc + +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = glx-symbol-check.sh + +EXTRA_DIST += \ + glx-symbol-check.sh \ + glx.symbols \ + meson.build diff --git a/src/GLX/gen_glx_stubs.py b/src/GLX/gen_glx_stubs.py new file mode 100755 index 0000000..79bafbc --- /dev/null +++ b/src/GLX/gen_glx_stubs.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +import sys + +GENERATED_ENTRYPOINT_MAX = 4096 + +def main(): + text = "" + + text += "#if defined(GLX_STUBS_COUNT)\n" + text += "#define GENERATED_ENTRYPOINT_MAX %d\n" % (GENERATED_ENTRYPOINT_MAX) + text += "#undef GLX_STUBS_COUNT\n" + text += "#endif\n\n" + + text += "#if defined(GLX_STUBS_ASM)\n" + for i in range(GENERATED_ENTRYPOINT_MAX): + text += "STUB_ASM(\"%d\")\n" % (i) + text += "#undef GLX_STUBS_ASM\n" + text += "#endif\n" + sys.stdout.write(text) + +if (__name__ == "__main__"): + main() + diff --git a/src/GLX/glvnd_genentry.c b/src/GLX/glvnd_genentry.c new file mode 100644 index 0000000..b373ba2 --- /dev/null +++ b/src/GLX/glvnd_genentry.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2015, NVIDIA CORPORATION. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * unaltered in all copies or substantial portions of the Materials. + * Any additions, deletions, or changes to the original source files + * must be clearly indicated in accompanying documentation. + * + * If only executable code is distributed, then the accompanying + * documentation must state that "this software is based in part on the + * work of the Khronos Group." + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + */ + +#include "glvnd_genentry.h" +#include "utils_misc.h" + +#include +#include +#include +#include +#include +#include + +#if defined(USE_DISPATCH_ASM) + +#define _U_STRINGIFY(x) #x +#define U_STRINGIFY(x) _U_STRINGIFY(x) + +#define GLX_STUBS_COUNT +#include "g_glx_dispatch_stub_list.h" + +static GLVNDentrypointStub entrypointFunctions[GENERATED_ENTRYPOINT_MAX]; +static char *entrypointNames[GENERATED_ENTRYPOINT_MAX] = {}; +static int entrypointCount = 0; + +extern char glx_entrypoint_start[]; +extern char glx_entrypoint_end[]; + +#if defined(USE_X86_ASM) + +#define STUB_SIZE 32 +#define STUB_ASM_ARCH(slot) \ + "push %ebx\n" \ + "call 1f\n" \ + "1:\n" \ + "popl %ebx\n" \ + "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx\n" \ + "movl entrypointFunctions@GOT(%ebx), %eax\n" \ + "pop %ebx\n" \ + "jmp *(4 * " slot ")(%eax)\n" + +#elif defined(USE_X86_64_ASM) + +#define STUB_SIZE 16 +#define STUB_ASM_ARCH(slot) \ + "movq entrypointFunctions@GOTPCREL(%rip), %rax\n\t" \ + "jmp *(8 * " slot ")(%rax)\n" + +#elif defined(USE_ARMV7_ASM) + +#define STUB_SIZE 64 +#define STUB_ASM_ARCH(slot) \ + "ldr ip, 1f\n" \ + "12:\n" \ + "add ip, pc\n" \ + "push { r0 }\n" \ + "ldr r0, 1f+4\n" \ + "add ip, r0\n" \ + "pop { r0 }\n" \ + "ldr ip, [ip]\n" \ + "bx ip\n" \ + "1:\n" \ + ".word entrypointFunctions - (12b + 8)\n" \ + ".word " slot " * 4\n" + +#elif defined(USE_AARCH64_ASM) + +#define STUB_SIZE 16 +#define STUB_ASM_ARCH(slot) \ + "adrp x16, entrypointFunctions + " slot "*8\n" \ + "ldr x16, [x16, #:lo12:(entrypointFunctions + " slot "*8)]\n" \ + "br x16\n" + +#elif defined(USE_PPC64_ASM) && defined(_CALL_ELF) && (_CALL_ELF == 2) + +#define STUB_SIZE 32 +#define STUB_ASM_ARCH(slot) \ + "0:\n" \ + "addis 2,12,.TOC.-0b@ha\n" \ + "addi 2,2,.TOC.-0b@l\n" \ + "addis 11, 2, entrypointFunctions@got@ha\n" \ + "ld 11, entrypointFunctions@got@l(11)\n" \ + "ld 12, (" slot " * 8)(11)\n" \ + "mtctr 12\n" \ + "bctr\n" + +#else +#error "Can't happen -- not implemented" +#endif + +#define STUB_ASM(slot) \ + ".globl glx_entrypoint_stub_" slot "\n" \ + ".hidden glx_entrypoint_stub_" slot "\n" \ + ".balign " U_STRINGIFY(STUB_SIZE) "\n" \ + "glx_entrypoint_stub_" slot ":\n" \ + STUB_ASM_ARCH(slot) + +__asm__(".globl glx_entrypoint_start\n" + ".hidden glx_entrypoint_start\n" + ".balign " U_STRINGIFY(STUB_SIZE) "\n" \ + "glx_entrypoint_start:\n" + +#define GLX_STUBS_ASM +#include "g_glx_dispatch_stub_list.h" + + ".globl glx_entrypoint_end\n" + ".hidden glx_entrypoint_end\n" + ".balign " U_STRINGIFY(STUB_SIZE) "\n" \ + "glx_entrypoint_end:\n" +); + +static void *DefaultDispatchFunc(void) +{ + // Print a warning message? + return NULL; +} + +static GLVNDentrypointStub GetEntrypointStub(int index) +{ + return (GLVNDentrypointStub) (glx_entrypoint_start + (index * STUB_SIZE)); +} + +GLVNDentrypointStub glvndGenerateEntrypoint(const char *procName) +{ + int i; + + for (i=0; i= GENERATED_ENTRYPOINT_MAX) { + return NULL; + } + + entrypointNames[entrypointCount] = strdup(procName); + if (entrypointNames[entrypointCount] == NULL) { + return NULL; + } + + entrypointFunctions[entrypointCount] = (GLVNDentrypointStub) DefaultDispatchFunc; + entrypointCount++; + return GetEntrypointStub(entrypointCount - 1); +} + +void glvndFreeEntrypoints(void) +{ + int i; + for (i=0; i: stp x1, x0, [sp,#-16]! - 0x58000240, // : ldr x0, - 0xf9400000, // : ldr x0, [x0] - 0xb40000a0, // : cbz x0, - 0x58000261, // : ldr x1, - 0xf8616810, // : ldr x16, [x0,x1] - 0xa8c103e1, // : ldp x1, x0, [sp],#16 - 0xd61f0200, // : br x16 - 0xf81f0ffe, // : str x30, [sp,#-16]! - 0xa9bf1be7, // : stp x7, x6, [sp,#-16]! - 0xa9bf13e5, // : stp x5, x4, [sp,#-16]! - 0xa9bf0be3, // : stp x3, x2, [sp,#-16]! - 0x58000120, // : ldr x0, - 0xd63f0000, // : blr x0 - 0xa8c10be3, // : ldp x3, x2, [sp],#16 - 0xa8c113e5, // : ldp x5, x4, [sp],#16 - 0xa8c11be7, // : ldp x7, x6, [sp],#16 - 0xf84107fe, // : ldr x30, [sp],#16 - 0x17fffff2, // : b - - // Offsets that need to be patched - 0x00000000, 0x00000000, // : _glapi_Current - 0x00000000, 0x00000000, // : _glapi_get_current - 0x00000000, 0x00000000, // : slot * sizeof(void*) -}; - __asm__(".section wtext,\"ax\"\n" ".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" ".globl public_entry_start\n" @@ -148,27 +117,3 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" const int entry_type = __GLDISPATCH_STUB_AARCH64; const int entry_stub_size = ENTRY_STUB_ALIGN; -// The offsets in ENTRY_TEMPLATE that need to be patched. -static const int TEMPLATE_OFFSET_CURRENT_TABLE = sizeof(ENTRY_TEMPLATE) - 3*8; -static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET = sizeof(ENTRY_TEMPLATE) - 2*8; -static const int TEMPLATE_OFFSET_SLOT = sizeof(ENTRY_TEMPLATE) - 8; - -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry; - - // Get the pointer to the writable mapping. - writeEntry = (char *) u_execmem_get_writable(entry); - - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - - // Patch the slot number and whatever addresses need to be patched. - *((uint64_t *)(writeEntry + TEMPLATE_OFFSET_SLOT)) = (uint64_t)(slot * sizeof(mapi_func)); - *((uint64_t *)(writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE)) = - (uint64_t)_glapi_Current; - *((uint64_t *)(writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = - (uint64_t)_glapi_get_current; - - // See http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code - __builtin___clear_cache(writeEntry, writeEntry + sizeof(ENTRY_TEMPLATE)); -} diff --git a/src/GLdispatch/vnd-glapi/entry_armv7_tsd.c b/src/GLdispatch/vnd-glapi/entry_armv7_tsd.c index be36ad3..384bd27 100644 --- a/src/GLdispatch/vnd-glapi/entry_armv7_tsd.c +++ b/src/GLdispatch/vnd-glapi/entry_armv7_tsd.c @@ -47,7 +47,7 @@ __asm__(".syntax unified\n\t"); /* - * u_execmem_alloc() allocates 64 bytes per stub. + * The size of each dispatch stub. */ #define ENTRY_STUB_ALIGN 128 #if !defined(GLDISPATCH_PAGE_SIZE) @@ -120,40 +120,6 @@ __asm__(".syntax unified\n\t"); "3:\n\t" \ ".word " slot "\n\t" -/* - * This template is used to generate new dispatch stubs at runtime. It's - * functionally equivalent to the code in STUB_ASM_CODE(), but not identical. - * The difference between the two is that STUB_ASM_CODE has to be position - * independent, so it has to go through the GOT and PLT to get the addresses of - * _glapi_Current and _glapi_get_current. In the generated stubs, we can just - * plug the addresses in directly. - */ -static const uint16_t ENTRY_TEMPLATE[] = -{ - 0xb40f, // push {r0-r3} - 0xf8df, 0x0028, // ldr r0, 1f - 0x6800, // ldr r0, [r0] - 0x2800, // cmp r0, #0 - 0xbf08, // it eq - 0xe008, // beq 10f - 0x4909, // 11: ldr r1, 3f - 0xf04f, 0x0204, // mov r2, #4 - 0xfb01, 0xf102, // mul r1, r1, r2 - 0xf850, 0xc001, // ldr ip, [r0, +r1] - 0xbc0f, // pop {r0-r3} - 0x4760, // bx ip - 0xb500, // 10: push {lr} - 0x4803, // ldr r0, 2f - 0x4780, // blx r0 - 0xf85d, 0xeb04, // pop {lr} - 0xe7f0, // b 11b - - // Offsets that need to be patched - 0x0000, 0x0000, // 1: .word _glapi_Current - 0x0000, 0x0000, // 2: .word _glapi_get_current - 0x0000, 0x0000, // 3: .word " slot " -}; - __asm__(".section wtext,\"ax\"\n" ".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" ".syntax unified\n" @@ -180,38 +146,6 @@ __asm__(".arm\n\t"); const int entry_type = __GLDISPATCH_STUB_ARMV7_THUMB; const int entry_stub_size = ENTRY_STUB_ALIGN; -static const int TEMPLATE_OFFSET_CURRENT_TABLE = sizeof(ENTRY_TEMPLATE) - 3*4; -static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET = sizeof(ENTRY_TEMPLATE) - 2*4; -static const int TEMPLATE_OFFSET_SLOT = sizeof(ENTRY_TEMPLATE) - 4; - -void -entry_init_public(void) -{ - STATIC_ASSERT(sizeof(ENTRY_TEMPLATE) <= ENTRY_STUB_ALIGN); -} - -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry; - - // Make sure the base address has the Thumb mode bit - assert((uintptr_t)entry & (uintptr_t)0x1); - - // Get the pointer to the writable mapping. - writeEntry = (char *) u_execmem_get_writable(entry - 1); - - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - - *((uint32_t *)(writeEntry + TEMPLATE_OFFSET_SLOT)) = slot; - *((uint32_t *)(writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE)) = - (uint32_t)_glapi_Current; - *((uint32_t *)(writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = - (uint32_t)_glapi_get_current; - - // See http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code - __builtin___clear_cache(writeEntry, writeEntry + sizeof(ENTRY_TEMPLATE)); -} - // Note: The rest of these functions could also be used for ARMv7 TLS stubs, // once those are implemented. @@ -222,27 +156,3 @@ entry_get_public(int index) return (mapi_func)(public_entry_start + (index * entry_stub_size) + 1); } -void entry_get_patch_addresses(mapi_func entry, void **writePtr, const void **execPtr) -{ - // Get the actual beginning of the stub allocation - void *entryBase = (void *) (((uintptr_t) entry) - 1); - *execPtr = (const void *) entryBase; - *writePtr = u_execmem_get_writable(entryBase); -} - -#if !defined(STATIC_DISPATCH_ONLY) -mapi_func entry_generate(int slot) -{ - void *code = u_execmem_alloc(entry_stub_size); - if (!code) { - return NULL; - } - - // Add 1 to the base address to force Thumb mode when jumping to the stub - code = (void *)((char *)code + 1); - - entry_generate_default_code(code, slot); - - return (mapi_func) code; -} -#endif // !defined(STATIC_DISPATCH_ONLY) diff --git a/src/GLdispatch/vnd-glapi/entry_common.c b/src/GLdispatch/vnd-glapi/entry_common.c index 155d144..c655178 100644 --- a/src/GLdispatch/vnd-glapi/entry_common.c +++ b/src/GLdispatch/vnd-glapi/entry_common.c @@ -74,3 +74,63 @@ int entry_patch_finish(void) return entry_patch_mprotect(PROT_READ | PROT_EXEC); } +void *entry_get_patch_address(int index) +{ + return (void *) (public_entry_start + (index * entry_stub_size)); +} + +void *entry_save_entrypoints(void) +{ + size_t size = ((uintptr_t) public_entry_end) - ((uintptr_t) public_entry_start); + void *buf = malloc(size); + if (buf != NULL) { + memcpy(buf, public_entry_start, size); + } + return buf; +} + +#if defined(USE_ARMV7_ASM) || defined(USE_AARCH64_ASM) +static void InvalidateCache(void) +{ + // See http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code + __builtin___clear_cache(public_entry_start, public_entry_end); +} +#elif defined(USE_PPC64_ASM) +static void InvalidateCache(void) +{ + // Note: We might be able to get away with only invalidating each cache + // block, instead of every single 32-bit increment. If that works, we'd + // need to query the AT_DCACHEBSIZE and AT_ICACHEBSIZE values at runtime + // with getauxval(3). + size_t dataBlockSize = 4; + size_t instructionBlockSize = 4; + char *ptr; + + for (ptr = public_entry_start; + (uintptr_t) ptr < (uintptr_t) public_entry_end; + ptr += dataBlockSize) { + __asm__ __volatile__("dcbst 0, %0" : : "r" (ptr)); + } + __asm__ __volatile__("sync"); + + for (ptr = public_entry_start; + (uintptr_t) ptr < (uintptr_t) public_entry_end; + ptr += instructionBlockSize) { + __asm__ __volatile__("icbi 0, %0" : : "r" (ptr)); + } + __asm__ __volatile__("isync"); +} +#else +static void InvalidateCache(void) +{ + // Nothing to do here. +} +#endif + +void entry_restore_entrypoints(void *saved) +{ + size_t size = ((uintptr_t) public_entry_end) - ((uintptr_t) public_entry_start); + memcpy(public_entry_start, saved, size); + InvalidateCache(); +} + diff --git a/src/GLdispatch/vnd-glapi/entry_common.h b/src/GLdispatch/vnd-glapi/entry_common.h index fcb9569..68a2cdd 100644 --- a/src/GLdispatch/vnd-glapi/entry_common.h +++ b/src/GLdispatch/vnd-glapi/entry_common.h @@ -34,15 +34,19 @@ * Common code for the x86-64 TLS, x86-64 TSD, and ARMv7 entrypoint stubs. */ -#if !defined(STATIC_DISPATCH_ONLY) -#include "u_execmem.h" -#else -#define u_execmem_get_writable(addr) ((void *) (addr)) -#endif - #include "entry.h" extern char public_entry_start[]; extern char public_entry_end[]; +#ifdef __CET__ +#ifdef __x86_64__ +#define ENDBR "endbr64\n\t" +#else +#define ENDBR "endbr32\n\t" +#endif +#else +#define ENDBR +#endif + #endif // ENTRY_COMMON_H diff --git a/src/GLdispatch/vnd-glapi/entry_files.mk b/src/GLdispatch/vnd-glapi/entry_files.mk index ce72f07..2865ae7 100644 --- a/src/GLdispatch/vnd-glapi/entry_files.mk +++ b/src/GLdispatch/vnd-glapi/entry_files.mk @@ -38,14 +38,14 @@ MAPI_GLDISPATCH_ENTRY_FILES += entry_simple_asm.c MAPI_GLDISPATCH_ENTRY_FILES += entry_common.c endif -if GLDISPATCH_TYPE_PPC64LE_TSD -MAPI_GLDISPATCH_ENTRY_FILES = entry_ppc64le_tsd.c +if GLDISPATCH_TYPE_PPC64_TSD +MAPI_GLDISPATCH_ENTRY_FILES = entry_ppc64_tsd.c MAPI_GLDISPATCH_ENTRY_FILES += entry_simple_asm.c MAPI_GLDISPATCH_ENTRY_FILES += entry_common.c endif -if GLDISPATCH_TYPE_PPC64LE_TLS -MAPI_GLDISPATCH_ENTRY_FILES = entry_ppc64le_tls.c +if GLDISPATCH_TYPE_PPC64_TLS +MAPI_GLDISPATCH_ENTRY_FILES = entry_ppc64_tls.c MAPI_GLDISPATCH_ENTRY_FILES += entry_simple_asm.c MAPI_GLDISPATCH_ENTRY_FILES += entry_common.c endif diff --git a/src/GLdispatch/vnd-glapi/entry_ppc64_tls.c b/src/GLdispatch/vnd-glapi/entry_ppc64_tls.c new file mode 100644 index 0000000..376c7e6 --- /dev/null +++ b/src/GLdispatch/vnd-glapi/entry_ppc64_tls.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2010 LunarG Inc. + * Copyright (c) 2017, NVIDIA CORPORATION. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "entry.h" +#include "entry_common.h" + +#include +#include +#include +#include +#include + +#include "utils_misc.h" +#include "u_macros.h" +#include "glapi.h" +#include "glvnd/GLdispatchABI.h" + +#if !defined(_CALL_ELF) || (_CALL_ELF == 1) +#error "ELFv1 ABI is not supported" +#endif + +// NOTE: These must be powers of two: +#define ENTRY_STUB_ALIGN 64 +#if !defined(GLDISPATCH_PAGE_SIZE) +#define GLDISPATCH_PAGE_SIZE 65536 +#endif + +__asm__(".section wtext,\"ax\",@progbits\n"); +__asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" + ".globl public_entry_start\n" + ".hidden public_entry_start\n" + "public_entry_start:"); + +#define STUB_ASM_ENTRY(func) \ + ".globl " func "\n" \ + ".type " func ", @function\n" \ + ".balign " U_STRINGIFY(ENTRY_STUB_ALIGN) "\n" \ + func ":\n\t" \ + " addis 2, 12, .TOC.-" func "@ha\n\t" \ + " addi 2, 2, .TOC.-" func "@l\n\t" \ + " .localentry " func ", .-" func "\n\t" + +#define STUB_ASM_CODE(slot) \ + " addis 11, 2, _glapi_tls_Current@got@tprel@ha\n\t" \ + " ld 11, _glapi_tls_Current@got@tprel@l(11)\n\t" \ + " add 11, 11,_glapi_tls_Current@tls\n\t" \ + " ld 11, 0(11)\n\t" \ + " addis 11, 11, (" slot "*8)@ha\n" \ + " ld 12, (" slot "*8)@l (11)\n" \ + " mtctr 12\n\t" \ + " bctr\n" \ + // Conceptually, this is: + // { + // void **dispatchTable = _glapi_tls_Current; + // jump_to_address(dispatchTable[slot]; + // } + // + // Note that _glapi_tls_Current is a global variable declared with + // __thread. + +#define MAPI_TMP_STUB_ASM_GCC +#include "mapi_tmp.h" + + +__asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" + ".globl public_entry_end\n" + ".hidden public_entry_end\n" + "public_entry_end:"); + +__asm__(".text\n"); + +__asm__("ppc64_current_tls:\n\t" + " addis 3, 2, _glapi_tls_Current@got@tprel@ha\n\t" + " ld 3, _glapi_tls_Current@got@tprel@l(3)\n\t" + " blr\n" + ); + +extern uint64_t ppc64_current_tls(); + +const int entry_type = __GLDISPATCH_STUB_PPC64; +const int entry_stub_size = ENTRY_STUB_ALIGN; + +static const uint32_t ENTRY_TEMPLATE[] = +{ + // This should be functionally the same code as would be generated from + // the STUB_ASM_CODE macro, but defined as a buffer. + // This is used to generate new dispatch stubs. libglvnd will copy this + // data to the dispatch stub, and then it will patch the slot number and + // any addresses that it needs to. + // NOTE!!! NOTE!!! NOTE!!! + // This representation is correct for both little- and big-endian systems. + // However, more work needs to be done for big-endian Linux because it + // adheres to an older, AIX-compatible ABI that uses function descriptors. + // 1000: + 0x7C0802A6, // : mflr 0 + 0xF8010010, // : std 0, 16(1) + 0xE96C0028, // : ld 11, 9000f-1000b+0(12) + 0x7D6B6A14, // : add 11, 11, 13 + 0xE96B0000, // : ld 11, 0(11) + 0xE80C0030, // : ld 0, 9000f-1000b+8(12) + 0x7D8B002A, // : ldx 12, 11, 0 + 0x7D8903A6, // : mtctr 12 + 0x4E800420, // : bctr + 0x60000000, // : nop + // 9000: + 0, 0, // : .quad _glapi_Current + 0, 0 // : .quad *8 +}; + +/* + * These are the offsets in ENTRY_TEMPLATE used in entry_generate_default_code + * to patch the dispatch table index and the slot number in the generated + * function. + * + * TEMPLATE_OFFSET_TLS_ADDR is the offset part of the _glapi_tls_Current + *__thread variable, + * TEMPLATE_OFFSET_SLOT is the dispatch table index. + */ + +static const int TEMPLATE_OFFSET_TLS_ADDR = sizeof(ENTRY_TEMPLATE) - 16; +static const int TEMPLATE_OFFSET_SLOT = sizeof(ENTRY_TEMPLATE) - 8; + +void entry_generate_default_code(int index, int slot) +{ + char *entry = (char *) (public_entry_start + (index * entry_stub_size)); + STATIC_ASSERT(ENTRY_STUB_ALIGN >= sizeof(ENTRY_TEMPLATE)); + + assert(slot >= 0); + + memcpy(entry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); + + *((uint64_t *) (entry + TEMPLATE_OFFSET_TLS_ADDR)) = (uintptr_t) ppc64_current_tls(); + *((uint64_t *) (entry + TEMPLATE_OFFSET_SLOT)) = slot * sizeof(mapi_func); + + // This sequence is from the PowerISA Version 2.07B book. + // It may be a bigger hammer than we need, but it works; + // note that the __builtin___clear_cache intrinsic for + // PPC does not seem to generate any code. + __asm__ __volatile__( + " dcbst 0, %0\n\t" + " sync\n\t" + " icbi 0, %0\n\t" + " isync\n" + : : "r" (entry) + ); +} + diff --git a/src/GLdispatch/vnd-glapi/entry_ppc64_tsd.c b/src/GLdispatch/vnd-glapi/entry_ppc64_tsd.c new file mode 100644 index 0000000..fd0c73e --- /dev/null +++ b/src/GLdispatch/vnd-glapi/entry_ppc64_tsd.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2010 LunarG Inc. + * Copyright (c) 2017, NVIDIA CORPORATION. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "entry.h" +#include "entry_common.h" + +#include +#include +#include +#include +#include + +#include "u_macros.h" +#include "glapi.h" +#include "glvnd/GLdispatchABI.h" + +#if !defined(_CALL_ELF) || (_CALL_ELF == 1) +#error "ELFv1 ABI is not supported" +#endif + +// NOTE: These must be powers of two: +#define ENTRY_STUB_ALIGN 256 +#if !defined(GLDISPATCH_PAGE_SIZE) +#define GLDISPATCH_PAGE_SIZE 65536 +#endif + +__asm__(".section wtext,\"ax\",@progbits\n"); +__asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" + ".globl public_entry_start\n" + ".hidden public_entry_start\n" + "public_entry_start:"); + +#define STUB_ASM_ENTRY(func) \ + ".globl " func "\n" \ + ".type " func ", @function\n" \ + ".balign " U_STRINGIFY(ENTRY_STUB_ALIGN) "\n" \ + func ":\n\t" \ + " addis 2, 12, .TOC.-" func "@ha\n\t" \ + " addi 2, 2, .TOC.-" func "@l\n\t" \ + " .localentry " func ", .-" func "\n\t" + +#define STUB_ASM_CODE(slot) \ + " addis 11, 2, _glapi_Current@got@ha\n" \ + " ld 11, _glapi_Current@got@l(11)\n" \ + " ld 11, 0(11)\n" \ + " cmpldi 11, 0\n" \ + " bne 1000f\n" \ + " mflr 0\n" \ + " std 0, 16(1)\n" \ + " stdu 1, -120(1)\n" \ + " std 3, 56(1)\n" \ + " std 4, 64(1)\n" \ + " std 5, 72(1)\n" \ + " std 6, 80(1)\n" \ + " std 7, 88(1)\n" \ + " std 8, 96(1)\n" \ + " std 9, 104(1)\n" \ + " std 10, 112(1)\n" \ + " bl _glapi_get_current\n" \ + " nop\n" \ + " mr 11, 3\n" \ + " ld 3, 56(1)\n" \ + " ld 4, 64(1)\n" \ + " ld 5, 72(1)\n" \ + " ld 6, 80(1)\n" \ + " ld 7, 88(1)\n" \ + " ld 8, 96(1)\n" \ + " ld 9, 104(1)\n" \ + " ld 10, 112(1)\n" \ + " addi 1, 1, 120\n" \ + " ld 0, 16(1)\n" \ + " mtlr 0\n" \ + "1000:\n" \ + " addis 11, 11, (" slot "*8)@ha\n" \ + " ld 12, (" slot "*8)@l (11)\n" \ + " mtctr 12\n" \ + " bctr\n" \ + + // Conceptually, this is: + // { + // void **dispatchTable = _glapi_Current[GLAPI_CURRENT_DISPATCH]; + // if (dispatchTable == NULL) { + // dispatchTable = _glapi_get_current(); + // } + // jump_to_address(dispatchTable[slot]); + // } + // + // Note that _glapi_Current is a simple global variable. + // See the x86 or x86-64 TSD code for examples. + +#define MAPI_TMP_STUB_ASM_GCC +#include "mapi_tmp.h" + + +__asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" + ".globl public_entry_end\n" + ".hidden public_entry_end\n" + "public_entry_end:"); +__asm__(".text\n"); + +const int entry_type = __GLDISPATCH_STUB_PPC64; +const int entry_stub_size = ENTRY_STUB_ALIGN; + +static const uint32_t ENTRY_TEMPLATE[] = +{ + // This should be functionally the same code as would be generated from + // the STUB_ASM_CODE macro, but defined as a buffer. + // This is used to generate new dispatch stubs. libglvnd will copy this + // data to the dispatch stub, and then it will patch the slot number and + // any addresses that it needs to. + // NOTE!!! NOTE!!! NOTE!!! + // This representation is correct for both little- and big-endian systems. + // However, more work needs to be done for big-endian Linux because it + // adheres to an older, AIX-compatible ABI that uses function descriptors. + // 1000: + 0x7c0802a6, // : mflr 0 + 0xf8010010, // : std 0, 16(1) + 0xe96c009c, // : ld 11, 9000f-1000b+0(12) + 0xe96b0000, // : ld 11, 0(11) + 0x282b0000, // : cmpldi 11, 0 + 0x41820014, // : beq 2000f + // 1050: + 0xe80c00ac, // : ld 0, 9000f-1000b+16(12) + 0x7d8b002a, // : ldx 12, 11, 0 + 0x7d8903a6, // : mtctr 12 + 0x4e800420, // : bctr + // 2000: + 0xf821ff71, // : stdu 1, -144(1) + 0xf8410018, // : std 2, 24(1) + 0xf8610038, // : std 3, 56(1) + 0xf8810040, // : std 4, 64(1) + 0xf8a10048, // : std 5, 72(1) + 0xf8c10050, // : std 6, 80(1) + 0xf8e10058, // : std 7, 88(1) + 0xf9010060, // : std 8, 96(1) + 0xf9210068, // : std 9, 104(1) + 0xf9410070, // : std 10, 112(1) + 0xf9810080, // : std 12, 128(1) + 0xe98c00a4, // : ld 12, 9000f-1000b+8(12) + 0x7d8903a6, // : mtctr 12 + 0x4e800421, // : bctrl + 0xe8410018, // : ld 2, 24(1) + 0xe9410070, // : ld 10, 112(1) + 0x7c6b1b78, // : mr 11, 3 + 0xe8610038, // : ld 3, 56(1) + 0xe8810040, // : ld 4, 64(1) + 0xe8a10048, // : ld 5, 72(1) + 0xe8c10050, // : ld 6, 80(1) + 0xe8e10058, // : ld 7, 88(1) + 0xe9010060, // : ld 8, 96(1) + 0xe9210068, // : ld 9, 104(1) + 0xe9810080, // : ld 12, 128(1) + 0x38210090, // : addi 1, 1, 144 + 0xe8010010, // : ld 0, 16(1) + 0x7c0803a6, // : mtlr 0 + 0x4bffff80, // : b 1050b + // 9000: + 0, 0, // : .quad _glapi_Current + 0, 0, // : .quad _glapi_get_current + 0, 0, // : .quad *8 +}; + +// These are the offsets in ENTRY_TEMPLATE of the values that we have to patch. +static const int TEMPLATE_OFFSET_CURRENT_TABLE = (sizeof(ENTRY_TEMPLATE) - 24); +static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET = (sizeof(ENTRY_TEMPLATE) - 16); +static const int TEMPLATE_OFFSET_SLOT = (sizeof(ENTRY_TEMPLATE) - 8); + +/* + * These offsets are used in entry_generate_default_code + * to patch the dispatch table index and any memory addresses in the generated + * function. + * + * TEMPLATE_OFFSET_SLOT is the dispatch table index. + * + * TEMPLATE_OFFSET_CURRENT_TABLE is the address of the global _glapi_Current + * variable. + * + * TEMPLATE_OFFSET_CURRENT_TABLE_GET is the address of the function + * _glapi_get_current. + */ +void entry_generate_default_code(int index, int slot) +{ + char *entry = (char *) (public_entry_start + (index * entry_stub_size)); + memcpy(entry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); + + *((uint32_t *) (entry + TEMPLATE_OFFSET_SLOT)) = slot * sizeof(mapi_func); + *((uintptr_t *) (entry + TEMPLATE_OFFSET_CURRENT_TABLE)) = (uintptr_t) _glapi_Current; + *((uintptr_t *) (entry + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = (uintptr_t) _glapi_get_current; + + // This sequence is from the PowerISA Version 2.07B book. + // It may be a bigger hammer than we need, but it works; + // note that the __builtin___clear_cache intrinsic for + // PPC does not seem to generate any code. + __asm__ __volatile__( + " dcbst 0, %0\n\t" + " sync\n\t" + " icbi 0, %0\n\t" + " isync\n" + : : "r" (entry) + ); +} + diff --git a/src/GLdispatch/vnd-glapi/entry_pure_c.c b/src/GLdispatch/vnd-glapi/entry_pure_c.c index e6d6657..6871d7d 100644 --- a/src/GLdispatch/vnd-glapi/entry_pure_c.c +++ b/src/GLdispatch/vnd-glapi/entry_pure_c.c @@ -30,6 +30,7 @@ #include #include "glapi.h" +#include "utils_misc.h" #include "glvnd/GLdispatchABI.h" static INLINE const struct _glapi_table * @@ -52,22 +53,15 @@ entry_current_get(void) const int entry_type = __GLDISPATCH_STUB_UNKNOWN; const int entry_stub_size = 0; -void -entry_init_public(void) -{ -} - -void -entry_generate_default_code(char *entry, int slot) -{ - assert(0); -} - mapi_func entry_get_public(int index) { - /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */ - return public_entries[index]; + /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */ + if (index >= 0 && index < ARRAY_LEN(public_entries)) { + return public_entries[index]; + } else { + return NULL; + } } int entry_patch_start(void) @@ -82,17 +76,19 @@ int entry_patch_finish(void) return 0; } -void entry_get_patch_addresses(mapi_func entry, void **writePtr, const void **execPtr) +void *entry_get_patch_address(int index) { assert(!"This should never be called"); - *writePtr = NULL; - *execPtr = NULL; + return NULL; } -#if !defined(STATIC_DISPATCH_ONLY) -mapi_func -entry_generate(int slot) +void *entry_save_entrypoints(void) +{ + assert(!"This should never be called"); + return NULL; +} + +void entry_restore_entrypoints(void *saved) { - return NULL; + assert(!"This should never be called"); } -#endif // !defined(STATIC_DISPATCH_ONLY) diff --git a/src/GLdispatch/vnd-glapi/entry_simple_asm.c b/src/GLdispatch/vnd-glapi/entry_simple_asm.c index 245b362..dcc9b8b 100644 --- a/src/GLdispatch/vnd-glapi/entry_simple_asm.c +++ b/src/GLdispatch/vnd-glapi/entry_simple_asm.c @@ -51,31 +51,7 @@ * each entrypoint to force switching to Thumb mode. */ -void entry_init_public(void) -{ -} - mapi_func entry_get_public(int index) { return (mapi_func)(public_entry_start + (index * entry_stub_size)); } - -void entry_get_patch_addresses(mapi_func entry, void **writePtr, const void **execPtr) -{ - *execPtr = (const void *) entry; - *writePtr = u_execmem_get_writable(entry); -} - -#if !defined(STATIC_DISPATCH_ONLY) -mapi_func entry_generate(int slot) -{ - void *code = u_execmem_alloc(entry_stub_size); - if (!code) { - return NULL; - } - - entry_generate_default_code(code, slot); - - return (mapi_func) code; -} -#endif // !defined(STATIC_DISPATCH_ONLY) diff --git a/src/GLdispatch/vnd-glapi/entry_x86_64_tls.c b/src/GLdispatch/vnd-glapi/entry_x86_64_tls.c index caca1cf..3f49990 100644 --- a/src/GLdispatch/vnd-glapi/entry_x86_64_tls.c +++ b/src/GLdispatch/vnd-glapi/entry_x86_64_tls.c @@ -58,6 +58,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" #ifdef __ILP32__ #define STUB_ASM_CODE(slot) \ + ENDBR \ "movq _glapi_tls_Current@GOTTPOFF(%rip), %rax\n\t" \ "movl %fs:(%rax), %r11d\n\t" \ "movl 4*" slot "(%r11d), %r11d\n\t" \ @@ -66,6 +67,7 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" #else // __ILP32__ #define STUB_ASM_CODE(slot) \ + ENDBR \ "movq _glapi_tls_Current@GOTTPOFF(%rip), %rax\n\t" \ "movq %fs:(%rax), %r11\n\t" \ "jmp *(8 * " slot ")(%r11)" @@ -82,53 +84,15 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" __asm__(".text\n"); -__asm__("x86_64_current_tls:\n\t" - "movq _glapi_tls_Current@GOTTPOFF(%rip), %rax\n\t" - "ret"); - -extern uint64_t -x86_64_current_tls(); - const int entry_stub_size = ENTRY_STUB_ALIGN; #ifdef __ILP32__ const int entry_type = __GLDISPATCH_STUB_X32; -static const unsigned char ENTRY_TEMPLATE[] = { - 0x64, 0x44, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, // movl %fs:0, %r11d - 0x67, 0x45, 0x8b, 0x9b, 0x34, 0x12, 0x00, 0x00, // movl 0x1234(%r11d), %r11d - 0x41, 0xff, 0xe3, // jmp *%r11 -}; - -static const unsigned int TLS_ADDR_OFFSET = 5; -static const unsigned int SLOT_OFFSET = 13; #else // __ILP32__ const int entry_type = __GLDISPATCH_STUB_X86_64; -static const unsigned char ENTRY_TEMPLATE[] = { - 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, // movq %fs:0, %r11 - 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00, // jmp *0x1234(%r11) -}; -static const unsigned int TLS_ADDR_OFFSET = 5; -static const unsigned int SLOT_OFFSET = 12; - #endif // __ILP32__ -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry = u_execmem_get_writable(entry); - uint64_t tls_addr; - - STATIC_ASSERT(ENTRY_STUB_ALIGN >= sizeof(ENTRY_TEMPLATE)); - - assert(slot >= 0); - - tls_addr = x86_64_current_tls(); - - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - *((unsigned int *) &writeEntry[TLS_ADDR_OFFSET]) = (unsigned int) tls_addr; - *((unsigned int *) &writeEntry[SLOT_OFFSET]) = (unsigned int) (slot * sizeof(mapi_func)); -} - diff --git a/src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c b/src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c index f3cff26..4f14d33 100644 --- a/src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c +++ b/src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c @@ -64,8 +64,12 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" * We can't do that in general for the generated stubs since they're emitted * into malloc()ed memory which may not be within 2GB of %rip, as explained in * the comment in u_execmem.c. + * + * TODO: The dynamic stubs are no longer allocated, so we should be able to + * assume that they're within 2GB of %rip. */ #define STUB_ASM_CODE(slot) \ + ENDBR \ "movq _glapi_Current@GOTPCREL(%rip), %rax\n\t" \ "movq (%rax), %rax\n" \ "test %rax, %rax\n\t" \ @@ -99,42 +103,3 @@ __asm__(".text\n"); const int entry_type = __GLDISPATCH_STUB_X86_64; const int entry_stub_size = ENTRY_STUB_ALIGN; -static const unsigned char ENTRY_TEMPLATE[] = -{ - // : movabs ENTRY_CURRENT_TABLE, %rax - 0x48, 0xa1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x48, 0x85, 0xc0, // : test %rax,%rax - 0x75, 0x1c, // : jne - // : movabs $_glapi_get_current, %rax - 0x48, 0xb8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, - 0x57, // : push %rdi - 0x56, // : push %rsi - 0x52, // : push %rdx - 0x51, // : push %rcx - 0x41, 0x50, // : push %r8 - 0x41, 0x51, // : push %r9 - 0xff, 0xd0, // : callq *%rax - 0x41, 0x59, // : pop %r9 - 0x41, 0x58, // : pop %r8 - 0x59, // : pop %rcx - 0x5a, // : pop %rdx - 0x5e, // : pop %rsi - 0x5f, // : pop %rdi - 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00 // jmpq *SLOT(%rax) -}; - -// These are the offsets in ENTRY_TEMPLATE of the values that we have to patch. -static const int TEMPLATE_OFFSET_CURRENT_TABLE = 2; -static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET = 17; -static const int TEMPLATE_OFFSET_SLOT = 45; - -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry = u_execmem_get_writable(entry); - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - - *((uint32_t *) (writeEntry + TEMPLATE_OFFSET_SLOT)) = slot * sizeof(mapi_func); - *((uintptr_t *) (writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE)) = (uintptr_t) _glapi_Current; - *((uintptr_t *) (writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = (uintptr_t) _glapi_get_current; -} - diff --git a/src/GLdispatch/vnd-glapi/entry_x86_tls.c b/src/GLdispatch/vnd-glapi/entry_x86_tls.c index 70db169..ec2d6d0 100644 --- a/src/GLdispatch/vnd-glapi/entry_x86_tls.c +++ b/src/GLdispatch/vnd-glapi/entry_x86_tls.c @@ -38,7 +38,7 @@ #include "glapi.h" #include "glvnd/GLdispatchABI.h" -#define ENTRY_STUB_ALIGN 16 +#define ENTRY_STUB_ALIGN 32 #if !defined(GLDISPATCH_PAGE_SIZE) #define GLDISPATCH_PAGE_SIZE 4096 #endif @@ -55,9 +55,14 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" ".balign " U_STRINGIFY(ENTRY_STUB_ALIGN) "\n" \ func ":\n" -#define STUB_ASM_CODE(slot) \ - "call x86_current_tls\n\t" \ - "movl %gs:(%eax), %eax\n\t" \ +#define STUB_ASM_CODE(slot) \ + ENDBR \ + "call 1f\n\t" \ + "1:\n\t" \ + "popl %eax\n\t" \ + "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t" \ + "movl _glapi_tls_Current@GOTNTPOFF(%eax), %eax\n\t" \ + "movl %gs:(%eax), %eax\n\t" \ "jmp *(4 * " slot ")(%eax)" #define MAPI_TMP_STUB_ASM_GCC @@ -70,35 +75,6 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" __asm__(".text\n"); -__asm__("x86_current_tls:\n\t" - ".balign " U_STRINGIFY(ENTRY_STUB_ALIGN) "\n" - "call 1f\n" - "1:\n\t" - "popl %eax\n\t" - "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t" - "movl _glapi_tls_Current@GOTNTPOFF(%eax), %eax\n\t" - "ret"); - -extern uint32_t -x86_current_tls(); - const int entry_type = __GLDISPATCH_STUB_X86; const int entry_stub_size = ENTRY_STUB_ALIGN; -static const unsigned char ENTRY_TEMPLATE[] = -{ - 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ - 0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */ -}; -static const int TEMPLATE_OFFSET_TLS_OFFSET = 2; -static const int TEMPLATE_OFFSET_SLOT = 8; - -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry = u_execmem_get_writable(entry); - - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - *((uint32_t *) (writeEntry + TEMPLATE_OFFSET_TLS_OFFSET)) = x86_current_tls(); - *((uint32_t *) (writeEntry + TEMPLATE_OFFSET_SLOT)) = (uint32_t) (slot * sizeof(mapi_func)); -} - diff --git a/src/GLdispatch/vnd-glapi/entry_x86_tsd.c b/src/GLdispatch/vnd-glapi/entry_x86_tsd.c index 2e0c690..84b0c2c 100644 --- a/src/GLdispatch/vnd-glapi/entry_x86_tsd.c +++ b/src/GLdispatch/vnd-glapi/entry_x86_tsd.c @@ -56,18 +56,20 @@ __asm__(".balign " U_STRINGIFY(GLDISPATCH_PAGE_SIZE) "\n" func ":\n" #define STUB_ASM_CODE(slot) \ - "push %ebx\n" \ + ENDBR \ "call 1f\n" \ "1:\n" \ - "popl %ebx\n" \ - "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx\n" \ - "movl _glapi_Current@GOT(%ebx), %eax\n" \ + "popl %ecx\n" \ + "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx\n" \ + "movl _glapi_Current@GOT(%ecx), %eax\n" \ "mov (%eax), %eax\n" \ "testl %eax, %eax\n" \ "jne 1f\n" \ + "push %ebx\n" \ + "movl %ecx, %ebx\n" \ "call _glapi_get_current@PLT\n" \ + "popl %ebx\n" \ "1:\n" \ - "pop %ebx\n" \ "jmp *(4 * " slot ")(%eax)\n" #define MAPI_TMP_STUB_ASM_GCC @@ -83,41 +85,3 @@ __asm__(".text\n"); const int entry_type = __GLDISPATCH_STUB_X86; const int entry_stub_size = ENTRY_STUB_ALIGN; -// Note that the generated stubs are simpler than the assembly stubs above. -// For the generated stubs, we can patch in the addresses of _glapi_Current and -// _glapi_get_current, so we don't need to go through the GOT and PLT lookups. -static const unsigned char ENTRY_TEMPLATE[] = -{ - 0xa1, 0x40, 0x30, 0x20, 0x10, // : mov _glapi_Current, %eax - 0x85, 0xc0, // : test %eax, %eax - 0x74, 0x06, // : je - 0xff, 0xa0, 0x40, 0x30, 0x20, 0x10, // : jmp *slot(%eax) - 0xe8, 0x40, 0x30, 0x20, 0x10, // : call _glapi_get_current - 0xff, 0xa0, 0x40, 0x30, 0x20, 0x10, // : jmp *slot(%eax) -}; - -// These are the offsets in ENTRY_TEMPLATE of the values that we have to patch. -static const int TEMPLATE_OFFSET_CURRENT_TABLE = 1; -static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET = 16; -static const int TEMPLATE_OFFSET_CURRENT_TABLE_GET_RELATIVE = 20; -static const int TEMPLATE_OFFSET_SLOT1 = 11; -static const int TEMPLATE_OFFSET_SLOT2 = 22; - -void entry_generate_default_code(char *entry, int slot) -{ - char *writeEntry = u_execmem_get_writable(entry); - uintptr_t getTableOffset; - - memcpy(writeEntry, ENTRY_TEMPLATE, sizeof(ENTRY_TEMPLATE)); - - *((uint32_t *) (writeEntry + TEMPLATE_OFFSET_SLOT1)) = slot * sizeof(mapi_func); - *((uint32_t *) (writeEntry + TEMPLATE_OFFSET_SLOT2)) = slot * sizeof(mapi_func); - *((uintptr_t *) (writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE)) = (uintptr_t) _glapi_Current; - - // Calculate the offset to patch for the CALL instruction to - // _glapi_get_current. - getTableOffset = (uintptr_t) _glapi_get_current; - getTableOffset -= (((uintptr_t) entry) + TEMPLATE_OFFSET_CURRENT_TABLE_GET_RELATIVE); - *((uintptr_t *) (writeEntry + TEMPLATE_OFFSET_CURRENT_TABLE_GET)) = getTableOffset; -} - diff --git a/src/GLdispatch/vnd-glapi/mapi_glapi.c b/src/GLdispatch/vnd-glapi/mapi_glapi.c index 07ecb5c..b44cd66 100644 --- a/src/GLdispatch/vnd-glapi/mapi_glapi.c +++ b/src/GLdispatch/vnd-glapi/mapi_glapi.c @@ -41,14 +41,13 @@ void _glapi_init(void) { u_current_init(); - entry_init_public(); } void _glapi_destroy(void) { u_current_destroy(); - stub_cleanup_dynamic(); + stub_cleanup(); } void @@ -83,19 +82,21 @@ _glapi_get_dispatch_table_size(void) return MAPI_TABLE_NUM_SLOTS; } -static const struct mapi_stub * +static int _glapi_get_stub(const char *name, int generate) { - const struct mapi_stub *stub; + int index; - if (!name) - return NULL; + if (!name) { + return -1; + } - stub = stub_find_public(name); - if (!stub) - stub = stub_find_dynamic(name, generate); + index = stub_find_public(name); + if (index < 0) { + index = stub_find_dynamic(name, generate); + } - return stub; + return index; } /** @@ -104,8 +105,7 @@ _glapi_get_stub(const char *name, int generate) int _glapi_get_proc_offset(const char *funcName) { - const struct mapi_stub *stub = _glapi_get_stub(funcName, 0); - return (stub) ? stub_get_slot(stub) : -1; + return _glapi_get_stub(funcName, 0); } /** @@ -116,8 +116,12 @@ _glapi_get_proc_offset(const char *funcName) _glapi_proc _glapi_get_proc_address(const char *funcName) { - const struct mapi_stub *stub = _glapi_get_stub(funcName, 1); - return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL; + int index = _glapi_get_stub(funcName, 1); + if (index >= 0) { + return stub_get_addr(index); + } else { + return NULL; + } } /** @@ -126,8 +130,7 @@ _glapi_get_proc_address(const char *funcName) const char * _glapi_get_proc_name(unsigned int offset) { - const struct mapi_stub *stub = stub_find_by_slot(offset); - return stub ? stub_get_name(stub) : NULL; + return stub_get_name(offset); } diff --git a/src/GLdispatch/vnd-glapi/meson.build b/src/GLdispatch/vnd-glapi/meson.build new file mode 100644 index 0000000..615cdff --- /dev/null +++ b/src/GLdispatch/vnd-glapi/meson.build @@ -0,0 +1,104 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +inc_vnd_glapi = include_directories('.') + +_libglapi_sources = [] +if have_tls + _libglapi_sources += 'u_current_tls.c' +else + _libglapi_sources += 'u_current_tsd.c' +endif + +_entry_files = [] +if gl_dispatch_type == 'pure_c' + _entry_files += 'entry_pure_c.c' +else + _entry_files += 'entry_common.c' + if gl_dispatch_type != 'armv7_tsd' + _entry_files += 'entry_simple_asm.c' + endif + if gl_dispatch_type == 'x86_tls' + _entry_files += 'entry_x86_tls.c' + elif gl_dispatch_type == 'x86_tsd' + _entry_files += 'entry_x86_tsd.c' + elif gl_dispatch_type == 'x86_64_tls' + _entry_files += 'entry_x86_64_tls.c' + elif gl_dispatch_type == 'x86_64_tsd' + _entry_files += 'entry_x86_64_tsd.c' + elif gl_dispatch_type == 'armv7_tsd' + _entry_files += 'entry_armv7_tsd.c' + elif gl_dispatch_type == 'aarch64_tsd' + _entry_files += 'entry_aarch64_tsd.c' + elif gl_dispatch_type == 'ppc64_tls' + _entry_files += 'entry_ppc64_tls.c' + elif gl_dispatch_type == 'ppc64_tsd' + _entry_files += 'entry_ppc64_tsd.c' + else + error('No matching ASM file for @0@'.format(gl_dispatch_type)) + endif +endif + +libglapi = static_library( + 'libglapi', + [ + 'mapi_glapi.c', + 'stub.c', + 'table.c', + _libglapi_sources, + glapi_mapi_tmp_h, + _entry_files, + ], + c_args : ['-DMAPI_ABI_HEADER="@0@"'.format(glapi_mapi_tmp_h.full_path())], + include_directories : inc_include, + dependencies : idep_utils_misc, + gnu_symbol_visibility : 'hidden', +) + +foreach g : ['gl', 'opengl', 'glesv1', 'glesv2'] + name = 'glapi_' + g + header = get_variable('g_glapi_mapi_@0@_tmp_h'.format(g)) + + _lib = static_library( + name, + ['stub.c', _entry_files, header], + c_args : [ + '-DSTATIC_DISPATCH_ONLY', + '-DMAPI_ABI_HEADER="@0@"'.format(header.full_path()), + ], + include_directories : [inc_include, inc_util], + gnu_symbol_visibility : 'hidden', + ) + + _dep = declare_dependency( + link_with : _lib, + include_directories : inc_vnd_glapi, + ) + + set_variable('idep_' + name, _dep) +endforeach + diff --git a/src/GLdispatch/vnd-glapi/stub.c b/src/GLdispatch/vnd-glapi/stub.c index e5490b5..bad5f7c 100644 --- a/src/GLdispatch/vnd-glapi/stub.c +++ b/src/GLdispatch/vnd-glapi/stub.c @@ -33,14 +33,12 @@ #include "entry.h" #include "stub.h" #include "table.h" +#include "utils_misc.h" #if !defined(STATIC_DISPATCH_ONLY) -#include "u_execmem.h" +static void stub_cleanup_dynamic(void); #endif -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) -#define MAPI_LAST_SLOT (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1) - struct mapi_stub { /*! * The name of the stub function. @@ -48,16 +46,10 @@ struct mapi_stub { const char *name; int slot; - mapi_func addr; - - /** - * A buffer to store the name of the function. This is only used for - * dynamic stubs. For static stubs, mapi_stub::name is a static - * string and mapi_stub::nameBuffer is NULL. - */ - char *nameBuffer; }; +static void *savedEntrypoints = NULL; + /* define public_stubs */ #define MAPI_TMP_PUBLIC_STUBS #include "mapi_tmp.h" @@ -78,21 +70,38 @@ stub_compare(const void *key, const void *elem) /** * Return the public stub with the given name. */ -const struct mapi_stub * +int stub_find_public(const char *name) { + const struct mapi_stub *stub; + // All of the function names start with "gl", so skip that prefix when // comparing names. if (name[0] == 'g' && name[1] == 'l') { name += 2; } - return (const struct mapi_stub *) bsearch(name, public_stubs, - ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare); + stub = (const struct mapi_stub *) bsearch(name, public_stubs, + ARRAY_LEN(public_stubs), sizeof(public_stubs[0]), stub_compare); + if (stub != NULL) { + return (stub - public_stubs); + } else { + return -1; + } +} + +void stub_cleanup(void) +{ + free(savedEntrypoints); + savedEntrypoints = NULL; + +#if !defined(STATIC_DISPATCH_ONLY) + stub_cleanup_dynamic(); +#endif } #if !defined(STATIC_DISPATCH_ONLY) -static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC]; +static char *dynamic_stub_names[MAPI_TABLE_NUM_DYNAMIC]; static int num_dynamic_stubs; void stub_cleanup_dynamic(void) @@ -101,139 +110,104 @@ void stub_cleanup_dynamic(void) // Free the copies of the stub names. for (i=0; inameBuffer); - stub->nameBuffer = NULL; + free(dynamic_stub_names[i]); + dynamic_stub_names[i] = NULL; } num_dynamic_stubs = 0; - u_execmem_free(); } /** * Add a dynamic stub. */ -static struct mapi_stub * +int stub_add_dynamic(const char *name) { - struct mapi_stub *stub; int idx; idx = num_dynamic_stubs; - /* minus 1 to make sure we can never reach the last slot */ - if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1) - return NULL; + if (idx >= MAPI_TABLE_NUM_DYNAMIC) + return -1; + + // Make sure that we have a dispatch stub for this index. If the stubs are + // in C instead of assembly, then we can't use dynamic dispatch stubs, and + // entry_get_public will return NULL. + if (entry_get_public(MAPI_TABLE_NUM_STATIC + idx) == NULL) { + return -1; + } - stub = &dynamic_stubs[idx]; + assert(dynamic_stub_names[idx] == NULL); /* * name is the pointer passed to glXGetProcAddress, so the caller may free * or modify it later. Allocate a copy of the name to store. */ - stub->nameBuffer = strdup(name); - if (stub->nameBuffer == NULL) { - return NULL; - } - - /* Assign the next unused slot. */ - stub->slot = MAPI_TABLE_NUM_STATIC + idx; - stub->addr = entry_generate(stub->slot); - if (!stub->addr) { - free(stub->nameBuffer); - stub->nameBuffer = NULL; - return NULL; + dynamic_stub_names[idx] = strdup(name); + if (dynamic_stub_names[idx] == NULL) { + return -1; } - stub->name = stub->nameBuffer; num_dynamic_stubs = idx + 1; - return stub; + return (MAPI_TABLE_NUM_STATIC + idx); } /** * Return the dynamic stub with the given name. If no such stub exists and * generate is true, a new stub is generated. */ -struct mapi_stub * +int stub_find_dynamic(const char *name, int generate) { - struct mapi_stub *stub = NULL; - int count, i; + int found = -1; + int i; - if (generate) - assert(!stub_find_public(name)); - - count = num_dynamic_stubs; - for (i = 0; i < count; i++) { - if (strcmp(name, dynamic_stubs[i].name) == 0) { - stub = &dynamic_stubs[i]; - break; - } - } - - /* generate a dynamic stub */ - if (generate && !stub) - stub = stub_add_dynamic(name); - - return stub; -} + if (generate) { + assert(stub_find_public(name) < 0); + } -const struct mapi_stub * -stub_find_by_slot(int slot) -{ - assert(slot >= 0); + for (i = 0; i < num_dynamic_stubs; i++) { + if (strcmp(name, dynamic_stub_names[i]) == 0) { + found = MAPI_TABLE_NUM_STATIC + i; + break; + } + } - if (slot < ARRAY_SIZE(public_stubs)) { - return &public_stubs[slot]; - } else if (slot - ARRAY_SIZE(public_stubs) < num_dynamic_stubs) { - return &dynamic_stubs[slot - ARRAY_SIZE(public_stubs)]; - } else { - return NULL; + /* generate a dynamic stub */ + if (generate && found < 0) { + found = stub_add_dynamic(name); } + + return found; } /** * Return the name of a stub. */ const char * -stub_get_name(const struct mapi_stub *stub) +stub_get_name(int index) { - return stub->name; + if (index < MAPI_TABLE_NUM_STATIC) { + return public_stubs[index].name; + } else { + return dynamic_stub_names[index - MAPI_TABLE_NUM_STATIC]; + } } int stub_get_count(void) { - return ARRAY_SIZE(public_stubs) + num_dynamic_stubs; -} - -#endif // !defined(STATIC_DISPATCH_ONLY) - -/** - * Return the slot of a stub. - */ -int -stub_get_slot(const struct mapi_stub *stub) -{ - return stub->slot; + return ARRAY_LEN(public_stubs) + num_dynamic_stubs; } /** * Return the address of a stub. */ mapi_func -stub_get_addr(const struct mapi_stub *stub) +stub_get_addr(int index) { - assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC); - if (stub->addr != NULL) - { - return stub->addr; - } - else - { - int index = stub - public_stubs; - return entry_get_public(index); - } + return entry_get_public(index); } +#endif // !defined(STATIC_DISPATCH_ONLY) static int stub_allow_override(void) { @@ -242,11 +216,20 @@ static int stub_allow_override(void) static GLboolean stubStartPatch(void) { + assert(savedEntrypoints == NULL); + if (!stub_allow_override()) { return GL_FALSE; } + savedEntrypoints = entry_save_entrypoints(); + if (savedEntrypoints == NULL) { + return GL_FALSE; + } + if (!entry_patch_start()) { + free(savedEntrypoints); + savedEntrypoints = NULL; return GL_FALSE; } @@ -260,26 +243,13 @@ static void stubFinishPatch(void) static void stubRestoreFuncsInternal(void) { - int i, slot; - const struct mapi_stub *stub; + assert(savedEntrypoints != NULL); assert(stub_allow_override()); - for (stub = public_stubs, i = 0; - i < ARRAY_SIZE(public_stubs); - stub++, i++) { - slot = (stub->slot == -1) ? MAPI_LAST_SLOT : stub->slot; - entry_generate_default_code((char *)stub_get_addr(stub), slot); - } - -#if !defined(STATIC_DISPATCH_ONLY) - for (stub = dynamic_stubs, i = 0; - i < num_dynamic_stubs; - stub++, i++) { - slot = (stub->slot == -1) ? MAPI_LAST_SLOT : stub->slot; - entry_generate_default_code((char *)stub_get_addr(stub), slot); - } -#endif // !defined(STATIC_DISPATCH_ONLY) + entry_restore_entrypoints(savedEntrypoints); + free(savedEntrypoints); + savedEntrypoints = NULL; } static GLboolean stubRestoreFuncs(void) @@ -301,33 +271,29 @@ static void stubAbortPatch(void) static GLboolean stubGetPatchOffset(const char *name, void **writePtr, const void **execPtr) { - const struct mapi_stub *stub; - void *writeAddr = NULL; - const void *execAddr = NULL; + int index; + void *addr = NULL; - stub = stub_find_public(name); + index = stub_find_public(name); #if !defined(STATIC_DISPATCH_ONLY) - if (!stub) { - stub = stub_find_dynamic(name, 0); + if (index < 0) { + index = stub_find_dynamic(name, 0); } #endif // !defined(STATIC_DISPATCH_ONLY) - if (stub) { - mapi_func addr = stub_get_addr(stub); - if (addr != NULL) { - entry_get_patch_addresses(addr, &writeAddr, &execAddr); - } + if (index >= 0) { + addr = entry_get_patch_address(index); } if (writePtr != NULL) { - *writePtr = writeAddr; + *writePtr = addr; } if (execPtr != NULL) { - *execPtr = execAddr; + *execPtr = addr; } - return ((writeAddr != NULL && execAddr != NULL) ? GL_TRUE : GL_FALSE); + return (addr != NULL ? GL_TRUE : GL_FALSE); } static int stubGetStubType(void) diff --git a/src/GLdispatch/vnd-glapi/stub.h b/src/GLdispatch/vnd-glapi/stub.h index 97211a7..698319c 100644 --- a/src/GLdispatch/vnd-glapi/stub.h +++ b/src/GLdispatch/vnd-glapi/stub.h @@ -31,35 +31,26 @@ #include "entry.h" #include "glapi.h" -struct mapi_stub; - -#if !defined(STATIC_DISPATCH_ONLY) - /** - * Frees any memory that was allocated for any dynamic stub functions. + * Frees any memory that was allocated for the stub functions. * - * This should only be called when the library is unloaded, since any generated - * functions won't work after this. + * This should only be called when the library is unloaded. */ -void stub_cleanup_dynamic(void); +void stub_cleanup(void); + +#if !defined(STATIC_DISPATCH_ONLY) -const struct mapi_stub * +int stub_find_public(const char *name); -struct mapi_stub * +int stub_find_dynamic(const char *name, int generate); -const struct mapi_stub * -stub_find_by_slot(int slot); - const char * -stub_get_name(const struct mapi_stub *stub); - -int -stub_get_slot(const struct mapi_stub *stub); +stub_get_name(int index); mapi_func -stub_get_addr(const struct mapi_stub *stub); +stub_get_addr(int index); int stub_get_count(void); #endif // !defined(STATIC_DISPATCH_ONLY) diff --git a/src/Makefile.am b/src/Makefile.am index 5f7ce79..c9551c0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,8 +12,10 @@ SUBDIRS += GLX SUBDIRS += GL endif -if ENABLE_GLES +if ENABLE_GLES1 SUBDIRS += GLESv1 +endif +if ENABLE_GLES2 SUBDIRS += GLESv2 endif @@ -28,7 +30,9 @@ EXTRA_DIST = \ generate/xml/gl.xml \ generate/xml/gl_other.xml \ generate/xml/glx.xml \ - generate/xml/glx_other.xml + generate/xml/glx_other.xml \ + generate/meson.build \ + meson.build clean-local: rm -f generate/*.pyc diff --git a/src/OpenGL/Makefile.am b/src/OpenGL/Makefile.am index 4b34dd5..edcfe3a 100644 --- a/src/OpenGL/Makefile.am +++ b/src/OpenGL/Makefile.am @@ -36,7 +36,7 @@ libopengl_main_la_CFLAGS = \ lib_LTLIBRARIES = libOpenGL.la -libOpenGL_la_SOURCES = +libOpenGL_la_SOURCES = libOpenGL_la_LDFLAGS = -shared \ $(LINKER_FLAG_NO_UNDEFINED) \ -version-info 0 @@ -49,3 +49,15 @@ libOpenGL_la_LIBADD = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opengl.pc + +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR='$(top_srcdir)' \ + TOP_BUILDDIR='$(top_builddir)' \ + NM='$(NM)' \ + PYTHON='$(PYTHON)' +TESTS = ogl-symbol-check.sh + +EXTRA_DIST = \ + ogl-symbol-check.sh \ + ogl.symbols \ + meson.build diff --git a/src/OpenGL/libopengl.c b/src/OpenGL/libopengl.c index 1b168d7..96932b7 100644 --- a/src/OpenGL/libopengl.c +++ b/src/OpenGL/libopengl.c @@ -43,9 +43,6 @@ void __attribute__((constructor)) __libGLInit(void) void _init(void) #endif { - // Fix up the static GL entrypoints, if necessary - entry_init_public(); - __glDispatchInit(); // Register these entrypoints with GLdispatch so they can be @@ -60,6 +57,7 @@ void _fini(void) #endif { // Unregister the GLdispatch entrypoints + stub_cleanup(); __glDispatchUnregisterStubCallbacks(patchStubId); __glDispatchFini(); } diff --git a/src/OpenGL/meson.build b/src/OpenGL/meson.build new file mode 100644 index 0000000..a08c897 --- /dev/null +++ b/src/OpenGL/meson.build @@ -0,0 +1,61 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libopengl_main = static_library( + 'opengl_main', + ['libopengl.c'], + include_directories : [inc_util, inc_vnd_glapi, inc_include, inc_dispatch], + gnu_symbol_visibility : 'hidden', +) + +libOpenGL = shared_library( + 'OpenGL', + link_whole : libopengl_main, + dependencies : [idep_gldispatch, idep_glapi_opengl, idep_utils_misc], + gnu_symbol_visibility : 'hidden', + install : true, + version : '0.0.0', +) + +pkg.generate( + libOpenGL, + filebase : 'opengl', + description : 'OpenGL (without GLX) library and headers.', + version : '4.5', +) + +test( + 'OpenGL symbols check', + prog_py, + args : [ + files_symbols_check, + '--nm', prog_nm.path(), + '--lib', libOpenGL, + '--symbols-file', files('ogl.symbols'), + ], + suite : ['symbols'], +) diff --git a/src/OpenGL/ogl-symbol-check.sh b/src/OpenGL/ogl-symbol-check.sh new file mode 100755 index 0000000..f8f951f --- /dev/null +++ b/src/OpenGL/ogl-symbol-check.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test "${PYTHON}" = ":" && exit 77 +test "x${NM}" = "x" && exit 77 + +exec "${PYTHON}" "${TOP_SRCDIR}/bin/symbols-check.py" \ + --nm "${NM}" \ + --lib "${TOP_BUILDDIR}/src/OpenGL/.libs/libOpenGL.so" \ + --symbols-file "${TOP_SRCDIR}/src/OpenGL/ogl.symbols" diff --git a/src/OpenGL/ogl.symbols b/src/OpenGL/ogl.symbols new file mode 100644 index 0000000..bd7d785 --- /dev/null +++ b/src/OpenGL/ogl.symbols @@ -0,0 +1,1044 @@ +glAccum +glActiveShaderProgram +glActiveTexture +glAlphaFunc +glAreTexturesResident +glArrayElement +glAttachShader +glBegin +glBeginConditionalRender +glBeginQuery +glBeginQueryIndexed +glBeginTransformFeedback +glBindAttribLocation +glBindBuffer +glBindBufferBase +glBindBufferRange +glBindBuffersBase +glBindBuffersRange +glBindFragDataLocation +glBindFragDataLocationIndexed +glBindFramebuffer +glBindImageTexture +glBindImageTextures +glBindProgramPipeline +glBindRenderbuffer +glBindSampler +glBindSamplers +glBindTexture +glBindTextures +glBindTextureUnit +glBindTransformFeedback +glBindVertexArray +glBindVertexBuffer +glBindVertexBuffers +glBitmap +glBlendColor +glBlendEquation +glBlendEquationi +glBlendEquationSeparate +glBlendEquationSeparatei +glBlendFunc +glBlendFunci +glBlendFuncSeparate +glBlendFuncSeparatei +glBlitFramebuffer +glBlitNamedFramebuffer +glBufferData +glBufferStorage +glBufferSubData +glCallList +glCallLists +glCheckFramebufferStatus +glCheckNamedFramebufferStatus +glClampColor +glClear +glClearAccum +glClearBufferData +glClearBufferfi +glClearBufferfv +glClearBufferiv +glClearBufferSubData +glClearBufferuiv +glClearColor +glClearDepth +glClearDepthf +glClearIndex +glClearNamedBufferData +glClearNamedBufferSubData +glClearNamedFramebufferfi +glClearNamedFramebufferfv +glClearNamedFramebufferiv +glClearNamedFramebufferuiv +glClearStencil +glClearTexImage +glClearTexSubImage +glClientActiveTexture +glClientWaitSync +glClipControl +glClipPlane +glColor3b +glColor3bv +glColor3d +glColor3dv +glColor3f +glColor3fv +glColor3i +glColor3iv +glColor3s +glColor3sv +glColor3ub +glColor3ubv +glColor3ui +glColor3uiv +glColor3us +glColor3usv +glColor4b +glColor4bv +glColor4d +glColor4dv +glColor4f +glColor4fv +glColor4i +glColor4iv +glColor4s +glColor4sv +glColor4ub +glColor4ubv +glColor4ui +glColor4uiv +glColor4us +glColor4usv +glColorMask +glColorMaski +glColorMaterial +glColorP3ui +glColorP3uiv +glColorP4ui +glColorP4uiv +glColorPointer +glCompileShader +glCompressedTexImage1D +glCompressedTexImage2D +glCompressedTexImage3D +glCompressedTexSubImage1D +glCompressedTexSubImage2D +glCompressedTexSubImage3D +glCompressedTextureSubImage1D +glCompressedTextureSubImage2D +glCompressedTextureSubImage3D +glCopyBufferSubData +glCopyImageSubData +glCopyNamedBufferSubData +glCopyPixels +glCopyTexImage1D +glCopyTexImage2D +glCopyTexSubImage1D +glCopyTexSubImage2D +glCopyTexSubImage3D +glCopyTextureSubImage1D +glCopyTextureSubImage2D +glCopyTextureSubImage3D +glCreateBuffers +glCreateFramebuffers +glCreateProgram +glCreateProgramPipelines +glCreateQueries +glCreateRenderbuffers +glCreateSamplers +glCreateShader +glCreateShaderProgramv +glCreateTextures +glCreateTransformFeedbacks +glCreateVertexArrays +glCullFace +glDebugMessageCallback +glDebugMessageControl +glDebugMessageInsert +glDeleteBuffers +glDeleteFramebuffers +glDeleteLists +glDeleteProgram +glDeleteProgramPipelines +glDeleteQueries +glDeleteRenderbuffers +glDeleteSamplers +glDeleteShader +glDeleteSync +glDeleteTextures +glDeleteTransformFeedbacks +glDeleteVertexArrays +glDepthFunc +glDepthMask +glDepthRange +glDepthRangeArrayv +glDepthRangef +glDepthRangeIndexed +glDetachShader +glDisable +glDisableClientState +glDisablei +glDisableVertexArrayAttrib +glDisableVertexAttribArray +glDispatchCompute +glDispatchComputeIndirect +glDrawArrays +glDrawArraysIndirect +glDrawArraysInstanced +glDrawArraysInstancedBaseInstance +glDrawBuffer +glDrawBuffers +glDrawElements +glDrawElementsBaseVertex +glDrawElementsIndirect +glDrawElementsInstanced +glDrawElementsInstancedBaseInstance +glDrawElementsInstancedBaseVertex +glDrawElementsInstancedBaseVertexBaseInstance +glDrawPixels +glDrawRangeElements +glDrawRangeElementsBaseVertex +glDrawTransformFeedback +glDrawTransformFeedbackInstanced +glDrawTransformFeedbackStream +glDrawTransformFeedbackStreamInstanced +glEdgeFlag +glEdgeFlagPointer +glEdgeFlagv +glEnable +glEnableClientState +glEnablei +glEnableVertexArrayAttrib +glEnableVertexAttribArray +glEnd +glEndConditionalRender +glEndList +glEndQuery +glEndQueryIndexed +glEndTransformFeedback +glEvalCoord1d +glEvalCoord1dv +glEvalCoord1f +glEvalCoord1fv +glEvalCoord2d +glEvalCoord2dv +glEvalCoord2f +glEvalCoord2fv +glEvalMesh1 +glEvalMesh2 +glEvalPoint1 +glEvalPoint2 +glFeedbackBuffer +glFenceSync +glFinish +glFlush +glFlushMappedBufferRange +glFlushMappedNamedBufferRange +glFogCoordd +glFogCoorddv +glFogCoordf +glFogCoordfv +glFogCoordPointer +glFogf +glFogfv +glFogi +glFogiv +glFramebufferParameteri +glFramebufferRenderbuffer +glFramebufferTexture +glFramebufferTexture1D +glFramebufferTexture2D +glFramebufferTexture3D +glFramebufferTextureLayer +glFrontFace +glFrustum +glGenBuffers +glGenerateMipmap +glGenerateTextureMipmap +glGenFramebuffers +glGenLists +glGenProgramPipelines +glGenQueries +glGenRenderbuffers +glGenSamplers +glGenTextures +glGenTransformFeedbacks +glGenVertexArrays +glGetActiveAtomicCounterBufferiv +glGetActiveAttrib +glGetActiveSubroutineName +glGetActiveSubroutineUniformiv +glGetActiveSubroutineUniformName +glGetActiveUniform +glGetActiveUniformBlockiv +glGetActiveUniformBlockName +glGetActiveUniformName +glGetActiveUniformsiv +glGetAttachedShaders +glGetAttribLocation +glGetBooleani_v +glGetBooleanv +glGetBufferParameteri64v +glGetBufferParameteriv +glGetBufferPointerv +glGetBufferSubData +glGetClipPlane +glGetCompressedTexImage +glGetCompressedTextureImage +glGetCompressedTextureSubImage +glGetDebugMessageLog +glGetDoublei_v +glGetDoublev +glGetError +glGetFloati_v +glGetFloatv +glGetFragDataIndex +glGetFragDataLocation +glGetFramebufferAttachmentParameteriv +glGetFramebufferParameteriv +glGetGraphicsResetStatus +glGetInteger64i_v +glGetInteger64v +glGetIntegeri_v +glGetIntegerv +glGetInternalformati64v +glGetInternalformativ +glGetLightfv +glGetLightiv +glGetMapdv +glGetMapfv +glGetMapiv +glGetMaterialfv +glGetMaterialiv +glGetMultisamplefv +glGetNamedBufferParameteri64v +glGetNamedBufferParameteriv +glGetNamedBufferPointerv +glGetNamedBufferSubData +glGetNamedFramebufferAttachmentParameteriv +glGetNamedFramebufferParameteriv +glGetNamedRenderbufferParameteriv +glGetnColorTable +glGetnCompressedTexImage +glGetnConvolutionFilter +glGetnHistogram +glGetnMapdv +glGetnMapfv +glGetnMapiv +glGetnMinmax +glGetnPixelMapfv +glGetnPixelMapuiv +glGetnPixelMapusv +glGetnPolygonStipple +glGetnSeparableFilter +glGetnTexImage +glGetnUniformdv +glGetnUniformfv +glGetnUniformiv +glGetnUniformuiv +glGetObjectLabel +glGetObjectPtrLabel +glGetPixelMapfv +glGetPixelMapuiv +glGetPixelMapusv +glGetPointerv +glGetPolygonStipple +glGetProgramBinary +glGetProgramInfoLog +glGetProgramInterfaceiv +glGetProgramiv +glGetProgramPipelineInfoLog +glGetProgramPipelineiv +glGetProgramResourceIndex +glGetProgramResourceiv +glGetProgramResourceLocation +glGetProgramResourceLocationIndex +glGetProgramResourceName +glGetProgramStageiv +glGetQueryBufferObjecti64v +glGetQueryBufferObjectiv +glGetQueryBufferObjectui64v +glGetQueryBufferObjectuiv +glGetQueryIndexediv +glGetQueryiv +glGetQueryObjecti64v +glGetQueryObjectiv +glGetQueryObjectui64v +glGetQueryObjectuiv +glGetRenderbufferParameteriv +glGetSamplerParameterfv +glGetSamplerParameterIiv +glGetSamplerParameterIuiv +glGetSamplerParameteriv +glGetShaderInfoLog +glGetShaderiv +glGetShaderPrecisionFormat +glGetShaderSource +glGetString +glGetStringi +glGetSubroutineIndex +glGetSubroutineUniformLocation +glGetSynciv +glGetTexEnvfv +glGetTexEnviv +glGetTexGendv +glGetTexGenfv +glGetTexGeniv +glGetTexImage +glGetTexLevelParameterfv +glGetTexLevelParameteriv +glGetTexParameterfv +glGetTexParameterIiv +glGetTexParameterIuiv +glGetTexParameteriv +glGetTextureImage +glGetTextureLevelParameterfv +glGetTextureLevelParameteriv +glGetTextureParameterfv +glGetTextureParameterIiv +glGetTextureParameterIuiv +glGetTextureParameteriv +glGetTextureSubImage +glGetTransformFeedbacki64_v +glGetTransformFeedbacki_v +glGetTransformFeedbackiv +glGetTransformFeedbackVarying +glGetUniformBlockIndex +glGetUniformdv +glGetUniformfv +glGetUniformIndices +glGetUniformiv +glGetUniformLocation +glGetUniformSubroutineuiv +glGetUniformuiv +glGetVertexArrayIndexed64iv +glGetVertexArrayIndexediv +glGetVertexArrayiv +glGetVertexAttribdv +glGetVertexAttribfv +glGetVertexAttribIiv +glGetVertexAttribIuiv +glGetVertexAttribiv +glGetVertexAttribLdv +glGetVertexAttribPointerv +glHint +glIndexd +glIndexdv +glIndexf +glIndexfv +glIndexi +glIndexiv +glIndexMask +glIndexPointer +glIndexs +glIndexsv +glIndexub +glIndexubv +glInitNames +glInterleavedArrays +glInvalidateBufferData +glInvalidateBufferSubData +glInvalidateFramebuffer +glInvalidateNamedFramebufferData +glInvalidateNamedFramebufferSubData +glInvalidateSubFramebuffer +glInvalidateTexImage +glInvalidateTexSubImage +glIsBuffer +glIsEnabled +glIsEnabledi +glIsFramebuffer +glIsList +glIsProgram +glIsProgramPipeline +glIsQuery +glIsRenderbuffer +glIsSampler +glIsShader +glIsSync +glIsTexture +glIsTransformFeedback +glIsVertexArray +glLightf +glLightfv +glLighti +glLightiv +glLightModelf +glLightModelfv +glLightModeli +glLightModeliv +glLineStipple +glLineWidth +glLinkProgram +glListBase +glLoadIdentity +glLoadMatrixd +glLoadMatrixf +glLoadName +glLoadTransposeMatrixd +glLoadTransposeMatrixf +glLogicOp +glMap1d +glMap1f +glMap2d +glMap2f +glMapBuffer +glMapBufferRange +glMapGrid1d +glMapGrid1f +glMapGrid2d +glMapGrid2f +glMapNamedBuffer +glMapNamedBufferRange +glMaterialf +glMaterialfv +glMateriali +glMaterialiv +glMatrixMode +glMemoryBarrier +glMemoryBarrierByRegion +glMinSampleShading +glMultiDrawArrays +glMultiDrawArraysIndirect +glMultiDrawElements +glMultiDrawElementsBaseVertex +glMultiDrawElementsIndirect +glMultiTexCoord1d +glMultiTexCoord1dv +glMultiTexCoord1f +glMultiTexCoord1fv +glMultiTexCoord1i +glMultiTexCoord1iv +glMultiTexCoord1s +glMultiTexCoord1sv +glMultiTexCoord2d +glMultiTexCoord2dv +glMultiTexCoord2f +glMultiTexCoord2fv +glMultiTexCoord2i +glMultiTexCoord2iv +glMultiTexCoord2s +glMultiTexCoord2sv +glMultiTexCoord3d +glMultiTexCoord3dv +glMultiTexCoord3f +glMultiTexCoord3fv +glMultiTexCoord3i +glMultiTexCoord3iv +glMultiTexCoord3s +glMultiTexCoord3sv +glMultiTexCoord4d +glMultiTexCoord4dv +glMultiTexCoord4f +glMultiTexCoord4fv +glMultiTexCoord4i +glMultiTexCoord4iv +glMultiTexCoord4s +glMultiTexCoord4sv +glMultiTexCoordP1ui +glMultiTexCoordP1uiv +glMultiTexCoordP2ui +glMultiTexCoordP2uiv +glMultiTexCoordP3ui +glMultiTexCoordP3uiv +glMultiTexCoordP4ui +glMultiTexCoordP4uiv +glMultMatrixd +glMultMatrixf +glMultTransposeMatrixd +glMultTransposeMatrixf +glNamedBufferData +glNamedBufferStorage +glNamedBufferSubData +glNamedFramebufferDrawBuffer +glNamedFramebufferDrawBuffers +glNamedFramebufferParameteri +glNamedFramebufferReadBuffer +glNamedFramebufferRenderbuffer +glNamedFramebufferTexture +glNamedFramebufferTextureLayer +glNamedRenderbufferStorage +glNamedRenderbufferStorageMultisample +glNewList +glNormal3b +glNormal3bv +glNormal3d +glNormal3dv +glNormal3f +glNormal3fv +glNormal3i +glNormal3iv +glNormal3s +glNormal3sv +glNormalP3ui +glNormalP3uiv +glNormalPointer +glObjectLabel +glObjectPtrLabel +glOrtho +glPassThrough +glPatchParameterfv +glPatchParameteri +glPauseTransformFeedback +glPixelMapfv +glPixelMapuiv +glPixelMapusv +glPixelStoref +glPixelStorei +glPixelTransferf +glPixelTransferi +glPixelZoom +glPointParameterf +glPointParameterfv +glPointParameteri +glPointParameteriv +glPointSize +glPolygonMode +glPolygonOffset +glPolygonStipple +glPopAttrib +glPopClientAttrib +glPopDebugGroup +glPopMatrix +glPopName +glPrimitiveRestartIndex +glPrioritizeTextures +glProgramBinary +glProgramParameteri +glProgramUniform1d +glProgramUniform1dv +glProgramUniform1f +glProgramUniform1fv +glProgramUniform1i +glProgramUniform1iv +glProgramUniform1ui +glProgramUniform1uiv +glProgramUniform2d +glProgramUniform2dv +glProgramUniform2f +glProgramUniform2fv +glProgramUniform2i +glProgramUniform2iv +glProgramUniform2ui +glProgramUniform2uiv +glProgramUniform3d +glProgramUniform3dv +glProgramUniform3f +glProgramUniform3fv +glProgramUniform3i +glProgramUniform3iv +glProgramUniform3ui +glProgramUniform3uiv +glProgramUniform4d +glProgramUniform4dv +glProgramUniform4f +glProgramUniform4fv +glProgramUniform4i +glProgramUniform4iv +glProgramUniform4ui +glProgramUniform4uiv +glProgramUniformMatrix2dv +glProgramUniformMatrix2fv +glProgramUniformMatrix2x3dv +glProgramUniformMatrix2x3fv +glProgramUniformMatrix2x4dv +glProgramUniformMatrix2x4fv +glProgramUniformMatrix3dv +glProgramUniformMatrix3fv +glProgramUniformMatrix3x2dv +glProgramUniformMatrix3x2fv +glProgramUniformMatrix3x4dv +glProgramUniformMatrix3x4fv +glProgramUniformMatrix4dv +glProgramUniformMatrix4fv +glProgramUniformMatrix4x2dv +glProgramUniformMatrix4x2fv +glProgramUniformMatrix4x3dv +glProgramUniformMatrix4x3fv +glProvokingVertex +glPushAttrib +glPushClientAttrib +glPushDebugGroup +glPushMatrix +glPushName +glQueryCounter +glRasterPos2d +glRasterPos2dv +glRasterPos2f +glRasterPos2fv +glRasterPos2i +glRasterPos2iv +glRasterPos2s +glRasterPos2sv +glRasterPos3d +glRasterPos3dv +glRasterPos3f +glRasterPos3fv +glRasterPos3i +glRasterPos3iv +glRasterPos3s +glRasterPos3sv +glRasterPos4d +glRasterPos4dv +glRasterPos4f +glRasterPos4fv +glRasterPos4i +glRasterPos4iv +glRasterPos4s +glRasterPos4sv +glReadBuffer +glReadnPixels +glReadPixels +glRectd +glRectdv +glRectf +glRectfv +glRecti +glRectiv +glRects +glRectsv +glReleaseShaderCompiler +glRenderbufferStorage +glRenderbufferStorageMultisample +glRenderMode +glResumeTransformFeedback +glRotated +glRotatef +glSampleCoverage +glSampleMaski +glSamplerParameterf +glSamplerParameterfv +glSamplerParameteri +glSamplerParameterIiv +glSamplerParameterIuiv +glSamplerParameteriv +glScaled +glScalef +glScissor +glScissorArrayv +glScissorIndexed +glScissorIndexedv +glSecondaryColor3b +glSecondaryColor3bv +glSecondaryColor3d +glSecondaryColor3dv +glSecondaryColor3f +glSecondaryColor3fv +glSecondaryColor3i +glSecondaryColor3iv +glSecondaryColor3s +glSecondaryColor3sv +glSecondaryColor3ub +glSecondaryColor3ubv +glSecondaryColor3ui +glSecondaryColor3uiv +glSecondaryColor3us +glSecondaryColor3usv +glSecondaryColorP3ui +glSecondaryColorP3uiv +glSecondaryColorPointer +glSelectBuffer +glShadeModel +glShaderBinary +glShaderSource +glShaderStorageBlockBinding +glStencilFunc +glStencilFuncSeparate +glStencilMask +glStencilMaskSeparate +glStencilOp +glStencilOpSeparate +glTexBuffer +glTexBufferRange +glTexCoord1d +glTexCoord1dv +glTexCoord1f +glTexCoord1fv +glTexCoord1i +glTexCoord1iv +glTexCoord1s +glTexCoord1sv +glTexCoord2d +glTexCoord2dv +glTexCoord2f +glTexCoord2fv +glTexCoord2i +glTexCoord2iv +glTexCoord2s +glTexCoord2sv +glTexCoord3d +glTexCoord3dv +glTexCoord3f +glTexCoord3fv +glTexCoord3i +glTexCoord3iv +glTexCoord3s +glTexCoord3sv +glTexCoord4d +glTexCoord4dv +glTexCoord4f +glTexCoord4fv +glTexCoord4i +glTexCoord4iv +glTexCoord4s +glTexCoord4sv +glTexCoordP1ui +glTexCoordP1uiv +glTexCoordP2ui +glTexCoordP2uiv +glTexCoordP3ui +glTexCoordP3uiv +glTexCoordP4ui +glTexCoordP4uiv +glTexCoordPointer +glTexEnvf +glTexEnvfv +glTexEnvi +glTexEnviv +glTexGend +glTexGendv +glTexGenf +glTexGenfv +glTexGeni +glTexGeniv +glTexImage1D +glTexImage2D +glTexImage2DMultisample +glTexImage3D +glTexImage3DMultisample +glTexParameterf +glTexParameterfv +glTexParameteri +glTexParameterIiv +glTexParameterIuiv +glTexParameteriv +glTexStorage1D +glTexStorage2D +glTexStorage2DMultisample +glTexStorage3D +glTexStorage3DMultisample +glTexSubImage1D +glTexSubImage2D +glTexSubImage3D +glTextureBarrier +glTextureBuffer +glTextureBufferRange +glTextureParameterf +glTextureParameterfv +glTextureParameteri +glTextureParameterIiv +glTextureParameterIuiv +glTextureParameteriv +glTextureStorage1D +glTextureStorage2D +glTextureStorage2DMultisample +glTextureStorage3D +glTextureStorage3DMultisample +glTextureSubImage1D +glTextureSubImage2D +glTextureSubImage3D +glTextureView +glTransformFeedbackBufferBase +glTransformFeedbackBufferRange +glTransformFeedbackVaryings +glTranslated +glTranslatef +glUniform1d +glUniform1dv +glUniform1f +glUniform1fv +glUniform1i +glUniform1iv +glUniform1ui +glUniform1uiv +glUniform2d +glUniform2dv +glUniform2f +glUniform2fv +glUniform2i +glUniform2iv +glUniform2ui +glUniform2uiv +glUniform3d +glUniform3dv +glUniform3f +glUniform3fv +glUniform3i +glUniform3iv +glUniform3ui +glUniform3uiv +glUniform4d +glUniform4dv +glUniform4f +glUniform4fv +glUniform4i +glUniform4iv +glUniform4ui +glUniform4uiv +glUniformBlockBinding +glUniformMatrix2dv +glUniformMatrix2fv +glUniformMatrix2x3dv +glUniformMatrix2x3fv +glUniformMatrix2x4dv +glUniformMatrix2x4fv +glUniformMatrix3dv +glUniformMatrix3fv +glUniformMatrix3x2dv +glUniformMatrix3x2fv +glUniformMatrix3x4dv +glUniformMatrix3x4fv +glUniformMatrix4dv +glUniformMatrix4fv +glUniformMatrix4x2dv +glUniformMatrix4x2fv +glUniformMatrix4x3dv +glUniformMatrix4x3fv +glUniformSubroutinesuiv +glUnmapBuffer +glUnmapNamedBuffer +glUseProgram +glUseProgramStages +glValidateProgram +glValidateProgramPipeline +glVertex2d +glVertex2dv +glVertex2f +glVertex2fv +glVertex2i +glVertex2iv +glVertex2s +glVertex2sv +glVertex3d +glVertex3dv +glVertex3f +glVertex3fv +glVertex3i +glVertex3iv +glVertex3s +glVertex3sv +glVertex4d +glVertex4dv +glVertex4f +glVertex4fv +glVertex4i +glVertex4iv +glVertex4s +glVertex4sv +glVertexArrayAttribBinding +glVertexArrayAttribFormat +glVertexArrayAttribIFormat +glVertexArrayAttribLFormat +glVertexArrayBindingDivisor +glVertexArrayElementBuffer +glVertexArrayVertexBuffer +glVertexArrayVertexBuffers +glVertexAttrib1d +glVertexAttrib1dv +glVertexAttrib1f +glVertexAttrib1fv +glVertexAttrib1s +glVertexAttrib1sv +glVertexAttrib2d +glVertexAttrib2dv +glVertexAttrib2f +glVertexAttrib2fv +glVertexAttrib2s +glVertexAttrib2sv +glVertexAttrib3d +glVertexAttrib3dv +glVertexAttrib3f +glVertexAttrib3fv +glVertexAttrib3s +glVertexAttrib3sv +glVertexAttrib4bv +glVertexAttrib4d +glVertexAttrib4dv +glVertexAttrib4f +glVertexAttrib4fv +glVertexAttrib4iv +glVertexAttrib4Nbv +glVertexAttrib4Niv +glVertexAttrib4Nsv +glVertexAttrib4Nub +glVertexAttrib4Nubv +glVertexAttrib4Nuiv +glVertexAttrib4Nusv +glVertexAttrib4s +glVertexAttrib4sv +glVertexAttrib4ubv +glVertexAttrib4uiv +glVertexAttrib4usv +glVertexAttribBinding +glVertexAttribDivisor +glVertexAttribFormat +glVertexAttribI1i +glVertexAttribI1iv +glVertexAttribI1ui +glVertexAttribI1uiv +glVertexAttribI2i +glVertexAttribI2iv +glVertexAttribI2ui +glVertexAttribI2uiv +glVertexAttribI3i +glVertexAttribI3iv +glVertexAttribI3ui +glVertexAttribI3uiv +glVertexAttribI4bv +glVertexAttribI4i +glVertexAttribI4iv +glVertexAttribI4sv +glVertexAttribI4ubv +glVertexAttribI4ui +glVertexAttribI4uiv +glVertexAttribI4usv +glVertexAttribIFormat +glVertexAttribIPointer +glVertexAttribL1d +glVertexAttribL1dv +glVertexAttribL2d +glVertexAttribL2dv +glVertexAttribL3d +glVertexAttribL3dv +glVertexAttribL4d +glVertexAttribL4dv +glVertexAttribLFormat +glVertexAttribLPointer +glVertexAttribP1ui +glVertexAttribP1uiv +glVertexAttribP2ui +glVertexAttribP2uiv +glVertexAttribP3ui +glVertexAttribP3uiv +glVertexAttribP4ui +glVertexAttribP4uiv +glVertexAttribPointer +glVertexBindingDivisor +glVertexP2ui +glVertexP2uiv +glVertexP3ui +glVertexP3uiv +glVertexP4ui +glVertexP4uiv +glVertexPointer +glViewport +glViewportArrayv +glViewportIndexedf +glViewportIndexedfv +glWaitSync +glWindowPos2d +glWindowPos2dv +glWindowPos2f +glWindowPos2fv +glWindowPos2i +glWindowPos2iv +glWindowPos2s +glWindowPos2sv +glWindowPos3d +glWindowPos3dv +glWindowPos3f +glWindowPos3fv +glWindowPos3i +glWindowPos3iv +glWindowPos3s +glWindowPos3sv diff --git a/src/generate/eglFunctionList.py b/src/generate/eglFunctionList.py index c14dd28..afe14c6 100644 --- a/src/generate/eglFunctionList.py +++ b/src/generate/eglFunctionList.py @@ -1,5 +1,3 @@ -#!/usr/bin/python - """ Contains a list of EGL functions to generate dispatch functions for. @@ -53,12 +51,10 @@ method values: Select the vendor that owns the current context. """ -def _eglFunc(name, method, static=False, public=False, inheader=None, prefix="", extension=None, retval=None): +def _eglFunc(name, method, inheader, static=False, public=False, prefix="", extension=None, retval=None): """ A convenience function to define an entry in the EGL function list. """ - if (inheader == None): - inheader = (not public) values = { "method" : method, "prefix" : prefix, @@ -71,10 +67,13 @@ def _eglFunc(name, method, static=False, public=False, inheader=None, prefix="", return (name, values) def _eglCore(name, method, **kwargs): - return _eglFunc(name, method, public=True, **kwargs) + return _eglFunc(name, method, public=True, inheader=False, **kwargs) -def _eglExt(name, method, **kwargs): - return _eglFunc(name, method, public=False, **kwargs) +def _eglExt(name, method, static=None, **kwargs): + if (static is None): + static = (method != "custom") + inheader = not static + return _eglFunc(name, method, static=static, inheader=inheader, public=False, **kwargs) EGL_FUNCTIONS = ( # EGL_VERSION_1_0 diff --git a/src/generate/genCommon.py b/src/generate/genCommon.py index 5c721ac..5c38d87 100644 --- a/src/generate/genCommon.py +++ b/src/generate/genCommon.py @@ -28,7 +28,7 @@ import sys import collections import re -import xml.etree.cElementTree as etree +import xml.etree.ElementTree as etree MAPI_TABLE_NUM_DYNAMIC = 4096 diff --git a/src/generate/gen_egl_dispatch.py b/src/generate/gen_egl_dispatch.py index 7c65e0b..5ff4a09 100755 --- a/src/generate/gen_egl_dispatch.py +++ b/src/generate/gen_egl_dispatch.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ Generates dispatch functions for EGL. @@ -7,26 +7,24 @@ The list of functions and arguments is read from the Khronos's XML files, with additional information defined in the module eglFunctionList. """ -import sys +import argparse import collections -import imp +import sys +import textwrap +import eglFunctionList import genCommon def main(): - if (len(sys.argv) < 4): - print("Usage: %r source|header [xml_file...]" % (sys.argv[0],)) - sys.exit(2) + parser = argparse.ArgumentParser() + parser.add_argument("target", choices=("header", "source"), + help="Whether to build the source or header file.") + parser.add_argument("xml_files", nargs="+", + help="The XML files with the EGL function lists.") - target = sys.argv[1] - funcListFile = sys.argv[2] - xmlFiles = sys.argv[3:] + args = parser.parse_args() - # The function list is a Python module, but it's specified on the command - # line. - eglFunctionList = imp.load_source("eglFunctionList", funcListFile) - - xmlFunctions = genCommon.getFunctions(xmlFiles) + xmlFunctions = genCommon.getFunctions(args.xml_files) xmlByName = dict((f.name, f) for f in xmlFunctions) functions = [] for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS: @@ -37,49 +35,47 @@ def main(): # Sort the function list by name. functions = sorted(functions, key=lambda f: f[0].name) - if (target == "header"): + if args.target == "header": text = generateHeader(functions) - elif (target == "source"): + elif args.target == "source": text = generateSource(functions) - else: - raise ValueError("Invalid target: %r" % (target,)) sys.stdout.write(text) def fixupEglFunc(func, eglFunc): result = dict(eglFunc) - if (result.get("prefix") == None): + if result.get("prefix") is None: result["prefix"] = "" - if (result.get("extension") != None): + if result.get("extension") is not None: text = "defined(" + result["extension"] + ")" result["extension"] = text - if (result["method"] in ("none", "custom")): + if result["method"] in ("none", "custom"): return result - if (result["method"] not in ("display", "device", "current")): + if result["method"] not in ("display", "device", "current"): raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name)) - if (func.hasReturn()): - if (result.get("retval") == None): + if func.hasReturn(): + if result.get("retval") is None: result["retval"] = getDefaultReturnValue(func.rt) return result def generateHeader(functions): - text = r""" -#ifndef G_EGLDISPATCH_STUBS_H -#define G_EGLDISPATCH_STUBS_H + text = textwrap.dedent(r""" + #ifndef G_EGLDISPATCH_STUBS_H + #define G_EGLDISPATCH_STUBS_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#include -#include -#include "glvnd/libeglabi.h" + #include + #include + #include "glvnd/libeglabi.h" -""".lstrip("\n") + """.lstrip("\n")) text += "enum {\n" for (func, eglFunc) in functions: @@ -90,17 +86,17 @@ extern "C" { text += "};\n" for (func, eglFunc) in functions: - if (eglFunc["inheader"]): + if eglFunc["inheader"]: text += generateGuardBegin(func, eglFunc) text += "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f=func, ex=eglFunc) text += generateGuardEnd(func, eglFunc) - text += r""" -#ifdef __cplusplus -} -#endif -#endif // G_EGLDISPATCH_STUBS_H -""" + text += textwrap.dedent(r""" + #ifdef __cplusplus + } + #endif + #endif // G_EGLDISPATCH_STUBS_H + """) return text def generateSource(functions): @@ -108,10 +104,11 @@ def generateSource(functions): text = "" text += '#include "egldispatchstubs.h"\n' text += '#include "g_egldispatchstubs.h"\n' + text += '#include \n' text += "\n" for (func, eglFunc) in functions: - if (eglFunc["method"] not in ("custom", "none")): + if eglFunc["method"] not in ("custom", "none"): text += generateGuardBegin(func, eglFunc) text += generateDispatchFunc(func, eglFunc) text += generateGuardEnd(func, eglFunc) @@ -128,7 +125,7 @@ def generateSource(functions): text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n" for (func, eglFunc) in functions: text += generateGuardBegin(func, eglFunc) - if (eglFunc["method"] != "none"): + if eglFunc["method"] != "none": text += " (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n" else: text += " NULL, // " + func.name + "\n" @@ -140,13 +137,13 @@ def generateSource(functions): def generateGuardBegin(func, eglFunc): ext = eglFunc.get("extension") - if (ext != None): + if ext is not None: return "#if " + ext + "\n" else: return "" def generateGuardEnd(func, eglFunc): - if (eglFunc.get("extension") != None): + if eglFunc.get("extension") is not None: return "#endif\n" else: return "" @@ -154,37 +151,39 @@ def generateGuardEnd(func, eglFunc): def generateDispatchFunc(func, eglFunc): text = "" - if (eglFunc.get("static")): + if eglFunc.get("static"): text += "static " - else: + elif eglFunc.get("public"): text += "PUBLIC " - text += r"""{f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs}) -{{ - typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs}); -""".format(f=func, ef=eglFunc) - - if (func.hasReturn()): + text += textwrap.dedent( + r""" + {f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs}) + {{ + typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs}); + """).lstrip("\n").format(f=func, ef=eglFunc) + + if func.hasReturn(): text += " {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc) text += " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func) - if (eglFunc["method"] == "current"): + if eglFunc["method"] == "current": text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func) - elif (eglFunc["method"] in ("display", "device")): - if (eglFunc["method"] == "display"): + elif eglFunc["method"] in ("display", "device"): + if eglFunc["method"] == "display": lookupFunc = "__eglDispatchFetchByDisplay" lookupType = "EGLDisplay" else: - assert(eglFunc["method"] == "device") + assert eglFunc["method"] == "device" lookupFunc = "__eglDispatchFetchByDevice" lookupType = "EGLDeviceEXT" lookupArg = None for arg in func.args: - if (arg.type == lookupType): + if arg.type == lookupType: lookupArg = arg.name break - if (lookupArg == None): + if lookupArg is None: raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,)) text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format( @@ -194,30 +193,30 @@ def generateDispatchFunc(func, eglFunc): text += " if(_ptr_{f.name} != NULL) {{\n".format(f=func) text += " " - if (func.hasReturn()): + if func.hasReturn(): text += "_ret = " text += "_ptr_{f.name}({f.callArgs});\n".format(f=func) text += " }\n" - if (func.hasReturn()): + if func.hasReturn(): text += " return _ret;\n" text += "}\n" return text def getDefaultReturnValue(typename): - if (typename.endswith("*")): + if typename.endswith("*"): return "NULL" - elif (typename == "EGLDisplay"): + elif typename == "EGLDisplay": return "EGL_NO_DISPLAY" - elif (typename == "EGLContext"): + elif typename == "EGLContext": return "EGL_NO_CONTEXT" - elif (typename == "EGLSurface"): + elif typename == "EGLSurface": return "EGL_NO_SURFACE" - elif (typename == "EGLBoolean"): + elif typename == "EGLBoolean": return "EGL_FALSE"; return "0" -if (__name__ == "__main__"): +if __name__ == "__main__": main() diff --git a/src/generate/gen_gldispatch_mapi.py b/src/generate/gen_gldispatch_mapi.py index 03fb49a..8a037d5 100755 --- a/src/generate/gen_gldispatch_mapi.py +++ b/src/generate/gen_gldispatch_mapi.py @@ -33,7 +33,7 @@ Generates the glapi_mapi_tmp.h header file from Khronos's XML file. """ import sys -import xml.etree.cElementTree as etree +import xml.etree.ElementTree as etree import genCommon @@ -53,7 +53,7 @@ def _main(): assert(all(functions[i].slot == i for i in range(len(functions)))) print(r""" -/* This file is automatically generated by mapi_abi.py. Do not modify. */ +/* This file is automatically generated by gen_gldispatch_mapi.py. Do not modify. */ #ifndef _GLAPI_TMP_H_ #define _GLAPI_TMP_H_ @@ -67,7 +67,7 @@ typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLe print(generate_noop_array(functions)) print(generate_public_stubs(functions)) print(generate_public_entries(functions)) - print(generate_stub_asm_gcc(functions)) + print(generate_stub_asm_gcc(functions, (target == "gldispatch"))) def generate_defines(functions): text = r""" @@ -132,7 +132,7 @@ def generate_public_stubs(functions): text += "static const struct mapi_stub public_stubs[] = {\n" for func in functions: - text += " { \"%s\", %d, NULL },\n" % (func.name, func.slot) + text += " { \"%s\", %d },\n" % (func.name, func.slot) text += "};\n" text += "#undef MAPI_TMP_PUBLIC_STUBS\n" text += "#endif /* MAPI_TMP_PUBLIC_STUBS */\n" @@ -162,7 +162,7 @@ GLAPI {f.rt} APIENTRY {f.name}({f.decArgs}) text += "#endif /* MAPI_TMP_PUBLIC_ENTRIES */\n" return text -def generate_stub_asm_gcc(functions): +def generate_stub_asm_gcc(functions, includeDynamic): text = "#ifdef MAPI_TMP_STUB_ASM_GCC\n" text += "__asm__(\n" @@ -170,6 +170,10 @@ def generate_stub_asm_gcc(functions): text += 'STUB_ASM_ENTRY("%s")"\\n"\n' % (func.name,) text += '"\\t"STUB_ASM_CODE("%d")"\\n"\n\n' % (func.slot,) + if (includeDynamic): + for i in range(genCommon.MAPI_TABLE_NUM_DYNAMIC): + text += 'STUB_ASM_ENTRY("dynamic_%04d")"\\n"\n' % (i,) + text += '"\\t"STUB_ASM_CODE("%d")"\\n"\n\n' % (len(functions) + i) text += ");\n" text += "#undef MAPI_TMP_STUB_ASM_GCC\n" text += "#endif /* MAPI_TMP_STUB_ASM_GCC */\n" diff --git a/src/generate/gen_libOpenGL_exports.py b/src/generate/gen_libOpenGL_exports.py index 92e4e7f..36721dd 100755 --- a/src/generate/gen_libOpenGL_exports.py +++ b/src/generate/gen_libOpenGL_exports.py @@ -30,7 +30,7 @@ Generates the list of functions that should be exported from libOpenGL.so. """ import sys -import xml.etree.cElementTree as etree +import xml.etree.ElementTree as etree import genCommon diff --git a/src/generate/meson.build b/src/generate/meson.build new file mode 100644 index 0000000..2d3554d --- /dev/null +++ b/src/generate/meson.build @@ -0,0 +1,74 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + + +foreach t : [['glapi_mapi_tmp.h', 'gldispatch'], + ['g_glapi_mapi_gl_tmp.h', 'gl'], + ['g_glapi_mapi_opengl_tmp.h', 'opengl'], + ['g_glapi_mapi_glesv1_tmp.h', 'glesv1'], + ['g_glapi_mapi_glesv2_tmp.h', 'glesv2']] + file = t[0] + target = t[1] + var = file.underscorify() + + _t = custom_target( + file, + input : ['gen_gldispatch_mapi.py', 'xml/gl.xml', 'xml/gl_other.xml'], + output : file, + command : [prog_py, '@INPUT0@', target, '@INPUT1@', '@INPUT2@'], + depend_files : files('genCommon.py'), + capture : true, + ) + + set_variable(var, _t) +endforeach + +foreach target : ['header', 'source'] + ext = target == 'header' ? 'h' : 'c' + _t = custom_target( + 'g_egldispatchstubs.' + ext, + input : ['gen_egl_dispatch.py', 'xml/egl.xml'], + output : ['g_egldispatchstubs.' + ext], + command : [ + prog_py, '@INPUT0@', target, '@INPUT1@', + ], + depend_files : files('genCommon.py', 'eglFunctionList.py'), + capture : true, + ) + + set_variable('g_egldispatchstubs_' + ext, _t) +endforeach + +g_libglglxwrapper_c = custom_target( + 'g_libglglxwrapper.c', + input : ['gen_libgl_glxstubs.py', 'xml/glx.xml', 'xml/glx_other.xml'], + output : ['g_libglglxwrapper.c'], + command : [prog_py, '@INPUT@'], + depend_files : files('genCommon.py'), + capture : true, +) + diff --git a/src/generate/xml/egl.xml b/src/generate/xml/egl.xml index c27f172..d354a1e 100644 --- a/src/generate/xml/egl.xml +++ b/src/generate/xml/egl.xml @@ -49,6 +49,9 @@ struct AHardwareBuffer; + struct wl_buffer; + struct wl_display; + struct wl_resource; @@ -89,7 +92,13 @@ EGLint iHeight; EGLint iStride; }; + typedef void ( *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); + #define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC + #define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC + #define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC + #define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC @@ -581,11 +590,27 @@ - + + + + + + + + + + + + @@ -719,7 +744,9 @@ - + + + @@ -1002,6 +1029,13 @@ + + + + + + + - - + + @@ -1796,14 +1830,14 @@ EGLBoolean eglSwapBuffersWithDamageEXT EGLDisplay dpy EGLSurface surface - EGLint *rects + const EGLint *rects EGLint n_rects EGLBoolean eglSwapBuffersWithDamageKHR EGLDisplay dpy EGLSurface surface - EGLint *rects + const EGLint *rects EGLint n_rects @@ -1900,6 +1934,28 @@ EGLint external_win_id EGLint policy + + EGLBoolean eglBindWaylandDisplayWL + EGLDisplay dpy + struct wl_display *display + + + EGLBoolean eglUnbindWaylandDisplayWL + EGLDisplay dpy + struct wl_display *display + + + EGLBoolean eglQueryWaylandBufferWL + EGLDisplay dpy + struct wl_resource *buffer + EGLint attribute + EGLint *value + + + struct wl_buffer *eglCreateWaylandBufferFromImageWL + EGLDisplay dpy + EGLImageKHR image + @@ -3278,5 +3334,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..0d57696 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,48 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +subdir('util') +subdir('generate') +subdir('GLdispatch') +subdir('OpenGL') + +if get_option('egl') + subdir('EGL') +endif + +if with_glx + subdir('GLX') + subdir('GL') +endif + +if get_option('gles1') + subdir('GLESv1') +endif +if get_option('gles2') + subdir('GLESv2') +endif + diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 88d3a58..73c3836 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -1,5 +1,4 @@ noinst_HEADERS = \ - glvnd_genentry.h \ utils_misc.h \ glvnd_pthread.h \ app_error_check.h \ @@ -7,7 +6,7 @@ noinst_HEADERS = \ trace.h \ cJSON.h -EXTRA_DIST = uthash cJSON +EXTRA_DIST = uthash cJSON meson.build noinst_LTLIBRARIES = AM_CPPFLAGS = -I$(top_srcdir)/include @@ -22,9 +21,6 @@ libapp_error_check_la_SOURCES = app_error_check.c noinst_LTLIBRARIES += libutils_misc.la libutils_misc_la_SOURCES = utils_misc.c -noinst_LTLIBRARIES += libglvnd_genentry.la -libglvnd_genentry_la_SOURCES = glvnd_genentry.c - noinst_LTLIBRARIES += libtrace.la libtrace_la_SOURCES = trace.c diff --git a/src/util/meson.build b/src/util/meson.build new file mode 100644 index 0000000..27c9f69 --- /dev/null +++ b/src/util/meson.build @@ -0,0 +1,100 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +inc_util = include_directories('.') + +libglvnd_pthread = static_library( + 'glvnd_pthread', + ['glvnd_pthread.c'], + dependencies : dep_dl, + gnu_symbol_visibility : 'hidden', +) + +idep_glvnd_pthread = declare_dependency( + link_with : libglvnd_pthread, + include_directories : inc_util, +) + +libapp_error_check = static_library( + 'app_error_check', + ['app_error_check.c'], + include_directories : inc_include, + gnu_symbol_visibility : 'hidden', +) + +idep_app_error_check = declare_dependency( + link_with : libapp_error_check, + include_directories : inc_util, +) + +libutils_misc = static_library( + 'utils_misc', + ['utils_misc.c'], + gnu_symbol_visibility : 'hidden', +) + +idep_utils_misc = declare_dependency( + link_with : libutils_misc, + include_directories : inc_util, +) + +libtrace = static_library( + 'trace', + ['trace.c'], + gnu_symbol_visibility : 'hidden', +) + +idep_trace = declare_dependency( + link_with : libtrace, + include_directories : inc_util, +) + +inc_uthash = include_directories('uthash/src') + +libwinsys_dispatch = static_library( + 'winsys_dispatch', + ['winsys_dispatch.c'], + include_directories : [inc_include, inc_uthash], + gnu_symbol_visibility : 'hidden', +) + +idep_winsys_dispatch = declare_dependency( + link_with : libwinsys_dispatch, + include_directories : [inc_util, inc_uthash], +) + +libcjson = static_library( + 'cJSON', + ['cJSON.c'], + gnu_symbol_visibility : 'hidden', +) + +idep_cjson = declare_dependency( + link_with : libcjson, + include_directories : inc_util, +) + diff --git a/src/util/utils_misc.c b/src/util/utils_misc.c index 52a8f43..7ff4c1e 100644 --- a/src/util/utils_misc.c +++ b/src/util/utils_misc.c @@ -39,33 +39,6 @@ #include #include -#define TEMP_FILENAME_ARRAY_SIZE 4 - -/** - * Populates \p dirs with a NULL-terminated list of directories to use to open - * a temp file. - * - * \param[out] dirs An array with at least \p TEMP_FILENAME_ARRAY_SIZE elements. - */ -static void GetTempDirs(const char **dirs); - -/** - * Creates a temp file. - * - * The file will be created with mkstemp(3), then immediately unlinked so that - * it doesn't risk leaving any clutter behind. - * - * \param tempdir The directory to create the file in. - * \return A file descriptor, or -1 on error. - */ -static int OpenTempFile(const char *tempdir); - -/** - * Allocates executable memory by mapping a file. - */ -static int AllocExecPagesFile(int fd, size_t size, void **writePtr, void **execPtr); -static int AllocExecPagesAnonymous(size_t size, void **writePtr, void **execPtr); - int glvnd_asprintf(char **strp, const char *fmt, ...) { va_list args; @@ -117,139 +90,6 @@ int glvnd_vasprintf(char **strp, const char *fmt, va_list args) return ret; } -int AllocExecPages(size_t size, void **writePtr, void **execPtr) -{ - const char *dirs[TEMP_FILENAME_ARRAY_SIZE]; - int i; - - *writePtr = NULL; - *execPtr = NULL; - - // Try to allocate the memory by creating a file and mapping it twice. - // This follows Ulrich Drepper's recommendation for allocating executable - // memory: - // http://www.akkadia.org/drepper/selinux-mem.html - GetTempDirs(dirs); - for (i=0; dirs[i] != NULL; i++) { - int fd = OpenTempFile(dirs[i]); - if (fd >= 0) { - int rv = AllocExecPagesFile(fd, size, writePtr, execPtr); - close(fd); - - if (rv == 0) { - return 0; - } - } - } - - // Using a file failed, so fall back to trying to create a single anonymous - // mapping. - return AllocExecPagesAnonymous(size, writePtr, execPtr); -} - -void FreeExecPages(size_t size, void *writePtr, void *execPtr) -{ - if (writePtr != NULL) { - munmap(writePtr, size); - } - if (execPtr != NULL && execPtr != writePtr) { - munmap(execPtr, size); - } -} - -int OpenTempFile(const char *tempdir) -{ - int fd = -1; - -#if defined(O_TMPFILE) - // If it's available, then try creating a file with O_TMPFILE first. - fd = open(tempdir, O_RDWR | O_TMPFILE | O_EXCL, S_IRUSR | S_IWUSR); -#endif // defined(HAVE_O_TMPFILE) - - if (fd < 0) - { - // If O_TMPFILE wasn't available or wasn't supported, then try mkstemp - // instead. - char *templateName = NULL; - if (glvnd_asprintf(&templateName, "%s/.glvndXXXXXX", tempdir) < 0) { - return -1; - } - - fd = mkstemp(templateName); - if (fd >= 0) { - // Unlink the file so that we don't leave any clutter behind. - unlink(templateName); - } - free(templateName); - templateName = NULL; - } - - // Make sure we can still use the file after it's unlinked. - if (fd >= 0) { - struct stat sb; - if (fstat(fd, &sb) != 0) { - close(fd); - fd = -1; - } - } - - return fd; -} - -int AllocExecPagesFile(int fd, size_t size, void **writePtr, void **execPtr) -{ - if (ftruncate(fd, size) != 0) { - return -1; - } - - *execPtr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); - if (*execPtr == MAP_FAILED) { - *execPtr = NULL; - return -1; - } - - *writePtr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (*writePtr == MAP_FAILED) { - munmap(*execPtr, size); - *execPtr = *writePtr = NULL; - return -1; - } - - return 0; -} - -int AllocExecPagesAnonymous(size_t size, void **writePtr, void **execPtr) -{ - void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (ptr == MAP_FAILED) { - return -1; - } - - *writePtr = *execPtr = ptr; - return 0; -} - -void GetTempDirs(const char **dirs) -{ - int count = 0; - - // Don't use the environment variables if we're running as setuid. - if (getuid() == geteuid()) { - dirs[count] = getenv("TMPDIR"); - if (dirs[count] != NULL) { - count++; - } - - dirs[count] = getenv("HOME"); - if (dirs[count] != NULL) { - count++; - } - } - dirs[count++] = "/tmp"; - dirs[count] = NULL; -} - void glvnd_byte_swap16(uint16_t* array, const size_t size) { int i; diff --git a/src/util/utils_misc.h b/src/util/utils_misc.h index a5e8ed7..711ce50 100644 --- a/src/util/utils_misc.h +++ b/src/util/utils_misc.h @@ -68,28 +68,6 @@ int glvnd_asprintf(char **strp, const char *fmt, ...); */ int glvnd_vasprintf(char **strp, const char *fmt, va_list args); -/** - * Allocates executable memory. - * - * To avoid having the same page be both writable and executable, this function - * returns two pointers to the same mapping, one read/write and one - * read/execute. - * - * Depending on the system, \p writePtr and \p execPtr may return the same - * pointer, mapped as read/write/execute. - * - * \param size The number of bytes to allocate. - * \param[out] writePtr Returns a pointer to the read/write mapping. - * \param[out] execPtr Returns a pointer to the read/exec mapping. - * \return Zero on success, non-zero on error. - */ -int AllocExecPages(size_t size, void **writePtr, void **execPtr); - -/** - * Frees the pages allocated from \p allocExecMem. - */ -void FreeExecPages(size_t size, void *writePtr, void *execPtr); - /*! * Swaps the bytes of an array. * diff --git a/tests/Makefile.am b/tests/Makefile.am index 2ae6ce2..74bb8bc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -43,7 +43,8 @@ check_PROGRAMS = EXTRA_DIST = $(TESTS) \ glxenv.sh \ eglenv.sh \ - json + json \ + meson.build CFLAGS_COMMON = \ -I$(top_srcdir)/include \ @@ -71,6 +72,16 @@ testgldispatch_LDADD += dummy/libpatchentrypoints.la testgldispatch_LDADD += $(top_builddir)/src/util/libutils_misc.la testgldispatch_LDADD += $(PTHREAD_LIBS) +TESTS += testgldispatchthread.sh +check_PROGRAMS += testgldispatchthread +testgldispatchthread_SOURCES = \ + testgldispatchthread.c +testgldispatchthread_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/GLdispatch \ + $(PTHREAD_CFLAGS) +testgldispatchthread_LDADD = $(top_builddir)/src/GLdispatch/libGLdispatch.la + # Start of GLX-specific tests. # Notes that the TESTS_GLX variable must be defined outside the conditional, so # that we can include the test scripts in the EXTRA_DIST package. Otherwise, @@ -81,13 +92,11 @@ TESTS_GLX += testglxcreatecontext.sh TESTS_GLX += testglxmcbasic.sh TESTS_GLX += testglxmcloop.sh TESTS_GLX += testglxmcthreads.sh -TESTS_GLX += testglxmclate.sh TESTS_GLX += testglxmcoldlink.sh TESTS_GLX += testglxgetprocaddress.sh TESTS_GLX += testglxgetprocaddress_genentry.sh TESTS_GLX += testglxgetclientstr.sh TESTS_GLX += testglxqueryversion.sh -TESTS_GLX += testpatchentrypoints.sh if ENABLE_GLX @@ -129,9 +138,19 @@ testglxmakecurrent_oldlink_LDADD += $(top_builddir)/src/util/libutils_misc.la check_PROGRAMS += testglxgetprocaddress -testglxgetprocaddress_CFLAGS = $(CFLAGS_COMMON) $(X11_CFLAGS) +testglxgetprocaddress_CFLAGS = \ + $(CFLAGS_COMMON) \ + $(X11_CFLAGS) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/GLdispatch testglxgetprocaddress_LDADD = $(X11_LIBS) testglxgetprocaddress_LDADD += $(top_builddir)/src/GLX/libGLX.la +testglxgetprocaddress_LDADD += $(top_builddir)/src/GLdispatch/libGLdispatch.la + + +check_PROGRAMS += testglxgetprocaddress_genentry +testglxgetprocaddress_genentry_LDADD = -lX11 +testglxgetprocaddress_genentry_LDADD += $(top_builddir)/src/GLX/libGLX.la check_PROGRAMS += testglxgetclientstr @@ -149,19 +168,6 @@ testglxqueryversion_LDADD = $(X11_LIBS) testglxqueryversion_LDADD += $(top_builddir)/src/GLX/libGLX.la testglxqueryversion_LDADD += $(top_builddir)/src/OpenGL/libOpenGL.la - -check_PROGRAMS += testpatchentrypoints -testpatchentrypoints_SOURCES = \ - testpatchentrypoints.c \ - test_utils.c - -testpatchentrypoints_CFLAGS = $(CFLAGS_COMMON) $(X11_CFLAGS) -testpatchentrypoints_LDADD = $(X11_LIBS) @LIB_DL@ -testpatchentrypoints_LDADD += $(top_builddir)/src/GLX/libGLX.la -testpatchentrypoints_LDADD += $(top_builddir)/src/OpenGL/libOpenGL.la -testpatchentrypoints_LDADD += $(top_builddir)/src/util/libtrace.la -testpatchentrypoints_LDADD += $(top_builddir)/src/util/libutils_misc.la - endif # ENABLE_GLX diff --git a/tests/dummy/GLX_dummy.c b/tests/dummy/GLX_dummy.c index 2f76082..525ac90 100644 --- a/tests/dummy/GLX_dummy.c +++ b/tests/dummy/GLX_dummy.c @@ -27,15 +27,12 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ -#include - #include #include #include #include #include #include -#include #include "GLX_dummy.h" #include "glvnd/libglxabi.h" @@ -67,11 +64,17 @@ static GLXContext dispatch_glXCreateContextVendorDUMMY(Display *dpy, static void dummy_glXExampleExtensionFunction(Display *dpy, int screen, int *retval); static void dispatch_glXExampleExtensionFunction(Display *dpy, int screen, int *retval); +static void dummy_glXExampleExtensionFunction2(Display *dpy, int screen, int *retval); +static void dispatch_glXExampleExtensionFunction2(Display *dpy, int screen, int *retval); +static void dummy_glXMakeCurrentTestResults(GLint req, GLboolean *saw, void **ret); +static void dispatch_glXMakeCurrentTestResults(GLint req, GLboolean *saw, void **ret); enum { DI_glXExampleExtensionFunction, + DI_glXExampleExtensionFunction2, DI_glXCreateContextVendorDUMMY, + DI_glXMakeCurrentTestResults, DI_COUNT, }; static struct { @@ -82,7 +85,9 @@ static struct { } glxExtensionProcs[] = { #define PROC_ENTRY(name) { #name, dummy_##name, dispatch_##name, -1 } PROC_ENTRY(glXExampleExtensionFunction), + PROC_ENTRY(glXExampleExtensionFunction2), PROC_ENTRY(glXCreateContextVendorDUMMY), + PROC_ENTRY(glXMakeCurrentTestResults), #undef PROC_ENTRY }; @@ -520,9 +525,7 @@ static void dummy_glEnd (void) ctx->endHit++; } -static void dummy_glMakeCurrentTestResults(GLint req, - GLboolean *saw, - void **ret) +static void dummy_glXMakeCurrentTestResults(GLint req, GLboolean *saw, void **ret) { GLXContext ctx = apiExports->getCurrentContext(); assert(ctx); @@ -538,15 +541,6 @@ static void dummy_glMakeCurrentTestResults(GLint req, *ret = (void *)data; } break; - case GL_MC_VENDOR_STRING: - { - // FIXME: This is used from testglxnscreens to check that the - // correct vendor library is loaded from each display. Originally, - // it used the vendor name passed to __glx_Main, but libGLX doesn't - // provide the vendor name anymore. - *ret = NULL; - } - break; case GL_MC_LAST_REQ: default: *ret = NULL; @@ -554,35 +548,76 @@ static void dummy_glMakeCurrentTestResults(GLint req, } } +static void dispatch_glXMakeCurrentTestResults(GLint req, GLboolean *saw, void **ret) +{ + __GLXvendorInfo *dynDispatch; + PFNGLXMAKECURRENTTESTRESULTSPROC func; + const int index = glxExtensionProcs[DI_glXMakeCurrentTestResults].index; + + dynDispatch = apiExports->getCurrentDynDispatch(); + if (!dynDispatch) { + return; + } + + func = (PFNGLXMAKECURRENTTESTRESULTSPROC) + apiExports->fetchDispatchEntry(dynDispatch, index); + if (func) { + func(req, saw, ret); + } +} + static void dummy_glXExampleExtensionFunction(Display *dpy, int screen, int *retval) { // Indicate that we've called the real function, and not a dispatch stub *retval = 1; } -static void dispatch_glXExampleExtensionFunction(Display *dpy, +static void commonDispatch_glXExampleExtensionFunction(Display *dpy, int screen, - int *retval) + int *retval, + int funcIndex) { - typedef void (*ExampleExtensionFunctionPtr)(Display *dpy, - int screen, - int *retval); __GLXvendorInfo *dynDispatch; - ExampleExtensionFunctionPtr func; - const int index = glxExtensionProcs[DI_glXExampleExtensionFunction].index; + PFNGLXEXAMPLEEXTENSIONFUNCTION func; + const int index = glxExtensionProcs[funcIndex].index; dynDispatch = apiExports->getDynDispatch(dpy, screen); if (!dynDispatch) { return; } - func = (ExampleExtensionFunctionPtr) + func = (PFNGLXEXAMPLEEXTENSIONFUNCTION) apiExports->fetchDispatchEntry(dynDispatch, index); if (func) { func(dpy, screen, retval); } } +static void dispatch_glXExampleExtensionFunction(Display *dpy, + int screen, + int *retval) +{ + // Set a different value here. That way, if a test fails, you can easily + // tell if it got as far as the dispatch function. + *retval = -1; + commonDispatch_glXExampleExtensionFunction(dpy, screen, retval, + DI_glXExampleExtensionFunction); +} + +static void dummy_glXExampleExtensionFunction2(Display *dpy, int screen, int *retval) +{ + *retval = 2; +} + +static void dispatch_glXExampleExtensionFunction2(Display *dpy, + int screen, + int *retval) +{ + *retval = -2; + commonDispatch_glXExampleExtensionFunction(dpy, screen, retval, + DI_glXExampleExtensionFunction2); +} + /* * Note we only fill in real implementations for a few core GL functions. * The rest will dispatch to the NOP stub. @@ -595,7 +630,6 @@ static const struct { PROC_ENTRY(glBegin), PROC_ENTRY(glEnd), PROC_ENTRY(glVertex3fv), - PROC_ENTRY(glMakeCurrentTestResults), PROC_ENTRY(glXChooseVisual), PROC_ENTRY(glXCopyContext), diff --git a/tests/dummy/GLX_dummy.h b/tests/dummy/GLX_dummy.h index 3c7c24a..fef6746 100644 --- a/tests/dummy/GLX_dummy.h +++ b/tests/dummy/GLX_dummy.h @@ -49,11 +49,6 @@ enum { GL_MC_FUNCTION_COUNTS, /* - * Returns a NULL-terminated string describing the name of this vendor. - */ - GL_MC_VENDOR_STRING, - - /* * Last request. Always returns NULL. */ GL_MC_LAST_REQ @@ -67,8 +62,16 @@ enum { */ #define GLX_CONTEX_ATTRIB_DUMMY 0x10000 +/** + * glXExampleExtensionFunction(): Dummy GLX extension function. + * + * This function just assigns 1 to *retval. It's used to test dispatching + * through a venodr-supplied dispatch function. + */ +typedef void (* PFNGLXEXAMPLEEXTENSIONFUNCTION) (Display *dpy, int screen, int *retval); + /* - * glMakeCurrentTestResults(): perform queries on vendor library state. + * glXMakeCurrentTestResults(): perform queries on vendor library state. * * This explicitly is designed to not return anything, in case a bug causes the * API library to dispatch this to a no-op stub. If this function returned a @@ -85,7 +88,7 @@ enum { * set to NULL if there was an error, or a pointer to request-specific data * otherwise. The pointer may be passed into free(3). */ -typedef void (*PFNGLMAKECURRENTTESTRESULTSPROC)( +typedef void (*PFNGLXMAKECURRENTTESTRESULTSPROC)( GLint req, GLboolean *saw, void **ret diff --git a/tests/dummy/Makefile.am b/tests/dummy/Makefile.am index 419a3d8..24afd73 100644 --- a/tests/dummy/Makefile.am +++ b/tests/dummy/Makefile.am @@ -4,7 +4,7 @@ noinst_HEADERS = \ EGL_dummy.h check_LTLIBRARIES = - + check_LTLIBRARIES += libpatchentrypoints.la libpatchentrypoints_la_CFLAGS = \ -I$(top_srcdir)/src/GLdispatch \ @@ -25,11 +25,13 @@ libGLX_dummy_la_SOURCES = \ libGLX_dummy_la_LIBADD = $(top_builddir)/src/util/libtrace.la libGLX_dummy_la_LIBADD += $(top_builddir)/src/util/libutils_misc.la libGLX_dummy_la_LIBADD += libpatchentrypoints.la +libGLX_dummy_la_LIBADD += $(X11_LIBS) # The -rpath option forces libtool to create a shared library instead of just a # static library. libGLX_dummy_la_LDFLAGS = \ -shared \ - -rpath /nowhere + -rpath /nowhere \ + $(LINKER_FLAG_NO_UNDEFINED) endif # ENABLE_GLX if ENABLE_EGL @@ -38,10 +40,13 @@ EGL_DUMMY_CFLAGS_COMMON = \ -I$(top_srcdir)/include EGL_DUMMY_SOURCES_COMMON = EGL_dummy.c EGL_DUMMY_LIBADD_COMMON = \ - $(top_builddir)/src/util/libglvnd_pthread.la + $(top_builddir)/src/util/libglvnd_pthread.la \ + $(top_builddir)/src/util/libtrace.la \ + $(top_builddir)/src/util/libutils_misc.la EGL_DUMMY_LDFLAGS_COMMON = \ -shared \ - -rpath /nowhere + -rpath /nowhere \ + $(LINKER_FLAG_NO_UNDEFINED) check_LTLIBRARIES += libEGL_dummy0.la libEGL_dummy0_la_CFLAGS = \ @@ -60,3 +65,5 @@ libEGL_dummy1_la_LIBADD = $(EGL_DUMMY_LIBADD_COMMON) libEGL_dummy1_la_LDFLAGS = $(EGL_DUMMY_LDFLAGS_COMMON) endif # ENABLE_EGL + +EXTRA_DIST = meson.build \ No newline at end of file diff --git a/tests/dummy/meson.build b/tests/dummy/meson.build new file mode 100644 index 0000000..71e5477 --- /dev/null +++ b/tests/dummy/meson.build @@ -0,0 +1,62 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +libpatchentrypoints = static_library( + 'patchentrypoints', + ['patchentrypoints.c'], + include_directories : [inc_include, inc_util, inc_dispatch], +) + +prog_cp = find_program('cp') + +if with_glx + libGLX_dummy = shared_library( + 'GLX_dummy', + ['GLX_dummy.c'], + include_directories : [inc_dispatch, inc_glx, inc_include], + link_with: [libpatchentrypoints], + dependencies : [idep_trace, idep_utils_misc, dep_x11], + version : '0', + ) +endif + +if get_option('egl') + foreach v : ['0', '1'] + shared_library( + 'EGL_dummy' + v, + ['EGL_dummy.c'], + c_args : ['-DDUMMY_VENDOR_NAME="dummy@0@"'.format(v)], + include_directories : [inc_include], + link_with: [libpatchentrypoints], + dependencies : [idep_glvnd_pthread], + version : '0', + ) + endforeach +endif + +dummy_build_dir = meson.current_build_dir() + diff --git a/tests/dummy/patchentrypoints.c b/tests/dummy/patchentrypoints.c index 6d57a5a..efbfcad 100644 --- a/tests/dummy/patchentrypoints.c +++ b/tests/dummy/patchentrypoints.c @@ -44,6 +44,7 @@ static void patch_x86_64(char *writeEntry, const char *execEntry, // that it's the right size for either build. uint64_t incrementAddr = (uint64_t) ((uintptr_t) incrementPtr); const char tmpl[] = { + 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 0xa1, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, // movabs 0x123456789abcdef0, %eax 0x83, 0xc0, 0x01, // add $0x1,%eax 0xa3, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, // movabs %eax,0x123456789abcdef0 @@ -55,8 +56,8 @@ static void patch_x86_64(char *writeEntry, const char *execEntry, } memcpy(writeEntry, tmpl, sizeof(tmpl)); - memcpy(writeEntry + 1, &incrementAddr, sizeof(incrementAddr)); - memcpy(writeEntry + 13, &incrementAddr, sizeof(incrementAddr)); + memcpy(writeEntry + 5, &incrementAddr, sizeof(incrementAddr)); + memcpy(writeEntry + 17, &incrementAddr, sizeof(incrementAddr)); #else assert(0); // Should not be calling this @@ -70,6 +71,7 @@ static void patch_x86(char *writeEntry, const char *execEntry, #if defined(__i386__) uintptr_t *p; char tmpl[] = { + 0xf3, 0x0f, 0x1e, 0xfb, // endbr32 0xa1, 0x0, 0x0, 0x0, 0x0, // mov 0x0, %eax 0x83, 0xc0, 0x01, // add $0x1, %eax 0xa3, 0x0, 0x0, 0x0, 0x0, // mov %eax, 0x0 @@ -83,10 +85,10 @@ static void patch_x86(char *writeEntry, const char *execEntry, } // Patch the address of the incrementPtr variable. - p = (uintptr_t *)&tmpl[1]; + p = (uintptr_t *)&tmpl[5]; *p = (uintptr_t) incrementPtr; - p = (uintptr_t *)&tmpl[9]; + p = (uintptr_t *)&tmpl[13]; *p = (uintptr_t) incrementPtr; memcpy(writeEntry, tmpl, sizeof(tmpl)); @@ -164,7 +166,7 @@ static void patch_aarch64(char *writeEntry, const char *execEntry, #endif } -static void patch_ppc64le(char *writeEntry, const char *execEntry, +static void patch_ppc64(char *writeEntry, const char *execEntry, int stubSize, void *incrementPtr) { #if defined(__PPC64__) @@ -176,9 +178,9 @@ static void patch_ppc64le(char *writeEntry, const char *execEntry, // 1000: 0x7D2903A6, // mtctr 9 0xE96C0020, // ld 11, 9000f-1000b(12) - 0xE92B0000, // ld 9, 0(11) + 0x812B0000, // lwz 9, 0(11) 0x39290001, // addi 9, 9, 1 - 0xF92B0000, // std 9, 0(11) + 0x912B0000, // stw 9, 0(11) 0x7D2902A6, // mfctr 9 0x4E800020, // blr 0x60000000, // nop @@ -220,7 +222,7 @@ GLboolean dummyCheckPatchSupported(int type, int stubSize) case __GLDISPATCH_STUB_ARMV7_THUMB: case __GLDISPATCH_STUB_AARCH64: case __GLDISPATCH_STUB_X32: - case __GLDISPATCH_STUB_PPC64LE: + case __GLDISPATCH_STUB_PPC64: return GL_TRUE; default: return GL_FALSE; @@ -253,8 +255,8 @@ GLboolean dummyPatchFunction(int type, int stubSize, case __GLDISPATCH_STUB_AARCH64: patch_aarch64(writeAddr, execAddr, stubSize, incrementPtr); break; - case __GLDISPATCH_STUB_PPC64LE: - patch_ppc64le(writeAddr, execAddr, stubSize, incrementPtr); + case __GLDISPATCH_STUB_PPC64: + patch_ppc64(writeAddr, execAddr, stubSize, incrementPtr); break; default: assert(0); diff --git a/tests/glxenv.sh b/tests/glxenv.sh index 7a3ed48..c6dea5c 100644 --- a/tests/glxenv.sh +++ b/tests/glxenv.sh @@ -1,6 +1,6 @@ #!/bin/sh -__GLX_VENDOR_LIBRARY_NAME=dummy -export __GLX_VENDOR_LIBRARY_NAME +__GLX_FORCE_VENDOR_LIBRARY_0=dummy +export __GLX_FORCE_VENDOR_LIBRARY_0 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TOP_BUILDDIR/tests/dummy/.libs export LD_LIBRARY_PATH diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..3509a57 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,214 @@ +# Copyright © 2019 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and/or associated documentation files (the +# "Materials"), to deal in the Materials without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Materials, and to +# permit persons to whom the Materials are furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be included +# unaltered in all copies or substantial portions of the Materials. +# Any additions, deletions, or changes to the original source files +# must be clearly indicated in accompanying documentation. + +# If only executable code is distributed, then the accompanying +# documentation must state that "this software is based in part on the +# work of the Khronos Group." + +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +subdir('dummy') + +exe_gldispatch = executable( + 'testgldispatch', + ['testgldispatch.c'], + include_directories : [inc_include], + link_with : [libOpenGL, libpatchentrypoints], + dependencies : [idep_gldispatch, idep_utils_misc, dep_threads], +) + +foreach k : [['static', ['-s']], + ['static thr', ['-s', '-t']], + ['generated', ['-g']], + ['generated end', ['-g', '-l']], + ['generated thr', ['-g', '-t']], + ['generated thr end', ['-g', '-t', '-l']], + ['patched', ['-s', '-g', '-p']], + ['patched end', ['-s', '-g', '-p', '-l']], + ['patched thr', ['-s', '-g', '-p', '-t']], + ['patched thr end', ['-s', '-g', '-p', '-t', '-l']]] + test( + 'gldispatch ' + k[0], + exe_gldispatch, + args : k[1], + suite : ['gldispatch'], + ) +endforeach + +test( + 'testgldispatchthread', + executable( + 'testgldispatchthread', + ['testgldispatchthread.c'], + include_directories : [inc_include], + dependencies : [idep_gldispatch, dep_threads], + ), + suite : ['gldispatch'], +) + +_env_ld = 'LD_LIBRARY_PATH=@0@/'.format(dummy_build_dir) + +if with_glx + env_glx = [ + '__GLX_FORCE_VENDOR_LIBRARY_0=dummy', + _env_ld, + ] + + test( + 'glxcreatecontext', + executable( + 'glxcreatecontext', + ['testglxcreatecontext.c', 'test_utils.c'], + include_directories : [inc_include], + link_with : libOpenGL, + dependencies : [idep_glx, dep_x11], + ), + env : env_glx, + suite : ['glx'], + ) + + exe_glxmakecurrent = executable( + 'glxmakecurrent', + ['testglxmakecurrent.c', 'test_utils.c'], + include_directories : [inc_include], + link_with : [libOpenGL], + dependencies : [ + dep_dl, dep_x11, idep_glvnd_pthread, idep_trace, idep_utils_misc, + idep_glx, + ], + ) + + foreach t : [['basic', ['-t', '1', '-i', '1'], env_glx], + ['loop', ['-t', '1', '-i', '250'], env_glx], + ['threads', ['-t', '5', '-i', '20000'], [env_glx, 'LD_PRELOAD=libpthread.so.0']], + ] + test( + 'glxmakecurrent (@0@)'.format(t[0]), + exe_glxmakecurrent, + args : t[1], + env : t[2], + suite : ['glx'], + ) + endforeach + + test( + 'glxmakecurrent (oldlink)', + executable( + 'glxmakecurrent_oldlink', + ['testglxmakecurrent.c', 'test_utils.c'], + include_directories : [inc_include], + link_with : [libGL], + dependencies : [ + dep_dl, dep_x11, idep_glvnd_pthread, idep_trace, idep_utils_misc, + ], + ), + args : ['-t', '1', '-i', '1'], + env : env_glx, + suite : ['glx'], + ) + + exe_glxgetprocaddress = executable( + 'glxgetprocaddress', + ['testglxgetprocaddress.c'], + include_directories : [inc_include], + dependencies : [dep_x11, idep_glx, idep_gldispatch], + ) + + test( + 'glxgetprocess', + exe_glxgetprocaddress, + env : env_glx, + suite : ['glx'], + ) + + test( + 'glxgetprocess_genentry', + exe_glxgetprocaddress, + env : env_glx, + suite : ['glx'], + ) + + test( + 'glxgetprocaddress_genentry', + executable( + 'testglxgetprocaddress_genentry', + ['testglxgetprocaddress_genentry.c'], + include_directories : [inc_include], + dependencies : [dep_x11, idep_glx], + ), + env : env_glx, + suite : ['glx'], + ) + + test( + 'glxgetclientstr', + executable( + 'glxgetclientstr', + ['testglxgetclientstr.c'], + include_directories : [inc_include], + link_with : libOpenGL, + dependencies : [dep_x11, idep_glx, idep_trace, idep_utils_misc], + ), + env : env_glx, + suite : ['glx'], + ) + + test( + 'glxgetqueryversion', + executable( + 'glxqueryversion', + ['testglxqueryversion.c'], + include_directories : [inc_include], + link_with : libOpenGL, + dependencies : [dep_x11, idep_glx], + ), + env : env_glx, + suite : ['glx'], + ) +endif + +if get_option('egl') + env_egl = [ + '__EGL_VENDOR_LIBRARY_DIRS=@0@'.format(join_paths(meson.current_source_dir(), 'json')), + _env_ld, + ] + + foreach t : [['egldisplay', [], []], + ['egldevice', [], []], + ['eglgetprocaddress', [], []], + ['eglmakecurrent', [libOpenGL], [idep_utils_misc]], + ['eglerror', [libOpenGL], []], + ['egldebug', [], []]] + test( + t[0], + executable( + t[0], + ['test@0@.c'.format(t[0]), 'egl_test_utils.c'], + include_directories : [inc_include], + link_with : [libEGL, t[1]], + dependencies : [t[2]], + ), + env : env_egl, + suite : ['egl'], + ) + endforeach +endif + diff --git a/tests/testgldispatch.c b/tests/testgldispatch.c index 4aedcfe..1b9341c 100644 --- a/tests/testgldispatch.c +++ b/tests/testgldispatch.c @@ -107,13 +107,14 @@ static GLboolean enableStaticTest = GL_FALSE; static GLboolean enableGeneratedTest = GL_FALSE; static GLboolean enablePatching = GL_FALSE; static GLboolean forceMultiThreaded = GL_FALSE; +static GLboolean useLastGenerated = GL_FALSE; int main(int argc, char **argv) { int i; while (1) { - int opt = getopt(argc, argv, "sgpt"); + int opt = getopt(argc, argv, "sgptl"); if (opt == -1) { break; } @@ -130,11 +131,24 @@ int main(int argc, char **argv) case 't': forceMultiThreaded = GL_TRUE; break; + case 'l': + useLastGenerated = GL_TRUE; + break; default: return 1; } }; +#if !defined(USE_DISPATCH_ASM) + // If the assembly dispatch stubs aren't enabled, then generating and + // patching entrypoints won't work. In that case, exit with 77 to tell + // automake to skip the test instead of failing. + if (enablePatching || enableGeneratedTest) + { + return 77; + } +#endif + __glDispatchInit(); InitDummyVendors(); @@ -153,9 +167,34 @@ int main(int argc, char **argv) } if (enableGeneratedTest) { + if (useLastGenerated) { + // Get enough dispatch stubs so that the one we test is at the very + // end of the dispatch table. On some architectures, loading from a + // high index can be more complicated than a low index, so make + // sure we got it right. + for (i=0; i<4095; i++) { + char name[32]; + snprintf(name, sizeof(name), "glDummyTestPaddingGLVND_%d", i); + __GLdispatchProc proc = __glDispatchGetProcAddress(name); + if (proc == NULL) { + printf("Can't find padding dispatch function for %d\n", i); + return 1; + } + } + } ptr_glDummyTestProc = (pfn_glVertex3fv) __glDispatchGetProcAddress(GENERATED_FUNCTION_NAME); if (ptr_glDummyTestProc == NULL) { printf("Can't find dispatch function for %s\n", GENERATED_FUNCTION_NAME); + return 1; + } + if (useLastGenerated) { + // We should have reached the end of the dispatch table by now, so + // another __glDispatchGetProcAddress call should return NULL. + __GLdispatchProc proc = __glDispatchGetProcAddress("glDummyTestPaddingGLVND_last"); + if (proc != NULL) { + printf("Got dispatch function past the end of the dispatch table.\n"); + return 1; + } } } diff --git a/tests/testgldispatch_generated.sh b/tests/testgldispatch_generated.sh index 8e98bc1..f729cf6 100755 --- a/tests/testgldispatch_generated.sh +++ b/tests/testgldispatch_generated.sh @@ -1,4 +1,7 @@ #!/bin/sh +set -e + ./testgldispatch -g +./testgldispatch -g -l diff --git a/tests/testgldispatch_generated_thr.sh b/tests/testgldispatch_generated_thr.sh index bf74be8..1379180 100755 --- a/tests/testgldispatch_generated_thr.sh +++ b/tests/testgldispatch_generated_thr.sh @@ -1,4 +1,7 @@ #!/bin/sh +set -e + ./testgldispatch -g -t +./testgldispatch -g -t -l diff --git a/tests/testgldispatch_patched.sh b/tests/testgldispatch_patched.sh index 78e4288..3795904 100755 --- a/tests/testgldispatch_patched.sh +++ b/tests/testgldispatch_patched.sh @@ -1,4 +1,7 @@ #!/bin/sh +set -e + ./testgldispatch -s -g -p +./testgldispatch -s -g -p -l diff --git a/tests/testgldispatch_patched_thr.sh b/tests/testgldispatch_patched_thr.sh index 78e4288..bacd4c1 100755 --- a/tests/testgldispatch_patched_thr.sh +++ b/tests/testgldispatch_patched_thr.sh @@ -1,4 +1,7 @@ #!/bin/sh -./testgldispatch -s -g -p +set -e + +./testgldispatch -s -g -p -t +./testgldispatch -s -g -p -t -l diff --git a/tests/testgldispatchthread.c b/tests/testgldispatchthread.c new file mode 100644 index 0000000..271bbe7 --- /dev/null +++ b/tests/testgldispatchthread.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * unaltered in all copies or substantial portions of the Materials. + * Any additions, deletions, or changes to the original source files + * must be clearly indicated in accompanying documentation. + * + * If only executable code is distributed, then the accompanying + * documentation must state that "this software is based in part on the + * work of the Khronos Group." + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define VENDOR_COUNT 2 +#define THREAD_COUNT 4 +#define CALL_COUNT 1 + +typedef struct { + int vendorID; + __GLdispatchTable *dispatch; +} VendorInfo; + +typedef struct { + __GLdispatchThreadState dispatchThreadState; + + pthread_t thread; + VendorInfo *vendor; + + int callCountStatic; + int callCountEarly; + int callCountLate; + GLboolean destroyed; +} ThreadState; + +typedef void (* pfn_glVertex3fv) (const GLfloat *v); + +static sem_t mainSemaphore; +static sem_t threadSemaphore; +static pfn_glVertex3fv ptr_glVertex3fv = NULL; +static pfn_glVertex3fv ptr_glTestFuncEarly = NULL; +static pfn_glVertex3fv ptr_glTestFuncLate = NULL; + +static ThreadState *GetCurrentThreadState(void) +{ + __GLdispatchThreadState *ts = __glDispatchGetCurrentThreadState(); + if (ts == NULL) { + printf("__glDispatchGetCurrentThreadState failed\n"); + } + return (ThreadState *) ts; +} + +static void dummy_glVertex3fv(const GLfloat *v) +{ + ThreadState *ts = GetCurrentThreadState(); + ts->callCountStatic++; +} + +static void glTestFuncEarlyDUMMY(const GLfloat *v) +{ + ThreadState *ts = GetCurrentThreadState(); + ts->callCountEarly++; +} +static void glTestFuncLateDUMMY(const GLfloat *v) +{ + ThreadState *ts = GetCurrentThreadState(); + ts->callCountLate++; +} + +static void *VendorGetProcAddressCallback(const char *procName, void *param) +{ + if (strcmp(procName, "glVertex3fv") == 0) { + return dummy_glVertex3fv; + } else if (strcmp(procName, "glTestFuncEarlyDUMMY") == 0) { + return glTestFuncEarlyDUMMY; + } else if (strcmp(procName, "glTestFuncLateDUMMY") == 0) { + return glTestFuncLateDUMMY; + } else { + return NULL; + } +} + +static void ThreadDestroyedCallback(__GLdispatchThreadState *dispatchThreadState) +{ + ThreadState *ts = (ThreadState *) dispatchThreadState; + ts->destroyed = GL_TRUE; +} + +static void *ThreadProc(void *param) +{ + ThreadState *ts = (ThreadState *) param; + int i; + + ts->dispatchThreadState.threadDestroyedCallback = ThreadDestroyedCallback; + + if (!__glDispatchMakeCurrent(&ts->dispatchThreadState, + ts->vendor->dispatch, ts->vendor->vendorID, + NULL)) { + printf("__glDispatchMakeCurrent failed\n"); + exit(1); + } + + // Notify the main thread that we're ready. + if (sem_post(&mainSemaphore) != 0) { + printf("sem_post failed\n"); + exit(1); + } + + // Wait for the main thread to finish calling __glDispatchGetProcAddress. + if (sem_wait(&threadSemaphore) != 0) { + printf("sem_wait failed\n"); + exit(1); + } + + for (i=0; i -#include #include #include -typedef __GLXextFuncPtr (* pfn_glXGetProcAddress) (const GLubyte *procName); -static pfn_glXGetProcAddress ptr_glXGetProcAddress; - -typedef void (* pfn_glXWaitGL) (void); -static pfn_glXWaitGL ptr_glXWaitGL; - -typedef void (* pfn_glVertex3fv) (const GLfloat *v); -static pfn_glVertex3fv ptr_glVertex3fv; - -typedef void (* pfn_glXExampleExtensionFunction) (Display *dpy, int screen, int *retval); -static pfn_glXExampleExtensionFunction ptr_glXExampleExtensionFunction; +#include +#include -typedef void (* pfn_glBogusFunc1) (int a, int b, int c); -static pfn_glBogusFunc1 ptr_glBogusFunc1; +#include +#include "dummy/GLX_dummy.h" -typedef void (* pfn_glBogusFunc2) (int a, int b, int c); -static pfn_glBogusFunc2 ptr_glBogusFunc2; +typedef const char * (* pfn_glXQueryServerString) (Display *dpy, int screen, int name); static void *LoadFunction(const char *name); int main(int argc, char **argv) { + pfn_glXQueryServerString ptr_glXQueryServerString; + PFNGLXEXAMPLEEXTENSIONFUNCTION ptr_glXExampleExtensionFunction; + Display *dpy = NULL; + const char *str; + __GLdispatchProc dispatchPtr, glxPtr; int retval = 0; - /* - * Try GetProcAddress on different classes of API functions, and bogus - * functions. The API library should return entry point addresses for - * any function beginning with gl*(), though bogus functions will resolve - * to no-ops. - */ - dpy = XOpenDisplay(NULL); if (dpy == NULL) { printf("Can't open display\n"); return 1; } - /* - * Load the function addresses up front. Note that in order to test GLX - * entrypoint generation, we have to load the functions early, before - * libGLX.so loads the vendor library. - */ - ptr_glXGetProcAddress = (pfn_glXGetProcAddress) - LoadFunction("glXGetProcAddress"); - ptr_glXWaitGL = (pfn_glXWaitGL) LoadFunction("glXWaitGL"); - ptr_glXExampleExtensionFunction = (pfn_glXExampleExtensionFunction) - LoadFunction("glXExampleExtensionFunction"); - ptr_glVertex3fv = (pfn_glVertex3fv) LoadFunction("glVertex3fv"); - ptr_glBogusFunc1 = (pfn_glBogusFunc1) LoadFunction("glBogusFunc1"); - ptr_glBogusFunc2 = (pfn_glBogusFunc2) LoadFunction("glBogusFunc2"); - - /* - * Test core GLX dispatch functions implemented by API library. This - * simply returns the symbol exported by libGLX. - */ - ptr_glXGetProcAddress((const GLubyte *) "glBogusFunc1"); - ptr_glXWaitGL(); - // Call glXGetClientString to force libGLX to load the vendor library. glXGetClientString(dpy, GLX_EXTENSIONS); + // Test a core GLX function first. + ptr_glXQueryServerString = (pfn_glXQueryServerString) LoadFunction("glXQueryServerString"); + str = ptr_glXQueryServerString(dpy, 0, GLX_VENDOR); + if (str == NULL) { + printf("glXQueryServerString returned NULL\n"); + return 1; + } + if (strcmp(str, "testlib") != 0) { + printf("glXQueryServerString returned unexpected value: %s\n", str); + return 1; + } + /* * Test a "GLX extension" function with a vendor-neutral dispatcher - * implemented by the vendor library (in this case, libGLX_dummy). If we - * successfully used libGLX_dummy's dispatcher, retval should be non-zero - * (a zero value indicates we might be calling into a no-op stub generated - * by libGLdispatch). + * implemented by the vendor library (in this case, libGLX_dummy). If we + * successfully used libGLX_dummy's dispatcher, retval should be 1. */ + ptr_glXExampleExtensionFunction = (PFNGLXEXAMPLEEXTENSIONFUNCTION) + LoadFunction("glXExampleExtensionFunction"); ptr_glXExampleExtensionFunction(dpy, 0, &retval); - if (!retval) { - printf("Unexpected glXExampleExtensionFunction() return value!\n"); + if (retval != 1) { + printf("Unexpected glXExampleExtensionFunction() return value: %d\n", retval); return 1; } - /* - * Try getting the address of the core GL function glVertex3fv(). - * This retrieves a static stub from glapi. - * Note calling this function with a NULL pointer is fine since this is a - * no-op function while there is no context current. - */ - ptr_glVertex3fv(NULL); - - /* - * These are bogus functions, but will get a valid entry point since they - * are prefixed with "gl". The first GetProcAddress() will early out since - * there should be a cached copy from the explicit call made above, but - * the second one will go through glapi's dynamic stub generation path. - * - * Again, calling these functions should be a no-op. - */ - ptr_glBogusFunc1(0, 0, 0); - ptr_glBogusFunc2(1, 1, 1); + // Test loading a normal GL function. Load the function through + // glXGetProcAddress, and then again directly through libGLdispatch. We + // should get the same poiner for both. + glxPtr = LoadFunction("glVertex3fv"); + dispatchPtr = __glDispatchGetProcAddress("glVertex3fv"); + if (dispatchPtr != glxPtr) { + printf("Mismatch for function glVertex3fv: GLX returned %p, GLdispatch returned %p\n", + glxPtr, dispatchPtr); + return 1; + } // Success! return 0; @@ -132,12 +101,21 @@ int main(int argc, char **argv) static void *LoadFunction(const char *name) { - __GLXextFuncPtr func = glXGetProcAddress((const GLubyte *) name); + __GLXextFuncPtr func, func2; + func = glXGetProcAddress((const GLubyte *) name); if (func == NULL) { printf("failed to get %s!\n", name); exit(1); } + // Call glXGetProcAddress again to make sure that we get the same address. + func2 = glXGetProcAddress((const GLubyte *) name); + if (func != func2) { + printf("glXGetProcAddress returned different address for %s: %p, %p\n", + name, func, func2); + exit(1); + } + return (void *) func; } diff --git a/tests/testglxgetprocaddress_genentry.c b/tests/testglxgetprocaddress_genentry.c new file mode 100644 index 0000000..7d97d1b --- /dev/null +++ b/tests/testglxgetprocaddress_genentry.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * unaltered in all copies or substantial portions of the Materials. + * Any additions, deletions, or changes to the original source files + * must be clearly indicated in accompanying documentation. + * + * If only executable code is distributed, then the accompanying + * documentation must state that "this software is based in part on the + * work of the Khronos Group." + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + */ + +#if defined(USE_DISPATCH_ASM) + +#include +#include +#include +#include + +#include "dummy/GLX_dummy.h" + +int main(int argc, char **argv) +{ + PFNGLXEXAMPLEEXTENSIONFUNCTION ptr_glXExampleExtensionFunction; + PFNGLXEXAMPLEEXTENSIONFUNCTION ptr_glXExampleExtensionFunction2; + __GLXextFuncPtr proc; + Display *dpy = NULL; + int result = 0; + int i; + + // Load the function pointer first, before libGLX can load the dummy vendor + // library. That'll force libGLX to generate an entrypoint stub. + ptr_glXExampleExtensionFunction = (PFNGLXEXAMPLEEXTENSIONFUNCTION) + glXGetProcAddress((const GLubyte *) "glXExampleExtensionFunction"); + if (ptr_glXExampleExtensionFunction == NULL) { + printf("Can't look up glXExampleExtensionFunction\n"); + return 1; + } + printf("Got glXExampleExtensionFunction at address %p\n", ptr_glXExampleExtensionFunction); + + // Call glXGetProcAddress to generate more dummy dispatch stubs, and then a + // second extension function. This tests that the generated dispatch stubs + // can correctly handle a large index. + for (i=0; i<4094; i++) { + char buf[50]; + + snprintf(buf, sizeof(buf), "glXUndefined%dDUMMY", i); + proc = glXGetProcAddress((const GLubyte *) buf); + if (proc == NULL) { + printf("Failed to generate stub for dummy function %d %s\n", i, buf); + return 1; + } + } + + ptr_glXExampleExtensionFunction2 = (PFNGLXEXAMPLEEXTENSIONFUNCTION) + glXGetProcAddress((const GLubyte *) "glXExampleExtensionFunction2"); + if (ptr_glXExampleExtensionFunction2 == NULL) { + printf("Can't look up glXExampleExtensionFunction\n"); + return 1; + } + printf("Got glXExampleExtensionFunction2 at address %p\n", ptr_glXExampleExtensionFunction2); + + // Make one more call to glXGetProcAddress. This should return NULL. + proc = glXGetProcAddress((const GLubyte *) "glXLastUndefinedDummy"); + if (proc != NULL) { + printf("Last glXGetProcAddress returned non-NULL: %p\n", proc); + return 1; + } + + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + printf("Can't open display\n"); + return 1; + } + + // Call glXGetClientString to force libGLX to load the vendor library. + glXGetClientString(dpy, GLX_EXTENSIONS); + + ptr_glXExampleExtensionFunction(dpy, 0, &result); + if (result != 1) { + printf("Unexpected glXExampleExtensionFunction() return value: %d\n", result); + XCloseDisplay(dpy); + return 1; + } + + ptr_glXExampleExtensionFunction2(dpy, 0, &result); + if (result != 2) { + printf("Unexpected glXExampleExtensionFunction2() return value: %d\n", result); + XCloseDisplay(dpy); + return 1; + } + + printf("%p - %p = %d\n", ptr_glXExampleExtensionFunction2, + ptr_glXExampleExtensionFunction, + (int) (((intptr_t) ptr_glXExampleExtensionFunction2) - ((intptr_t) ptr_glXExampleExtensionFunction))); + + XCloseDisplay(dpy); + return 0; +} + +#else // defined(USE_DISPATCH_ASM) + +int main(int argc, char **argv) +{ + // If libGLX can't generate new dispatch stubs, then just skip this test. + return 77; +} + +#endif // defined(USE_DISPATCH_ASM) diff --git a/tests/testglxgetprocaddress_genentry.sh b/tests/testglxgetprocaddress_genentry.sh index c8dac94..aa96294 100755 --- a/tests/testglxgetprocaddress_genentry.sh +++ b/tests/testglxgetprocaddress_genentry.sh @@ -2,11 +2,4 @@ . $TOP_SRCDIR/tests/glxenv.sh -# Set __GLX_FORCE_VENDOR_LIBRARY_0 instead of __GLX_VENDOR_LIBRARY_NAME. That -# way, it won't pre-load the vendor library, which would force it to generate -# a dispatch stub for glXExampleExtensionFunction. -__GLX_FORCE_VENDOR_LIBRARY_0=$__GLX_VENDOR_LIBRARY_NAME -export __GLX_FORCE_VENDOR_LIBRARY_0 -unset __GLX_VENDOR_LIBRARY_NAME - -./testglxgetprocaddress +./testglxgetprocaddress_genentry diff --git a/tests/testglxmakecurrent.c b/tests/testglxmakecurrent.c index c02c7b1..18ccb21 100644 --- a/tests/testglxmakecurrent.c +++ b/tests/testglxmakecurrent.c @@ -49,7 +49,6 @@ typedef struct TestOptionsRec { int iterations; int threads; - GLboolean late; } TestOptions; static void print_help(void) @@ -58,8 +57,7 @@ static void print_help(void) "Options: \n" " -h, --help Print this help message.\n" " -i, --iterations= Run N make current iterations in each thread \n" - " -t, --threads= Run with N threads.\n" - " -l, --late Call GetProcAddress() after MakeCurrent()\n"; + " -t, --threads= Run with N threads.\n"; printf("%s", help_string); } @@ -71,17 +69,15 @@ void init_options(int argc, char **argv, TestOptions *t) { "help", no_argument, NULL, 'h'}, { "iterations", required_argument, NULL, 'i'}, { "threads", required_argument, NULL, 't'}, - { "late", no_argument, NULL, 'l' }, { NULL, no_argument, NULL, 0 } }; // Initialize defaults t->iterations = 1; t->threads = 1; - t->late = GL_FALSE; do { - c = getopt_long(argc, argv, "hi:t:l", long_options, NULL); + c = getopt_long(argc, argv, "hi:t:", long_options, NULL); switch (c) { case -1: default: @@ -106,36 +102,15 @@ void init_options(int argc, char **argv, TestOptions *t) exit(1); } break; - case 'l': - t->late = GL_TRUE; - break; } } while (c != -1); } -static PFNGLMAKECURRENTTESTRESULTSPROC GetMakeCurrentTestResults(void) -{ - int i; - PFNGLMAKECURRENTTESTRESULTSPROC proc = NULL, old_proc = NULL; - // Call this multiple times to verify address caching works correctly. - for (i = 0; i < 3; i++) { - proc = (PFNGLMAKECURRENTTESTRESULTSPROC) - glXGetProcAddress((GLubyte *)"glMakeCurrentTestResults"); - if ((i != 0) && (proc != old_proc)) - { - printError("Got different addresses for glMakeCurrentTestResults: %p, %p\n", proc, old_proc); - return NULL; - } - old_proc = proc; - } - return proc; -} - void *MakeCurrentThread(void *arg) { struct window_info wi; - PFNGLMAKECURRENTTESTRESULTSPROC pMakeCurrentTestResults = NULL; + PFNGLXMAKECURRENTTESTRESULTSPROC pMakeCurrentTestResults = NULL; GLXContext ctx = NULL; const GLfloat v[] = { 0, 0, 0 }; struct { @@ -162,15 +137,16 @@ void *MakeCurrentThread(void *arg) goto fail; } + // Make sure that libGLX has loaded the vendor library. + glXGetClientString(dpy, GLX_EXTENSIONS); + // Test the robustness of GetProcAddress() by calling this separately for // each thread. - if (!t->late) { - pMakeCurrentTestResults = GetMakeCurrentTestResults(); - - if (!pMakeCurrentTestResults) { - printError("Failed to get glMakeCurrentTestResults() function!\n"); - goto fail; - } + pMakeCurrentTestResults = (PFNGLXMAKECURRENTTESTRESULTSPROC) + glXGetProcAddress((const GLubyte *) "glXMakeCurrentTestResults"); + if (pMakeCurrentTestResults == NULL) { + printError("Failed to get glXMakeCurrentTestResults() function!\n"); + goto fail; } success = testUtilsCreateWindow(dpy, &wi, 0); @@ -192,22 +168,13 @@ void *MakeCurrentThread(void *arg) goto fail; } - if (t->late) { - pMakeCurrentTestResults = GetMakeCurrentTestResults(); - - if (!pMakeCurrentTestResults) { - printError("Failed to get glMakeCurrentTestResults() function!\n"); - goto fail; - } - } - glBegin(GL_TRIANGLES); BeginCount++; glVertex3fv(v); Vertex3fvCount++; glVertex3fv(v); Vertex3fvCount++; glVertex3fv(v); Vertex3fvCount++; glEnd(); EndCount++; - // Make a call to glMakeCurrentTestResults() to get the function counts. + // Make a call to glXMakeCurrentTestResults() to get the function counts. makeCurrentTestResultsParams.req = GL_MC_FUNCTION_COUNTS; makeCurrentTestResultsParams.saw = GL_FALSE; makeCurrentTestResultsParams.ret = NULL; @@ -217,12 +184,12 @@ void *MakeCurrentThread(void *arg) &makeCurrentTestResultsParams.ret); if (!makeCurrentTestResultsParams.saw) { - printError("Failed to dispatch glMakeCurrentTestResults()!\n"); + printError("Failed to dispatch glXMakeCurrentTestResults()!\n"); goto fail; } if (!makeCurrentTestResultsParams.ret) { - printError("Internal glMakeCurrentTestResults() error!\n"); + printError("Internal glXMakeCurrentTestResults() error!\n"); goto fail; } @@ -248,7 +215,7 @@ void *MakeCurrentThread(void *arg) glVertex3fv(NULL); glEnd(); - // Similarly the call to the dynamic function glMakeCurrentTestResults() + // Similarly the call to the dynamic function glXMakeCurrentTestResults() // should be a no-op. makeCurrentTestResultsParams.req = GL_MC_FUNCTION_COUNTS; makeCurrentTestResultsParams.saw = GL_FALSE; @@ -259,7 +226,7 @@ void *MakeCurrentThread(void *arg) &makeCurrentTestResultsParams.ret); if (makeCurrentTestResultsParams.saw) { - printError("Dynamic function glMakeCurrentTestResults() dispatched " + printError("Dynamic function glXMakeCurrentTestResults() dispatched " "to vendor library even though no context was current!\n"); goto fail; }