|
|
|
@ -316,6 +316,26 @@ void object_update_mappings(Material material, Object object, uint32_t frame_num
|
|
|
|
|
map_iterator_free(mapping_iterator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphore* create_semaphores(VkDevice device, VkSemaphoreCreateFlags flags, uint32_t count) {
|
|
|
|
|
VkSemaphore* semaphores = malloc(sizeof(VkSemaphore)*count);
|
|
|
|
|
if(semaphores == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphoreCreateInfo semaphore_info = {};
|
|
|
|
|
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
|
|
|
semaphore_info.flags = flags;
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < count; i++) {
|
|
|
|
|
VkResult result = vkCreateSemaphore(device, &semaphore_info, 0, &semaphores[i]);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
free(semaphores);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return semaphores;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFormat find_depth_format(VkPhysicalDevice physical_device, uint32_t num_requested, VkFormat* requested, VkImageTiling tiling, VkFormatFeatureFlags features) {
|
|
|
|
|
for(uint32_t i = 0; i < num_requested; i++) {
|
|
|
|
|
VkFormatProperties properties;
|
|
|
|
@ -763,7 +783,6 @@ VkSwapchainKHR create_swapchain(VkDevice device, VkSurfaceFormatKHR format, VkPr
|
|
|
|
|
swapchain_info.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
|
|
|
|
|
swapchain_info.presentMode = present_mode;
|
|
|
|
|
swapchain_info.clipped = VK_TRUE;
|
|
|
|
|
|
|
|
|
|
swapchain_info.oldSwapchain = old_swapchain;
|
|
|
|
|
|
|
|
|
|
VkSwapchainKHR swapchain;
|
|
|
|
@ -1167,7 +1186,7 @@ VkResult command_copy_buffers(VkDevice device, VkCommandPool transfer_pool, VkQu
|
|
|
|
|
return command_end_single(device, command_buffer, transfer_pool, transfer_queue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family) {
|
|
|
|
|
VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags) {
|
|
|
|
|
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
|
|
|
|
|
|
|
|
|
|
VkImageMemoryBarrier barrier = {
|
|
|
|
@ -1178,7 +1197,7 @@ VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer
|
|
|
|
|
.dstQueueFamilyIndex = dest_family,
|
|
|
|
|
.image = image,
|
|
|
|
|
.subresourceRange = {
|
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
.aspectMask = aspect_flags,
|
|
|
|
|
.levelCount = 1,
|
|
|
|
|
.layerCount = 1,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
@ -1292,7 +1311,7 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device,
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.image, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_family, transfer_family);
|
|
|
|
|
result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.image, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_family, transfer_family, VK_IMAGE_ASPECT_COLOR_BIT);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
deallocate_buffer(device, staging);
|
|
|
|
|
deallocate_image(device, image);
|
|
|
|
@ -1306,14 +1325,14 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device,
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family);
|
|
|
|
|
result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family, VK_IMAGE_ASPECT_COLOR_BIT);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
deallocate_buffer(device, staging);
|
|
|
|
|
deallocate_image(device, image);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family);
|
|
|
|
|
result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family, VK_IMAGE_ASPECT_COLOR_BIT);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
deallocate_buffer(device, staging);
|
|
|
|
|
deallocate_image(device, image);
|
|
|
|
@ -1602,17 +1621,27 @@ int create_depth_image(VulkanContext* context) {
|
|
|
|
|
context->depth_image_view = depth_image_view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = command_transition_image_layout(context->device, context->extra_graphics_pool, context->queues.graphics, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, context->depth_image, 0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, VK_IMAGE_ASPECT_DEPTH_BIT);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to transition depth image\n");
|
|
|
|
|
return 5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult recreate_swap_chain(VulkanContext* context) {
|
|
|
|
|
VkResult recreate_swapchain(VulkanContext* context) {
|
|
|
|
|
for(uint32_t i = 0; i < context->swapchain_image_count; i++) {
|
|
|
|
|
vkDestroyFramebuffer(context->device, context->swapchain_framebuffers[i], 0);
|
|
|
|
|
vkDestroyImageView(context->device, context->swapchain_image_views[i], 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vkDestroySwapchainKHR(context->device, context->swapchain, 0);
|
|
|
|
|
free(context->swapchain_images);
|
|
|
|
|
for(uint32_t i = 0; i < context->max_frames_in_flight; i++) {
|
|
|
|
|
vkDestroySemaphore(context->device, context->image_available_semaphores[i], 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//vkDestroySwapchainKHR(context->device, context->swapchain, 0);
|
|
|
|
|
//free(context->swapchain_images);
|
|
|
|
|
free(context->swapchain_image_views);
|
|
|
|
|
free(context->swapchain_framebuffers);
|
|
|
|
|
free(context->swapchain_details.formats);
|
|
|
|
@ -1665,6 +1694,14 @@ VkResult recreate_swap_chain(VulkanContext* context) {
|
|
|
|
|
context->swapchain_framebuffers = framebuffers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphore* ia_semaphores = create_semaphores(context->device, 0, context->max_frames_in_flight);
|
|
|
|
|
if(ia_semaphores == 0) {
|
|
|
|
|
fprintf(stderr, "failed to create vulkan image available semaphores\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->image_available_semaphores = ia_semaphores;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1787,26 +1824,6 @@ VkCommandBuffer* create_command_buffers(VkDevice device, VkCommandPool command_p
|
|
|
|
|
return command_buffers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphore* create_semaphores(VkDevice device, VkSemaphoreCreateFlags flags, uint32_t count) {
|
|
|
|
|
VkSemaphore* semaphores = malloc(sizeof(VkSemaphore)*count);
|
|
|
|
|
if(semaphores == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphoreCreateInfo semaphore_info = {};
|
|
|
|
|
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
|
|
|
semaphore_info.flags = flags;
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < count; i++) {
|
|
|
|
|
VkResult result = vkCreateSemaphore(device, &semaphore_info, 0, &semaphores[i]);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
free(semaphores);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return semaphores;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count) {
|
|
|
|
|
VkFence* fences = malloc(sizeof(VkFence)*count);
|
|
|
|
|
if(fences == 0) {
|
|
|
|
@ -2406,6 +2423,18 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
context->depth_format = depth_format;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkCommandPoolCreateInfo extra_pool_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
|
|
.queueFamilyIndex = context->queue_indices.graphics_family,
|
|
|
|
|
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateCommandPool(context->device, &extra_pool_info, 0, &context->extra_graphics_pool);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "failed to create extra graphics command pool\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(create_depth_image(context) != 0) {
|
|
|
|
|
fprintf(stderr, "failed to create depth image\n");
|
|
|
|
|
return 0;
|
|
|
|
@ -2465,14 +2494,6 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
context->swapchain_command_buffers = swapchain_command_buffers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkCommandPoolCreateInfo extra_pool_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
|
|
.queueFamilyIndex = context->queue_indices.graphics_family,
|
|
|
|
|
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreateCommandPool(context->device, &extra_pool_info, 0, &context->extra_graphics_pool);
|
|
|
|
|
|
|
|
|
|
VkSemaphore* ia_semaphores = create_semaphores(context->device, 0, max_frames_in_flight);
|
|
|
|
|
if(ia_semaphores == 0) {
|
|
|
|
|
fprintf(stderr, "failed to create vulkan image available semaphores\n");
|
|
|
|
@ -3261,7 +3282,8 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
|
|
|
|
|
|
|
|
|
|
VkResult result = draw_frame(context, &scene, sizeof(materials)/sizeof(Material), materials, objects_counts, objects);
|
|
|
|
|
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
|
|
|
|
|
recreate_swap_chain(context);
|
|
|
|
|
vkDeviceWaitIdle(context->device);
|
|
|
|
|
recreate_swapchain(context);
|
|
|
|
|
} else if(result != VK_SUCCESS) {
|
|
|
|
|
fprintf(stderr, "draw_frame error %d\n", result);
|
|
|
|
|
return;
|
|
|
|
|