Class: Vulkan::Instance

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

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Checks

check_result

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 Finalizer

#finalize_with, #hexaddr, included, #to_ptr

Constructor Details

#initialize(application_name: $0, application_version: '1.0.0', engine_name: 'vulkan-ruby', engine_version: Vulkan::VERSION, api_version: self.class.version, extensions:, layers: []) ⇒ Instance

Returns a new instance of Instance.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/vulkan/instance.rb', line 48

def initialize(application_name: $0,            application_version: '1.0.0',
               engine_name: 'vulkan-ruby',      engine_version: Vulkan::VERSION,
               api_version: self.class.version, extensions: ,
               layers: [])
  layers.concat     ENV['LAYERS'].split(/\:\s/)              if ENV['LAYERS']
  extensions.concat ENV['INSTANCE_EXTENSIONS'].split(/\:\s/) if ENV['INSTANCE_EXTENSIONS']

  if ENV['DEBUG']
    extension_names = self.class.extension_names
    %w(
      VK_EXT_debug_utils
    ).each { |ext_name| extensions << ext_name if extension_names.include?(ext_name) }

    layer_names = self.class.layer_names
    %w(
      VK_LAYER_LUNARG_standard_validation
      VK_LAYER_LUNARG_parameter_validation
      VK_LAYER_LUNARG_assistant_layer
      VK_LAYER_LUNARG_api_dump
      VK_LAYER_GOOGLE_unique_objects
      VK_LAYER_LUNARG_demo_layer
      VK_LAYER_GOOGLE_threading
      VK_LAYER_LUNARG_monitor
      VK_LAYER_LUNARG_starter_layer
      VK_LAYER_LUNARG_core_validation
      VK_LAYER_LUNARG_object_tracker
    ).each do |layer_name|
      layers << layer_name if layer_names.include?(layer_name)
    end
  end

  extensions_p = Vulkan.struct("names[#{extensions.size}]" => ['char *name']).malloc
  extensions.each_with_index do |ext, i|
    extname = ext.kind_of?(String) ? ext : ext[:extension_name]
    extensions_p.names[i].name = Fiddle::Pointer[extname.b + "\x00"]
  end

  layers_p = Vulkan.struct("names[#{layers.size}]" => ['char *name']).malloc
  layers.each_with_index do |layer, i|
    layer_name = layer.kind_of?(String) ? layer : layer[:layer_name]
    layers_p.names[i].name = Fiddle::Pointer[layer_name.b + "\x00"]
  end

  application_info = VkApplicationInfo.malloc
  application_info.sType               = VK_STRUCTURE_TYPE_APPLICATION_INFO
  application_info.pNext               = nil
  application_info.pApplicationName    = application_name
  application_info.applicationVersion  = vk_make_version(application_version)
  application_info.pEngineName         = 'vulkan-ruby'
  application_info.engineVersion       = vk_make_version(engine_version)
  application_info.apiVersion          = vk_make_version(api_version)

  instance_info = VkInstanceCreateInfo.malloc
  instance_info.sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
  instance_info.pNext                   = nil
  instance_info.flags                   = 0
  instance_info.pApplicationInfo        = application_info
  instance_info.enabledLayerCount       = layers.size
  instance_info.ppEnabledLayerNames     = layers_p
  instance_info.enabledExtensionCount   = extensions.size
  instance_info.ppEnabledExtensionNames = extensions_p

  instance_wrapper = Vulkan.create_value("void *", nil)
  check_result Vulkan[nil, nil].vkCreateInstance(instance_info, nil, instance_wrapper)
  @handle = instance_wrapper.value
  @vk = Vulkan[self, nil]
  hook_debug_utils_callback if extensions.include?('VK_EXT_debug_utils')
  finalize_with @vk, :vkDestroyInstance, @handle, nil
end

Class Method Details

.extension_namesObject



33
34
35
# File 'lib/vulkan/instance.rb', line 33

def extension_names
  extensions.map { |ext| ext[:extension_name] }
end

.extensionsObject



10
11
12
13
14
15
16
17
18
19
# File 'lib/vulkan/instance.rb', line 10

def extensions
  @extensions ||= begin
    property_count_ptr = Vulkan.create_value("uint32_t", 0)
    check_result Vulkan[nil, nil].vkEnumerateInstanceExtensionProperties(nil, property_count_ptr, nil)
    property_count = property_count_ptr.value
    container = Vulkan.struct("properties[#{property_count}]" => VkExtensionProperties).malloc
    check_result Vulkan[nil, nil].vkEnumerateInstanceExtensionProperties(nil, property_count_ptr, container)
    container.properties.map { |prop| struct_to_hash(prop) }
  end
end

.layer_namesObject



37
38
39
# File 'lib/vulkan/instance.rb', line 37

def layer_names
  layers.map { |layer| layer[:layer_name] }
end

.layersObject



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/vulkan/instance.rb', line 21

def layers
  @layers ||= begin
    property_count_ptr = Vulkan.create_value("uint32_t", 0)
    check_result Vulkan[nil, nil].vkEnumerateInstanceLayerProperties(property_count_ptr, nil)
    property_count = property_count_ptr.value
    container_struct = Vulkan.struct("properties[#{property_count}]" => VkLayerProperties)
    container = container_struct.malloc
    check_result Vulkan[nil, nil].vkEnumerateInstanceLayerProperties(property_count_ptr, container)
    container.properties.map { |prop| struct_to_hash(prop) }
  end
end

.versionObject



41
42
43
44
45
# File 'lib/vulkan/instance.rb', line 41

def version
  ver_p = Vulkan.create_value('uint32_t', 0)
  check_result Vulkan[nil, nil].vkEnumerateInstanceVersion(ver_p)
  vk_parse_version ver_p.value
end

Instance Method Details

#create_window_surface(window) ⇒ Object



156
157
158
# File 'lib/vulkan/instance.rb', line 156

def create_window_surface(window)
  WindowSurface.new(self, window)
end

#hook_debug_utils_callbackObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/vulkan/instance.rb', line 122

def hook_debug_utils_callback
  _, return_type, param_types = Vulkan.parse_signature('VkBool32 debug_callback(int   messageSeverity,' +
                                                                               'int   messageType,' +
                                                                               'void *pCallbackData,' +
                                                                               'void *pUserData)')
  @debug_util_callback = Fiddle::Closure::BlockCaller.new(return_type, param_types) do |msg_severity, msg_type, cb_data_addr, user_arg_addr|
    data     = VkDebugUtilsMessengerCallbackDataEXT.new(cb_data_addr)
    type     = const_to_symbol(msg_type,     /^VK_DEBUG_UTILS_MESSAGE_TYPE_(.*?)_BIT_EXT$/)
    severity = const_to_symbol(msg_severity, /^VK_DEBUG_UTILS_MESSAGE_SEVERITY_(.*?)_BIT_EXT$/)
    if @log_callback
      @log_callback.call severity, type, data.pMessage.to_s
    else
      puts ['[UTIL]', "[#{severity}]", "[#{type}]", data.pMessage.to_s].join("\t")
    end
    VK_FALSE # don't bail
  end

  create_info = VkDebugUtilsMessengerCreateInfoEXT.malloc
  create_info.sType           = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT
  create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
                                VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
                                VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
  create_info.messageType     = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT    |
                                VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
                                VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
  create_info.pUserData       = nil
  create_info.pfnUserCallback = @debug_util_callback

  callback_p = Vulkan.create_value('void *', nil)
  check_result @vk.vkCreateDebugUtilsMessengerEXT(to_ptr, create_info, nil, callback_p)
  @debug_util_callback_handle = callback_p.value
  finalize_with @vk, :vkDestroyDebugUtilsMessengerEXT, to_ptr, @debug_util_callback_handle, nil
end

#on_log(&cb) ⇒ Object



118
119
120
# File 'lib/vulkan/instance.rb', line 118

def on_log(&cb)
  @log_callback = cb
end

#physical_device_handlesObject

Returns an array of physical device handles. Use these to query the capabilities of each physical device, and to create logical devices based on the results.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/vulkan/instance.rb', line 163

def physical_device_handles
  @physical_device_handles ||= begin
    # get device count
    device_count_ptr = Vulkan.create_value("uint32_t", 0)
    # check_result func.call(@handle, device_count_ptr, nil)
    check_result @vk.vkEnumeratePhysicalDevices(@handle, device_count_ptr, nil)
    device_count = device_count_ptr.value
    # allocate n devices
    container_struct = Vulkan.struct("handles[#{device_count}]" => ['VkPhysicalDevice handle'])
    container = container_struct.malloc
    # check_result func.call(@handle, device_count_ptr, container)
    check_result @vk.vkEnumeratePhysicalDevices(@handle, device_count_ptr, container)
    container.handles
  end
end

#physical_devicesObject



179
180
181
# File 'lib/vulkan/instance.rb', line 179

def physical_devices
  @physical_devices ||= physical_device_handles.map { |dev| PhysicalDevice.new(self, dev.handle) }
end