diff --git a/src/main.c b/src/main.c index 15dbd20..9b6311a 100644 --- a/src/main.c +++ b/src/main.c @@ -144,12 +144,6 @@ typedef struct MaterialStruct { Map object_descriptor_mappings; } Material; -typedef struct MemoryIndicesStruct { - uint32_t host_visible; - uint32_t device_local; - uint32_t device_lazy; -} MemoryIndices; - typedef struct VulkanContextStruct { VkInstance instance; VkDebugUtilsMessengerEXT debug_messenger; @@ -194,7 +188,8 @@ typedef struct VulkanContextStruct { uint32_t current_frame; - MemoryIndices memory_indices; + VkPhysicalDeviceMemoryProperties memories; + VkCommandPool extra_graphics_pool; } VulkanContext; typedef struct SceneContextStruct { @@ -269,6 +264,17 @@ void glfw_error(int error, const char* description) { fprintf(stderr, "GLFW_ERR: 0x%02x - %s\n", error, description); } +uint32_t pick_memory(VkPhysicalDeviceMemoryProperties properties, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude) { + for(uint32_t i = 0; i < properties.memoryTypeCount; i++){ + if((filter & (1 << i)) + && ((include & properties.memoryTypes[i].propertyFlags) == include) + && ((exclude & properties.memoryTypes[i].propertyFlags) == 0)) { + return i; + } + } + return 0xFFFFFFFF; +} + GLFWwindow* init_window(int width, int height) { glfwInit(); glfwSetErrorCallback(glfw_error); @@ -864,7 +870,7 @@ VkFramebuffer* create_swapchain_framebuffers(VkDevice device, uint32_t image_cou VkShaderModule create_shader_module(VkDevice device, const char * code, uint32_t code_size) { VkShaderModuleCreateInfo shader_info = {}; - shader_info.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT; + shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shader_info.codeSize = code_size; shader_info.pCode = (uint32_t*)code; @@ -968,18 +974,7 @@ VkRenderPass create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFo return render_pass; } -uint32_t pick_memory_type(VkPhysicalDeviceMemoryProperties memories, uint32_t filter, VkMemoryPropertyFlags flags) { - for(uint32_t i = 0; i < memories.memoryTypeCount; i++) { - if((filter & (1 << i)) - && ((memories.memoryTypes[i].propertyFlags & flags) == flags)) { - return i; - } - } - - return 0xFFFFFFFF; -} - -AllocatedImage allocate_image(uint32_t memory_index, VkDevice device, VkImageType type, VkFormat format, VkExtent3D size, VkImageUsageFlags usage) { +AllocatedImage allocate_image(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkImageType type, VkFormat format, VkExtent3D size, VkImageUsageFlags usage, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude) { VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .imageType = type, @@ -1010,7 +1005,7 @@ AllocatedImage allocate_image(uint32_t memory_index, VkDevice device, VkImageTyp VkMemoryAllocateInfo memory_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = memory_requirements.size, - .memoryTypeIndex = memory_index, + .memoryTypeIndex = pick_memory(memories, memory_requirements.memoryTypeBits, include, exclude), }; result = vkAllocateMemory(device, &memory_info, 0, &allocated.memory); @@ -1033,7 +1028,7 @@ AllocatedImage allocate_image(uint32_t memory_index, VkDevice device, VkImageTyp return allocated; } -AllocatedBuffer allocate_buffer(uint32_t memory_index, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage) { +AllocatedBuffer allocate_buffer(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude) { AllocatedBuffer ret = {}; ret.memory = VK_NULL_HANDLE; ret.buffer = VK_NULL_HANDLE; @@ -1058,7 +1053,7 @@ AllocatedBuffer allocate_buffer(uint32_t memory_index, VkDevice device, VkDevice VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = memory_index; + alloc_info.memoryTypeIndex = pick_memory(memories, memory_requirements.memoryTypeBits, include, exclude); result = vkAllocateMemory(device, &alloc_info, 0, &ret.memory); if(result != VK_SUCCESS) { @@ -1089,14 +1084,14 @@ void deallocate_image(VkDevice device, AllocatedImage image) { vkFreeMemory(device, image.memory, 0); }; -AllocatedBuffer* allocate_buffers(uint32_t memory_index, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, uint32_t count) { +AllocatedBuffer* allocate_buffers(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, uint32_t count, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude) { AllocatedBuffer* buffers = malloc(sizeof(AllocatedBuffer)*count); if(buffers == 0) { return 0; } for(uint32_t i = 0; i < count; i++) { - buffers[i] = allocate_buffer(memory_index, device, size, usage); + buffers[i] = allocate_buffer(memories, device, size, usage, include, exclude); if(buffers[i].memory == VK_NULL_HANDLE) { for(uint32_t j = 0; j < i; j++) { deallocate_buffer(device, buffers[i]); @@ -1137,12 +1132,18 @@ VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_poo } VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, VkQueue transfer_queue) { + VkResult result = vkEndCommandBuffer(command_buffer); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } + VkSubmitInfo submit_info = {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &command_buffer; - VkResult result = vkQueueSubmit(transfer_queue, 1, &submit_info, 0); + result = vkQueueSubmit(transfer_queue, 1, &submit_info, 0); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; @@ -1162,24 +1163,19 @@ VkResult command_copy_buffers(VkDevice device, VkCommandPool transfer_pool, VkQu copy_region.size = size; vkCmdCopyBuffer(command_buffer, source, dest, 1, ©_region); - VkResult result = vkEndCommandBuffer(command_buffer); - if(result != VK_SUCCESS) { - vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); - return result; - } 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) { +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) { VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .oldLayout = old_layout, .newLayout = new_layout, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .srcQueueFamilyIndex = source_family, + .dstQueueFamilyIndex = dest_family, .image = image, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, @@ -1188,10 +1184,10 @@ VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer .baseMipLevel = 0, .baseArrayLayer = 0, }, - .srcAccessMask = 0, - .dstAccessMask = 0, + .srcAccessMask = src_mask, + .dstAccessMask = dst_mask, }; - vkCmdPipelineBarrier(command_buffer, 0, 0, 0, 0, 0, 0, 0, 1, &barrier); + vkCmdPipelineBarrier(command_buffer, source, dest, 0, 0, 0, 0, 0, 1, &barrier); return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } @@ -1222,10 +1218,10 @@ VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_po return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -AllocatedBuffer create_populated_buffer(MemoryIndices memories, VkDevice device, void* data, VkDeviceSize size, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBufferUsageFlags usage) { +AllocatedBuffer create_populated_buffer(VkPhysicalDeviceMemoryProperties memories, VkDevice device, void* data, VkDeviceSize size, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBufferUsageFlags usage) { AllocatedBuffer staging_buffer = {}; AllocatedBuffer vertex_buffer = {}; - staging_buffer = allocate_buffer(memories.host_visible, device, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + staging_buffer = allocate_buffer(memories, device, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(staging_buffer.memory == VK_NULL_HANDLE) { return vertex_buffer; } @@ -1242,7 +1238,7 @@ AllocatedBuffer create_populated_buffer(MemoryIndices memories, VkDevice device, vkUnmapMemory(device, staging_buffer.memory); - vertex_buffer = allocate_buffer(memories.device_local, device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage); + vertex_buffer = allocate_buffer(memories, device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { deallocate_buffer(device, staging_buffer); return vertex_buffer; @@ -1260,7 +1256,7 @@ AllocatedBuffer create_populated_buffer(MemoryIndices memories, VkDevice device, return vertex_buffer; } -Texture load_texture(MemoryIndices memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkExtent2D size, uint32_t stride, VkFormat format, void* image_data){ +Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, uint32_t stride, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family){ Texture ret = { .image.image = VK_NULL_HANDLE, .image.memory = VK_NULL_HANDLE, @@ -1268,7 +1264,7 @@ Texture load_texture(MemoryIndices memories, VkDevice device, VkCommandPool tran }; uint32_t image_size = size.width * size.height * stride; - AllocatedBuffer staging = allocate_buffer(memories.host_visible, device, image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + AllocatedBuffer staging = allocate_buffer(memories, device, image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(staging.memory == VK_NULL_HANDLE) { return ret; } @@ -1289,14 +1285,14 @@ Texture load_texture(MemoryIndices memories, VkDevice device, VkCommandPool tran .height = size.height, .depth = 1, }; - AllocatedImage image = allocate_image(memories.device_local, device, VK_IMAGE_TYPE_2D, format, full_extent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + AllocatedImage image = allocate_image(memories, device, VK_IMAGE_TYPE_2D, format, full_extent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0); if(image.memory == VK_NULL_HANDLE) { deallocate_buffer(device, staging); deallocate_image(device, image); return ret; } - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.image); + 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); if(result != VK_SUCCESS) { deallocate_buffer(device, staging); deallocate_image(device, image); @@ -1310,6 +1306,20 @@ Texture load_texture(MemoryIndices memories, VkDevice device, VkCommandPool tran 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); + 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); + if(result != VK_SUCCESS) { + deallocate_buffer(device, staging); + deallocate_image(device, image); + return ret; + } + VkImageView view; VkImageViewCreateInfo view_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, @@ -1491,6 +1501,7 @@ VkPipeline create_graphics_pipeline( pipeline_info.pColorBlendState = &color_blend_info; pipeline_info.pDynamicState = &dynamic_info; pipeline_info.pDepthStencilState = &depth_info; + pipeline_info.pMultisampleState = &multisample_info; pipeline_info.layout = layout; pipeline_info.renderPass = render_pass; pipeline_info.subpass = 0; @@ -1507,21 +1518,6 @@ VkPipeline create_graphics_pipeline( return pipeline; } -VkCommandPool create_command_pool(VkDevice device, uint32_t queue_family) { - VkCommandPoolCreateInfo pool_info = {}; - pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - pool_info.queueFamilyIndex = queue_family; - - VkCommandPool command_pool; - VkResult result = vkCreateCommandPool(device, &pool_info, 0, &command_pool); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return command_pool; -} - int create_depth_image(VulkanContext* context) { VkExtent3D depth_extent = { .width = context->swapchain_extent.width, @@ -1538,7 +1534,7 @@ int create_depth_image(VulkanContext* context) { .format = context->depth_format, .tiling = VK_IMAGE_TILING_OPTIMAL, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .samples = VK_SAMPLE_COUNT_1_BIT, .flags = 0, @@ -1559,7 +1555,7 @@ int create_depth_image(VulkanContext* context) { VkMemoryAllocateInfo depth_memory_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = depth_image_requirements.size, - .memoryTypeIndex = context->memory_indices.device_lazy, + .memoryTypeIndex = pick_memory(context->memories, depth_image_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0), }; VkDeviceMemory depth_image_memory; @@ -1831,7 +1827,7 @@ VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count return fences; } -Mesh* load_texture_mesh(MemoryIndices memories, VkDevice device, struct TextureVertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Mesh* load_texture_mesh(VkPhysicalDeviceMemoryProperties memories, VkDevice device, struct TextureVertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { AllocatedBuffer vertex_buffer = create_populated_buffer(memories, device, (void*)vertices, sizeof(struct TextureVertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { return 0; @@ -1938,7 +1934,7 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set return object; } -Mesh* load_simple_mesh(MemoryIndices memories, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Mesh* load_simple_mesh(VkPhysicalDeviceMemoryProperties memories, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { AllocatedBuffer vertex_buffer = create_populated_buffer(memories, device, (void*)vertices, sizeof(struct Vertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { return 0; @@ -2105,16 +2101,21 @@ Material create_material( Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) { VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device); VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device); - VkPipelineShaderStageCreateInfo shader_stages[2] = {}; - shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT; - shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; - shader_stages[0].module = vert_shader; - shader_stages[0].pName = "main"; + VkPipelineShaderStageCreateInfo shader_stages[2] = { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vert_shader, + .pName = "main", + }, + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = frag_shader, + .pName = "main", + }, + }; - shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT; - shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; - shader_stages[1].module = frag_shader; - shader_stages[1].pName = "main"; VkVertexInputBindingDescription bindings[1] = { { @@ -2200,13 +2201,13 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend } VkPipelineShaderStageCreateInfo shader_stages[2] = { { - .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .stage = VK_SHADER_STAGE_VERTEX_BIT, .module = vert_shader, .pName = "main", }, { - .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .stage = VK_SHADER_STAGE_FRAGMENT_BIT, .module = frag_shader, .pName = "main", @@ -2325,35 +2326,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->physical_device = physical_device; } - VkPhysicalDeviceMemoryProperties memories; - vkGetPhysicalDeviceMemoryProperties(context->physical_device, &memories); - MemoryIndices memory_indices = { - .device_local = 0xFFFFFFFF, - .host_visible = 0xFFFFFFFF, - }; - for(uint32_t i = 0; i < memories.memoryTypeCount; i++) { - VkMemoryPropertyFlags flags = memories.memoryTypes[i].propertyFlags; - - if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) - && !(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - && (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) { - memory_indices.device_lazy = i; - } else if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) - && !(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { - memory_indices.device_local = i; - } else if((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - && !(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { - memory_indices.host_visible = i; - } - } - - if(memory_indices.host_visible == 0xFFFFFFFF || memory_indices.device_local == 0xFFFFFFFF || memory_indices.device_lazy == 0xFFFFFFFF) { - fprintf(stderr, "failed to select suitable memory types\n"); - fprintf(stderr, "%d, %d, %d\n", memory_indices.device_local, memory_indices.device_lazy, memory_indices.host_visible); - return 0; - } else { - context->memory_indices = memory_indices; - } + vkGetPhysicalDeviceMemoryProperties(context->physical_device, &context->memories); VkSurfaceKHR surface; VkResult result = glfwCreateWindowSurface(instance, window, 0, &surface); @@ -2454,16 +2427,28 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->swapchain_framebuffers = framebuffers; } - VkCommandPool graphics_command_pool = create_command_pool(context->device, context->queue_indices.graphics_family); - if(graphics_command_pool == VK_NULL_HANDLE) { + VkCommandPoolCreateInfo graphics_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = context->queue_indices.graphics_family, + }; + VkCommandPool graphics_command_pool; + result = vkCreateCommandPool(context->device, &graphics_pool_info, 0, &graphics_command_pool); + if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan graphics command pool"); return 0; } else { context->graphics_command_pool = graphics_command_pool; } - VkCommandPool transfer_command_pool = create_command_pool(context->device, context->queue_indices.transfer_family); - if(transfer_command_pool == VK_NULL_HANDLE) { + VkCommandPoolCreateInfo transfer_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, + .queueFamilyIndex = context->queue_indices.transfer_family, + }; + VkCommandPool transfer_command_pool; + result = vkCreateCommandPool(context->device, &transfer_pool_info, 0, &transfer_command_pool); + if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan transfer command pool"); return 0; } else { @@ -2480,6 +2465,14 @@ 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"); @@ -2507,7 +2500,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { return context; } -SceneContext create_scene_context(VkDevice device, MemoryIndices memories, uint32_t max_frames_in_flight) { +SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryProperties memories, uint32_t max_frames_in_flight) { SceneContext ret = { .pool = VK_NULL_HANDLE, .descriptor_layout = VK_NULL_HANDLE, @@ -2577,7 +2570,7 @@ SceneContext create_scene_context(VkDevice device, MemoryIndices memories, uint3 } VkDescriptorSetAllocateInfo set_alloc_info = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorPool = pool, .descriptorSetCount = max_frames_in_flight, .pSetLayouts = layouts, @@ -2591,7 +2584,7 @@ SceneContext create_scene_context(VkDevice device, MemoryIndices memories, uint3 return ret; } - AllocatedBuffer* ubos = allocate_buffers(memories.host_visible, device, sizeof(struct SceneUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight); + AllocatedBuffer* ubos = allocate_buffers(memories, device, sizeof(struct SceneUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(ubos == 0) { free(layouts); free(sets); @@ -2940,7 +2933,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi return vkQueuePresentKHR(context->queues.present, &present_info); } -Object create_simple_mesh_object(Material* simple_mesh_material, MemoryIndices memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) { +Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) { Object zero = {}; Mesh* mesh = load_simple_mesh(memories, device, (struct Vertex*)vertices, 4, (uint16*)indices, 6, transfer_pool, transfer_queue); @@ -2995,7 +2988,7 @@ Object create_simple_mesh_object(Material* simple_mesh_material, MemoryIndices m return zero; } - AllocatedBuffer* position_buffers = allocate_buffers(memories.host_visible, device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight); + AllocatedBuffer* position_buffers = allocate_buffers(memories, device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(position_buffers == 0) { return zero; } @@ -3034,7 +3027,7 @@ Object create_simple_mesh_object(Material* simple_mesh_material, MemoryIndices m return object; } -Object create_texture_mesh_object(Material* texture_mesh_material, MemoryIndices memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) { +Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool, uint32_t transfer_family, uint32_t graphics_family) { Object zero = {}; Mesh* mesh = load_texture_mesh(memories, device, (struct TextureVertex*)texture_vertices, 4, (uint16_t*)indices, 6, transfer_pool, transfer_queue); @@ -3089,7 +3082,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, MemoryIndices return zero; } - AllocatedBuffer* ubos = allocate_buffers(memories.host_visible, device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight); + AllocatedBuffer* ubos = allocate_buffers(memories, device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, max_frames_in_flight, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(ubos == 0) { return zero; } @@ -3156,7 +3149,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, MemoryIndices RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, }; - Texture test_texture = load_texture(memories, device, transfer_pool, transfer_queue, texture_size, 4, VK_FORMAT_R8G8B8A8_SRGB, texture_data); + Texture test_texture = load_texture(memories, device, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, 4, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family); for(uint32_t i = 0; i < max_frames_in_flight; i++) { VkDescriptorImageInfo image_info = { @@ -3183,7 +3176,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, MemoryIndices } void main_loop(GLFWwindow* window, VulkanContext* context) { - SceneContext scene = create_scene_context(context->device, context->memory_indices, context->max_frames_in_flight); + SceneContext scene = create_scene_context(context->device, context->memories, context->max_frames_in_flight); if(scene.pool == VK_NULL_HANDLE) { return; } @@ -3215,7 +3208,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) { return; } - Object triangle_object = create_simple_mesh_object(&simple_mesh_material, context->memory_indices, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, simple_pool); + Object triangle_object = create_simple_mesh_object(&simple_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, simple_pool); if(triangle_object.attributes.buckets == 0) { fprintf(stderr, "failed to create simple mesh object\n"); return; @@ -3252,7 +3245,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) { return; } - Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_material, context->memory_indices, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, texture_pool); + Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->extra_graphics_pool, context->queues.graphics, context->max_frames_in_flight, texture_pool, context->queue_indices.transfer_family, context->queue_indices.graphics_family); if(triangle_object_textured.attributes.buckets == 0) { fprintf(stderr, "failed to create texture mesh object\n"); return;