wgpu 1.2.0 → 1.2.1
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/CHANGELOG.md +40 -0
- data/README.md +18 -2
- data/docs/README.md +2 -2
- data/docs/api_coverage.md +23 -15
- data/docs/async.md +10 -0
- data/docs/command_encoding.md +25 -0
- data/docs/getting_started_compute.md +1 -0
- data/docs/pipeline_descriptors.md +7 -2
- data/docs/releasing.md +11 -1
- data/docs/resource_lifetime.md +16 -2
- data/docs/texture_readback.md +27 -0
- data/docs/troubleshooting.md +5 -0
- data/docs/upgrading_wgpu_native.md +16 -5
- data/lib/wgpu/async_task.rb +19 -0
- data/lib/wgpu/commands/command_buffer.rb +14 -1
- data/lib/wgpu/commands/command_encoder.rb +58 -1
- data/lib/wgpu/commands/compute_pass.rb +43 -0
- data/lib/wgpu/commands/render_bundle.rb +9 -1
- data/lib/wgpu/commands/render_bundle_encoder.rb +55 -1
- data/lib/wgpu/commands/render_pass.rb +102 -0
- data/lib/wgpu/core/adapter.rb +91 -12
- data/lib/wgpu/core/async_waiter.rb +15 -0
- data/lib/wgpu/core/canvas_context.rb +32 -0
- data/lib/wgpu/core/device.rb +296 -46
- data/lib/wgpu/core/instance.rb +20 -0
- data/lib/wgpu/core/queue.rb +139 -24
- data/lib/wgpu/core/surface.rb +49 -1
- data/lib/wgpu/data_types.rb +16 -0
- data/lib/wgpu/descriptor_helpers.rb +65 -0
- data/lib/wgpu/error.rb +15 -0
- data/lib/wgpu/native/abi_verifier.rb +37 -3
- data/lib/wgpu/native/callbacks.rb +6 -0
- data/lib/wgpu/native/capabilities.rb +16 -2
- data/lib/wgpu/native/distribution.rb +63 -0
- data/lib/wgpu/native/enum_helper.rb +17 -0
- data/lib/wgpu/native/enums.rb +8 -0
- data/lib/wgpu/native/fixtures/webgpu-v27.0.4.0-enums.h +848 -0
- data/lib/wgpu/native/functions.rb +11 -0
- data/lib/wgpu/native/installer.rb +48 -17
- data/lib/wgpu/native/loader.rb +22 -0
- data/lib/wgpu/native/structs.rb +18 -1
- data/lib/wgpu/native_resource.rb +174 -3
- data/lib/wgpu/pipeline/bind_group.rb +9 -0
- data/lib/wgpu/pipeline/bind_group_layout.rb +17 -4
- data/lib/wgpu/pipeline/compute_pipeline.rb +20 -32
- data/lib/wgpu/pipeline/pipeline_layout.rb +8 -0
- data/lib/wgpu/pipeline/render_pipeline.rb +27 -42
- data/lib/wgpu/pipeline/shader_module.rb +54 -29
- data/lib/wgpu/resources/buffer.rb +258 -31
- data/lib/wgpu/resources/query_set.rb +12 -0
- data/lib/wgpu/resources/sampler.rb +7 -0
- data/lib/wgpu/resources/texture.rb +45 -6
- data/lib/wgpu/resources/texture_view.rb +24 -4
- data/lib/wgpu/texture_format.rb +14 -0
- data/lib/wgpu/version.rb +1 -1
- data/lib/wgpu/window.rb +26 -0
- data/sig/wgpu.rbs +84 -5
- metadata +3 -1
|
@@ -4,6 +4,10 @@ module WGPU
|
|
|
4
4
|
class CommandEncoder
|
|
5
5
|
attr_reader :handle
|
|
6
6
|
|
|
7
|
+
# Creates an encoder for commands submitted to a device queue.
|
|
8
|
+
# @param device [Device] owning device
|
|
9
|
+
# @param label [String, nil] optional debug label
|
|
10
|
+
# @raise [CommandError] if the native encoder cannot be created
|
|
7
11
|
def initialize(device, label: nil)
|
|
8
12
|
@device = device
|
|
9
13
|
@finished = false
|
|
@@ -24,6 +28,11 @@ module WGPU
|
|
|
24
28
|
raise CommandError, "Failed to create command encoder" if @handle.null?
|
|
25
29
|
end
|
|
26
30
|
|
|
31
|
+
# Begins a compute pass, optionally yielding it for scoped recording.
|
|
32
|
+
# @param label [String, nil] optional debug label
|
|
33
|
+
# @param timestamp_writes [Hash, nil] timestamp query settings
|
|
34
|
+
# @yieldparam pass [ComputePass] newly created pass
|
|
35
|
+
# @return [ComputePass, Object] pass without a block, otherwise the block result
|
|
27
36
|
def begin_compute_pass(label: nil, timestamp_writes: nil)
|
|
28
37
|
ensure_can_begin_pass!
|
|
29
38
|
pass = ComputePass.new(self, label: label, timestamp_writes: timestamp_writes)
|
|
@@ -42,6 +51,10 @@ module WGPU
|
|
|
42
51
|
end
|
|
43
52
|
end
|
|
44
53
|
|
|
54
|
+
# Begins a render pass, optionally yielding it for scoped recording.
|
|
55
|
+
# @param color_attachments [Array<Hash>] color attachment descriptors
|
|
56
|
+
# @yieldparam pass [RenderPass] newly created pass
|
|
57
|
+
# @return [RenderPass, Object] pass without a block, otherwise the block result
|
|
45
58
|
def begin_render_pass(color_attachments:, depth_stencil_attachment: nil, occlusion_query_set: nil, timestamp_writes: nil, max_draw_count: nil, label: nil)
|
|
46
59
|
ensure_can_begin_pass!
|
|
47
60
|
pass = RenderPass.new(self,
|
|
@@ -67,6 +80,8 @@ module WGPU
|
|
|
67
80
|
end
|
|
68
81
|
end
|
|
69
82
|
|
|
83
|
+
# Copies bytes between buffers.
|
|
84
|
+
# @return [void]
|
|
70
85
|
def copy_buffer_to_buffer(source:, source_offset: 0, destination:, destination_offset: 0, size:)
|
|
71
86
|
raise CommandError, "Encoder already finished" if @finished
|
|
72
87
|
Native.wgpuCommandEncoderCopyBufferToBuffer(
|
|
@@ -77,6 +92,11 @@ module WGPU
|
|
|
77
92
|
)
|
|
78
93
|
end
|
|
79
94
|
|
|
95
|
+
# Copies buffer data into a texture region.
|
|
96
|
+
# @param source [Hash] buffer and layout descriptor
|
|
97
|
+
# @param destination [Hash] texture and origin descriptor
|
|
98
|
+
# @param copy_size [Hash, Array] extent to copy
|
|
99
|
+
# @return [void]
|
|
80
100
|
def copy_buffer_to_texture(source:, destination:, copy_size:)
|
|
81
101
|
raise CommandError, "Encoder already finished" if @finished
|
|
82
102
|
|
|
@@ -106,6 +126,11 @@ module WGPU
|
|
|
106
126
|
Native.wgpuCommandEncoderCopyBufferToTexture(@handle, src, dst, size)
|
|
107
127
|
end
|
|
108
128
|
|
|
129
|
+
# Copies a texture region into a buffer.
|
|
130
|
+
# @param source [Hash] texture and origin descriptor
|
|
131
|
+
# @param destination [Hash] buffer and layout descriptor
|
|
132
|
+
# @param copy_size [Hash, Array] extent to copy
|
|
133
|
+
# @return [void]
|
|
109
134
|
def copy_texture_to_buffer(source:, destination:, copy_size:)
|
|
110
135
|
raise CommandError, "Encoder already finished" if @finished
|
|
111
136
|
|
|
@@ -135,6 +160,11 @@ module WGPU
|
|
|
135
160
|
Native.wgpuCommandEncoderCopyTextureToBuffer(@handle, src, dst, size)
|
|
136
161
|
end
|
|
137
162
|
|
|
163
|
+
# Copies one texture region into another texture.
|
|
164
|
+
# @param source [Hash] source texture and origin descriptor
|
|
165
|
+
# @param destination [Hash] destination texture and origin descriptor
|
|
166
|
+
# @param copy_size [Hash, Array] extent to copy
|
|
167
|
+
# @return [void]
|
|
138
168
|
def copy_texture_to_texture(source:, destination:, copy_size:)
|
|
139
169
|
raise CommandError, "Encoder already finished" if @finished
|
|
140
170
|
|
|
@@ -170,6 +200,8 @@ module WGPU
|
|
|
170
200
|
Native.wgpuCommandEncoderCopyTextureToTexture(@handle, src, dst, size)
|
|
171
201
|
end
|
|
172
202
|
|
|
203
|
+
# Resolves query results into a destination buffer.
|
|
204
|
+
# @return [void]
|
|
173
205
|
def resolve_query_set(query_set:, first_query:, query_count:, destination:, destination_offset:)
|
|
174
206
|
raise CommandError, "Encoder already finished" if @finished
|
|
175
207
|
Native.wgpuCommandEncoderResolveQuerySet(
|
|
@@ -182,17 +214,29 @@ module WGPU
|
|
|
182
214
|
)
|
|
183
215
|
end
|
|
184
216
|
|
|
217
|
+
# Clears a byte range in a buffer to zero.
|
|
218
|
+
# @param buffer [Buffer] buffer to clear
|
|
219
|
+
# @param offset [Integer] first byte to clear
|
|
220
|
+
# @param size [Integer, nil] number of bytes to clear
|
|
221
|
+
# @return [void]
|
|
185
222
|
def clear_buffer(buffer, offset: 0, size: nil)
|
|
186
223
|
raise CommandError, "Encoder already finished" if @finished
|
|
187
224
|
size ||= buffer.size - offset
|
|
188
225
|
Native.wgpuCommandEncoderClearBuffer(@handle, buffer.handle, offset, size)
|
|
189
226
|
end
|
|
190
227
|
|
|
228
|
+
# Writes a GPU timestamp to a query set.
|
|
229
|
+
# @param query_set [QuerySet] timestamp query set
|
|
230
|
+
# @param query_index [Integer] destination query index
|
|
231
|
+
# @return [void]
|
|
191
232
|
def write_timestamp(query_set, query_index)
|
|
192
233
|
raise CommandError, "Encoder already finished" if @finished
|
|
193
234
|
Native.wgpuCommandEncoderWriteTimestamp(@handle, query_set.handle, query_index)
|
|
194
235
|
end
|
|
195
236
|
|
|
237
|
+
# Starts a labeled group in GPU debugging tools.
|
|
238
|
+
# @param label [String] group label
|
|
239
|
+
# @return [void]
|
|
196
240
|
def push_debug_group(label)
|
|
197
241
|
raise CommandError, "Encoder already finished" if @finished
|
|
198
242
|
label_view = Native::StringView.new
|
|
@@ -202,11 +246,16 @@ module WGPU
|
|
|
202
246
|
Native.wgpuCommandEncoderPushDebugGroup(@handle, label_view)
|
|
203
247
|
end
|
|
204
248
|
|
|
249
|
+
# Ends the most recently pushed debug group.
|
|
250
|
+
# @return [void]
|
|
205
251
|
def pop_debug_group
|
|
206
252
|
raise CommandError, "Encoder already finished" if @finished
|
|
207
253
|
Native.wgpuCommandEncoderPopDebugGroup(@handle)
|
|
208
254
|
end
|
|
209
255
|
|
|
256
|
+
# Inserts a labeled point in GPU debugging tools.
|
|
257
|
+
# @param label [String] marker label
|
|
258
|
+
# @return [void]
|
|
210
259
|
def insert_debug_marker(label)
|
|
211
260
|
raise CommandError, "Encoder already finished" if @finished
|
|
212
261
|
label_view = Native::StringView.new
|
|
@@ -216,6 +265,10 @@ module WGPU
|
|
|
216
265
|
Native.wgpuCommandEncoderInsertDebugMarker(@handle, label_view)
|
|
217
266
|
end
|
|
218
267
|
|
|
268
|
+
# Finishes recording and returns a command buffer.
|
|
269
|
+
# @param label [String, nil] optional command buffer label
|
|
270
|
+
# @return [CommandBuffer]
|
|
271
|
+
# @raise [CommandError] if the encoder is finished, has an active pass, or native creation fails
|
|
219
272
|
def finish(label: nil)
|
|
220
273
|
raise CommandError, "Encoder already finished" if @finished
|
|
221
274
|
if @active_pass && !@active_pass.ended?
|
|
@@ -235,9 +288,13 @@ module WGPU
|
|
|
235
288
|
buffer_handle = Native.wgpuCommandEncoderFinish(@handle, desc)
|
|
236
289
|
raise CommandError, "Failed to finish command encoder" if buffer_handle.null?
|
|
237
290
|
|
|
238
|
-
CommandBuffer.new(buffer_handle)
|
|
291
|
+
CommandBuffer.new(buffer_handle, device: @device)
|
|
239
292
|
end
|
|
240
293
|
|
|
294
|
+
# Releases the native command encoder handle.
|
|
295
|
+
#
|
|
296
|
+
# Calling this method more than once has no effect.
|
|
297
|
+
# @return [void]
|
|
241
298
|
def release
|
|
242
299
|
return if @handle.null?
|
|
243
300
|
Native.wgpuCommandEncoderRelease(@handle)
|
|
@@ -4,6 +4,11 @@ module WGPU
|
|
|
4
4
|
class ComputePass
|
|
5
5
|
attr_reader :handle
|
|
6
6
|
|
|
7
|
+
# Begins a compute pass owned by the command encoder.
|
|
8
|
+
# @param encoder [CommandEncoder] owning encoder
|
|
9
|
+
# @param label [String, nil] optional debug label
|
|
10
|
+
# @param timestamp_writes [Hash, nil] beginning and ending timestamp query settings
|
|
11
|
+
# @raise [CommandError] if the native pass cannot be created
|
|
7
12
|
def initialize(encoder, label: nil, timestamp_writes: nil)
|
|
8
13
|
@encoder = encoder
|
|
9
14
|
@ended = false
|
|
@@ -32,10 +37,18 @@ module WGPU
|
|
|
32
37
|
raise CommandError, "Failed to begin compute pass" if @handle.null?
|
|
33
38
|
end
|
|
34
39
|
|
|
40
|
+
# Selects the compute pipeline used by subsequent dispatches.
|
|
41
|
+
# @param pipeline [ComputePipeline] pipeline to bind
|
|
42
|
+
# @return [void]
|
|
35
43
|
def set_pipeline(pipeline)
|
|
36
44
|
Native.wgpuComputePassEncoderSetPipeline(@handle, pipeline.handle)
|
|
37
45
|
end
|
|
38
46
|
|
|
47
|
+
# Binds a resource group for subsequent dispatches.
|
|
48
|
+
# @param index [Integer] bind group index
|
|
49
|
+
# @param bind_group [BindGroup] group to bind
|
|
50
|
+
# @param dynamic_offsets [Array<Integer>] dynamic buffer offsets
|
|
51
|
+
# @return [void]
|
|
39
52
|
def set_bind_group(index, bind_group, dynamic_offsets: [])
|
|
40
53
|
if dynamic_offsets.empty?
|
|
41
54
|
Native.wgpuComputePassEncoderSetBindGroup(@handle, index, bind_group.handle, 0, nil)
|
|
@@ -46,14 +59,27 @@ module WGPU
|
|
|
46
59
|
end
|
|
47
60
|
end
|
|
48
61
|
|
|
62
|
+
# Dispatches a three-dimensional compute workgroup grid.
|
|
63
|
+
# @param x [Integer] workgroup count on the x axis
|
|
64
|
+
# @param y [Integer] workgroup count on the y axis
|
|
65
|
+
# @param z [Integer] workgroup count on the z axis
|
|
66
|
+
# @return [void]
|
|
49
67
|
def dispatch_workgroups(x, y = 1, z = 1)
|
|
50
68
|
Native.wgpuComputePassEncoderDispatchWorkgroups(@handle, x, y, z)
|
|
51
69
|
end
|
|
52
70
|
|
|
71
|
+
# Dispatches workgroups using arguments read from a buffer.
|
|
72
|
+
# @param buffer [Buffer] indirect argument buffer
|
|
73
|
+
# @param offset [Integer] byte offset of the arguments
|
|
74
|
+
# @return [void]
|
|
53
75
|
def dispatch_workgroups_indirect(buffer, offset: 0)
|
|
54
76
|
Native.wgpuComputePassEncoderDispatchWorkgroupsIndirect(@handle, buffer.handle, offset)
|
|
55
77
|
end
|
|
56
78
|
|
|
79
|
+
# Starts a labeled group in GPU debugging tools.
|
|
80
|
+
#
|
|
81
|
+
# @param label [String] group label
|
|
82
|
+
# @return [void]
|
|
57
83
|
def push_debug_group(label)
|
|
58
84
|
label_view = Native::StringView.new
|
|
59
85
|
label_ptr = FFI::MemoryPointer.from_string(label)
|
|
@@ -62,10 +88,17 @@ module WGPU
|
|
|
62
88
|
Native.wgpuComputePassEncoderPushDebugGroup(@handle, label_view)
|
|
63
89
|
end
|
|
64
90
|
|
|
91
|
+
# Ends the most recently pushed debug group.
|
|
92
|
+
#
|
|
93
|
+
# @return [void]
|
|
65
94
|
def pop_debug_group
|
|
66
95
|
Native.wgpuComputePassEncoderPopDebugGroup(@handle)
|
|
67
96
|
end
|
|
68
97
|
|
|
98
|
+
# Inserts a labeled point in GPU debugging tools.
|
|
99
|
+
#
|
|
100
|
+
# @param label [String] marker label
|
|
101
|
+
# @return [void]
|
|
69
102
|
def insert_debug_marker(label)
|
|
70
103
|
label_view = Native::StringView.new
|
|
71
104
|
label_ptr = FFI::MemoryPointer.from_string(label)
|
|
@@ -74,6 +107,8 @@ module WGPU
|
|
|
74
107
|
Native.wgpuComputePassEncoderInsertDebugMarker(@handle, label_view)
|
|
75
108
|
end
|
|
76
109
|
|
|
110
|
+
# Ends the pass if it has not already ended.
|
|
111
|
+
# @return [void]
|
|
77
112
|
def end_pass
|
|
78
113
|
return if @ended
|
|
79
114
|
|
|
@@ -82,14 +117,22 @@ module WGPU
|
|
|
82
117
|
@encoder.send(:pass_ended, self)
|
|
83
118
|
end
|
|
84
119
|
|
|
120
|
+
# Ends the pass.
|
|
121
|
+
# @return [void]
|
|
85
122
|
def end
|
|
86
123
|
end_pass
|
|
87
124
|
end
|
|
88
125
|
|
|
126
|
+
# Reports whether the pass has ended.
|
|
127
|
+
# @return [Boolean]
|
|
89
128
|
def ended?
|
|
90
129
|
@ended
|
|
91
130
|
end
|
|
92
131
|
|
|
132
|
+
# Releases the native compute pass encoder handle.
|
|
133
|
+
#
|
|
134
|
+
# Calling this method more than once has no effect.
|
|
135
|
+
# @return [void]
|
|
93
136
|
def release
|
|
94
137
|
return if @handle.null?
|
|
95
138
|
Native.wgpuComputePassEncoderRelease(@handle)
|
|
@@ -4,10 +4,18 @@ module WGPU
|
|
|
4
4
|
class RenderBundle
|
|
5
5
|
attr_reader :handle
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# Wraps a reusable native render bundle.
|
|
8
|
+
# @param handle [FFI::Pointer] native render bundle handle
|
|
9
|
+
# @param device [Device, nil] device whose callbacks the render bundle may use
|
|
10
|
+
def initialize(handle, device: nil)
|
|
8
11
|
@handle = handle
|
|
12
|
+
@device = device
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
# Releases the native render bundle handle.
|
|
16
|
+
#
|
|
17
|
+
# Calling this method more than once has no effect.
|
|
18
|
+
# @return [void]
|
|
11
19
|
def release
|
|
12
20
|
return if @handle.null?
|
|
13
21
|
|
|
@@ -4,6 +4,15 @@ module WGPU
|
|
|
4
4
|
class RenderBundleEncoder
|
|
5
5
|
attr_reader :handle
|
|
6
6
|
|
|
7
|
+
# Creates an encoder for reusable render commands.
|
|
8
|
+
# @param device [Device] owning device
|
|
9
|
+
# @param color_formats [Array<Symbol, Integer>] color attachment formats
|
|
10
|
+
# @param depth_stencil_format [Symbol, Integer, nil] optional depth/stencil format
|
|
11
|
+
# @param sample_count [Integer] multisample count
|
|
12
|
+
# @param depth_read_only [Boolean] whether depth writes are disabled
|
|
13
|
+
# @param stencil_read_only [Boolean] whether stencil writes are disabled
|
|
14
|
+
# @param label [String, nil] optional debug label
|
|
15
|
+
# @raise [RenderBundleError] if the native encoder cannot be created
|
|
7
16
|
def initialize(device, color_formats:, depth_stencil_format: nil, sample_count: 1,
|
|
8
17
|
depth_read_only: false, stencil_read_only: false, label: nil)
|
|
9
18
|
@device = device
|
|
@@ -42,12 +51,21 @@ module WGPU
|
|
|
42
51
|
raise RenderBundleError, "Failed to create render bundle encoder" if @handle.null?
|
|
43
52
|
end
|
|
44
53
|
|
|
54
|
+
# Selects the pipeline used by subsequent bundle draws.
|
|
55
|
+
# @param pipeline [RenderPipeline] pipeline to bind
|
|
56
|
+
# @raise [RenderBundleError] if the encoder is finished
|
|
57
|
+
# @return [void]
|
|
45
58
|
def set_pipeline(pipeline)
|
|
46
59
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
47
60
|
|
|
48
61
|
Native.wgpuRenderBundleEncoderSetPipeline(@handle, pipeline.handle)
|
|
49
62
|
end
|
|
50
63
|
|
|
64
|
+
# Binds a resource group for subsequent bundle draws.
|
|
65
|
+
# @param index [Integer] bind group index
|
|
66
|
+
# @param bind_group [BindGroup] group to bind
|
|
67
|
+
# @param dynamic_offsets [Array<Integer>, nil] dynamic buffer offsets
|
|
68
|
+
# @return [void]
|
|
51
69
|
def set_bind_group(index, bind_group, dynamic_offsets: nil)
|
|
52
70
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
53
71
|
|
|
@@ -60,6 +78,10 @@ module WGPU
|
|
|
60
78
|
end
|
|
61
79
|
end
|
|
62
80
|
|
|
81
|
+
# Binds a vertex buffer to a slot.
|
|
82
|
+
# @param slot [Integer] vertex buffer slot
|
|
83
|
+
# @param buffer [Buffer] vertex data buffer
|
|
84
|
+
# @return [void]
|
|
63
85
|
def set_vertex_buffer(slot, buffer, offset: 0, size: nil)
|
|
64
86
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
65
87
|
|
|
@@ -67,6 +89,10 @@ module WGPU
|
|
|
67
89
|
Native.wgpuRenderBundleEncoderSetVertexBuffer(@handle, slot, buffer.handle, offset, size)
|
|
68
90
|
end
|
|
69
91
|
|
|
92
|
+
# Binds an index buffer for indexed bundle draws.
|
|
93
|
+
# @param buffer [Buffer] index data buffer
|
|
94
|
+
# @param format [Symbol, Integer] index element format
|
|
95
|
+
# @return [void]
|
|
70
96
|
def set_index_buffer(buffer, format: :uint32, offset: 0, size: nil)
|
|
71
97
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
72
98
|
|
|
@@ -75,30 +101,45 @@ module WGPU
|
|
|
75
101
|
Native.wgpuRenderBundleEncoderSetIndexBuffer(@handle, buffer.handle, format_value, offset, size)
|
|
76
102
|
end
|
|
77
103
|
|
|
104
|
+
# Records a non-indexed draw in the bundle.
|
|
105
|
+
# @return [void]
|
|
78
106
|
def draw(vertex_count, instance_count: 1, first_vertex: 0, first_instance: 0)
|
|
79
107
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
80
108
|
|
|
81
109
|
Native.wgpuRenderBundleEncoderDraw(@handle, vertex_count, instance_count, first_vertex, first_instance)
|
|
82
110
|
end
|
|
83
111
|
|
|
112
|
+
# Records an indexed draw in the bundle.
|
|
113
|
+
# @return [void]
|
|
84
114
|
def draw_indexed(index_count, instance_count: 1, first_index: 0, base_vertex: 0, first_instance: 0)
|
|
85
115
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
86
116
|
|
|
87
117
|
Native.wgpuRenderBundleEncoderDrawIndexed(@handle, index_count, instance_count, first_index, base_vertex, first_instance)
|
|
88
118
|
end
|
|
89
119
|
|
|
120
|
+
# Records a non-indexed draw using buffer arguments.
|
|
121
|
+
# @param buffer [Buffer] indirect argument buffer
|
|
122
|
+
# @param offset [Integer] byte offset of the arguments
|
|
123
|
+
# @return [void]
|
|
90
124
|
def draw_indirect(buffer, offset: 0)
|
|
91
125
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
92
126
|
|
|
93
127
|
Native.wgpuRenderBundleEncoderDrawIndirect(@handle, buffer.handle, offset)
|
|
94
128
|
end
|
|
95
129
|
|
|
130
|
+
# Records an indexed draw using buffer arguments.
|
|
131
|
+
# @param buffer [Buffer] indirect argument buffer
|
|
132
|
+
# @param offset [Integer] byte offset of the arguments
|
|
133
|
+
# @return [void]
|
|
96
134
|
def draw_indexed_indirect(buffer, offset: 0)
|
|
97
135
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
98
136
|
|
|
99
137
|
Native.wgpuRenderBundleEncoderDrawIndexedIndirect(@handle, buffer.handle, offset)
|
|
100
138
|
end
|
|
101
139
|
|
|
140
|
+
# Starts a labeled group in GPU debugging tools.
|
|
141
|
+
# @param label [String] group label
|
|
142
|
+
# @return [void]
|
|
102
143
|
def push_debug_group(label)
|
|
103
144
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
104
145
|
|
|
@@ -109,12 +150,17 @@ module WGPU
|
|
|
109
150
|
Native.wgpuRenderBundleEncoderPushDebugGroup(@handle, label_view)
|
|
110
151
|
end
|
|
111
152
|
|
|
153
|
+
# Ends the most recently pushed debug group.
|
|
154
|
+
# @return [void]
|
|
112
155
|
def pop_debug_group
|
|
113
156
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
114
157
|
|
|
115
158
|
Native.wgpuRenderBundleEncoderPopDebugGroup(@handle)
|
|
116
159
|
end
|
|
117
160
|
|
|
161
|
+
# Inserts a labeled point in GPU debugging tools.
|
|
162
|
+
# @param label [String] marker label
|
|
163
|
+
# @return [void]
|
|
118
164
|
def insert_debug_marker(label)
|
|
119
165
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
120
166
|
|
|
@@ -125,6 +171,10 @@ module WGPU
|
|
|
125
171
|
Native.wgpuRenderBundleEncoderInsertDebugMarker(@handle, label_view)
|
|
126
172
|
end
|
|
127
173
|
|
|
174
|
+
# Finishes recording and creates an immutable render bundle.
|
|
175
|
+
# @param label [String, nil] optional bundle label
|
|
176
|
+
# @return [RenderBundle]
|
|
177
|
+
# @raise [RenderBundleError] if already finished or native creation fails
|
|
128
178
|
def finish(label: nil)
|
|
129
179
|
raise RenderBundleError, "Encoder already finished" if @finished
|
|
130
180
|
|
|
@@ -142,9 +192,13 @@ module WGPU
|
|
|
142
192
|
bundle_handle = Native.wgpuRenderBundleEncoderFinish(@handle, desc)
|
|
143
193
|
raise RenderBundleError, "Failed to finish render bundle encoder" if bundle_handle.null?
|
|
144
194
|
|
|
145
|
-
RenderBundle.new(bundle_handle)
|
|
195
|
+
RenderBundle.new(bundle_handle, device: @device)
|
|
146
196
|
end
|
|
147
197
|
|
|
198
|
+
# Releases the native render bundle encoder handle.
|
|
199
|
+
#
|
|
200
|
+
# Calling this method more than once has no effect.
|
|
201
|
+
# @return [void]
|
|
148
202
|
def release
|
|
149
203
|
return if @handle.null?
|
|
150
204
|
|
|
@@ -4,6 +4,15 @@ module WGPU
|
|
|
4
4
|
class RenderPass
|
|
5
5
|
attr_reader :handle
|
|
6
6
|
|
|
7
|
+
# Begins a render pass owned by the command encoder.
|
|
8
|
+
# @param encoder [CommandEncoder] owning encoder
|
|
9
|
+
# @param label [String, nil] optional debug label
|
|
10
|
+
# @param color_attachments [Array<Hash>] color attachment descriptors
|
|
11
|
+
# @param depth_stencil_attachment [Hash, nil] depth/stencil attachment descriptor
|
|
12
|
+
# @param occlusion_query_set [QuerySet, nil] query set for occlusion queries
|
|
13
|
+
# @param timestamp_writes [Hash, nil] beginning and ending timestamp query settings
|
|
14
|
+
# @param max_draw_count [Integer, nil] implementation hint for the maximum draw count
|
|
15
|
+
# @raise [CommandError] if the native pass cannot be created
|
|
7
16
|
def initialize(encoder, label: nil, color_attachments:, depth_stencil_attachment: nil, occlusion_query_set: nil, timestamp_writes: nil, max_draw_count: nil)
|
|
8
17
|
@encoder = encoder
|
|
9
18
|
@pointers = []
|
|
@@ -41,10 +50,18 @@ module WGPU
|
|
|
41
50
|
raise CommandError, "Failed to begin render pass" if @handle.null?
|
|
42
51
|
end
|
|
43
52
|
|
|
53
|
+
# Selects the render pipeline used by subsequent draws.
|
|
54
|
+
# @param pipeline [RenderPipeline] pipeline to bind
|
|
55
|
+
# @return [void]
|
|
44
56
|
def set_pipeline(pipeline)
|
|
45
57
|
Native.wgpuRenderPassEncoderSetPipeline(@handle, pipeline.handle)
|
|
46
58
|
end
|
|
47
59
|
|
|
60
|
+
# Binds a resource group for subsequent draws.
|
|
61
|
+
# @param index [Integer] bind group index
|
|
62
|
+
# @param bind_group [BindGroup] group to bind
|
|
63
|
+
# @param dynamic_offsets [Array<Integer>] dynamic buffer offsets
|
|
64
|
+
# @return [void]
|
|
48
65
|
def set_bind_group(index, bind_group, dynamic_offsets: [])
|
|
49
66
|
if dynamic_offsets.empty?
|
|
50
67
|
Native.wgpuRenderPassEncoderSetBindGroup(@handle, index, bind_group.handle, 0, nil)
|
|
@@ -55,33 +72,72 @@ module WGPU
|
|
|
55
72
|
end
|
|
56
73
|
end
|
|
57
74
|
|
|
75
|
+
# Binds a vertex buffer to a slot.
|
|
76
|
+
# @param slot [Integer] vertex buffer slot
|
|
77
|
+
# @param buffer [Buffer] vertex data buffer
|
|
78
|
+
# @param offset [Integer] first byte to bind
|
|
79
|
+
# @param size [Integer, nil] number of bytes to bind
|
|
80
|
+
# @return [void]
|
|
58
81
|
def set_vertex_buffer(slot, buffer, offset: 0, size: nil)
|
|
59
82
|
size ||= buffer.size - offset
|
|
60
83
|
Native.wgpuRenderPassEncoderSetVertexBuffer(@handle, slot, buffer.handle, offset, size)
|
|
61
84
|
end
|
|
62
85
|
|
|
86
|
+
# Binds an index buffer for indexed draws.
|
|
87
|
+
# @param buffer [Buffer] index data buffer
|
|
88
|
+
# @param format [Symbol, Integer] index element format
|
|
89
|
+
# @param offset [Integer] first byte to bind
|
|
90
|
+
# @param size [Integer, nil] number of bytes to bind
|
|
91
|
+
# @return [void]
|
|
63
92
|
def set_index_buffer(buffer, format, offset: 0, size: nil)
|
|
64
93
|
size ||= buffer.size - offset
|
|
65
94
|
format_value = Native::EnumHelper.coerce(Native::IndexFormat, format, name: "index format")
|
|
66
95
|
Native.wgpuRenderPassEncoderSetIndexBuffer(@handle, buffer.handle, format_value, offset, size)
|
|
67
96
|
end
|
|
68
97
|
|
|
98
|
+
# Records a non-indexed draw.
|
|
99
|
+
# @return [void]
|
|
69
100
|
def draw(vertex_count, instance_count: 1, first_vertex: 0, first_instance: 0)
|
|
70
101
|
Native.wgpuRenderPassEncoderDraw(@handle, vertex_count, instance_count, first_vertex, first_instance)
|
|
71
102
|
end
|
|
72
103
|
|
|
104
|
+
# Records an indexed draw.
|
|
105
|
+
# @return [void]
|
|
73
106
|
def draw_indexed(index_count, instance_count: 1, first_index: 0, base_vertex: 0, first_instance: 0)
|
|
74
107
|
Native.wgpuRenderPassEncoderDrawIndexed(@handle, index_count, instance_count, first_index, base_vertex, first_instance)
|
|
75
108
|
end
|
|
76
109
|
|
|
110
|
+
# Sets the viewport used by subsequent draw calls.
|
|
111
|
+
#
|
|
112
|
+
# @param x [Numeric] left coordinate in pixels
|
|
113
|
+
# @param y [Numeric] top coordinate in pixels
|
|
114
|
+
# @param width [Numeric] viewport width in pixels
|
|
115
|
+
# @param height [Numeric] viewport height in pixels
|
|
116
|
+
# @param min_depth [Numeric] minimum depth value
|
|
117
|
+
# @param max_depth [Numeric] maximum depth value
|
|
118
|
+
# @return [void]
|
|
77
119
|
def set_viewport(x, y, width, height, min_depth: 0.0, max_depth: 1.0)
|
|
78
120
|
Native.wgpuRenderPassEncoderSetViewport(@handle, x, y, width, height, min_depth, max_depth)
|
|
79
121
|
end
|
|
80
122
|
|
|
123
|
+
# Restricts rasterization to a rectangular region.
|
|
124
|
+
#
|
|
125
|
+
# @param x [Integer] left coordinate in pixels
|
|
126
|
+
# @param y [Integer] top coordinate in pixels
|
|
127
|
+
# @param width [Integer] rectangle width in pixels
|
|
128
|
+
# @param height [Integer] rectangle height in pixels
|
|
129
|
+
# @return [void]
|
|
81
130
|
def set_scissor_rect(x, y, width, height)
|
|
82
131
|
Native.wgpuRenderPassEncoderSetScissorRect(@handle, x, y, width, height)
|
|
83
132
|
end
|
|
84
133
|
|
|
134
|
+
# Sets the constant color used by blend factors.
|
|
135
|
+
#
|
|
136
|
+
# @param r [Numeric] red component
|
|
137
|
+
# @param g [Numeric] green component
|
|
138
|
+
# @param b [Numeric] blue component
|
|
139
|
+
# @param a [Numeric] alpha component
|
|
140
|
+
# @return [void]
|
|
85
141
|
def set_blend_constant(r: 0.0, g: 0.0, b: 0.0, a: 1.0)
|
|
86
142
|
color = Native::Color.new
|
|
87
143
|
color[:r] = r
|
|
@@ -91,18 +147,36 @@ module WGPU
|
|
|
91
147
|
Native.wgpuRenderPassEncoderSetBlendConstant(@handle, color.to_ptr)
|
|
92
148
|
end
|
|
93
149
|
|
|
150
|
+
# Sets the stencil reference used by subsequent draw calls.
|
|
151
|
+
#
|
|
152
|
+
# @param reference [Integer] unsigned stencil reference
|
|
153
|
+
# @return [void]
|
|
94
154
|
def set_stencil_reference(reference)
|
|
95
155
|
Native.wgpuRenderPassEncoderSetStencilReference(@handle, reference)
|
|
96
156
|
end
|
|
97
157
|
|
|
158
|
+
# Draws using non-indexed arguments stored in a buffer.
|
|
159
|
+
#
|
|
160
|
+
# @param buffer [Buffer] buffer containing the indirect arguments
|
|
161
|
+
# @param offset [Integer] byte offset of the arguments
|
|
162
|
+
# @return [void]
|
|
98
163
|
def draw_indirect(buffer, offset: 0)
|
|
99
164
|
Native.wgpuRenderPassEncoderDrawIndirect(@handle, buffer.handle, offset)
|
|
100
165
|
end
|
|
101
166
|
|
|
167
|
+
# Draws using indexed arguments stored in a buffer.
|
|
168
|
+
#
|
|
169
|
+
# @param buffer [Buffer] buffer containing the indirect arguments
|
|
170
|
+
# @param offset [Integer] byte offset of the arguments
|
|
171
|
+
# @return [void]
|
|
102
172
|
def draw_indexed_indirect(buffer, offset: 0)
|
|
103
173
|
Native.wgpuRenderPassEncoderDrawIndexedIndirect(@handle, buffer.handle, offset)
|
|
104
174
|
end
|
|
105
175
|
|
|
176
|
+
# Executes pre-recorded render bundles.
|
|
177
|
+
#
|
|
178
|
+
# @param bundles [Array<RenderBundle>] bundles to execute in order
|
|
179
|
+
# @return [void]
|
|
106
180
|
def execute_bundles(bundles)
|
|
107
181
|
bundle_handles = bundles.map(&:handle)
|
|
108
182
|
bundles_ptr = FFI::MemoryPointer.new(:pointer, bundle_handles.size)
|
|
@@ -110,14 +184,25 @@ module WGPU
|
|
|
110
184
|
Native.wgpuRenderPassEncoderExecuteBundles(@handle, bundle_handles.size, bundles_ptr)
|
|
111
185
|
end
|
|
112
186
|
|
|
187
|
+
# Begins an occlusion query for subsequent draw calls.
|
|
188
|
+
#
|
|
189
|
+
# @param query_index [Integer] destination index in the pass query set
|
|
190
|
+
# @return [void]
|
|
113
191
|
def begin_occlusion_query(query_index)
|
|
114
192
|
Native.wgpuRenderPassEncoderBeginOcclusionQuery(@handle, query_index)
|
|
115
193
|
end
|
|
116
194
|
|
|
195
|
+
# Ends the active occlusion query.
|
|
196
|
+
#
|
|
197
|
+
# @return [void]
|
|
117
198
|
def end_occlusion_query
|
|
118
199
|
Native.wgpuRenderPassEncoderEndOcclusionQuery(@handle)
|
|
119
200
|
end
|
|
120
201
|
|
|
202
|
+
# Starts a labeled group in GPU debugging tools.
|
|
203
|
+
#
|
|
204
|
+
# @param label [String] group label
|
|
205
|
+
# @return [void]
|
|
121
206
|
def push_debug_group(label)
|
|
122
207
|
label_view = Native::StringView.new
|
|
123
208
|
label_ptr = FFI::MemoryPointer.from_string(label)
|
|
@@ -126,10 +211,17 @@ module WGPU
|
|
|
126
211
|
Native.wgpuRenderPassEncoderPushDebugGroup(@handle, label_view)
|
|
127
212
|
end
|
|
128
213
|
|
|
214
|
+
# Ends the most recently pushed debug group.
|
|
215
|
+
#
|
|
216
|
+
# @return [void]
|
|
129
217
|
def pop_debug_group
|
|
130
218
|
Native.wgpuRenderPassEncoderPopDebugGroup(@handle)
|
|
131
219
|
end
|
|
132
220
|
|
|
221
|
+
# Inserts a labeled point in GPU debugging tools.
|
|
222
|
+
#
|
|
223
|
+
# @param label [String] marker label
|
|
224
|
+
# @return [void]
|
|
133
225
|
def insert_debug_marker(label)
|
|
134
226
|
label_view = Native::StringView.new
|
|
135
227
|
label_ptr = FFI::MemoryPointer.from_string(label)
|
|
@@ -138,6 +230,8 @@ module WGPU
|
|
|
138
230
|
Native.wgpuRenderPassEncoderInsertDebugMarker(@handle, label_view)
|
|
139
231
|
end
|
|
140
232
|
|
|
233
|
+
# Ends the pass if it has not already ended.
|
|
234
|
+
# @return [void]
|
|
141
235
|
def end_pass
|
|
142
236
|
return if @ended
|
|
143
237
|
|
|
@@ -146,14 +240,22 @@ module WGPU
|
|
|
146
240
|
@encoder.send(:pass_ended, self)
|
|
147
241
|
end
|
|
148
242
|
|
|
243
|
+
# Ends the pass.
|
|
244
|
+
# @return [void]
|
|
149
245
|
def end
|
|
150
246
|
end_pass
|
|
151
247
|
end
|
|
152
248
|
|
|
249
|
+
# Reports whether the pass has ended.
|
|
250
|
+
# @return [Boolean]
|
|
153
251
|
def ended?
|
|
154
252
|
@ended
|
|
155
253
|
end
|
|
156
254
|
|
|
255
|
+
# Releases the native render pass encoder handle.
|
|
256
|
+
#
|
|
257
|
+
# Calling this method more than once has no effect.
|
|
258
|
+
# @return [void]
|
|
157
259
|
def release
|
|
158
260
|
return if @handle.null?
|
|
159
261
|
Native.wgpuRenderPassEncoderRelease(@handle)
|