| #!/usr/bin/env ruby |
| |
| # Copyright 2019 Google LLC |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| require 'json' |
| |
| GRAMMAR = "../../external/spirv-headers/include/spirv/unified1/spirv.core.grammar.json" |
| GLSL = "../../external/spirv-headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json" |
| |
| CAPABILITIES = %w( |
| Matrix |
| Shader |
| Sampled1D |
| Image1D |
| DerivativeControl |
| ImageQuery |
| VulkanMemoryModel |
| ) |
| |
| g = JSON.parse(File.open(GRAMMAR).read) |
| magic = g['magic_number'] |
| vers = [g['major_version'], g['minor_version']] |
| instructions = {} |
| |
| g['instructions'].each do |inst| |
| if (inst.has_key?('capabilities')) |
| skip = true |
| inst['capabilities'].each do |cap| |
| if CAPABILITIES.include?(cap) |
| skip = false |
| break |
| end |
| end |
| next if skip |
| end |
| |
| op = { |
| opcode: inst['opcode'], |
| operands: [] |
| } |
| |
| if !inst['operands'].nil? |
| inst['operands'].each do |operand| |
| operand.delete('name') |
| op[:operands] << operand |
| end |
| end |
| |
| instructions[inst['opname']] = op |
| end |
| |
| operand_kinds = {} |
| g['operand_kinds'].each do |op_kind| |
| next if op_kind['category'] !~ /Enum/ |
| |
| kind = { |
| type: op_kind['category'], |
| values: {} |
| } |
| |
| op_kind['enumerants'].each do |enum| |
| if (enum.has_key?('capabilities')) |
| skip = true |
| enum['capabilities'].each do |cap| |
| if CAPABILITIES.include?(cap) |
| skip = false |
| break |
| end |
| end |
| next if skip |
| end |
| |
| v = if op_kind['category'] == 'BitEnum' |
| enum['value'].to_i(16) |
| else |
| enum['value'].to_i |
| end |
| params = [] |
| if enum.has_key?('parameters') |
| enum['parameters'].each do |param| |
| params << param['kind'] |
| end |
| end |
| kind[:values][enum['enumerant']] = {value: v} |
| kind[:values][enum['enumerant']][:params] = params unless params.empty? |
| end |
| |
| next if kind[:values].empty? |
| operand_kinds[op_kind['kind']] = kind |
| end |
| |
| # We only support GLSL extensions at the moment. |
| ext = {} |
| glsl = JSON.parse(File.open(GLSL).read) |
| glsl['instructions'].each do |inst| |
| ext[inst['opname']] = inst['opcode'] |
| end |
| |
| puts "/*#{g['copyright'].join("\n")}*/" |
| puts "\n// THIS FILE IS GENERATED WITH tools/process_grammar.rb\n\n" |
| puts "export default " + JSON.pretty_generate({ |
| magic: magic, |
| version: vers, |
| instructions: instructions, |
| operand_kinds: operand_kinds, |
| ext: ext |
| }) |