Created
June 12, 2025 16:17
-
-
Save Luxistor/c12d3b5e955bbca0dcb6ec8a364e4df1 to your computer and use it in GitHub Desktop.
Vulkan backend intialization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| fn_decl void | |
| r_init(R_Init_Params *params) | |
| { | |
| // Allocate memory | |
| r_vk_state.permanent_arena = arena_alloc(); | |
| r_vk_state.frame_arena = arena_alloc(); | |
| r_vk_state.buffer_pool = pool_alloc(r_vk_state.permanent_arena, R_VK_Buffer, R_MAX_BUFFERS); | |
| r_vk_state.texture_pool = pool_alloc(r_vk_state.permanent_arena, R_VK_Texture, R_MAX_TEXTURES); | |
| r_vk_state.sampler_pool = pool_alloc(r_vk_state.permanent_arena, R_VK_Sampler, R_MAX_SAMPLERS); | |
| r_vk_state.pipeline_pool = pool_alloc(r_vk_state.permanent_arena, R_VK_Pipeline, R_MAX_PIPELINES); | |
| r_vk_state.swapchain_pool = pool_alloc(r_vk_state.permanent_arena, R_VK_Swapchain, R_MAX_SWAPCHAINS); | |
| // Open the library and load global functions | |
| { | |
| Str8 library_name = str8_lit("vulkan-1.dll"); | |
| OS_Handle library = os_libary_open(library_name); | |
| if (library == 0) | |
| { | |
| Arena_Temp scratch = get_scratch(); | |
| os_popup_message(str8_lit("Vulkan Backend Failure"), str8_concat(scratch.arena, str8_lit("Failed to load"), library_name)); | |
| os_abort(-1); | |
| release_scratch(&scratch); | |
| } | |
| r_vk_state.vulkan_library = library; | |
| } | |
| { | |
| r_vk_load_global_functions(r_vk_state.vulkan_library); | |
| } | |
| // determine instance api version | |
| U32 instance_api_version = VK_API_VERSION_1_0; | |
| if (vkEnumerateInstanceVersion) | |
| { | |
| R_VK_Check(vkEnumerateInstanceVersion(&instance_api_version)); | |
| } | |
| { | |
| // we'll handle the case of being <1.3 later on | |
| VkApplicationInfo application_info = {0}; | |
| application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; | |
| application_info.apiVersion = instance_api_version; | |
| application_info.pEngineName = (const char *)params->app_name.str; | |
| application_info.pApplicationName = (const char *)params->app_name.str; | |
| const char *instance_extensions[] = { | |
| VK_KHR_SURFACE_EXTENSION_NAME, | |
| R_VK_SURFACE_EXTENSION_NAME, | |
| #if BUILD_DEBUG | |
| VK_EXT_DEBUG_UTILS_EXTENSION_NAME, | |
| #endif | |
| }; | |
| #if BUILD_DEBUG | |
| const char *validation_layer_name = "VK_LAYER_KHRONOS_validation"; | |
| #endif | |
| VkInstanceCreateInfo create_info = {0}; | |
| create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | |
| create_info.pApplicationInfo = &application_info; | |
| create_info.ppEnabledExtensionNames = instance_extensions; | |
| create_info.enabledExtensionCount = ArrayCount(instance_extensions); | |
| #if BUILD_DEBUG | |
| create_info.ppEnabledLayerNames = &validation_layer_name; | |
| create_info.enabledLayerCount = 1; | |
| #endif | |
| VkResult result = vkCreateInstance(&create_info, NULL, &r_vk_state.instance); | |
| if (result != VK_SUCCESS) | |
| { | |
| if (result == VK_ERROR_EXTENSION_NOT_PRESENT) | |
| { | |
| os_popup_message(str8_lit("Vulkan Backend Failure"), | |
| str8_lit("Your Vulkan driver does not support the surface instance extension. Try updating it " | |
| "on your vendor's website.")); | |
| } else | |
| { | |
| os_popup_message(str8_lit("Vulkan Backend Failure"), str8_lit("Something went wrong on instance creation")); | |
| } | |
| os_abort(-1); | |
| } | |
| } | |
| // Load instance functions | |
| { | |
| r_vk_load_instance_functions(r_vk_state.instance); | |
| } | |
| // Initialize debug utils | |
| #if BUILD_DEBUG | |
| { | |
| VkDebugUtilsMessengerCreateInfoEXT messenger_create_info = {0}; | |
| messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; | |
| messenger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; | |
| messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; | |
| messenger_create_info.pfnUserCallback = r_vk_debug_messenger_callback; | |
| VkResult result = | |
| vkCreateDebugUtilsMessengerEXT(r_vk_state.instance, &messenger_create_info, NULL, &r_vk_state.debug_messenger); | |
| if (result != VK_SUCCESS) | |
| { | |
| os_popup_message(str8_lit("Vulkan Backend Warning"), str8_lit("Failed to initialize debug messenger")); | |
| } | |
| } | |
| #endif | |
| // Select physical device | |
| { | |
| U32 physical_device_count = 0; | |
| R_VK_Check(vkEnumeratePhysicalDevices(r_vk_state.instance, &physical_device_count, NULL)); | |
| if (physical_device_count == 0) | |
| { | |
| os_popup_message(str8_lit("Vulkan Backend Failure"), | |
| str8_lit("No devices on your system have Vulkan support. This means you will be unable to use " | |
| "the application with this device.")); | |
| os_abort(-1); | |
| } | |
| Arena_Temp scratch = get_scratch(); | |
| VkPhysicalDevice *physical_devices = arena_push_array(scratch.arena, VkPhysicalDevice, physical_device_count); | |
| R_VK_Check(vkEnumeratePhysicalDevices(r_vk_state.instance, &physical_device_count, physical_devices)); | |
| VkPhysicalDeviceProperties *physical_device_property_array = | |
| arena_push_array(scratch.arena, VkPhysicalDeviceProperties, physical_device_count); | |
| Str8 required_device_extensions[] = { | |
| str8_lit("VK_KHR_swapchain"), | |
| str8_lit("VK_EXT_descriptor_indexing"), | |
| str8_lit("VK_KHR_shader_draw_parameters"), | |
| }; | |
| VkPhysicalDeviceType preferred_device_type = vk_device_type_from_rhi(params->preferred_device_type); | |
| U32 selected_gpu = UINT32_MAX; | |
| U32 selected_gpu_graphics_queue_family_index = UINT32_MAX; | |
| for (U32 i = 0; i < physical_device_count; i++) | |
| { | |
| VkPhysicalDevice current_gpu = physical_devices[i]; | |
| // Query for device extension support | |
| { | |
| U32 device_extension_count = 0; | |
| R_VK_Check(vkEnumerateDeviceExtensionProperties(current_gpu, NULL, &device_extension_count, NULL)); | |
| if (device_extension_count < 1) | |
| continue; | |
| Arena_Temp scratch = get_scratch(); | |
| VkExtensionProperties *extensions = arena_push_array(scratch.arena, VkExtensionProperties, device_extension_count); | |
| R_VK_Check(vkEnumerateDeviceExtensionProperties(current_gpu, NULL, &device_extension_count, extensions)); | |
| B32 are_extensions_supported = 1; | |
| for (U32 j = 0; j < ArrayCount(required_device_extensions); j++) | |
| { | |
| Str8 enabled_extension_name = required_device_extensions[j]; | |
| B32 found_extension = 0; | |
| for (U32 i = 0; i < device_extension_count; i++) | |
| { | |
| Str8 device_extension_name = str8_from_cstring(extensions[i].extensionName); | |
| if (str8_comp(enabled_extension_name, device_extension_name) != 0) | |
| continue; | |
| found_extension = 1; | |
| break; | |
| } | |
| if (!found_extension) | |
| { | |
| are_extensions_supported = 0; | |
| break; | |
| } | |
| } | |
| release_scratch(&scratch); | |
| if (!are_extensions_supported) | |
| continue; | |
| } | |
| vkGetPhysicalDeviceProperties(current_gpu, &physical_device_property_array[i]); | |
| VkPhysicalDeviceProperties *properties = &physical_device_property_array[i]; | |
| if (properties->apiVersion < VK_API_VERSION_1_3) | |
| continue; | |
| // Select graphics queue family index | |
| { | |
| Arena_Temp scratch = get_scratch(); | |
| U32 queue_family_count = 0; | |
| vkGetPhysicalDeviceQueueFamilyProperties(current_gpu, &queue_family_count, NULL); | |
| VkQueueFamilyProperties *queue_families = arena_push_array(scratch.arena, VkQueueFamilyProperties, queue_family_count); | |
| vkGetPhysicalDeviceQueueFamilyProperties(current_gpu, &queue_family_count, queue_families); | |
| U32 graphics_queue_family_index = UINT32_MAX; | |
| for (U32 i = 0; i < queue_family_count; i++) | |
| { | |
| VkQueueFamilyProperties *current_family = &queue_families[i]; | |
| B32 supports_present = 0; | |
| #if OS == OS_WINDOWS | |
| supports_present = vkGetPhysicalDeviceWin32PresentationSupportKHR(current_gpu, i); | |
| #endif | |
| if ((current_family->queueFlags & VK_QUEUE_GRAPHICS_BIT) && supports_present) | |
| { | |
| graphics_queue_family_index = i; | |
| break; | |
| } | |
| } | |
| release_scratch(&scratch); | |
| if (graphics_queue_family_index == UINT32_MAX) | |
| { | |
| continue; | |
| } | |
| selected_gpu_graphics_queue_family_index = graphics_queue_family_index; | |
| selected_gpu = i; | |
| } | |
| if (properties->deviceType == preferred_device_type) | |
| break; | |
| } | |
| // On device selection fail | |
| if (selected_gpu == UINT32_MAX || instance_api_version < VK_API_VERSION_1_3) | |
| { | |
| Arena_Temp scratch = get_scratch(); | |
| Str8_List gpu_strings = {0}; | |
| for (U32 i = 0; i < physical_device_count; i++) | |
| { | |
| VkPhysicalDeviceProperties *gpu_props = &physical_device_property_array[i]; | |
| Str8 vendor_name = str8_lit("UNKNOWN VENDOR"); | |
| Str8 driver_version = {0}; | |
| // from https://tinyurl.com/bdeavzhb | |
| switch (gpu_props->vendorID) | |
| { | |
| case 4138: { | |
| vendor_name = str8_lit("Nvidia"); | |
| U32 major = (gpu_props->driverVersion >> 22) & 0x3ff; | |
| U32 minor = (gpu_props->driverVersion >> 14) & 0x0ff; | |
| U32 patch0 = (gpu_props->driverVersion >> 6) & 0x0ff; | |
| U32 patch1 = (gpu_props->driverVersion) & 0x003f; | |
| driver_version = str8_format(scratch.arena, "%i.%i.%i.%i", major, minor, patch0, patch1); | |
| } | |
| break; | |
| #if OS == OS_WINDOWS | |
| case 0x8086: { | |
| vendor_name = str8_lit("Intel"); | |
| U32 major = (gpu_props->driverVersion >> 14); | |
| U32 minor = (gpu_props->driverVersion) & 0x3fff; | |
| driver_version = str8_format(scratch.arena, "%i.%i", major, minor); | |
| } | |
| break; | |
| #endif | |
| case 0x1002: { | |
| vendor_name = str8_lit("AMD"); | |
| } | |
| default: { | |
| U32 major = VK_API_VERSION_MAJOR(gpu_props->driverVersion); | |
| U32 minor = VK_API_VERSION_MINOR(gpu_props->driverVersion); | |
| U32 patch = VK_API_VERSION_PATCH(gpu_props->driverVersion); | |
| driver_version = str8_format(scratch.arena, "%i.%i.%i", major, minor, patch); | |
| } | |
| } | |
| Str8 formatted = str8_format(scratch.arena, | |
| "Device Name: %s, Device Driver Version: %S. You can find drivers for %S on their website.", | |
| gpu_props->deviceName, driver_version, vendor_name); | |
| str8_list_push(scratch.arena, &gpu_strings, formatted); | |
| } | |
| Str8 error_msg = str8_format(scratch.arena, | |
| "None of the following devices in your system support Vulkan 1.3. You may need to " | |
| "update your drivers. Note that your" | |
| "devices may be out of date and no-longer support new drivers, or your device may " | |
| "not support a required feature of the application.\n Devices:\n %S", | |
| str8_list_fold(scratch.arena, &gpu_strings, str8_lit("\n"))); | |
| os_popup_message(str8_lit("Vulkan Backend Failure"), error_msg); | |
| os_abort(-1); | |
| } | |
| // Set gpu info | |
| VkPhysicalDeviceProperties *selected_gpu_properties = &physical_device_property_array[selected_gpu]; | |
| R_Device_Type device_type = rhi_device_type_from_vk(selected_gpu_properties->deviceType); | |
| r_vk_state.gpu_info.device_type = device_type; | |
| Str8 temp = str8_from_cstring(selected_gpu_properties->deviceName); | |
| r_vk_state.gpu_info.device_name = str8_copy(r_vk_state.permanent_arena, temp); | |
| r_vk_state.physical_device = physical_devices[selected_gpu]; | |
| r_vk_state.graphics_queue_family_index = selected_gpu_graphics_queue_family_index; | |
| release_scratch(&scratch); | |
| } | |
| // Create device | |
| { | |
| VkPhysicalDeviceVulkan13Features required_vulkan_13_features = {0}; | |
| required_vulkan_13_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, | |
| required_vulkan_13_features.synchronization2 = VK_TRUE; | |
| required_vulkan_13_features.dynamicRendering = VK_TRUE; | |
| required_vulkan_13_features.maintenance4 = VK_TRUE; | |
| VkPhysicalDeviceVulkan12Features required_vulkan_12_features = {0}; | |
| required_vulkan_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, | |
| required_vulkan_12_features.pNext = &required_vulkan_13_features; | |
| required_vulkan_12_features.runtimeDescriptorArray = VK_TRUE; | |
| required_vulkan_12_features.descriptorBindingPartiallyBound = VK_TRUE; | |
| required_vulkan_12_features.descriptorBindingUpdateUnusedWhilePending = VK_TRUE; | |
| required_vulkan_12_features.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE; | |
| required_vulkan_12_features.descriptorBindingStorageImageUpdateAfterBind = VK_TRUE; | |
| required_vulkan_12_features.bufferDeviceAddress = VK_TRUE; | |
| VkPhysicalDeviceVulkan11Features required_vulkan_11_features = {0}; | |
| required_vulkan_11_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; | |
| required_vulkan_11_features.pNext = &required_vulkan_12_features; | |
| required_vulkan_11_features.shaderDrawParameters = VK_TRUE; | |
| F32 queue_priority = 1.0f; | |
| VkDeviceQueueCreateInfo queue_create_info = {0}; | |
| queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; | |
| queue_create_info.queueFamilyIndex = r_vk_state.graphics_queue_family_index; | |
| queue_create_info.queueCount = 1; | |
| queue_create_info.pQueuePriorities = &queue_priority; | |
| // we only actually want to enable vk_khr_swapchain, the other extensions are via features | |
| const char *swapchain_extension = "VK_KHR_swapchain"; | |
| VkDeviceCreateInfo device_create_info = {0}; | |
| device_create_info.pNext = &required_vulkan_11_features; | |
| device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; | |
| device_create_info.queueCreateInfoCount = 1; | |
| device_create_info.pQueueCreateInfos = &queue_create_info; | |
| device_create_info.enabledExtensionCount = 1; | |
| device_create_info.ppEnabledExtensionNames = &swapchain_extension; | |
| R_VK_Check(vkCreateDevice(r_vk_state.physical_device, &device_create_info, NULL, &r_vk_state.device)); | |
| r_vk_set_debug_name(str8_lit("main-instance"), VK_OBJECT_TYPE_INSTANCE, (U64)r_vk_state.instance); | |
| r_vk_set_debug_name(r_get_gpu_info()->device_name, VK_OBJECT_TYPE_PHYSICAL_DEVICE, (U64)r_vk_state.physical_device); | |
| r_vk_set_debug_name(str8_lit("main-device"), VK_OBJECT_TYPE_DEVICE, (U64)r_vk_state.device); | |
| } | |
| // Load device functions from library | |
| { | |
| r_vk_load_device_functions(r_vk_state.device); | |
| } | |
| // Get graphics queue | |
| { | |
| vkGetDeviceQueue(r_vk_state.device, r_vk_state.graphics_queue_family_index, 0, &r_vk_state.graphics_queue); | |
| r_vk_set_debug_name(str8_lit("graphics-queue"), VK_OBJECT_TYPE_QUEUE, (U64)r_vk_state.graphics_queue); | |
| } | |
| // Create descriptor pool | |
| { | |
| VkDescriptorPoolSize pool_sizes[] = { | |
| {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, R_MAX_TEXTURES}, | |
| {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, R_MAX_TEXTURES}, | |
| {VK_DESCRIPTOR_TYPE_SAMPLER, R_MAX_SAMPLERS}, | |
| }; | |
| VkDescriptorPoolCreateInfo pool_create_info = {0}; | |
| pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; | |
| pool_create_info.maxSets = 1; | |
| pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT; | |
| pool_create_info.poolSizeCount = ArrayCount(pool_sizes); | |
| pool_create_info.pPoolSizes = pool_sizes; | |
| R_VK_Check(vkCreateDescriptorPool(r_vk_state.device, &pool_create_info, NULL, &r_vk_state.descriptor_pool)); | |
| r_vk_set_debug_name(str8_lit("descriptor-pool"), VK_OBJECT_TYPE_DESCRIPTOR_POOL, (U64)r_vk_state.descriptor_pool); | |
| } | |
| // create descriptor set layout | |
| { | |
| VkDescriptorSetLayoutBinding storage_image_array_binding = {0}; | |
| storage_image_array_binding.binding = R_VK_DESCRIPTOR_BINDING_STORAGE_IMAGE_ARRAY; | |
| storage_image_array_binding.descriptorCount = R_MAX_TEXTURES; | |
| storage_image_array_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; | |
| storage_image_array_binding.stageFlags = R_VK_SHADER_STAGES; | |
| VkDescriptorSetLayoutBinding sampled_image_array_binding = {0}; | |
| sampled_image_array_binding.binding = R_VK_DESCRIPTOR_BINDING_SAMPLED_IMAGE_ARRAY; | |
| sampled_image_array_binding.descriptorCount = R_MAX_TEXTURES; | |
| sampled_image_array_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; | |
| sampled_image_array_binding.stageFlags = R_VK_SHADER_STAGES; | |
| VkDescriptorSetLayoutBinding sampler_array_binding = {0}; | |
| sampler_array_binding.binding = R_VK_DESCRIPTOR_BINDING_SAMPLER_ARRAY; | |
| sampler_array_binding.descriptorCount = R_MAX_SAMPLERS; | |
| sampler_array_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; | |
| sampler_array_binding.stageFlags = R_VK_SHADER_STAGES; | |
| VkDescriptorSetLayoutBinding bindings[] = {storage_image_array_binding, sampled_image_array_binding, sampler_array_binding}; | |
| VkDescriptorBindingFlags binding_flags[] = { | |
| VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, | |
| VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, | |
| VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, | |
| }; | |
| VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_info = {0}; | |
| binding_flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; | |
| binding_flags_info.bindingCount = ArrayCount(binding_flags); | |
| binding_flags_info.pBindingFlags = binding_flags; | |
| VkDescriptorSetLayoutCreateInfo global_set_layout_create_info = {0}; | |
| global_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; | |
| global_set_layout_create_info.pNext = &binding_flags_info; | |
| global_set_layout_create_info.bindingCount = ArrayCount(bindings); | |
| global_set_layout_create_info.pBindings = bindings; | |
| global_set_layout_create_info.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; | |
| R_VK_Check(vkCreateDescriptorSetLayout(r_vk_state.device, &global_set_layout_create_info, NULL, | |
| &r_vk_state.global_descriptor_set_layout)); | |
| r_vk_set_debug_name(str8_lit("global-descriptor-set-layout"), VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, | |
| (U64)r_vk_state.global_descriptor_set_layout); | |
| } | |
| // allocate descriptor set | |
| { | |
| VkDescriptorSetAllocateInfo allocate_info = {0}; | |
| allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; | |
| allocate_info.descriptorPool = r_vk_state.descriptor_pool; | |
| allocate_info.descriptorSetCount = 1; | |
| allocate_info.pSetLayouts = &r_vk_state.global_descriptor_set_layout; | |
| R_VK_Check(vkAllocateDescriptorSets(r_vk_state.device, &allocate_info, &r_vk_state.global_descriptor_set)); | |
| r_vk_set_debug_name(str8_lit("global-descriptor-set"), VK_OBJECT_TYPE_DESCRIPTOR_SET, (U64)r_vk_state.global_descriptor_set); | |
| } | |
| // Create global pipeline layout | |
| { | |
| VkPushConstantRange push_constant_range = {0}; | |
| push_constant_range.size = R_MAX_PUSH_CONSTANT_SIZE; | |
| push_constant_range.stageFlags = R_VK_SHADER_STAGES; | |
| VkPipelineLayoutCreateInfo pipeline_layout_create_info = {0}; | |
| pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; | |
| pipeline_layout_create_info.pSetLayouts = &r_vk_state.global_descriptor_set_layout; | |
| pipeline_layout_create_info.setLayoutCount = 1; | |
| pipeline_layout_create_info.pushConstantRangeCount = 1; | |
| pipeline_layout_create_info.pPushConstantRanges = &push_constant_range; | |
| R_VK_Check(vkCreatePipelineLayout(r_vk_state.device, &pipeline_layout_create_info, NULL, &r_vk_state.global_pipeline_layout)); | |
| r_vk_set_debug_name(str8_lit("global-pipeline-layout"), VK_OBJECT_TYPE_PIPELINE_LAYOUT, | |
| (U64)r_vk_state.global_pipeline_layout); | |
| } | |
| // Get memory types | |
| { | |
| VkPhysicalDeviceMemoryProperties memory_properties; | |
| vkGetPhysicalDeviceMemoryProperties(r_vk_state.physical_device, &memory_properties); | |
| memcpy(&r_vk_state.memory_types, &memory_properties.memoryTypes, MemberSize(R_VK_State, memory_types)); | |
| r_vk_state.memory_type_count = memory_properties.memoryTypeCount; | |
| } | |
| // Create fence | |
| { | |
| VkFenceCreateInfo create_info = {0}; | |
| create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; | |
| create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; | |
| R_VK_Check(vkCreateFence(r_vk_state.device, &create_info, NULL, &r_vk_state.render_finished_fence)); | |
| r_vk_set_debug_name(str8_lit("render-finished-fence"), VK_OBJECT_TYPE_FENCE, (U64)r_vk_state.render_finished_fence); | |
| } | |
| // create upload finished semaphore | |
| { | |
| r_vk_state.upload_finished_semaphore = r_vk_create_semaphore(); | |
| r_vk_set_debug_name(str8_lit("upload-finished-semaphore"), VK_OBJECT_TYPE_SEMAPHORE, | |
| (U64)r_vk_state.upload_finished_semaphore); | |
| } | |
| // Init frame state | |
| { | |
| for (U32 i = 0; i < 2; i++) | |
| { | |
| Arena_Temp scratch = get_scratch(); | |
| Str8 frame_suffix = str8_format(scratch.arena, "__frame-%i", i); | |
| R_VK_Frame_State *frame_state = &r_vk_state.frame_states[i]; | |
| VkCommandPoolCreateInfo command_pool_create_info = {0}; | |
| command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | |
| command_pool_create_info.queueFamilyIndex = r_vk_state.graphics_queue_family_index; | |
| R_VK_Check(vkCreateCommandPool(r_vk_state.device, &command_pool_create_info, NULL, &frame_state->command_pool)); | |
| r_vk_set_debug_name_with_suffix(str8_lit("command-pool"), frame_suffix, VK_OBJECT_TYPE_COMMAND_POOL, | |
| (U64)frame_state->command_pool); | |
| VkCommandBufferAllocateInfo allocate_info = {0}; | |
| allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | |
| allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | |
| allocate_info.commandPool = frame_state->command_pool; | |
| allocate_info.commandBufferCount = 2; | |
| R_VK_Check(vkAllocateCommandBuffers(r_vk_state.device, &allocate_info, &frame_state->command_buffer)); | |
| frame_state->staging_arena.buffer = r_buffer_alloc(&(R_Buffer_Params){ | |
| .flags = R_BUFFER_FLAG_HOST_ALLOCATION | R_BUFFER_FLAG_TRANSFER_SRC, | |
| .capacity = params->staging_memory_cap, | |
| .label = str8_concat(scratch.arena, str8_lit("staging-arena-backing-buffer"), frame_suffix), | |
| }); | |
| frame_state->frame_data_arena.buffer = r_buffer_alloc(&(R_Buffer_Params){ | |
| .flags = R_BUFFER_FLAG_HOST_ALLOCATION, | |
| .capacity = params->data_memory_cap, | |
| .label = str8_concat(scratch.arena, str8_lit("data-arena-backing-buffer"), frame_suffix), | |
| }); | |
| release_scratch(&scratch); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment