|
|
|
@ -446,21 +446,19 @@ VkDescriptorSet* create_descriptor_sets(VkDevice device, VkDescriptorSetLayout l
|
|
|
|
|
return sets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDevice get_best_physical_device(VkInstance instance) {
|
|
|
|
|
VkPhysicalDevice device = VK_NULL_HANDLE;
|
|
|
|
|
|
|
|
|
|
VkResult get_best_physical_device(VkInstance instance, VkPhysicalDevice* device) {
|
|
|
|
|
uint32_t device_count = 0;
|
|
|
|
|
VkResult result;
|
|
|
|
|
result = vkEnumeratePhysicalDevices(instance, &device_count, 0);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDevice* devices = malloc(sizeof(VkPhysicalDevice)*device_count);
|
|
|
|
|
result = vkEnumeratePhysicalDevices(instance, &device_count, devices);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
free(devices);
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int top_score = -1;
|
|
|
|
@ -492,13 +490,13 @@ VkPhysicalDevice get_best_physical_device(VkInstance instance) {
|
|
|
|
|
|
|
|
|
|
if(score > top_score) {
|
|
|
|
|
top_score = score;
|
|
|
|
|
device = devices[i];
|
|
|
|
|
*device = devices[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(devices);
|
|
|
|
|
|
|
|
|
|
return device;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool check_queue_indices(QueueIndices indices) {
|
|
|
|
@ -507,15 +505,8 @@ bool check_queue_indices(QueueIndices indices) {
|
|
|
|
|
&& (indices.transfer_family != 0xFFFFFFFF));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QueueIndices get_queue_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
|
|
|
|
QueueIndices indices = {
|
|
|
|
|
.graphics_family = 0xFFFFFFFF,
|
|
|
|
|
.graphics_index = 0xFFFFFFFF,
|
|
|
|
|
.present_family = 0xFFFFFFFF,
|
|
|
|
|
.present_index = 0xFFFFFFFF,
|
|
|
|
|
.transfer_family = 0xFFFFFFFF,
|
|
|
|
|
.transfer_index = 0xFFFFFFFF,
|
|
|
|
|
};
|
|
|
|
|
VkResult get_queue_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface, QueueIndices* indices) {
|
|
|
|
|
memset(indices, 0xFF, sizeof(QueueIndices));
|
|
|
|
|
|
|
|
|
|
uint32_t queue_family_count;
|
|
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, 0);
|
|
|
|
@ -528,44 +519,41 @@ QueueIndices get_queue_indices(VkPhysicalDevice physical_device, VkSurfaceKHR su
|
|
|
|
|
VkBool32 present_support;
|
|
|
|
|
vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, family_idx, surface, &present_support);
|
|
|
|
|
for(uint32_t queue_idx = 0; queue_idx < queue_families[family_idx].queueCount; queue_idx++) {
|
|
|
|
|
if(((indices.graphics_family == 0xFFFFFFFF)
|
|
|
|
|
|| (indices.present_family == 0xFFFFFFFF)
|
|
|
|
|
|| (indices.present_family != indices.graphics_family))
|
|
|
|
|
if(((indices->graphics_family == 0xFFFFFFFF)
|
|
|
|
|
|| (indices->present_family == 0xFFFFFFFF)
|
|
|
|
|
|| (indices->present_family != indices->graphics_family))
|
|
|
|
|
&& (queue_families[family_idx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
|
|
|
&& (present_support == VK_TRUE)) {
|
|
|
|
|
fprintf(stderr, "Selected %d:%d for graphics and present queues\n", family_idx, queue_idx);
|
|
|
|
|
indices.graphics_family = family_idx;
|
|
|
|
|
indices.graphics_index = queue_idx;
|
|
|
|
|
indices->graphics_family = family_idx;
|
|
|
|
|
indices->graphics_index = queue_idx;
|
|
|
|
|
|
|
|
|
|
indices.present_family = family_idx;
|
|
|
|
|
indices.present_index = queue_idx;
|
|
|
|
|
} else if((indices.graphics_family == 0xFFFFFFFF)
|
|
|
|
|
indices->present_family = family_idx;
|
|
|
|
|
indices->present_index = queue_idx;
|
|
|
|
|
} else if((indices->graphics_family == 0xFFFFFFFF)
|
|
|
|
|
&& (queue_families[family_idx].queueFlags & VK_QUEUE_GRAPHICS_BIT)) {
|
|
|
|
|
fprintf(stderr, "Selected %d:%d for graphics queue\n", family_idx, queue_idx);
|
|
|
|
|
indices.graphics_family = family_idx;
|
|
|
|
|
indices.graphics_index = queue_idx;
|
|
|
|
|
} else if((indices.present_family == 0xFFFFFFFF)
|
|
|
|
|
indices->graphics_family = family_idx;
|
|
|
|
|
indices->graphics_index = queue_idx;
|
|
|
|
|
} else if((indices->present_family == 0xFFFFFFFF)
|
|
|
|
|
&& (present_support == VK_TRUE)) {
|
|
|
|
|
fprintf(stderr, "Selected %d:%d for present queue\n", family_idx, queue_idx);
|
|
|
|
|
indices.present_family = family_idx;
|
|
|
|
|
indices.present_index = queue_idx;
|
|
|
|
|
} else if((indices.transfer_family == 0xFFFFFFFF)
|
|
|
|
|
indices->present_family = family_idx;
|
|
|
|
|
indices->present_index = queue_idx;
|
|
|
|
|
} else if((indices->transfer_family == 0xFFFFFFFF)
|
|
|
|
|
&& (queue_families[family_idx].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) {
|
|
|
|
|
fprintf(stderr, "Selected %d:%d for transfer queue\n", family_idx, queue_idx);
|
|
|
|
|
indices.transfer_family = family_idx;
|
|
|
|
|
indices.transfer_index = queue_idx;
|
|
|
|
|
indices->transfer_family = family_idx;
|
|
|
|
|
indices->transfer_index = queue_idx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(queue_families);
|
|
|
|
|
|
|
|
|
|
return indices;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) {
|
|
|
|
|
VkDebugUtilsMessengerEXT debug_messenger;
|
|
|
|
|
|
|
|
|
|
VkResult create_debug_messenger(VkInstance instance, VkDebugUtilsMessengerEXT* debug_messenger) {
|
|
|
|
|
VkDebugUtilsMessengerCreateInfoEXT messenger_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
|
|
|
|
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
|
|
|
|
@ -577,21 +565,23 @@ VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) {
|
|
|
|
|
PFN_vkCreateDebugUtilsMessengerEXT func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
result = func(instance, &messenger_info, 0, &debug_messenger);
|
|
|
|
|
result = func(instance, &messenger_info, 0, debug_messenger);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to create debug messenger\n");
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return debug_messenger;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkInstance create_instance() {
|
|
|
|
|
VkInstance instance;
|
|
|
|
|
VkResult create_instance(VkInstance* instance) {
|
|
|
|
|
if(instance == NULL) {
|
|
|
|
|
return VK_ERROR_VALIDATION_FAILED_EXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(check_validation_layers(validation_layers, validation_layer_count) == false) {
|
|
|
|
|
fprintf(stderr, "requested validation layers not supported");
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return VK_ERROR_VALIDATION_FAILED_EXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkApplicationInfo app_info = {
|
|
|
|
@ -629,20 +619,17 @@ VkInstance create_instance() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkResult result = vkCreateInstance(&instance_info, 0, &instance);
|
|
|
|
|
VkResult result = vkCreateInstance(&instance_info, 0, instance);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "vkCreateInstance: 0x%02x\n", result);
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(requested_extensions);
|
|
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDevice create_logical_device(VkPhysicalDevice physical_device, QueueIndices queue_indices) {
|
|
|
|
|
VkDevice device;
|
|
|
|
|
|
|
|
|
|
VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices queue_indices, VkDevice* device) {
|
|
|
|
|
uint32_t unique_families[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
|
|
|
|
|
uint32_t unique_family_queues[3] = {0, 0, 0};
|
|
|
|
|
uint32_t unique_family_count = 0;
|
|
|
|
@ -696,12 +683,12 @@ VkDevice create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu
|
|
|
|
|
.ppEnabledLayerNames = validation_layers,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result = vkCreateDevice(physical_device, &device_create_info, 0, &device);
|
|
|
|
|
VkResult result = vkCreateDevice(physical_device, &device_create_info, 0, device);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return device;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SwapchainDetails get_swapchain_details(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
|
|
|
@ -2195,59 +2182,47 @@ Mesh* load_mesh_to_buffer(VkDevice device, GPUPage* page, GPUBuffer staging, uin
|
|
|
|
|
VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
VulkanContext* context = (VulkanContext*)malloc(sizeof(VulkanContext));
|
|
|
|
|
|
|
|
|
|
VkInstance instance = create_instance();
|
|
|
|
|
if(instance == VK_NULL_HANDLE) {
|
|
|
|
|
VkResult result = create_instance(&context->instance);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to initialize vulkan instance\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->instance = instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDebugUtilsMessengerEXT debug_messenger = create_debug_messenger(context->instance);
|
|
|
|
|
if(debug_messenger == VK_NULL_HANDLE) {
|
|
|
|
|
result = create_debug_messenger(context->instance, &context->debug_messenger);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to initialize vulkan debug messenger\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->debug_messenger = debug_messenger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDevice physical_device = get_best_physical_device(context->instance);
|
|
|
|
|
if(physical_device == VK_NULL_HANDLE) {
|
|
|
|
|
result = get_best_physical_device(context->instance, &context->physical_device);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to pick vulkan physical device\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->physical_device = physical_device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vkGetPhysicalDeviceMemoryProperties(context->physical_device, &context->memories);
|
|
|
|
|
|
|
|
|
|
VkSurfaceKHR surface;
|
|
|
|
|
VkResult result = glfwCreateWindowSurface(instance, window, 0, &surface);
|
|
|
|
|
result = glfwCreateWindowSurface(context->instance, window, 0, &context->surface);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to create vulkan surface\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->surface = surface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QueueIndices queue_indices = get_queue_indices(context->physical_device, context->surface);
|
|
|
|
|
if(check_queue_indices(queue_indices) == false) {
|
|
|
|
|
result = get_queue_indices(context->physical_device, context->surface, &context->queue_indices);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to get vulkan queue indices\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->queue_indices = queue_indices;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDevice device = create_logical_device(context->physical_device, context->queue_indices);
|
|
|
|
|
if(device == VK_NULL_HANDLE) {
|
|
|
|
|
result = create_logical_device(context->physical_device, context->queue_indices, &context->device);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to create vulkan logical device\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->device = device;
|
|
|
|
|
}
|
|
|
|
|
vkGetDeviceQueue(device, context->queue_indices.graphics_family, context->queue_indices.graphics_index, &context->queues.graphics);
|
|
|
|
|
vkGetDeviceQueue(device, context->queue_indices.present_family, context->queue_indices.present_index, &context->queues.present);
|
|
|
|
|
vkGetDeviceQueue(device, context->queue_indices.transfer_family, context->queue_indices.transfer_index, &context->queues.transfer);
|
|
|
|
|
|
|
|
|
|
vkGetDeviceQueue(context->device, context->queue_indices.graphics_family, context->queue_indices.graphics_index, &context->queues.graphics);
|
|
|
|
|
vkGetDeviceQueue(context->device, context->queue_indices.present_family, context->queue_indices.present_index, &context->queues.present);
|
|
|
|
|
vkGetDeviceQueue(context->device, context->queue_indices.transfer_family, context->queue_indices.transfer_index, &context->queues.transfer);
|
|
|
|
|
|
|
|
|
|
SwapchainDetails swapchain_details = get_swapchain_details(context->physical_device, context->surface);
|
|
|
|
|
if(swapchain_details.formats == 0) {
|
|
|
|
@ -2394,7 +2369,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
context->in_flight_fences = if_fences;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = gpu_page_allocate(context->device, context->memories, 1000000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &context->g_buffer_page);
|
|
|
|
|
result = gpu_page_allocate(context->device, context->memories, 15360000*3, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &context->g_buffer_page);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -2412,10 +2387,12 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
.arrayLayers = 1,
|
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
|
|
|
|
.format = VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = gpu_image_malloc(context->device, context->g_buffer_page, &g_pos_info, &context->g_image_position);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to allocate image\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2434,6 +2411,10 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateImageView(context->device, &g_pos_view_info, 0, &context->g_image_view_position);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to create image view\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|