1848b8605Smrg
2848b8605Smrg# (C) Copyright IBM Corporation 2004, 2005
3848b8605Smrg# (C) Copyright Apple Inc. 2011
4b8e80941Smrg# Copyright (C) 2015 Intel Corporation
5848b8605Smrg# All Rights Reserved.
6848b8605Smrg#
7848b8605Smrg# Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg# copy of this software and associated documentation files (the "Software"),
9848b8605Smrg# to deal in the Software without restriction, including without limitation
10848b8605Smrg# on the rights to use, copy, modify, merge, publish, distribute, sub
11848b8605Smrg# license, and/or sell copies of the Software, and to permit persons to whom
12848b8605Smrg# the Software is furnished to do so, subject to the following conditions:
13848b8605Smrg#
14848b8605Smrg# The above copyright notice and this permission notice (including the next
15848b8605Smrg# paragraph) shall be included in all copies or substantial portions of the
16848b8605Smrg# Software.
17848b8605Smrg#
18848b8605Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19848b8605Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20848b8605Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
21848b8605Smrg# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22848b8605Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23848b8605Smrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24848b8605Smrg# IN THE SOFTWARE.
25848b8605Smrg#
26848b8605Smrg# Authors:
27848b8605Smrg#    Jeremy Huddleston <jeremyhu@apple.com>
28848b8605Smrg#
29848b8605Smrg# Based on code ogiginally by:
30848b8605Smrg#    Ian Romanick <idr@us.ibm.com>
31848b8605Smrg
32b8e80941Smrgfrom __future__ import print_function
33b8e80941Smrg
34b8e80941Smrgimport argparse
35b8e80941Smrg
36848b8605Smrgimport license
37848b8605Smrgimport gl_XML, glX_XML
38848b8605Smrg
39848b8605Smrgheader = """/* GLXEXT is the define used in the xserver when the GLX extension is being
40848b8605Smrg * built.  Hijack this to determine whether this file is being built for the
41848b8605Smrg * server or the client.
42848b8605Smrg */
43848b8605Smrg#ifdef HAVE_DIX_CONFIG_H
44848b8605Smrg#include <dix-config.h>
45848b8605Smrg#endif
46848b8605Smrg
47848b8605Smrg#if (defined(GLXEXT) && defined(HAVE_BACKTRACE)) \\
48b8e80941Smrg	|| (!defined(GLXEXT) && defined(DEBUG) && defined(HAVE_EXECINFO_H))
49848b8605Smrg#define USE_BACKTRACE
50848b8605Smrg#endif
51848b8605Smrg
52848b8605Smrg#ifdef USE_BACKTRACE
53848b8605Smrg#include <execinfo.h>
54848b8605Smrg#endif
55848b8605Smrg
56848b8605Smrg#ifndef _WIN32
57848b8605Smrg#include <dlfcn.h>
58848b8605Smrg#endif
59848b8605Smrg#include <stdlib.h>
60848b8605Smrg#include <stdio.h>
61b8e80941Smrg#include <string.h>
62848b8605Smrg
63848b8605Smrg#include "main/glheader.h"
64848b8605Smrg
65848b8605Smrg#include "glapi.h"
66848b8605Smrg#include "glapitable.h"
67848b8605Smrg
68848b8605Smrg#ifdef GLXEXT
69848b8605Smrg#include "os.h"
70848b8605Smrg#endif
71848b8605Smrg
72848b8605Smrgstatic void
73848b8605Smrg__glapi_gentable_NoOp(void) {
74848b8605Smrg    const char *fstr = "Unknown";
75848b8605Smrg
76848b8605Smrg    /* Silence potential GCC warning for some #ifdef paths.
77848b8605Smrg     */
78848b8605Smrg    (void) fstr;
79848b8605Smrg#if defined(USE_BACKTRACE)
80848b8605Smrg#if !defined(GLXEXT)
81848b8605Smrg    if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"))
82848b8605Smrg#endif
83848b8605Smrg    {
84848b8605Smrg        void *frames[2];
85848b8605Smrg
86848b8605Smrg        if(backtrace(frames, 2) == 2) {
87848b8605Smrg            Dl_info info;
88848b8605Smrg            dladdr(frames[1], &info);
89848b8605Smrg            if(info.dli_sname)
90848b8605Smrg                fstr = info.dli_sname;
91848b8605Smrg        }
92848b8605Smrg
93848b8605Smrg#if !defined(GLXEXT)
94848b8605Smrg        fprintf(stderr, "Call to unimplemented API: %s\\n", fstr);
95848b8605Smrg#endif
96848b8605Smrg    }
97848b8605Smrg#endif
98848b8605Smrg#if defined(GLXEXT)
99848b8605Smrg    LogMessage(X_ERROR, "GLX: Call to unimplemented API: %s\\n", fstr);
100848b8605Smrg#endif
101848b8605Smrg}
102848b8605Smrg
103848b8605Smrgstatic void
104848b8605Smrg__glapi_gentable_set_remaining_noop(struct _glapi_table *disp) {
105848b8605Smrg    GLuint entries = _glapi_get_dispatch_table_size();
106848b8605Smrg    void **dispatch = (void **) disp;
107b8e80941Smrg    unsigned i;
108848b8605Smrg
109848b8605Smrg    /* ISO C is annoying sometimes */
110848b8605Smrg    union {_glapi_proc p; void *v;} p;
111848b8605Smrg    p.p = __glapi_gentable_NoOp;
112848b8605Smrg
113848b8605Smrg    for(i=0; i < entries; i++)
114848b8605Smrg        if(dispatch[i] == NULL)
115848b8605Smrg            dispatch[i] = p.v;
116848b8605Smrg}
117848b8605Smrg
118b8e80941Smrg"""
119b8e80941Smrg
120b8e80941Smrgfooter = """
121848b8605Smrgstruct _glapi_table *
122848b8605Smrg_glapi_create_table_from_handle(void *handle, const char *symbol_prefix) {
123b8e80941Smrg    struct _glapi_table *disp = calloc(_glapi_get_dispatch_table_size(), sizeof(_glapi_proc));
124848b8605Smrg    char symboln[512];
125848b8605Smrg
126848b8605Smrg    if(!disp)
127848b8605Smrg        return NULL;
128848b8605Smrg
129848b8605Smrg    if(symbol_prefix == NULL)
130848b8605Smrg        symbol_prefix = "";
131848b8605Smrg
132b8e80941Smrg    /* Note: This code relies on _glapi_table_func_names being sorted by the
133b8e80941Smrg     * entry point index of each function.
134b8e80941Smrg     */
135b8e80941Smrg    for (int func_index = 0; func_index < GLAPI_TABLE_COUNT; ++func_index) {
136b8e80941Smrg        const char *name = _glapi_table_func_names[func_index];
137b8e80941Smrg        void ** procp = &((void **)disp)[func_index];
138848b8605Smrg
139b8e80941Smrg        snprintf(symboln, sizeof(symboln), \"%s%s\", symbol_prefix, name);
140848b8605Smrg#ifdef _WIN32
141848b8605Smrg        *procp = GetProcAddress(handle, symboln);
142848b8605Smrg#else
143848b8605Smrg        *procp = dlsym(handle, symboln);
144848b8605Smrg#endif
145848b8605Smrg    }
146b8e80941Smrg    __glapi_gentable_set_remaining_noop(disp);
147b8e80941Smrg
148b8e80941Smrg    return disp;
149b8e80941Smrg}
150b8e80941Smrg
151b8e80941Smrgvoid
152b8e80941Smrg _glapi_table_patch(struct _glapi_table *table, const char *name, void *wrapper)
153b8e80941Smrg{
154b8e80941Smrg   for (int func_index = 0; func_index < GLAPI_TABLE_COUNT; ++func_index) {
155b8e80941Smrg      if (!strcmp(_glapi_table_func_names[func_index], name)) {
156b8e80941Smrg            ((void **)table)[func_index] = wrapper;
157b8e80941Smrg            return;
158b8e80941Smrg         }
159b8e80941Smrg   }
160b8e80941Smrg   fprintf(stderr, "could not patch %s in dispatch table\\n", name);
161b8e80941Smrg}
162b8e80941Smrg
163848b8605Smrg"""
164848b8605Smrg
165b8e80941Smrg
166848b8605Smrgclass PrintCode(gl_XML.gl_print_base):
167848b8605Smrg
168848b8605Smrg    def __init__(self):
169848b8605Smrg        gl_XML.gl_print_base.__init__(self)
170848b8605Smrg
171b8e80941Smrg        self.name = "gl_gentable.py (from Mesa)"
172848b8605Smrg        self.license = license.bsd_license_template % ( \
173848b8605Smrg"""Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
174848b8605Smrg(C) Copyright IBM Corporation 2004, 2005
175848b8605Smrg(C) Copyright Apple Inc 2011""", "BRIAN PAUL, IBM")
176848b8605Smrg
177848b8605Smrg        return
178848b8605Smrg
179848b8605Smrg
180848b8605Smrg    def get_stack_size(self, f):
181848b8605Smrg        size = 0
182848b8605Smrg        for p in f.parameterIterator():
183848b8605Smrg            if p.is_padding:
184848b8605Smrg                continue
185848b8605Smrg
186848b8605Smrg            size += p.get_stack_size()
187848b8605Smrg
188848b8605Smrg        return size
189848b8605Smrg
190848b8605Smrg
191848b8605Smrg    def printRealHeader(self):
192b8e80941Smrg        print(header)
193848b8605Smrg        return
194848b8605Smrg
195848b8605Smrg
196848b8605Smrg    def printRealFooter(self):
197b8e80941Smrg        print(footer)
198848b8605Smrg        return
199848b8605Smrg
200848b8605Smrg
201848b8605Smrg    def printBody(self, api):
202848b8605Smrg
203b8e80941Smrg        # Determine how many functions have a defined offset.
204b8e80941Smrg        func_count = 0
205b8e80941Smrg        for f in api.functions_by_name.values():
206b8e80941Smrg            if f.offset != -1:
207b8e80941Smrg                func_count += 1
208b8e80941Smrg
209b8e80941Smrg        # Build the mapping from offset to function name.
210b8e80941Smrg        funcnames = [None] * func_count
211b8e80941Smrg        for f in api.functions_by_name.values():
212b8e80941Smrg            if f.offset != -1:
213b8e80941Smrg                if not (funcnames[f.offset] is None):
214b8e80941Smrg                    raise Exception("Function table has more than one function with same offset (offset %d, func %s)" % (f.offset, f.name))
215b8e80941Smrg                funcnames[f.offset] = f.name
216b8e80941Smrg
217b8e80941Smrg        # Check that the table has no gaps.  We expect a function at every offset,
218b8e80941Smrg        # and the code which generates the table relies on this.
219b8e80941Smrg        for i in range(0, func_count):
220b8e80941Smrg            if funcnames[i] is None:
221b8e80941Smrg                raise Exception("Function table has no function at offset %d" % (i))
222b8e80941Smrg
223b8e80941Smrg        print("#define GLAPI_TABLE_COUNT %d" % func_count)
224b8e80941Smrg        print("static const char * const _glapi_table_func_names[GLAPI_TABLE_COUNT] = {")
225b8e80941Smrg        for i in range(0, func_count):
226b8e80941Smrg            print("    /* %5d */ \"%s\"," % (i, funcnames[i]))
227b8e80941Smrg        print("};")
228b8e80941Smrg
229848b8605Smrg        return
230848b8605Smrg
231848b8605Smrg
232b8e80941Smrgdef _parser():
233b8e80941Smrg    """Parse arguments and return a namespace object."""
234b8e80941Smrg    parser = argparse.ArgumentParser()
235b8e80941Smrg    parser.add_argument('-f',
236b8e80941Smrg                        dest='filename',
237b8e80941Smrg                        default='gl_API.xml',
238b8e80941Smrg                        help='An XML file description of an API')
239b8e80941Smrg
240b8e80941Smrg    return parser.parse_args()
241848b8605Smrg
242848b8605Smrg
243b8e80941Smrgdef main():
244b8e80941Smrg    """Main function."""
245b8e80941Smrg    args = _parser()
246848b8605Smrg
247848b8605Smrg    printer = PrintCode()
248848b8605Smrg
249b8e80941Smrg    api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
250848b8605Smrg    printer.Print(api)
251b8e80941Smrg
252b8e80941Smrg
253b8e80941Smrgif __name__ == '__main__':
254b8e80941Smrg    main()
255