3 # -*- Mode: Python; py-indent-offset: 4 -*-
5 # Copyright © 2012 Intel Corporation
7 # Based on code by Kristian Høgsberg <krh@bitplanet.net>,
8 # extracted from mesa/main/get.c
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:
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
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
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
32 import os
, sys
, imp
, getopt
33 from collections
import defaultdict
34 import get_hash_params
36 cur_dir
= os
.path
.dirname(sys
.argv
[0])
37 param_desc_file
= "%s/get_hash_params.py" % cur_dir
39 GLAPI
= "%s/../../mapi/glapi/gen" % cur_dir
40 sys
.path
.append(GLAPI
)
45 hash_table_size
= 1024
47 gl_apis
=set(["GL", "GL_CORE", "GLES", "GLES2"])
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
)
54 def print_params(params
):
55 print "static struct value_desc values[] = {"
57 print " { %s, %s }," % (p
[0], p
[1])
62 return "API_OPEN%s" % api
64 # This must match gl_api enum in src/mesa/main/mtypes.h
73 return api_enum
.index(api
)
76 return "table_" + api_name(api
)
78 def print_table(api
, table
):
79 print "static table_t %s = {" % (table_name(api
))
81 # convert sparse (index, value) table into a dense table
82 dense_table
= [0] * hash_table_size
87 for i
in range(0, hash_table_size
, row_size
):
88 row
= dense_table
[i
: i
+ row_size
]
89 idx_val
= ["%4d" % v
for v
in row
]
90 print " " * 4 + ", ".join(idx_val
) + ","
94 def print_tables(tables
):
96 print_table(table
["apis"][0], table
["indices"])
98 dense_tables
= ['NULL'] * len(api_enum
)
100 tname
= table_name(table
["apis"][0])
101 for api
in table
["apis"]:
103 dense_tables
[i
] = "&%s" % (tname
)
105 print "static table_t *table_set[] = {"
106 for expr
in dense_tables
:
110 print "#define table(api) (*table_set[api])"
112 # Merge tables with matching parameter lists (i.e. GL and GL_CORE)
113 def merge_tables(tables
):
115 for api
, indices
in sorted(tables
.items()):
116 matching_table
= filter(lambda mt
:mt
["indices"] == indices
,
119 matching_table
[0]["apis"].append(api
)
121 merged_tables
.append({"apis": [api
], "indices": indices
})
125 def add_to_hash_table(table
, hash_val
, value
):
127 index
= hash_val
& (hash_table_size
- 1)
128 if index
not in table
:
131 hash_val
+= prime_step
134 sys
.stderr
.write("%s: %s\n" % (program
, msg
))
137 program
= os
.path
.basename(sys
.argv
[0])
139 def generate_hash_tables(enum_list
, enabled_apis
, param_descriptors
):
140 tables
= defaultdict(lambda:{})
142 # the first entry should be invalid, so that get.c:find_value can use
143 # its index for the 'enum not found' condition.
146 for param_block
in param_descriptors
:
147 if set(["apis", "params"]) != set(param_block
):
148 die("missing fields (%s) in param descriptor file (%s)" %
149 (", ".join(set(["apis", "params"]) - set(param_block
)),
152 valid_apis
= set(param_block
["apis"])
153 if valid_apis
- gl_apis
:
154 die("unknown API(s) in param descriptor file (%s): %s\n" %
155 (param_desc_file
, ",".join(valid_apis
- gl_apis
)))
157 if not (valid_apis
& enabled_apis
):
160 valid_apis
&= enabled_apis
162 for param
in param_block
["params"]:
164 enum_val
= enum_list
[enum_name
].value
165 hash_val
= enum_val
* prime_factor
167 for api
in valid_apis
:
168 add_to_hash_table(tables
[api
], hash_val
, len(params
))
170 params
.append(["GL_" + enum_name
, param
[1]])
173 for api
, indices
in tables
.items():
174 sorted_tables
[api
] = sorted(indices
.items())
176 return params
, merge_tables(sorted_tables
)
178 def opt_to_apis(feature
):
179 _map
= {"ES1": "GLES", "ES2": "GLES2", "GL": "GL"}
180 if feature
not in _map
:
183 apis
= set([_map
[feature
]])
191 """Usage: %s [OPTIONS]
192 -f <file> specify GL API XML file
193 -a [GL|ES1|ES2] specify APIs to generate hash tables for
197 if __name__
== '__main__':
199 (opts
, args
) = getopt
.getopt(sys
.argv
[1:], "f:a:")
206 enabled_apis
= set([])
209 for opt_name
, opt_val
in opts
:
211 api_desc_file
= opt_val
213 apis
= opt_to_apis(opt_val
.upper())
215 die("invalid API %s\n" % opt_val
)
219 if not api_desc_file
:
220 die("missing descriptor file (-f)\n")
222 if len(enabled_apis
) == 0:
223 die("need at least a single enabled API\n")
226 api_desc
= gl_XML
.parse_GL_API(api_desc_file
)
228 die("couldn't parse API specification file %s\n" % api_desc_file
)
230 (params
, hash_tables
) = generate_hash_tables(api_desc
.enums_by_name
,
231 enabled_apis
, get_hash_params
.descriptor
)
235 print_tables(hash_tables
)