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
, getopt
34 from collections
import defaultdict
35 import get_hash_params
37 param_desc_file
= os
.path
.join(os
.path
.dirname(__file__
), "get_hash_params.py")
39 GLAPI
= os
.path
.join(os
.path
.dirname(__file__
), "..", "..", "mapi", "glapi", "gen")
40 sys
.path
.insert(0, GLAPI
)
45 hash_table_size
= 1024
47 gl_apis
=set(["GL", "GL_CORE", "GLES", "GLES2", "GLES3", "GLES31", "GLES32"])
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
72 'GLES32', # Not in gl_api enum in mtypes.h
76 return api_enum
.index(api
)
79 return "table_" + api_name(api
)
81 def print_table(api
, table
):
82 print("static table_t %s = {" % (table_name(api
)))
84 # convert sparse (index, value) table into a dense table
85 dense_table
= [0] * hash_table_size
90 for i
in range(0, hash_table_size
, row_size
):
91 row
= dense_table
[i
: i
+ row_size
]
92 idx_val
= ["%4d" % v
for v
in row
]
93 print(" " * 4 + ", ".join(idx_val
) + ",")
97 def print_tables(tables
):
99 print_table(table
["apis"][0], table
["indices"])
101 dense_tables
= ['NULL'] * len(api_enum
)
103 tname
= table_name(table
["apis"][0])
104 for api
in table
["apis"]:
106 dense_tables
[i
] = "&%s" % (tname
)
108 print("static table_t *table_set[] = {")
109 for expr
in dense_tables
:
113 print("#define table(api) (*table_set[api])")
115 # Merge tables with matching parameter lists (i.e. GL and GL_CORE)
116 def merge_tables(tables
):
118 for api
, indices
in sorted(tables
.items()):
119 matching_table
= list(filter(lambda mt
:mt
["indices"] == indices
,
122 matching_table
[0]["apis"].append(api
)
124 merged_tables
.append({"apis": [api
], "indices": indices
})
128 def add_to_hash_table(table
, hash_val
, value
):
130 index
= hash_val
& (hash_table_size
- 1)
131 if index
not in table
:
134 hash_val
+= prime_step
137 sys
.stderr
.write("%s: %s\n" % (program
, msg
))
140 program
= os
.path
.basename(sys
.argv
[0])
142 def generate_hash_tables(enum_list
, enabled_apis
, param_descriptors
):
143 tables
= defaultdict(lambda:{})
145 # the first entry should be invalid, so that get.c:find_value can use
146 # its index for the 'enum not found' condition.
149 for param_block
in param_descriptors
:
150 if set(["apis", "params"]) != set(param_block
):
151 die("missing fields (%s) in param descriptor file (%s)" %
152 (", ".join(set(["apis", "params"]) - set(param_block
)),
155 valid_apis
= set(param_block
["apis"])
156 if valid_apis
- gl_apis
:
157 die("unknown API(s) in param descriptor file (%s): %s\n" %
158 (param_desc_file
, ",".join(valid_apis
- gl_apis
)))
160 if not (valid_apis
& enabled_apis
):
163 valid_apis
&= enabled_apis
165 for param
in param_block
["params"]:
167 enum_val
= enum_list
[enum_name
].value
168 hash_val
= enum_val
* prime_factor
170 for api
in valid_apis
:
171 add_to_hash_table(tables
[api
], hash_val
, len(params
))
172 # Also add GLES2 items to the GLES3+ hash tables
174 add_to_hash_table(tables
["GLES3"], hash_val
, len(params
))
175 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
176 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
177 # Also add GLES3 items to the GLES31+ hash tables
179 add_to_hash_table(tables
["GLES31"], hash_val
, len(params
))
180 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
181 # Also add GLES31 items to the GLES32+ hash tables
183 add_to_hash_table(tables
["GLES32"], hash_val
, len(params
))
184 params
.append(["GL_" + enum_name
, param
[1]])
187 for api
, indices
in tables
.items():
188 sorted_tables
[api
] = sorted(indices
.items())
190 return params
, merge_tables(sorted_tables
)
195 """Usage: %s [OPTIONS]
196 -f <file> specify GL API XML file
200 if __name__
== '__main__':
202 (opts
, args
) = getopt
.getopt(sys
.argv
[1:], "f:")
211 for opt_name
, opt_val
in opts
:
213 api_desc_file
= opt_val
215 if not api_desc_file
:
216 die("missing descriptor file (-f)\n")
218 # generate the code for all APIs
219 enabled_apis
= set(["GLES", "GLES2", "GLES3", "GLES31", "GLES32",
223 api_desc
= gl_XML
.parse_GL_API(api_desc_file
)
225 die("couldn't parse API specification file %s\n" % api_desc_file
)
227 (params
, hash_tables
) = generate_hash_tables(api_desc
.enums_by_name
,
228 enabled_apis
, get_hash_params
.descriptor
)
232 print_tables(hash_tables
)