From 11c135d696967d3b84a93f21bdf9cce1ba914df5 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Tue, 16 Jan 2024 15:09:33 -0700 Subject: [PATCH] Added QueueStruct for holding VkQueue + family + index --- Makefile | 2 +- shader_src/texture.frag | 4 +- src/main.c | 305 ++++++++++++++++++++-------------------- 3 files changed, 154 insertions(+), 157 deletions(-) diff --git a/Makefile b/Makefile index e4a2443..b00b7f0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) CFLAGS = -fsanitize=address -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra -LDFLAGS = -L/opt/homebrew/opt/llvm/lib -L/usr/local/lib -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /usr/local/lib -Xlinker -rpath -Xlinker /opt/homebrew/opt/llvm/lib -Xpreprocessor -fooenmp +LDFLAGS = -L/opt/homebrew/opt/llvm/lib -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/opt/llvm/lib -Xpreprocessor -fooenmp CC = /opt/homebrew/opt/llvm/bin/clang GDB = lldb diff --git a/shader_src/texture.frag b/shader_src/texture.frag index 43b4014..1d6f919 100644 --- a/shader_src/texture.frag +++ b/shader_src/texture.frag @@ -4,8 +4,8 @@ layout(location = 0) in vec3 fragColor; layout(location = 1) in vec2 fragTex; layout(location = 0) out vec4 outColor; -layout(set = 1, binding = 0) uniform sampler2D texSampler; +layout(set = 1, binding = 0) uniform sampler2D texSamplers[1000]; void main() { - outColor = texture(texSampler, fragTex); + outColor = texture(texSamplers[1], fragTex); } diff --git a/src/main.c b/src/main.c index 1ca5777..109444d 100644 --- a/src/main.c +++ b/src/main.c @@ -23,22 +23,11 @@ #include #include -typedef struct QueueIndicesStruct { - uint32_t graphics_family; - uint32_t graphics_index; - - uint32_t present_family; - uint32_t present_index; - - uint32_t transfer_family; - uint32_t transfer_index; -} QueueIndices; - -typedef struct QueuesStruct { - VkQueue graphics; - VkQueue present; - VkQueue transfer; -} Queues; +typedef struct QueueStruct { + VkQueue handle; + uint32_t family; + uint32_t index; +} Queue; typedef struct SwapchainDetailsStruct { VkSurfaceCapabilitiesKHR capabilities; @@ -133,9 +122,11 @@ typedef struct VulkanContextStruct { VkDebugUtilsMessengerEXT debug_messenger; VkPhysicalDevice physical_device; - QueueIndices queue_indices; VkDevice device; - Queues queues; + + Queue graphics_queue; + Queue transfer_queue; + Queue present_queue; // G Buffer GPUPage* g_buffer_page; @@ -451,60 +442,6 @@ VkResult get_best_physical_device(VkInstance instance, VkPhysicalDevice* device) return VK_SUCCESS; } -bool check_queue_indices(QueueIndices indices) { - return ((indices.graphics_family != 0xFFFFFFFF) - && (indices.present_family != 0xFFFFFFFF) - && (indices.transfer_family != 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); - - VkQueueFamilyProperties* queue_families = malloc(sizeof(VkQueueFamilyProperties)*queue_family_count); - - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, queue_families); - - for(uint32_t family_idx = 0; family_idx < queue_family_count; family_idx++) { - 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)) - && (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->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) - && (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) - && (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; - } - } - } - - free(queue_families); - return VK_SUCCESS; -} - VkResult create_debug_messenger(VkInstance instance, VkDebugUtilsMessengerEXT* debug_messenger) { VkDebugUtilsMessengerCreateInfoEXT messenger_info = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, @@ -581,42 +518,80 @@ VkResult create_instance(VkInstance* instance) { return VK_SUCCESS; } -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; +VkResult create_logical_device(VkPhysicalDevice physical_device, VkSurfaceKHR surface, Queue* graphics_queue, Queue* present_queue, Queue* transfer_queue, VkDevice* device) { + if(graphics_queue == NULL || present_queue == NULL || transfer_queue == NULL || device == NULL) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + + uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, NULL); - uint32_t queue_family[] = {queue_indices.transfer_family, queue_indices.graphics_family, queue_indices.present_family}; - uint32_t unique_queue_count = 3; - if((queue_indices.graphics_family == queue_indices.present_family) - && (queue_indices.graphics_index == queue_indices.present_index)) { - unique_queue_count = 2; + VkQueueFamilyProperties* queue_families = malloc(sizeof(VkQueueFamilyProperties)*queue_family_count); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, queue_families); + + graphics_queue->family = 0xFFFFFFFF; + present_queue->family = 0xFFFFFFFF; + for(uint32_t idx = 0; idx < queue_family_count; idx++) { + VkBool32 present_support = VK_FALSE; + vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, idx, surface, &present_support); + VkBool32 graphics_support = (queue_families[idx].queueFlags & VK_QUEUE_GRAPHICS_BIT); + + if(graphics_support && present_support) { + graphics_queue->family = idx; + graphics_queue->index = 0; + + present_queue->family = idx; + present_queue->index = 0; + break; + } else if (graphics_support && (graphics_queue->family == 0xFFFFFFFF)) { + graphics_queue->family = idx; + graphics_queue->index = 0; + } else if (present_support && (present_queue->family == 0xFFFFFFFF)) { + graphics_queue->family = idx; + present_queue->index = 0; + } } - for(uint32_t queue_idx = 0; queue_idx < unique_queue_count; queue_idx++) { - uint32_t idx = 0xFFFFFFFF; - for(uint32_t check_idx = 0; check_idx < unique_family_count; check_idx++) { - if(queue_family[queue_idx] == unique_families[check_idx]) { - idx = check_idx; - break; - } + transfer_queue->family = 0xFFFFFFFF; + for(uint32_t idx = 0; idx < queue_family_count; idx++) { + VkBool32 graphics_support = (queue_families[idx].queueFlags & VK_QUEUE_GRAPHICS_BIT); + VkBool32 compute_support = (queue_families[idx].queueFlags & VK_QUEUE_COMPUTE_BIT); + VkBool32 is_graphics_family = (graphics_queue->family == idx); + VkBool32 is_present_family = (present_queue->family == idx); + uint32_t queue_count = queue_families[idx].queueCount; + + if(is_graphics_family && (queue_count == 1)) { + continue; + } else if (is_present_family && (queue_count == 1)) { + continue; } - if(idx == 0xFFFFFFFF) { - unique_families[unique_family_count] = queue_family[queue_idx]; - unique_family_queues[unique_family_count] += 1; - unique_family_count += 1; - } else { - unique_family_queues[idx] += 1; + if(graphics_support && compute_support) { + transfer_queue->family = idx; + if(is_graphics_family || is_present_family) { + transfer_queue->index = 1; + } else { + transfer_queue->index = 0; + } } } + if(graphics_queue->family == 0xFFFFFFFF || present_queue->family == 0xFFFFFFFF || transfer_queue->family == 0xFFFFFFFF) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + uint32_t family_indices[] = { + transfer_queue->family, + graphics_queue->family, + present_queue->family, + }; + VkDeviceQueueCreateInfo queue_create_info[3] = {}; float default_queue_priority = 1.0f; - for(uint32_t i = 0; i < unique_family_count; i++) { + for(uint32_t i = 0; i < 3; i++) { queue_create_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_create_info[i].queueFamilyIndex = unique_families[i]; - queue_create_info[i].queueCount = unique_family_queues[i]; + queue_create_info[i].queueFamilyIndex = family_indices[i]; + queue_create_info[i].queueCount = 1; queue_create_info[i].pQueuePriorities = &default_queue_priority; } @@ -638,7 +613,7 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu VkDeviceCreateInfo device_create_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pQueueCreateInfos = queue_create_info, - .queueCreateInfoCount = unique_family_count, + .queueCreateInfoCount = 3, .pEnabledFeatures = &device_features, .enabledExtensionCount = device_extension_count, .ppEnabledExtensionNames = device_extensions, @@ -652,6 +627,10 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu return result; } + vkGetDeviceQueue(*device, graphics_queue->family, graphics_queue->index, &graphics_queue->handle); + vkGetDeviceQueue(*device, present_queue->family, present_queue->index, &present_queue->handle); + vkGetDeviceQueue(*device, transfer_queue->family, transfer_queue->index, &transfer_queue->handle); + return VK_SUCCESS; } @@ -717,7 +696,7 @@ VkExtent2D choose_swapchain_extent(SwapchainDetails swapchain_details) { return swapchain_details.capabilities.currentExtent; } -VkSwapchainKHR create_swapchain(VkDevice device, VkSurfaceFormatKHR format, VkPresentModeKHR present_mode, VkExtent2D extent, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR capabilities, QueueIndices indices, VkSwapchainKHR old_swapchain) { +VkSwapchainKHR create_swapchain(VkDevice device, VkSurfaceFormatKHR format, VkPresentModeKHR present_mode, VkExtent2D extent, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR capabilities, uint32_t graphics_family_index, uint32_t present_family_index, VkSwapchainKHR old_swapchain) { uint32_t image_count = capabilities.minImageCount + 1; uint32_t max_images = capabilities.maxImageCount; if((max_images > 0) && (image_count > max_images)) { @@ -740,8 +719,8 @@ VkSwapchainKHR create_swapchain(VkDevice device, VkSurfaceFormatKHR format, VkPr .oldSwapchain = old_swapchain, }; - uint32_t queue_families[2] = {indices.graphics_family, indices.present_index}; - if(indices.graphics_family != indices.present_family) { + uint32_t queue_families[2] = {graphics_family_index, present_family_index}; + if(graphics_family_index != present_family_index) { swapchain_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; swapchain_info.queueFamilyIndexCount = 2; swapchain_info.pQueueFamilyIndices = queue_families; @@ -1013,7 +992,7 @@ VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_poo return command_buffer; } -VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, VkQueue transfer_queue) { +VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue) { VkResult result = vkEndCommandBuffer(command_buffer); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); @@ -1026,18 +1005,18 @@ VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkC .pCommandBuffers = &command_buffer, }; - result = vkQueueSubmit(transfer_queue, 1, &submit_info, 0); + result = vkQueueSubmit(transfer_queue.handle, 1, &submit_info, 0); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; } - result = vkQueueWaitIdle(transfer_queue); + result = vkQueueWaitIdle(transfer_queue.handle); vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; } -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) { +VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue 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 = { @@ -1062,7 +1041,7 @@ VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkExtent3D image_size, VkBuffer source, VkImage dest) { +VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkExtent3D image_size, VkBuffer source, VkImage dest) { VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); VkBufferImageCopy region = { @@ -1088,7 +1067,7 @@ VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_po return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family){ +Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, Queue transfer_queue, VkCommandPool graphics_pool, Queue graphics_queue, VkExtent2D size, VkFormat format, void* image_data){ Texture ret = { .image.page = NULL, .image.memory = NULL, @@ -1125,7 +1104,7 @@ Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkComman memcpy(staging.page->ptr + staging.memory->offset, image_data, image.memory->size); - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.handle, 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); + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.handle, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_queue.family, transfer_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { gpu_image_free(device, image); return ret; @@ -1137,13 +1116,13 @@ Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkComman 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.handle, 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); + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { gpu_image_free(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.handle, 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); + result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { gpu_image_free(device, image); return ret; @@ -1293,7 +1272,7 @@ 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, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, VK_IMAGE_ASPECT_DEPTH_BIT); + result = command_transition_image_layout(context->device, context->extra_graphics_pool, context->graphics_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, context->depth_image, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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; @@ -1332,7 +1311,7 @@ VkResult recreate_swapchain(VulkanContext* context) { create_depth_image(context); - VkSwapchainKHR swapchain = create_swapchain(context->device, context->swapchain_format, context->swapchain_present_mode, context->swapchain_extent, context->surface, context->swapchain_details.capabilities, context->queue_indices, context->swapchain); + VkSwapchainKHR swapchain = create_swapchain(context->device, context->swapchain_format, context->swapchain_present_mode, context->swapchain_extent, context->surface, context->swapchain_details.capabilities, context->graphics_queue.family, context->present_queue.family, context->swapchain); if(swapchain == VK_NULL_HANDLE) { context->swapchain = VK_NULL_HANDLE; return VK_ERROR_INITIALIZATION_FAILED; @@ -1604,12 +1583,17 @@ Object create_renderable(Mesh* mesh, GraphicsPipeline* pipeline) { typedef struct TextureSetStruct { uint32_t max_images; - GPUImage** images; + Texture* textures; VkDescriptorSet descriptor; VkDescriptorPool pool; } TextureSet; +// TODO +/*VkResult texture_set_add(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family) { + return VK_SUCCESS; +}*/ + VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint32_t max_images, TextureSet* out) { if(out == NULL) { return VK_ERROR_VALIDATION_FAILED_EXT; @@ -1617,8 +1601,8 @@ VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint3 out->max_images = max_images; - out->images = malloc(sizeof(GPUImage*)*max_images); - if(out->images == NULL) { + out->textures = malloc(sizeof(Texture*)*max_images); + if(out->textures == NULL) { return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -1640,7 +1624,7 @@ VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint3 VkResult result = vkCreateDescriptorPool(device, &pool_info, 0, &out->pool); if(result != VK_SUCCESS) { - free(out->images); + free(out->textures); return result; }; @@ -1658,7 +1642,7 @@ VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint3 result = vkAllocateDescriptorSets(device, &set_info, &out->descriptor); if(result != VK_SUCCESS) { - free(out->images); + free(out->textures); vkDestroyDescriptorPool(device, out->pool, 0); return result; } @@ -1955,7 +1939,7 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRende return create_graphics_pipeline(device, extent, render_pass, offscreen_render_pass, pipeline_info, max_frames_in_flight, out); } -VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkRenderPass offscreen_render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, VkCommandPool transfer_pool, VkQueue transfer_queue, VkQueue graphics_queue, VkCommandPool graphics_pool, uint32_t transfer_family, uint32_t graphics_family, GraphicsPipeline* out) { +VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkRenderPass offscreen_render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, VkCommandPool transfer_pool, Queue transfer_queue, Queue graphics_queue, VkCommandPool graphics_pool, GraphicsPipeline* out) { if(out == NULL) { return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -2094,7 +2078,7 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro struct texel GRN = {0, 255, 0, 255}; struct texel BLU = {0, 0, 255, 255}; - struct texel texture_data[100] = { + struct texel texture_data_0[100] = { RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, @@ -2106,7 +2090,19 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, }; - (void)texture_data; + + struct texel texture_data_1[100] = { + RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, + RED, WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, RED, + RED, WHT, GRN, GRN, GRN, GRN, GRN, GRN, WHT, RED, + RED, WHT, GRN, BLU, BLU, BLU, BLU, GRN, WHT, RED, + RED, WHT, GRN, BLU, BLK, BLK, BLU, GRN, WHT, RED, + RED, WHT, GRN, BLU, BLK, BLK, BLU, GRN, WHT, RED, + RED, WHT, GRN, BLU, BLU, BLU, BLU, GRN, WHT, RED, + RED, WHT, GRN, GRN, GRN, GRN, GRN, GRN, WHT, RED, + RED, WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, RED, + RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, + }; GPUPage* texture_memory = NULL; result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0, &texture_memory); @@ -2126,13 +2122,19 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro return result; } - Texture test_texture = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family); + Texture test_texture_0 = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_0); + + Texture test_texture_1 = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_1); - texture_set.images[0] = &test_texture.image; + VkDescriptorImageInfo image_info_0 = { + .sampler = test_texture_0.sampler, + .imageView = test_texture_0.view, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; - VkDescriptorImageInfo image_info = { - .sampler = test_texture.sampler, - .imageView = test_texture.view, + VkDescriptorImageInfo image_info_1 = { + .sampler = test_texture_1.sampler, + .imageView = test_texture_1.view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; @@ -2140,24 +2142,29 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstSet = texture_set.descriptor, .dstBinding = 0, - .dstArrayElement = 0, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 1, .pBufferInfo = 0, - .pImageInfo = &image_info, .pTexelBufferView = 0, }; + + descriptor_write.pImageInfo = &image_info_0; + descriptor_write.dstArrayElement = 0; + vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); + + descriptor_write.pImageInfo = &image_info_1; + descriptor_write.dstArrayElement = 1; vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); for(uint32_t i = 0; i < out->max_frames_in_flight; i++) { - fprintf(stderr, "descriptor[%d]: %p\n", i, out->descriptors[i]); out->descriptors[i] = texture_set.descriptor; + fprintf(stderr, "descriptor[%d]: %p\n", i, out->descriptors[i]); } return VK_SUCCESS; } -VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) { +VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, Queue queue) { memcpy(staging.page->ptr + staging.memory->offset, data, size); VkCommandBuffer command_buffer = command_begin_single(device, pool); @@ -2176,7 +2183,7 @@ VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer des return command_end_single(device, command_buffer, pool, queue); } -Mesh* load_mesh_to_buffer(VkDevice device, GPUPage* page, GPUBuffer staging, uint32_t vertex_count, uint32_t vertex_stride, void* vertex_data, uint32_t index_count, uint32_t index_stride, void* index_data, VkCommandPool pool, VkQueue queue) { +Mesh* load_mesh_to_buffer(VkDevice device, GPUPage* page, GPUBuffer staging, uint32_t vertex_count, uint32_t vertex_stride, void* vertex_data, uint32_t index_count, uint32_t index_stride, void* index_data, VkCommandPool pool, Queue queue) { GPUBuffer vertex_buffer = {0}; GPUBuffer index_buffer = {0}; @@ -2246,22 +2253,12 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { return 0; } - 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; - } - - result = create_logical_device(context->physical_device, context->queue_indices, &context->device); + result = create_logical_device(context->physical_device, context->surface, &context->graphics_queue, &context->present_queue, &context->transfer_queue, &context->device); if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan logical device\n"); return 0; } - 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); - result = get_swapchain_details(context->physical_device, context->surface, &context->swapchain_details); if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan logical device\n"); @@ -2272,7 +2269,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->swapchain_present_mode = choose_present_mode(context->swapchain_details); context->swapchain_extent = choose_swapchain_extent(context->swapchain_details); - VkSwapchainKHR swapchain = create_swapchain(context->device, context->swapchain_format, context->swapchain_present_mode, context->swapchain_extent, context->surface, context->swapchain_details.capabilities, context->queue_indices, VK_NULL_HANDLE); + VkSwapchainKHR swapchain = create_swapchain(context->device, context->swapchain_format, context->swapchain_present_mode, context->swapchain_extent, context->surface, context->swapchain_details.capabilities, context->graphics_queue.family, context->present_queue.family, VK_NULL_HANDLE); if(swapchain == VK_NULL_HANDLE) { fprintf(stderr, "failed to create vulkan swapchain\n"); return 0; @@ -2312,7 +2309,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { VkCommandPoolCreateInfo extra_pool_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .queueFamilyIndex = context->queue_indices.graphics_family, + .queueFamilyIndex = context->graphics_queue.family, .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, }; @@ -2346,7 +2343,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { 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, + .queueFamilyIndex = context->graphics_queue.family, }; VkCommandPool graphics_command_pool; result = vkCreateCommandPool(context->device, &graphics_pool_info, 0, &graphics_command_pool); @@ -2360,7 +2357,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { 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, + .queueFamilyIndex = context->transfer_queue.family, }; VkCommandPool transfer_command_pool; result = vkCreateCommandPool(context->device, &transfer_pool_info, 0, &transfer_command_pool); @@ -2517,7 +2514,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { return 0; } - 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->g_image_depth.handle, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, VK_IMAGE_ASPECT_DEPTH_BIT); + result = command_transition_image_layout(context->device, context->extra_graphics_pool, context->graphics_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, context->g_image_depth.handle, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, VK_IMAGE_ASPECT_DEPTH_BIT); if(result != VK_SUCCESS) { fprintf(stderr, "Failed to transition g_image_depth to VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL\n"); return 0; @@ -3058,12 +3055,12 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t pipeli .pSignalSemaphores = &context->render_finished_semaphores[context->current_frame], }; - result = vkQueueSubmit(context->queues.graphics, 1, &offscreen_submit_info, 0); + result = vkQueueSubmit(context->graphics_queue.handle, 1, &offscreen_submit_info, 0); if(result != VK_SUCCESS) { return result; } - result = vkQueueSubmit(context->queues.graphics, 1, &submit_info, context->in_flight_fences[context->current_frame]); + result = vkQueueSubmit(context->graphics_queue.handle, 1, &submit_info, context->in_flight_fences[context->current_frame]); if(result != VK_SUCCESS) { return result; } @@ -3078,10 +3075,10 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t pipeli .pResults = 0, }; - return vkQueuePresentKHR(context->queues.present, &present_info); + return vkQueuePresentKHR(context->present_queue.handle, &present_info); } -Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue) { Object zero = {}; GPUPage* mesh_memory = NULL; @@ -3142,7 +3139,7 @@ Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh return object; } -Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue) { Object zero = {}; GPUPage* mesh_memory = NULL; @@ -3206,19 +3203,19 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) { return; } - Object triangle_object = create_simple_mesh_object(ply_mesh, &simple_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->queues.transfer); + Object triangle_object = create_simple_mesh_object(ply_mesh, &simple_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->transfer_queue); if(triangle_object.attributes.buckets == 0) { fprintf(stderr, "failed to create simple mesh object\n"); return; } - result = create_texture_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, context->g_renderpass, scene.descriptor_layout, context->max_frames_in_flight, context->transfer_command_pool, context->queues.transfer, context->queues.graphics, context->extra_graphics_pool, context->queue_indices.transfer_family, context->queue_indices.graphics_index, &texture_mesh_pipeline); + result = create_texture_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, context->g_renderpass, scene.descriptor_layout, context->max_frames_in_flight, context->transfer_command_pool, context->transfer_queue, context->graphics_queue, context->extra_graphics_pool, &texture_mesh_pipeline); if(result != VK_SUCCESS) { fprintf(stderr, "failed to create texture mesh material\n"); return; } - Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->queues.transfer); + Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->transfer_queue); if(triangle_object_textured.attributes.buckets == 0) { fprintf(stderr, "failed to create texture mesh object\n"); return;