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

.extent_3d(size) ⇒ Native::Extent3D

Normalizes an Array or Hash texture extent to a native descriptor.

Parameters:

  • size (Array<Integer>, Hash)

    width, height, and depth/layer count

Returns:



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

def extent_3d(size)
  values = case size
           when Array
             [size.fetch(0), size[1] || 1, size[2] || 1]
           when Hash
             [size.fetch(:width), size[:height] || 1, size[:depth_or_array_layers] || 1]
           else
             raise ArgumentError, "texture size must be an Array or Hash"
           end
  extent = Native::Extent3D.new
  [:width, :height, :depth_or_array_layers].zip(values).each do |field, value|
    value = Integer(value)
    raise ArgumentError, "#{field} must be between 0 and 4294967295" unless (0..0xFFFFFFFF).cover?(value)

    extent[field] = value
  end
  extent
end

.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



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/wgpu/descriptor_helpers.rb', line 89

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



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/wgpu/descriptor_helpers.rb', line 37

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



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

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



54
55
56
57
58
59
60
61
# File 'lib/wgpu/descriptor_helpers.rb', line 54

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



115
116
117
118
119
120
121
122
123
124
# File 'lib/wgpu/descriptor_helpers.rb', line 115

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