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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +18 -2
  4. data/docs/README.md +2 -2
  5. data/docs/api_coverage.md +23 -15
  6. data/docs/async.md +10 -0
  7. data/docs/command_encoding.md +25 -0
  8. data/docs/getting_started_compute.md +1 -0
  9. data/docs/pipeline_descriptors.md +7 -2
  10. data/docs/releasing.md +11 -1
  11. data/docs/resource_lifetime.md +16 -2
  12. data/docs/texture_readback.md +27 -0
  13. data/docs/troubleshooting.md +5 -0
  14. data/docs/upgrading_wgpu_native.md +16 -5
  15. data/lib/wgpu/async_task.rb +19 -0
  16. data/lib/wgpu/commands/command_buffer.rb +14 -1
  17. data/lib/wgpu/commands/command_encoder.rb +58 -1
  18. data/lib/wgpu/commands/compute_pass.rb +43 -0
  19. data/lib/wgpu/commands/render_bundle.rb +9 -1
  20. data/lib/wgpu/commands/render_bundle_encoder.rb +55 -1
  21. data/lib/wgpu/commands/render_pass.rb +102 -0
  22. data/lib/wgpu/core/adapter.rb +91 -12
  23. data/lib/wgpu/core/async_waiter.rb +15 -0
  24. data/lib/wgpu/core/canvas_context.rb +32 -0
  25. data/lib/wgpu/core/device.rb +296 -46
  26. data/lib/wgpu/core/instance.rb +20 -0
  27. data/lib/wgpu/core/queue.rb +139 -24
  28. data/lib/wgpu/core/surface.rb +49 -1
  29. data/lib/wgpu/data_types.rb +16 -0
  30. data/lib/wgpu/descriptor_helpers.rb +65 -0
  31. data/lib/wgpu/error.rb +15 -0
  32. data/lib/wgpu/native/abi_verifier.rb +37 -3
  33. data/lib/wgpu/native/callbacks.rb +6 -0
  34. data/lib/wgpu/native/capabilities.rb +16 -2
  35. data/lib/wgpu/native/distribution.rb +63 -0
  36. data/lib/wgpu/native/enum_helper.rb +17 -0
  37. data/lib/wgpu/native/enums.rb +8 -0
  38. data/lib/wgpu/native/fixtures/webgpu-v27.0.4.0-enums.h +848 -0
  39. data/lib/wgpu/native/functions.rb +11 -0
  40. data/lib/wgpu/native/installer.rb +48 -17
  41. data/lib/wgpu/native/loader.rb +22 -0
  42. data/lib/wgpu/native/structs.rb +18 -1
  43. data/lib/wgpu/native_resource.rb +174 -3
  44. data/lib/wgpu/pipeline/bind_group.rb +9 -0
  45. data/lib/wgpu/pipeline/bind_group_layout.rb +17 -4
  46. data/lib/wgpu/pipeline/compute_pipeline.rb +20 -32
  47. data/lib/wgpu/pipeline/pipeline_layout.rb +8 -0
  48. data/lib/wgpu/pipeline/render_pipeline.rb +27 -42
  49. data/lib/wgpu/pipeline/shader_module.rb +54 -29
  50. data/lib/wgpu/resources/buffer.rb +258 -31
  51. data/lib/wgpu/resources/query_set.rb +12 -0
  52. data/lib/wgpu/resources/sampler.rb +7 -0
  53. data/lib/wgpu/resources/texture.rb +45 -6
  54. data/lib/wgpu/resources/texture_view.rb +24 -4
  55. data/lib/wgpu/texture_format.rb +14 -0
  56. data/lib/wgpu/version.rb +1 -1
  57. data/lib/wgpu/window.rb +26 -0
  58. data/sig/wgpu.rbs +84 -5
  59. 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
- def initialize(handle)
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)