wgpu 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/lib/wgpu/core/adapter.rb +15 -11
- data/lib/wgpu/core/async_waiter.rb +64 -0
- data/lib/wgpu/core/device.rb +26 -14
- data/lib/wgpu/core/instance.rb +1 -1
- data/lib/wgpu/core/queue.rb +4 -11
- data/lib/wgpu/native/callbacks.rb +6 -6
- data/lib/wgpu/native/capabilities.rb +15 -0
- data/lib/wgpu/native/enums.rb +22 -5
- data/lib/wgpu/native/functions.rb +17 -8
- data/lib/wgpu/native/loader.rb +1 -0
- data/lib/wgpu/native/structs.rb +19 -5
- data/lib/wgpu/pipeline/shader_module.rb +4 -7
- data/lib/wgpu/resources/buffer.rb +24 -16
- data/lib/wgpu/version.rb +1 -1
- data/lib/wgpu.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd711bce02ed7be442c0f636460bf55f23df6e9b26cb7a6f07ed1b48b99ca78b
|
|
4
|
+
data.tar.gz: f6ffe9530b72876da7b91805ab22b9a20dd065857bfc7fe99c66a79823fb4c75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3430e9a25cdc932eb8441903b9f5f5aa83ebdafd34d56311ac8f794240a983b9adb6745fef484293dc968fb76b7e1f5da7813faa5a63b46b46126bb817e1b2eb
|
|
7
|
+
data.tar.gz: 75b6031fc4e7654541e6e8596434f8c1e3c4b24d89a16d5b946a29a40ba8da0b6082e395d8ac0a47928e7bc56b2e1e473a350051d78b9a9e6edc4945d293deed
|
data/lib/wgpu/core/adapter.rb
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module WGPU
|
|
4
4
|
class Adapter
|
|
5
|
-
attr_reader :handle
|
|
5
|
+
attr_reader :handle, :instance
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def self.from_handle(handle)
|
|
7
|
+
def self.from_handle(handle, instance: nil)
|
|
10
8
|
adapter = allocate
|
|
11
9
|
adapter.instance_variable_set(:@handle, handle)
|
|
10
|
+
adapter.instance_variable_set(:@instance, instance)
|
|
12
11
|
adapter
|
|
13
12
|
end
|
|
14
13
|
|
|
@@ -17,13 +16,14 @@ module WGPU
|
|
|
17
16
|
status_holder = { value: nil, message: nil }
|
|
18
17
|
|
|
19
18
|
callback = FFI::Function.new(
|
|
20
|
-
:void, [:uint32, :pointer, Native::StringView.by_value, :pointer]
|
|
21
|
-
) do |status, adapter, message,
|
|
19
|
+
:void, [:uint32, :pointer, Native::StringView.by_value, :pointer, :pointer]
|
|
20
|
+
) do |status, adapter, message, _userdata1, _userdata2|
|
|
22
21
|
status_holder[:value] = Native::RequestAdapterStatus[status]
|
|
23
22
|
if message[:data] && !message[:data].null? && message[:length] > 0
|
|
24
23
|
status_holder[:message] = message[:data].read_string(message[:length])
|
|
25
24
|
end
|
|
26
25
|
adapter_ptr.write_pointer(adapter)
|
|
26
|
+
status_holder[:done] = true
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
options = Native::RequestAdapterOptions.new
|
|
@@ -36,11 +36,14 @@ module WGPU
|
|
|
36
36
|
|
|
37
37
|
callback_info = Native::RequestAdapterCallbackInfo.new
|
|
38
38
|
callback_info[:next_in_chain] = nil
|
|
39
|
-
callback_info[:mode] =
|
|
39
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: instance)
|
|
40
40
|
callback_info[:callback] = callback
|
|
41
|
-
callback_info[:
|
|
41
|
+
callback_info[:userdata1] = nil
|
|
42
|
+
callback_info[:userdata2] = nil
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
status_holder[:done] = false
|
|
45
|
+
future = Native.wgpuInstanceRequestAdapter(instance.handle, options, callback_info)
|
|
46
|
+
AsyncWaiter.wait(status_holder: status_holder, instance: instance, future: future)
|
|
44
47
|
|
|
45
48
|
handle = adapter_ptr.read_pointer
|
|
46
49
|
if handle.null? || status_holder[:value] != :success
|
|
@@ -48,11 +51,12 @@ module WGPU
|
|
|
48
51
|
raise AdapterError, "Failed to request adapter: #{msg}"
|
|
49
52
|
end
|
|
50
53
|
|
|
51
|
-
new(handle)
|
|
54
|
+
new(handle, instance: instance)
|
|
52
55
|
end
|
|
53
56
|
|
|
54
|
-
def initialize(handle)
|
|
57
|
+
def initialize(handle, instance: nil)
|
|
55
58
|
@handle = handle
|
|
59
|
+
@instance = instance
|
|
56
60
|
end
|
|
57
61
|
|
|
58
62
|
def request_device(label: nil, required_features: [], required_limits: nil)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WGPU
|
|
4
|
+
module AsyncWaiter
|
|
5
|
+
POLL_INTERVAL_SECONDS = 0.001
|
|
6
|
+
CALLBACK_MODE_FALLBACK = {
|
|
7
|
+
allow_process_events: 2,
|
|
8
|
+
allow_spontaneous: 3
|
|
9
|
+
}.freeze
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def callback_mode(instance:)
|
|
14
|
+
if instance
|
|
15
|
+
callback_mode_value(:allow_process_events)
|
|
16
|
+
else
|
|
17
|
+
callback_mode_value(:allow_spontaneous)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wait(status_holder:, instance: nil, device: nil, future: nil)
|
|
22
|
+
wait_info = build_wait_info(future) if instance && Native.future_api?
|
|
23
|
+
|
|
24
|
+
until status_holder[:done]
|
|
25
|
+
if instance && wait_info
|
|
26
|
+
wait_with_wait_any(instance, wait_info)
|
|
27
|
+
elsif instance
|
|
28
|
+
instance.process_events
|
|
29
|
+
elsif device && Native.device_poll_available?
|
|
30
|
+
Native.wgpuDevicePoll(device.handle, 0, nil)
|
|
31
|
+
end
|
|
32
|
+
sleep(POLL_INTERVAL_SECONDS) unless status_holder[:done]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def callback_mode_value(name)
|
|
37
|
+
Native::CallbackMode[name] || CALLBACK_MODE_FALLBACK.fetch(name)
|
|
38
|
+
end
|
|
39
|
+
private_class_method :callback_mode_value
|
|
40
|
+
|
|
41
|
+
def build_wait_info(future)
|
|
42
|
+
return nil unless future.respond_to?(:[])
|
|
43
|
+
|
|
44
|
+
id = future[:id].to_i
|
|
45
|
+
return nil if id.zero?
|
|
46
|
+
|
|
47
|
+
wait_info = Native::FutureWaitInfo.new
|
|
48
|
+
wait_info[:future] = future
|
|
49
|
+
wait_info[:completed] = 0
|
|
50
|
+
wait_info
|
|
51
|
+
rescue StandardError
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
private_class_method :build_wait_info
|
|
55
|
+
|
|
56
|
+
def wait_with_wait_any(instance, wait_info)
|
|
57
|
+
status = Native.wgpuInstanceWaitAny(instance.handle, 1, wait_info.to_ptr, 0)
|
|
58
|
+
return if [:success, :timed_out].include?(status)
|
|
59
|
+
|
|
60
|
+
raise Error, "wgpuInstanceWaitAny failed: #{status.inspect}"
|
|
61
|
+
end
|
|
62
|
+
private_class_method :wait_with_wait_any
|
|
63
|
+
end
|
|
64
|
+
end
|
data/lib/wgpu/core/device.rb
CHANGED
|
@@ -4,21 +4,21 @@ module WGPU
|
|
|
4
4
|
class Device
|
|
5
5
|
attr_reader :handle, :queue, :adapter
|
|
6
6
|
|
|
7
|
-
CALLBACK_MODE_WAIT_ANY_ONLY = 1
|
|
8
7
|
LIMIT_FIELDS = Native::Limits.members.freeze
|
|
9
8
|
|
|
10
9
|
def self.request(adapter, label: nil, required_features: [], required_limits: nil)
|
|
11
10
|
device_ptr = FFI::MemoryPointer.new(:pointer)
|
|
12
|
-
status_holder = { value: nil, message: nil }
|
|
11
|
+
status_holder = { done: false, value: nil, message: nil }
|
|
13
12
|
|
|
14
13
|
callback = FFI::Function.new(
|
|
15
|
-
:void, [:uint32, :pointer, Native::StringView.by_value, :pointer]
|
|
16
|
-
) do |status, device, message,
|
|
14
|
+
:void, [:uint32, :pointer, Native::StringView.by_value, :pointer, :pointer]
|
|
15
|
+
) do |status, device, message, _userdata1, _userdata2|
|
|
17
16
|
status_holder[:value] = Native::RequestDeviceStatus[status]
|
|
18
17
|
if message[:data] && !message[:data].null? && message[:length] > 0
|
|
19
18
|
status_holder[:message] = message[:data].read_string(message[:length])
|
|
20
19
|
end
|
|
21
20
|
device_ptr.write_pointer(device)
|
|
21
|
+
status_holder[:done] = true
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
queue_desc = Native::QueueDescriptor.new
|
|
@@ -30,12 +30,14 @@ module WGPU
|
|
|
30
30
|
device_lost_info[:next_in_chain] = nil
|
|
31
31
|
device_lost_info[:mode] = 0
|
|
32
32
|
device_lost_info[:callback] = nil
|
|
33
|
-
device_lost_info[:
|
|
33
|
+
device_lost_info[:userdata1] = nil
|
|
34
|
+
device_lost_info[:userdata2] = nil
|
|
34
35
|
|
|
35
36
|
error_info = Native::UncapturedErrorCallbackInfo.new
|
|
36
37
|
error_info[:next_in_chain] = nil
|
|
37
38
|
error_info[:callback] = nil
|
|
38
|
-
error_info[:
|
|
39
|
+
error_info[:userdata1] = nil
|
|
40
|
+
error_info[:userdata2] = nil
|
|
39
41
|
|
|
40
42
|
desc = Native::DeviceDescriptor.new
|
|
41
43
|
desc[:next_in_chain] = nil
|
|
@@ -67,11 +69,13 @@ module WGPU
|
|
|
67
69
|
|
|
68
70
|
callback_info = Native::RequestDeviceCallbackInfo.new
|
|
69
71
|
callback_info[:next_in_chain] = nil
|
|
70
|
-
callback_info[:mode] =
|
|
72
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: adapter.instance)
|
|
71
73
|
callback_info[:callback] = callback
|
|
72
|
-
callback_info[:
|
|
74
|
+
callback_info[:userdata1] = nil
|
|
75
|
+
callback_info[:userdata2] = nil
|
|
73
76
|
|
|
74
|
-
Native.wgpuAdapterRequestDevice(adapter.handle, desc, callback_info)
|
|
77
|
+
future = Native.wgpuAdapterRequestDevice(adapter.handle, desc, callback_info)
|
|
78
|
+
AsyncWaiter.wait(status_holder: status_holder, instance: adapter.instance, future: future)
|
|
75
79
|
|
|
76
80
|
handle = device_ptr.read_pointer
|
|
77
81
|
if handle.null? || status_holder[:value] != :success
|
|
@@ -235,7 +239,12 @@ module WGPU
|
|
|
235
239
|
end
|
|
236
240
|
|
|
237
241
|
def poll(wait: false)
|
|
238
|
-
Native.
|
|
242
|
+
if Native.device_poll_available?
|
|
243
|
+
Native.wgpuDevicePoll(@handle, wait ? 1 : 0, nil)
|
|
244
|
+
else
|
|
245
|
+
@adapter&.instance&.process_events
|
|
246
|
+
0
|
|
247
|
+
end
|
|
239
248
|
end
|
|
240
249
|
|
|
241
250
|
def push_error_scope(filter = :validation)
|
|
@@ -243,11 +252,13 @@ module WGPU
|
|
|
243
252
|
end
|
|
244
253
|
|
|
245
254
|
def pop_error_scope
|
|
246
|
-
error_holder = { type: nil, message: nil }
|
|
255
|
+
error_holder = { done: false, status: nil, type: nil, message: nil }
|
|
247
256
|
|
|
248
257
|
callback = FFI::Function.new(
|
|
249
258
|
:void, [:uint32, :uint32, Native::StringView.by_value, :pointer, :pointer]
|
|
250
|
-
) do |
|
|
259
|
+
) do |status, error_type, message, _userdata1, _userdata2|
|
|
260
|
+
error_holder[:done] = true
|
|
261
|
+
error_holder[:status] = Native::PopErrorScopeStatus[status]
|
|
251
262
|
error_holder[:type] = Native::ErrorType[error_type]
|
|
252
263
|
if message[:data] && !message[:data].null? && message[:length] > 0
|
|
253
264
|
error_holder[:message] = message[:data].read_string(message[:length])
|
|
@@ -256,12 +267,13 @@ module WGPU
|
|
|
256
267
|
|
|
257
268
|
callback_info = Native::PopErrorScopeCallbackInfo.new
|
|
258
269
|
callback_info[:next_in_chain] = nil
|
|
259
|
-
callback_info[:mode] =
|
|
270
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: @adapter&.instance)
|
|
260
271
|
callback_info[:callback] = callback
|
|
261
272
|
callback_info[:userdata1] = nil
|
|
262
273
|
callback_info[:userdata2] = nil
|
|
263
274
|
|
|
264
|
-
Native.wgpuDevicePopErrorScope(@handle, callback_info)
|
|
275
|
+
future = Native.wgpuDevicePopErrorScope(@handle, callback_info)
|
|
276
|
+
AsyncWaiter.wait(status_holder: error_holder, instance: @adapter&.instance, device: self, future: future)
|
|
265
277
|
|
|
266
278
|
error_holder
|
|
267
279
|
end
|
data/lib/wgpu/core/instance.rb
CHANGED
data/lib/wgpu/core/queue.rb
CHANGED
|
@@ -133,6 +133,7 @@ module WGPU
|
|
|
133
133
|
|
|
134
134
|
def on_submitted_work_done(device: nil)
|
|
135
135
|
device ||= @device
|
|
136
|
+
instance = device&.adapter&.instance
|
|
136
137
|
status_holder = { done: false, status: nil }
|
|
137
138
|
|
|
138
139
|
callback = FFI::Function.new(
|
|
@@ -144,21 +145,13 @@ module WGPU
|
|
|
144
145
|
|
|
145
146
|
callback_info = Native::QueueWorkDoneCallbackInfo.new
|
|
146
147
|
callback_info[:next_in_chain] = nil
|
|
147
|
-
callback_info[:mode] =
|
|
148
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: instance)
|
|
148
149
|
callback_info[:callback] = callback
|
|
149
150
|
callback_info[:userdata1] = nil
|
|
150
151
|
callback_info[:userdata2] = nil
|
|
151
152
|
|
|
152
|
-
Native.wgpuQueueOnSubmittedWorkDone(@handle, callback_info)
|
|
153
|
-
|
|
154
|
-
if device
|
|
155
|
-
until status_holder[:done]
|
|
156
|
-
Native.wgpuDevicePoll(device.handle, 0, nil)
|
|
157
|
-
sleep(0.001)
|
|
158
|
-
end
|
|
159
|
-
else
|
|
160
|
-
sleep(0.001) until status_holder[:done]
|
|
161
|
-
end
|
|
153
|
+
future = Native.wgpuQueueOnSubmittedWorkDone(@handle, callback_info)
|
|
154
|
+
AsyncWaiter.wait(status_holder: status_holder, instance: instance, device: device, future: future)
|
|
162
155
|
|
|
163
156
|
status_holder[:status]
|
|
164
157
|
end
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
module WGPU
|
|
4
4
|
module Native
|
|
5
5
|
callback :request_adapter_callback,
|
|
6
|
-
[RequestAdapterStatus, :pointer, StringView.by_value, :pointer], :void
|
|
6
|
+
[RequestAdapterStatus, :pointer, StringView.by_value, :pointer, :pointer], :void
|
|
7
7
|
|
|
8
8
|
callback :request_device_callback,
|
|
9
|
-
[RequestDeviceStatus, :pointer, StringView.by_value, :pointer], :void
|
|
9
|
+
[RequestDeviceStatus, :pointer, StringView.by_value, :pointer, :pointer], :void
|
|
10
10
|
|
|
11
11
|
callback :buffer_map_callback,
|
|
12
|
-
[MapAsyncStatus, :pointer], :void
|
|
12
|
+
[MapAsyncStatus, StringView.by_value, :pointer, :pointer], :void
|
|
13
13
|
|
|
14
|
-
callback :
|
|
15
|
-
[:
|
|
14
|
+
callback :uncaptured_error_callback,
|
|
15
|
+
[:pointer, ErrorType, StringView.by_value, :pointer, :pointer], :void
|
|
16
16
|
|
|
17
17
|
callback :device_lost_callback,
|
|
18
|
-
[:pointer, :uint32, StringView.by_value, :pointer], :void
|
|
18
|
+
[:pointer, :uint32, StringView.by_value, :pointer, :pointer], :void
|
|
19
19
|
|
|
20
20
|
callback :pop_error_scope_callback,
|
|
21
21
|
[PopErrorScopeStatus, ErrorType, StringView.by_value, :pointer, :pointer], :void
|
data/lib/wgpu/native/enums.rb
CHANGED
|
@@ -50,13 +50,15 @@ 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
|
|
60
62
|
)
|
|
61
63
|
|
|
62
64
|
BufferMapState = enum(
|
|
@@ -65,11 +67,18 @@ module WGPU
|
|
|
65
67
|
:mapped, 0x00000003
|
|
66
68
|
)
|
|
67
69
|
|
|
70
|
+
CallbackMode = enum(
|
|
71
|
+
:wait_any_only, 0x00000001,
|
|
72
|
+
:allow_process_events, 0x00000002,
|
|
73
|
+
:allow_spontaneous, 0x00000003
|
|
74
|
+
)
|
|
75
|
+
|
|
68
76
|
MapAsyncStatus = enum(
|
|
69
77
|
:success, 0x00000001,
|
|
70
78
|
:instance_dropped, 0x00000002,
|
|
71
79
|
:error, 0x00000003,
|
|
72
|
-
:aborted, 0x00000004
|
|
80
|
+
:aborted, 0x00000004,
|
|
81
|
+
:unknown, 0x00000005
|
|
73
82
|
)
|
|
74
83
|
|
|
75
84
|
BufferUsage = {
|
|
@@ -482,8 +491,16 @@ module WGPU
|
|
|
482
491
|
|
|
483
492
|
PopErrorScopeStatus = enum(
|
|
484
493
|
:success, 0x00000001,
|
|
485
|
-
:
|
|
486
|
-
:
|
|
494
|
+
:instance_dropped, 0x00000002,
|
|
495
|
+
:empty_stack, 0x00000003
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
WaitStatus = enum(
|
|
499
|
+
:success, 0x00000001,
|
|
500
|
+
:timed_out, 0x00000002,
|
|
501
|
+
:unsupported_timeout, 0x00000003,
|
|
502
|
+
:unsupported_count, 0x00000004,
|
|
503
|
+
:unsupported_mixed_sources, 0x00000005
|
|
487
504
|
)
|
|
488
505
|
|
|
489
506
|
QueueWorkDoneStatus = enum(
|
|
@@ -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],
|
|
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,12 @@ module WGPU
|
|
|
17
17
|
attach_function :wgpuInstanceProcessEvents,
|
|
18
18
|
[:pointer], :void
|
|
19
19
|
|
|
20
|
+
begin
|
|
21
|
+
attach_function :wgpuInstanceWaitAny,
|
|
22
|
+
[:pointer, :size_t, :pointer, :uint64], WaitStatus
|
|
23
|
+
rescue FFI::NotFoundError
|
|
24
|
+
end
|
|
25
|
+
|
|
20
26
|
attach_function :wgpuAdapterRelease,
|
|
21
27
|
[:pointer], :void
|
|
22
28
|
|
|
@@ -24,7 +30,7 @@ module WGPU
|
|
|
24
30
|
[:pointer, AdapterInfo.by_ref], :void
|
|
25
31
|
|
|
26
32
|
attach_function :wgpuAdapterRequestDevice,
|
|
27
|
-
[:pointer, DeviceDescriptor.by_ref, RequestDeviceCallbackInfo.by_value],
|
|
33
|
+
[:pointer, DeviceDescriptor.by_ref, RequestDeviceCallbackInfo.by_value], Future.by_value
|
|
28
34
|
|
|
29
35
|
attach_function :wgpuAdapterGetFeatures,
|
|
30
36
|
[:pointer, :pointer], :void
|
|
@@ -71,8 +77,11 @@ module WGPU
|
|
|
71
77
|
attach_function :wgpuDeviceCreateCommandEncoder,
|
|
72
78
|
[:pointer, CommandEncoderDescriptor.by_ref], :pointer
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
begin
|
|
81
|
+
attach_function :wgpuDevicePoll,
|
|
82
|
+
[:pointer, :uint32, :pointer], :uint32
|
|
83
|
+
rescue FFI::NotFoundError
|
|
84
|
+
end
|
|
76
85
|
|
|
77
86
|
attach_function :wgpuQueueRelease,
|
|
78
87
|
[:pointer], :void
|
|
@@ -81,7 +90,7 @@ module WGPU
|
|
|
81
90
|
[:pointer, :size_t, :pointer], :void
|
|
82
91
|
|
|
83
92
|
attach_function :wgpuQueueOnSubmittedWorkDone,
|
|
84
|
-
[:pointer, QueueWorkDoneCallbackInfo.by_value],
|
|
93
|
+
[:pointer, QueueWorkDoneCallbackInfo.by_value], Future.by_value
|
|
85
94
|
|
|
86
95
|
attach_function :wgpuQueueWriteBuffer,
|
|
87
96
|
[:pointer, :pointer, :uint64, :pointer, :size_t], :void
|
|
@@ -96,7 +105,7 @@ module WGPU
|
|
|
96
105
|
[:pointer], :void
|
|
97
106
|
|
|
98
107
|
attach_function :wgpuBufferMapAsync,
|
|
99
|
-
[:pointer, :uint64, :size_t, :size_t, BufferMapCallbackInfo.by_value],
|
|
108
|
+
[:pointer, :uint64, :size_t, :size_t, BufferMapCallbackInfo.by_value], Future.by_value
|
|
100
109
|
|
|
101
110
|
attach_function :wgpuBufferUnmap,
|
|
102
111
|
[:pointer], :void
|
|
@@ -120,7 +129,7 @@ module WGPU
|
|
|
120
129
|
[:pointer], :void
|
|
121
130
|
|
|
122
131
|
attach_function :wgpuShaderModuleGetCompilationInfo,
|
|
123
|
-
[:pointer, CompilationInfoCallbackInfo.by_value],
|
|
132
|
+
[:pointer, CompilationInfoCallbackInfo.by_value], Future.by_value
|
|
124
133
|
|
|
125
134
|
attach_function :wgpuCommandEncoderRelease,
|
|
126
135
|
[:pointer], :void
|
|
@@ -363,7 +372,7 @@ module WGPU
|
|
|
363
372
|
[:pointer, ErrorFilter], :void
|
|
364
373
|
|
|
365
374
|
attach_function :wgpuDevicePopErrorScope,
|
|
366
|
-
[:pointer, PopErrorScopeCallbackInfo.by_value],
|
|
375
|
+
[:pointer, PopErrorScopeCallbackInfo.by_value], Future.by_value
|
|
367
376
|
|
|
368
377
|
attach_function :wgpuComputePipelineGetBindGroupLayout,
|
|
369
378
|
[:pointer, :uint32], :pointer
|
data/lib/wgpu/native/loader.rb
CHANGED
data/lib/wgpu/native/structs.rb
CHANGED
|
@@ -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
|
-
:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
385
|
+
:userdata1, :pointer,
|
|
386
|
+
:userdata2, :pointer
|
|
373
387
|
end
|
|
374
388
|
|
|
375
389
|
class TextureViewDescriptor < FFI::Struct
|
|
@@ -35,6 +35,7 @@ module WGPU
|
|
|
35
35
|
|
|
36
36
|
def get_compilation_info
|
|
37
37
|
result_holder = { done: false, status: nil, messages: [] }
|
|
38
|
+
instance = @device.adapter&.instance
|
|
38
39
|
|
|
39
40
|
callback = FFI::Function.new(
|
|
40
41
|
:void, [:uint32, :pointer, :pointer, :pointer]
|
|
@@ -69,17 +70,13 @@ module WGPU
|
|
|
69
70
|
|
|
70
71
|
callback_info = Native::CompilationInfoCallbackInfo.new
|
|
71
72
|
callback_info[:next_in_chain] = nil
|
|
72
|
-
callback_info[:mode] =
|
|
73
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: instance)
|
|
73
74
|
callback_info[:callback] = callback
|
|
74
75
|
callback_info[:userdata1] = nil
|
|
75
76
|
callback_info[:userdata2] = nil
|
|
76
77
|
|
|
77
|
-
Native.wgpuShaderModuleGetCompilationInfo(@handle, callback_info)
|
|
78
|
-
|
|
79
|
-
until result_holder[:done]
|
|
80
|
-
Native.wgpuDevicePoll(@device.handle, 0, nil)
|
|
81
|
-
sleep(0.001)
|
|
82
|
-
end
|
|
78
|
+
future = Native.wgpuShaderModuleGetCompilationInfo(@handle, callback_info)
|
|
79
|
+
AsyncWaiter.wait(status_holder: result_holder, instance: instance, device: @device, future: future)
|
|
83
80
|
|
|
84
81
|
{
|
|
85
82
|
status: result_holder[:status],
|
|
@@ -60,17 +60,17 @@ module WGPU
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def map_sync(mode, offset: 0, size: nil)
|
|
63
|
-
status_holder, callback = begin_map_request(mode, offset: offset, size: size)
|
|
64
|
-
wait_for_map(status_holder)
|
|
63
|
+
status_holder, callback, future = begin_map_request(mode, offset: offset, size: size)
|
|
64
|
+
wait_for_map(status_holder, future)
|
|
65
65
|
finalize_map(status_holder)
|
|
66
66
|
ensure
|
|
67
67
|
@map_callbacks.delete(callback) if callback
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def map_async(mode, offset: 0, size: nil)
|
|
71
|
-
status_holder, callback = begin_map_request(mode, offset: offset, size: size)
|
|
71
|
+
status_holder, callback, future = begin_map_request(mode, offset: offset, size: size)
|
|
72
72
|
AsyncTask.new do
|
|
73
|
-
wait_for_map(status_holder)
|
|
73
|
+
wait_for_map(status_holder, future)
|
|
74
74
|
finalize_map(status_holder)
|
|
75
75
|
ensure
|
|
76
76
|
@map_callbacks.delete(callback)
|
|
@@ -137,29 +137,35 @@ module WGPU
|
|
|
137
137
|
else raise ArgumentError, "Invalid map mode: #{mode}"
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
-
status_holder = { done: false, status: nil }
|
|
141
|
-
callback = FFI::Function.new(:void, [:uint32, :pointer]) do |status,
|
|
140
|
+
status_holder = { done: false, status: nil, message: nil }
|
|
141
|
+
callback = FFI::Function.new(:void, [:uint32, Native::StringView.by_value, :pointer, :pointer]) do |status, message, _userdata1, _userdata2|
|
|
142
142
|
status_holder[:done] = true
|
|
143
143
|
status_holder[:status] = Native::MapAsyncStatus[status]
|
|
144
|
+
if message[:data] && !message[:data].null? && message[:length] > 0
|
|
145
|
+
status_holder[:message] = message[:data].read_string(message[:length])
|
|
146
|
+
end
|
|
144
147
|
end
|
|
145
148
|
@map_callbacks << callback
|
|
146
149
|
|
|
147
150
|
callback_info = Native::BufferMapCallbackInfo.new
|
|
148
151
|
callback_info[:next_in_chain] = nil
|
|
149
|
-
callback_info[:mode] =
|
|
152
|
+
callback_info[:mode] = AsyncWaiter.callback_mode(instance: @device.adapter&.instance)
|
|
150
153
|
callback_info[:callback] = callback
|
|
151
|
-
callback_info[:
|
|
154
|
+
callback_info[:userdata1] = nil
|
|
155
|
+
callback_info[:userdata2] = nil
|
|
152
156
|
|
|
153
|
-
Native.wgpuBufferMapAsync(@handle, mode_flag, offset, size, callback_info)
|
|
157
|
+
future = Native.wgpuBufferMapAsync(@handle, mode_flag, offset, size, callback_info)
|
|
154
158
|
|
|
155
|
-
[status_holder, callback]
|
|
159
|
+
[status_holder, callback, future]
|
|
156
160
|
end
|
|
157
161
|
|
|
158
|
-
def wait_for_map(status_holder)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
def wait_for_map(status_holder, future)
|
|
163
|
+
AsyncWaiter.wait(
|
|
164
|
+
status_holder: status_holder,
|
|
165
|
+
instance: @device.adapter&.instance,
|
|
166
|
+
device: @device,
|
|
167
|
+
future: future
|
|
168
|
+
)
|
|
163
169
|
end
|
|
164
170
|
|
|
165
171
|
def finalize_map(status_holder)
|
|
@@ -167,7 +173,9 @@ module WGPU
|
|
|
167
173
|
@mapped = true
|
|
168
174
|
true
|
|
169
175
|
else
|
|
170
|
-
|
|
176
|
+
detail = status_holder[:message]
|
|
177
|
+
base = "Failed to map buffer: #{status_holder[:status]}"
|
|
178
|
+
raise BufferError, detail && !detail.empty? ? "#{base} (#{detail})" : base
|
|
171
179
|
end
|
|
172
180
|
end
|
|
173
181
|
|
data/lib/wgpu/version.rb
CHANGED
data/lib/wgpu.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative "wgpu/version"
|
|
|
4
4
|
require_relative "wgpu/error"
|
|
5
5
|
require_relative "wgpu/native/loader"
|
|
6
6
|
require_relative "wgpu/async_task"
|
|
7
|
+
require_relative "wgpu/core/async_waiter"
|
|
7
8
|
|
|
8
9
|
require_relative "wgpu/resources/buffer"
|
|
9
10
|
require_relative "wgpu/resources/texture"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wgpu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yudai Takada
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- lib/wgpu/commands/render_bundle_encoder.rb
|
|
75
75
|
- lib/wgpu/commands/render_pass.rb
|
|
76
76
|
- lib/wgpu/core/adapter.rb
|
|
77
|
+
- lib/wgpu/core/async_waiter.rb
|
|
77
78
|
- lib/wgpu/core/canvas_context.rb
|
|
78
79
|
- lib/wgpu/core/device.rb
|
|
79
80
|
- lib/wgpu/core/instance.rb
|
|
@@ -81,6 +82,7 @@ files:
|
|
|
81
82
|
- lib/wgpu/core/surface.rb
|
|
82
83
|
- lib/wgpu/error.rb
|
|
83
84
|
- lib/wgpu/native/callbacks.rb
|
|
85
|
+
- lib/wgpu/native/capabilities.rb
|
|
84
86
|
- lib/wgpu/native/enums.rb
|
|
85
87
|
- lib/wgpu/native/functions.rb
|
|
86
88
|
- lib/wgpu/native/loader.rb
|