• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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