spirv-cross 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9d6331db8f6c8b94443ccd0bf40ebf7953ad3e2553b8bfcf5dc002e12bf0c385
4
+ data.tar.gz: 8f53d46776d479e96182259c930cfd2b288f20ab2615869a41365f82a6d33e09
5
+ SHA512:
6
+ metadata.gz: 65b1627f27bf19d1bafa8d67867c89f938369e60d35843bf3f42393cd35a320cd8bb52915647595377ec4978fee68cd15c36cb3b9a15e0d0411ca90464d449ce
7
+ data.tar.gz: d5f82285dcfae9b846ccb1b98ef1435d78e457f17b38dfeaa0a483df211f68c4836d5582af42c5d6670eca0940feeb0feb587f94af7ee4c98bf62c080a924b35
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.4.5
7
+ before_install: gem install bundler -v 1.17.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in spirv-cross.gemspec
6
+ gemspec
@@ -0,0 +1,25 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ spirv-cross (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.11.3)
10
+ rake (10.5.0)
11
+ rake-compiler (1.0.5)
12
+ rake
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ bundler (~> 1.17)
19
+ minitest (~> 5.0)
20
+ rake (~> 10.0)
21
+ rake-compiler
22
+ spirv-cross!
23
+
24
+ BUNDLED WITH
25
+ 1.17.1
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Colin MacKenzie IV
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,175 @@
1
+ # SPIRV::Cross
2
+
3
+ Provides Ruby bindings for [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'spirv-cross'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install spirv-cross
20
+
21
+ ## Usage
22
+
23
+ * **NOTE:** In addition to reflection,
24
+ [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) provides the ability
25
+ to compile a shader to other languages (GLSL, HLSL, C++, etc). However, that
26
+ functionality has not been exposed to Ruby by this gem as of this writing.
27
+ If this functionality is desired, [create an issue](https://github.com/sinisterchipmunk/spirv-cross-ruby/issues)
28
+ so that the need can be tracked. Or better yet, add it yourself and send a pull
29
+ request. (Unit tests, please.)
30
+
31
+ compiler = SPIRV::Cross::Compiler(File.open('path/to/shader', 'rb').read)
32
+
33
+ pp compiler.specialization_constants
34
+ #=> [{:constant_id=>20, :name=>"Const"}]
35
+
36
+ pp compiler.entry_points
37
+ #=> [{:name=>"main", :execution_model=>:vertex}]
38
+
39
+ pp compiler.shader_resources
40
+ #=> Hash containing all resources defined by this shader
41
+
42
+ pp compiler.active_shader_resources
43
+ #=> Hash containing only resources actually used by this shader
44
+
45
+ In both cases, the shader resources hash looks like:
46
+
47
+ {:uniform_buffers=>
48
+ [{:type=>:struct,
49
+ :width=>0,
50
+ :vecsize=>1,
51
+ :columns=>1,
52
+ :is_pointer=>true,
53
+ :storage_class=>:uniform,
54
+ :members=>
55
+ [{:type=>:float,
56
+ :width=>32,
57
+ :vecsize=>4,
58
+ :columns=>4,
59
+ :is_pointer=>false,
60
+ :storage_class=>:generic,
61
+ :members=>[],
62
+ :size=>64,
63
+ :offset=>0,
64
+ :matrix_stride=>16,
65
+ :name=>"model"},
66
+ {:type=>:float,
67
+ :width=>32,
68
+ :vecsize=>4,
69
+ :columns=>4,
70
+ :is_pointer=>false,
71
+ :storage_class=>:generic,
72
+ :members=>[],
73
+ :size=>64,
74
+ :offset=>64,
75
+ :matrix_stride=>16,
76
+ :name=>"view"},
77
+ {:type=>:float,
78
+ :width=>32,
79
+ :vecsize=>4,
80
+ :columns=>4,
81
+ :is_pointer=>false,
82
+ :storage_class=>:generic,
83
+ :members=>[],
84
+ :size=>64,
85
+ :offset=>128,
86
+ :matrix_stride=>16,
87
+ :name=>"proj"}],
88
+ :active_buffer_ranges=>
89
+ [{:index=>2, :offset=>128, :size=>64},
90
+ {:index=>1, :offset=>64, :size=>64},
91
+ {:index=>0, :offset=>0, :size=>64}],
92
+ :array_sizes=>[],
93
+ :name=>"UniformBufferObject",
94
+ :descriptor_set=>0,
95
+ :binding=>0,
96
+ :block_size=>192}],
97
+ :storage_buffers=>[],
98
+ :stage_inputs=>
99
+ [{:type=>:float,
100
+ :width=>32,
101
+ :vecsize=>3,
102
+ :columns=>1,
103
+ :is_pointer=>true,
104
+ :storage_class=>:input,
105
+ :members=>[],
106
+ :active_buffer_ranges=>[],
107
+ :array_sizes=>[],
108
+ :name=>"inPosition",
109
+ :location=>0},
110
+ {:type=>:float,
111
+ :width=>32,
112
+ :vecsize=>3,
113
+ :columns=>1,
114
+ :is_pointer=>true,
115
+ :storage_class=>:input,
116
+ :members=>[],
117
+ :active_buffer_ranges=>[],
118
+ :array_sizes=>[],
119
+ :name=>"inColor",
120
+ :location=>1},
121
+ {:type=>:float,
122
+ :width=>32,
123
+ :vecsize=>2,
124
+ :columns=>1,
125
+ :is_pointer=>true,
126
+ :storage_class=>:input,
127
+ :members=>[],
128
+ :active_buffer_ranges=>[],
129
+ :array_sizes=>[],
130
+ :name=>"inTexCoord",
131
+ :location=>2}],
132
+ :stage_outputs=>
133
+ [{:type=>:float,
134
+ :width=>32,
135
+ :vecsize=>3,
136
+ :columns=>1,
137
+ :is_pointer=>true,
138
+ :storage_class=>:output,
139
+ :members=>[],
140
+ :active_buffer_ranges=>[],
141
+ :array_sizes=>[],
142
+ :name=>"fragColor",
143
+ :location=>0},
144
+ {:type=>:float,
145
+ :width=>32,
146
+ :vecsize=>2,
147
+ :columns=>1,
148
+ :is_pointer=>true,
149
+ :storage_class=>:output,
150
+ :members=>[],
151
+ :active_buffer_ranges=>[],
152
+ :array_sizes=>[],
153
+ :name=>"fragTexCoord",
154
+ :location=>1}],
155
+ :subpass_inputs=>[],
156
+ :storage_images=>[],
157
+ :sampled_images=>[],
158
+ :atomic_counters=>[],
159
+ :push_constant_buffers=>[],
160
+ :separate_images=>[],
161
+ :separate_samplers=>[]}
162
+
163
+ ## Development
164
+
165
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
166
+
167
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
168
+
169
+ ## Contributing
170
+
171
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sinisterchipmunk/spirv-cross-ruby.
172
+
173
+ ## License
174
+
175
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ require "rake/extensiontask"
11
+
12
+ task :build => :compile
13
+
14
+ Rake::ExtensionTask.new("spirv_cross") do |ext|
15
+ ext.lib_dir = "lib/spirv"
16
+ end
17
+
18
+ task :default => [:clobber, :compile, :test]
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "spirv/cross"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,24 @@
1
+ require "mkmf"
2
+ require 'rake'
3
+ require 'rake/file_utils'
4
+
5
+ include FileUtils
6
+
7
+ REVISION = 'ea6bdacd056b77ec1004822482d08b6f31473f25'
8
+
9
+ unless File.directory?(File.expand_path('spirv-cross', __dir__))
10
+ sh 'git', 'clone', 'https://github.com/KhronosGroup/SPIRV-Cross', File.expand_path('spirv-cross', __dir__)
11
+ end
12
+
13
+ chdir File.expand_path('spirv-cross', __dir__) do
14
+ sh 'git', 'fetch'
15
+ sh 'git', 'checkout', REVISION
16
+ sh 'make'
17
+ end
18
+
19
+ $CFLAGS << ' -I' << File.expand_path('spirv-cross', __dir__)
20
+ $CXXFLAGS << ' -I' << File.expand_path('spirv-cross', __dir__) << ' -std=c++11'
21
+ $LDFLAGS << ' -L' << File.expand_path('spirv-cross', __dir__)
22
+ have_library 'spirv-cross'
23
+
24
+ create_makefile("spirv/spirv_cross")
@@ -0,0 +1,25 @@
1
+ #ifndef RB_SPIRV_CROSS_H
2
+ #define RB_SPIRV_CROSS_H 1
3
+
4
+ #include "ruby.h"
5
+
6
+ #if __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ extern VALUE rb_eSPIRVError;
11
+ extern VALUE rb_mSPIRV;
12
+ extern VALUE rb_mCross;
13
+ extern VALUE rb_cCompiler;
14
+
15
+ VALUE rb_spvx_compiler_initialize(VALUE self, VALUE binstr);
16
+ VALUE rb_spvx_compiler_all_shader_resources(VALUE self);
17
+ VALUE rb_spvx_compiler_active_shader_resources(VALUE self);
18
+ VALUE rb_spvx_compiler_entry_points(VALUE self);
19
+ VALUE rb_spvx_compiler_specialization_constants(VALUE self);
20
+
21
+ #if __cplusplus
22
+ }
23
+ #endif
24
+
25
+ #endif /* RB_SPIRV_CROSS_H */
@@ -0,0 +1,376 @@
1
+ #include "rb_spirv_cross.h"
2
+ #include "spirv_cross.hpp"
3
+
4
+ using namespace spirv_cross;
5
+ using namespace std;
6
+ using namespace spv;
7
+
8
+ void compiler_free(void* data) {
9
+ Compiler *comp = (Compiler *) data;
10
+ delete comp;
11
+ }
12
+
13
+ size_t compiler_size(const void* data) {
14
+ return sizeof(Compiler);
15
+ }
16
+
17
+ static const rb_data_type_t compiler_type = {
18
+ .wrap_struct_name = "SPIRVCompiler",
19
+ .function = {
20
+ .dmark = NULL,
21
+ .dfree = compiler_free,
22
+ .dsize = compiler_size,
23
+ .reserved = { 0, 0 }
24
+ },
25
+ .parent = NULL,
26
+ .data = NULL,
27
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
28
+ };
29
+
30
+ extern "C" {
31
+ VALUE rb_spirv_type(Compiler &compiler, uint32_t type_id) {
32
+ VALUE vres = rb_hash_new();
33
+ auto &base_type = compiler.get_type(type_id);
34
+ switch(base_type.basetype) {
35
+ case SPIRType::BaseType::Void: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("void"))); break;
36
+ case SPIRType::BaseType::Boolean: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("boolean"))); break;
37
+ case SPIRType::BaseType::Char: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("char"))); break;
38
+ case SPIRType::BaseType::Int: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("int"))); break;
39
+ case SPIRType::BaseType::UInt: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("uint"))); break;
40
+ case SPIRType::BaseType::Int64: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("int64"))); break;
41
+ case SPIRType::BaseType::UInt64: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("uint64"))); break;
42
+ case SPIRType::BaseType::AtomicCounter: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("atomic_counter"))); break;
43
+ case SPIRType::BaseType::Half: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("half"))); break;
44
+ case SPIRType::BaseType::Float: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("float"))); break;
45
+ case SPIRType::BaseType::Double: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("double"))); break;
46
+ case SPIRType::BaseType::Struct: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("struct"))); break;
47
+ case SPIRType::BaseType::Image: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("image"))); break;
48
+ case SPIRType::BaseType::SampledImage: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("sampled_image"))); break;
49
+ case SPIRType::BaseType::Sampler: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("sampler"))); break;
50
+ default: rb_hash_aset(vres, ID2SYM(rb_intern("type")), ID2SYM(rb_intern("unknown")));
51
+ }
52
+
53
+ rb_hash_aset(vres, ID2SYM(rb_intern("width")), UINT2NUM(base_type.width));
54
+ rb_hash_aset(vres, ID2SYM(rb_intern("vecsize")), UINT2NUM(base_type.vecsize));
55
+ rb_hash_aset(vres, ID2SYM(rb_intern("columns")), UINT2NUM(base_type.columns));
56
+ rb_hash_aset(vres, ID2SYM(rb_intern("is_pointer")), base_type.pointer ? Qtrue : Qfalse);
57
+
58
+ if (base_type.basetype == SPIRType::BaseType::Image || base_type.basetype == SPIRType::BaseType::SampledImage) {
59
+ VALUE vimg = rb_hash_new();
60
+ rb_hash_aset(vimg, ID2SYM(rb_intern("type")), rb_spirv_type(compiler, base_type.image.type));
61
+ switch(base_type.image.dim) {
62
+ case Dim::Dim1D: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), INT2NUM(1)); break;
63
+ case Dim::Dim2D: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), INT2NUM(2)); break;
64
+ case Dim::Dim3D: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), INT2NUM(3)); break;
65
+ case Dim::DimCube: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("cube"))); break;
66
+ case Dim::DimRect: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("rect"))); break;
67
+ case Dim::DimBuffer: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("buffer"))); break;
68
+ case Dim::DimSubpassData: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("subpass_data"))); break;
69
+ case Dim::DimMax: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("max"))); break;
70
+ default: rb_hash_aset(vimg, ID2SYM(rb_intern("dimensions")), ID2SYM(rb_intern("unknown")));
71
+ }
72
+ rb_hash_aset(vimg, ID2SYM(rb_intern("depth")), base_type.image.depth ? Qtrue : Qfalse);
73
+ rb_hash_aset(vimg, ID2SYM(rb_intern("arrayed")), base_type.image.arrayed ? Qtrue : Qfalse);
74
+ rb_hash_aset(vimg, ID2SYM(rb_intern("multisampled")), base_type.image.ms ? Qtrue : Qfalse);
75
+ switch(base_type.image.sampled) {
76
+ case 1: rb_hash_aset(vimg, ID2SYM(rb_intern("sampling")), ID2SYM(rb_intern("sampled"))); break;
77
+ case 2: rb_hash_aset(vimg, ID2SYM(rb_intern("sampling")), ID2SYM(rb_intern("image_load_store"))); break;
78
+ default: rb_hash_aset(vimg, ID2SYM(rb_intern("sampling")), Qfalse);
79
+ }
80
+ switch(base_type.image.format) {
81
+ case ImageFormatRgba32f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba32f"))); break;
82
+ case ImageFormatRgba16f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba16f"))); break;
83
+ case ImageFormatR32f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r32f"))); break;
84
+ case ImageFormatRgba8: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba8"))); break;
85
+ case ImageFormatRgba8Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba8snorm"))); break;
86
+ case ImageFormatRg32f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg32f"))); break;
87
+ case ImageFormatRg16f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg16f"))); break;
88
+ case ImageFormatR11fG11fB10f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r11fg11fb10f"))); break;
89
+ case ImageFormatR16f: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r16f"))); break;
90
+ case ImageFormatRgba16: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba16"))); break;
91
+ case ImageFormatRgb10A2: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgb10a2"))); break;
92
+ case ImageFormatRg16: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg16"))); break;
93
+ case ImageFormatRg8: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg8"))); break;
94
+ case ImageFormatR16: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r16"))); break;
95
+ case ImageFormatR8: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r8"))); break;
96
+ case ImageFormatRgba16Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba16snorm"))); break;
97
+ case ImageFormatRg16Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg16snorm"))); break;
98
+ case ImageFormatRg8Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg8snorm"))); break;
99
+ case ImageFormatR16Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r16snorm"))); break;
100
+ case ImageFormatR8Snorm: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r8snorm"))); break;
101
+ case ImageFormatRgba32i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba32i"))); break;
102
+ case ImageFormatRgba16i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba16i"))); break;
103
+ case ImageFormatRgba8i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba8i"))); break;
104
+ case ImageFormatR32i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r32i"))); break;
105
+ case ImageFormatRg32i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg32i"))); break;
106
+ case ImageFormatRg16i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg16i"))); break;
107
+ case ImageFormatRg8i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg8i"))); break;
108
+ case ImageFormatR16i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r16i"))); break;
109
+ case ImageFormatR8i: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r8i"))); break;
110
+ case ImageFormatRgba32ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba32ui"))); break;
111
+ case ImageFormatRgba16ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba16ui"))); break;
112
+ case ImageFormatRgba8ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgba8ui"))); break;
113
+ case ImageFormatR32ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r32ui"))); break;
114
+ case ImageFormatRgb10a2ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rgb10a2ui"))); break;
115
+ case ImageFormatRg32ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg32ui"))); break;
116
+ case ImageFormatRg16ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg16ui"))); break;
117
+ case ImageFormatRg8ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("rg8ui"))); break;
118
+ case ImageFormatR16ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r16ui"))); break;
119
+ case ImageFormatR8ui: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("r8ui"))); break;
120
+ case ImageFormatMax: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("max"))); break;
121
+ default: rb_hash_aset(vimg, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("unknown")));
122
+ }
123
+ switch(base_type.image.access) {
124
+ case AccessQualifierReadOnly: rb_hash_aset(vimg, ID2SYM(rb_intern("access")), ID2SYM(rb_intern("read_only"))); break;
125
+ case AccessQualifierWriteOnly: rb_hash_aset(vimg, ID2SYM(rb_intern("access")), ID2SYM(rb_intern("write_only"))); break;
126
+ case AccessQualifierReadWrite: rb_hash_aset(vimg, ID2SYM(rb_intern("access")), ID2SYM(rb_intern("read_write"))); break;
127
+ case AccessQualifierMax: rb_hash_aset(vimg, ID2SYM(rb_intern("access")), ID2SYM(rb_intern("max"))); break;
128
+ default: rb_hash_aset(vimg, ID2SYM(rb_intern("access")), ID2SYM(rb_intern("unknown"))); break;
129
+ }
130
+ rb_hash_aset(vres, ID2SYM(rb_intern("image")), vimg);
131
+ }
132
+
133
+ switch(base_type.storage) {
134
+ case StorageClassGeneric: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("generic"))); break;
135
+ case StorageClassUniformConstant: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("uniform_constant"))); break;
136
+ case StorageClassInput: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("input"))); break;
137
+ case StorageClassUniform: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("uniform"))); break;
138
+ case StorageClassOutput: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("output"))); break;
139
+ case StorageClassWorkgroup: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("workgroup"))); break;
140
+ case StorageClassCrossWorkgroup: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("cross_work_group"))); break;
141
+ case StorageClassPrivate: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("private"))); break;
142
+ case StorageClassFunction: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("function"))); break;
143
+ case StorageClassPushConstant: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("push_constant"))); break;
144
+ case StorageClassAtomicCounter: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("atomic_counter"))); break;
145
+ case StorageClassImage: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("image"))); break;
146
+ case StorageClassStorageBuffer: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("storage_buffer"))); break;
147
+ case StorageClassMax: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("max"))); break;
148
+ default: rb_hash_aset(vres, ID2SYM(rb_intern("storage_class")), ID2SYM(rb_intern("unknown")));
149
+ }
150
+
151
+ VALUE vmembers = rb_ary_new();
152
+ rb_hash_aset(vres, ID2SYM(rb_intern("members")), vmembers);
153
+ for (unsigned i = 0; i < base_type.member_types.size(); i++) {
154
+ uint32_t mtype_id = base_type.member_types[i];
155
+ // VALUE vmember = rb_hash_new();
156
+ VALUE vmember = rb_spirv_type(compiler, mtype_id);
157
+ rb_ary_push(vmembers, vmember);
158
+ // rb_hash_aset(vmember, ID2SYM(rb_intern("type")), rb_spirv_type(compiler, mtype_id));
159
+ auto &member_type = compiler.get_type(mtype_id);
160
+ size_t member_size = compiler.get_declared_struct_member_size(base_type, i);
161
+ rb_hash_aset(vmember, ID2SYM(rb_intern("size")), SIZET2NUM(member_size));
162
+
163
+ // Get member offset within this struct.
164
+ size_t offset = compiler.type_struct_member_offset(base_type, i);
165
+ rb_hash_aset(vmember, ID2SYM(rb_intern("offset")), SIZET2NUM(offset));
166
+
167
+ if (!member_type.array.empty())
168
+ {
169
+ // Get array stride, e.g. float4 foo[]; Will have array stride of 16 bytes.
170
+ size_t array_stride = compiler.type_struct_member_array_stride(base_type, i);
171
+ rb_hash_aset(vmember, ID2SYM(rb_intern("array_stride")), SIZET2NUM(array_stride));
172
+ }
173
+
174
+ if (member_type.columns > 1)
175
+ {
176
+ // Get bytes stride between columns (if column major), for float4x4 -> 16 bytes.
177
+ size_t matrix_stride = compiler.type_struct_member_matrix_stride(base_type, i);
178
+ rb_hash_aset(vmember, ID2SYM(rb_intern("matrix_stride")), SIZET2NUM(matrix_stride));
179
+ }
180
+ const string &name = compiler.get_member_name(base_type.self, i);
181
+ rb_hash_aset(vmember, ID2SYM(rb_intern("name")), rb_str_new2(name.c_str()));
182
+ }
183
+
184
+ return vres;
185
+ }
186
+
187
+ VALUE shader_resource_vector_to_ary(Compiler &compiler, vector<Resource> &vec, bool print_ssbo) {
188
+ VALUE ret = rb_ary_new();
189
+ for (size_t i = 0; i < vec.size(); i++) {
190
+ Resource &res = vec[i];
191
+
192
+ // just merge extra data into the type hash instead of creating a nested type hash
193
+ VALUE vres = rb_spirv_type(compiler, res.type_id);
194
+
195
+ // VALUE vres = rb_hash_new();
196
+ // Docs say base type is only really useful for decorations, which we do further down, so
197
+ // we'll omit it here to save redundancy.
198
+ // // rb_hash_aset(vres, ID2SYM(rb_intern("base_type")), rb_spirv_type(compiler, res.base_type_id));
199
+ // rb_hash_aset(vres, ID2SYM(rb_intern("type")), rb_spirv_type(compiler, res.type_id));
200
+
201
+ vector<BufferRange> ranges = compiler.get_active_buffer_ranges(res.id);
202
+ VALUE vranges = rb_ary_new();
203
+ rb_hash_aset(vres, ID2SYM(rb_intern("active_buffer_ranges")), vranges);
204
+ for (auto &range : ranges) {
205
+ VALUE vrange = rb_hash_new();
206
+ rb_hash_aset(vrange, ID2SYM(rb_intern("index")), UINT2NUM(range.index));
207
+ rb_hash_aset(vrange, ID2SYM(rb_intern("offset")), SIZET2NUM(range.offset));
208
+ rb_hash_aset(vrange, ID2SYM(rb_intern("size")), SIZET2NUM(range.range));
209
+ rb_ary_push(vranges, vrange);
210
+ }
211
+
212
+ auto &type = compiler.get_type(res.type_id);
213
+
214
+ /* The following code was basically lifted from spirv-cross/main.cpp */
215
+
216
+ if (print_ssbo && compiler.buffer_is_hlsl_counter_buffer(res.id))
217
+ continue;
218
+
219
+ // If we don't have a name, use the fallback for the type instead of the variable
220
+ // for SSBOs and UBOs since those are the only meaningful names to use externally.
221
+ // Push constant blocks are still accessed by name and not block name, even though they are technically Blocks.
222
+ bool is_push_constant = compiler.get_storage_class(res.id) == StorageClassPushConstant;
223
+ bool is_block = compiler.get_decoration_bitset(type.self).get(DecorationBlock) ||
224
+ compiler.get_decoration_bitset(type.self).get(DecorationBufferBlock);
225
+ bool is_sized_block = is_block && (compiler.get_storage_class(res.id) == StorageClassUniform ||
226
+ compiler.get_storage_class(res.id) == StorageClassUniformConstant);
227
+ uint32_t fallback_id = !is_push_constant && is_block ? res.base_type_id : res.id;
228
+
229
+ uint32_t block_size = 0;
230
+ uint32_t runtime_array_stride = 0;
231
+ if (is_sized_block)
232
+ {
233
+ auto &base_type = compiler.get_type(res.base_type_id);
234
+ block_size = uint32_t(compiler.get_declared_struct_size(base_type));
235
+ runtime_array_stride = uint32_t(compiler.get_declared_struct_size_runtime_array(base_type, 1) -
236
+ compiler.get_declared_struct_size_runtime_array(base_type, 0));
237
+ }
238
+
239
+ Bitset mask;
240
+ if (print_ssbo)
241
+ mask = compiler.get_buffer_block_flags(res.id);
242
+ else
243
+ mask = compiler.get_decoration_bitset(res.id);
244
+
245
+ VALUE ary = rb_ary_new();
246
+ rb_hash_aset(vres, ID2SYM(rb_intern("array_sizes")), ary);
247
+ for (size_t j = 0; j < type.array.size(); j++) {
248
+ if (type.array_size_literal[j])
249
+ rb_ary_push(ary, UINT2NUM(type.array[j]));
250
+ else
251
+ rb_ary_push(ary, ID2SYM(rb_intern("expression")));
252
+ }
253
+
254
+ rb_hash_aset(vres, ID2SYM(rb_intern("name")),
255
+ rb_str_new2(!res.name.empty() ?
256
+ res.name.c_str() :
257
+ compiler.get_fallback_name(fallback_id).c_str()));
258
+
259
+ if (mask.get(DecorationLocation))
260
+ rb_hash_aset(vres, ID2SYM(rb_intern("location")), UINT2NUM(compiler.get_decoration(res.id, DecorationLocation)));
261
+ if (mask.get(DecorationDescriptorSet))
262
+ rb_hash_aset(vres, ID2SYM(rb_intern("descriptor_set")), UINT2NUM(compiler.get_decoration(res.id, DecorationDescriptorSet)));
263
+ if (mask.get(DecorationBinding))
264
+ rb_hash_aset(vres, ID2SYM(rb_intern("binding")), UINT2NUM(compiler.get_decoration(res.id, DecorationBinding)));
265
+ if (mask.get(DecorationInputAttachmentIndex))
266
+ rb_hash_aset(vres, ID2SYM(rb_intern("attachment")), UINT2NUM(compiler.get_decoration(res.id, DecorationInputAttachmentIndex)));
267
+ if (mask.get(DecorationNonReadable))
268
+ rb_hash_aset(vres, ID2SYM(rb_intern("write_only")), Qtrue);
269
+ if (mask.get(DecorationNonWritable))
270
+ rb_hash_aset(vres, ID2SYM(rb_intern("read_only")), Qtrue);
271
+ if (is_sized_block)
272
+ {
273
+ rb_hash_aset(vres, ID2SYM(rb_intern("block_size")), UINT2NUM(block_size));
274
+ if (runtime_array_stride)
275
+ rb_hash_aset(vres, ID2SYM(rb_intern("unsized_array_stride")), UINT2NUM(runtime_array_stride));
276
+ }
277
+
278
+ uint32_t counter_id = 0;
279
+ if (print_ssbo && compiler.buffer_get_hlsl_counter_buffer(res.id, counter_id))
280
+ rb_hash_aset(vres, ID2SYM(rb_intern("hlsl_counter_buffer_id")), UINT2NUM(counter_id));
281
+
282
+ rb_ary_push(ret, vres);
283
+ }
284
+ return ret;
285
+ }
286
+
287
+ inline VALUE shader_resources_to_hash(Compiler *comp, ShaderResources &resources) {
288
+ VALUE vsr = rb_hash_new();
289
+ #define HASH_PUSH_RESOURCE_ARY(name, ssbo) \
290
+ rb_hash_aset(vsr, ID2SYM(rb_intern(#name)), shader_resource_vector_to_ary(*comp, resources.name, ssbo));
291
+ HASH_PUSH_RESOURCE_ARY(uniform_buffers, false);
292
+ HASH_PUSH_RESOURCE_ARY(storage_buffers, true);
293
+ HASH_PUSH_RESOURCE_ARY(stage_inputs, false);
294
+ HASH_PUSH_RESOURCE_ARY(stage_outputs, false);
295
+ HASH_PUSH_RESOURCE_ARY(subpass_inputs, false);
296
+ HASH_PUSH_RESOURCE_ARY(storage_images, false);
297
+ HASH_PUSH_RESOURCE_ARY(sampled_images, false);
298
+ HASH_PUSH_RESOURCE_ARY(atomic_counters, false);
299
+ HASH_PUSH_RESOURCE_ARY(push_constant_buffers, false);
300
+ HASH_PUSH_RESOURCE_ARY(separate_images, false);
301
+ HASH_PUSH_RESOURCE_ARY(separate_samplers, false);
302
+ return vsr;
303
+ }
304
+
305
+ VALUE rb_spvx_compiler_all_shader_resources(VALUE self) {
306
+ Compiler *comp;
307
+ TypedData_Get_Struct(rb_ivar_get(self, rb_intern("@handle")), Compiler, &compiler_type, comp);
308
+ ShaderResources resources = comp->get_shader_resources();
309
+ return shader_resources_to_hash(comp, resources);
310
+ }
311
+
312
+ VALUE rb_spvx_compiler_active_shader_resources(VALUE self) {
313
+ Compiler *comp;
314
+ TypedData_Get_Struct(rb_ivar_get(self, rb_intern("@handle")), Compiler, &compiler_type, comp);
315
+ auto active = comp->get_active_interface_variables();
316
+ ShaderResources resources = comp->get_shader_resources(active);
317
+ // comp->set_enabled_interface_variables(move(active));
318
+ return shader_resources_to_hash(comp, resources);
319
+ }
320
+
321
+ VALUE rb_spvx_compiler_entry_points(VALUE self) {
322
+ Compiler *comp;
323
+ TypedData_Get_Struct(rb_ivar_get(self, rb_intern("@handle")), Compiler, &compiler_type, comp);
324
+ std::vector<EntryPoint> entry_points = comp->get_entry_points_and_stages();
325
+ VALUE ret = rb_ary_new();
326
+ for (auto &ep : entry_points) {
327
+ VALUE vep = rb_hash_new();
328
+ rb_ary_push(ret, vep);
329
+ rb_hash_aset(vep, ID2SYM(rb_intern("name")), rb_str_new2(ep.name.c_str()));
330
+ switch(ep.execution_model) {
331
+ case ExecutionModel::ExecutionModelVertex: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("vertex"))); break;
332
+ case ExecutionModel::ExecutionModelTessellationControl: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("tessellation_control"))); break;
333
+ case ExecutionModel::ExecutionModelTessellationEvaluation: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("tessellation_evaluation"))); break;
334
+ case ExecutionModel::ExecutionModelGeometry: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("geometry"))); break;
335
+ case ExecutionModel::ExecutionModelFragment: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("fragment"))); break;
336
+ case ExecutionModel::ExecutionModelGLCompute: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("gl_compute"))); break;
337
+ case ExecutionModel::ExecutionModelKernel: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("kernel"))); break;
338
+ case ExecutionModel::ExecutionModelMax: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("max"))); break;
339
+ default: rb_hash_aset(vep, ID2SYM(rb_intern("execution_model")), ID2SYM(rb_intern("unknown"))); break;
340
+ }
341
+ }
342
+ return ret;
343
+ }
344
+
345
+ VALUE rb_spvx_compiler_specialization_constants(VALUE self) {
346
+ Compiler *comp;
347
+ TypedData_Get_Struct(rb_ivar_get(self, rb_intern("@handle")), Compiler, &compiler_type, comp);
348
+ vector<SpecializationConstant> consts = comp->get_specialization_constants();
349
+ VALUE vconsts = rb_ary_new();
350
+ for (auto &c : consts) {
351
+ VALUE vconst = rb_hash_new();
352
+ rb_hash_aset(vconst, ID2SYM(rb_intern("constant_id")), INT2NUM(c.constant_id));
353
+ rb_hash_aset(vconst, ID2SYM(rb_intern("name")), rb_str_new2(comp->get_name(c.id).c_str()));
354
+ rb_ary_push(vconsts, vconst);
355
+ }
356
+ return vconsts;
357
+ }
358
+
359
+ VALUE rb_spvx_compiler_initialize(VALUE self, VALUE binstr) {
360
+ size_t len = RSTRING_LEN(binstr) / sizeof(uint32_t);
361
+ uint32_t *data = (uint32_t *) RSTRING_PTR(binstr);
362
+ vector<uint32_t> spirv;
363
+ for (size_t i = 0; i < len; i++) {
364
+ spirv.push_back(data[i]);
365
+ }
366
+
367
+ try {
368
+ Compiler *compiler = new Compiler(move(spirv));
369
+ rb_ivar_set(self, rb_intern("@handle"), TypedData_Wrap_Struct(rb_cData, &compiler_type, compiler));
370
+ } catch(const exception &ex) {
371
+ rb_raise(rb_eSPIRVError, "%s", ex.what());
372
+ }
373
+
374
+ return self;
375
+ }
376
+ }
@@ -0,0 +1,21 @@
1
+ #include "rb_spirv_cross.h"
2
+
3
+ VALUE rb_eSPIRVError;
4
+ VALUE rb_mSPIRV;
5
+ VALUE rb_mCross;
6
+ VALUE rb_cCompiler;
7
+
8
+ void Init_spirv_cross() {
9
+ rb_mSPIRV = rb_define_module("SPIRV");
10
+ rb_mCross = rb_define_module_under(rb_mSPIRV, "Cross");
11
+ rb_cCompiler = rb_define_class_under(rb_mCross, "Compiler", rb_cObject);
12
+ rb_eSPIRVError = rb_define_class_under(rb_mCross, "Error", rb_eStandardError);
13
+
14
+ rb_define_method(rb_cCompiler, "initialize", rb_spvx_compiler_initialize, 1);
15
+ rb_define_method(rb_cCompiler, "active_shader_resources", rb_spvx_compiler_active_shader_resources, 0);
16
+ rb_define_method(rb_cCompiler, "all_shader_resources", rb_spvx_compiler_all_shader_resources, 0);
17
+ rb_define_method(rb_cCompiler, "entry_points", rb_spvx_compiler_entry_points, 0);
18
+ rb_define_method(rb_cCompiler, "specialization_constants", rb_spvx_compiler_specialization_constants, 0);
19
+
20
+ rb_define_alias(rb_cCompiler, "shader_resources", "all_shader_resources");
21
+ }
@@ -0,0 +1 @@
1
+ require 'spirv/cross'
@@ -0,0 +1,9 @@
1
+ require "spirv/cross/version"
2
+ require "spirv/spirv_cross"
3
+
4
+ module SPIRV
5
+ module Cross
6
+ class Error < StandardError; end
7
+ # Your code goes here...
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module SPIRV
2
+ module Cross
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require 'spirv/cross'
@@ -0,0 +1,40 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "spirv/cross/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "spirv-cross"
8
+ spec.version = SPIRV::Cross::VERSION
9
+ spec.authors = ["Colin MacKenzie IV"]
10
+ spec.email = ["sinisterchipmunk@gmail.com"]
11
+
12
+ spec.summary = %q{Ruby bindings for SPIRV-Cross to provide reflection of SPIR-V shaders.}
13
+ spec.homepage = "https://github.com/sinisterchipmunk/spirv-cross-ruby"
14
+ spec.license = "MIT"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+ spec.extensions = ["ext/spirv_cross/extconf.rb"]
35
+
36
+ spec.add_development_dependency "bundler", "~> 1.17"
37
+ spec.add_development_dependency "rake", "~> 10.0"
38
+ spec.add_development_dependency "rake-compiler"
39
+ spec.add_development_dependency "minitest", "~> 5.0"
40
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spirv-cross
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Colin MacKenzie IV
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-11-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description:
70
+ email:
71
+ - sinisterchipmunk@gmail.com
72
+ executables: []
73
+ extensions:
74
+ - ext/spirv_cross/extconf.rb
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - ext/spirv_cross/extconf.rb
87
+ - ext/spirv_cross/rb_spirv_cross.h
88
+ - ext/spirv_cross/rb_spvx_compiler.cpp
89
+ - ext/spirv_cross/rb_spvx_init.c
90
+ - lib/spirv-cross.rb
91
+ - lib/spirv/cross.rb
92
+ - lib/spirv/cross/version.rb
93
+ - lib/spirv_cross.rb
94
+ - spirv-cross.gemspec
95
+ homepage: https://github.com/sinisterchipmunk/spirv-cross-ruby
96
+ licenses:
97
+ - MIT
98
+ metadata:
99
+ allowed_push_host: https://rubygems.org
100
+ homepage_uri: https://github.com/sinisterchipmunk/spirv-cross-ruby
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.7.8
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: Ruby bindings for SPIRV-Cross to provide reflection of SPIR-V shaders.
121
+ test_files: []