wgpu 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +26 -3
  4. data/docs/README.md +22 -0
  5. data/docs/api_coverage.md +132 -0
  6. data/docs/async.md +31 -0
  7. data/docs/bind_groups.md +25 -0
  8. data/docs/buffer_data.md +37 -0
  9. data/docs/command_encoding.md +24 -0
  10. data/docs/errors.md +40 -0
  11. data/docs/getting_started_compute.md +61 -0
  12. data/docs/getting_started_rendering.md +62 -0
  13. data/docs/installation.md +94 -0
  14. data/docs/pipeline_descriptors.md +38 -0
  15. data/docs/releasing.md +22 -0
  16. data/docs/resource_lifetime.md +94 -0
  17. data/docs/shaders.md +32 -0
  18. data/docs/texture_readback.md +19 -0
  19. data/docs/troubleshooting.md +48 -0
  20. data/docs/upgrading_wgpu_native.md +26 -0
  21. data/ext/wgpu/extconf.rb +10 -142
  22. data/lib/wgpu/commands/command_buffer.rb +11 -0
  23. data/lib/wgpu/commands/command_encoder.rb +65 -8
  24. data/lib/wgpu/commands/compute_pass.rb +10 -0
  25. data/lib/wgpu/commands/render_bundle_encoder.rb +10 -3
  26. data/lib/wgpu/commands/render_pass.rb +34 -8
  27. data/lib/wgpu/core/adapter.rb +49 -20
  28. data/lib/wgpu/core/async_waiter.rb +92 -0
  29. data/lib/wgpu/core/canvas_context.rb +0 -2
  30. data/lib/wgpu/core/device.rb +160 -52
  31. data/lib/wgpu/core/instance.rb +9 -5
  32. data/lib/wgpu/core/queue.rb +81 -57
  33. data/lib/wgpu/core/surface.rb +16 -17
  34. data/lib/wgpu/data_types.rb +67 -0
  35. data/lib/wgpu/descriptor_helpers.rb +39 -0
  36. data/lib/wgpu/error.rb +55 -0
  37. data/lib/wgpu/logging.rb +63 -0
  38. data/lib/wgpu/native/abi_verifier.rb +109 -0
  39. data/lib/wgpu/native/callbacks.rb +9 -6
  40. data/lib/wgpu/native/capabilities.rb +31 -0
  41. data/lib/wgpu/native/distribution.rb +113 -0
  42. data/lib/wgpu/native/enum_helper.rb +63 -0
  43. data/lib/wgpu/native/enums.rb +82 -13
  44. data/lib/wgpu/native/functions.rb +17 -8
  45. data/lib/wgpu/native/installer.rb +192 -0
  46. data/lib/wgpu/native/loader.rb +40 -21
  47. data/lib/wgpu/native/structs.rb +19 -5
  48. data/lib/wgpu/native_resource.rb +171 -0
  49. data/lib/wgpu/pipeline/bind_group.rb +12 -0
  50. data/lib/wgpu/pipeline/bind_group_layout.rb +91 -37
  51. data/lib/wgpu/pipeline/compute_pipeline.rb +28 -26
  52. data/lib/wgpu/pipeline/render_pipeline.rb +180 -68
  53. data/lib/wgpu/pipeline/shader_module.rb +51 -12
  54. data/lib/wgpu/resources/buffer.rb +167 -84
  55. data/lib/wgpu/resources/query_set.rb +14 -12
  56. data/lib/wgpu/resources/sampler.rb +36 -20
  57. data/lib/wgpu/resources/texture.rb +44 -42
  58. data/lib/wgpu/resources/texture_view.rb +11 -3
  59. data/lib/wgpu/texture_format.rb +82 -0
  60. data/lib/wgpu/version.rb +1 -1
  61. data/lib/wgpu/window.rb +8 -1
  62. data/lib/wgpu.rb +33 -0
  63. data/sig/wgpu.rbs +381 -0
  64. metadata +33 -16
@@ -50,13 +50,22 @@ module WGPU
50
50
  :success, 0x00000001,
51
51
  :instance_dropped, 0x00000002,
52
52
  :unavailable, 0x00000003,
53
- :error, 0x00000004
53
+ :error, 0x00000004,
54
+ :unknown, 0x00000005
54
55
  )
55
56
 
56
57
  RequestDeviceStatus = enum(
57
58
  :success, 0x00000001,
58
59
  :instance_dropped, 0x00000002,
59
- :error, 0x00000003
60
+ :error, 0x00000003,
61
+ :unknown, 0x00000004
62
+ )
63
+
64
+ DeviceLostReason = enum(
65
+ :unknown, 0x00000001,
66
+ :destroyed, 0x00000002,
67
+ :instance_dropped, 0x00000003,
68
+ :failed_creation, 0x00000004
60
69
  )
61
70
 
62
71
  BufferMapState = enum(
@@ -65,11 +74,18 @@ module WGPU
65
74
  :mapped, 0x00000003
66
75
  )
67
76
 
77
+ CallbackMode = enum(
78
+ :wait_any_only, 0x00000001,
79
+ :allow_process_events, 0x00000002,
80
+ :allow_spontaneous, 0x00000003
81
+ )
82
+
68
83
  MapAsyncStatus = enum(
69
84
  :success, 0x00000001,
70
85
  :instance_dropped, 0x00000002,
71
86
  :error, 0x00000003,
72
- :aborted, 0x00000004
87
+ :aborted, 0x00000004,
88
+ :unknown, 0x00000005
73
89
  )
74
90
 
75
91
  BufferUsage = {
@@ -274,7 +290,9 @@ module WGPU
274
290
  :sint32, 0x00000024,
275
291
  :sint32x2, 0x00000025,
276
292
  :sint32x3, 0x00000026,
277
- :sint32x4, 0x00000027
293
+ :sint32x4, 0x00000027,
294
+ :unorm10_10_10_2, 0x00000028,
295
+ :unorm8x4_bgra, 0x00000029
278
296
  )
279
297
 
280
298
  IndexFormat = enum(
@@ -357,11 +375,11 @@ module WGPU
357
375
  :undefined, 0x00000000,
358
376
  :never, 0x00000001,
359
377
  :less, 0x00000002,
360
- :less_equal, 0x00000003,
361
- :greater, 0x00000004,
362
- :greater_equal, 0x00000005,
363
- :equal, 0x00000006,
364
- :not_equal, 0x00000007,
378
+ :equal, 0x00000003,
379
+ :less_equal, 0x00000004,
380
+ :greater, 0x00000005,
381
+ :not_equal, 0x00000006,
382
+ :greater_equal, 0x00000007,
365
383
  :always, 0x00000008
366
384
  )
367
385
 
@@ -458,7 +476,9 @@ module WGPU
458
476
  :timeout, 0x00000003,
459
477
  :outdated, 0x00000004,
460
478
  :lost, 0x00000005,
461
- :error, 0x00000006
479
+ :out_of_memory, 0x00000006,
480
+ :device_lost, 0x00000007,
481
+ :error, 0x00000008
462
482
  )
463
483
 
464
484
  QueryType = enum(
@@ -482,8 +502,16 @@ module WGPU
482
502
 
483
503
  PopErrorScopeStatus = enum(
484
504
  :success, 0x00000001,
485
- :callback_cancelled, 0x00000002,
486
- :error, 0x00000003
505
+ :instance_dropped, 0x00000002,
506
+ :empty_stack, 0x00000003
507
+ )
508
+
509
+ WaitStatus = enum(
510
+ :success, 0x00000001,
511
+ :timed_out, 0x00000002,
512
+ :unsupported_timeout, 0x00000003,
513
+ :unsupported_count, 0x00000004,
514
+ :unsupported_mixed_sources, 0x00000005
487
515
  )
488
516
 
489
517
  QueueWorkDoneStatus = enum(
@@ -506,6 +534,15 @@ module WGPU
506
534
  :info, 0x00000003
507
535
  )
508
536
 
537
+ LogLevel = enum(
538
+ :off, 0x00000000,
539
+ :error, 0x00000001,
540
+ :warn, 0x00000002,
541
+ :info, 0x00000003,
542
+ :debug, 0x00000004,
543
+ :trace, 0x00000005
544
+ )
545
+
509
546
  FeatureName = enum(
510
547
  :undefined, 0x00000000,
511
548
  :depth_clip_control, 0x00000001,
@@ -523,7 +560,39 @@ module WGPU
523
560
  :float32_filterable, 0x0000000D,
524
561
  :float32_blendable, 0x0000000E,
525
562
  :clip_distances, 0x0000000F,
526
- :dual_source_blending, 0x00000010
563
+ :dual_source_blending, 0x00000010,
564
+ # wgpu-native extensions from wgpu.h.
565
+ :push_constants, 0x00030001,
566
+ :texture_adapter_specific_format_features, 0x00030002,
567
+ :multi_draw_indirect_count, 0x00030004,
568
+ :vertex_writable_storage, 0x00030005,
569
+ :texture_binding_array, 0x00030006,
570
+ :sampled_texture_and_storage_buffer_array_non_uniform_indexing, 0x00030007,
571
+ :pipeline_statistics_query, 0x00030008,
572
+ :storage_resource_binding_array, 0x00030009,
573
+ :partially_bound_binding_array, 0x0003000A,
574
+ :texture_format_16bit_norm, 0x0003000B,
575
+ :texture_compression_astc_hdr, 0x0003000C,
576
+ :mappable_primary_buffers, 0x0003000E,
577
+ :buffer_binding_array, 0x0003000F,
578
+ :uniform_buffer_and_storage_texture_array_non_uniform_indexing, 0x00030010,
579
+ :polygon_mode_line, 0x00030013,
580
+ :polygon_mode_point, 0x00030014,
581
+ :conservative_rasterization, 0x00030015,
582
+ :spirv_shader_passthrough, 0x00030017,
583
+ :vertex_attribute_64bit, 0x00030019,
584
+ :texture_format_nv12, 0x0003001A,
585
+ :ray_query, 0x0003001C,
586
+ :shader_f64, 0x0003001D,
587
+ :shader_i16, 0x0003001E,
588
+ :shader_primitive_index, 0x0003001F,
589
+ :shader_early_depth_test, 0x00030020,
590
+ :subgroup, 0x00030021,
591
+ :subgroup_vertex, 0x00030022,
592
+ :subgroup_barrier, 0x00030023,
593
+ :timestamp_query_inside_encoders, 0x00030024,
594
+ :timestamp_query_inside_passes, 0x00030025,
595
+ :shader_int64, 0x00030026
527
596
  )
528
597
  end
529
598
  end
@@ -9,7 +9,7 @@ module WGPU
9
9
  [:pointer], :void
10
10
 
11
11
  attach_function :wgpuInstanceRequestAdapter,
12
- [:pointer, RequestAdapterOptions.by_ref, RequestAdapterCallbackInfo.by_value], :pointer
12
+ [:pointer, RequestAdapterOptions.by_ref, RequestAdapterCallbackInfo.by_value], Future.by_value
13
13
 
14
14
  attach_function :wgpuInstanceEnumerateAdapters,
15
15
  [:pointer, :pointer, :pointer], :size_t
@@ -17,6 +17,9 @@ module WGPU
17
17
  attach_function :wgpuInstanceProcessEvents,
18
18
  [:pointer], :void
19
19
 
20
+ attach_optional_function :wgpuInstanceWaitAny,
21
+ [:pointer, :size_t, :pointer, :uint64], WaitStatus
22
+
20
23
  attach_function :wgpuAdapterRelease,
21
24
  [:pointer], :void
22
25
 
@@ -24,7 +27,7 @@ module WGPU
24
27
  [:pointer, AdapterInfo.by_ref], :void
25
28
 
26
29
  attach_function :wgpuAdapterRequestDevice,
27
- [:pointer, DeviceDescriptor.by_ref, RequestDeviceCallbackInfo.by_value], :pointer
30
+ [:pointer, DeviceDescriptor.by_ref, RequestDeviceCallbackInfo.by_value], Future.by_value
28
31
 
29
32
  attach_function :wgpuAdapterGetFeatures,
30
33
  [:pointer, :pointer], :void
@@ -71,8 +74,8 @@ module WGPU
71
74
  attach_function :wgpuDeviceCreateCommandEncoder,
72
75
  [:pointer, CommandEncoderDescriptor.by_ref], :pointer
73
76
 
74
- attach_function :wgpuDevicePoll,
75
- [:pointer, :uint32, :pointer], :uint32
77
+ attach_optional_function :wgpuDevicePoll,
78
+ [:pointer, :uint32, :pointer], :uint32
76
79
 
77
80
  attach_function :wgpuQueueRelease,
78
81
  [:pointer], :void
@@ -81,7 +84,7 @@ module WGPU
81
84
  [:pointer, :size_t, :pointer], :void
82
85
 
83
86
  attach_function :wgpuQueueOnSubmittedWorkDone,
84
- [:pointer, QueueWorkDoneCallbackInfo.by_value], :pointer
87
+ [:pointer, QueueWorkDoneCallbackInfo.by_value], Future.by_value
85
88
 
86
89
  attach_function :wgpuQueueWriteBuffer,
87
90
  [:pointer, :pointer, :uint64, :pointer, :size_t], :void
@@ -96,7 +99,7 @@ module WGPU
96
99
  [:pointer], :void
97
100
 
98
101
  attach_function :wgpuBufferMapAsync,
99
- [:pointer, :uint64, :size_t, :size_t, BufferMapCallbackInfo.by_value], :pointer
102
+ [:pointer, :uint64, :size_t, :size_t, BufferMapCallbackInfo.by_value], Future.by_value
100
103
 
101
104
  attach_function :wgpuBufferUnmap,
102
105
  [:pointer], :void
@@ -120,7 +123,7 @@ module WGPU
120
123
  [:pointer], :void
121
124
 
122
125
  attach_function :wgpuShaderModuleGetCompilationInfo,
123
- [:pointer, CompilationInfoCallbackInfo.by_value], :pointer
126
+ [:pointer, CompilationInfoCallbackInfo.by_value], Future.by_value
124
127
 
125
128
  attach_function :wgpuCommandEncoderRelease,
126
129
  [:pointer], :void
@@ -363,7 +366,7 @@ module WGPU
363
366
  [:pointer, ErrorFilter], :void
364
367
 
365
368
  attach_function :wgpuDevicePopErrorScope,
366
- [:pointer, PopErrorScopeCallbackInfo.by_value], :pointer
369
+ [:pointer, PopErrorScopeCallbackInfo.by_value], Future.by_value
367
370
 
368
371
  attach_function :wgpuComputePipelineGetBindGroupLayout,
369
372
  [:pointer, :uint32], :pointer
@@ -415,5 +418,11 @@ module WGPU
415
418
 
416
419
  attach_function :wgpuRenderBundleEncoderInsertDebugMarker,
417
420
  [:pointer, StringView.by_value], :void
421
+
422
+ attach_optional_function :wgpuSetLogCallback,
423
+ [:log_callback, :pointer], :void
424
+
425
+ attach_optional_function :wgpuSetLogLevel,
426
+ [LogLevel], :void
418
427
  end
419
428
  end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fileutils"
5
+ require "net/http"
6
+ require "uri"
7
+
8
+ require_relative "distribution"
9
+
10
+ module WGPU
11
+ module Native
12
+ class InstallError < StandardError; end
13
+
14
+ class Installer
15
+ attr_reader :platform
16
+
17
+ def initialize(platform: RUBY_PLATFORM, env: ENV, home: Dir.home,
18
+ host_os: RbConfig::CONFIG["host_os"], output: $stdout)
19
+ @platform = platform
20
+ @env = env
21
+ @home = home
22
+ @host_os = host_os
23
+ @output = output
24
+ end
25
+
26
+ def install
27
+ return custom_library_path if custom_library_path
28
+
29
+ artifact = Distribution.artifact_for(platform)
30
+ cached_path = existing_library_path(artifact)
31
+ if cached_path
32
+ @output.puts "wgpu-native already cached at #{cached_path}"
33
+ return cached_path
34
+ end
35
+
36
+ install_artifact(artifact)
37
+ rescue LoadError, InstallError => error
38
+ raise InstallError, "#{error.message}\n\n#{recovery_instructions}"
39
+ end
40
+
41
+ def clean_path
42
+ Distribution.primary_cache_dir(env: @env, home: @home, host_os: @host_os)
43
+ end
44
+
45
+ private
46
+
47
+ def custom_library_path
48
+ path = @env["WGPU_LIB_PATH"]
49
+ return if path.nil? || path.empty?
50
+ raise InstallError, "WGPU_LIB_PATH points to a non-existent file: #{path}" unless File.file?(path)
51
+
52
+ File.expand_path(path)
53
+ end
54
+
55
+ def existing_library_path(artifact)
56
+ Distribution.cache_directories(env: @env, home: @home, host_os: @host_os).each do |directory|
57
+ path = File.join(directory, "lib", artifact.fetch(:library))
58
+ return path if File.file?(path)
59
+ end
60
+ nil
61
+ end
62
+
63
+ def install_artifact(artifact)
64
+ cache_dir = clean_path
65
+ archive_path = File.join(cache_dir, artifact.fetch(:archive))
66
+ library_path = File.join(cache_dir, "lib", artifact.fetch(:library))
67
+ FileUtils.mkdir_p(cache_dir)
68
+
69
+ @output.puts "Downloading wgpu-native #{Distribution::VERSION} from GitHub..."
70
+ @output.puts " URL: #{Distribution.release_url(artifact)}"
71
+ download_file(Distribution.release_url(artifact), archive_path)
72
+ verify_checksum!(archive_path, artifact.fetch(:sha256))
73
+
74
+ @output.puts "Extracting to #{cache_dir}..."
75
+ extract_zip(archive_path, cache_dir)
76
+ raise InstallError, "Archive did not contain lib/#{artifact.fetch(:library)}" unless File.file?(library_path)
77
+
78
+ @output.puts "wgpu-native installed successfully!"
79
+ library_path
80
+ ensure
81
+ FileUtils.rm_f(archive_path) if archive_path
82
+ end
83
+
84
+ def verify_checksum!(path, expected)
85
+ actual = Digest::SHA256.file(path).hexdigest
86
+ return if actual == expected
87
+
88
+ FileUtils.rm_f(path)
89
+ raise InstallError, "SHA-256 mismatch for #{File.basename(path)} (expected #{expected}, got #{actual})"
90
+ end
91
+
92
+ def download_file(url, destination)
93
+ return if curl_available? && download_with_curl(url, destination)
94
+ return if download_with_ruby(url, destination)
95
+
96
+ raise InstallError, "Download failed: #{url}"
97
+ end
98
+
99
+ def curl_available?
100
+ system("curl", "--version", out: File::NULL, err: File::NULL)
101
+ end
102
+
103
+ def download_with_curl(url, destination)
104
+ system("curl", "-fsSL", "-o", destination, url)
105
+ end
106
+
107
+ def download_with_ruby(url, destination, redirects = 5)
108
+ raise InstallError, "Too many redirects while downloading #{url}" if redirects.zero?
109
+
110
+ uri = URI.parse(url)
111
+ http = Net::HTTP.new(uri.host, uri.port)
112
+ http.use_ssl = uri.scheme == "https"
113
+ http.open_timeout = 10
114
+ http.read_timeout = 120
115
+
116
+ http.request(Net::HTTP::Get.new(uri.request_uri)) do |response|
117
+ case response
118
+ when Net::HTTPRedirection
119
+ location = response["location"]
120
+ raise InstallError, "Redirect response did not include a location" unless location
121
+
122
+ location = URI.join(url, location).to_s
123
+ return download_with_ruby(location, destination, redirects - 1)
124
+ when Net::HTTPSuccess
125
+ File.open(destination, "wb") do |file|
126
+ response.read_body { |chunk| file.write(chunk) }
127
+ end
128
+ return true
129
+ end
130
+ end
131
+
132
+ false
133
+ rescue SystemCallError, SocketError, URI::InvalidURIError => error
134
+ @output.puts "Ruby download failed: #{error.message}"
135
+ false
136
+ end
137
+
138
+ def extract_zip(archive_path, destination)
139
+ return if extract_with_rubyzip(archive_path, destination)
140
+ return if windows? && extract_with_powershell(archive_path, destination)
141
+ return if extract_with_unzip(archive_path, destination)
142
+
143
+ raise InstallError, "Failed to extract zip; install the rubyzip gem or a supported system extractor"
144
+ end
145
+
146
+ def extract_with_rubyzip(archive_path, destination)
147
+ require "zip"
148
+ destination_root = "#{File.expand_path(destination)}#{File::SEPARATOR}"
149
+
150
+ Zip::File.open(archive_path) do |zip_file|
151
+ zip_file.each do |entry|
152
+ target = File.expand_path(entry.name, destination)
153
+ unless target.start_with?(destination_root)
154
+ raise InstallError, "Archive entry escapes destination: #{entry.name}"
155
+ end
156
+
157
+ FileUtils.mkdir_p(entry.directory? ? target : File.dirname(target))
158
+ entry.extract(target) { true } unless entry.directory?
159
+ end
160
+ end
161
+ true
162
+ rescue LoadError
163
+ false
164
+ end
165
+
166
+ def extract_with_powershell(archive_path, destination)
167
+ system(
168
+ "powershell",
169
+ "-NoProfile",
170
+ "-Command",
171
+ "Expand-Archive -Force -LiteralPath '#{archive_path}' -DestinationPath '#{destination}'"
172
+ )
173
+ end
174
+
175
+ def extract_with_unzip(archive_path, destination)
176
+ system("unzip", "-o", "-q", archive_path, "-d", destination)
177
+ end
178
+
179
+ def windows?
180
+ /mingw|mswin/.match?(platform)
181
+ end
182
+
183
+ def recovery_instructions
184
+ <<~INSTRUCTIONS.chomp
185
+ Download the matching #{Distribution::VERSION} artifact manually and set:
186
+ WGPU_LIB_PATH=/absolute/path/to/the/wgpu-native/shared-library
187
+ See docs/installation.md for platform details.
188
+ INSTRUCTIONS
189
+ end
190
+ end
191
+ end
192
+ end
@@ -1,53 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ffi"
4
- require "rbconfig"
4
+ require_relative "distribution"
5
5
 
6
6
  module WGPU
7
7
  module Native
8
- extend FFI::Library
8
+ module OptionalFunctions
9
+ def attach_optional_function(name, arguments, result)
10
+ attach_function(name, arguments, result)
11
+ optional_functions[name] = true
12
+ rescue FFI::NotFoundError
13
+ optional_functions[name] = false
14
+ define_singleton_method(name) do |*|
15
+ raise WGPU::Error,
16
+ "Optional wgpu-native function #{name} is unavailable in the loaded library " \
17
+ "(expected #{Distribution::VERSION})"
18
+ end
19
+ end
20
+
21
+ def optional_function_available?(name)
22
+ optional_functions.fetch(name, false)
23
+ end
24
+
25
+ def optional_capabilities
26
+ optional_functions.dup.freeze
27
+ end
28
+
29
+ private
9
30
 
10
- WGPU_VERSION = "v27.0.4.0"
31
+ def optional_functions
32
+ @optional_functions ||= {}
33
+ end
34
+ end
35
+
36
+ extend FFI::Library
37
+ extend OptionalFunctions
11
38
 
12
39
  class << self
13
40
  def library_path
14
- if ENV["WGPU_LIB_PATH"]
15
- path = ENV["WGPU_LIB_PATH"]
41
+ if ENV["WGPU_LIB_PATH"] && !ENV["WGPU_LIB_PATH"].empty?
42
+ path = File.expand_path(ENV["WGPU_LIB_PATH"])
16
43
  raise LoadError, "WGPU_LIB_PATH points to non-existent file: #{path}" unless File.exist?(path)
17
44
  return path
18
45
  end
19
46
 
20
- cached_path = File.join(cache_dir, "lib", library_name)
21
- return cached_path if File.exist?(cached_path)
47
+ cached_path = Distribution.library_paths.find { |path| File.file?(path) }
48
+ return cached_path if cached_path
22
49
 
23
50
  raise LoadError, <<~MSG
24
51
  wgpu-native library not found.
25
- Expected at: #{cached_path}
52
+ Searched:
53
+ #{Distribution.library_paths.join("\n ")}
26
54
 
27
55
  Try reinstalling the gem:
28
56
  gem install wgpu
29
57
 
30
58
  Or set WGPU_LIB_PATH environment variable to your custom wgpu-native build.
59
+ See docs/installation.md for manual installation instructions.
31
60
  MSG
32
61
  end
33
62
 
34
63
  def cache_dir
35
- File.join(Dir.home, ".cache", "wgpu-ruby", WGPU_VERSION)
64
+ Distribution.primary_cache_dir
36
65
  end
37
66
 
38
67
  def library_name
39
- case host_os
40
- when /linux/ then "libwgpu_native.so"
41
- when /darwin/ then "libwgpu_native.dylib"
42
- when /mingw|mswin/ then "wgpu_native.dll"
43
- else raise LoadError, "Unsupported OS: #{host_os}"
44
- end
45
- end
46
-
47
- private
48
-
49
- def host_os
50
- RbConfig::CONFIG["host_os"]
68
+ Distribution.artifact_for.fetch(:library)
51
69
  end
52
70
  end
53
71
 
@@ -59,3 +77,4 @@ require_relative "enums"
59
77
  require_relative "structs"
60
78
  require_relative "callbacks"
61
79
  require_relative "functions"
80
+ require_relative "capabilities"
@@ -17,6 +17,15 @@ module WGPU
17
17
  :s_type, SType
18
18
  end
19
19
 
20
+ class Future < FFI::Struct
21
+ layout :id, :uint64
22
+ end
23
+
24
+ class FutureWaitInfo < FFI::Struct
25
+ layout :future, Future.by_value,
26
+ :completed, :uint32
27
+ end
28
+
20
29
  class InstanceCapabilities < FFI::Struct
21
30
  layout :next_in_chain, :pointer,
22
31
  :timed_wait_any_enable, :uint32,
@@ -58,13 +67,15 @@ module WGPU
58
67
  layout :next_in_chain, :pointer,
59
68
  :mode, :uint32,
60
69
  :callback, :pointer,
61
- :userdata, :pointer
70
+ :userdata1, :pointer,
71
+ :userdata2, :pointer
62
72
  end
63
73
 
64
74
  class UncapturedErrorCallbackInfo < FFI::Struct
65
75
  layout :next_in_chain, :pointer,
66
76
  :callback, :pointer,
67
- :userdata, :pointer
77
+ :userdata1, :pointer,
78
+ :userdata2, :pointer
68
79
  end
69
80
 
70
81
  class PopErrorScopeCallbackInfo < FFI::Struct
@@ -355,21 +366,24 @@ module WGPU
355
366
  layout :next_in_chain, :pointer,
356
367
  :mode, :uint32,
357
368
  :callback, :pointer,
358
- :userdata, :pointer
369
+ :userdata1, :pointer,
370
+ :userdata2, :pointer
359
371
  end
360
372
 
361
373
  class RequestDeviceCallbackInfo < FFI::Struct
362
374
  layout :next_in_chain, :pointer,
363
375
  :mode, :uint32,
364
376
  :callback, :pointer,
365
- :userdata, :pointer
377
+ :userdata1, :pointer,
378
+ :userdata2, :pointer
366
379
  end
367
380
 
368
381
  class BufferMapCallbackInfo < FFI::Struct
369
382
  layout :next_in_chain, :pointer,
370
383
  :mode, :uint32,
371
384
  :callback, :pointer,
372
- :userdata, :pointer
385
+ :userdata1, :pointer,
386
+ :userdata2, :pointer
373
387
  end
374
388
 
375
389
  class TextureViewDescriptor < FFI::Struct