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", "GLES3"])
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
70 'GLES3', # Not in gl_api enum in mtypes.h
74 return api_enum
.index(api
)
77 return "table_" + api_name(api
)
79 def print_table(api
, table
):
80 print "static table_t %s = {" % (table_name(api
))
82 # convert sparse (index, value) table into a dense table
83 dense_table
= [0] * hash_table_size
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
) + ","
95 def print_tables(tables
):
97 print_table(table
["apis"][0], table
["indices"])
99 dense_tables
= ['NULL'] * len(api_enum
)
101 tname
= table_name(table
["apis"][0])
102 for api
in table
["apis"]:
104 dense_tables
[i
] = "&%s" % (tname
)
106 print "static table_t *table_set[] = {"
107 for expr
in dense_tables
:
111 print "#define table(api) (*table_set[api])"
113 # Merge tables with matching parameter lists (i.e. GL and GL_CORE)
114 def merge_tables(tables
):
116 for api
, indices
in sorted(tables
.items()):
117 matching_table
= filter(lambda mt
:mt
["indices"] == indices
,
120 matching_table
[0]["apis"].append(api
)
122 merged_tables
.append({"apis": [api
], "indices": indices
})
126 def add_to_hash_table(table
, hash_val
, value
):
128 index
= hash_val
& (hash_table_size
- 1)
129 if index
not in table
:
132 hash_val
+= prime_step
135 sys
.stderr
.write("%s: %s\n" % (program
, msg
))
138 program
= os
.path
.basename(sys
.argv
[0])
140 def generate_hash_tables(enum_list
, enabled_apis
, param_descriptors
):
141 tables
= defaultdict(lambda:{})
143 # the first entry should be invalid, so that get.c:find_value can use
144 # its index for the 'enum not found' condition.
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
)),
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
)))
158 if not (valid_apis
& enabled_apis
):
161 valid_apis
&= enabled_apis
163 for param
in param_block
["params"]:
165 enum_val
= enum_list
[enum_name
].value
166 hash_val
= enum_val
* prime_factor
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
172 add_to_hash_table(tables
["GLES3"], hash_val
, len(params
))
174 params
.append(["GL_" + enum_name
, param
[1]])
177 for api
, indices
in tables
.items():
178 sorted_tables
[api
] = sorted(indices
.items())
180 return params
, merge_tables(sorted_tables
)
185 """Usage: %s [OPTIONS]
186 -f <file> specify GL API XML file
190 if __name__
== '__main__':
192 (opts
, args
) = getopt
.getopt(sys
.argv
[1:], "f:")
201 for opt_name
, opt_val
in opts
:
203 api_desc_file
= opt_val
205 if not api_desc_file
:
206 die("missing descriptor file (-f)\n")
208 # generate the code for all APIs
209 enabled_apis
= set(["GLES", "GLES2", "GLES3", "GL", "GL_CORE"])
212 api_desc
= gl_XML
.parse_GL_API(api_desc_file
)
214 die("couldn't parse API specification file %s\n" % api_desc_file
)
216 (params
, hash_tables
) = generate_hash_tables(api_desc
.enums_by_name
,
217 enabled_apis
, get_hash_params
.descriptor
)
221 print_tables(hash_tables
)