|
|
|
|
@ -29,6 +29,7 @@ const char * device_extensions[] = {
|
|
|
|
|
"VK_KHR_portability_subset",
|
|
|
|
|
#endif
|
|
|
|
|
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
|
|
|
|
|
VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
|
|
|
|
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
|
|
|
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
|
|
|
|
|
VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME,
|
|
|
|
|
@ -149,7 +150,7 @@ VkResult create_instance(VkInstance* instance) {
|
|
|
|
|
.applicationVersion = VK_MAKE_VERSION(0, 0, 1),
|
|
|
|
|
.pEngineName = "roleplay",
|
|
|
|
|
.engineVersion = VK_MAKE_VERSION(0, 0, 1),
|
|
|
|
|
.apiVersion = VK_API_VERSION_1_2,
|
|
|
|
|
.apiVersion = VK_API_VERSION_1_3,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32_t glfwExtensionCount = 0;
|
|
|
|
|
@ -391,9 +392,15 @@ VkResult create_logical_device(
|
|
|
|
|
queue_create_info[1].pQueuePriorities = &default_queue_priority;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
|
|
|
|
|
.dynamicRendering = VK_TRUE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceSynchronization2FeaturesKHR sync2 = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR,
|
|
|
|
|
.synchronization2 = VK_TRUE,
|
|
|
|
|
.pNext = &dynamic_rendering,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Features features_12 = {
|
|
|
|
|
@ -442,7 +449,7 @@ VkResult create_memory_allocator(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VmaAllocator* allocator) {
|
|
|
|
|
VmaAllocatorCreateInfo allocator_create_info = {
|
|
|
|
|
.vulkanApiVersion = VK_API_VERSION_1_2,
|
|
|
|
|
.vulkanApiVersion = VK_API_VERSION_1_3,
|
|
|
|
|
.instance = instance,
|
|
|
|
|
.physicalDevice = physical_device,
|
|
|
|
|
.device = device,
|
|
|
|
|
@ -652,153 +659,6 @@ VkResult find_depth_format(
|
|
|
|
|
return VK_ERROR_VALIDATION_FAILED_EXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_render_pass(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkSurfaceFormatKHR format,
|
|
|
|
|
VkFormat depth_format,
|
|
|
|
|
VkRenderPass* render_pass) {
|
|
|
|
|
VkAttachmentDescription attachments[] = {
|
|
|
|
|
{
|
|
|
|
|
.format = format.format,
|
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
|
|
|
|
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
|
|
|
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
|
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
|
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.format = depth_format,
|
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
|
|
|
|
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
|
|
|
|
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
|
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkAttachmentReference color_attachment_refs[] = {
|
|
|
|
|
{
|
|
|
|
|
.attachment = 0,
|
|
|
|
|
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkAttachmentReference depth_attachment_ref = {
|
|
|
|
|
.attachment = 1,
|
|
|
|
|
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Create a subpass with the color and depth attachments
|
|
|
|
|
VkSubpassDescription subpasses[] = {
|
|
|
|
|
{
|
|
|
|
|
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
|
|
.colorAttachmentCount = sizeof(color_attachment_refs)/sizeof(VkAttachmentReference),
|
|
|
|
|
.pColorAttachments = color_attachment_refs,
|
|
|
|
|
.pDepthStencilAttachment = &depth_attachment_ref,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
|
|
|
|
.colorAttachmentCount = sizeof(color_attachment_refs)/sizeof(VkAttachmentReference),
|
|
|
|
|
.pColorAttachments = color_attachment_refs,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// This basically says "make sure nothing else is writing to the depth_stencil or the color attachment during the pipeline
|
|
|
|
|
VkSubpassDependency dependencies[] = {
|
|
|
|
|
{
|
|
|
|
|
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
|
|
|
|
.dstSubpass = 1,
|
|
|
|
|
.srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
|
.dstStageMask = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
|
|
|
|
.dstSubpass = 0,
|
|
|
|
|
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
|
|
|
|
.dstSubpass = 0,
|
|
|
|
|
.srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.srcSubpass = 0,
|
|
|
|
|
.dstSubpass = 1,
|
|
|
|
|
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkRenderPassCreateInfo render_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
|
|
|
|
.attachmentCount = sizeof(attachments)/sizeof(VkAttachmentDescription),
|
|
|
|
|
.pAttachments = attachments,
|
|
|
|
|
.subpassCount = sizeof(subpasses)/sizeof(VkSubpassDescription),
|
|
|
|
|
.pSubpasses = subpasses,
|
|
|
|
|
.dependencyCount = sizeof(dependencies)/sizeof(VkSubpassDependency),
|
|
|
|
|
.pDependencies = dependencies,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
VK_RESULT(vkCreateRenderPass(device, &render_info, 0, render_pass));
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult create_swapchain_framebuffers(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
uint32_t image_count,
|
|
|
|
|
VkImageView* image_views,
|
|
|
|
|
VkImageView depth_image_view,
|
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
|
VkExtent2D extent,
|
|
|
|
|
VkFramebuffer** framebuffers) {
|
|
|
|
|
*framebuffers = malloc(sizeof(VkFramebuffer)*image_count);
|
|
|
|
|
if(*framebuffers == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFramebuffer* framebuffer_ptr = *framebuffers;
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < image_count; i++) {
|
|
|
|
|
VkImageView attachments[] = {
|
|
|
|
|
image_views[i],
|
|
|
|
|
depth_image_view,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkFramebufferCreateInfo framebuffer_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
|
|
|
|
.renderPass = render_pass,
|
|
|
|
|
.attachmentCount = 2,
|
|
|
|
|
.pAttachments = attachments,
|
|
|
|
|
.width = extent.width,
|
|
|
|
|
.height = extent.height,
|
|
|
|
|
.layers = 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result = vkCreateFramebuffer(device, &framebuffer_info, 0, &framebuffer_ptr[i]);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
free(*framebuffers);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphore create_timeline_semaphore(VkDevice device) {
|
|
|
|
|
VkSemaphoreTypeCreateInfo semaphore_type = {
|
|
|
|
|
@ -1059,15 +919,11 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
|
|
|
|
|
&context->swapchain_images,
|
|
|
|
|
&context->swapchain_image_count));
|
|
|
|
|
|
|
|
|
|
context->swapchain_command_buffers = create_command_buffers(context->device, context->graphics_pool, context->swapchain_image_count);
|
|
|
|
|
if(context->swapchain_command_buffers == NULL) {
|
|
|
|
|
context->frame_command_buffers = create_command_buffers(context->device, context->graphics_pool, MAX_FRAMES_IN_FLIGHT);
|
|
|
|
|
if(context->frame_command_buffers == NULL) {
|
|
|
|
|
return VK_ERROR_VALIDATION_FAILED_EXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
context->swapchain_command_buffer_record_id = 1;
|
|
|
|
|
context->swapchain_command_buffer_record_ids = malloc(sizeof(uint64_t)*context->swapchain_image_count);
|
|
|
|
|
memset(context->swapchain_command_buffer_record_ids, 0, sizeof(uint64_t)*context->swapchain_image_count);
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_image_views(
|
|
|
|
|
context->device,
|
|
|
|
|
context->swapchain_image_count,
|
|
|
|
|
@ -1081,12 +937,6 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
|
|
|
|
|
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
|
|
|
|
&context->depth_format));
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_render_pass(
|
|
|
|
|
context->device,
|
|
|
|
|
context->swapchain_format,
|
|
|
|
|
context->depth_format,
|
|
|
|
|
&context->render_pass));
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_depth_image(
|
|
|
|
|
context->device,
|
|
|
|
|
context->depth_format,
|
|
|
|
|
@ -1098,15 +948,6 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) {
|
|
|
|
|
&context->depth_image_memory,
|
|
|
|
|
&context->depth_image_view));
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_swapchain_framebuffers(
|
|
|
|
|
context->device,
|
|
|
|
|
context->swapchain_image_count,
|
|
|
|
|
context->swapchain_image_views,
|
|
|
|
|
context->depth_image_view,
|
|
|
|
|
context->render_pass,
|
|
|
|
|
context->swapchain_extent,
|
|
|
|
|
&context->swapchain_framebuffers));
|
|
|
|
|
|
|
|
|
|
context->current_frame = 0;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
@ -1360,7 +1201,6 @@ VkResult recreate_framebuffer(RenderContext* gpu) {
|
|
|
|
|
vkDeviceWaitIdle(gpu->device);
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < gpu->swapchain_image_count; i++) {
|
|
|
|
|
vkDestroyFramebuffer(gpu->device, gpu->swapchain_framebuffers[i], NULL);
|
|
|
|
|
vkDestroyImageView(gpu->device, gpu->swapchain_image_views[i], NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1369,7 +1209,6 @@ VkResult recreate_framebuffer(RenderContext* gpu) {
|
|
|
|
|
|
|
|
|
|
free(gpu->swapchain_images);
|
|
|
|
|
free(gpu->swapchain_image_views);
|
|
|
|
|
free(gpu->swapchain_framebuffers);
|
|
|
|
|
free(gpu->swapchain_details.formats);
|
|
|
|
|
free(gpu->swapchain_details.present_modes);
|
|
|
|
|
|
|
|
|
|
@ -1415,15 +1254,6 @@ VkResult recreate_framebuffer(RenderContext* gpu) {
|
|
|
|
|
&gpu->depth_image_memory,
|
|
|
|
|
&gpu->depth_image_view));
|
|
|
|
|
|
|
|
|
|
VK_RESULT(create_swapchain_framebuffers(
|
|
|
|
|
gpu->device,
|
|
|
|
|
gpu->swapchain_image_count,
|
|
|
|
|
gpu->swapchain_image_views,
|
|
|
|
|
gpu->depth_image_view,
|
|
|
|
|
gpu->render_pass,
|
|
|
|
|
gpu->swapchain_extent,
|
|
|
|
|
&gpu->swapchain_framebuffers));
|
|
|
|
|
|
|
|
|
|
gpu->framebuffer_recreated = true;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|