2 # -*- Mode: Python; py-indent-offset: 4 -*-
4 # Copyright © 2012 Intel Corporation
6 # Based on code by Kristian Høgsberg <krh@bitplanet.net>,
7 # extracted from mesa/main/get.c
9 # Permission is hereby granted, free of charge, to any person obtaining a
10 # copy of this software and associated documentation files (the "Software"),
11 # to deal in the Software without restriction, including without limitation
12 # on the rights to use, copy, modify, merge, publish, distribute, sub
13 # license, and/or sell copies of the Software, and to permit persons to whom
14 # the Software is furnished to do so, subject to the following conditions:
16 # The above copyright notice and this permission notice (including the next
17 # paragraph) shall be included in all copies or substantial portions of the
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 # Generate a C header file containing hash tables of glGet parameter
29 # names for each GL API. The generated file is to be included by glGet.c
31 from __future__
import print_function
33 import os
, sys
, imp
, getopt
34 from collections
import defaultdict
35 import get_hash_params
37 cur_dir
= os
.path
.dirname(sys
.argv
[0])
38 param_desc_file
= "%s/get_hash_params.py" % cur_dir
40 GLAPI
= "%s/../../mapi/glapi/gen" % cur_dir
41 sys
.path
.append(GLAPI
)
46 hash_table_size
= 1024
48 gl_apis
=set(["GL", "GL_CORE", "GLES", "GLES2", "GLES3", "GLES31", "GLES32"])
51 print("typedef const unsigned short table_t[%d];\n" % (hash_table_size
))
52 print("static const int prime_factor = %d, prime_step = %d;\n" % \
53 (prime_factor
, prime_step
))
55 def print_params(params
):
56 print("static const struct value_desc values[] = {")
58 print(" { %s, %s }," % (p
[0], p
[1]))
63 return "API_OPEN%s" % api
65 # This must match gl_api enum in src/mesa/main/mtypes.h
71 'GLES3', # Not in gl_api enum in mtypes.h
72 'GLES31', # Not in gl_api enum in mtypes.h
73 'GLES32', # Not in gl_api enum in mtypes.h
77 return api_enum
.index(api
)
80 return "table_" + api_name(api
)
82 def print_table(api
, table
):
83 print("static table_t %s = {" % (table_name(api
)))
85 # convert sparse (index, value) table into a dense table
86 dense_table
= [0] * hash_table_size
91 for i
in range(0, hash_table_size
, row_size
):
92 row
= dense_table
[i
: i
+ row_size
]
93 idx_val
= ["%4d" % v
for v
in row
]
94 print(" " * 4 + ", ".join(idx_val
) + ",")
98 def print_tables(tables
):
100 print_table(table
["apis"][0], table
["indices"])
102 dense_tables
= ['NULL'] * len(api_enum
)
104 tname
= table_name(table
["apis"][0])
105 for api
in table
["apis"]:
107 dense_tables
[i
] = "&%s" % (tname
)
109 print("static table_t *table_set[] = {")
110 for expr
in dense_tables
:
114 print("#define table(api) (*table_set[api])")
116 # Merge tables with matching parameter lists (i.e. GL and GL_CORE)
117 def merge_tables(tables
):
119 for api
, indices
in sorted(tables
.items()):
120 matching_table
= filter(lambda mt
:mt
["indices"] == indices
,
123 matching_table
[0]["apis"].append(api
)
125 merged_tables
.append({"apis": [api
], "indices": indices
})
129 def add_to_hash_table(table
, hash_val
, value
):
131 index
= hash_val
& (hash_table_size
- 1)
132 if index
not in table
:
135 hash_val
+= prime_step
138 sys
.stderr
.write("%s: %s\n" % (program
, msg
))
141 program
= os
.path
.basename(sys
.argv
[0])
143 def generate_hash_tables(enum_list
, enabled_apis
, param_descriptors
):
144 tables
= defaultdict(lambda:{})
146 # the first entry should be invalid, so that get.c:find_value can use
147 # its index for the 'enum not found' condition.
150 for param_block
in param_descriptors
:
151 if set(["apis", "params"]) != set(param_block
):
152 die("missing fields (%s) in param descriptor file (%s)" %
153 (", ".join(set(["apis", "params"]) - set(param_block
)),
156 valid_apis
= set(param_block
["apis"])
157 if valid_apis
- gl_apis
:
158 die("unknown API(s) in param descriptor file (%s): %s\n" %
159 (param_desc_file
, ",".join(valid_apis
- gl_apis
)))
161 if not (valid_apis
& enabled_apis
):
164 valid_apis
&= enabled_apis
166 for param
in param_block
["params"]:
168 enum_val
= enum_list
[enum_name
].value
169 hash_val
= enum_val
* prime_factor
171 for api
in valid_apis
:
172 add_to_hash_table(tables
[api
], hash_val
, len(params
))
173 # Also add GLES2 items to the GLES3+ hash tables
175 add_to_hash_table(tables
["GLES3"], hash_val
, len(params
))
176 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
177 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
178 # Also add GLES3 items to the GLES31+ hash tables
180 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
181 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
182 # Also add GLES31 items to the GLES32+ hash tables
184 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
185 params
.append(["GL_" + enum_name
, param
[1]])
188 for api
, indices
in tables
.items():
189 sorted_tables
[api
] = sorted(indices
.items())
191 return params
, merge_tables(sorted_tables
)
196 """Usage: %s [OPTIONS]
197 -f <file> specify GL API XML file
201 if __name__
== '__main__':
203 (opts
, args
) = getopt
.getopt(sys
.argv
[1:], "f:")
212 for opt_name
, opt_val
in opts
:
214 api_desc_file
= opt_val
216 if not api_desc_file
:
217 die("missing descriptor file (-f)\n")
219 # generate the code for all APIs
220 enabled_apis
= set(["GLES", "GLES2", "GLES3", "GLES31", "GLES32",
224 api_desc
= gl_XML
.parse_GL_API(api_desc_file
)
226 die("couldn't parse API specification file %s\n" % api_desc_file
)
228 (params
, hash_tables
) = generate_hash_tables(api_desc
.enums_by_name
,
229 enabled_apis
, get_hash_params
.descriptor
)
233 print_tables(hash_tables
)