From: Matt Turner Date: Mon, 21 Jan 2013 18:27:25 +0000 (-0800) Subject: build: Move src/mapi/mapi/* to src/mapi/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d5e9426b9605264608e0b1204ebf818103f1f011;p=mesa.git build: Move src/mapi/mapi/* to src/mapi/ Tested-by: Emil Velikov Reviewed-and-Tested-by: Andreas Boll Reviewed-by: Jordan Justen --- diff --git a/src/gallium/state_trackers/vega/Makefile.am b/src/gallium/state_trackers/vega/Makefile.am index 3ae096c85f3..5c5d071d105 100644 --- a/src/gallium/state_trackers/vega/Makefile.am +++ b/src/gallium/state_trackers/vega/Makefile.am @@ -63,6 +63,6 @@ libvega_la_SOURCES = \ BUILT_SOURCES = api_tmp.h CLEANFILES = api_tmp.h -api_tmp.h: $(top_srcdir)/src/mapi/vgapi/vgapi.csv $(top_srcdir)/src/mapi/mapi/mapi_abi.py - $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi/mapi_abi.py \ +api_tmp.h: $(top_srcdir)/src/mapi/vgapi/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py + $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \ --printer vgapi --mode app $< > $@ diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript index 394eaffe7bd..f8d75040255 100644 --- a/src/gallium/state_trackers/vega/SConscript +++ b/src/gallium/state_trackers/vega/SConscript @@ -49,7 +49,7 @@ vega_sources = [ api_tmp, = env.CodeGenerate( target = 'api_tmp.h', - script = '#src/mapi/mapi/mapi_abi.py', + script = '#src/mapi/mapi_abi.py', source = '#src/mapi/vgapi/vgapi.csv', command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET' ) diff --git a/src/gallium/state_trackers/vega/api.c b/src/gallium/state_trackers/vega/api.c index 4bf7c71d453..8fb0c418b19 100644 --- a/src/gallium/state_trackers/vega/api.c +++ b/src/gallium/state_trackers/vega/api.c @@ -26,7 +26,7 @@ * Chia-I Wu */ -#include "mapi/mapi.h" +#include "mapi.h" /* define vega_spec and vega_procs for use with mapi */ #define API_TMP_DEFINE_SPEC diff --git a/src/mapi/Android.mk b/src/mapi/Android.mk index d1749a2625d..f10437874dd 100644 --- a/src/mapi/Android.mk +++ b/src/mapi/Android.mk @@ -36,12 +36,12 @@ include $(CLEAR_VARS) abi_header := shared-glapi/glapi_mapi_tmp.h LOCAL_SRC_FILES := \ - mapi/entry.c \ - mapi/mapi_glapi.c \ - mapi/stub.c \ - mapi/table.c \ - mapi/u_current.c \ - mapi/u_execmem.c + entry.c \ + mapi_glapi.c \ + stub.c \ + table.c \ + u_current.c \ + u_execmem.c LOCAL_CFLAGS := \ -DMAPI_MODE_GLAPI \ @@ -68,9 +68,9 @@ include $(BUILD_SHARED_LIBRARY) mapi_abi_deps := \ $(wildcard $(LOCAL_PATH)/glapi/gen/*.py) \ $(wildcard $(LOCAL_PATH)/glapi/gen/*.xml) \ - $(LOCAL_PATH)/mapi/mapi_abi.py + $(LOCAL_PATH)/mapi_abi.py -$(mapi_abi_headers): PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/mapi/mapi_abi.py +$(mapi_abi_headers): PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/mapi_abi.py $(mapi_abi_headers): PRIVATE_APIXML := $(LOCAL_PATH)/glapi/gen/gl_and_es_API.xml $(mapi_abi_headers): $(mapi_abi_deps) @mkdir -p $(dir $@) diff --git a/src/mapi/Makefile.sources b/src/mapi/Makefile.sources new file mode 100644 index 00000000000..aff465a6015 --- /dev/null +++ b/src/mapi/Makefile.sources @@ -0,0 +1,36 @@ +# src/mapi/Makefile.sources +# +# mapi may be used in several ways +# +# - In default mode, mapi implements the interface defined by mapi.h. To use +# this mode, compile MAPI_FILES. +# +# - In util mode, mapi provides utility functions for use with glapi. To use +# this mode, compile MAPI_UTIL_FILES with MAPI_MODE_UTIL defined. +# +# - In glapi mode, mapi implements the interface defined by glapi.h. To use +# this mode, compile MAPI_GLAPI_FILES with MAPI_MODE_GLAPI defined. +# +# - In bridge mode, mapi provides entry points calling into glapi. To use +# this mode, compile MAPI_BRIDGE_FILES with MAPI_MODE_BRIDGE defined. + +MAPI_UTIL_FILES = \ + $(TOP)/src/mapi/u_current.c \ + $(TOP)/src/mapi/u_execmem.c + +MAPI_FILES = \ + $(TOP)/src/mapi/entry.c \ + $(TOP)/src/mapi/mapi.c \ + $(TOP)/src/mapi/stub.c \ + $(TOP)/src/mapi/table.c \ + $(MAPI_UTIL_FILES) + +MAPI_GLAPI_FILES = \ + $(TOP)/src/mapi/entry.c \ + $(TOP)/src/mapi/mapi_glapi.c \ + $(TOP)/src/mapi/stub.c \ + $(TOP)/src/mapi/table.c \ + $(MAPI_UTIL_FILES) + +MAPI_BRIDGE_FILES = \ + $(TOP)/src/mapi/entry.c diff --git a/src/mapi/entry.c b/src/mapi/entry.c new file mode 100644 index 00000000000..3d9168a7243 --- /dev/null +++ b/src/mapi/entry.c @@ -0,0 +1,98 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include "entry.h" +#include "u_current.h" +#include "u_macros.h" + +/* define macros for use by assembly dispatchers */ +#define ENTRY_CURRENT_TABLE U_STRINGIFY(u_current_table) + +/* in bridge mode, mapi is a user of glapi */ +#ifdef MAPI_MODE_BRIDGE +#define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch" +#else +#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_internal) +#endif + +#if defined(USE_X86_ASM) && defined(__GNUC__) +# ifdef GLX_USE_TLS +# include "entry_x86_tls.h" +# else +# include "entry_x86_tsd.h" +# endif +#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(GLX_USE_TLS) +# include "entry_x86-64_tls.h" +#else + +#include + +static INLINE const struct mapi_table * +entry_current_get(void) +{ +#ifdef MAPI_MODE_BRIDGE + return GET_DISPATCH(); +#else + return u_current_get(); +#endif +} + +/* C version of the public entries */ +#define MAPI_TMP_DEFINES +#define MAPI_TMP_PUBLIC_DECLARES +#define MAPI_TMP_PUBLIC_ENTRIES +#include "mapi_tmp.h" + +#ifndef MAPI_MODE_BRIDGE + +void +entry_patch_public(void) +{ +} + +mapi_func +entry_get_public(int slot) +{ + /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */ + return public_entries[slot]; +} + +mapi_func +entry_generate(int slot) +{ + return NULL; +} + +void +entry_patch(mapi_func entry, int slot) +{ +} + +#endif /* MAPI_MODE_BRIDGE */ + +#endif /* asm */ diff --git a/src/mapi/entry.h b/src/mapi/entry.h new file mode 100644 index 00000000000..9df81000470 --- /dev/null +++ b/src/mapi/entry.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#ifndef _ENTRY_H_ +#define _ENTRY_H_ + +#include "u_compiler.h" + +typedef void (*mapi_func)(void); + +void +entry_patch_public(void); + +mapi_func +entry_get_public(int slot); + +mapi_func +entry_generate(int slot); + +void +entry_patch(mapi_func entry, int slot); + +#endif /* _ENTRY_H_ */ diff --git a/src/mapi/entry_x86-64_tls.h b/src/mapi/entry_x86-64_tls.h new file mode 100644 index 00000000000..72d4125a694 --- /dev/null +++ b/src/mapi/entry_x86-64_tls.h @@ -0,0 +1,126 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include "u_macros.h" + +#ifdef __linux__ +__asm__(".section .note.ABI-tag, \"a\"\n\t" + ".p2align 2\n\t" + ".long 1f - 0f\n\t" /* name length */ + ".long 3f - 2f\n\t" /* data length */ + ".long 1\n\t" /* note length */ + "0: .asciz \"GNU\"\n\t" /* vendor name */ + "1: .p2align 2\n\t" + "2: .long 0\n\t" /* note data: the ABI tag */ + ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ + "3: .p2align 2\n\t"); /* pad out section */ +#endif /* __linux__ */ + +__asm__(".text\n" + ".balign 32\n" + "x86_64_entry_start:"); + +#define STUB_ASM_ENTRY(func) \ + ".globl " func "\n" \ + ".type " func ", @function\n" \ + ".balign 32\n" \ + func ":" + +#define STUB_ASM_CODE(slot) \ + "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ + "movq %fs:(%rax), %r11\n\t" \ + "jmp *(8 * " slot ")(%r11)" + +#define MAPI_TMP_STUB_ASM_GCC +#include "mapi_tmp.h" + +#ifndef MAPI_MODE_BRIDGE + +__asm__("x86_64_current_tls:\n\t" + "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" + "ret"); + +extern unsigned long +x86_64_current_tls(); + +#include +#include "u_execmem.h" + +void +entry_patch_public(void) +{ +} + +static char +x86_64_entry_start[]; + +mapi_func +entry_get_public(int slot) +{ + return (mapi_func) (x86_64_entry_start + slot * 32); +} + +void +entry_patch(mapi_func entry, int slot) +{ + char *code = (char *) entry; + *((unsigned int *) (code + 12)) = slot * sizeof(mapi_func); +} + +mapi_func +entry_generate(int slot) +{ + const char code_templ[16] = { + /* movq %fs:0, %r11 */ + 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, + /* jmp *0x1234(%r11) */ + 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00, + }; + unsigned long addr; + void *code; + mapi_func entry; + + addr = x86_64_current_tls(); + if ((addr >> 32) != 0xffffffff) + return NULL; + addr &= 0xffffffff; + + code = u_execmem_alloc(sizeof(code_templ)); + if (!code) + return NULL; + + memcpy(code, code_templ, sizeof(code_templ)); + + *((unsigned int *) (code + 5)) = addr; + entry = (mapi_func) code; + entry_patch(entry, slot); + + return entry; +} + +#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/entry_x86_tls.h b/src/mapi/entry_x86_tls.h new file mode 100644 index 00000000000..de918128eee --- /dev/null +++ b/src/mapi/entry_x86_tls.h @@ -0,0 +1,146 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include +#include "u_macros.h" + +#ifdef __linux__ +__asm__(".section .note.ABI-tag, \"a\"\n\t" + ".p2align 2\n\t" + ".long 1f - 0f\n\t" /* name length */ + ".long 3f - 2f\n\t" /* data length */ + ".long 1\n\t" /* note length */ + "0: .asciz \"GNU\"\n\t" /* vendor name */ + "1: .p2align 2\n\t" + "2: .long 0\n\t" /* note data: the ABI tag */ + ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ + "3: .p2align 2\n\t"); /* pad out section */ +#endif /* __linux__ */ + +__asm__(".text"); + +__asm__("x86_current_tls:\n\t" + "call 1f\n" + "1:\n\t" + "popl %eax\n\t" + "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t" + "movl " ENTRY_CURRENT_TABLE "@GOTNTPOFF(%eax), %eax\n\t" + "ret"); + +#ifndef GLX_X86_READONLY_TEXT +__asm__(".section wtext, \"awx\", @progbits"); +#endif /* GLX_X86_READONLY_TEXT */ + +__asm__(".balign 16\n" + "x86_entry_start:"); + +#define STUB_ASM_ENTRY(func) \ + ".globl " func "\n" \ + ".type " func ", @function\n" \ + ".balign 16\n" \ + func ":" + +#define STUB_ASM_CODE(slot) \ + "call x86_current_tls\n\t" \ + "movl %gs:(%eax), %eax\n\t" \ + "jmp *(4 * " slot ")(%eax)" + +#define MAPI_TMP_STUB_ASM_GCC +#include "mapi_tmp.h" + +#ifndef GLX_X86_READONLY_TEXT +__asm__(".balign 16\n" + "x86_entry_end:"); +__asm__(".text"); +#endif /* GLX_X86_READONLY_TEXT */ + +#ifndef MAPI_MODE_BRIDGE + +#include "u_execmem.h" + +extern unsigned long +x86_current_tls(); + +static char x86_entry_start[]; +static char x86_entry_end[]; + +void +entry_patch_public(void) +{ +#ifndef GLX_X86_READONLY_TEXT + char patch[8] = { + 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ + 0x90, 0x90 /* nop's */ + }; + char *entry; + + *((unsigned long *) (patch + 2)) = x86_current_tls(); + + for (entry = x86_entry_start; entry < x86_entry_end; entry += 16) + memcpy(entry, patch, sizeof(patch)); +#endif +} + +mapi_func +entry_get_public(int slot) +{ + return (mapi_func) (x86_entry_start + slot * 16); +} + +void +entry_patch(mapi_func entry, int slot) +{ + char *code = (char *) entry; + *((unsigned long *) (code + 8)) = slot * sizeof(mapi_func); +} + +mapi_func +entry_generate(int slot) +{ + const char code_templ[16] = { + 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ + 0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */ + 0x90, 0x90, 0x90, 0x90 /* nop's */ + }; + void *code; + mapi_func entry; + + code = u_execmem_alloc(sizeof(code_templ)); + if (!code) + return NULL; + + memcpy(code, code_templ, sizeof(code_templ)); + + *((unsigned long *) (code + 2)) = x86_current_tls(); + entry = (mapi_func) code; + entry_patch(entry, slot); + + return entry; +} + +#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/entry_x86_tsd.h b/src/mapi/entry_x86_tsd.h new file mode 100644 index 00000000000..c479c199e23 --- /dev/null +++ b/src/mapi/entry_x86_tsd.h @@ -0,0 +1,104 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include "u_macros.h" + +#define X86_ENTRY_SIZE 32 + +__asm__(".text\n" + ".balign 32\n" + "x86_entry_start:"); + +#define STUB_ASM_ENTRY(func) \ + ".globl " func "\n" \ + ".type " func ", @function\n" \ + ".balign 32\n" \ + func ":" + +#define STUB_ASM_CODE(slot) \ + "movl " ENTRY_CURRENT_TABLE ", %eax\n\t" \ + "testl %eax, %eax\n\t" \ + "je 1f\n\t" \ + "jmp *(4 * " slot ")(%eax)\n" \ + "1:\n\t" \ + "call " ENTRY_CURRENT_TABLE_GET "\n\t" \ + "jmp *(4 * " slot ")(%eax)" + +#define MAPI_TMP_STUB_ASM_GCC +#include "mapi_tmp.h" + +#ifndef MAPI_MODE_BRIDGE + +__asm__(".balign 32\n" + "x86_entry_end:"); + +#include +#include "u_execmem.h" + +static const char x86_entry_start[]; +static const char x86_entry_end[]; + +void +entry_patch_public(void) +{ +} + +mapi_func +entry_get_public(int slot) +{ + return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE); +} + +void +entry_patch(mapi_func entry, int slot) +{ + char *code = (char *) entry; + + *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func); + *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func); +} + +mapi_func +entry_generate(int slot) +{ + const char *code_templ = x86_entry_end - X86_ENTRY_SIZE; + void *code; + mapi_func entry; + + code = u_execmem_alloc(X86_ENTRY_SIZE); + if (!code) + return NULL; + + memcpy(code, code_templ, X86_ENTRY_SIZE); + entry = (mapi_func) code; + entry_patch(entry, slot); + + return entry; +} + +#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/es1api/Makefile.am b/src/mapi/es1api/Makefile.am index bd3c60d7a7b..eb98f165aa9 100644 --- a/src/mapi/es1api/Makefile.am +++ b/src/mapi/es1api/Makefile.am @@ -42,7 +42,7 @@ GLES_include_HEADERS = \ lib_LTLIBRARIES = libGLESv1_CM.la -libGLESv1_CM_la_SOURCES = ../mapi/entry.c glapi_mapi_tmp.h +libGLESv1_CM_la_SOURCES = ../entry.c glapi_mapi_tmp.h libGLESv1_CM_la_LIBADD = $(GLESv1_CM_LIB_DEPS) libGLESv1_CM_la_LDFLAGS = -version-number 1:1 -no-undefined diff --git a/src/mapi/es2api/Makefile.am b/src/mapi/es2api/Makefile.am index 9f79536942d..c6b0ca4ac3c 100644 --- a/src/mapi/es2api/Makefile.am +++ b/src/mapi/es2api/Makefile.am @@ -46,7 +46,7 @@ GLES3_include_HEADERS = \ lib_LTLIBRARIES = libGLESv2.la -libGLESv2_la_SOURCES = ../mapi/entry.c glapi_mapi_tmp.h +libGLESv2_la_SOURCES = ../entry.c glapi_mapi_tmp.h libGLESv2_la_LIBADD = $(GLESv2_LIB_DEPS) libGLESv2_la_LDFLAGS = -version-number 2 -no-undefined diff --git a/src/mapi/glapi/Makefile.am b/src/mapi/glapi/Makefile.am index cf2602aed0a..1698d1474e2 100644 --- a/src/mapi/glapi/Makefile.am +++ b/src/mapi/glapi/Makefile.am @@ -21,7 +21,7 @@ TOP = $(top_srcdir) include Makefile.sources -include ../mapi/Makefile.sources +include ../Makefile.sources AM_CPPFLAGS = \ $(DEFINES) \ diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript index 00cce3e7fda..79cbb6a40d1 100644 --- a/src/mapi/glapi/SConscript +++ b/src/mapi/glapi/SConscript @@ -43,7 +43,7 @@ mapi_sources = [ 'u_execmem.c', ] for s in mapi_sources: - o = env.SharedObject(s[:-2], '../mapi/' + s) + o = env.SharedObject(s[:-2], '../' + s) glapi_sources.append(o) # diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am index 36e47e21eac..97200598e65 100644 --- a/src/mapi/glapi/gen/Makefile.am +++ b/src/mapi/glapi/gen/Makefile.am @@ -20,7 +20,7 @@ XORG_INDENT_FLAGS = -linux -bad -bap -blf -bli0 -cbi0 -cdw -nce -cs -i4 -lc80 -p MESA_DIR = $(top_srcdir)/src/mesa MESA_GLAPI_DIR = $(top_srcdir)/src/mapi/glapi -MESA_MAPI_DIR = $(top_srcdir)/src/mapi/mapi +MESA_MAPI_DIR = $(top_srcdir)/src/mapi MESA_GLX_DIR = $(top_srcdir)/src/glx MESA_GLAPI_OUTPUTS = \ diff --git a/src/mapi/glapi/gen/glapi_gen.mk b/src/mapi/glapi/gen/glapi_gen.mk index f65286fbd9a..242ae5fd908 100644 --- a/src/mapi/glapi/gen/glapi_gen.mk +++ b/src/mapi/glapi/gen/glapi_gen.mk @@ -4,7 +4,7 @@ glapi_gen_common_deps := \ $(wildcard $(top_srcdir)/src/mapi/glapi/gen/*.xml) \ $(wildcard $(top_srcdir)/src/mapi/glapi/gen/*.py) -glapi_gen_mapi_script := $(top_srcdir)/src/mapi/mapi/mapi_abi.py +glapi_gen_mapi_script := $(top_srcdir)/src/mapi/mapi_abi.py glapi_gen_mapi_deps := \ $(glapi_gen_mapi_script) \ $(glapi_gen_common_deps) diff --git a/src/mapi/glapi/glapi.c b/src/mapi/glapi/glapi.c index f7655c558c4..18a7d31a758 100644 --- a/src/mapi/glapi/glapi.c +++ b/src/mapi/glapi/glapi.c @@ -27,7 +27,7 @@ */ #include "glapi/glapi.h" -#include "mapi/u_current.h" +#include "u_current.h" /* * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in diff --git a/src/mapi/glapi/glapi_entrypoint.c b/src/mapi/glapi/glapi_entrypoint.c index 7a0eb353775..791bd428b02 100644 --- a/src/mapi/glapi/glapi_entrypoint.c +++ b/src/mapi/glapi/glapi_entrypoint.c @@ -30,7 +30,7 @@ #include "glapi/glapi_priv.h" -#include "mapi/u_execmem.h" +#include "u_execmem.h" #ifdef USE_X86_ASM diff --git a/src/mapi/glapi/glthread.h b/src/mapi/glapi/glthread.h index 1c3f4e2bf76..2399abb2bae 100644 --- a/src/mapi/glapi/glthread.h +++ b/src/mapi/glapi/glthread.h @@ -1,7 +1,7 @@ #ifndef GLTHREAD_H #define GLTHREAD_H -#include "mapi/u_thread.h" +#include "u_thread.h" #ifdef __cplusplus extern "C" { diff --git a/src/mapi/mapi.c b/src/mapi/mapi.c new file mode 100644 index 00000000000..b471c40b144 --- /dev/null +++ b/src/mapi/mapi.c @@ -0,0 +1,191 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include +#include + +#include "u_current.h" +#include "u_thread.h" +#include "mapi.h" +#include "stub.h" +#include "table.h" + +/* dynamic stubs will run out before this array */ +static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS]; +static int mapi_num_stubs; + +static const struct mapi_stub * +get_stub(const char *name, const struct mapi_stub *alias) +{ + const struct mapi_stub *stub; + + stub = stub_find_public(name); + if (!stub) { + struct mapi_stub *dyn = stub_find_dynamic(name, 1); + if (dyn) { + stub_fix_dynamic(dyn, alias); + stub = dyn; + } + } + + return stub; +} + +/** + * Initialize mapi. spec consists of NULL-separated strings. The first string + * denotes the version. It is followed by variable numbers of entries. Each + * entry can have multiple names. An empty name terminates an entry. An empty + * entry terminates the spec. A spec of two entries, Foo and Bar, is as + * follows + * + * "1\0" + * "Foo\0" + * "FooEXT\0" + * "\0" + * "Bar\0" + * "\0" + */ +void +mapi_init(const char *spec) +{ + u_mutex_declare_static(mutex); + const char *p; + int ver, count; + + u_mutex_lock(mutex); + + /* already initialized */ + if (mapi_num_stubs) { + u_mutex_unlock(mutex); + return; + } + + count = 0; + p = spec; + + /* parse version string */ + ver = atoi(p); + if (ver != 1) { + u_mutex_unlock(mutex); + return; + } + p += strlen(p) + 1; + + while (*p) { + const struct mapi_stub *stub; + + stub = get_stub(p, NULL); + /* out of dynamic entries */ + if (!stub) + break; + p += strlen(p) + 1; + + while (*p) { + get_stub(p, stub); + p += strlen(p) + 1; + } + + mapi_stub_map[count++] = stub; + p++; + } + + mapi_num_stubs = count; + + u_mutex_unlock(mutex); +} + +/** + * Return the address of an entry. Optionally generate the entry if it does + * not exist. + */ +mapi_proc +mapi_get_proc_address(const char *name) +{ + const struct mapi_stub *stub; + + stub = stub_find_public(name); + if (!stub) + stub = stub_find_dynamic(name, 0); + + return (stub) ? (mapi_proc) stub_get_addr(stub) : NULL; +} + +/** + * Create a dispatch table. + */ +struct mapi_table * +mapi_table_create(void) +{ + const struct mapi_table *noop = table_get_noop(); + struct mapi_table *tbl; + + tbl = malloc(MAPI_TABLE_SIZE); + if (tbl) + memcpy(tbl, noop, MAPI_TABLE_SIZE); + + return tbl; +} + +/** + * Destroy a dispatch table. + */ +void +mapi_table_destroy(struct mapi_table *tbl) +{ + free(tbl); +} + +/** + * Fill a dispatch table. The order of the procs is determined when mapi_init + * is called. + */ +void +mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs) +{ + const struct mapi_table *noop = table_get_noop(); + int i; + + for (i = 0; i < mapi_num_stubs; i++) { + const struct mapi_stub *stub = mapi_stub_map[i]; + int slot = stub_get_slot(stub); + mapi_func func = (mapi_func) procs[i]; + + if (!func) + func = table_get_func(noop, slot); + table_set_func(tbl, slot, func); + } +} + +/** + * Make a dispatch table current. + */ +void +mapi_table_make_current(const struct mapi_table *tbl) +{ + u_current_set(tbl); +} diff --git a/src/mapi/mapi.h b/src/mapi/mapi.h new file mode 100644 index 00000000000..c7e43e22e9f --- /dev/null +++ b/src/mapi/mapi.h @@ -0,0 +1,66 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#ifndef _MAPI_H_ +#define _MAPI_H_ + +#include "u_compiler.h" + +#ifdef _WIN32 +#ifdef MAPI_DLL_EXPORTS +#define MAPI_EXPORT __declspec(dllexport) +#else +#define MAPI_EXPORT __declspec(dllimport) +#endif +#else /* _WIN32 */ +#define MAPI_EXPORT PUBLIC +#endif + +typedef void (*mapi_proc)(void); + +struct mapi_table; + +MAPI_EXPORT void +mapi_init(const char *spec); + +MAPI_EXPORT mapi_proc +mapi_get_proc_address(const char *name); + +MAPI_EXPORT struct mapi_table * +mapi_table_create(void); + +MAPI_EXPORT void +mapi_table_destroy(struct mapi_table *tbl); + +MAPI_EXPORT void +mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs); + +MAPI_EXPORT void +mapi_table_make_current(const struct mapi_table *tbl); + +#endif /* _MAPI_H_ */ diff --git a/src/mapi/mapi/Makefile.sources b/src/mapi/mapi/Makefile.sources deleted file mode 100644 index a2f6c716984..00000000000 --- a/src/mapi/mapi/Makefile.sources +++ /dev/null @@ -1,36 +0,0 @@ -# src/mapi/mapi/Makefile.sources -# -# mapi may be used in several ways -# -# - In default mode, mapi implements the interface defined by mapi.h. To use -# this mode, compile MAPI_FILES. -# -# - In util mode, mapi provides utility functions for use with glapi. To use -# this mode, compile MAPI_UTIL_FILES with MAPI_MODE_UTIL defined. -# -# - In glapi mode, mapi implements the interface defined by glapi.h. To use -# this mode, compile MAPI_GLAPI_FILES with MAPI_MODE_GLAPI defined. -# -# - In bridge mode, mapi provides entry points calling into glapi. To use -# this mode, compile MAPI_BRIDGE_FILES with MAPI_MODE_BRIDGE defined. - -MAPI_UTIL_FILES = \ - $(TOP)/src/mapi/mapi/u_current.c \ - $(TOP)/src/mapi/mapi/u_execmem.c - -MAPI_FILES = \ - $(TOP)/src/mapi/mapi/entry.c \ - $(TOP)/src/mapi/mapi/mapi.c \ - $(TOP)/src/mapi/mapi/stub.c \ - $(TOP)/src/mapi/mapi/table.c \ - $(MAPI_UTIL_FILES) - -MAPI_GLAPI_FILES = \ - $(TOP)/src/mapi/mapi/entry.c \ - $(TOP)/src/mapi/mapi/mapi_glapi.c \ - $(TOP)/src/mapi/mapi/stub.c \ - $(TOP)/src/mapi/mapi/table.c \ - $(MAPI_UTIL_FILES) - -MAPI_BRIDGE_FILES = \ - $(TOP)/src/mapi/mapi/entry.c diff --git a/src/mapi/mapi/entry.c b/src/mapi/mapi/entry.c deleted file mode 100644 index 3d9168a7243..00000000000 --- a/src/mapi/mapi/entry.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include "entry.h" -#include "u_current.h" -#include "u_macros.h" - -/* define macros for use by assembly dispatchers */ -#define ENTRY_CURRENT_TABLE U_STRINGIFY(u_current_table) - -/* in bridge mode, mapi is a user of glapi */ -#ifdef MAPI_MODE_BRIDGE -#define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch" -#else -#define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_internal) -#endif - -#if defined(USE_X86_ASM) && defined(__GNUC__) -# ifdef GLX_USE_TLS -# include "entry_x86_tls.h" -# else -# include "entry_x86_tsd.h" -# endif -#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(GLX_USE_TLS) -# include "entry_x86-64_tls.h" -#else - -#include - -static INLINE const struct mapi_table * -entry_current_get(void) -{ -#ifdef MAPI_MODE_BRIDGE - return GET_DISPATCH(); -#else - return u_current_get(); -#endif -} - -/* C version of the public entries */ -#define MAPI_TMP_DEFINES -#define MAPI_TMP_PUBLIC_DECLARES -#define MAPI_TMP_PUBLIC_ENTRIES -#include "mapi_tmp.h" - -#ifndef MAPI_MODE_BRIDGE - -void -entry_patch_public(void) -{ -} - -mapi_func -entry_get_public(int slot) -{ - /* pubic_entries are defined by MAPI_TMP_PUBLIC_ENTRIES */ - return public_entries[slot]; -} - -mapi_func -entry_generate(int slot) -{ - return NULL; -} - -void -entry_patch(mapi_func entry, int slot) -{ -} - -#endif /* MAPI_MODE_BRIDGE */ - -#endif /* asm */ diff --git a/src/mapi/mapi/entry.h b/src/mapi/mapi/entry.h deleted file mode 100644 index 9df81000470..00000000000 --- a/src/mapi/mapi/entry.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#ifndef _ENTRY_H_ -#define _ENTRY_H_ - -#include "u_compiler.h" - -typedef void (*mapi_func)(void); - -void -entry_patch_public(void); - -mapi_func -entry_get_public(int slot); - -mapi_func -entry_generate(int slot); - -void -entry_patch(mapi_func entry, int slot); - -#endif /* _ENTRY_H_ */ diff --git a/src/mapi/mapi/entry_x86-64_tls.h b/src/mapi/mapi/entry_x86-64_tls.h deleted file mode 100644 index 72d4125a694..00000000000 --- a/src/mapi/mapi/entry_x86-64_tls.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include "u_macros.h" - -#ifdef __linux__ -__asm__(".section .note.ABI-tag, \"a\"\n\t" - ".p2align 2\n\t" - ".long 1f - 0f\n\t" /* name length */ - ".long 3f - 2f\n\t" /* data length */ - ".long 1\n\t" /* note length */ - "0: .asciz \"GNU\"\n\t" /* vendor name */ - "1: .p2align 2\n\t" - "2: .long 0\n\t" /* note data: the ABI tag */ - ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ - "3: .p2align 2\n\t"); /* pad out section */ -#endif /* __linux__ */ - -__asm__(".text\n" - ".balign 32\n" - "x86_64_entry_start:"); - -#define STUB_ASM_ENTRY(func) \ - ".globl " func "\n" \ - ".type " func ", @function\n" \ - ".balign 32\n" \ - func ":" - -#define STUB_ASM_CODE(slot) \ - "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" \ - "movq %fs:(%rax), %r11\n\t" \ - "jmp *(8 * " slot ")(%r11)" - -#define MAPI_TMP_STUB_ASM_GCC -#include "mapi_tmp.h" - -#ifndef MAPI_MODE_BRIDGE - -__asm__("x86_64_current_tls:\n\t" - "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t" - "ret"); - -extern unsigned long -x86_64_current_tls(); - -#include -#include "u_execmem.h" - -void -entry_patch_public(void) -{ -} - -static char -x86_64_entry_start[]; - -mapi_func -entry_get_public(int slot) -{ - return (mapi_func) (x86_64_entry_start + slot * 32); -} - -void -entry_patch(mapi_func entry, int slot) -{ - char *code = (char *) entry; - *((unsigned int *) (code + 12)) = slot * sizeof(mapi_func); -} - -mapi_func -entry_generate(int slot) -{ - const char code_templ[16] = { - /* movq %fs:0, %r11 */ - 0x64, 0x4c, 0x8b, 0x1c, 0x25, 0x00, 0x00, 0x00, 0x00, - /* jmp *0x1234(%r11) */ - 0x41, 0xff, 0xa3, 0x34, 0x12, 0x00, 0x00, - }; - unsigned long addr; - void *code; - mapi_func entry; - - addr = x86_64_current_tls(); - if ((addr >> 32) != 0xffffffff) - return NULL; - addr &= 0xffffffff; - - code = u_execmem_alloc(sizeof(code_templ)); - if (!code) - return NULL; - - memcpy(code, code_templ, sizeof(code_templ)); - - *((unsigned int *) (code + 5)) = addr; - entry = (mapi_func) code; - entry_patch(entry, slot); - - return entry; -} - -#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/mapi/entry_x86_tls.h b/src/mapi/mapi/entry_x86_tls.h deleted file mode 100644 index de918128eee..00000000000 --- a/src/mapi/mapi/entry_x86_tls.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include -#include "u_macros.h" - -#ifdef __linux__ -__asm__(".section .note.ABI-tag, \"a\"\n\t" - ".p2align 2\n\t" - ".long 1f - 0f\n\t" /* name length */ - ".long 3f - 2f\n\t" /* data length */ - ".long 1\n\t" /* note length */ - "0: .asciz \"GNU\"\n\t" /* vendor name */ - "1: .p2align 2\n\t" - "2: .long 0\n\t" /* note data: the ABI tag */ - ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ - "3: .p2align 2\n\t"); /* pad out section */ -#endif /* __linux__ */ - -__asm__(".text"); - -__asm__("x86_current_tls:\n\t" - "call 1f\n" - "1:\n\t" - "popl %eax\n\t" - "addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax\n\t" - "movl " ENTRY_CURRENT_TABLE "@GOTNTPOFF(%eax), %eax\n\t" - "ret"); - -#ifndef GLX_X86_READONLY_TEXT -__asm__(".section wtext, \"awx\", @progbits"); -#endif /* GLX_X86_READONLY_TEXT */ - -__asm__(".balign 16\n" - "x86_entry_start:"); - -#define STUB_ASM_ENTRY(func) \ - ".globl " func "\n" \ - ".type " func ", @function\n" \ - ".balign 16\n" \ - func ":" - -#define STUB_ASM_CODE(slot) \ - "call x86_current_tls\n\t" \ - "movl %gs:(%eax), %eax\n\t" \ - "jmp *(4 * " slot ")(%eax)" - -#define MAPI_TMP_STUB_ASM_GCC -#include "mapi_tmp.h" - -#ifndef GLX_X86_READONLY_TEXT -__asm__(".balign 16\n" - "x86_entry_end:"); -__asm__(".text"); -#endif /* GLX_X86_READONLY_TEXT */ - -#ifndef MAPI_MODE_BRIDGE - -#include "u_execmem.h" - -extern unsigned long -x86_current_tls(); - -static char x86_entry_start[]; -static char x86_entry_end[]; - -void -entry_patch_public(void) -{ -#ifndef GLX_X86_READONLY_TEXT - char patch[8] = { - 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ - 0x90, 0x90 /* nop's */ - }; - char *entry; - - *((unsigned long *) (patch + 2)) = x86_current_tls(); - - for (entry = x86_entry_start; entry < x86_entry_end; entry += 16) - memcpy(entry, patch, sizeof(patch)); -#endif -} - -mapi_func -entry_get_public(int slot) -{ - return (mapi_func) (x86_entry_start + slot * 16); -} - -void -entry_patch(mapi_func entry, int slot) -{ - char *code = (char *) entry; - *((unsigned long *) (code + 8)) = slot * sizeof(mapi_func); -} - -mapi_func -entry_generate(int slot) -{ - const char code_templ[16] = { - 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ - 0xff, 0xa0, 0x34, 0x12, 0x00, 0x00, /* jmp *0x1234(%eax) */ - 0x90, 0x90, 0x90, 0x90 /* nop's */ - }; - void *code; - mapi_func entry; - - code = u_execmem_alloc(sizeof(code_templ)); - if (!code) - return NULL; - - memcpy(code, code_templ, sizeof(code_templ)); - - *((unsigned long *) (code + 2)) = x86_current_tls(); - entry = (mapi_func) code; - entry_patch(entry, slot); - - return entry; -} - -#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/mapi/entry_x86_tsd.h b/src/mapi/mapi/entry_x86_tsd.h deleted file mode 100644 index c479c199e23..00000000000 --- a/src/mapi/mapi/entry_x86_tsd.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include "u_macros.h" - -#define X86_ENTRY_SIZE 32 - -__asm__(".text\n" - ".balign 32\n" - "x86_entry_start:"); - -#define STUB_ASM_ENTRY(func) \ - ".globl " func "\n" \ - ".type " func ", @function\n" \ - ".balign 32\n" \ - func ":" - -#define STUB_ASM_CODE(slot) \ - "movl " ENTRY_CURRENT_TABLE ", %eax\n\t" \ - "testl %eax, %eax\n\t" \ - "je 1f\n\t" \ - "jmp *(4 * " slot ")(%eax)\n" \ - "1:\n\t" \ - "call " ENTRY_CURRENT_TABLE_GET "\n\t" \ - "jmp *(4 * " slot ")(%eax)" - -#define MAPI_TMP_STUB_ASM_GCC -#include "mapi_tmp.h" - -#ifndef MAPI_MODE_BRIDGE - -__asm__(".balign 32\n" - "x86_entry_end:"); - -#include -#include "u_execmem.h" - -static const char x86_entry_start[]; -static const char x86_entry_end[]; - -void -entry_patch_public(void) -{ -} - -mapi_func -entry_get_public(int slot) -{ - return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE); -} - -void -entry_patch(mapi_func entry, int slot) -{ - char *code = (char *) entry; - - *((unsigned long *) (code + 11)) = slot * sizeof(mapi_func); - *((unsigned long *) (code + 22)) = slot * sizeof(mapi_func); -} - -mapi_func -entry_generate(int slot) -{ - const char *code_templ = x86_entry_end - X86_ENTRY_SIZE; - void *code; - mapi_func entry; - - code = u_execmem_alloc(X86_ENTRY_SIZE); - if (!code) - return NULL; - - memcpy(code, code_templ, X86_ENTRY_SIZE); - entry = (mapi_func) code; - entry_patch(entry, slot); - - return entry; -} - -#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/mapi/mapi.c b/src/mapi/mapi/mapi.c deleted file mode 100644 index b471c40b144..00000000000 --- a/src/mapi/mapi/mapi.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include -#include - -#include "u_current.h" -#include "u_thread.h" -#include "mapi.h" -#include "stub.h" -#include "table.h" - -/* dynamic stubs will run out before this array */ -static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS]; -static int mapi_num_stubs; - -static const struct mapi_stub * -get_stub(const char *name, const struct mapi_stub *alias) -{ - const struct mapi_stub *stub; - - stub = stub_find_public(name); - if (!stub) { - struct mapi_stub *dyn = stub_find_dynamic(name, 1); - if (dyn) { - stub_fix_dynamic(dyn, alias); - stub = dyn; - } - } - - return stub; -} - -/** - * Initialize mapi. spec consists of NULL-separated strings. The first string - * denotes the version. It is followed by variable numbers of entries. Each - * entry can have multiple names. An empty name terminates an entry. An empty - * entry terminates the spec. A spec of two entries, Foo and Bar, is as - * follows - * - * "1\0" - * "Foo\0" - * "FooEXT\0" - * "\0" - * "Bar\0" - * "\0" - */ -void -mapi_init(const char *spec) -{ - u_mutex_declare_static(mutex); - const char *p; - int ver, count; - - u_mutex_lock(mutex); - - /* already initialized */ - if (mapi_num_stubs) { - u_mutex_unlock(mutex); - return; - } - - count = 0; - p = spec; - - /* parse version string */ - ver = atoi(p); - if (ver != 1) { - u_mutex_unlock(mutex); - return; - } - p += strlen(p) + 1; - - while (*p) { - const struct mapi_stub *stub; - - stub = get_stub(p, NULL); - /* out of dynamic entries */ - if (!stub) - break; - p += strlen(p) + 1; - - while (*p) { - get_stub(p, stub); - p += strlen(p) + 1; - } - - mapi_stub_map[count++] = stub; - p++; - } - - mapi_num_stubs = count; - - u_mutex_unlock(mutex); -} - -/** - * Return the address of an entry. Optionally generate the entry if it does - * not exist. - */ -mapi_proc -mapi_get_proc_address(const char *name) -{ - const struct mapi_stub *stub; - - stub = stub_find_public(name); - if (!stub) - stub = stub_find_dynamic(name, 0); - - return (stub) ? (mapi_proc) stub_get_addr(stub) : NULL; -} - -/** - * Create a dispatch table. - */ -struct mapi_table * -mapi_table_create(void) -{ - const struct mapi_table *noop = table_get_noop(); - struct mapi_table *tbl; - - tbl = malloc(MAPI_TABLE_SIZE); - if (tbl) - memcpy(tbl, noop, MAPI_TABLE_SIZE); - - return tbl; -} - -/** - * Destroy a dispatch table. - */ -void -mapi_table_destroy(struct mapi_table *tbl) -{ - free(tbl); -} - -/** - * Fill a dispatch table. The order of the procs is determined when mapi_init - * is called. - */ -void -mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs) -{ - const struct mapi_table *noop = table_get_noop(); - int i; - - for (i = 0; i < mapi_num_stubs; i++) { - const struct mapi_stub *stub = mapi_stub_map[i]; - int slot = stub_get_slot(stub); - mapi_func func = (mapi_func) procs[i]; - - if (!func) - func = table_get_func(noop, slot); - table_set_func(tbl, slot, func); - } -} - -/** - * Make a dispatch table current. - */ -void -mapi_table_make_current(const struct mapi_table *tbl) -{ - u_current_set(tbl); -} diff --git a/src/mapi/mapi/mapi.h b/src/mapi/mapi/mapi.h deleted file mode 100644 index c7e43e22e9f..00000000000 --- a/src/mapi/mapi/mapi.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#ifndef _MAPI_H_ -#define _MAPI_H_ - -#include "u_compiler.h" - -#ifdef _WIN32 -#ifdef MAPI_DLL_EXPORTS -#define MAPI_EXPORT __declspec(dllexport) -#else -#define MAPI_EXPORT __declspec(dllimport) -#endif -#else /* _WIN32 */ -#define MAPI_EXPORT PUBLIC -#endif - -typedef void (*mapi_proc)(void); - -struct mapi_table; - -MAPI_EXPORT void -mapi_init(const char *spec); - -MAPI_EXPORT mapi_proc -mapi_get_proc_address(const char *name); - -MAPI_EXPORT struct mapi_table * -mapi_table_create(void); - -MAPI_EXPORT void -mapi_table_destroy(struct mapi_table *tbl); - -MAPI_EXPORT void -mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs); - -MAPI_EXPORT void -mapi_table_make_current(const struct mapi_table *tbl); - -#endif /* _MAPI_H_ */ diff --git a/src/mapi/mapi/mapi_abi.py b/src/mapi/mapi/mapi_abi.py deleted file mode 100644 index c645c02f919..00000000000 --- a/src/mapi/mapi/mapi_abi.py +++ /dev/null @@ -1,873 +0,0 @@ -#!/usr/bin/env python - -# Mesa 3-D graphics library -# Version: 7.9 -# -# Copyright (C) 2010 LunarG Inc. -# -# 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. -# -# Authors: -# Chia-I Wu - -import sys -# make it possible to import glapi -import os -GLAPI = os.path.join(".", os.path.dirname(sys.argv[0]), "../glapi/gen") -sys.path.append(GLAPI) - -import re -from optparse import OptionParser -import gl_XML -import glX_XML - - -# number of dynamic entries -ABI_NUM_DYNAMIC_ENTRIES = 256 - -class ABIEntry(object): - """Represent an ABI entry.""" - - _match_c_param = re.compile( - '^(?P[\w\s*]+?)(?P\w+)(\[(?P\d+)\])?$') - - def __init__(self, cols, attrs, xml_data = None): - self._parse(cols) - - self.slot = attrs['slot'] - self.hidden = attrs['hidden'] - self.alias = attrs['alias'] - self.handcode = attrs['handcode'] - self.xml_data = xml_data - - def c_prototype(self): - return '%s %s(%s)' % (self.c_return(), self.name, self.c_params()) - - def c_return(self): - ret = self.ret - if not ret: - ret = 'void' - - return ret - - def c_params(self): - """Return the parameter list used in the entry prototype.""" - c_params = [] - for t, n, a in self.params: - sep = '' if t.endswith('*') else ' ' - arr = '[%d]' % a if a else '' - c_params.append(t + sep + n + arr) - if not c_params: - c_params.append('void') - - return ", ".join(c_params) - - def c_args(self): - """Return the argument list used in the entry invocation.""" - c_args = [] - for t, n, a in self.params: - c_args.append(n) - - return ", ".join(c_args) - - def _parse(self, cols): - ret = cols.pop(0) - if ret == 'void': - ret = None - - name = cols.pop(0) - - params = [] - if not cols: - raise Exception(cols) - elif len(cols) == 1 and cols[0] == 'void': - pass - else: - for val in cols: - params.append(self._parse_param(val)) - - self.ret = ret - self.name = name - self.params = params - - def _parse_param(self, c_param): - m = self._match_c_param.match(c_param) - if not m: - raise Exception('unrecognized param ' + c_param) - - c_type = m.group('type').strip() - c_name = m.group('name') - c_array = m.group('array') - c_array = int(c_array) if c_array else 0 - - return (c_type, c_name, c_array) - - def __str__(self): - return self.c_prototype() - - def __cmp__(self, other): - # compare slot, alias, and then name - res = cmp(self.slot, other.slot) - if not res: - if not self.alias: - res = -1 - elif not other.alias: - res = 1 - - if not res: - res = cmp(self.name, other.name) - - return res - -def abi_parse_xml(xml): - """Parse a GLAPI XML file for ABI entries.""" - api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory()) - - entry_dict = {} - for func in api.functionIterateByOffset(): - # make sure func.name appear first - entry_points = func.entry_points[:] - entry_points.remove(func.name) - entry_points.insert(0, func.name) - - for name in entry_points: - attrs = { - 'slot': func.offset, - 'hidden': not func.is_static_entry_point(name), - 'alias': None if name == func.name else func.name, - 'handcode': bool(func.has_different_protocol(name)), - } - - # post-process attrs - if attrs['alias']: - try: - alias = entry_dict[attrs['alias']] - except KeyError: - raise Exception('failed to alias %s' % attrs['alias']) - if alias.alias: - raise Exception('recursive alias %s' % ent.name) - attrs['alias'] = alias - if attrs['handcode']: - attrs['handcode'] = func.static_glx_name(name) - else: - attrs['handcode'] = None - - if entry_dict.has_key(name): - raise Exception('%s is duplicated' % (name)) - - cols = [] - cols.append(func.return_type) - cols.append(name) - params = func.get_parameter_string(name) - cols.extend([p.strip() for p in params.split(',')]) - - ent = ABIEntry(cols, attrs, func) - entry_dict[ent.name] = ent - - entries = entry_dict.values() - entries.sort() - - return entries - -def abi_parse_line(line): - cols = [col.strip() for col in line.split(',')] - - attrs = { - 'slot': -1, - 'hidden': False, - 'alias': None, - 'handcode': None, - } - - # extract attributes from the first column - vals = cols[0].split(':') - while len(vals) > 1: - val = vals.pop(0) - if val.startswith('slot='): - attrs['slot'] = int(val[5:]) - elif val == 'hidden': - attrs['hidden'] = True - elif val.startswith('alias='): - attrs['alias'] = val[6:] - elif val.startswith('handcode='): - attrs['handcode'] = val[9:] - elif not val: - pass - else: - raise Exception('unknown attribute %s' % val) - cols[0] = vals[0] - - return (attrs, cols) - -def abi_parse(filename): - """Parse a CSV file for ABI entries.""" - fp = open(filename) if filename != '-' else sys.stdin - lines = [line.strip() for line in fp.readlines() - if not line.startswith('#') and line.strip()] - - entry_dict = {} - next_slot = 0 - for line in lines: - attrs, cols = abi_parse_line(line) - - # post-process attributes - if attrs['alias']: - try: - alias = entry_dict[attrs['alias']] - except KeyError: - raise Exception('failed to alias %s' % attrs['alias']) - if alias.alias: - raise Exception('recursive alias %s' % ent.name) - slot = alias.slot - attrs['alias'] = alias - else: - slot = next_slot - next_slot += 1 - - if attrs['slot'] < 0: - attrs['slot'] = slot - elif attrs['slot'] != slot: - raise Exception('invalid slot in %s' % (line)) - - ent = ABIEntry(cols, attrs) - if entry_dict.has_key(ent.name): - raise Exception('%s is duplicated' % (ent.name)) - entry_dict[ent.name] = ent - - entries = entry_dict.values() - entries.sort() - - return entries - -def abi_sanity_check(entries): - if not entries: - return - - all_names = [] - last_slot = entries[-1].slot - i = 0 - for slot in xrange(last_slot + 1): - if entries[i].slot != slot: - raise Exception('entries are not ordered by slots') - if entries[i].alias: - raise Exception('first entry of slot %d aliases %s' - % (slot, entries[i].alias.name)) - handcode = None - while i < len(entries) and entries[i].slot == slot: - ent = entries[i] - if not handcode and ent.handcode: - handcode = ent.handcode - elif ent.handcode != handcode: - raise Exception('two aliases with handcode %s != %s', - ent.handcode, handcode) - - if ent.name in all_names: - raise Exception('%s is duplicated' % (ent.name)) - if ent.alias and ent.alias.name not in all_names: - raise Exception('failed to alias %s' % (ent.alias.name)) - all_names.append(ent.name) - i += 1 - if i < len(entries): - raise Exception('there are %d invalid entries' % (len(entries) - 1)) - -class ABIPrinter(object): - """MAPI Printer""" - - def __init__(self, entries): - self.entries = entries - - # sort entries by their names - self.entries_sorted_by_names = self.entries[:] - self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name)) - - self.indent = ' ' * 3 - self.noop_warn = 'noop_warn' - self.noop_generic = 'noop_generic' - self.current_get = 'entry_current_get' - - self.api_defines = [] - self.api_headers = ['"KHR/khrplatform.h"'] - self.api_call = 'KHRONOS_APICALL' - self.api_entry = 'KHRONOS_APIENTRY' - self.api_attrs = 'KHRONOS_APIATTRIBUTES' - - self.c_header = '' - - self.lib_need_table_size = True - self.lib_need_noop_array = True - self.lib_need_stubs = True - self.lib_need_all_entries = True - self.lib_need_non_hidden_entries = False - - def c_notice(self): - return '/* This file is automatically generated by mapi_abi.py. Do not modify. */' - - def c_public_includes(self): - """Return includes of the client API headers.""" - defines = ['#define ' + d for d in self.api_defines] - includes = ['#include ' + h for h in self.api_headers] - return "\n".join(defines + includes) - - def need_entry_point(self, ent): - """Return True if an entry point is needed for the entry.""" - # non-handcode hidden aliases may share the entry they alias - use_alias = (ent.hidden and ent.alias and not ent.handcode) - return not use_alias - - def c_public_declarations(self, prefix): - """Return the declarations of public entry points.""" - decls = [] - for ent in self.entries: - if not self.need_entry_point(ent): - continue - export = self.api_call if not ent.hidden else '' - decls.append(self._c_decl(ent, prefix, True, export) + ';') - - return "\n".join(decls) - - def c_mapi_table(self): - """Return defines of the dispatch table size.""" - num_static_entries = self.entries[-1].slot + 1 - return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \ - '#define MAPI_TABLE_NUM_DYNAMIC %d') % ( - num_static_entries, ABI_NUM_DYNAMIC_ENTRIES) - - def c_mapi_table_initializer(self, prefix): - """Return the array initializer for mapi_table_fill.""" - entries = [self._c_function(ent, prefix) - for ent in self.entries if not ent.alias] - pre = self.indent + '(mapi_proc) ' - return pre + (',\n' + pre).join(entries) - - def c_mapi_table_spec(self): - """Return the spec for mapi_init.""" - specv1 = [] - line = '"1' - for ent in self.entries: - if not ent.alias: - line += '\\0"\n' - specv1.append(line) - line = '"' - line += '%s\\0' % ent.name - line += '";' - specv1.append(line) - - return self.indent + self.indent.join(specv1) - - def _c_function(self, ent, prefix, mangle=False, stringify=False): - """Return the function name of an entry.""" - formats = { - True: { True: '%s_STR(%s)', False: '%s(%s)' }, - False: { True: '"%s%s"', False: '%s%s' }, - } - fmt = formats[prefix.isupper()][stringify] - name = ent.name - if mangle and ent.hidden: - name = '_dispatch_stub_' + str(ent.slot) - return fmt % (prefix, name) - - def _c_function_call(self, ent, prefix): - """Return the function name used for calling.""" - if ent.handcode: - # _c_function does not handle this case - formats = { True: '%s(%s)', False: '%s%s' } - fmt = formats[prefix.isupper()] - name = fmt % (prefix, ent.handcode) - elif self.need_entry_point(ent): - name = self._c_function(ent, prefix, True) - else: - name = self._c_function(ent.alias, prefix, True) - return name - - def _c_decl(self, ent, prefix, mangle=False, export=''): - """Return the C declaration for the entry.""" - decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry, - self._c_function(ent, prefix, mangle), ent.c_params()) - if export: - decl = export + ' ' + decl - if self.api_attrs: - decl += ' ' + self.api_attrs - - return decl - - def _c_cast(self, ent): - """Return the C cast for the entry.""" - cast = '%s (%s *)(%s)' % ( - ent.c_return(), self.api_entry, ent.c_params()) - - return cast - - def c_private_declarations(self, prefix): - """Return the declarations of private functions.""" - decls = [self._c_decl(ent, prefix) + ';' - for ent in self.entries if not ent.alias] - - return "\n".join(decls) - - def c_public_dispatches(self, prefix, no_hidden): - """Return the public dispatch functions.""" - dispatches = [] - for ent in self.entries: - if ent.hidden and no_hidden: - continue - - if not self.need_entry_point(ent): - continue - - export = self.api_call if not ent.hidden else '' - - proto = self._c_decl(ent, prefix, True, export) - cast = self._c_cast(ent) - - ret = '' - if ent.ret: - ret = 'return ' - stmt1 = self.indent - stmt1 += 'const struct mapi_table *_tbl = %s();' % ( - self.current_get) - stmt2 = self.indent - stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % ( - ent.slot) - stmt3 = self.indent - stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args()) - - disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3) - - if ent.handcode: - disp = '#if 0\n' + disp + '\n#endif' - - dispatches.append(disp) - - return '\n\n'.join(dispatches) - - def c_public_initializer(self, prefix): - """Return the initializer for public dispatch functions.""" - names = [] - for ent in self.entries: - if ent.alias: - continue - - name = '%s(mapi_func) %s' % (self.indent, - self._c_function_call(ent, prefix)) - names.append(name) - - return ',\n'.join(names) - - def c_stub_string_pool(self): - """Return the string pool for use by stubs.""" - # sort entries by their names - sorted_entries = self.entries[:] - sorted_entries.sort(lambda x, y: cmp(x.name, y.name)) - - pool = [] - offsets = {} - count = 0 - for ent in sorted_entries: - offsets[ent] = count - pool.append('%s' % (ent.name)) - count += len(ent.name) + 1 - - pool_str = self.indent + '"' + \ - ('\\0"\n' + self.indent + '"').join(pool) + '";' - return (pool_str, offsets) - - def c_stub_initializer(self, prefix, pool_offsets): - """Return the initializer for struct mapi_stub array.""" - stubs = [] - for ent in self.entries_sorted_by_names: - stubs.append('%s{ (void *) %d, %d, NULL }' % ( - self.indent, pool_offsets[ent], ent.slot)) - - return ',\n'.join(stubs) - - def c_noop_functions(self, prefix, warn_prefix): - """Return the noop functions.""" - noops = [] - for ent in self.entries: - if ent.alias: - continue - - proto = self._c_decl(ent, prefix, False, 'static') - - stmt1 = self.indent; - space = '' - for t, n, a in ent.params: - stmt1 += "%s(void) %s;" % (space, n) - space = ' ' - - if ent.params: - stmt1 += '\n'; - - stmt1 += self.indent + '%s(%s);' % (self.noop_warn, - self._c_function(ent, warn_prefix, False, True)) - - if ent.ret: - stmt2 = self.indent + 'return (%s) 0;' % (ent.ret) - noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2) - else: - noop = '%s\n{\n%s\n}' % (proto, stmt1) - - noops.append(noop) - - return '\n\n'.join(noops) - - def c_noop_initializer(self, prefix, use_generic): - """Return an initializer for the noop dispatch table.""" - entries = [self._c_function(ent, prefix) - for ent in self.entries if not ent.alias] - if use_generic: - entries = [self.noop_generic] * len(entries) - - entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES) - - pre = self.indent + '(mapi_func) ' - return pre + (',\n' + pre).join(entries) - - def c_asm_gcc(self, prefix, no_hidden): - asm = [] - - for ent in self.entries: - if ent.hidden and no_hidden: - continue - - if not self.need_entry_point(ent): - continue - - name = self._c_function(ent, prefix, True, True) - - if ent.handcode: - asm.append('#if 0') - - if ent.hidden: - asm.append('".hidden "%s"\\n"' % (name)) - - if ent.alias and not (ent.alias.hidden and no_hidden): - asm.append('".globl "%s"\\n"' % (name)) - asm.append('".set "%s", "%s"\\n"' % (name, - self._c_function(ent.alias, prefix, True, True))) - else: - asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name)) - asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot)) - - if ent.handcode: - asm.append('#endif') - asm.append('') - - return "\n".join(asm) - - def output_for_lib(self): - print self.c_notice() - - if self.c_header: - print - print self.c_header - - print - print '#ifdef MAPI_TMP_DEFINES' - print self.c_public_includes() - print - print self.c_public_declarations(self.prefix_lib) - print '#undef MAPI_TMP_DEFINES' - print '#endif /* MAPI_TMP_DEFINES */' - - if self.lib_need_table_size: - print - print '#ifdef MAPI_TMP_TABLE' - print self.c_mapi_table() - print '#undef MAPI_TMP_TABLE' - print '#endif /* MAPI_TMP_TABLE */' - - if self.lib_need_noop_array: - print - print '#ifdef MAPI_TMP_NOOP_ARRAY' - print '#ifdef DEBUG' - print - print self.c_noop_functions(self.prefix_noop, self.prefix_warn) - print - print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop) - print self.c_noop_initializer(self.prefix_noop, False) - print '};' - print - print '#else /* DEBUG */' - print - print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop) - print self.c_noop_initializer(self.prefix_noop, True) - print '};' - print - print '#endif /* DEBUG */' - print '#undef MAPI_TMP_NOOP_ARRAY' - print '#endif /* MAPI_TMP_NOOP_ARRAY */' - - if self.lib_need_stubs: - pool, pool_offsets = self.c_stub_string_pool() - print - print '#ifdef MAPI_TMP_PUBLIC_STUBS' - print 'static const char public_string_pool[] =' - print pool - print - print 'static const struct mapi_stub public_stubs[] = {' - print self.c_stub_initializer(self.prefix_lib, pool_offsets) - print '};' - print '#undef MAPI_TMP_PUBLIC_STUBS' - print '#endif /* MAPI_TMP_PUBLIC_STUBS */' - - if self.lib_need_all_entries: - print - print '#ifdef MAPI_TMP_PUBLIC_ENTRIES' - print self.c_public_dispatches(self.prefix_lib, False) - print - print 'static const mapi_func public_entries[] = {' - print self.c_public_initializer(self.prefix_lib) - print '};' - print '#undef MAPI_TMP_PUBLIC_ENTRIES' - print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */' - - print - print '#ifdef MAPI_TMP_STUB_ASM_GCC' - print '__asm__(' - print self.c_asm_gcc(self.prefix_lib, False) - print ');' - print '#undef MAPI_TMP_STUB_ASM_GCC' - print '#endif /* MAPI_TMP_STUB_ASM_GCC */' - - if self.lib_need_non_hidden_entries: - all_hidden = True - for ent in self.entries: - if not ent.hidden: - all_hidden = False - break - if not all_hidden: - print - print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN' - print self.c_public_dispatches(self.prefix_lib, True) - print - print '/* does not need public_entries */' - print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN' - print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */' - - print - print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN' - print '__asm__(' - print self.c_asm_gcc(self.prefix_lib, True) - print ');' - print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN' - print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */' - - def output_for_app(self): - print self.c_notice() - print - print self.c_private_declarations(self.prefix_app) - print - print '#ifdef API_TMP_DEFINE_SPEC' - print - print 'static const char %s_spec[] =' % (self.prefix_app) - print self.c_mapi_table_spec() - print - print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app) - print self.c_mapi_table_initializer(self.prefix_app) - print '};' - print - print '#endif /* API_TMP_DEFINE_SPEC */' - -class GLAPIPrinter(ABIPrinter): - """OpenGL API Printer""" - - def __init__(self, entries): - for ent in entries: - self._override_for_api(ent) - super(GLAPIPrinter, self).__init__(entries) - - self.api_defines = ['GL_GLEXT_PROTOTYPES'] - self.api_headers = ['"GL/gl.h"', '"GL/glext.h"'] - self.api_call = 'GLAPI' - self.api_entry = 'APIENTRY' - self.api_attrs = '' - - self.lib_need_table_size = False - self.lib_need_noop_array = False - self.lib_need_stubs = False - self.lib_need_all_entries = False - self.lib_need_non_hidden_entries = True - - self.prefix_lib = 'GLAPI_PREFIX' - self.prefix_app = '_mesa_' - self.prefix_noop = 'noop' - self.prefix_warn = self.prefix_lib - - self.c_header = self._get_c_header() - - def _override_for_api(self, ent): - """Override attributes of an entry if necessary for this - printer.""" - # By default, no override is necessary. - pass - - def _get_c_header(self): - header = """#ifndef _GLAPI_TMP_H_ -#define _GLAPI_TMP_H_ -#ifdef USE_MGL_NAMESPACE -#define GLAPI_PREFIX(func) mgl##func -#define GLAPI_PREFIX_STR(func) "mgl"#func -#else -#define GLAPI_PREFIX(func) gl##func -#define GLAPI_PREFIX_STR(func) "gl"#func -#endif /* USE_MGL_NAMESPACE */ - -typedef int GLfixed; -typedef int GLclampx; -#endif /* _GLAPI_TMP_H_ */""" - - return header - -class ES1APIPrinter(GLAPIPrinter): - """OpenGL ES 1.x API Printer""" - - def __init__(self, entries): - super(ES1APIPrinter, self).__init__(entries) - self.prefix_lib = 'gl' - self.prefix_warn = 'gl' - - def _override_for_api(self, ent): - if ent.xml_data is None: - raise Exception('ES2 API printer requires XML input') - ent.hidden = ent.name not in \ - ent.xml_data.entry_points_for_api_version('es1') - ent.handcode = False - - def _get_c_header(self): - header = """#ifndef _GLAPI_TMP_H_ -#define _GLAPI_TMP_H_ -typedef int GLfixed; -typedef int GLclampx; -#endif /* _GLAPI_TMP_H_ */""" - - return header - -class ES2APIPrinter(GLAPIPrinter): - """OpenGL ES 2.x API Printer""" - - def __init__(self, entries): - super(ES2APIPrinter, self).__init__(entries) - self.prefix_lib = 'gl' - self.prefix_warn = 'gl' - - def _override_for_api(self, ent): - if ent.xml_data is None: - raise Exception('ES2 API printer requires XML input') - ent.hidden = ent.name not in \ - ent.xml_data.entry_points_for_api_version('es2') - ent.handcode = False - - def _get_c_header(self): - header = """#ifndef _GLAPI_TMP_H_ -#define _GLAPI_TMP_H_ -typedef int GLfixed; -typedef int GLclampx; -#endif /* _GLAPI_TMP_H_ */""" - - return header - -class SharedGLAPIPrinter(GLAPIPrinter): - """Shared GLAPI API Printer""" - - def __init__(self, entries): - super(SharedGLAPIPrinter, self).__init__(entries) - - self.lib_need_table_size = True - self.lib_need_noop_array = True - self.lib_need_stubs = True - self.lib_need_all_entries = True - self.lib_need_non_hidden_entries = False - - self.prefix_lib = 'shared' - self.prefix_warn = 'gl' - - def _override_for_api(self, ent): - ent.hidden = True - ent.handcode = False - - def _get_c_header(self): - header = """#ifndef _GLAPI_TMP_H_ -#define _GLAPI_TMP_H_ -typedef int GLfixed; -typedef int GLclampx; -#endif /* _GLAPI_TMP_H_ */""" - - return header - -class VGAPIPrinter(ABIPrinter): - """OpenVG API Printer""" - - def __init__(self, entries): - super(VGAPIPrinter, self).__init__(entries) - - self.api_defines = ['VG_VGEXT_PROTOTYPES'] - self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"'] - self.api_call = 'VG_API_CALL' - self.api_entry = 'VG_API_ENTRY' - self.api_attrs = 'VG_API_EXIT' - - self.prefix_lib = 'vg' - self.prefix_app = 'vega' - self.prefix_noop = 'noop' - self.prefix_warn = 'vg' - -def parse_args(): - printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi'] - modes = ['lib', 'app'] - - parser = OptionParser(usage='usage: %prog [options] ') - parser.add_option('-p', '--printer', dest='printer', - help='printer to use: %s' % (", ".join(printers))) - parser.add_option('-m', '--mode', dest='mode', - help='target user: %s' % (", ".join(modes))) - - options, args = parser.parse_args() - if not args or options.printer not in printers or \ - options.mode not in modes: - parser.print_help() - sys.exit(1) - - return (args[0], options) - -def main(): - printers = { - 'vgapi': VGAPIPrinter, - 'glapi': GLAPIPrinter, - 'es1api': ES1APIPrinter, - 'es2api': ES2APIPrinter, - 'shared-glapi': SharedGLAPIPrinter, - } - - filename, options = parse_args() - - if filename.endswith('.xml'): - entries = abi_parse_xml(filename) - else: - entries = abi_parse(filename) - abi_sanity_check(entries) - - printer = printers[options.printer](entries) - if options.mode == 'lib': - printer.output_for_lib() - else: - printer.output_for_app() - -if __name__ == '__main__': - main() diff --git a/src/mapi/mapi/mapi_glapi.c b/src/mapi/mapi/mapi_glapi.c deleted file mode 100644 index 4627c4de02b..00000000000 --- a/src/mapi/mapi/mapi_glapi.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include -#include "glapi/glapi.h" -#include "mapi/u_current.h" -#include "mapi/table.h" /* for MAPI_TABLE_NUM_SLOTS */ -#include "mapi/stub.h" - -/* - * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in - * u_current.c. - */ - -#ifdef GLX_USE_TLS -/* not used, but defined for compatibility */ -const struct _glapi_table *_glapi_Dispatch; -const void *_glapi_Context; -#endif /* GLX_USE_TLS */ - -void -_glapi_destroy_multithread(void) -{ - u_current_destroy(); -} - -void -_glapi_check_multithread(void) -{ - u_current_init(); -} - -void -_glapi_set_context(void *context) -{ - u_current_set_user((const void *) context); -} - -void -_glapi_set_dispatch(struct _glapi_table *dispatch) -{ - u_current_set((const struct mapi_table *) dispatch); -} - -/** - * Return size of dispatch table struct as number of functions (or - * slots). - */ -unsigned int -_glapi_get_dispatch_table_size(void) -{ - return MAPI_TABLE_NUM_SLOTS; -} - -/** - * Fill-in the dispatch stub for the named function. - * - * This function is intended to be called by a hardware driver. When called, - * a dispatch stub may be created created for the function. A pointer to this - * dispatch function will be returned by glXGetProcAddress. - * - * \param function_names Array of pointers to function names that should - * share a common dispatch offset. - * \param parameter_signature String representing the types of the parameters - * passed to the named function. Parameter types - * are converted to characters using the following - * rules: - * - 'i' for \c GLint, \c GLuint, and \c GLenum - * - 'p' for any pointer type - * - 'f' for \c GLfloat and \c GLclampf - * - 'd' for \c GLdouble and \c GLclampd - * - * \returns - * The offset in the dispatch table of the named function. A pointer to the - * driver's implementation of the named function should be stored at - * \c dispatch_table[\c offset]. Return -1 if error/problem. - * - * \sa glXGetProcAddress - * - * \warning - * This function can only handle up to 8 names at a time. As far as I know, - * the maximum number of names ever associated with an existing GL function is - * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, - * \c glPointParameterfARB, and \c glPointParameterf), so this should not be - * too painful of a limitation. - * - * \todo - * Check parameter_signature. - */ -int -_glapi_add_dispatch( const char * const * function_names, - const char * parameter_signature ) -{ - const struct mapi_stub *function_stubs[8]; - const struct mapi_stub *alias = NULL; - unsigned i; - - (void) memset(function_stubs, 0, sizeof(function_stubs)); - - /* find the missing stubs, and decide the alias */ - for (i = 0; function_names[i] != NULL && i < 8; i++) { - const char * funcName = function_names[i]; - const struct mapi_stub *stub; - int slot; - - if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') - return -1; - funcName += 2; - - stub = stub_find_public(funcName); - if (!stub) - stub = stub_find_dynamic(funcName, 0); - - slot = (stub) ? stub_get_slot(stub) : -1; - if (slot >= 0) { - if (alias && stub_get_slot(alias) != slot) - return -1; - /* use the first existing stub as the alias */ - if (!alias) - alias = stub; - - function_stubs[i] = stub; - } - } - - /* generate missing stubs */ - for (i = 0; function_names[i] != NULL && i < 8; i++) { - const char * funcName = function_names[i] + 2; - struct mapi_stub *stub; - - if (function_stubs[i]) - continue; - - stub = stub_find_dynamic(funcName, 1); - if (!stub) - return -1; - - stub_fix_dynamic(stub, alias); - if (!alias) - alias = stub; - } - - return (alias) ? stub_get_slot(alias) : -1; -} - -static const struct mapi_stub * -_glapi_get_stub(const char *name, int generate) -{ - const struct mapi_stub *stub; - -#ifdef USE_MGL_NAMESPACE - if (name) - name++; -#endif - - if (!name || name[0] != 'g' || name[1] != 'l') - return NULL; - name += 2; - - stub = stub_find_public(name); - if (!stub) - stub = stub_find_dynamic(name, generate); - - return stub; -} - -/** - * Return offset of entrypoint for named function within dispatch table. - */ -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 pointer to the named function. If the function name isn't found - * in the name of static functions, try generating a new API entrypoint on - * the fly with assembly language. - */ -_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; -} - -/** - * Return the name of the function at the given dispatch offset. - * This is only intended for debugging. - */ -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; -} - -unsigned long -_glthread_GetID(void) -{ - return u_thread_self(); -} - -void -_glapi_noop_enable_warnings(unsigned char enable) -{ -} - -void -_glapi_set_warning_func(_glapi_proc func) -{ -} diff --git a/src/mapi/mapi/mapi_tmp.h b/src/mapi/mapi/mapi_tmp.h deleted file mode 100644 index f326b4a4e14..00000000000 --- a/src/mapi/mapi/mapi_tmp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#ifndef MAPI_ABI_HEADER -#error "MAPI_ABI_HEADER must be defined" -#endif - -/* does not need hidden entries in bridge mode */ -#ifdef MAPI_MODE_BRIDGE - -#ifdef MAPI_TMP_PUBLIC_ENTRIES -#undef MAPI_TMP_PUBLIC_ENTRIES -#define MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN -#endif - -#ifdef MAPI_TMP_STUB_ASM_GCC -#undef MAPI_TMP_STUB_ASM_GCC -#define MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN -#endif - -#endif /* MAPI_MODE_BRIDGE */ - -#include MAPI_ABI_HEADER diff --git a/src/mapi/mapi/stub.c b/src/mapi/mapi/stub.c deleted file mode 100644 index 688dc8143a4..00000000000 --- a/src/mapi/mapi/stub.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include -#include -#include - -#include "u_current.h" -#include "u_thread.h" -#include "entry.h" -#include "stub.h" -#include "table.h" - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) - -struct mapi_stub { - const void *name; - int slot; - mapi_func addr; -}; - -/* define public_string_pool and public_stubs */ -#define MAPI_TMP_PUBLIC_STUBS -#include "mapi_tmp.h" - -static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC]; -static int num_dynamic_stubs; -static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC; - -void -stub_init_once(void) -{ -#ifdef HAVE_PTHREAD - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, entry_patch_public); -#else - static int first = 1; - if (first) { - first = 0; - entry_patch_public(); - } -#endif -} - -static int -stub_compare(const void *key, const void *elem) -{ - const char *name = (const char *) key; - const struct mapi_stub *stub = (const struct mapi_stub *) elem; - const char *stub_name; - - stub_name = &public_string_pool[(unsigned long) stub->name]; - - return strcmp(name, stub_name); -} - -/** - * Return the public stub with the given name. - */ -const struct mapi_stub * -stub_find_public(const char *name) -{ - return (const struct mapi_stub *) bsearch(name, public_stubs, - ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare); -} - -/** - * Add a dynamic stub. - */ -static struct mapi_stub * -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; - - stub = &dynamic_stubs[idx]; - - /* dispatch to the last slot, which is reserved for no-op */ - stub->addr = entry_generate( - MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1); - if (!stub->addr) - return NULL; - - stub->name = (const void *) name; - /* to be fixed later */ - stub->slot = -1; - - num_dynamic_stubs = idx + 1; - - return stub; -} - -/** - * 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 * -stub_find_dynamic(const char *name, int generate) -{ - u_mutex_declare_static(dynamic_mutex); - struct mapi_stub *stub = NULL; - int count, i; - - u_mutex_lock(dynamic_mutex); - - if (generate) - assert(!stub_find_public(name)); - - count = num_dynamic_stubs; - for (i = 0; i < count; i++) { - if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) { - stub = &dynamic_stubs[i]; - break; - } - } - - /* generate a dynamic stub */ - if (generate && !stub) - stub = stub_add_dynamic(name); - - u_mutex_unlock(dynamic_mutex); - - return stub; -} - -static const struct mapi_stub * -search_table_by_slot(const struct mapi_stub *table, size_t num_entries, - int slot) -{ - size_t i; - for (i = 0; i < num_entries; ++i) { - if (table[i].slot == slot) - return &table[i]; - } - return NULL; -} - -const struct mapi_stub * -stub_find_by_slot(int slot) -{ - const struct mapi_stub *stub = - search_table_by_slot(public_stubs, ARRAY_SIZE(public_stubs), slot); - if (stub) - return stub; - return search_table_by_slot(dynamic_stubs, num_dynamic_stubs, slot); -} - -void -stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias) -{ - int slot; - - if (stub->slot >= 0) - return; - - if (alias) - slot = alias->slot; - else - slot = next_dynamic_slot++; - - entry_patch(stub->addr, slot); - stub->slot = slot; -} - -/** - * Return the name of a stub. - */ -const char * -stub_get_name(const struct mapi_stub *stub) -{ - const char *name; - - if (stub >= public_stubs && - stub < public_stubs + ARRAY_SIZE(public_stubs)) - name = &public_string_pool[(unsigned long) stub->name]; - else - name = (const char *) stub->name; - - return name; -} - -/** - * Return the slot of a stub. - */ -int -stub_get_slot(const struct mapi_stub *stub) -{ - return stub->slot; -} - -/** - * Return the address of a stub. - */ -mapi_func -stub_get_addr(const struct mapi_stub *stub) -{ - assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC); - return (stub->addr) ? stub->addr : entry_get_public(stub->slot); -} diff --git a/src/mapi/mapi/stub.h b/src/mapi/mapi/stub.h deleted file mode 100644 index 98e2553ecdd..00000000000 --- a/src/mapi/mapi/stub.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#ifndef _STUB_H_ -#define _STUB_H_ - -#include "entry.h" - -struct mapi_stub; - -void -stub_init_once(void); - -const struct mapi_stub * -stub_find_public(const char *name); - -struct mapi_stub * -stub_find_dynamic(const char *name, int generate); - -const struct mapi_stub * -stub_find_by_slot(int slot); - -void -stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias); - -const char * -stub_get_name(const struct mapi_stub *stub); - -int -stub_get_slot(const struct mapi_stub *stub); - -mapi_func -stub_get_addr(const struct mapi_stub *stub); - -#endif /* _STUB_H_ */ diff --git a/src/mapi/mapi/table.c b/src/mapi/mapi/table.c deleted file mode 100644 index 9bb9f654a2a..00000000000 --- a/src/mapi/mapi/table.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#include -#include - -#include "table.h" - -static void -noop_warn(const char *name) -{ - static int debug = -1; - - if (debug < 0) - debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")); - - if (debug) - fprintf(stderr, "%s is no-op\n", name); -} - -static int -noop_generic(void) -{ - noop_warn("function"); - return 0; -} - -/* define noop_array */ -#define MAPI_TMP_DEFINES -#define MAPI_TMP_NOOP_ARRAY -#include "mapi_tmp.h" diff --git a/src/mapi/mapi/table.h b/src/mapi/mapi/table.h deleted file mode 100644 index d84523f7777..00000000000 --- a/src/mapi/mapi/table.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * 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. - * - * Authors: - * Chia-I Wu - */ - -#ifndef _TABLE_H_ -#define _TABLE_H_ - -#include "u_compiler.h" -#include "entry.h" - -#define MAPI_TMP_TABLE -#include "mapi_tmp.h" - -#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC) -#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func)) - -extern const mapi_func table_noop_array[]; - -/** - * Get the no-op dispatch table. - */ -static INLINE const struct mapi_table * -table_get_noop(void) -{ - return (const struct mapi_table *) table_noop_array; -} - -/** - * Set the function of a slot. - */ -static INLINE void -table_set_func(struct mapi_table *tbl, int slot, mapi_func func) -{ - mapi_func *funcs = (mapi_func *) tbl; - funcs[slot] = func; -} - -/** - * Return the function of a slot. - */ -static INLINE mapi_func -table_get_func(const struct mapi_table *tbl, int slot) -{ - const mapi_func *funcs = (const mapi_func *) tbl; - return funcs[slot]; -} - -#endif /* _TABLE_H_ */ diff --git a/src/mapi/mapi/u_compiler.h b/src/mapi/mapi/u_compiler.h deleted file mode 100644 index f376e97a0f3..00000000000 --- a/src/mapi/mapi/u_compiler.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _U_COMPILER_H_ -#define _U_COMPILER_H_ - -#include "c99_compat.h" /* inline, __func__, etc. */ - - -/* XXX: Use standard `inline` keyword instead */ -#ifndef INLINE -# define INLINE inline -#endif - -/* Function visibility */ -#ifndef PUBLIC -# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) -# define PUBLIC __attribute__((visibility("default"))) -# elif defined(_MSC_VER) -# define PUBLIC __declspec(dllexport) -# else -# define PUBLIC -# endif -#endif - -#ifndef likely -# if defined(__GNUC__) -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -# else -# define likely(x) (x) -# define unlikely(x) (x) -# endif -#endif - -#endif /* _U_COMPILER_H_ */ diff --git a/src/mapi/mapi/u_current.c b/src/mapi/mapi/u_current.c deleted file mode 100644 index d902375f8c6..00000000000 --- a/src/mapi/mapi/u_current.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * 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 - * BRIAN PAUL 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. - */ - - -/* - * This file manages the OpenGL API dispatch layer. - * The dispatch table (struct _glapi_table) is basically just a list - * of function pointers. - * There are functions to set/get the current dispatch table for the - * current thread and to manage registration/dispatch of dynamically - * added extension functions. - * - * It's intended that this file and the other glapi*.[ch] files are - * flexible enough to be reused in several places: XFree86, DRI- - * based libGL.so, and perhaps the SGI SI. - * - * NOTE: There are no dependencies on Mesa in this code. - * - * Versions (API changes): - * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 - * 2001/01/16 - added dispatch override feature for Mesa 3.5 - * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1. - * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints - * itself (using offset ~0). _glapi_add_entrypoint() can be - * called afterward and it'll fill in the correct dispatch - * offset. This allows DRI libGL to avoid probing for DRI - * drivers! No changes to the public glapi interface. - */ - -#include "u_current.h" -#include "u_thread.h" - -#ifndef MAPI_MODE_UTIL - -#include "table.h" -#include "stub.h" - -#else - -extern void init_glapi_relocs_once(void); -extern void (*__glapi_noop_table[])(void); - -#define table_noop_array __glapi_noop_table -#define stub_init_once() init_glapi_relocs_once() - -#endif - -/** - * \name Current dispatch and current context control variables - * - * Depending on whether or not multithreading is support, and the type of - * support available, several variables are used to store the current context - * pointer and the current dispatch table pointer. In the non-threaded case, - * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this - * purpose. - * - * In the "normal" threaded case, the variables \c _glapi_Dispatch and - * \c _glapi_Context will be \c NULL if an application is detected as being - * multithreaded. Single-threaded applications will use \c _glapi_Dispatch - * and \c _glapi_Context just like the case without any threading support. - * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state - * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the - * static dispatch functions access these variables via \c _glapi_get_dispatch - * and \c _glapi_get_context. - * - * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is - * possible for the original thread to be setting it at the same instant a new - * thread, perhaps running on a different processor, is clearing it. Because - * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is - * used to determine whether or not the application is multithreaded. - * - * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are - * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and - * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and - * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability - * between TLS enabled loaders and non-TLS DRI drivers. - */ -/*@{*/ -#if defined(GLX_USE_TLS) - -__thread struct mapi_table *u_current_table - __attribute__((tls_model("initial-exec"))) - = (struct mapi_table *) table_noop_array; - -__thread void *u_current_user - __attribute__((tls_model("initial-exec"))); - -#else - -struct mapi_table *u_current_table = - (struct mapi_table *) table_noop_array; -void *u_current_user; - -#ifdef THREADS -struct u_tsd u_current_table_tsd; -static struct u_tsd u_current_user_tsd; -static int ThreadSafe; -#endif /* THREADS */ - -#endif /* defined(GLX_USE_TLS) */ -/*@}*/ - - -void -u_current_destroy(void) -{ -#if defined(THREADS) && defined(_WIN32) - u_tsd_destroy(&u_current_table_tsd); - u_tsd_destroy(&u_current_user_tsd); -#endif -} - - -#if defined(THREADS) && !defined(GLX_USE_TLS) - -static void -u_current_init_tsd(void) -{ - u_tsd_init(&u_current_table_tsd); - u_tsd_init(&u_current_user_tsd); -} - -/** - * Mutex for multithread check. - */ -u_mutex_declare_static(ThreadCheckMutex); - -/** - * We should call this periodically from a function such as glXMakeCurrent - * in order to test if multiple threads are being used. - */ -void -u_current_init(void) -{ - static unsigned long knownID; - static int firstCall = 1; - - if (ThreadSafe) - return; - - u_mutex_lock(ThreadCheckMutex); - if (firstCall) { - u_current_init_tsd(); - - knownID = u_thread_self(); - firstCall = 0; - } - else if (knownID != u_thread_self()) { - ThreadSafe = 1; - u_current_set(NULL); - u_current_set_user(NULL); - } - u_mutex_unlock(ThreadCheckMutex); -} - -#else - -void -u_current_init(void) -{ -} - -#endif - - - -/** - * Set the current context pointer for this thread. - * The context pointer is an opaque type which should be cast to - * void from the real context pointer type. - */ -void -u_current_set_user(const void *ptr) -{ - u_current_init(); - -#if defined(GLX_USE_TLS) - u_current_user = (void *) ptr; -#elif defined(THREADS) - u_tsd_set(&u_current_user_tsd, (void *) ptr); - u_current_user = (ThreadSafe) ? NULL : (void *) ptr; -#else - u_current_user = (void *) ptr; -#endif -} - -/** - * Get the current context pointer for this thread. - * The context pointer is an opaque type which should be cast from - * void to the real context pointer type. - */ -void * -u_current_get_user_internal(void) -{ -#if defined(GLX_USE_TLS) - return u_current_user; -#elif defined(THREADS) - return (ThreadSafe) - ? u_tsd_get(&u_current_user_tsd) - : u_current_user; -#else - return u_current_user; -#endif -} - -/** - * Set the global or per-thread dispatch table pointer. - * If the dispatch parameter is NULL we'll plug in the no-op dispatch - * table (__glapi_noop_table). - */ -void -u_current_set(const struct mapi_table *tbl) -{ - u_current_init(); - - stub_init_once(); - - if (!tbl) - tbl = (const struct mapi_table *) table_noop_array; - -#if defined(GLX_USE_TLS) - u_current_table = (struct mapi_table *) tbl; -#elif defined(THREADS) - u_tsd_set(&u_current_table_tsd, (void *) tbl); - u_current_table = (ThreadSafe) ? NULL : (void *) tbl; -#else - u_current_table = (struct mapi_table *) tbl; -#endif -} - -/** - * Return pointer to current dispatch table for calling thread. - */ -struct mapi_table * -u_current_get_internal(void) -{ -#if defined(GLX_USE_TLS) - return u_current_table; -#elif defined(THREADS) - return (struct mapi_table *) ((ThreadSafe) ? - u_tsd_get(&u_current_table_tsd) : (void *) u_current_table); -#else - return u_current_table; -#endif -} diff --git a/src/mapi/mapi/u_current.h b/src/mapi/mapi/u_current.h deleted file mode 100644 index f9cffd8c3d0..00000000000 --- a/src/mapi/mapi/u_current.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _U_CURRENT_H_ -#define _U_CURRENT_H_ - -#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \ - defined(MAPI_MODE_BRIDGE) - -#include "glapi/glapi.h" - -/* ugly renames to match glapi.h */ -#define mapi_table _glapi_table - -#ifdef GLX_USE_TLS -#define u_current_table _glapi_tls_Dispatch -#define u_current_user _glapi_tls_Context -#else -#define u_current_table _glapi_Dispatch -#define u_current_user _glapi_Context -#endif - -#define u_current_get_internal _glapi_get_dispatch -#define u_current_get_user_internal _glapi_get_context - -#define u_current_table_tsd _gl_DispatchTSD - -#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */ - -#include "u_compiler.h" - -struct mapi_table; - -#ifdef GLX_USE_TLS - -extern __thread struct mapi_table *u_current_table - __attribute__((tls_model("initial-exec"))); - -extern __thread void *u_current_user - __attribute__((tls_model("initial-exec"))); - -#else /* GLX_USE_TLS */ - -extern struct mapi_table *u_current_table; -extern void *u_current_user; - -#endif /* GLX_USE_TLS */ - -#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */ - -void -u_current_init(void); - -void -u_current_destroy(void); - -void -u_current_set(const struct mapi_table *tbl); - -struct mapi_table * -u_current_get_internal(void); - -void -u_current_set_user(const void *ptr); - -void * -u_current_get_user_internal(void); - -static INLINE const struct mapi_table * -u_current_get(void) -{ -#ifdef GLX_USE_TLS - return u_current_table; -#else - return (likely(u_current_table) ? - u_current_table : u_current_get_internal()); -#endif -} - -static INLINE const void * -u_current_get_user(void) -{ -#ifdef GLX_USE_TLS - return u_current_user; -#else - return likely(u_current_user) ? u_current_user : u_current_get_user_internal(); -#endif -} - -#endif /* _U_CURRENT_H_ */ diff --git a/src/mapi/mapi/u_execmem.c b/src/mapi/mapi/u_execmem.c deleted file mode 100644 index e5072e06e9a..00000000000 --- a/src/mapi/mapi/u_execmem.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * 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 - * BRIAN PAUL 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. - */ - - -/** - * \file glapi_execmem.c - * - * Function for allocating executable memory for dispatch stubs. - * - * Copied from main/execmem.c and simplified for dispatch stubs. - */ - - -#include "u_compiler.h" -#include "u_thread.h" -#include "u_execmem.h" - - -#define EXEC_MAP_SIZE (4*1024) - -u_mutex_declare_static(exec_mutex); - -static unsigned int head = 0; - -static unsigned char *exec_mem = (unsigned char *)0; - - -#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) - -#include -#include - -#ifdef MESA_SELINUX -#include -#endif - - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - - -/* - * Dispatch stubs are of fixed size and never freed. Thus, we do not need to - * overlay a heap, we just mmap a page and manage through an index. - */ - -static int -init_map(void) -{ -#ifdef MESA_SELINUX - if (is_selinux_enabled()) { - if (!security_get_boolean_active("allow_execmem") || - !security_get_boolean_pending("allow_execmem")) - return 0; - } -#endif - - if (!exec_mem) - exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - return (exec_mem != MAP_FAILED); -} - - -#elif defined(_WIN32) - -#include - - -/* - * Avoid Data Execution Prevention. - */ - -static int -init_map(void) -{ - exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - - return (exec_mem != NULL); -} - - -#else - -#include - -static int -init_map(void) -{ - exec_mem = malloc(EXEC_MAP_SIZE); - - return (exec_mem != NULL); -} - - -#endif - -void * -u_execmem_alloc(unsigned int size) -{ - void *addr = NULL; - - u_mutex_lock(exec_mutex); - - if (!init_map()) - goto bail; - - /* free space check, assumes no integer overflow */ - if (head + size > EXEC_MAP_SIZE) - goto bail; - - /* allocation, assumes proper addr and size alignement */ - addr = exec_mem + head; - head += size; - -bail: - u_mutex_unlock(exec_mutex); - - return addr; -} - - diff --git a/src/mapi/mapi/u_execmem.h b/src/mapi/mapi/u_execmem.h deleted file mode 100644 index 13fff8df225..00000000000 --- a/src/mapi/mapi/u_execmem.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _U_EXECMEM_H_ -#define _U_EXECMEM_H_ - -void * -u_execmem_alloc(unsigned int size); - -#endif /* _U_EXECMEM_H_ */ diff --git a/src/mapi/mapi/u_macros.h b/src/mapi/mapi/u_macros.h deleted file mode 100644 index 72345b5f156..00000000000 --- a/src/mapi/mapi/u_macros.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _U_MACROS_ -#define _U_MACROS_ - -#define _U_STRINGIFY(x) #x -#define _U_CONCAT(x, y) x ## y -#define _U_CONCAT_STR(x, y) #x#y - -#define U_STRINGIFY(x) _U_STRINGIFY(x) -#define U_CONCAT(x, y) _U_CONCAT(x, y) -#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y) - -#endif /* _U_MACROS_ */ diff --git a/src/mapi/mapi/u_thread.h b/src/mapi/mapi/u_thread.h deleted file mode 100644 index a5e5043701f..00000000000 --- a/src/mapi/mapi/u_thread.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * 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 - * BRIAN PAUL 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. - */ - - -/* - * Thread support for gl dispatch. - * - * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) - * and Christoph Poliwoda (poliwoda@volumegraphics.com) - * Revised by Keith Whitwell - * Adapted for new gl dispatcher by Brian Paul - * Modified for use in mapi by Chia-I Wu - */ - -/* - * If this file is accidentally included by a non-threaded build, - * it should not cause the build to fail, or otherwise cause problems. - * In general, it should only be included when needed however. - */ - -#ifndef _U_THREAD_H_ -#define _U_THREAD_H_ - -#include -#include -#include "u_compiler.h" - -#if defined(HAVE_PTHREAD) -#include /* POSIX threads headers */ -#endif -#ifdef _WIN32 -#include -#endif - -#if defined(HAVE_PTHREAD) || defined(_WIN32) -#ifndef THREADS -#define THREADS -#endif -#endif - -/* - * Error messages - */ -#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" -#define GET_TSD_ERROR "_glthread_: failed to get thread specific data" -#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" - - -/* - * Magic number to determine if a TSD object has been initialized. - * Kind of a hack but there doesn't appear to be a better cross-platform - * solution. - */ -#define INIT_MAGIC 0xff8adc98 - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * POSIX threads. This should be your choice in the Unix world - * whenever possible. When building with POSIX threads, be sure - * to enable any compiler flags which will cause the MT-safe - * libc (if one exists) to be used when linking, as well as any - * header macros for MT-safe errno, etc. For Solaris, this is the -mt - * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable - * proper compiling for MT-safe libc etc. - */ -#if defined(HAVE_PTHREAD) - -struct u_tsd { - pthread_key_t key; - unsigned initMagic; -}; - -typedef pthread_mutex_t u_mutex; - -#define u_mutex_declare_static(name) \ - static u_mutex name = PTHREAD_MUTEX_INITIALIZER - -#define u_mutex_init(name) pthread_mutex_init(&(name), NULL) -#define u_mutex_destroy(name) pthread_mutex_destroy(&(name)) -#define u_mutex_lock(name) (void) pthread_mutex_lock(&(name)) -#define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name)) - -static INLINE unsigned long -u_thread_self(void) -{ - return (unsigned long) pthread_self(); -} - - -static INLINE void -u_tsd_init(struct u_tsd *tsd) -{ - if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { - perror(INIT_TSD_ERROR); - exit(-1); - } - tsd->initMagic = INIT_MAGIC; -} - - -static INLINE void * -u_tsd_get(struct u_tsd *tsd) -{ - if (tsd->initMagic != INIT_MAGIC) { - u_tsd_init(tsd); - } - return pthread_getspecific(tsd->key); -} - - -static INLINE void -u_tsd_set(struct u_tsd *tsd, void *ptr) -{ - if (tsd->initMagic != INIT_MAGIC) { - u_tsd_init(tsd); - } - if (pthread_setspecific(tsd->key, ptr) != 0) { - perror(SET_TSD_ERROR); - exit(-1); - } -} - -#endif /* HAVE_PTHREAD */ - - -/* - * Windows threads. Should work with Windows NT and 95. - * IMPORTANT: Link with multithreaded runtime library when THREADS are - * used! - */ -#ifdef _WIN32 - -struct u_tsd { - DWORD key; - unsigned initMagic; -}; - -typedef CRITICAL_SECTION u_mutex; - -/* http://locklessinc.com/articles/pthreads_on_windows/ */ -#define u_mutex_declare_static(name) \ - static u_mutex name = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0} - -#define u_mutex_init(name) InitializeCriticalSection(&name) -#define u_mutex_destroy(name) DeleteCriticalSection(&name) -#define u_mutex_lock(name) EnterCriticalSection(&name) -#define u_mutex_unlock(name) LeaveCriticalSection(&name) - -static INLINE unsigned long -u_thread_self(void) -{ - return GetCurrentThreadId(); -} - - -static INLINE void -u_tsd_init(struct u_tsd *tsd) -{ - tsd->key = TlsAlloc(); - if (tsd->key == TLS_OUT_OF_INDEXES) { - perror(INIT_TSD_ERROR); - exit(-1); - } - tsd->initMagic = INIT_MAGIC; -} - - -static INLINE void -u_tsd_destroy(struct u_tsd *tsd) -{ - if (tsd->initMagic != INIT_MAGIC) { - return; - } - TlsFree(tsd->key); - tsd->initMagic = 0x0; -} - - -static INLINE void * -u_tsd_get(struct u_tsd *tsd) -{ - if (tsd->initMagic != INIT_MAGIC) { - u_tsd_init(tsd); - } - return TlsGetValue(tsd->key); -} - - -static INLINE void -u_tsd_set(struct u_tsd *tsd, void *ptr) -{ - /* the following code assumes that the struct u_tsd has been initialized - to zero at creation */ - if (tsd->initMagic != INIT_MAGIC) { - u_tsd_init(tsd); - } - if (TlsSetValue(tsd->key, ptr) == 0) { - perror(SET_TSD_ERROR); - exit(-1); - } -} - -#endif /* _WIN32 */ - - -/* - * THREADS not defined - */ -#ifndef THREADS - -struct u_tsd { - unsigned initMagic; -}; - -typedef unsigned u_mutex; - -#define u_mutex_declare_static(name) static u_mutex name = 0 -#define u_mutex_init(name) (void) name -#define u_mutex_destroy(name) (void) name -#define u_mutex_lock(name) (void) name -#define u_mutex_unlock(name) (void) name - -/* - * no-op functions - */ - -static INLINE unsigned long -u_thread_self(void) -{ - return 0; -} - - -static INLINE void -u_tsd_init(struct u_tsd *tsd) -{ - (void) tsd; -} - - -static INLINE void * -u_tsd_get(struct u_tsd *tsd) -{ - (void) tsd; - return NULL; -} - - -static INLINE void -u_tsd_set(struct u_tsd *tsd, void *ptr) -{ - (void) tsd; - (void) ptr; -} -#endif /* THREADS */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _U_THREAD_H_ */ diff --git a/src/mapi/mapi_abi.py b/src/mapi/mapi_abi.py new file mode 100644 index 00000000000..6bfcfa9af68 --- /dev/null +++ b/src/mapi/mapi_abi.py @@ -0,0 +1,873 @@ +#!/usr/bin/env python + +# Mesa 3-D graphics library +# Version: 7.9 +# +# Copyright (C) 2010 LunarG Inc. +# +# 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. +# +# Authors: +# Chia-I Wu + +import sys +# make it possible to import glapi +import os +GLAPI = os.path.join(".", os.path.dirname(sys.argv[0]), "glapi/gen") +sys.path.append(GLAPI) + +import re +from optparse import OptionParser +import gl_XML +import glX_XML + + +# number of dynamic entries +ABI_NUM_DYNAMIC_ENTRIES = 256 + +class ABIEntry(object): + """Represent an ABI entry.""" + + _match_c_param = re.compile( + '^(?P[\w\s*]+?)(?P\w+)(\[(?P\d+)\])?$') + + def __init__(self, cols, attrs, xml_data = None): + self._parse(cols) + + self.slot = attrs['slot'] + self.hidden = attrs['hidden'] + self.alias = attrs['alias'] + self.handcode = attrs['handcode'] + self.xml_data = xml_data + + def c_prototype(self): + return '%s %s(%s)' % (self.c_return(), self.name, self.c_params()) + + def c_return(self): + ret = self.ret + if not ret: + ret = 'void' + + return ret + + def c_params(self): + """Return the parameter list used in the entry prototype.""" + c_params = [] + for t, n, a in self.params: + sep = '' if t.endswith('*') else ' ' + arr = '[%d]' % a if a else '' + c_params.append(t + sep + n + arr) + if not c_params: + c_params.append('void') + + return ", ".join(c_params) + + def c_args(self): + """Return the argument list used in the entry invocation.""" + c_args = [] + for t, n, a in self.params: + c_args.append(n) + + return ", ".join(c_args) + + def _parse(self, cols): + ret = cols.pop(0) + if ret == 'void': + ret = None + + name = cols.pop(0) + + params = [] + if not cols: + raise Exception(cols) + elif len(cols) == 1 and cols[0] == 'void': + pass + else: + for val in cols: + params.append(self._parse_param(val)) + + self.ret = ret + self.name = name + self.params = params + + def _parse_param(self, c_param): + m = self._match_c_param.match(c_param) + if not m: + raise Exception('unrecognized param ' + c_param) + + c_type = m.group('type').strip() + c_name = m.group('name') + c_array = m.group('array') + c_array = int(c_array) if c_array else 0 + + return (c_type, c_name, c_array) + + def __str__(self): + return self.c_prototype() + + def __cmp__(self, other): + # compare slot, alias, and then name + res = cmp(self.slot, other.slot) + if not res: + if not self.alias: + res = -1 + elif not other.alias: + res = 1 + + if not res: + res = cmp(self.name, other.name) + + return res + +def abi_parse_xml(xml): + """Parse a GLAPI XML file for ABI entries.""" + api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory()) + + entry_dict = {} + for func in api.functionIterateByOffset(): + # make sure func.name appear first + entry_points = func.entry_points[:] + entry_points.remove(func.name) + entry_points.insert(0, func.name) + + for name in entry_points: + attrs = { + 'slot': func.offset, + 'hidden': not func.is_static_entry_point(name), + 'alias': None if name == func.name else func.name, + 'handcode': bool(func.has_different_protocol(name)), + } + + # post-process attrs + if attrs['alias']: + try: + alias = entry_dict[attrs['alias']] + except KeyError: + raise Exception('failed to alias %s' % attrs['alias']) + if alias.alias: + raise Exception('recursive alias %s' % ent.name) + attrs['alias'] = alias + if attrs['handcode']: + attrs['handcode'] = func.static_glx_name(name) + else: + attrs['handcode'] = None + + if entry_dict.has_key(name): + raise Exception('%s is duplicated' % (name)) + + cols = [] + cols.append(func.return_type) + cols.append(name) + params = func.get_parameter_string(name) + cols.extend([p.strip() for p in params.split(',')]) + + ent = ABIEntry(cols, attrs, func) + entry_dict[ent.name] = ent + + entries = entry_dict.values() + entries.sort() + + return entries + +def abi_parse_line(line): + cols = [col.strip() for col in line.split(',')] + + attrs = { + 'slot': -1, + 'hidden': False, + 'alias': None, + 'handcode': None, + } + + # extract attributes from the first column + vals = cols[0].split(':') + while len(vals) > 1: + val = vals.pop(0) + if val.startswith('slot='): + attrs['slot'] = int(val[5:]) + elif val == 'hidden': + attrs['hidden'] = True + elif val.startswith('alias='): + attrs['alias'] = val[6:] + elif val.startswith('handcode='): + attrs['handcode'] = val[9:] + elif not val: + pass + else: + raise Exception('unknown attribute %s' % val) + cols[0] = vals[0] + + return (attrs, cols) + +def abi_parse(filename): + """Parse a CSV file for ABI entries.""" + fp = open(filename) if filename != '-' else sys.stdin + lines = [line.strip() for line in fp.readlines() + if not line.startswith('#') and line.strip()] + + entry_dict = {} + next_slot = 0 + for line in lines: + attrs, cols = abi_parse_line(line) + + # post-process attributes + if attrs['alias']: + try: + alias = entry_dict[attrs['alias']] + except KeyError: + raise Exception('failed to alias %s' % attrs['alias']) + if alias.alias: + raise Exception('recursive alias %s' % ent.name) + slot = alias.slot + attrs['alias'] = alias + else: + slot = next_slot + next_slot += 1 + + if attrs['slot'] < 0: + attrs['slot'] = slot + elif attrs['slot'] != slot: + raise Exception('invalid slot in %s' % (line)) + + ent = ABIEntry(cols, attrs) + if entry_dict.has_key(ent.name): + raise Exception('%s is duplicated' % (ent.name)) + entry_dict[ent.name] = ent + + entries = entry_dict.values() + entries.sort() + + return entries + +def abi_sanity_check(entries): + if not entries: + return + + all_names = [] + last_slot = entries[-1].slot + i = 0 + for slot in xrange(last_slot + 1): + if entries[i].slot != slot: + raise Exception('entries are not ordered by slots') + if entries[i].alias: + raise Exception('first entry of slot %d aliases %s' + % (slot, entries[i].alias.name)) + handcode = None + while i < len(entries) and entries[i].slot == slot: + ent = entries[i] + if not handcode and ent.handcode: + handcode = ent.handcode + elif ent.handcode != handcode: + raise Exception('two aliases with handcode %s != %s', + ent.handcode, handcode) + + if ent.name in all_names: + raise Exception('%s is duplicated' % (ent.name)) + if ent.alias and ent.alias.name not in all_names: + raise Exception('failed to alias %s' % (ent.alias.name)) + all_names.append(ent.name) + i += 1 + if i < len(entries): + raise Exception('there are %d invalid entries' % (len(entries) - 1)) + +class ABIPrinter(object): + """MAPI Printer""" + + def __init__(self, entries): + self.entries = entries + + # sort entries by their names + self.entries_sorted_by_names = self.entries[:] + self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name)) + + self.indent = ' ' * 3 + self.noop_warn = 'noop_warn' + self.noop_generic = 'noop_generic' + self.current_get = 'entry_current_get' + + self.api_defines = [] + self.api_headers = ['"KHR/khrplatform.h"'] + self.api_call = 'KHRONOS_APICALL' + self.api_entry = 'KHRONOS_APIENTRY' + self.api_attrs = 'KHRONOS_APIATTRIBUTES' + + self.c_header = '' + + self.lib_need_table_size = True + self.lib_need_noop_array = True + self.lib_need_stubs = True + self.lib_need_all_entries = True + self.lib_need_non_hidden_entries = False + + def c_notice(self): + return '/* This file is automatically generated by mapi_abi.py. Do not modify. */' + + def c_public_includes(self): + """Return includes of the client API headers.""" + defines = ['#define ' + d for d in self.api_defines] + includes = ['#include ' + h for h in self.api_headers] + return "\n".join(defines + includes) + + def need_entry_point(self, ent): + """Return True if an entry point is needed for the entry.""" + # non-handcode hidden aliases may share the entry they alias + use_alias = (ent.hidden and ent.alias and not ent.handcode) + return not use_alias + + def c_public_declarations(self, prefix): + """Return the declarations of public entry points.""" + decls = [] + for ent in self.entries: + if not self.need_entry_point(ent): + continue + export = self.api_call if not ent.hidden else '' + decls.append(self._c_decl(ent, prefix, True, export) + ';') + + return "\n".join(decls) + + def c_mapi_table(self): + """Return defines of the dispatch table size.""" + num_static_entries = self.entries[-1].slot + 1 + return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \ + '#define MAPI_TABLE_NUM_DYNAMIC %d') % ( + num_static_entries, ABI_NUM_DYNAMIC_ENTRIES) + + def c_mapi_table_initializer(self, prefix): + """Return the array initializer for mapi_table_fill.""" + entries = [self._c_function(ent, prefix) + for ent in self.entries if not ent.alias] + pre = self.indent + '(mapi_proc) ' + return pre + (',\n' + pre).join(entries) + + def c_mapi_table_spec(self): + """Return the spec for mapi_init.""" + specv1 = [] + line = '"1' + for ent in self.entries: + if not ent.alias: + line += '\\0"\n' + specv1.append(line) + line = '"' + line += '%s\\0' % ent.name + line += '";' + specv1.append(line) + + return self.indent + self.indent.join(specv1) + + def _c_function(self, ent, prefix, mangle=False, stringify=False): + """Return the function name of an entry.""" + formats = { + True: { True: '%s_STR(%s)', False: '%s(%s)' }, + False: { True: '"%s%s"', False: '%s%s' }, + } + fmt = formats[prefix.isupper()][stringify] + name = ent.name + if mangle and ent.hidden: + name = '_dispatch_stub_' + str(ent.slot) + return fmt % (prefix, name) + + def _c_function_call(self, ent, prefix): + """Return the function name used for calling.""" + if ent.handcode: + # _c_function does not handle this case + formats = { True: '%s(%s)', False: '%s%s' } + fmt = formats[prefix.isupper()] + name = fmt % (prefix, ent.handcode) + elif self.need_entry_point(ent): + name = self._c_function(ent, prefix, True) + else: + name = self._c_function(ent.alias, prefix, True) + return name + + def _c_decl(self, ent, prefix, mangle=False, export=''): + """Return the C declaration for the entry.""" + decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry, + self._c_function(ent, prefix, mangle), ent.c_params()) + if export: + decl = export + ' ' + decl + if self.api_attrs: + decl += ' ' + self.api_attrs + + return decl + + def _c_cast(self, ent): + """Return the C cast for the entry.""" + cast = '%s (%s *)(%s)' % ( + ent.c_return(), self.api_entry, ent.c_params()) + + return cast + + def c_private_declarations(self, prefix): + """Return the declarations of private functions.""" + decls = [self._c_decl(ent, prefix) + ';' + for ent in self.entries if not ent.alias] + + return "\n".join(decls) + + def c_public_dispatches(self, prefix, no_hidden): + """Return the public dispatch functions.""" + dispatches = [] + for ent in self.entries: + if ent.hidden and no_hidden: + continue + + if not self.need_entry_point(ent): + continue + + export = self.api_call if not ent.hidden else '' + + proto = self._c_decl(ent, prefix, True, export) + cast = self._c_cast(ent) + + ret = '' + if ent.ret: + ret = 'return ' + stmt1 = self.indent + stmt1 += 'const struct mapi_table *_tbl = %s();' % ( + self.current_get) + stmt2 = self.indent + stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % ( + ent.slot) + stmt3 = self.indent + stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args()) + + disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3) + + if ent.handcode: + disp = '#if 0\n' + disp + '\n#endif' + + dispatches.append(disp) + + return '\n\n'.join(dispatches) + + def c_public_initializer(self, prefix): + """Return the initializer for public dispatch functions.""" + names = [] + for ent in self.entries: + if ent.alias: + continue + + name = '%s(mapi_func) %s' % (self.indent, + self._c_function_call(ent, prefix)) + names.append(name) + + return ',\n'.join(names) + + def c_stub_string_pool(self): + """Return the string pool for use by stubs.""" + # sort entries by their names + sorted_entries = self.entries[:] + sorted_entries.sort(lambda x, y: cmp(x.name, y.name)) + + pool = [] + offsets = {} + count = 0 + for ent in sorted_entries: + offsets[ent] = count + pool.append('%s' % (ent.name)) + count += len(ent.name) + 1 + + pool_str = self.indent + '"' + \ + ('\\0"\n' + self.indent + '"').join(pool) + '";' + return (pool_str, offsets) + + def c_stub_initializer(self, prefix, pool_offsets): + """Return the initializer for struct mapi_stub array.""" + stubs = [] + for ent in self.entries_sorted_by_names: + stubs.append('%s{ (void *) %d, %d, NULL }' % ( + self.indent, pool_offsets[ent], ent.slot)) + + return ',\n'.join(stubs) + + def c_noop_functions(self, prefix, warn_prefix): + """Return the noop functions.""" + noops = [] + for ent in self.entries: + if ent.alias: + continue + + proto = self._c_decl(ent, prefix, False, 'static') + + stmt1 = self.indent; + space = '' + for t, n, a in ent.params: + stmt1 += "%s(void) %s;" % (space, n) + space = ' ' + + if ent.params: + stmt1 += '\n'; + + stmt1 += self.indent + '%s(%s);' % (self.noop_warn, + self._c_function(ent, warn_prefix, False, True)) + + if ent.ret: + stmt2 = self.indent + 'return (%s) 0;' % (ent.ret) + noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2) + else: + noop = '%s\n{\n%s\n}' % (proto, stmt1) + + noops.append(noop) + + return '\n\n'.join(noops) + + def c_noop_initializer(self, prefix, use_generic): + """Return an initializer for the noop dispatch table.""" + entries = [self._c_function(ent, prefix) + for ent in self.entries if not ent.alias] + if use_generic: + entries = [self.noop_generic] * len(entries) + + entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES) + + pre = self.indent + '(mapi_func) ' + return pre + (',\n' + pre).join(entries) + + def c_asm_gcc(self, prefix, no_hidden): + asm = [] + + for ent in self.entries: + if ent.hidden and no_hidden: + continue + + if not self.need_entry_point(ent): + continue + + name = self._c_function(ent, prefix, True, True) + + if ent.handcode: + asm.append('#if 0') + + if ent.hidden: + asm.append('".hidden "%s"\\n"' % (name)) + + if ent.alias and not (ent.alias.hidden and no_hidden): + asm.append('".globl "%s"\\n"' % (name)) + asm.append('".set "%s", "%s"\\n"' % (name, + self._c_function(ent.alias, prefix, True, True))) + else: + asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name)) + asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot)) + + if ent.handcode: + asm.append('#endif') + asm.append('') + + return "\n".join(asm) + + def output_for_lib(self): + print self.c_notice() + + if self.c_header: + print + print self.c_header + + print + print '#ifdef MAPI_TMP_DEFINES' + print self.c_public_includes() + print + print self.c_public_declarations(self.prefix_lib) + print '#undef MAPI_TMP_DEFINES' + print '#endif /* MAPI_TMP_DEFINES */' + + if self.lib_need_table_size: + print + print '#ifdef MAPI_TMP_TABLE' + print self.c_mapi_table() + print '#undef MAPI_TMP_TABLE' + print '#endif /* MAPI_TMP_TABLE */' + + if self.lib_need_noop_array: + print + print '#ifdef MAPI_TMP_NOOP_ARRAY' + print '#ifdef DEBUG' + print + print self.c_noop_functions(self.prefix_noop, self.prefix_warn) + print + print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop) + print self.c_noop_initializer(self.prefix_noop, False) + print '};' + print + print '#else /* DEBUG */' + print + print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop) + print self.c_noop_initializer(self.prefix_noop, True) + print '};' + print + print '#endif /* DEBUG */' + print '#undef MAPI_TMP_NOOP_ARRAY' + print '#endif /* MAPI_TMP_NOOP_ARRAY */' + + if self.lib_need_stubs: + pool, pool_offsets = self.c_stub_string_pool() + print + print '#ifdef MAPI_TMP_PUBLIC_STUBS' + print 'static const char public_string_pool[] =' + print pool + print + print 'static const struct mapi_stub public_stubs[] = {' + print self.c_stub_initializer(self.prefix_lib, pool_offsets) + print '};' + print '#undef MAPI_TMP_PUBLIC_STUBS' + print '#endif /* MAPI_TMP_PUBLIC_STUBS */' + + if self.lib_need_all_entries: + print + print '#ifdef MAPI_TMP_PUBLIC_ENTRIES' + print self.c_public_dispatches(self.prefix_lib, False) + print + print 'static const mapi_func public_entries[] = {' + print self.c_public_initializer(self.prefix_lib) + print '};' + print '#undef MAPI_TMP_PUBLIC_ENTRIES' + print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */' + + print + print '#ifdef MAPI_TMP_STUB_ASM_GCC' + print '__asm__(' + print self.c_asm_gcc(self.prefix_lib, False) + print ');' + print '#undef MAPI_TMP_STUB_ASM_GCC' + print '#endif /* MAPI_TMP_STUB_ASM_GCC */' + + if self.lib_need_non_hidden_entries: + all_hidden = True + for ent in self.entries: + if not ent.hidden: + all_hidden = False + break + if not all_hidden: + print + print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN' + print self.c_public_dispatches(self.prefix_lib, True) + print + print '/* does not need public_entries */' + print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN' + print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */' + + print + print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN' + print '__asm__(' + print self.c_asm_gcc(self.prefix_lib, True) + print ');' + print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN' + print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */' + + def output_for_app(self): + print self.c_notice() + print + print self.c_private_declarations(self.prefix_app) + print + print '#ifdef API_TMP_DEFINE_SPEC' + print + print 'static const char %s_spec[] =' % (self.prefix_app) + print self.c_mapi_table_spec() + print + print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app) + print self.c_mapi_table_initializer(self.prefix_app) + print '};' + print + print '#endif /* API_TMP_DEFINE_SPEC */' + +class GLAPIPrinter(ABIPrinter): + """OpenGL API Printer""" + + def __init__(self, entries): + for ent in entries: + self._override_for_api(ent) + super(GLAPIPrinter, self).__init__(entries) + + self.api_defines = ['GL_GLEXT_PROTOTYPES'] + self.api_headers = ['"GL/gl.h"', '"GL/glext.h"'] + self.api_call = 'GLAPI' + self.api_entry = 'APIENTRY' + self.api_attrs = '' + + self.lib_need_table_size = False + self.lib_need_noop_array = False + self.lib_need_stubs = False + self.lib_need_all_entries = False + self.lib_need_non_hidden_entries = True + + self.prefix_lib = 'GLAPI_PREFIX' + self.prefix_app = '_mesa_' + self.prefix_noop = 'noop' + self.prefix_warn = self.prefix_lib + + self.c_header = self._get_c_header() + + def _override_for_api(self, ent): + """Override attributes of an entry if necessary for this + printer.""" + # By default, no override is necessary. + pass + + def _get_c_header(self): + header = """#ifndef _GLAPI_TMP_H_ +#define _GLAPI_TMP_H_ +#ifdef USE_MGL_NAMESPACE +#define GLAPI_PREFIX(func) mgl##func +#define GLAPI_PREFIX_STR(func) "mgl"#func +#else +#define GLAPI_PREFIX(func) gl##func +#define GLAPI_PREFIX_STR(func) "gl"#func +#endif /* USE_MGL_NAMESPACE */ + +typedef int GLfixed; +typedef int GLclampx; +#endif /* _GLAPI_TMP_H_ */""" + + return header + +class ES1APIPrinter(GLAPIPrinter): + """OpenGL ES 1.x API Printer""" + + def __init__(self, entries): + super(ES1APIPrinter, self).__init__(entries) + self.prefix_lib = 'gl' + self.prefix_warn = 'gl' + + def _override_for_api(self, ent): + if ent.xml_data is None: + raise Exception('ES2 API printer requires XML input') + ent.hidden = ent.name not in \ + ent.xml_data.entry_points_for_api_version('es1') + ent.handcode = False + + def _get_c_header(self): + header = """#ifndef _GLAPI_TMP_H_ +#define _GLAPI_TMP_H_ +typedef int GLfixed; +typedef int GLclampx; +#endif /* _GLAPI_TMP_H_ */""" + + return header + +class ES2APIPrinter(GLAPIPrinter): + """OpenGL ES 2.x API Printer""" + + def __init__(self, entries): + super(ES2APIPrinter, self).__init__(entries) + self.prefix_lib = 'gl' + self.prefix_warn = 'gl' + + def _override_for_api(self, ent): + if ent.xml_data is None: + raise Exception('ES2 API printer requires XML input') + ent.hidden = ent.name not in \ + ent.xml_data.entry_points_for_api_version('es2') + ent.handcode = False + + def _get_c_header(self): + header = """#ifndef _GLAPI_TMP_H_ +#define _GLAPI_TMP_H_ +typedef int GLfixed; +typedef int GLclampx; +#endif /* _GLAPI_TMP_H_ */""" + + return header + +class SharedGLAPIPrinter(GLAPIPrinter): + """Shared GLAPI API Printer""" + + def __init__(self, entries): + super(SharedGLAPIPrinter, self).__init__(entries) + + self.lib_need_table_size = True + self.lib_need_noop_array = True + self.lib_need_stubs = True + self.lib_need_all_entries = True + self.lib_need_non_hidden_entries = False + + self.prefix_lib = 'shared' + self.prefix_warn = 'gl' + + def _override_for_api(self, ent): + ent.hidden = True + ent.handcode = False + + def _get_c_header(self): + header = """#ifndef _GLAPI_TMP_H_ +#define _GLAPI_TMP_H_ +typedef int GLfixed; +typedef int GLclampx; +#endif /* _GLAPI_TMP_H_ */""" + + return header + +class VGAPIPrinter(ABIPrinter): + """OpenVG API Printer""" + + def __init__(self, entries): + super(VGAPIPrinter, self).__init__(entries) + + self.api_defines = ['VG_VGEXT_PROTOTYPES'] + self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"'] + self.api_call = 'VG_API_CALL' + self.api_entry = 'VG_API_ENTRY' + self.api_attrs = 'VG_API_EXIT' + + self.prefix_lib = 'vg' + self.prefix_app = 'vega' + self.prefix_noop = 'noop' + self.prefix_warn = 'vg' + +def parse_args(): + printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi'] + modes = ['lib', 'app'] + + parser = OptionParser(usage='usage: %prog [options] ') + parser.add_option('-p', '--printer', dest='printer', + help='printer to use: %s' % (", ".join(printers))) + parser.add_option('-m', '--mode', dest='mode', + help='target user: %s' % (", ".join(modes))) + + options, args = parser.parse_args() + if not args or options.printer not in printers or \ + options.mode not in modes: + parser.print_help() + sys.exit(1) + + return (args[0], options) + +def main(): + printers = { + 'vgapi': VGAPIPrinter, + 'glapi': GLAPIPrinter, + 'es1api': ES1APIPrinter, + 'es2api': ES2APIPrinter, + 'shared-glapi': SharedGLAPIPrinter, + } + + filename, options = parse_args() + + if filename.endswith('.xml'): + entries = abi_parse_xml(filename) + else: + entries = abi_parse(filename) + abi_sanity_check(entries) + + printer = printers[options.printer](entries) + if options.mode == 'lib': + printer.output_for_lib() + else: + printer.output_for_app() + +if __name__ == '__main__': + main() diff --git a/src/mapi/mapi_glapi.c b/src/mapi/mapi_glapi.c new file mode 100644 index 00000000000..a6838ce61e4 --- /dev/null +++ b/src/mapi/mapi_glapi.c @@ -0,0 +1,240 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include +#include "glapi/glapi.h" +#include "u_current.h" +#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */ +#include "stub.h" + +/* + * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in + * u_current.c. + */ + +#ifdef GLX_USE_TLS +/* not used, but defined for compatibility */ +const struct _glapi_table *_glapi_Dispatch; +const void *_glapi_Context; +#endif /* GLX_USE_TLS */ + +void +_glapi_destroy_multithread(void) +{ + u_current_destroy(); +} + +void +_glapi_check_multithread(void) +{ + u_current_init(); +} + +void +_glapi_set_context(void *context) +{ + u_current_set_user((const void *) context); +} + +void +_glapi_set_dispatch(struct _glapi_table *dispatch) +{ + u_current_set((const struct mapi_table *) dispatch); +} + +/** + * Return size of dispatch table struct as number of functions (or + * slots). + */ +unsigned int +_glapi_get_dispatch_table_size(void) +{ + return MAPI_TABLE_NUM_SLOTS; +} + +/** + * Fill-in the dispatch stub for the named function. + * + * This function is intended to be called by a hardware driver. When called, + * a dispatch stub may be created created for the function. A pointer to this + * dispatch function will be returned by glXGetProcAddress. + * + * \param function_names Array of pointers to function names that should + * share a common dispatch offset. + * \param parameter_signature String representing the types of the parameters + * passed to the named function. Parameter types + * are converted to characters using the following + * rules: + * - 'i' for \c GLint, \c GLuint, and \c GLenum + * - 'p' for any pointer type + * - 'f' for \c GLfloat and \c GLclampf + * - 'd' for \c GLdouble and \c GLclampd + * + * \returns + * The offset in the dispatch table of the named function. A pointer to the + * driver's implementation of the named function should be stored at + * \c dispatch_table[\c offset]. Return -1 if error/problem. + * + * \sa glXGetProcAddress + * + * \warning + * This function can only handle up to 8 names at a time. As far as I know, + * the maximum number of names ever associated with an existing GL function is + * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, + * \c glPointParameterfARB, and \c glPointParameterf), so this should not be + * too painful of a limitation. + * + * \todo + * Check parameter_signature. + */ +int +_glapi_add_dispatch( const char * const * function_names, + const char * parameter_signature ) +{ + const struct mapi_stub *function_stubs[8]; + const struct mapi_stub *alias = NULL; + unsigned i; + + (void) memset(function_stubs, 0, sizeof(function_stubs)); + + /* find the missing stubs, and decide the alias */ + for (i = 0; function_names[i] != NULL && i < 8; i++) { + const char * funcName = function_names[i]; + const struct mapi_stub *stub; + int slot; + + if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') + return -1; + funcName += 2; + + stub = stub_find_public(funcName); + if (!stub) + stub = stub_find_dynamic(funcName, 0); + + slot = (stub) ? stub_get_slot(stub) : -1; + if (slot >= 0) { + if (alias && stub_get_slot(alias) != slot) + return -1; + /* use the first existing stub as the alias */ + if (!alias) + alias = stub; + + function_stubs[i] = stub; + } + } + + /* generate missing stubs */ + for (i = 0; function_names[i] != NULL && i < 8; i++) { + const char * funcName = function_names[i] + 2; + struct mapi_stub *stub; + + if (function_stubs[i]) + continue; + + stub = stub_find_dynamic(funcName, 1); + if (!stub) + return -1; + + stub_fix_dynamic(stub, alias); + if (!alias) + alias = stub; + } + + return (alias) ? stub_get_slot(alias) : -1; +} + +static const struct mapi_stub * +_glapi_get_stub(const char *name, int generate) +{ + const struct mapi_stub *stub; + +#ifdef USE_MGL_NAMESPACE + if (name) + name++; +#endif + + if (!name || name[0] != 'g' || name[1] != 'l') + return NULL; + name += 2; + + stub = stub_find_public(name); + if (!stub) + stub = stub_find_dynamic(name, generate); + + return stub; +} + +/** + * Return offset of entrypoint for named function within dispatch table. + */ +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 pointer to the named function. If the function name isn't found + * in the name of static functions, try generating a new API entrypoint on + * the fly with assembly language. + */ +_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; +} + +/** + * Return the name of the function at the given dispatch offset. + * This is only intended for debugging. + */ +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; +} + +unsigned long +_glthread_GetID(void) +{ + return u_thread_self(); +} + +void +_glapi_noop_enable_warnings(unsigned char enable) +{ +} + +void +_glapi_set_warning_func(_glapi_proc func) +{ +} diff --git a/src/mapi/mapi_tmp.h b/src/mapi/mapi_tmp.h new file mode 100644 index 00000000000..f326b4a4e14 --- /dev/null +++ b/src/mapi/mapi_tmp.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#ifndef MAPI_ABI_HEADER +#error "MAPI_ABI_HEADER must be defined" +#endif + +/* does not need hidden entries in bridge mode */ +#ifdef MAPI_MODE_BRIDGE + +#ifdef MAPI_TMP_PUBLIC_ENTRIES +#undef MAPI_TMP_PUBLIC_ENTRIES +#define MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN +#endif + +#ifdef MAPI_TMP_STUB_ASM_GCC +#undef MAPI_TMP_STUB_ASM_GCC +#define MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN +#endif + +#endif /* MAPI_MODE_BRIDGE */ + +#include MAPI_ABI_HEADER diff --git a/src/mapi/shared-glapi/Makefile.am b/src/mapi/shared-glapi/Makefile.am index 2cc5c590548..2021a7330f1 100644 --- a/src/mapi/shared-glapi/Makefile.am +++ b/src/mapi/shared-glapi/Makefile.am @@ -2,7 +2,7 @@ TOP = $(top_srcdir) GLAPI = $(top_srcdir)/src/mapi/glapi -include $(top_srcdir)/src/mapi/mapi/Makefile.sources +include $(top_srcdir)/src/mapi/Makefile.sources lib_LTLIBRARIES = libglapi.la libglapi_la_SOURCES = $(MAPI_GLAPI_FILES) diff --git a/src/mapi/shared-glapi/SConscript b/src/mapi/shared-glapi/SConscript index 0097c1c79ec..07b3eff118d 100644 --- a/src/mapi/shared-glapi/SConscript +++ b/src/mapi/shared-glapi/SConscript @@ -28,7 +28,7 @@ def mapi_objects(env, printer, mode): # generate ABI header header = env.CodeGenerate( target = header_name, - script = '../mapi/mapi_abi.py', + script = '../mapi_abi.py', source = '../glapi/gen/gl_and_es_API.xml', command = python_cmd + ' $SCRIPT ' + \ '--printer %s --mode lib $SOURCE > $TARGET' % (printer), @@ -59,7 +59,7 @@ def mapi_objects(env, printer, mode): for s in mapi_sources[mode]: o = env.SharedObject( target = '%s-%s' % (printer, s[:-2]), - source = '../mapi/' + s, + source = '../' + s, CPPPATH = cpppath, CPPDEFINES = cppdefines, ) diff --git a/src/mapi/stub.c b/src/mapi/stub.c new file mode 100644 index 00000000000..688dc8143a4 --- /dev/null +++ b/src/mapi/stub.c @@ -0,0 +1,229 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include +#include +#include + +#include "u_current.h" +#include "u_thread.h" +#include "entry.h" +#include "stub.h" +#include "table.h" + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +struct mapi_stub { + const void *name; + int slot; + mapi_func addr; +}; + +/* define public_string_pool and public_stubs */ +#define MAPI_TMP_PUBLIC_STUBS +#include "mapi_tmp.h" + +static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC]; +static int num_dynamic_stubs; +static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC; + +void +stub_init_once(void) +{ +#ifdef HAVE_PTHREAD + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, entry_patch_public); +#else + static int first = 1; + if (first) { + first = 0; + entry_patch_public(); + } +#endif +} + +static int +stub_compare(const void *key, const void *elem) +{ + const char *name = (const char *) key; + const struct mapi_stub *stub = (const struct mapi_stub *) elem; + const char *stub_name; + + stub_name = &public_string_pool[(unsigned long) stub->name]; + + return strcmp(name, stub_name); +} + +/** + * Return the public stub with the given name. + */ +const struct mapi_stub * +stub_find_public(const char *name) +{ + return (const struct mapi_stub *) bsearch(name, public_stubs, + ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare); +} + +/** + * Add a dynamic stub. + */ +static struct mapi_stub * +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; + + stub = &dynamic_stubs[idx]; + + /* dispatch to the last slot, which is reserved for no-op */ + stub->addr = entry_generate( + MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1); + if (!stub->addr) + return NULL; + + stub->name = (const void *) name; + /* to be fixed later */ + stub->slot = -1; + + num_dynamic_stubs = idx + 1; + + return stub; +} + +/** + * 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 * +stub_find_dynamic(const char *name, int generate) +{ + u_mutex_declare_static(dynamic_mutex); + struct mapi_stub *stub = NULL; + int count, i; + + u_mutex_lock(dynamic_mutex); + + if (generate) + assert(!stub_find_public(name)); + + count = num_dynamic_stubs; + for (i = 0; i < count; i++) { + if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) { + stub = &dynamic_stubs[i]; + break; + } + } + + /* generate a dynamic stub */ + if (generate && !stub) + stub = stub_add_dynamic(name); + + u_mutex_unlock(dynamic_mutex); + + return stub; +} + +static const struct mapi_stub * +search_table_by_slot(const struct mapi_stub *table, size_t num_entries, + int slot) +{ + size_t i; + for (i = 0; i < num_entries; ++i) { + if (table[i].slot == slot) + return &table[i]; + } + return NULL; +} + +const struct mapi_stub * +stub_find_by_slot(int slot) +{ + const struct mapi_stub *stub = + search_table_by_slot(public_stubs, ARRAY_SIZE(public_stubs), slot); + if (stub) + return stub; + return search_table_by_slot(dynamic_stubs, num_dynamic_stubs, slot); +} + +void +stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias) +{ + int slot; + + if (stub->slot >= 0) + return; + + if (alias) + slot = alias->slot; + else + slot = next_dynamic_slot++; + + entry_patch(stub->addr, slot); + stub->slot = slot; +} + +/** + * Return the name of a stub. + */ +const char * +stub_get_name(const struct mapi_stub *stub) +{ + const char *name; + + if (stub >= public_stubs && + stub < public_stubs + ARRAY_SIZE(public_stubs)) + name = &public_string_pool[(unsigned long) stub->name]; + else + name = (const char *) stub->name; + + return name; +} + +/** + * Return the slot of a stub. + */ +int +stub_get_slot(const struct mapi_stub *stub) +{ + return stub->slot; +} + +/** + * Return the address of a stub. + */ +mapi_func +stub_get_addr(const struct mapi_stub *stub) +{ + assert(stub->addr || (unsigned int) stub->slot < MAPI_TABLE_NUM_STATIC); + return (stub->addr) ? stub->addr : entry_get_public(stub->slot); +} diff --git a/src/mapi/stub.h b/src/mapi/stub.h new file mode 100644 index 00000000000..98e2553ecdd --- /dev/null +++ b/src/mapi/stub.h @@ -0,0 +1,60 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#ifndef _STUB_H_ +#define _STUB_H_ + +#include "entry.h" + +struct mapi_stub; + +void +stub_init_once(void); + +const struct mapi_stub * +stub_find_public(const char *name); + +struct mapi_stub * +stub_find_dynamic(const char *name, int generate); + +const struct mapi_stub * +stub_find_by_slot(int slot); + +void +stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias); + +const char * +stub_get_name(const struct mapi_stub *stub); + +int +stub_get_slot(const struct mapi_stub *stub); + +mapi_func +stub_get_addr(const struct mapi_stub *stub); + +#endif /* _STUB_H_ */ diff --git a/src/mapi/table.c b/src/mapi/table.c new file mode 100644 index 00000000000..9bb9f654a2a --- /dev/null +++ b/src/mapi/table.c @@ -0,0 +1,56 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#include +#include + +#include "table.h" + +static void +noop_warn(const char *name) +{ + static int debug = -1; + + if (debug < 0) + debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")); + + if (debug) + fprintf(stderr, "%s is no-op\n", name); +} + +static int +noop_generic(void) +{ + noop_warn("function"); + return 0; +} + +/* define noop_array */ +#define MAPI_TMP_DEFINES +#define MAPI_TMP_NOOP_ARRAY +#include "mapi_tmp.h" diff --git a/src/mapi/table.h b/src/mapi/table.h new file mode 100644 index 00000000000..d84523f7777 --- /dev/null +++ b/src/mapi/table.h @@ -0,0 +1,72 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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. + * + * Authors: + * Chia-I Wu + */ + +#ifndef _TABLE_H_ +#define _TABLE_H_ + +#include "u_compiler.h" +#include "entry.h" + +#define MAPI_TMP_TABLE +#include "mapi_tmp.h" + +#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC) +#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func)) + +extern const mapi_func table_noop_array[]; + +/** + * Get the no-op dispatch table. + */ +static INLINE const struct mapi_table * +table_get_noop(void) +{ + return (const struct mapi_table *) table_noop_array; +} + +/** + * Set the function of a slot. + */ +static INLINE void +table_set_func(struct mapi_table *tbl, int slot, mapi_func func) +{ + mapi_func *funcs = (mapi_func *) tbl; + funcs[slot] = func; +} + +/** + * Return the function of a slot. + */ +static INLINE mapi_func +table_get_func(const struct mapi_table *tbl, int slot) +{ + const mapi_func *funcs = (const mapi_func *) tbl; + return funcs[slot]; +} + +#endif /* _TABLE_H_ */ diff --git a/src/mapi/u_compiler.h b/src/mapi/u_compiler.h new file mode 100644 index 00000000000..f376e97a0f3 --- /dev/null +++ b/src/mapi/u_compiler.h @@ -0,0 +1,33 @@ +#ifndef _U_COMPILER_H_ +#define _U_COMPILER_H_ + +#include "c99_compat.h" /* inline, __func__, etc. */ + + +/* XXX: Use standard `inline` keyword instead */ +#ifndef INLINE +# define INLINE inline +#endif + +/* Function visibility */ +#ifndef PUBLIC +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define PUBLIC __attribute__((visibility("default"))) +# elif defined(_MSC_VER) +# define PUBLIC __declspec(dllexport) +# else +# define PUBLIC +# endif +#endif + +#ifndef likely +# if defined(__GNUC__) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# else +# define likely(x) (x) +# define unlikely(x) (x) +# endif +#endif + +#endif /* _U_COMPILER_H_ */ diff --git a/src/mapi/u_current.c b/src/mapi/u_current.c new file mode 100644 index 00000000000..d902375f8c6 --- /dev/null +++ b/src/mapi/u_current.c @@ -0,0 +1,266 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + + +/* + * This file manages the OpenGL API dispatch layer. + * The dispatch table (struct _glapi_table) is basically just a list + * of function pointers. + * There are functions to set/get the current dispatch table for the + * current thread and to manage registration/dispatch of dynamically + * added extension functions. + * + * It's intended that this file and the other glapi*.[ch] files are + * flexible enough to be reused in several places: XFree86, DRI- + * based libGL.so, and perhaps the SGI SI. + * + * NOTE: There are no dependencies on Mesa in this code. + * + * Versions (API changes): + * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 + * 2001/01/16 - added dispatch override feature for Mesa 3.5 + * 2002/06/28 - added _glapi_set_warning_func(), Mesa 4.1. + * 2002/10/01 - _glapi_get_proc_address() will now generate new entrypoints + * itself (using offset ~0). _glapi_add_entrypoint() can be + * called afterward and it'll fill in the correct dispatch + * offset. This allows DRI libGL to avoid probing for DRI + * drivers! No changes to the public glapi interface. + */ + +#include "u_current.h" +#include "u_thread.h" + +#ifndef MAPI_MODE_UTIL + +#include "table.h" +#include "stub.h" + +#else + +extern void init_glapi_relocs_once(void); +extern void (*__glapi_noop_table[])(void); + +#define table_noop_array __glapi_noop_table +#define stub_init_once() init_glapi_relocs_once() + +#endif + +/** + * \name Current dispatch and current context control variables + * + * Depending on whether or not multithreading is support, and the type of + * support available, several variables are used to store the current context + * pointer and the current dispatch table pointer. In the non-threaded case, + * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this + * purpose. + * + * In the "normal" threaded case, the variables \c _glapi_Dispatch and + * \c _glapi_Context will be \c NULL if an application is detected as being + * multithreaded. Single-threaded applications will use \c _glapi_Dispatch + * and \c _glapi_Context just like the case without any threading support. + * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state + * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the + * static dispatch functions access these variables via \c _glapi_get_dispatch + * and \c _glapi_get_context. + * + * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is + * possible for the original thread to be setting it at the same instant a new + * thread, perhaps running on a different processor, is clearing it. Because + * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is + * used to determine whether or not the application is multithreaded. + * + * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are + * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and + * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and + * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability + * between TLS enabled loaders and non-TLS DRI drivers. + */ +/*@{*/ +#if defined(GLX_USE_TLS) + +__thread struct mapi_table *u_current_table + __attribute__((tls_model("initial-exec"))) + = (struct mapi_table *) table_noop_array; + +__thread void *u_current_user + __attribute__((tls_model("initial-exec"))); + +#else + +struct mapi_table *u_current_table = + (struct mapi_table *) table_noop_array; +void *u_current_user; + +#ifdef THREADS +struct u_tsd u_current_table_tsd; +static struct u_tsd u_current_user_tsd; +static int ThreadSafe; +#endif /* THREADS */ + +#endif /* defined(GLX_USE_TLS) */ +/*@}*/ + + +void +u_current_destroy(void) +{ +#if defined(THREADS) && defined(_WIN32) + u_tsd_destroy(&u_current_table_tsd); + u_tsd_destroy(&u_current_user_tsd); +#endif +} + + +#if defined(THREADS) && !defined(GLX_USE_TLS) + +static void +u_current_init_tsd(void) +{ + u_tsd_init(&u_current_table_tsd); + u_tsd_init(&u_current_user_tsd); +} + +/** + * Mutex for multithread check. + */ +u_mutex_declare_static(ThreadCheckMutex); + +/** + * We should call this periodically from a function such as glXMakeCurrent + * in order to test if multiple threads are being used. + */ +void +u_current_init(void) +{ + static unsigned long knownID; + static int firstCall = 1; + + if (ThreadSafe) + return; + + u_mutex_lock(ThreadCheckMutex); + if (firstCall) { + u_current_init_tsd(); + + knownID = u_thread_self(); + firstCall = 0; + } + else if (knownID != u_thread_self()) { + ThreadSafe = 1; + u_current_set(NULL); + u_current_set_user(NULL); + } + u_mutex_unlock(ThreadCheckMutex); +} + +#else + +void +u_current_init(void) +{ +} + +#endif + + + +/** + * Set the current context pointer for this thread. + * The context pointer is an opaque type which should be cast to + * void from the real context pointer type. + */ +void +u_current_set_user(const void *ptr) +{ + u_current_init(); + +#if defined(GLX_USE_TLS) + u_current_user = (void *) ptr; +#elif defined(THREADS) + u_tsd_set(&u_current_user_tsd, (void *) ptr); + u_current_user = (ThreadSafe) ? NULL : (void *) ptr; +#else + u_current_user = (void *) ptr; +#endif +} + +/** + * Get the current context pointer for this thread. + * The context pointer is an opaque type which should be cast from + * void to the real context pointer type. + */ +void * +u_current_get_user_internal(void) +{ +#if defined(GLX_USE_TLS) + return u_current_user; +#elif defined(THREADS) + return (ThreadSafe) + ? u_tsd_get(&u_current_user_tsd) + : u_current_user; +#else + return u_current_user; +#endif +} + +/** + * Set the global or per-thread dispatch table pointer. + * If the dispatch parameter is NULL we'll plug in the no-op dispatch + * table (__glapi_noop_table). + */ +void +u_current_set(const struct mapi_table *tbl) +{ + u_current_init(); + + stub_init_once(); + + if (!tbl) + tbl = (const struct mapi_table *) table_noop_array; + +#if defined(GLX_USE_TLS) + u_current_table = (struct mapi_table *) tbl; +#elif defined(THREADS) + u_tsd_set(&u_current_table_tsd, (void *) tbl); + u_current_table = (ThreadSafe) ? NULL : (void *) tbl; +#else + u_current_table = (struct mapi_table *) tbl; +#endif +} + +/** + * Return pointer to current dispatch table for calling thread. + */ +struct mapi_table * +u_current_get_internal(void) +{ +#if defined(GLX_USE_TLS) + return u_current_table; +#elif defined(THREADS) + return (struct mapi_table *) ((ThreadSafe) ? + u_tsd_get(&u_current_table_tsd) : (void *) u_current_table); +#else + return u_current_table; +#endif +} diff --git a/src/mapi/u_current.h b/src/mapi/u_current.h new file mode 100644 index 00000000000..f9cffd8c3d0 --- /dev/null +++ b/src/mapi/u_current.h @@ -0,0 +1,87 @@ +#ifndef _U_CURRENT_H_ +#define _U_CURRENT_H_ + +#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \ + defined(MAPI_MODE_BRIDGE) + +#include "glapi/glapi.h" + +/* ugly renames to match glapi.h */ +#define mapi_table _glapi_table + +#ifdef GLX_USE_TLS +#define u_current_table _glapi_tls_Dispatch +#define u_current_user _glapi_tls_Context +#else +#define u_current_table _glapi_Dispatch +#define u_current_user _glapi_Context +#endif + +#define u_current_get_internal _glapi_get_dispatch +#define u_current_get_user_internal _glapi_get_context + +#define u_current_table_tsd _gl_DispatchTSD + +#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */ + +#include "u_compiler.h" + +struct mapi_table; + +#ifdef GLX_USE_TLS + +extern __thread struct mapi_table *u_current_table + __attribute__((tls_model("initial-exec"))); + +extern __thread void *u_current_user + __attribute__((tls_model("initial-exec"))); + +#else /* GLX_USE_TLS */ + +extern struct mapi_table *u_current_table; +extern void *u_current_user; + +#endif /* GLX_USE_TLS */ + +#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */ + +void +u_current_init(void); + +void +u_current_destroy(void); + +void +u_current_set(const struct mapi_table *tbl); + +struct mapi_table * +u_current_get_internal(void); + +void +u_current_set_user(const void *ptr); + +void * +u_current_get_user_internal(void); + +static INLINE const struct mapi_table * +u_current_get(void) +{ +#ifdef GLX_USE_TLS + return u_current_table; +#else + return (likely(u_current_table) ? + u_current_table : u_current_get_internal()); +#endif +} + +static INLINE const void * +u_current_get_user(void) +{ +#ifdef GLX_USE_TLS + return u_current_user; +#else + return likely(u_current_user) ? u_current_user : u_current_get_user_internal(); +#endif +} + +#endif /* _U_CURRENT_H_ */ diff --git a/src/mapi/u_execmem.c b/src/mapi/u_execmem.c new file mode 100644 index 00000000000..e5072e06e9a --- /dev/null +++ b/src/mapi/u_execmem.c @@ -0,0 +1,145 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + + +/** + * \file glapi_execmem.c + * + * Function for allocating executable memory for dispatch stubs. + * + * Copied from main/execmem.c and simplified for dispatch stubs. + */ + + +#include "u_compiler.h" +#include "u_thread.h" +#include "u_execmem.h" + + +#define EXEC_MAP_SIZE (4*1024) + +u_mutex_declare_static(exec_mutex); + +static unsigned int head = 0; + +static unsigned char *exec_mem = (unsigned char *)0; + + +#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) + +#include +#include + +#ifdef MESA_SELINUX +#include +#endif + + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + + +/* + * Dispatch stubs are of fixed size and never freed. Thus, we do not need to + * overlay a heap, we just mmap a page and manage through an index. + */ + +static int +init_map(void) +{ +#ifdef MESA_SELINUX + if (is_selinux_enabled()) { + if (!security_get_boolean_active("allow_execmem") || + !security_get_boolean_pending("allow_execmem")) + return 0; + } +#endif + + if (!exec_mem) + exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + return (exec_mem != MAP_FAILED); +} + + +#elif defined(_WIN32) + +#include + + +/* + * Avoid Data Execution Prevention. + */ + +static int +init_map(void) +{ + exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + return (exec_mem != NULL); +} + + +#else + +#include + +static int +init_map(void) +{ + exec_mem = malloc(EXEC_MAP_SIZE); + + return (exec_mem != NULL); +} + + +#endif + +void * +u_execmem_alloc(unsigned int size) +{ + void *addr = NULL; + + u_mutex_lock(exec_mutex); + + if (!init_map()) + goto bail; + + /* free space check, assumes no integer overflow */ + if (head + size > EXEC_MAP_SIZE) + goto bail; + + /* allocation, assumes proper addr and size alignement */ + addr = exec_mem + head; + head += size; + +bail: + u_mutex_unlock(exec_mutex); + + return addr; +} + + diff --git a/src/mapi/u_execmem.h b/src/mapi/u_execmem.h new file mode 100644 index 00000000000..13fff8df225 --- /dev/null +++ b/src/mapi/u_execmem.h @@ -0,0 +1,7 @@ +#ifndef _U_EXECMEM_H_ +#define _U_EXECMEM_H_ + +void * +u_execmem_alloc(unsigned int size); + +#endif /* _U_EXECMEM_H_ */ diff --git a/src/mapi/u_macros.h b/src/mapi/u_macros.h new file mode 100644 index 00000000000..72345b5f156 --- /dev/null +++ b/src/mapi/u_macros.h @@ -0,0 +1,12 @@ +#ifndef _U_MACROS_ +#define _U_MACROS_ + +#define _U_STRINGIFY(x) #x +#define _U_CONCAT(x, y) x ## y +#define _U_CONCAT_STR(x, y) #x#y + +#define U_STRINGIFY(x) _U_STRINGIFY(x) +#define U_CONCAT(x, y) _U_CONCAT(x, y) +#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y) + +#endif /* _U_MACROS_ */ diff --git a/src/mapi/u_thread.h b/src/mapi/u_thread.h new file mode 100644 index 00000000000..a5e5043701f --- /dev/null +++ b/src/mapi/u_thread.h @@ -0,0 +1,287 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * Modified for use in mapi by Chia-I Wu + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef _U_THREAD_H_ +#define _U_THREAD_H_ + +#include +#include +#include "u_compiler.h" + +#if defined(HAVE_PTHREAD) +#include /* POSIX threads headers */ +#endif +#ifdef _WIN32 +#include +#endif + +#if defined(HAVE_PTHREAD) || defined(_WIN32) +#ifndef THREADS +#define THREADS +#endif +#endif + +/* + * Error messages + */ +#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" +#define GET_TSD_ERROR "_glthread_: failed to get thread specific data" +#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" + + +/* + * Magic number to determine if a TSD object has been initialized. + * Kind of a hack but there doesn't appear to be a better cross-platform + * solution. + */ +#define INIT_MAGIC 0xff8adc98 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(HAVE_PTHREAD) + +struct u_tsd { + pthread_key_t key; + unsigned initMagic; +}; + +typedef pthread_mutex_t u_mutex; + +#define u_mutex_declare_static(name) \ + static u_mutex name = PTHREAD_MUTEX_INITIALIZER + +#define u_mutex_init(name) pthread_mutex_init(&(name), NULL) +#define u_mutex_destroy(name) pthread_mutex_destroy(&(name)) +#define u_mutex_lock(name) (void) pthread_mutex_lock(&(name)) +#define u_mutex_unlock(name) (void) pthread_mutex_unlock(&(name)) + +static INLINE unsigned long +u_thread_self(void) +{ + return (unsigned long) pthread_self(); +} + + +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + return pthread_getspecific(tsd->key); +} + + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + if (pthread_setspecific(tsd->key, ptr) != 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* HAVE_PTHREAD */ + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef _WIN32 + +struct u_tsd { + DWORD key; + unsigned initMagic; +}; + +typedef CRITICAL_SECTION u_mutex; + +/* http://locklessinc.com/articles/pthreads_on_windows/ */ +#define u_mutex_declare_static(name) \ + static u_mutex name = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0} + +#define u_mutex_init(name) InitializeCriticalSection(&name) +#define u_mutex_destroy(name) DeleteCriticalSection(&name) +#define u_mutex_lock(name) EnterCriticalSection(&name) +#define u_mutex_unlock(name) LeaveCriticalSection(&name) + +static INLINE unsigned long +u_thread_self(void) +{ + return GetCurrentThreadId(); +} + + +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + tsd->key = TlsAlloc(); + if (tsd->key == TLS_OUT_OF_INDEXES) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +static INLINE void +u_tsd_destroy(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + return; + } + TlsFree(tsd->key); + tsd->initMagic = 0x0; +} + + +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + return TlsGetValue(tsd->key); +} + + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + /* the following code assumes that the struct u_tsd has been initialized + to zero at creation */ + if (tsd->initMagic != INIT_MAGIC) { + u_tsd_init(tsd); + } + if (TlsSetValue(tsd->key, ptr) == 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* _WIN32 */ + + +/* + * THREADS not defined + */ +#ifndef THREADS + +struct u_tsd { + unsigned initMagic; +}; + +typedef unsigned u_mutex; + +#define u_mutex_declare_static(name) static u_mutex name = 0 +#define u_mutex_init(name) (void) name +#define u_mutex_destroy(name) (void) name +#define u_mutex_lock(name) (void) name +#define u_mutex_unlock(name) (void) name + +/* + * no-op functions + */ + +static INLINE unsigned long +u_thread_self(void) +{ + return 0; +} + + +static INLINE void +u_tsd_init(struct u_tsd *tsd) +{ + (void) tsd; +} + + +static INLINE void * +u_tsd_get(struct u_tsd *tsd) +{ + (void) tsd; + return NULL; +} + + +static INLINE void +u_tsd_set(struct u_tsd *tsd, void *ptr) +{ + (void) tsd; + (void) ptr; +} +#endif /* THREADS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _U_THREAD_H_ */ diff --git a/src/mapi/vgapi/Makefile.am b/src/mapi/vgapi/Makefile.am index 7d7c581236e..0af7115eb70 100644 --- a/src/mapi/vgapi/Makefile.am +++ b/src/mapi/vgapi/Makefile.am @@ -40,13 +40,13 @@ VG_include_HEADERS = \ lib_LTLIBRARIES = libOpenVG.la TOP=$(top_srcdir) -include ../mapi/Makefile.sources +include ../Makefile.sources libOpenVG_la_SOURCES = $(MAPI_FILES) vgapi_tmp.h libOpenVG_la_LIBADD = $(VG_LIB_DEPS) libOpenVG_la_LDFLAGS = -version-number 1 -no-undefined -vgapi_tmp.h: $(srcdir)/vgapi.csv $(top_srcdir)/src/mapi/mapi/mapi_abi.py - $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi/mapi_abi.py \ +vgapi_tmp.h: $(srcdir)/vgapi.csv $(top_srcdir)/src/mapi/mapi_abi.py + $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(top_srcdir)/src/mapi/mapi_abi.py \ --printer vgapi --mode lib $< > $@ BUILT_SOURCES = vgapi_tmp.h diff --git a/src/mapi/vgapi/SConscript b/src/mapi/vgapi/SConscript index fd4467bb231..63102c107ed 100644 --- a/src/mapi/vgapi/SConscript +++ b/src/mapi/vgapi/SConscript @@ -9,7 +9,7 @@ env = env.Clone() vgapi_header, = env.CodeGenerate( target = 'vgapi_tmp.h', - script = '../mapi/mapi_abi.py', + script = '../mapi_abi.py', source = 'vgapi.csv', command = python_cmd + ' $SCRIPT --printer vgapi --mode lib $SOURCE > $TARGET' ) @@ -37,7 +37,7 @@ mapi_sources = [ vgapi_objects = [] for s in mapi_sources: - o = env.SharedObject(s[:-2], '../mapi/' + s) + o = env.SharedObject(s[:-2], '../' + s) vgapi_objects.append(o) env.Depends(vgapi_objects, vgapi_header)