Added QueueStruct for holding VkQueue + family + index

main
noah metz 2024-01-16 15:09:33 -07:00
parent 007520a92c
commit 11c135d696
3 changed files with 154 additions and 157 deletions

@ -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

@ -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);
}

@ -23,22 +23,11 @@
#include <map.h>
#include <gpu_mem.h>
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;
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;
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;
}
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;
uint32_t queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, NULL);
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;
}
}
if(idx == 0xFFFFFFFF) {
unique_families[unique_family_count] = queue_family[queue_idx];
unique_family_queues[unique_family_count] += 1;
unique_family_count += 1;
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(graphics_support && compute_support) {
transfer_queue->family = idx;
if(is_graphics_family || is_present_family) {
transfer_queue->index = 1;
} else {
unique_family_queues[idx] += 1;
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;