2 # Copyright (c) 2016 Google Inc.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 """Generates various info tables from SPIR-V JSON grammar."""
17 from __future__ import print_function
24 # Prefix for all C variables generated by this script.
25 PYGEN_VARIABLE_PREFIX = 'pygen_variable'
27 # Extensions to recognize, but which don't necessarily come from the SPIR-V
28 # core grammar. Get this list from the SPIR-V registery web page.
29 EXTENSIONS_FROM_SPIRV_REGISTRY = """
30 SPV_AMD_shader_explicit_vertex_parameter
31 SPV_AMD_shader_trinary_minmax
35 SPV_AMD_gpu_shader_half_float
36 SPV_KHR_shader_draw_parameters
41 SPV_NVX_multiview_per_view_attributes
42 SPV_NV_viewport_array2
43 SPV_NV_stereo_view_rendering
44 SPV_NV_sample_mask_override_coverage
45 SPV_NV_geometry_shader_passthrough
46 SPV_AMD_texture_gather_bias_lod
47 SPV_KHR_storage_buffer_storage_class
48 SPV_KHR_variable_pointers
49 SPV_AMD_gpu_shader_int16
50 SPV_KHR_post_depth_coverage
51 SPV_KHR_shader_atomic_counter_ops
52 SPV_EXT_shader_stencil_export
53 SPV_EXT_shader_viewport_index_layer
54 SPV_AMD_shader_image_load_store_lod
55 SPV_AMD_shader_fragment_mask
59 def make_path_to_file(f):
60 """Makes all ancestor directories to the given file, if they
64 f: The file whose ancestor directories are to be created.
66 dir = os.path.dirname(os.path.abspath(f))
70 if e.errno == errno.EEXIST and os.path.isdir(dir):
76 def compose_capability_list(caps):
77 """Returns a string containing a braced list of capabilities as enums.
80 - caps: a sequence of capability names
83 a string containing the braced list of SpvCapability* enums named by caps.
85 return "{" + ", ".join(['SpvCapability{}'.format(c) for c in caps]) + "}"
88 def get_capability_array_name(caps, version):
89 """Returns the name of the array containing all the given capabilities.
92 - caps: a sequence of capability names
97 return '{}_caps_{}_{}'.format(
98 PYGEN_VARIABLE_PREFIX, ''.join(caps), version)
101 def generate_capability_arrays(caps, version):
102 """Returns the arrays of capabilities.
105 - caps: a sequence of sequence of capability names
107 caps = sorted(set([tuple(c) for c in caps if c]))
109 'static const SpvCapability {}[] = {};'.format(
110 get_capability_array_name(c, version), compose_capability_list(c))
112 return '\n'.join(arrays)
115 def compose_extension_list(exts):
116 """Returns a string containing a braced list of extensions as enums.
119 - exts: a sequence of extension names
122 a string containing the braced list of extensions named by exts.
124 return "{" + ", ".join(
125 ['libspirv::Extension::k{}'.format(e) for e in exts]) + "}"
128 def get_extension_array_name(extensions, version):
129 """Returns the name of the array containing all the given extensions.
132 - extensions: a sequence of extension names
137 return '{}_exts_{}_{}'.format(
138 PYGEN_VARIABLE_PREFIX, ''.join(extensions), version)
141 def generate_extension_arrays(extensions, version):
142 """Returns the arrays of extensions.
145 - caps: a sequence of sequence of extension names
147 extensions = sorted(set([tuple(e) for e in extensions if e]))
149 'static const libspirv::Extension {}[] = {};'.format(
150 get_extension_array_name(e, version), compose_extension_list(e))
152 return '\n'.join(arrays)
155 def convert_operand_kind(operand_tuple):
156 """Returns the corresponding operand type used in spirv-tools for
157 the given operand kind and quantifier used in the JSON grammar.
160 - operand_tuple: a tuple of two elements:
161 - operand kind: used in the JSON grammar
162 - quantifier: '', '?', or '*'
165 a string of the enumerant name in spv_operand_type_t
167 kind, quantifier = operand_tuple
168 # The following cases are where we differ between the JSON grammar and
170 if kind == 'IdResultType':
172 elif kind == 'IdResult':
174 elif kind == 'IdMemorySemantics' or kind == 'MemorySemantics':
175 kind = 'MemorySemanticsId'
176 elif kind == 'IdScope' or kind == 'Scope':
178 elif kind == 'IdRef':
181 elif kind == 'ImageOperands':
184 kind = 'Dimensionality'
185 elif kind == 'ImageFormat':
186 kind = 'SamplerImageFormat'
187 elif kind == 'KernelEnqueueFlags':
188 kind = 'KernelEnqFlags'
190 elif kind == 'LiteralExtInstInteger':
191 kind = 'ExtensionInstructionNumber'
192 elif kind == 'LiteralSpecConstantOpInteger':
193 kind = 'SpecConstantOpNumber'
194 elif kind == 'LiteralContextDependentNumber':
195 kind = 'TypedLiteralNumber'
197 elif kind == 'PairLiteralIntegerIdRef':
198 kind = 'LiteralIntegerId'
199 elif kind == 'PairIdRefLiteralInteger':
200 kind = 'IdLiteralInteger'
201 elif kind == 'PairIdRefIdRef': # Used by OpPhi in the grammar
204 if kind == 'FPRoundingMode':
205 kind = 'FpRoundingMode'
206 elif kind == 'FPFastMathMode':
207 kind = 'FpFastMathMode'
209 if quantifier == '?':
210 kind = 'Optional{}'.format(kind)
211 elif quantifier == '*':
212 kind = 'Variable{}'.format(kind)
214 return 'SPV_OPERAND_TYPE_{}'.format(
215 re.sub(r'([a-z])([A-Z])', r'\1_\2', kind).upper())
218 class InstInitializer(object):
219 """Instances holds a SPIR-V instruction suitable for printing as
220 the initializer for spv_opcode_desc_t."""
222 def __init__(self, opname, caps, operands, version):
226 - opname: opcode name (with the 'Op' prefix)
227 - caps: a sequence of capability names required by this opcode
228 - operands: a sequence of (operand-kind, operand-quantifier) tuples
229 - version: version of the instruction set
231 assert opname.startswith('Op')
232 self.opname = opname[2:] # Remove the "Op" prefix.
233 self.num_caps = len(caps)
234 self.caps_mask = get_capability_array_name(caps, version)
235 self.operands = [convert_operand_kind(o) for o in operands]
239 operands = [o[0] for o in operands]
240 self.ref_type_id = 'IdResultType' in operands
241 self.def_result_id = 'IdResult' in operands
243 def fix_syntax(self):
244 """Fix an instruction's syntax, adjusting for differences between
245 the officially released grammar and how SPIRV-Tools uses the grammar.
248 - ExtInst should not end with SPV_OPERAND_VARIABLE_ID.
249 https://github.com/KhronosGroup/SPIRV-Tools/issues/233
251 if (self.opname == 'ExtInst'
252 and self.operands[-1] == 'SPV_OPERAND_TYPE_VARIABLE_ID'):
256 template = ['{{"{opname}"', 'SpvOp{opname}',
257 '{num_caps}', '{caps_mask}',
258 '{num_operands}', '{{{operands}}}',
259 '{def_result_id}', '{ref_type_id}}}']
260 return ', '.join(template).format(
262 num_caps=self.num_caps,
263 caps_mask=self.caps_mask,
264 num_operands=len(self.operands),
265 operands=', '.join(self.operands),
266 def_result_id=(1 if self.def_result_id else 0),
267 ref_type_id=(1 if self.ref_type_id else 0))
270 class ExtInstInitializer(object):
271 """Instances holds a SPIR-V extended instruction suitable for printing as
272 the initializer for spv_ext_inst_desc_t."""
274 def __init__(self, opname, opcode, caps, operands, version):
278 - opname: opcode name
279 - opcode: enumerant value for this opcode
280 - caps: a sequence of capability names required by this opcode
281 - operands: a sequence of (operand-kind, operand-quantifier) tuples
282 - version: version of the extended instruction set
286 self.num_caps = len(caps)
287 self.caps_mask = get_capability_array_name(caps, version)
288 self.operands = [convert_operand_kind(o) for o in operands]
289 self.operands.append('SPV_OPERAND_TYPE_NONE')
292 template = ['{{"{opname}"', '{opcode}', '{num_caps}', '{caps_mask}',
294 return ', '.join(template).format(
297 num_caps=self.num_caps,
298 caps_mask=self.caps_mask,
299 operands=', '.join(self.operands))
302 def generate_instruction(inst, version, is_ext_inst):
303 """Returns the C initializer for the given SPIR-V instruction.
306 - inst: a dict containing information about a SPIR-V instruction
307 - is_ext_inst: a bool indicating whether |inst| is an extended
311 a string containing the C initializer for spv_opcode_desc_t or
314 opname = inst.get('opname')
315 opcode = inst.get('opcode')
316 caps = inst.get('capabilities', [])
317 operands = inst.get('operands', {})
318 operands = [(o['kind'], o.get('quantifier', '')) for o in operands]
320 assert opname is not None
323 return str(ExtInstInitializer(opname, opcode, caps, operands, version))
325 return str(InstInitializer(opname, caps, operands, version))
328 def generate_instruction_table(inst_table, version):
329 """Returns the info table containing all SPIR-V instructions,
330 sorted by opcode, and prefixed by capability arrays.
333 - the built-in sorted() function is guaranteed to be stable.
334 https://docs.python.org/3/library/functions.html#sorted
337 - inst_table: a list containing all SPIR-V instructions.
338 - vesion: SPIR-V version.
340 inst_table = sorted(inst_table, key=lambda k: k['opcode'])
341 caps_arrays = generate_capability_arrays(
342 [inst.get('capabilities', []) for inst in inst_table], version)
343 insts = [generate_instruction(inst, version, False) for inst in inst_table]
344 insts = ['static const spv_opcode_desc_t kOpcodeTableEntries_{}[] = {{\n'
345 ' {}\n}};'.format(version, ',\n '.join(insts))]
347 return '{}\n\n{}'.format(caps_arrays, '\n'.join(insts))
350 def generate_extended_instruction_table(inst_table, set_name, version):
351 """Returns the info table containing all SPIR-V extended instructions,
352 sorted by opcode, and prefixed by capability arrays.
355 - inst_table: a list containing all SPIR-V instructions.
356 - set_name: the name of the extended instruction set.
358 inst_table = sorted(inst_table, key=lambda k: k['opcode'])
359 caps = [inst.get('capabilities', []) for inst in inst_table]
360 caps_arrays = generate_capability_arrays(caps, version)
361 insts = [generate_instruction(inst, version, True) for inst in inst_table]
362 insts = ['static const spv_ext_inst_desc_t {}_entries[] = {{\n'
363 ' {}\n}};'.format(set_name, ',\n '.join(insts))]
365 return '{}\n\n{}'.format(caps_arrays, '\n'.join(insts))
368 class EnumerantInitializer(object):
369 """Prints an enumerant as the initializer for spv_operand_desc_t."""
371 def __init__(self, enumerant, value, caps, exts, parameters, version):
375 - enumerant: enumerant name
376 - value: enumerant value
377 - caps: a sequence of capability names required by this enumerant
378 - exts: a sequence of names of extensions enabling this enumerant
379 - parameters: a sequence of (operand-kind, operand-quantifier) tuples
381 self.enumerant = enumerant
383 self.num_caps = len(caps)
384 self.caps = get_capability_array_name(caps, version)
385 self.num_exts = len(exts)
386 self.exts = get_extension_array_name(exts, version)
387 self.parameters = [convert_operand_kind(p) for p in parameters]
390 template = ['{{"{enumerant}"', '{value}', '{num_caps}',
391 '{caps}', '{num_exts}', '{exts}', '{{{parameters}}}}}']
392 return ', '.join(template).format(
393 enumerant=self.enumerant,
395 num_caps=self.num_caps,
397 num_exts=self.num_exts,
399 parameters=', '.join(self.parameters))
402 def generate_enum_operand_kind_entry(entry, version):
403 """Returns the C initializer for the given operand enum entry.
406 - entry: a dict containing information about an enum entry
409 a string containing the C initializer for spv_operand_desc_t
411 enumerant = entry.get('enumerant')
412 value = entry.get('value')
413 caps = entry.get('capabilities', [])
414 exts = entry.get('extensions', [])
415 params = entry.get('parameters', [])
416 params = [p.get('kind') for p in params]
417 params = zip(params, [''] * len(params))
419 assert enumerant is not None
420 assert value is not None
422 return str(EnumerantInitializer(
423 enumerant, value, caps, exts, params, version))
426 def generate_enum_operand_kind(enum, version):
427 """Returns the C definition for the given operand kind."""
428 kind = enum.get('kind')
429 assert kind is not None
431 name = '{}_{}Entries_{}'.format(PYGEN_VARIABLE_PREFIX, kind, version)
432 entries = [' {}'.format(generate_enum_operand_kind_entry(e, version))
433 for e in enum.get('enumerants', [])]
435 template = ['static const spv_operand_desc_t {name}[] = {{',
437 entries = '\n'.join(template).format(
439 entries=',\n'.join(entries))
441 return kind, name, entries
444 def generate_operand_kind_table(enums, version):
445 """Returns the info table containing all SPIR-V operand kinds."""
446 # We only need to output info tables for those operand kinds that are enums.
447 enums = [e for e in enums if e.get('category') in ['ValueEnum', 'BitEnum']]
449 caps = [entry.get('capabilities', [])
451 for entry in enum.get('enumerants', [])]
452 caps_arrays = generate_capability_arrays(caps, version)
454 exts = [entry.get('extensions', [])
456 for entry in enum.get('enumerants', [])]
457 exts_arrays = generate_extension_arrays(exts, version)
459 enums = [generate_enum_operand_kind(e, version) for e in enums]
460 # We have three operand kinds that requires their optional counterpart to
461 # exist in the operand info table.
462 three_optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess']
463 three_optional_enums = [e for e in enums if e[0] in three_optional_enums]
464 enums.extend(three_optional_enums)
466 enum_kinds, enum_names, enum_entries = zip(*enums)
467 # Mark the last three as optional ones.
468 enum_quantifiers = [''] * (len(enums) - 3) + ['?'] * 3
469 # And we don't want redefinition of them.
470 enum_entries = enum_entries[:-3]
471 enum_kinds = [convert_operand_kind(e)
472 for e in zip(enum_kinds, enum_quantifiers)]
473 table_entries = zip(enum_kinds, enum_names, enum_names)
474 table_entries = [' {{{}, ARRAY_SIZE({}), {}}}'.format(*e)
475 for e in table_entries]
478 'static const spv_operand_desc_group_t {p}_OperandInfoTable_{v}[] = {{',
480 table = '\n'.join(template).format(
481 p=PYGEN_VARIABLE_PREFIX, v=version, enums=',\n'.join(table_entries))
483 return '\n\n'.join((caps_arrays,) + (exts_arrays,) + enum_entries + (table,))
486 def get_extension_list(operands):
487 """Returns extensions as an alphabetically sorted list of strings."""
488 enumerants = sum([item.get('enumerants', []) for item in operands
489 if item.get('category') in ['ValueEnum']], [])
491 extensions = sum([item.get('extensions', []) for item in enumerants
492 if item.get('extensions')], [])
494 extensions.extend(EXTENSIONS_FROM_SPIRV_REGISTRY.split())
496 # Validator would ignore type declaration unique check. Should only be used
497 # for legacy autogenerated test files containing multiple instances of the
498 # same type declaration, if fixing the test by other methods is too
499 # difficult. Shouldn't be used for any other reasons.
500 extensions.append('SPV_VALIDATOR_ignore_type_decl_unique')
502 return sorted(set(extensions))
505 def get_capabilities(operands):
506 """Returns capabilities as a list of JSON objects, in order of
509 enumerants = sum([item.get('enumerants', []) for item in operands
510 if item.get('kind') in ['Capability']], [])
514 def generate_extension_enum(operands):
515 """Returns enumeration containing extensions declared in the grammar."""
516 extensions = get_extension_list(operands)
517 return ',\n'.join(['k' + extension for extension in extensions])
520 def generate_extension_to_string_table(operands):
521 """Returns extension to string mapping table."""
522 extensions = get_extension_list(operands)
523 entry_template = ' {{Extension::k{extension},\n "{extension}"}}'
524 table_entries = [entry_template.format(extension=extension)
525 for extension in extensions]
526 table_template = '{{\n{enums}\n}}'
527 return table_template.format(enums=',\n'.join(table_entries))
530 def generate_string_to_extension_table(operands):
531 """Returns string to extension mapping table."""
532 extensions = get_extension_list(operands)
533 entry_template = ' {{"{extension}",\n Extension::k{extension}}}'
534 table_entries = [entry_template.format(extension=extension)
535 for extension in extensions]
536 table_template = '{{\n{enums}\n}}'
537 return table_template.format(enums=',\n'.join(table_entries))
540 def generate_capability_to_string_table(operands):
541 """Returns capability to string mapping table."""
542 capabilities = [item.get('enumerant')
543 for item in get_capabilities(operands)]
544 entry_template = ' {{SpvCapability{capability},\n "{capability}"}}'
545 table_entries = [entry_template.format(capability=capability)
546 for capability in capabilities]
547 table_template = '{{\n{enums}\n}}'
548 return table_template.format(enums=',\n'.join(table_entries))
551 def generate_extension_to_string_mapping(operands):
552 """Returns mapping function from extensions to corresponding strings."""
553 extensions = get_extension_list(operands)
554 function = 'const char* ExtensionToString(Extension extension) {\n'
555 function += ' switch (extension) {\n'
556 template = ' case Extension::k{extension}:\n' \
557 ' return "{extension}";\n'
558 function += ''.join([template.format(extension=extension)
559 for extension in extensions])
560 function += ' };\n\n return "";\n}'
564 def generate_string_to_extension_mapping(operands):
565 """Returns mapping function from strings to corresponding extensions."""
566 extensions = get_extension_list(operands) # Already sorted
569 bool GetExtensionFromString(const char* str, Extension* extension) {{
570 static const char* known_ext_strs[] = {{ {strs} }};
571 static const Extension known_ext_ids[] = {{ {ids} }};
572 const auto b = std::begin(known_ext_strs);
573 const auto e = std::end(known_ext_strs);
574 const auto found = std::equal_range(
575 b, e, str, [](const char* str1, const char* str2) {{
576 return std::strcmp(str1, str2) < 0;
578 if (found.first == e || found.first == found.second) return false;
580 *extension = known_ext_ids[found.first - b];
583 '''.format(strs=', '.join(['"{}"'.format(e) for e in extensions]),
584 ids=', '.join(['Extension::k{}'.format(e) for e in extensions]))
589 def generate_capability_to_string_mapping(operands):
590 """Returns mapping function from capabilities to corresponding strings.
591 We take care to avoid emitting duplicate values.
593 function = 'const char* CapabilityToString(SpvCapability capability) {\n'
594 function += ' switch (capability) {\n'
595 template = ' case SpvCapability{capability}:\n' \
596 ' return "{capability}";\n'
597 emitted = set() # The values of capabilities we already have emitted
598 for capability in get_capabilities(operands):
599 value = capability.get('value')
600 if value not in emitted:
602 function += template.format(capability=capability.get('enumerant'))
603 function += ' case SpvCapabilityMax:\n' \
604 ' assert(0 && "Attempting to convert SpvCapabilityMax to string");\n' \
606 function += ' };\n\n return "";\n}'
610 def generate_all_string_enum_mappings(operands):
611 """Returns all string-to-enum / enum-to-string mapping tables."""
613 tables.append(generate_extension_to_string_mapping(operands))
614 tables.append(generate_string_to_extension_mapping(operands))
615 tables.append(generate_capability_to_string_mapping(operands))
616 return '\n\n'.join(tables)
621 parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
623 parser.add_argument('--spirv-core-grammar', metavar='<path>',
624 type=str, required=False,
625 help='input JSON grammar file for core SPIR-V '
627 parser.add_argument('--extinst-debuginfo-grammar', metavar='<path>',
628 type=str, required=False, default=None,
629 help='input JSON grammar file for DebugInfo extended '
631 parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
632 type=str, required=False, default=None,
633 help='input JSON grammar file for GLSL extended '
635 parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
636 type=str, required=False, default=None,
637 help='input JSON grammar file for OpenCL extended '
640 parser.add_argument('--core-insts-output', metavar='<path>',
641 type=str, required=False, default=None,
642 help='output file for core SPIR-V instructions')
643 parser.add_argument('--glsl-insts-output', metavar='<path>',
644 type=str, required=False, default=None,
645 help='output file for GLSL extended instruction set')
646 parser.add_argument('--opencl-insts-output', metavar='<path>',
647 type=str, required=False, default=None,
648 help='output file for OpenCL extended instruction set')
649 parser.add_argument('--operand-kinds-output', metavar='<path>',
650 type=str, required=False, default=None,
651 help='output file for operand kinds')
652 parser.add_argument('--extension-enum-output', metavar='<path>',
653 type=str, required=False, default=None,
654 help='output file for extension enumeration')
655 parser.add_argument('--enum-string-mapping-output', metavar='<path>',
656 type=str, required=False, default=None,
657 help='output file for enum-string mappings')
658 parser.add_argument('--extinst-vendor-grammar', metavar='<path>',
659 type=str, required=False, default=None,
660 help='input JSON grammar file for vendor extended '
662 parser.add_argument('--vendor-insts-output', metavar='<path>',
663 type=str, required=False, default=None,
664 help='output file for vendor extended instruction set')
665 args = parser.parse_args()
667 if (args.core_insts_output is None) != \
668 (args.operand_kinds_output is None):
669 print('error: --core-insts-output and --operand-kinds-output '
670 'should be specified together.')
672 if args.operand_kinds_output and not (args.spirv_core_grammar and args.extinst_debuginfo_grammar):
673 print('error: --operand-kinds-output requires --spirv-core-grammar '
674 'and --exinst-debuginfo-grammar')
676 if (args.glsl_insts_output is None) != \
677 (args.extinst_glsl_grammar is None):
678 print('error: --glsl-insts-output and --extinst-glsl-grammar '
679 'should be specified together.')
681 if (args.opencl_insts_output is None) != \
682 (args.extinst_opencl_grammar is None):
683 print('error: --opencl-insts-output and --extinst-opencl-grammar '
684 'should be specified together.')
686 if (args.vendor_insts_output is None) != \
687 (args.extinst_vendor_grammar is None):
688 print('error: --vendor-insts-output and '
689 '--extinst-vendor-grammar should be specified together.')
691 if all([args.core_insts_output is None,
692 args.glsl_insts_output is None,
693 args.opencl_insts_output is None,
694 args.vendor_insts_output is None,
695 args.extension_enum_output is None,
696 args.enum_string_mapping_output is None]):
697 print('error: at least one output should be specified.')
700 if args.spirv_core_grammar is not None:
701 with open(args.spirv_core_grammar) as json_file:
702 grammar = json.loads(json_file.read())
703 with open(args.extinst_debuginfo_grammar) as debuginfo_json_file:
704 debuginfo_grammar = json.loads(debuginfo_json_file.read())
705 operand_kinds = grammar['operand_kinds']
706 operand_kinds.extend(debuginfo_grammar['operand_kinds'])
707 if args.core_insts_output is not None:
708 make_path_to_file(args.core_insts_output)
709 make_path_to_file(args.operand_kinds_output)
710 version = '{}_{}'.format(grammar['major_version'],
711 grammar['minor_version'])
712 print(generate_instruction_table(
713 grammar['instructions'], version),
714 file=open(args.core_insts_output, 'w'))
715 print(generate_operand_kind_table(operand_kinds, version),
716 file=open(args.operand_kinds_output, 'w'))
717 if args.extension_enum_output is not None:
718 make_path_to_file(args.extension_enum_output)
719 print(generate_extension_enum(grammar['operand_kinds']),
720 file=open(args.extension_enum_output, 'w'))
721 if args.enum_string_mapping_output is not None:
722 make_path_to_file(args.enum_string_mapping_output)
723 print(generate_all_string_enum_mappings(operand_kinds),
724 file=open(args.enum_string_mapping_output, 'w'))
726 if args.extinst_glsl_grammar is not None:
727 with open(args.extinst_glsl_grammar) as json_file:
728 grammar = json.loads(json_file.read())
729 make_path_to_file(args.glsl_insts_output)
730 print(generate_extended_instruction_table(
731 grammar['instructions'], "glsl", "1_0"),
732 file=open(args.glsl_insts_output, 'w'))
734 if args.extinst_opencl_grammar is not None:
735 with open(args.extinst_opencl_grammar) as json_file:
736 grammar = json.loads(json_file.read())
737 make_path_to_file(args.opencl_insts_output)
738 print(generate_extended_instruction_table(
739 grammar['instructions'], "opencl", "1_0"),
740 file=open(args.opencl_insts_output, 'w'))
742 if args.extinst_vendor_grammar is not None:
743 with open(args.extinst_vendor_grammar) as json_file:
744 grammar = json.loads(json_file.read())
745 make_path_to_file(args.vendor_insts_output)
746 name = args.extinst_vendor_grammar
747 start = name.find("extinst.") + len("extinst.")
748 name = name[start:-len(".grammar.json")].replace("-", "_")
749 print(generate_extended_instruction_table(
750 grammar['instructions'], name, "1_0"),
751 file=open(args.vendor_insts_output, 'w'))
754 if __name__ == '__main__':