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