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", "GLES31"])
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 const 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
71 'GLES31', # Not in gl_api enum in mtypes.h
75 return api_enum
.index(api
)
78 return "table_" + api_name(api
)
80 def print_table(api
, table
):
81 print "static table_t %s = {" % (table_name(api
))
83 # convert sparse (index, value) table into a dense table
84 dense_table
= [0] * hash_table_size
89 for i
in range(0, hash_table_size
, row_size
):
90 row
= dense_table
[i
: i
+ row_size
]
91 idx_val
= ["%4d" % v
for v
in row
]
92 print " " * 4 + ", ".join(idx_val
) + ","
96 def print_tables(tables
):
98 print_table(table
["apis"][0], table
["indices"])
100 dense_tables
= ['NULL'] * len(api_enum
)
102 tname
= table_name(table
["apis"][0])
103 for api
in table
["apis"]:
105 dense_tables
[i
] = "&%s" % (tname
)
107 print "static table_t *table_set[] = {"
108 for expr
in dense_tables
:
112 print "#define table(api) (*table_set[api])"
114 # Merge tables with matching parameter lists (i.e. GL and GL_CORE)
115 def merge_tables(tables
):
117 for api
, indices
in sorted(tables
.items()):
118 matching_table
= filter(lambda mt
:mt
["indices"] == indices
,
121 matching_table
[0]["apis"].append(api
)
123 merged_tables
.append({"apis": [api
], "indices": indices
})
127 def add_to_hash_table(table
, hash_val
, value
):
129 index
= hash_val
& (hash_table_size
- 1)
130 if index
not in table
:
133 hash_val
+= prime_step
136 sys
.stderr
.write("%s: %s\n" % (program
, msg
))
139 program
= os
.path
.basename(sys
.argv
[0])
141 def generate_hash_tables(enum_list
, enabled_apis
, param_descriptors
):
142 tables
= defaultdict(lambda:{})
144 # the first entry should be invalid, so that get.c:find_value can use
145 # its index for the 'enum not found' condition.
148 for param_block
in param_descriptors
:
149 if set(["apis", "params"]) != set(param_block
):
150 die("missing fields (%s) in param descriptor file (%s)" %
151 (", ".join(set(["apis", "params"]) - set(param_block
)),
154 valid_apis
= set(param_block
["apis"])
155 if valid_apis
- gl_apis
:
156 die("unknown API(s) in param descriptor file (%s): %s\n" %
157 (param_desc_file
, ",".join(valid_apis
- gl_apis
)))
159 if not (valid_apis
& enabled_apis
):
162 valid_apis
&= enabled_apis
164 for param
in param_block
["params"]:
166 enum_val
= enum_list
[enum_name
].value
167 hash_val
= enum_val
* prime_factor
169 for api
in valid_apis
:
170 add_to_hash_table(tables
[api
], hash_val
, len(params
))
171 # Also add GLES2 items to the GLES3 and GLES31 hash table
173 add_to_hash_table(tables
["GLES3"], hash_val
, len(params
))
174 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
175 # Also add GLES3 items to the GLES31 hash table
177 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
178 params
.append(["GL_" + enum_name
, param
[1]])
181 for api
, indices
in tables
.items():
182 sorted_tables
[api
] = sorted(indices
.items())
184 return params
, merge_tables(sorted_tables
)
189 """Usage: %s [OPTIONS]
190 -f <file> specify GL API XML file
194 if __name__
== '__main__':
196 (opts
, args
) = getopt
.getopt(sys
.argv
[1:], "f:")
205 for opt_name
, opt_val
in opts
:
207 api_desc_file
= opt_val
209 if not api_desc_file
:
210 die("missing descriptor file (-f)\n")
212 # generate the code for all APIs
213 enabled_apis
= set(["GLES", "GLES2", "GLES3", "GLES31", "GL", "GL_CORE"])
216 api_desc
= gl_XML
.parse_GL_API(api_desc_file
)
218 die("couldn't parse API specification file %s\n" % api_desc_file
)
220 (params
, hash_tables
) = generate_hash_tables(api_desc
.enums_by_name
,
221 enabled_apis
, get_hash_params
.descriptor
)
225 print_tables(hash_tables
)