Class: Vulkan::Memory

Inherits:
Object
  • Object
show all
Includes:
Checks, Conversions, Finalizer
Defined in:
lib/vulkan/memory.rb

Direct Known Subclasses

BufferMemory, ImageMemory

Constant Summary

Constants included from Conversions

Conversions::ACCESS_MASK_BITS, Conversions::BORDER_COLORS, Conversions::BUFFER_USAGE_BITS, Conversions::COMPARE_OPS, Conversions::DEPENDENCY_FLAG_BITS, Conversions::DESCRIPTOR_TYPES, Conversions::DYNAMIC_STATES, Conversions::FILTERS, Conversions::FORMAT_FEATURE_BITS, Conversions::IMAGE_ASPECT_BITS, Conversions::IMAGE_CREATE_BITS, Conversions::IMAGE_FORMATS, Conversions::IMAGE_TILING, Conversions::IMAGE_TYPES, Conversions::IMAGE_USAGE_BITS, Conversions::MEMORY_PROPERTIES, Conversions::PIPELINE_STAGE_BITS, Conversions::PRESENT_MODES, Conversions::SAMPLER_ADDRESS_MODES, Conversions::SAMPLER_MIPMAP_MODES, Conversions::SHADER_STAGE_BITS, Conversions::SHARING_MODES, Conversions::SURFACE_TRANSFORMS, Conversions::VERTEX_INPUT_RATES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Finalizer

#finalize_with, #hexaddr, included, #to_ptr

Methods included from Conversions

#array_of_pointers, #array_of_structures, #array_of_uint32s, #bool_to_vk, #buffer_usage_flags_to_syms, #const_to_symbol, #cstr_to_rbstr, #flags_to_symbols, #flags_to_syms, #num_to_samples, #present_mode_to_sym, #queue_family_to_index, #struct_to_hash, #sym_to_blend_factor, #sym_to_blend_op, #sym_to_border_color, #sym_to_color_component_bit, #sym_to_command_buffer_level, #sym_to_command_buffer_usage, #sym_to_compare_op, #sym_to_cull_mode, #sym_to_descriptor_type, #sym_to_dynamic_state, #sym_to_filter, #sym_to_front_face, #sym_to_image_format, #sym_to_image_layout, #sym_to_image_tiling, #sym_to_image_type, #sym_to_index_type, #sym_to_load_op, #sym_to_pipeline_bind_point, #sym_to_polygon_mode, #sym_to_present_mode, #sym_to_sampler_address_mode, #sym_to_sampler_mipmap_mode, #sym_to_samples, #sym_to_sharing_mode, #sym_to_store_op, #sym_to_subpass_contents, #sym_to_topology, #sym_to_val, #sym_to_vertex_input_rate, #syms_to_access_mask, #syms_to_buffer_usage_flags, #syms_to_dependency_flags, #syms_to_descriptor_set_layout_type_flags, #syms_to_flags, #syms_to_format_feature_flags, #syms_to_image_aspect_flags, #syms_to_image_create_flags, #syms_to_image_usage_flags, #syms_to_memory_properties, #syms_to_pipeline_stage_flags, #syms_to_shader_stage_flags, #syms_to_surface_transforms, #vk_make_version, #vk_parse_version

Methods included from Checks

#check_result

Constructor Details

#initialize(vk, physical_device, properties: [:host_visible]) ⇒ Memory

Returns a new instance of Memory.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/vulkan/memory.rb', line 10

def initialize(vk, physical_device, properties: [:host_visible])
  @range_array = nil
  @vk = vk
  @physical_device = physical_device
  @properties = syms_to_memory_properties(properties)
  @mapped = Vulkan.create_value('void *', nil)

  @requirements = query_memory_requirements

  alloc_info = VkMemoryAllocateInfo.malloc
  alloc_info.sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
  alloc_info.allocationSize  = @requirements.size
  alloc_info.memoryTypeIndex = memory_type_index
  memory_handle_p = Vulkan.create_value('void *', nil)
  check_result @vk.vkAllocateMemory(@vk.device, alloc_info, nil, memory_handle_p)
  @handle = memory_handle_p.value
  finalize_with @vk, :vkFreeMemory, @vk.device, @handle, nil
  bind
end

Instance Attribute Details

#physical_deviceObject (readonly)

Returns the value of attribute physical_device.



8
9
10
# File 'lib/vulkan/memory.rb', line 8

def physical_device
  @physical_device
end

#requirementsObject (readonly)

Returns the value of attribute requirements.



7
8
9
# File 'lib/vulkan/memory.rb', line 7

def requirements
  @requirements
end

Instance Method Details

#dataObject



54
55
56
57
# File 'lib/vulkan/memory.rb', line 54

def data
  raise 'no data pointer: buffer is not mapped' unless mapped?
  @mapped
end

#flush(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE) ⇒ Object

Flushes a single range of memory, which defaults to the entire buffer. Do this after modifying memory to inform the device that it may have changed. This method is called automatically after the block form of #map has completed, but is not called automatically if no block is provided to #map.

See www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkFlushMappedMemoryRanges.html



76
77
78
# File 'lib/vulkan/memory.rb', line 76

def flush(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE)
  flush_all [{ offset: offset, size: size }]
end

#flush_all(ranges) ⇒ Object

Flushes each of a set of memory ranges, given as ‘[=> number, :size => number]`. No defaults are provided, and ArgumentError will be raised if any fields are omitted. Do this after modifying memory to inform the device that it may have changed.

See www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkFlushMappedMemoryRanges.html



87
88
89
# File 'lib/vulkan/memory.rb', line 87

def flush_all(ranges)
  @vk.vkFlushMappedMemoryRanges(@vk.device, ranges.size, memory_ranges(ranges))
end

#invalidate(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE) ⇒ Object

Invalidates a single range of memory, which defaults to the entire buffer. Do this prior to reading memory that may have been modified by a device. This method is called automatically at the beginning of #map, but is not called automatically at any other point, so if you leave the memory mapped (for example, by not passing a block to #map), then you need to call this method explicitly at the appropriate times.

See www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkInvalidateMappedMemoryRanges.html



99
100
101
# File 'lib/vulkan/memory.rb', line 99

def invalidate(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE)
  invalidate_all [{ offset: offset, size: size }]
end

#invalidate_all(ranges) ⇒ Object

Invalidates each of a set of memory ranges, given as ‘[=> number, :size => number]`. No defaults are provided, and ArgumentError will be raised if any fields are omitted. Do this prior to reading memory that may have been modified by a device.

See www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkInvalidateMappedMemoryRanges.html



109
110
111
112
113
# File 'lib/vulkan/memory.rb', line 109

def invalidate_all(ranges)
  if mapped?
    @vk.vkInvalidateMappedMemoryRanges(@vk.device, ranges.size, memory_ranges(ranges))
  end
end

#map(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE, invalidate: true, flush: true, &block) ⇒ Object

Maps this memory range. If a block is provided, a pointer to the start of the mapped memory range is yielded to the block and the memory is automatically unmapped after the block finishes and ‘nil` is returned to prevent writing to a no-longer-mapped address.

If no block is provided, the memory remains mapped and the pointer is returned.

If ‘invalidate` is true, the range to be mapped will be invalidated automatically before mapping to ensure that the memory will be up to date with any changes from the device. If false, the memory may be out of date when you map it.

If ‘flush` is true, and a block is given, then the memory will be flushed to ensure that it is updated on the device after your block completes. If no block is given, this option has no effect.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/vulkan/memory.rb', line 151

def map(offset: 0, size: offset > 0 ? self.size - offset : VK_WHOLE_SIZE,
        invalidate: true, flush: true, &block)
  raise 'buffer is already mapped' if mapped?
  self.invalidate offset: offset, size: size if invalidate
  @vk.vkMapMemory(@vk.device, @handle, offset, size, 0, @mapped)
  size = self.size if size == VK_WHOLE_SIZE
  if block_given?
    begin
      yield Fiddle::Pointer.new(@mapped.value.to_i, size)
    ensure
      self.flush offset: offset, size: size if flush
      unmap
    end
    return nil
  else
    return Fiddle::Pointer.new(@mapped.value.to_i, size)
  end
end

#mapped?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/vulkan/memory.rb', line 59

def mapped?
  @mapped && @mapped.value.to_i != 0
end

#memory_type_indexObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/vulkan/memory.rb', line 34

def memory_type_index
  properties = {}
  physical_device.memory_properties[:memory_type_count].times do |i|
    if (requirements.memoryTypeBits & (1 << i)) != 0
      if (physical_device.memory_properties[:memory_types][i][:property_flags] & @properties) == @properties
        return i
      else
        properties[i] = "0x%x" % physical_device.memory_properties[:memory_types][i][:property_flags]
      end
    end
  end

  raise 'failed to find suitable memory type (needed properties == 0x%x, memory type count == %d, requrement memory type bits == 0b%s, available properties == %s)' % [
    @properties,
    physical_device.memory_properties[:memory_type_count],
    requirements.memoryTypeBits.to_s(2),
    properties.inspect
  ]
end

#sizeObject



30
31
32
# File 'lib/vulkan/memory.rb', line 30

def size
  @requirements.size
end

#unmapObject



63
64
65
66
67
# File 'lib/vulkan/memory.rb', line 63

def unmap
  raise 'buffer is not mapped' unless mapped?
  @mapped.value = nil
  @vk.vkUnmapMemory(@vk.device, @handle)
end