Module: WGPU::DescriptorHelpers

Defined in:
lib/wgpu/descriptor_helpers.rb

Constant Summary collapse

SIZE_MAX =
(1 << (FFI.type_size(:size_t) * 8)) - 1

Class Method Summary collapse

Class Method Details

.set_constants(stage_descriptor, constants, keepalive:) ⇒ void

This method returns an undefined value.

Writes pipeline-overridable constants into a stage descriptor.

Parameters:

  • stage_descriptor (FFI::Struct)

    programmable stage descriptor

  • constants (Hash{#to_s => Numeric}, nil)

    constant names and values

  • keepalive (Array)

    receives allocated pointers that must remain alive



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/wgpu/descriptor_helpers.rb', line 67

def set_constants(stage_descriptor, constants, keepalive:)
  stage_descriptor[:constant_count] = 0
  stage_descriptor[:constants] = nil
  return if constants.nil? || constants.empty?

  constants_pointer = FFI::MemoryPointer.new(Native::ConstantEntry, constants.size)
  keepalive << constants_pointer

  constants.each_with_index do |(key, value), index|
    entry_pointer = constants_pointer + (index * Native::ConstantEntry.size)
    entry = Native::ConstantEntry.new(entry_pointer)
    entry[:next_in_chain] = nil
    set_nullable_string_view(entry[:key], key.to_s, keepalive:)
    entry[:value] = value.to_f
  end

  stage_descriptor[:constant_count] = constants.size
  stage_descriptor[:constants] = constants_pointer
end

.set_label(descriptor, label, keepalive:) ⇒ void

This method returns an undefined value.

Writes an optional Ruby label into a native descriptor.

Parameters:

  • descriptor (FFI::Struct)

    descriptor with a label member

  • label (String, nil)

    label text

  • keepalive (Array)

    receives allocated pointers that must remain alive



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/wgpu/descriptor_helpers.rb', line 15

def set_label(descriptor, label, keepalive:)
  if label
    pointer = FFI::MemoryPointer.from_string(label)
    keepalive << pointer
    descriptor[:label][:data] = pointer
    descriptor[:label][:length] = label.bytesize
  else
    descriptor[:label][:data] = nil
    descriptor[:label][:length] = 0
  end
end

.set_nullable_string_view(string_view, value, keepalive:) ⇒ void

This method returns an undefined value.

Writes a nullable string into a native string view.

Parameters:

  • string_view (Native::StringView)

    destination view

  • value (String, nil)

    string value; nil uses the native null sentinel

  • keepalive (Array)

    receives allocated pointers that must remain alive



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/wgpu/descriptor_helpers.rb', line 47

def set_nullable_string_view(string_view, value, keepalive:)
  if value.nil?
    string_view[:data] = nil
    string_view[:length] = SIZE_MAX
    return
  end

  string = value
  pointer = FFI::MemoryPointer.from_string(string)
  keepalive << pointer
  string_view[:data] = pointer
  string_view[:length] = string.bytesize
end

.uint32_array(values, keepalive:) ⇒ FFI::MemoryPointer?

Allocates and fills a native uint32 array.

Parameters:

  • values (Array<Integer>)

    values to copy

  • keepalive (Array)

    receives the allocated pointer

Returns:

  • (FFI::MemoryPointer, nil)

    pointer, or nil for an empty array



32
33
34
35
36
37
38
39
# File 'lib/wgpu/descriptor_helpers.rb', line 32

def uint32_array(values, keepalive:)
  return nil if values.empty?

  pointer = FFI::MemoryPointer.new(:uint32, values.length)
  pointer.write_array_of_uint32(values)
  keepalive << pointer
  pointer
end

.validate_keys!(options, allowed:, required: [], context: "descriptor") ⇒ Hash

Checks required keys and warns about unsupported descriptor keys.

Parameters:

  • options (Hash)

    descriptor options

  • allowed (Array<Symbol>)

    supported keys

  • required (Array<Symbol>) (defaults to: [])

    mandatory keys

Returns:

  • (Hash)

    original options

Raises:

  • (ArgumentError)

    when required keys are missing



93
94
95
96
97
98
99
100
101
102
# File 'lib/wgpu/descriptor_helpers.rb', line 93

def validate_keys!(options, allowed:, required: [], context: "descriptor")
  return options unless options.is_a?(Hash)

  missing = required - options.keys
  raise ArgumentError, "#{context} is missing required keys: #{missing.map(&:inspect).join(", ")}" unless missing.empty?

  unknown = options.keys - allowed
  warn "Unknown #{context} keys: #{unknown.map(&:inspect).join(", ")}" unless unknown.empty?
  options
end