1#!/usr/bin/env ruby 2 3# Copyright 2019 Google LLC 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17require 'json' 18 19GRAMMAR = "../../external/spirv-headers/include/spirv/unified1/spirv.core.grammar.json" 20GLSL = "../../external/spirv-headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json" 21 22CAPABILITIES = %w( 23 Matrix 24 Shader 25 Sampled1D 26 Image1D 27 DerivativeControl 28 ImageQuery 29 VulkanMemoryModel 30) 31 32g = JSON.parse(File.open(GRAMMAR).read) 33magic = g['magic_number'] 34vers = [g['major_version'], g['minor_version']] 35instructions = {} 36 37g['instructions'].each do |inst| 38 if (inst.has_key?('capabilities')) 39 skip = true 40 inst['capabilities'].each do |cap| 41 if CAPABILITIES.include?(cap) 42 skip = false 43 break 44 end 45 end 46 next if skip 47 end 48 49 op = { 50 opcode: inst['opcode'], 51 operands: [] 52 } 53 54 if !inst['operands'].nil? 55 inst['operands'].each do |operand| 56 operand.delete('name') 57 op[:operands] << operand 58 end 59 end 60 61 instructions[inst['opname']] = op 62end 63 64operand_kinds = {} 65g['operand_kinds'].each do |op_kind| 66 next if op_kind['category'] !~ /Enum/ 67 68 kind = { 69 type: op_kind['category'], 70 values: {} 71 } 72 73 op_kind['enumerants'].each do |enum| 74 if (enum.has_key?('capabilities')) 75 skip = true 76 enum['capabilities'].each do |cap| 77 if CAPABILITIES.include?(cap) 78 skip = false 79 break 80 end 81 end 82 next if skip 83 end 84 85 v = if op_kind['category'] == 'BitEnum' 86 enum['value'].to_i(16) 87 else 88 enum['value'].to_i 89 end 90 params = [] 91 if enum.has_key?('parameters') 92 enum['parameters'].each do |param| 93 params << param['kind'] 94 end 95 end 96 kind[:values][enum['enumerant']] = {value: v} 97 kind[:values][enum['enumerant']][:params] = params unless params.empty? 98 end 99 100 next if kind[:values].empty? 101 operand_kinds[op_kind['kind']] = kind 102end 103 104# We only support GLSL extensions at the moment. 105ext = {} 106glsl = JSON.parse(File.open(GLSL).read) 107glsl['instructions'].each do |inst| 108 ext[inst['opname']] = inst['opcode'] 109end 110 111puts "/*#{g['copyright'].join("\n")}*/" 112puts "\n// THIS FILE IS GENERATED WITH tools/process_grammar.rb\n\n" 113puts "export default " + JSON.pretty_generate({ 114 magic: magic, 115 version: vers, 116 instructions: instructions, 117 operand_kinds: operand_kinds, 118 ext: ext 119}) 120