Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
#!/usr/bin/python2
2
# coding=utf-8
3
# -*- Mode: Python; py-indent-offset: 4 -*-
4
#
5
# Copyright © 2012 Intel Corporation
6
#
7
# Based on code by Kristian Høgsberg ,
8
#   extracted from mesa/main/get.c
9
#
10
# Permission is hereby granted, free of charge, to any person obtaining a
11
# copy of this software and associated documentation files (the "Software"),
12
# to deal in the Software without restriction, including without limitation
13
# on the rights to use, copy, modify, merge, publish, distribute, sub
14
# license, and/or sell copies of the Software, and to permit persons to whom
15
# the Software is furnished to do so, subject to the following conditions:
16
#
17
# The above copyright notice and this permission notice (including the next
18
# paragraph) shall be included in all copies or substantial portions of the
19
# Software.
20
#
21
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
24
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27
# IN THE SOFTWARE.
28
 
29
# Generate a C header file containing hash tables of glGet parameter
30
# names for each GL API. The generated file is to be included by glGet.c
31
 
32
import os, sys, imp, getopt
33
from collections import defaultdict
34
import get_hash_params
35
 
36
cur_dir = os.path.dirname(sys.argv[0])
37
param_desc_file = "%s/get_hash_params.py" % cur_dir
38
 
39
GLAPI = "%s/../../mapi/glapi/gen" % cur_dir
40
sys.path.append(GLAPI)
41
import gl_XML
42
 
43
prime_factor = 89
44
prime_step = 281
45
hash_table_size = 1024
46
 
47
gl_apis=set(["GL", "GL_CORE", "GLES", "GLES2", "GLES3"])
48
 
49
def print_header():
50
   print "typedef const unsigned short table_t[%d];\n" % (hash_table_size)
51
   print "static const int prime_factor = %d, prime_step = %d;\n" % \
52
          (prime_factor, prime_step)
53
 
54
def print_params(params):
55
   print "static const struct value_desc values[] = {"
56
   for p in params:
57
      print "    { %s, %s }," % (p[0], p[1])
58
 
59
   print "};\n"
60
 
61
def api_name(api):
62
   return "API_OPEN%s" % api
63
 
64
# This must match gl_api enum in src/mesa/main/mtypes.h
65
api_enum = [
66
   'GL',
67
   'GLES',
68
   'GLES2',
69
   'GL_CORE',
70
   'GLES3', # Not in gl_api enum in mtypes.h
71
]
72
 
73
def api_index(api):
74
    return api_enum.index(api)
75
 
76
def table_name(api):
77
   return "table_" + api_name(api)
78
 
79
def print_table(api, table):
80
   print "static table_t %s = {" % (table_name(api))
81
 
82
   # convert sparse (index, value) table into a dense table
83
   dense_table = [0] * hash_table_size
84
   for i, v in table:
85
      dense_table[i] = v
86
 
87
   row_size = 4
88
   for i in range(0, hash_table_size, row_size):
89
      row = dense_table[i : i + row_size]
90
      idx_val = ["%4d" % v for v in row]
91
      print " " * 4 + ", ".join(idx_val) + ","
92
 
93
   print "};\n"
94
 
95
def print_tables(tables):
96
   for table in tables:
97
      print_table(table["apis"][0], table["indices"])
98
 
99
   dense_tables = ['NULL'] * len(api_enum)
100
   for table in tables:
101
      tname = table_name(table["apis"][0])
102
      for api in table["apis"]:
103
         i = api_index(api)
104
         dense_tables[i] = "&%s" % (tname)
105
 
106
   print "static table_t *table_set[] = {"
107
   for expr in dense_tables:
108
      print "   %s," % expr
109
   print "};\n"
110
 
111
   print "#define table(api) (*table_set[api])"
112
 
113
# Merge tables with matching parameter lists (i.e. GL and GL_CORE)
114
def merge_tables(tables):
115
   merged_tables = []
116
   for api, indices in sorted(tables.items()):
117
      matching_table = filter(lambda mt:mt["indices"] == indices,
118
                              merged_tables)
119
      if matching_table:
120
         matching_table[0]["apis"].append(api)
121
      else:
122
         merged_tables.append({"apis": [api], "indices": indices})
123
 
124
   return merged_tables
125
 
126
def add_to_hash_table(table, hash_val, value):
127
   while True:
128
      index = hash_val & (hash_table_size - 1)
129
      if index not in table:
130
         table[index] = value
131
         break
132
      hash_val += prime_step
133
 
134
def die(msg):
135
   sys.stderr.write("%s: %s\n" % (program, msg))
136
   exit(1)
137
 
138
program = os.path.basename(sys.argv[0])
139
 
140
def generate_hash_tables(enum_list, enabled_apis, param_descriptors):
141
   tables = defaultdict(lambda:{})
142
 
143
   # the first entry should be invalid, so that get.c:find_value can use
144
   # its index for the 'enum not found' condition.
145
   params = [[0, ""]]
146
 
147
   for param_block in param_descriptors:
148
      if set(["apis", "params"]) != set(param_block):
149
         die("missing fields (%s) in param descriptor file (%s)" %
150
               (", ".join(set(["apis", "params"]) - set(param_block)),
151
                param_desc_file))
152
 
153
      valid_apis = set(param_block["apis"])
154
      if valid_apis - gl_apis:
155
         die("unknown API(s) in param descriptor file (%s): %s\n" %
156
               (param_desc_file, ",".join(valid_apis - gl_apis)))
157
 
158
      if not (valid_apis & enabled_apis):
159
         continue
160
 
161
      valid_apis &= enabled_apis
162
 
163
      for param in param_block["params"]:
164
         enum_name = param[0]
165
         enum_val = enum_list[enum_name].value
166
         hash_val = enum_val * prime_factor
167
 
168
         for api in valid_apis:
169
            add_to_hash_table(tables[api], hash_val, len(params))
170
            # Also add GLES2 items to the GLES3 hash table
171
            if api == "GLES2":
172
               add_to_hash_table(tables["GLES3"], hash_val, len(params))
173
 
174
         params.append(["GL_" + enum_name, param[1]])
175
 
176
   sorted_tables={}
177
   for api, indices in tables.items():
178
      sorted_tables[api] = sorted(indices.items())
179
 
180
   return params, merge_tables(sorted_tables)
181
 
182
 
183
def show_usage():
184
   sys.stderr.write(
185
"""Usage: %s [OPTIONS]
186
  -f           specify GL API XML file
187
""" % (program))
188
   exit(1)
189
 
190
if __name__ == '__main__':
191
   try:
192
      (opts, args) = getopt.getopt(sys.argv[1:], "f:")
193
   except Exception,e:
194
      show_usage()
195
 
196
   if len(args) != 0:
197
      show_usage()
198
 
199
   api_desc_file = ""
200
 
201
   for opt_name, opt_val in opts:
202
      if opt_name == "-f":
203
         api_desc_file = opt_val
204
 
205
   if not api_desc_file:
206
      die("missing descriptor file (-f)\n")
207
 
208
   # generate the code for all APIs
209
   enabled_apis = set(["GLES", "GLES2", "GLES3", "GL", "GL_CORE"])
210
 
211
   try:
212
      api_desc = gl_XML.parse_GL_API(api_desc_file)
213
   except Exception:
214
      die("couldn't parse API specification file %s\n" % api_desc_file)
215
 
216
   (params, hash_tables) = generate_hash_tables(api_desc.enums_by_name,
217
                              enabled_apis, get_hash_params.descriptor)
218
 
219
   print_header()
220
   print_params(params)
221
   print_tables(hash_tables)