Class: WGPU::CommandEncoder

Inherits:
Object
  • Object
show all
Includes:
NativeResource
Defined in:
lib/wgpu/commands/command_encoder.rb,
sig/wgpu.rbs

Constant Summary

Constants included from NativeResource

NativeResource::GUARDED_METHOD_EXEMPTIONS

Instance Attribute Summary collapse

Attributes included from NativeResource

#label

Instance Method Summary collapse

Methods included from NativeResource

checked_handle, included, #inspect, #released?, #use

Constructor Details

#initialize(device, label: nil) ⇒ CommandEncoder

Creates an encoder for commands submitted to a device queue.

Parameters:

  • device (Device)

    owning device

  • label (String, nil) (defaults to: nil)

    optional debug label

Raises:

  • (CommandError)

    if the native encoder cannot be created



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/wgpu/commands/command_encoder.rb', line 11

def initialize(device, label: nil)
  @device = device
  @finished = false
  @active_pass = nil

  desc = Native::CommandEncoderDescriptor.new
  desc[:next_in_chain] = nil
  if label
    label_ptr = FFI::MemoryPointer.from_string(label)
    desc[:label][:data] = label_ptr
    desc[:label][:length] = label.bytesize
  else
    desc[:label][:data] = nil
    desc[:label][:length] = 0
  end

  @handle = Native.wgpuDeviceCreateCommandEncoder(NativeResource.checked_handle(device, expected_class: Device), desc)
  raise CommandError, "Failed to create command encoder" if @handle.null?
end

Instance Attribute Details

#handleObject (readonly)

Returns the value of attribute handle.

Returns:

  • (Object)


5
6
7
# File 'lib/wgpu/commands/command_encoder.rb', line 5

def handle
  @handle
end

Instance Method Details

#begin_compute_pass(arg0) ⇒ ComputePass #begin_compute_passvoid

Begins a compute pass, optionally yielding it for scoped recording.

Overloads:

  • #begin_compute_pass(arg0) ⇒ ComputePass

    Parameters:

    • arg0 (Object)

    Returns:

  • #begin_compute_passvoid

    This method returns an undefined value.

Parameters:

  • label (String, nil) (defaults to: nil)

    optional debug label

  • timestamp_writes (Hash, nil) (defaults to: nil)

    timestamp query settings

Yield Parameters:

Returns:

  • (ComputePass, Object)

    pass without a block, otherwise the block result



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/wgpu/commands/command_encoder.rb', line 36

def begin_compute_pass(label: nil, timestamp_writes: nil)
  ensure_can_begin_pass!
  pass = ComputePass.new(self, label: label, timestamp_writes: timestamp_writes)
  @active_pass = pass
  return pass unless block_given?

  begin
    yield pass
  ensure
    begin
      pass.end_pass unless pass.ended?
    ensure
      pass.release
      pass_ended(pass)
    end
  end
end

#begin_render_pass(arg0) ⇒ RenderPass #begin_render_passvoid

Begins a render pass, optionally yielding it for scoped recording.

Overloads:

  • #begin_render_pass(arg0) ⇒ RenderPass

    Parameters:

    • arg0 (Object)

    Returns:

  • #begin_render_passvoid

    This method returns an undefined value.

Parameters:

  • color_attachments (Array<Hash>)

    color attachment descriptors

Yield Parameters:

Returns:

  • (RenderPass, Object)

    pass without a block, otherwise the block result



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/wgpu/commands/command_encoder.rb', line 58

def begin_render_pass(color_attachments:, depth_stencil_attachment: nil, occlusion_query_set: nil, timestamp_writes: nil, max_draw_count: nil, label: nil)
  ensure_can_begin_pass!
  pass = RenderPass.new(self,
    color_attachments: color_attachments,
    depth_stencil_attachment: depth_stencil_attachment,
    occlusion_query_set: occlusion_query_set,
    timestamp_writes: timestamp_writes,
    max_draw_count: max_draw_count,
    label: label
  )
  @active_pass = pass
  return pass unless block_given?

  begin
    yield pass
  ensure
    begin
      pass.end_pass unless pass.ended?
    ensure
      pass.release
      pass_ended(pass)
    end
  end
end

#clear_buffer(buffer, offset: 0, size: nil) ⇒ void

This method returns an undefined value.

Clears a byte range in a buffer to zero.

Parameters:

  • buffer (Buffer)

    buffer to clear

  • offset (Integer) (defaults to: 0)

    first byte to clear

  • size (Integer, nil) (defaults to: nil)

    number of bytes to clear

  • (Buffer)
  • offset: (Integer) (defaults to: 0)
  • size: (Integer, nil) (defaults to: nil)

Raises:



213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/wgpu/commands/command_encoder.rb', line 213

def clear_buffer(buffer, offset: 0, size: nil)
  raise CommandError, "Encoder already finished" if @finished
  buffer_handle = NativeResource.checked_handle(buffer, expected_class: Buffer)
  offset = DataTypes.validate_alignment!(offset, 4, name: "clear offset")
  size = DataTypes.validate_alignment!(size || (buffer.size - offset), 4, name: "clear size")
  if offset > buffer.size || size > buffer.size - offset
    raise ArgumentError, "clear range exceeds buffer size"
  end
  return if size.zero?

  Native.wgpuCommandEncoderClearBuffer(@handle, buffer_handle, offset, size)
end

#copy_buffer_to_buffer(source:, source_offset: 0, destination:, destination_offset: 0, size:) ⇒ void

This method returns an undefined value.

Copies bytes between buffers.

Parameters:

  • (Object)

Raises:



85
86
87
88
89
90
91
92
93
# File 'lib/wgpu/commands/command_encoder.rb', line 85

def copy_buffer_to_buffer(source:, source_offset: 0, destination:, destination_offset: 0, size:)
  raise CommandError, "Encoder already finished" if @finished
  Native.wgpuCommandEncoderCopyBufferToBuffer(
    @handle,
    NativeResource.checked_handle(source, expected_class: Buffer), source_offset,
    NativeResource.checked_handle(destination, expected_class: Buffer), destination_offset,
    size
  )
end

#copy_buffer_to_texture(source:, destination:, copy_size:) ⇒ void

This method returns an undefined value.

Copies buffer data into a texture region.

Parameters:

  • source (Hash)

    buffer and layout descriptor

  • destination (Hash)

    texture and origin descriptor

  • copy_size (Hash, Array)

    extent to copy

  • (Object)

Raises:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/wgpu/commands/command_encoder.rb', line 100

def copy_buffer_to_texture(source:, destination:, copy_size:)
  raise CommandError, "Encoder already finished" if @finished

  size = DescriptorHelpers.extent_3d(copy_size)

  src = Native::ImageCopyBuffer.new
  src[:layout][:offset] = source[:offset] || 0
  src[:layout][:bytes_per_row] = source[:bytes_per_row]
  src[:layout][:rows_per_image] = source[:rows_per_image] || size[:height]
  src[:buffer] = NativeResource.checked_handle(source[:buffer], expected_class: Buffer)

  dst = Native::ImageCopyTexture.new
  dst[:texture] = NativeResource.checked_handle(destination[:texture], expected_class: Texture)
  dst[:mip_level] = destination[:mip_level] || 0
  dst[:origin][:x] = destination.dig(:origin, :x) || 0
  dst[:origin][:y] = destination.dig(:origin, :y) || 0
  dst[:origin][:z] = destination.dig(:origin, :z) || 0
  dst[:aspect] = Native::EnumHelper.coerce(
    Native::TextureAspect,
    destination[:aspect] || :all,
    name: "texture aspect"
  )

  Native.wgpuCommandEncoderCopyBufferToTexture(@handle, src, dst, size)
end

#copy_texture_to_buffer(source:, destination:, copy_size:) ⇒ void

This method returns an undefined value.

Copies a texture region into a buffer.

Parameters:

  • source (Hash)

    texture and origin descriptor

  • destination (Hash)

    buffer and layout descriptor

  • copy_size (Hash, Array)

    extent to copy

  • (Object)

Raises:



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/wgpu/commands/command_encoder.rb', line 131

def copy_texture_to_buffer(source:, destination:, copy_size:)
  raise CommandError, "Encoder already finished" if @finished

  size = DescriptorHelpers.extent_3d(copy_size)

  src = Native::ImageCopyTexture.new
  src[:texture] = NativeResource.checked_handle(source[:texture], expected_class: Texture)
  src[:mip_level] = source[:mip_level] || 0
  src[:origin][:x] = source.dig(:origin, :x) || 0
  src[:origin][:y] = source.dig(:origin, :y) || 0
  src[:origin][:z] = source.dig(:origin, :z) || 0
  src[:aspect] = Native::EnumHelper.coerce(
    Native::TextureAspect,
    source[:aspect] || :all,
    name: "texture aspect"
  )

  dst = Native::ImageCopyBuffer.new
  dst[:layout][:offset] = destination[:offset] || 0
  dst[:layout][:bytes_per_row] = destination[:bytes_per_row]
  dst[:layout][:rows_per_image] = destination[:rows_per_image] || size[:height]
  dst[:buffer] = NativeResource.checked_handle(destination[:buffer], expected_class: Buffer)

  Native.wgpuCommandEncoderCopyTextureToBuffer(@handle, src, dst, size)
end

#copy_texture_to_texture(source:, destination:, copy_size:) ⇒ void

This method returns an undefined value.

Copies one texture region into another texture.

Parameters:

  • source (Hash)

    source texture and origin descriptor

  • destination (Hash)

    destination texture and origin descriptor

  • copy_size (Hash, Array)

    extent to copy

  • (Object)

Raises:



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/wgpu/commands/command_encoder.rb', line 162

def copy_texture_to_texture(source:, destination:, copy_size:)
  raise CommandError, "Encoder already finished" if @finished

  src = Native::ImageCopyTexture.new
  src[:texture] = NativeResource.checked_handle(source[:texture], expected_class: Texture)
  src[:mip_level] = source[:mip_level] || 0
  src[:origin][:x] = source.dig(:origin, :x) || 0
  src[:origin][:y] = source.dig(:origin, :y) || 0
  src[:origin][:z] = source.dig(:origin, :z) || 0
  src[:aspect] = Native::EnumHelper.coerce(
    Native::TextureAspect,
    source[:aspect] || :all,
    name: "source texture aspect"
  )

  dst = Native::ImageCopyTexture.new
  dst[:texture] = NativeResource.checked_handle(destination[:texture], expected_class: Texture)
  dst[:mip_level] = destination[:mip_level] || 0
  dst[:origin][:x] = destination.dig(:origin, :x) || 0
  dst[:origin][:y] = destination.dig(:origin, :y) || 0
  dst[:origin][:z] = destination.dig(:origin, :z) || 0
  dst[:aspect] = Native::EnumHelper.coerce(
    Native::TextureAspect,
    destination[:aspect] || :all,
    name: "destination texture aspect"
  )

  size = DescriptorHelpers.extent_3d(copy_size)

  Native.wgpuCommandEncoderCopyTextureToTexture(@handle, src, dst, size)
end

#finish(label: nil) ⇒ CommandBuffer

Finishes recording and returns a command buffer.

Parameters:

  • label (String, nil) (defaults to: nil)

    optional command buffer label

  • label: (String, nil) (defaults to: nil)

Returns:

Raises:

  • (CommandError)

    if the encoder is finished, has an active pass, or native creation fails



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/wgpu/commands/command_encoder.rb', line 270

def finish(label: nil)
  raise CommandError, "Encoder already finished" if @finished
  if @active_pass && !@active_pass.ended?
    raise CommandError, "Cannot finish command encoder while a pass is active"
  end
  @finished = true

  desc = nil
  if label
    desc = Native::CommandBufferDescriptor.new
    desc[:next_in_chain] = nil
    label_ptr = FFI::MemoryPointer.from_string(label)
    desc[:label][:data] = label_ptr
    desc[:label][:length] = label.bytesize
  end

  buffer_handle = Native.wgpuCommandEncoderFinish(@handle, desc)
  raise CommandError, "Failed to finish command encoder" if buffer_handle.null?

  CommandBuffer.new(buffer_handle, device: @device)
end

#insert_debug_marker(label) ⇒ void

This method returns an undefined value.

Inserts a labeled point in GPU debugging tools.

Parameters:

  • label (String)

    marker label

  • (String)

Raises:



257
258
259
260
261
262
263
264
# File 'lib/wgpu/commands/command_encoder.rb', line 257

def insert_debug_marker(label)
  raise CommandError, "Encoder already finished" if @finished
  label_view = Native::StringView.new
  label_ptr = FFI::MemoryPointer.from_string(label)
  label_view[:data] = label_ptr
  label_view[:length] = label.bytesize
  Native.wgpuCommandEncoderInsertDebugMarker(@handle, label_view)
end

#pop_debug_groupvoid

This method returns an undefined value.

Ends the most recently pushed debug group.

Raises:



249
250
251
252
# File 'lib/wgpu/commands/command_encoder.rb', line 249

def pop_debug_group
  raise CommandError, "Encoder already finished" if @finished
  Native.wgpuCommandEncoderPopDebugGroup(@handle)
end

#push_debug_group(label) ⇒ void

This method returns an undefined value.

Starts a labeled group in GPU debugging tools.

Parameters:

  • label (String)

    group label

  • (String)

Raises:



238
239
240
241
242
243
244
245
# File 'lib/wgpu/commands/command_encoder.rb', line 238

def push_debug_group(label)
  raise CommandError, "Encoder already finished" if @finished
  label_view = Native::StringView.new
  label_ptr = FFI::MemoryPointer.from_string(label)
  label_view[:data] = label_ptr
  label_view[:length] = label.bytesize
  Native.wgpuCommandEncoderPushDebugGroup(@handle, label_view)
end

#releasevoid

This method returns an undefined value.

Releases the native command encoder handle.

Calling this method more than once has no effect.



296
297
298
299
300
# File 'lib/wgpu/commands/command_encoder.rb', line 296

def release
  return if @handle.null?
  Native.wgpuCommandEncoderRelease(@handle)
  @handle = FFI::Pointer::NULL
end

#resolve_query_set(query_set:, first_query:, query_count:, destination:, destination_offset:) ⇒ void

This method returns an undefined value.

Resolves query results into a destination buffer.

Parameters:

  • (Object)

Raises:



196
197
198
199
200
201
202
203
204
205
206
# File 'lib/wgpu/commands/command_encoder.rb', line 196

def resolve_query_set(query_set:, first_query:, query_count:, destination:, destination_offset:)
  raise CommandError, "Encoder already finished" if @finished
  Native.wgpuCommandEncoderResolveQuerySet(
    @handle,
    NativeResource.checked_handle(query_set, expected_class: QuerySet),
    first_query,
    query_count,
    NativeResource.checked_handle(destination, expected_class: Buffer),
    destination_offset
  )
end

#write_timestamp(query_set, query_index) ⇒ void

This method returns an undefined value.

Writes a GPU timestamp to a query set.

Parameters:

  • query_set (QuerySet)

    timestamp query set

  • query_index (Integer)

    destination query index

  • (QuerySet)
  • (Integer)

Raises:



230
231
232
233
# File 'lib/wgpu/commands/command_encoder.rb', line 230

def write_timestamp(query_set, query_index)
  raise CommandError, "Encoder already finished" if @finished
  Native.wgpuCommandEncoderWriteTimestamp(@handle, NativeResource.checked_handle(query_set, expected_class: QuerySet), query_index)
end