summaryrefslogtreecommitdiffstats
path: root/src/vksetup.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vksetup.h')
-rw-r--r--src/vksetup.h248
1 files changed, 199 insertions, 49 deletions
diff --git a/src/vksetup.h b/src/vksetup.h
index e3b8f75..273a785 100644
--- a/src/vksetup.h
+++ b/src/vksetup.h
@@ -150,6 +150,9 @@ typedef struct vks_swapchain {
VkExtent2D extent;
uint32_t image_count;
+
+ // todo: relace with vks_image although
+ // memory is managed by the swapchain
VkImage images[5];
VkImageView image_views[5]; // 5 for some reason
} vks_swapchain;
@@ -180,6 +183,15 @@ typedef struct vks_context {
vks_swapchain swapchain;
+ VkQueue graphics_and_compute_queue;
+ VkQueue present_queue;
+ VkQueue transfer_queue;
+
+ VkCommandPool command_pool;
+
+ vks_image color_image;
+ vks_image depth_image;
+
VkSampleCountFlagBits msaa_samples;
} vks_context;
@@ -197,17 +209,8 @@ typedef struct vks_frame_data {
} vks_frame_data;
/* Info structs */
-typedef struct vks_command_info
-{
- vks_context vk;
- VkCommandPool pool;
- VkQueue queue;
-} vks_command_info;
-
typedef struct vks_transition_image_layout_info
{
- /* command */
- vks_command_info cmd_info;
/* image */
VkImage image;
VkFormat format;
@@ -222,15 +225,15 @@ typedef struct vks_transition_image_layout_info
/* Exported API */
-VKSDEF void vks_create_vulkan_context (vks_context *vk, VkQueue *graphics_and_compute_queue, VkQueue *present_queue);
+VKSDEF void vks_create_vulkan_context (vks_context *vk);
VKSDEF void vks_create_buffer (const vks_context vk, const VkDeviceSize size, const VkBufferUsageFlags usage, const VkMemoryPropertyFlags properties, vks_buffer *buffer);
VKSDEF void vks_create_image (const vks_context vk, const uint32_t width, const uint32_t height, const uint32_t mipLevels, const VkFormat format, const VkImageTiling tiling, const VkImageUsageFlags usage, const VkMemoryPropertyFlags properties, const VkSampleCountFlagBits numSamples, vks_image *image);
-VKSDEF void vks_transition_image_layout (const vks_transition_image_layout_info *info);
-VKSDEF void vks_copy_buffer (const vks_command_info *cmd_info, const VkBuffer src_buffer, VkBuffer dst_buffer, const VkDeviceSize size);
-VKSDEF void vks_copy_buffer_to_image (const vks_command_info* cmd_info, const VkBuffer buffer, VkImage image, const uint32_t width, const uint32_t height);
-VKSDEF void vks_generate_mipmaps (const vks_command_info* cmd_info, VkImage image, const VkFormat imageFormat, const int32_t texWidth, const int32_t texHeight, const uint32_t mipLevels);
+VKSDEF void vks_transition_image_layout (const vks_context vk, const vks_transition_image_layout_info *info);
+VKSDEF void vks_copy_buffer (const vks_context vk, const VkBuffer src_buffer, VkBuffer dst_buffer, const VkDeviceSize size);
+VKSDEF void vks_copy_buffer_to_image (const vks_context vk, const VkBuffer buffer, VkImage image, const uint32_t width, const uint32_t height);
+VKSDEF void vks_generate_mipmaps (const vks_context vk, VkImage image, const VkFormat imageFormat, const int32_t texWidth, const int32_t texHeight, const uint32_t mipLevels);
VKSDEF VkImageView vks_create_image_view (const vks_context vk, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels);
-
+VKSDEF VkFormat findDepthFormat(const vks_context vk);
/* VKSDEF void vulkan_create_descriptor_set_layout(); */
/* VKSDEF void vulkan_create_graphics_pipeline(); */
/* VKSDEF void vulkan_create_command_pool(); */
@@ -304,17 +307,17 @@ _find_memory_type(const vks_context vk,
return 9999;
}
-static VkCommandBuffer
-_vks_begin_single_time_commands(const vks_command_info *info)
+VKSDEF VkCommandBuffer
+_vks_begin_single_time_commands(const vks_context vk)
{
VkCommandBufferAllocateInfo allocInfo = {0};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocInfo.commandPool = info->pool;
+ allocInfo.commandPool = vk.command_pool;
allocInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
- VK_CHECK(vkAllocateCommandBuffers(info->vk.device, &allocInfo, &commandBuffer));
+ VK_CHECK(vkAllocateCommandBuffers(vk.device, &allocInfo, &commandBuffer));
VkCommandBufferBeginInfo beginInfo = {0};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@@ -324,8 +327,8 @@ _vks_begin_single_time_commands(const vks_command_info *info)
return commandBuffer;
}
-static void
-_vks_end_single_time_commands(const vks_command_info *info, VkCommandBuffer command_buffer)
+VKSDEF void
+_vks_end_single_time_commands(const vks_context vk, VkCommandBuffer command_buffer)
{
VK_CHECK(vkEndCommandBuffer(command_buffer));
@@ -334,10 +337,10 @@ _vks_end_single_time_commands(const vks_command_info *info, VkCommandBuffer comm
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &command_buffer;
- VK_CHECK(vkQueueSubmit(info->queue, 1, &submitInfo, VK_NULL_HANDLE));
- VK_CHECK(vkQueueWaitIdle(info->queue));
+ VK_CHECK(vkQueueSubmit(vk.graphics_and_compute_queue, 1, &submitInfo, VK_NULL_HANDLE));
+ VK_CHECK(vkQueueWaitIdle(vk.graphics_and_compute_queue));
- vkFreeCommandBuffers(info->vk.device, info->pool, 1, &command_buffer);
+ vkFreeCommandBuffers(vk.device, vk.command_pool, 1, &command_buffer);
}
static int
@@ -501,6 +504,33 @@ _vulkan_find_queue_families(vks_context* vk, VkPhysicalDevice device)
vkGetPhysicalDeviceQueueFamilyProperties(
device, &queueFamilyCount, queueFamilies);
+ /* vk_log(VK_INFO, "Found %ld queues\n", queueFamilyCount); */
+ /* for (uint32_t i = 0; i < queueFamilyCount; i++) { */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_GRAPHICS_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_COMPUTE_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_TRANSFER_BIT) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_TRANSFER_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_SPARSE_BINDING_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_PROTECTED_BIT) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_PROTECTED_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_VIDEO_DECODE_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_VIDEO_ENCODE_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* if (queueFamilies[i].queueFlags & VK_QUEUE_OPTICAL_FLOW_BIT_NV) { */
+ /* vk_log(VK_INFO, " %d: VK_QUEUE_OPTICAL_FLOW_BIT\n", queueFamilies[i].queueFlags); */
+ /* } */
+ /* } */
for (uint32_t i = 0; i < queueFamilyCount; i++) {
if ((queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) &&
(queueFamilies[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) {
@@ -647,8 +677,7 @@ _vulkan_pick_physical_device(vks_context* vk)
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
VkExtensionProperties extensions[extensionCount];
- VkResult result =
- vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions);
+ vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions);
vk_log(VK_INFO, "Vulkan enabled extensions:\n");
for (uint32_t i = 0; i < extensionCount; i++) {
@@ -657,9 +686,7 @@ _vulkan_pick_physical_device(vks_context* vk)
}
static void
-_vulkan_create_logical_device(vks_context* vk,
- VkQueue* graphics_and_compute_queue,
- VkQueue* present_queue)
+_vulkan_create_logical_device(vks_context* vk)
{
_QueueFamilyIndices indices =
_vulkan_find_queue_families(vk, vk->physical_device);
@@ -710,8 +737,8 @@ _vulkan_create_logical_device(vks_context* vk,
vkGetDeviceQueue(vk->device,
indices.graphicsAndComputeFamily,
0,
- graphics_and_compute_queue);
- vkGetDeviceQueue(vk->device, indices.presentFamily, 0, present_queue);
+ &vk->graphics_and_compute_queue);
+ vkGetDeviceQueue(vk->device, indices.presentFamily, 0, &vk->present_queue);
}
static VkSurfaceFormatKHR
@@ -776,8 +803,6 @@ _chooseSwapExtent(const vks_context* vk,
}
}
-static void bla() {printf("blah\n");}
-
VKSDEF void
_vulkan_create_swap_chain(vks_context* vk)
{
@@ -862,12 +887,131 @@ _vulkan_create_swap_chain(vks_context* vk)
}
}
+static void
+_vulkan_create_command_pool(vks_context *vk)
+{
+ _QueueFamilyIndices queueFamilyIndices = _vulkan_find_queue_families(vk, vk->physical_device);
+
+ VkCommandPoolCreateInfo poolInfo = {0};
+ poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ // AMD doesn't like this flag for some reason
+ poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+ poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsAndComputeFamily;
+
+ VK_CHECK(vkCreateCommandPool(vk->device, &poolInfo, NULL, &vk->command_pool));
+}
+
+VkFormat
+_findSupportedFormat(const vks_context vk,
+ VkFormat* candidates,
+ size_t n,
+ VkImageTiling tiling,
+ VkFormatFeatureFlags features)
+{
+ for (size_t i = 0; i < n; i++) {
+ VkFormat format = candidates[i];
+ VkFormatProperties props;
+ vkGetPhysicalDeviceFormatProperties(vk.physical_device, format, &props);
+
+ if (tiling == VK_IMAGE_TILING_LINEAR &&
+ (props.linearTilingFeatures & features) == features) {
+ return format;
+ } else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
+ (props.optimalTilingFeatures & features) == features) {
+ return format;
+ }
+ }
+
+ vk_log(VK_ERROR, "failed to find supported format!\n");
+ abort();
+}
+
+VKSDEF VkFormat
+findDepthFormat(const vks_context vk)
+{
+ VkFormat formats[] = { VK_FORMAT_D32_SFLOAT,
+ VK_FORMAT_D32_SFLOAT_S8_UINT,
+ VK_FORMAT_D24_UNORM_S8_UINT };
+ return _findSupportedFormat(vk, formats,
+ VK_ARRAY_LEN(formats),
+ VK_IMAGE_TILING_OPTIMAL,
+ VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
+}
+
+VKSDEF void
+_vulkan_create_depth_resources(vks_context *vk)
+{
+ VkFormat depth_format = findDepthFormat(*vk);
+ vks_create_image(*vk, vk->swapchain.extent.width, vk->swapchain.extent.height, 1,
+ depth_format, VK_IMAGE_TILING_OPTIMAL,
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk->msaa_samples,
+ &vk->depth_image);
+ vk->depth_image.view = vks_create_image_view(*vk, vk->depth_image.handle, depth_format,
+ VK_IMAGE_ASPECT_DEPTH_BIT, 1);
+
+ vks_transition_image_layout_info transition_info = { 0 };
+ transition_info.image = vk->depth_image.handle;
+ transition_info.format = depth_format;
+ transition_info.srcAccessMask = VK_ACCESS_NONE;
+ transition_info.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ transition_info.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ transition_info.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
+ transition_info.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ transition_info.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ transition_info.mipLevels = 1;
+
+ //vks_transition_image_layout(*vk, &transition_info);
+}
+
+VKSDEF void
+_vulkan_create_color_resources(vks_context *vk)
+{
+ VkFormat colorFormat = vk->swapchain.image_format;
+
+ vks_create_image(*vk, vk->swapchain.extent.width, vk->swapchain.extent.height, 1,
+ colorFormat, VK_IMAGE_TILING_OPTIMAL,
+ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk->msaa_samples,
+ &vk->color_image);
+ vk->color_image.view = vks_create_image_view(*vk, vk->color_image.handle, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
+}
+
/* Vks API implementation */
VKSDEF void
-vks_create_vulkan_context(vks_context* vk,
- VkQueue* graphics_and_compute_queue,
- VkQueue* present_queue)
+vks_cleanup_swapchain(const vks_context vk)
+{
+ vkDestroyImageView(vk.device, vk.color_image.view, NULL);
+ vkDestroyImage(vk.device, vk.color_image.handle, NULL);
+ vkFreeMemory(vk.device, vk.color_image.memory, NULL);
+
+ vkDestroyImageView(vk.device, vk.depth_image.view, NULL);
+ vkDestroyImage(vk.device, vk.depth_image.handle, NULL);
+ vkFreeMemory(vk.device, vk.depth_image.memory, NULL);
+
+ for (uint32_t i = 0; i < vk.swapchain.image_count; i++) {
+ vkDestroyImageView(vk.device, vk.swapchain.image_views[i], NULL);
+ }
+ vkDestroySwapchainKHR(vk.device, vk.swapchain.handle, NULL);
+}
+
+VKSDEF void
+vks_recreate_swapchain(vks_context* vk)
+{
+ vkDeviceWaitIdle(vk->device);
+
+ vks_cleanup_swapchain(*vk);
+
+ _vulkan_create_swap_chain(vk);
+ _vulkan_create_color_resources(vk);
+ _vulkan_create_depth_resources(vk);
+}
+
+VKSDEF void
+vks_create_vulkan_context(vks_context* vk)
{
/* Create vulkan instance */
vk->instance = _vks_create_instance(enable_validation_layers,
@@ -888,11 +1032,17 @@ vks_create_vulkan_context(vks_context* vk,
/* Create logical device and get queues */
/* TODO: Create vks_get_queue helpers?? */
- _vulkan_create_logical_device(vk, graphics_and_compute_queue, present_queue);
+ _vulkan_create_logical_device(vk);
+
+ _vulkan_create_command_pool(vk);
/* Create swapchain */
/* TODO: Make swapchain api */
_vulkan_create_swap_chain(vk);
+
+ /* Create resources */
+ _vulkan_create_color_resources(vk);
+ _vulkan_create_depth_resources(vk);
}
VKSDEF VkImageView
@@ -920,14 +1070,14 @@ vks_create_image_view(const vks_context vk,
}
VKSDEF void
-vks_generate_mipmaps(const vks_command_info* cmd_info,
+vks_generate_mipmaps(const vks_context vk,
VkImage image,
const VkFormat imageFormat,
const int32_t texWidth,
const int32_t texHeight,
const uint32_t mipLevels)
{
- VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info);
+ VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk);
VkImageMemoryBarrier barrier = { 0 };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -1007,17 +1157,17 @@ vks_generate_mipmaps(const vks_command_info* cmd_info,
mipHeight /= 2;
}
- _vks_end_single_time_commands(cmd_info, command_buffer);
+ _vks_end_single_time_commands(vk, command_buffer);
}
VKSDEF void
-vks_copy_buffer_to_image(const vks_command_info* cmd_info,
+vks_copy_buffer_to_image(const vks_context vk,
const VkBuffer buffer,
VkImage image,
const uint32_t width,
const uint32_t height)
{
- VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info);
+ VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk);
VkBufferImageCopy region = { 0 };
region.bufferOffset = 0;
@@ -1039,16 +1189,16 @@ vks_copy_buffer_to_image(const vks_command_info* cmd_info,
1,
&region);
- _vks_end_single_time_commands(cmd_info, command_buffer);
+ _vks_end_single_time_commands(vk, command_buffer);
}
VKSDEF void
-vks_copy_buffer(const vks_command_info* cmd_info,
+vks_copy_buffer(const vks_context vk,
const VkBuffer src_buffer,
VkBuffer dst_buffer,
const VkDeviceSize size)
{
- VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info);
+ VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk);
VkBufferCopy copy_region = { 0 };
copy_region.srcOffset = 0; // Optional
@@ -1056,13 +1206,13 @@ vks_copy_buffer(const vks_command_info* cmd_info,
copy_region.size = size;
vkCmdCopyBuffer(command_buffer, src_buffer, dst_buffer, 1, &copy_region);
- _vks_end_single_time_commands(cmd_info, command_buffer);
+ _vks_end_single_time_commands(vk, command_buffer);
}
VKSDEF void
-vks_transition_image_layout(const vks_transition_image_layout_info* info)
+vks_transition_image_layout(const vks_context vk, const vks_transition_image_layout_info* info)
{
- VkCommandBuffer command_buffer = _vks_begin_single_time_commands(&info->cmd_info);
+ VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk);
VkImageMemoryBarrier barrier = { 0 };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -1101,7 +1251,7 @@ vks_transition_image_layout(const vks_transition_image_layout_info* info)
1,
&barrier);
- _vks_end_single_time_commands(&info->cmd_info, command_buffer);
+ _vks_end_single_time_commands(vk, command_buffer);
}
VKSDEF void