diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-05-05 00:43:54 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-05-05 00:49:12 +0200 |
| commit | c3aac9026951e2a6e35e76b9c7d36e114a281453 (patch) | |
| tree | bdfc2ab5d5f1d196ba8c7a76371a29911f75913e /src/vk-api.cpp | |
| parent | 754249d9c652ef941e6b082d2e86538d15ba9434 (diff) | |
Remove old api and move api-test content to src and include dirs
Diffstat (limited to 'src/vk-api.cpp')
| -rw-r--r-- | src/vk-api.cpp | 1257 |
1 files changed, 0 insertions, 1257 deletions
diff --git a/src/vk-api.cpp b/src/vk-api.cpp deleted file mode 100644 index 2040b44..0000000 --- a/src/vk-api.cpp +++ /dev/null @@ -1,1257 +0,0 @@ -#include "vk-api.hpp" - -#include <cassert> -#include <filesystem> - -#include <vk_mem_alloc.h> - -#include "utils.hpp" -#include "vk-context.hpp" -#include "window.hpp" - -#include "vulkan-loader.hpp" - -#ifdef _DEBUG -#define VKRESULT(result) assert(result == VK_SUCCESS); -#else -#define VKRESULT(result) result; -#endif - - -vkapi::vkapi(vkcontext& context) - : context(context) { - VkDescriptorPoolSize descriptor_pools_sizes[] = { - { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = (uint32_t)global_descriptor::pool_size, - }, - { - .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = (uint32_t)global_descriptor::pool_size, - }, - { - .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = (uint32_t)global_descriptor::pool_size, - }, - { - .type = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = (uint32_t)global_descriptor::pool_size, - } - }; - - VkDescriptorPoolCreateInfo descriptor_pool_create_info = {}; - descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptor_pool_create_info.pNext = nullptr; - descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - descriptor_pool_create_info.maxSets = 0xff; - descriptor_pool_create_info.poolSizeCount = sizeof(descriptor_pools_sizes) / sizeof(descriptor_pools_sizes[0]); - descriptor_pool_create_info.pPoolSizes = descriptor_pools_sizes; - - VKRESULT(vkCreateDescriptorPool(context.device, &descriptor_pool_create_info, nullptr, &descriptor_pool)) - - // Global descriptor - VkDescriptorSetLayoutBinding bindless_layout_bindings[] = { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = global_descriptor::pool_size, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = global_descriptor::pool_size, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = 2, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .descriptorCount = global_descriptor::pool_size, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - }; - - VkDescriptorBindingFlags flags[3] = { - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, - }; - - VkDescriptorSetLayoutBindingFlagsCreateInfo descriptor_set_layout_binding_flags = {}; - descriptor_set_layout_binding_flags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; - descriptor_set_layout_binding_flags.pNext = VK_NULL_HANDLE; - descriptor_set_layout_binding_flags.bindingCount = sizeof(flags) / sizeof(VkDescriptorBindingFlags); - descriptor_set_layout_binding_flags.pBindingFlags = flags; - - VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info = {}; - descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptor_set_layout_create_info.pNext = &descriptor_set_layout_binding_flags; - descriptor_set_layout_create_info.flags = 0; - descriptor_set_layout_create_info.bindingCount = sizeof(bindless_layout_bindings) / sizeof(VkDescriptorSetLayoutBinding); - descriptor_set_layout_create_info.pBindings = bindless_layout_bindings; - - VKRESULT(vkCreateDescriptorSetLayout(context.device, &descriptor_set_layout_create_info, nullptr, &bindless_descriptor.set_layout)) - - - VkPushConstantRange push_constants[] = { - { - .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, - .offset = 0, - .size = 64, - }, - { - .stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS, - .offset = 64, - .size = 64, - }, - // { - // .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - // .offset = 64, - // .size = 32, - // }, - // { - // .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - // .offset = 96, - // .size = 32, - // }, - }; - - VkPipelineLayoutCreateInfo layout_create_info = {}; - layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - layout_create_info.pNext = nullptr; - layout_create_info.flags = 0; - layout_create_info.setLayoutCount = 1; - layout_create_info.pSetLayouts = &bindless_descriptor.set_layout; - layout_create_info.pushConstantRangeCount = sizeof(push_constants) / sizeof(VkPushConstantRange); - layout_create_info.pPushConstantRanges = push_constants; - - VKRESULT(vkCreatePipelineLayout(context.device, &layout_create_info, nullptr, &bindless_descriptor.pipeline_layout)) - - - VkDescriptorSetAllocateInfo descriptor_set_allocate_info = {}; - descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - descriptor_set_allocate_info.pNext = VK_NULL_HANDLE; - descriptor_set_allocate_info.descriptorPool = descriptor_pool; - descriptor_set_allocate_info.descriptorSetCount = 1; - descriptor_set_allocate_info.pSetLayouts = &bindless_descriptor.set_layout; - - vkAllocateDescriptorSets(context.device, &descriptor_set_allocate_info, &bindless_descriptor.set); -} - -vkapi::~vkapi() { - // Free resources - for (handle buffer_handle = 0; buffer_handle < buffers.size(); buffer_handle++) { - destroy_buffer(buffer_handle); - } - - for (handle image_handle = 0; image_handle < images.size(); image_handle++) { - destroy_image(image_handle); - } - - for (handle sampler_handle = 0; sampler_handle < samplers.size(); sampler_handle++) { - destroy_sampler(sampler_handle); - } - - // Free bindless descriptor stuff - vkDestroyDescriptorSetLayout(context.device, bindless_descriptor.set_layout, nullptr); - vkDestroyPipelineLayout(context.device, bindless_descriptor.pipeline_layout, nullptr); - vkFreeDescriptorSets(context.device, descriptor_pool, 1, &bindless_descriptor.set); - - vkDestroyDescriptorPool(context.device, descriptor_pool, nullptr); -} - -handle vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, uint32_t mem_usage) { - auto* buffer = new struct buffer(); - - VkBufferCreateInfo buffer_info = {}; - buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buffer_info.size = data_size; - buffer_info.usage = buffer_usage | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR; - - VmaAllocationCreateInfo alloc_create_info = {}; - alloc_create_info.usage = (VmaMemoryUsage)mem_usage; - alloc_create_info.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - - VmaAllocationInfo alloc_info{}; - - VKRESULT(vmaCreateBuffer(context.allocator, &buffer_info, &alloc_create_info, &buffer->handle, &buffer->alloc, &alloc_info)) - - VkBufferDeviceAddressInfo buffer_device_address_info = {}; - buffer_device_address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; - buffer_device_address_info.pNext = VK_NULL_HANDLE; - buffer_device_address_info.buffer = buffer->handle; - - buffer->size = data_size; - - buffer->device_address = vkGetBufferDeviceAddress(context.device, &buffer_device_address_info); - buffer->device_ptr = alloc_info.pMappedData; - - buffers.push_back(buffer); - - return buffers.size() - 1; -} - -void vkapi::copy_buffer(VkCommandBuffer cmd_buf, handle src, handle dst, size_t size) { - VkBufferCopy buffer_copy = {}; - buffer_copy.srcOffset = 0; - buffer_copy.dstOffset = 0; - buffer_copy.size = size; - - vkCmdCopyBuffer(cmd_buf, buffers[src]->handle, buffers[dst]->handle, 1, &buffer_copy); -} - -// TODO: Change handle type, here we don't know what type of ressources we are working with -void vkapi::copy_buffer(VkCommandBuffer cmd_buf, handle src, handle dst, size_t size, size_t buffer_offset) { - auto& dst_image = images[dst]; - - VkImageSubresourceLayers image_subresource_layers = {}; - image_subresource_layers.aspectMask = dst_image->subresource_range.aspectMask; - image_subresource_layers.mipLevel = 0; - image_subresource_layers.baseArrayLayer = 0; - image_subresource_layers.layerCount = 1; - - VkBufferImageCopy buffer_to_image_copy = {}; - buffer_to_image_copy.bufferOffset = buffer_offset; - buffer_to_image_copy.bufferRowLength = 0; - buffer_to_image_copy.bufferImageHeight = 0; - buffer_to_image_copy.imageSubresource = image_subresource_layers; - buffer_to_image_copy.imageOffset = { 0, 0, 0 }; - buffer_to_image_copy.imageExtent = dst_image->size; - - vkCmdCopyBufferToImage(cmd_buf, buffers[src]->handle, dst_image->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffer_to_image_copy); -} - -void vkapi::destroy_buffer(handle buffer) { - vmaDestroyBuffer(context.allocator, buffers[buffer]->handle, buffers[buffer]->alloc); - - // TODO: Free the element once using freelists - // buffers.erase(buffer.handle); -} - -handle vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages) { - auto* image = new struct image(); - - image->size = size; - - image->subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image->subresource_range.baseMipLevel = 0; - image->subresource_range.levelCount = 1; - image->subresource_range.baseArrayLayer = 0; - image->subresource_range.layerCount = 1; - - VkImageCreateInfo img_create_info = {}; - img_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - img_create_info.pNext = VK_NULL_HANDLE; - img_create_info.flags = 0; - img_create_info.imageType = VK_IMAGE_TYPE_2D; - img_create_info.format = format; - img_create_info.extent = size; - img_create_info.mipLevels = 1; - img_create_info.arrayLayers = 1; - img_create_info.samples = VK_SAMPLE_COUNT_1_BIT; - img_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; - img_create_info.usage = usages; - img_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - img_create_info.queueFamilyIndexCount = 0; - img_create_info.pQueueFamilyIndices = nullptr; - img_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - VmaAllocationCreateInfo alloc_create_info = {}; - alloc_create_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; - - VmaAllocationInfo alloc_info{}; - - VKRESULT(vmaCreateImage(context.allocator, &img_create_info, &alloc_create_info, &image->handle, &image->alloc, &alloc_info)) - - VkImageViewCreateInfo image_view_create_info = {}; - image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - image_view_create_info.pNext = nullptr; - image_view_create_info.flags = 0; - image_view_create_info.image = image->handle; - image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - image_view_create_info.format = format; - image_view_create_info.components = { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY - }; - image_view_create_info.subresourceRange = image->subresource_range; - - VKRESULT(vkCreateImageView(context.device, &image_view_create_info, VK_NULL_HANDLE, &image->view)) - - image->format = format; - image->usages = usages; - - images.push_back(image); - - auto image_handle = images.size() - 1; - - if ((usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0U) { - image->bindless_storage_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - update_descriptor_image(image_handle, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - } - - if ((usages & VK_IMAGE_USAGE_SAMPLED_BIT) != 0U) { - image->bindless_sampled_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - update_descriptor_image(image_handle, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - } - - return image_handle; -} - -void vkapi::destroy_image(handle image) { - auto* current_image = images[image]; - - if (current_image->bindless_storage_index != 0U) { - bindless_descriptor.free(current_image->bindless_storage_index, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - } - - if (current_image->bindless_sampled_index != 0U) { - bindless_descriptor.free(current_image->bindless_sampled_index, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - } - - vmaDestroyImage(context.allocator, current_image->handle, current_image->alloc); - vkDestroyImageView(context.device, current_image->view, nullptr); - - // TODO: Free once using freelist - // images.erase(image.handle); -} - -std::vector<handle> vkapi::create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count) { - std::vector<handle> images_handles(image_count); - - for (size_t image_index = 0; image_index < image_count; image_index++) { - images_handles[image_index] = create_image(size, format, usages); - } - - return images_handles; -} - -void vkapi::destroy_images(std::vector<handle>& imgs) { - for (auto handle : imgs) { - destroy_image(handle); - } -} - -VkFence vkapi::create_fence() const { - VkFence fence; - VkFenceCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - create_info.pNext = nullptr; - create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - VKRESULT(vkCreateFence(context.device, &create_info, nullptr, &fence)) - - return fence; -} - -void vkapi::destroy_fence(VkFence fence) const { - vkDestroyFence(context.device, fence, nullptr); -} - -std::vector<VkFence> vkapi::create_fences(size_t fences_count) const { - std::vector<VkFence> fences{ fences_count }; - - for (size_t fence_index = 0; fence_index < fences_count; fence_index++) { - fences[fence_index] = create_fence(); - } - - return fences; -} - -void vkapi::destroy_fences(VkFence fences[], size_t fences_count) const { - for (size_t index{ 0 }; index < fences_count; index++) { - vkDestroyFence(context.device, fences[index], nullptr); - } -} - -VkSemaphore vkapi::create_semaphore() const { - VkSemaphore semaphore; - VkSemaphoreCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - create_info.pNext = nullptr; - create_info.flags = 0; - - VKRESULT(vkCreateSemaphore(context.device, &create_info, nullptr, &semaphore)) - - return semaphore; -} - -void vkapi::destroy_semaphore(VkSemaphore semaphore) const { - vkDestroySemaphore(context.device, semaphore, nullptr); -} - -std::vector<VkSemaphore> vkapi::create_semaphores(size_t semaphores_count) const { - std::vector<VkSemaphore> semaphores{ semaphores_count }; - - for (size_t semaphore_index{ 0 }; semaphore_index < semaphores_count; semaphore_index++) { - semaphores[semaphore_index] = create_semaphore(); - } - - return semaphores; -} - -void vkapi::destroy_semaphores(VkSemaphore semaphores[], size_t semaphores_count) const { - for (size_t index{ 0 }; index < semaphores_count; index++) { - vkDestroySemaphore(context.device, semaphores[index], nullptr); - } -} - -handle vkapi::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) { - VkSamplerCreateInfo sampler_create_info = {}; - sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - sampler_create_info.pNext = VK_NULL_HANDLE; - sampler_create_info.flags = 0; - sampler_create_info.magFilter = filter; - sampler_create_info.minFilter = filter; - sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - sampler_create_info.addressModeU = address_mode; - sampler_create_info.addressModeV = address_mode; - sampler_create_info.addressModeW = address_mode; - sampler_create_info.mipLodBias = 0.f; - sampler_create_info.anisotropyEnable = VK_FALSE; - sampler_create_info.compareEnable = VK_FALSE; - sampler_create_info.compareOp = VK_COMPARE_OP_ALWAYS; - sampler_create_info.minLod = 0.f; - sampler_create_info.maxLod = 0.f; - sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - sampler_create_info.unnormalizedCoordinates = VK_FALSE; - - struct sampler* sampler = new struct sampler(); - VKRESULT(vkCreateSampler(context.device, &sampler_create_info, VK_NULL_HANDLE, &sampler->handle)) - - sampler->bindless_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLER); - - - samplers.push_back(sampler); - - update_descriptor_sampler(samplers.size() - 1); - - return samplers.size() - 1; -} - -void vkapi::destroy_sampler(handle sampler) { - auto* current_sampler = samplers[sampler]; - bindless_descriptor.free(current_sampler->bindless_index, VK_DESCRIPTOR_TYPE_SAMPLER); - - vkDestroySampler(context.device, current_sampler->handle, VK_NULL_HANDLE); - - // samplers.erase(sampler.handle); -} - -VkCommandPool vkapi::create_command_pool() const { - VkCommandPoolCreateInfo cmd_pool_create_info = {}; - cmd_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmd_pool_create_info.pNext = nullptr; - cmd_pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - cmd_pool_create_info.queueFamilyIndex = context.graphics_queue.index; - - VkCommandPool command_pool; - VKRESULT(vkCreateCommandPool(context.device, &cmd_pool_create_info, nullptr, &command_pool)) - - return command_pool; -} - -void vkapi::allocate_command_buffers(VkCommandPool command_pool, VkCommandBuffer* command_buffers, size_t count) const { - VkCommandBufferAllocateInfo cmd_buf_allocate_info = {}; - cmd_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cmd_buf_allocate_info.pNext = VK_NULL_HANDLE; - cmd_buf_allocate_info.commandPool = command_pool; - cmd_buf_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmd_buf_allocate_info.commandBufferCount = count; - - vkAllocateCommandBuffers(context.device, &cmd_buf_allocate_info, command_buffers); -} - -// TODO: attachment structure -VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_format, VkImageLayout initial_layout, VkImageLayout final_layout) { - std::vector<VkAttachmentDescription> attachments_description = {}; - std::vector<VkAttachmentReference> attachments_reference = {}; - - for (size_t attachment_index = 0; attachment_index < color_attachments_format.size(); attachment_index++) { - auto format = color_attachments_format[attachment_index]; - VkAttachmentDescription attachment_description = {}; - attachment_description.flags = 0; - attachment_description.format = format; - attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; - attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // TODO: Set based on render pass usage - attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // TODO: Set based on render pass usage - - attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_description.initialLayout = initial_layout; - attachment_description.finalLayout = final_layout; - - attachments_description.push_back(attachment_description); - - VkAttachmentReference attachment_reference = {}; - attachment_reference.attachment = attachment_index; - attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - attachments_reference.push_back(attachment_reference); - } - - VkSubpassDescription subpass_description = {}; - subpass_description.flags = 0; - subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass_description.colorAttachmentCount = attachments_reference.size(); - subpass_description.pColorAttachments = attachments_reference.data(); - subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE; - subpass_description.pResolveAttachments = VK_NULL_HANDLE; - subpass_description.preserveAttachmentCount = 0; - subpass_description.pPreserveAttachments = VK_NULL_HANDLE; - - - VkSubpassDependency subpass_dependency[2] = {}; - subpass_dependency[0].srcSubpass = VK_SUBPASS_EXTERNAL; - subpass_dependency[0].dstSubpass = 1; // First subpass attachment is used in - subpass_dependency[0].srcStageMask = VK_PIPELINE_STAGE_NONE_KHR; - subpass_dependency[0].dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - subpass_dependency[0].srcAccessMask = 0; - subpass_dependency[0].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - subpass_dependency[0].dependencyFlags = 0; - - - subpass_dependency[1].srcSubpass = 1; // Last subpass attachment is used in - subpass_dependency[1].dstSubpass = VK_SUBPASS_EXTERNAL; - subpass_dependency[1].srcStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - subpass_dependency[1].dstStageMask = VK_PIPELINE_STAGE_NONE_KHR; - subpass_dependency[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - subpass_dependency[1].dstAccessMask = 0; - subpass_dependency[1].dependencyFlags = 0; - - - VkRenderPass render_pass; - VkRenderPassCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - create_info.pNext = VK_NULL_HANDLE; - create_info.flags = 0; - create_info.attachmentCount = attachments_description.size(); - create_info.pAttachments = attachments_description.data(); - create_info.subpassCount = 1; - create_info.pSubpasses = &subpass_description; - // create_info.dependencyCount = sizeof(subpass_dependency) / sizeof(VkSubpassDependency); - // create_info.pDependencies = subpass_dependency; - - VKRESULT(vkCreateRenderPass(context.device, &create_info, VK_NULL_HANDLE, &render_pass)) - - return render_pass; -} - -void vkapi::destroy_render_pass(VkRenderPass render_pass) { - vkDestroyRenderPass(context.device, render_pass, VK_NULL_HANDLE); -} - -framebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector<VkFormat>& formats, VkExtent2D size) { - VkFramebuffer framebuffer_handle; - - std::vector<VkFramebufferAttachmentImageInfo> attachments_image_infos(formats.size()); - for (size_t index = 0; index < formats.size(); index++) { - VkFramebufferAttachmentImageInfo attachments_image_info = {}; - attachments_image_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO; - attachments_image_info.pNext = VK_NULL_HANDLE; - attachments_image_info.flags = 0; - attachments_image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - attachments_image_info.width = size.width; - attachments_image_info.height = size.height; - attachments_image_info.layerCount = 1; - attachments_image_info.viewFormatCount = 1; - attachments_image_info.pViewFormats = &formats[index]; - - attachments_image_infos[index] = attachments_image_info; - } - - VkFramebufferAttachmentsCreateInfo attachments_create_info = {}; - attachments_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO; - attachments_create_info.pNext = VK_NULL_HANDLE; - attachments_create_info.attachmentImageInfoCount = attachments_image_infos.size(); - attachments_create_info.pAttachmentImageInfos = attachments_image_infos.data(); - - VkFramebufferCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - create_info.pNext = &attachments_create_info; - create_info.flags = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT; - create_info.renderPass = render_pass; - create_info.attachmentCount = formats.size(); - create_info.pAttachments = VK_NULL_HANDLE; - create_info.width = size.width; - create_info.height = size.height; - create_info.layers = 1; - - VKRESULT(vkCreateFramebuffer(context.device, &create_info, VK_NULL_HANDLE, &framebuffer_handle)) - - return { .handle = framebuffer_handle, .size = size }; -} - -std::vector<framebuffer> vkapi::create_framebuffers(VkRenderPass render_pass, std::vector<VkFormat>& formats, VkExtent2D size, uint32_t framebuffer_count) { - std::vector<framebuffer> framebuffers{ framebuffer_count }; - - for (auto& framebuffer : framebuffers) { - framebuffer = create_framebuffer(render_pass, formats, size); - } - - return framebuffers; -} - -void vkapi::destroy_framebuffer(framebuffer framebuffer) const { - VKRESULT(vkDeviceWaitIdle(context.device)) - - vkDestroyFramebuffer(context.device, framebuffer.handle, VK_NULL_HANDLE); -} - -void vkapi::destroy_framebuffers(std::vector<framebuffer>& framebuffers) const { - VKRESULT(vkDeviceWaitIdle(context.device)) - - for (auto& framebuffer : framebuffers) { - vkDestroyFramebuffer(context.device, framebuffer.handle, VK_NULL_HANDLE); - } -} - -pipeline vkapi::create_compute_pipeline(const char* shader_name) const { - pipeline pipeline{ - .bind_point = VK_PIPELINE_BIND_POINT_COMPUTE - }; - - auto shader_filename = std::string(shader_name) + ".comp.spv"; - auto shader_path = std::filesystem::path{ "./shaders" } / shader_filename; - auto shader_code = read_file(shader_path.string().c_str()); - assert(!shader_code.empty()); - - pipeline.shader_modules.resize(1); - - VkShaderModuleCreateInfo shader_create_info = {}; - shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_create_info.pNext = VK_NULL_HANDLE; - shader_create_info.flags = 0; - shader_create_info.codeSize = shader_code.size(); - shader_create_info.pCode = reinterpret_cast<uint32_t*>(shader_code.data()); - - VKRESULT(vkCreateShaderModule(context.device, &shader_create_info, VK_NULL_HANDLE, (pipeline.shader_modules).data())) - - VkPipelineShaderStageCreateInfo stage_create_info = {}; - stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stage_create_info.pNext = VK_NULL_HANDLE; - stage_create_info.flags = 0; - stage_create_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; - stage_create_info.module = pipeline.shader_modules[0]; - stage_create_info.pName = "main"; - stage_create_info.pSpecializationInfo = VK_NULL_HANDLE; - - - VkComputePipelineCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - create_info.pNext = VK_NULL_HANDLE; - create_info.flags = 0; - create_info.stage = stage_create_info; - create_info.layout = bindless_descriptor.pipeline_layout; - - VKRESULT(vkCreateComputePipelines( - context.device, - VK_NULL_HANDLE, - 1, - &create_info, - nullptr, - &pipeline.handle)) - - return pipeline; -} - -pipeline vkapi::create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector<VkDynamicState>& dynamic_states) const { - pipeline pipeline{ - .bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS - }; - - std::vector<VkPipelineShaderStageCreateInfo> stages_create_info = {}; - - for (VkShaderStageFlags stage_flag = VK_SHADER_STAGE_VERTEX_BIT; stage_flag <= VK_SHADER_STAGE_ALL_GRAPHICS; stage_flag <<= 2) { - if ((stage_flag & shader_stages) != 0U) { - VkShaderModule shader_module; - - auto shader_filename = std::string(shader_name) + shader_stage_extension(stage_flag) + ".spv"; - auto shader_path = std::filesystem::path{ "./shaders" } / shader_filename; - std::vector<uint8_t> shader_code = read_file(shader_path.string().c_str()); - assert(!shader_code.empty()); - - VkShaderModuleCreateInfo shader_create_info = {}; - shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_create_info.pNext = nullptr; - shader_create_info.flags = 0; - shader_create_info.codeSize = shader_code.size(); - shader_create_info.pCode = reinterpret_cast<uint32_t*>(shader_code.data()); - - VKRESULT(vkCreateShaderModule(context.device, &shader_create_info, nullptr, &shader_module)) - - pipeline.shader_modules.push_back(shader_module); - - VkPipelineShaderStageCreateInfo stage_create_info = {}; - stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stage_create_info.pNext = nullptr; - stage_create_info.flags = 0; - stage_create_info.stage = (VkShaderStageFlagBits)stage_flag; - stage_create_info.module = shader_module; - stage_create_info.pName = "main"; - stage_create_info.pSpecializationInfo = nullptr; - - stages_create_info.push_back(stage_create_info); - } - } - - - VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = {}; - vertex_input_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - - VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = {}; - input_assembly_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly_state_create_info.pNext = nullptr; - input_assembly_state_create_info.flags = 0; - input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - - VkPipelineViewportStateCreateInfo viewport_state_create_info = {}; - viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_state_create_info.pNext = nullptr; - viewport_state_create_info.flags = 0; - viewport_state_create_info.viewportCount = 1; - viewport_state_create_info.pViewports = VK_NULL_HANDLE; - viewport_state_create_info.scissorCount = 1; - viewport_state_create_info.pScissors = VK_NULL_HANDLE; - - VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {}; - rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterization_state_create_info.pNext = nullptr; - rasterization_state_create_info.flags = 0; - rasterization_state_create_info.depthClampEnable = VK_FALSE; - rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE; - rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL; - rasterization_state_create_info.cullMode = VK_CULL_MODE_NONE; - rasterization_state_create_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterization_state_create_info.depthBiasEnable = VK_FALSE; - rasterization_state_create_info.lineWidth = 1.f; - - VkPipelineMultisampleStateCreateInfo multisample_state_create_info = {}; - multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisample_state_create_info.pNext = nullptr; - multisample_state_create_info.flags = 0; - multisample_state_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisample_state_create_info.sampleShadingEnable = VK_FALSE; - multisample_state_create_info.minSampleShading = 1.f; - - VkPipelineColorBlendAttachmentState color_attachment_state = {}; - color_attachment_state.blendEnable = VK_TRUE; - color_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - color_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; - color_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; - color_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {}; - color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blend_state_create_info.pNext = nullptr; - color_blend_state_create_info.flags = 0; - color_blend_state_create_info.logicOpEnable = VK_FALSE; - color_blend_state_create_info.attachmentCount = 1; - color_blend_state_create_info.pAttachments = &color_attachment_state; - - VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {}; - dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_create_info.pNext = VK_NULL_HANDLE; - dynamic_state_create_info.flags = 0; - dynamic_state_create_info.dynamicStateCount = dynamic_states.size(); - dynamic_state_create_info.pDynamicStates = dynamic_states.data(); - - VkGraphicsPipelineCreateInfo pipeline_create_info = {}; - pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipeline_create_info.pNext = nullptr; - pipeline_create_info.flags = 0; - pipeline_create_info.stageCount = stages_create_info.size(); - pipeline_create_info.pStages = stages_create_info.data(); - pipeline_create_info.pVertexInputState = &vertex_input_state_create_info; - pipeline_create_info.pInputAssemblyState = &input_assembly_state_create_info; - pipeline_create_info.pViewportState = &viewport_state_create_info; - pipeline_create_info.pRasterizationState = &rasterization_state_create_info; - pipeline_create_info.pMultisampleState = &multisample_state_create_info; - pipeline_create_info.pColorBlendState = &color_blend_state_create_info; - pipeline_create_info.pDynamicState = &dynamic_state_create_info; - pipeline_create_info.layout = bindless_descriptor.pipeline_layout; - pipeline_create_info.renderPass = render_pass; - pipeline_create_info.subpass = 0; - - VKRESULT(vkCreateGraphicsPipelines(context.device, VK_NULL_HANDLE, 1, &pipeline_create_info, VK_NULL_HANDLE, &pipeline.handle)) - - return pipeline; -} - -void vkapi::destroy_pipeline(pipeline& pipeline) const { - for (auto& shader_module : pipeline.shader_modules) { - vkDestroyShaderModule(context.device, shader_module, nullptr); - } - - vkDestroyPipeline(context.device, pipeline.handle, nullptr); -} - -VkSurfaceKHR vkapi::create_surface(window& wnd) const { - VkSurfaceKHR surface; - -#if defined(LINUX) - VkXcbSurfaceCreateInfoKHR create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; - create_info.pNext = nullptr; - create_info.flags = 0; - create_info.connection = wnd.connection; - create_info.window = wnd.win; - - VKRESULT(vkCreateXcbSurfaceKHR(context.instance, &create_info, nullptr, &surface)) -#elif defined(WINDOWS) - VkWin32SurfaceCreateInfoKHR create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - create_info.pNext = nullptr; - create_info.flags = 0; - create_info.hinstance = GetModuleHandle(nullptr); - create_info.hwnd = wnd.handle; - - VKRESULT(vkCreateWin32SurfaceKHR(context.instance, &create_info, nullptr, &surface)) -#elif defined(MACOS) - VkMetalSurfaceCreateInfoEXT create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; - create_info.pNext = nullptr; - create_info.flags = 0; - // create_info.pLayer = GetModuleHandle(NULL); - - VKRESULT(vkCreateMetalSurfaceEXT(context.instance, &create_info, nullptr, &surface)) -#endif - - return surface; -} - -void vkapi::destroy_surface(VkSurfaceKHR surface) { - vkDestroySurfaceKHR(context.instance, surface, nullptr); -} - -swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, VkSwapchainKHR old_swapchain) { - swapchain swapchain; - - VkBool32 queue_support_presentation = VK_FALSE; - VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(context.physical_device, context.graphics_queue.index, surface, &queue_support_presentation)) - - assert(queue_support_presentation == VK_TRUE); - - VkSurfaceCapabilitiesKHR caps; - VKRESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(context.physical_device, surface, &caps)) - - swapchain.extent = caps.currentExtent; - - if (swapchain.extent.width < caps.minImageExtent.width) { - swapchain.extent.width = caps.minImageExtent.width; - } else if (swapchain.extent.width > caps.maxImageExtent.width) { - swapchain.extent.width = caps.maxImageExtent.width; - } - - if (swapchain.extent.height < caps.minImageExtent.height) { - swapchain.extent.height = caps.minImageExtent.height; - } else if (swapchain.extent.height > caps.maxImageExtent.height) { - swapchain.extent.height = caps.maxImageExtent.height; - } - - - uint32_t supported_formats_count = 0; - VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(context.physical_device, surface, &supported_formats_count, VK_NULL_HANDLE)) - - std::vector<VkSurfaceFormatKHR> supported_formats{ supported_formats_count }; - VKRESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(context.physical_device, surface, &supported_formats_count, supported_formats.data())) - - - uint32_t supported_present_modes_count = 0; - VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(context.physical_device, surface, &supported_present_modes_count, VK_NULL_HANDLE)) - - std::vector<VkPresentModeKHR> supported_present_modes{ supported_present_modes_count }; - VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(context.physical_device, surface, &supported_present_modes_count, supported_present_modes.data())) - - - swapchain.surface_format = supported_formats[0]; - - VkSwapchainCreateInfoKHR create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - create_info.pNext = nullptr; - create_info.flags = 0; - create_info.surface = surface; - create_info.minImageCount = min_image_count; - create_info.imageFormat = swapchain.surface_format.format; - create_info.imageColorSpace = swapchain.surface_format.colorSpace; - create_info.imageExtent = swapchain.extent; - create_info.imageArrayLayers = 1; - create_info.imageUsage = usages; - create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - create_info.preTransform = caps.currentTransform; - create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - create_info.presentMode = supported_present_modes[0]; - create_info.clipped = VK_TRUE; - create_info.oldSwapchain = old_swapchain; - - VKRESULT(vkCreateSwapchainKHR(context.device, &create_info, nullptr, &swapchain.handle)) - - - VKRESULT(vkGetSwapchainImagesKHR(context.device, swapchain.handle, &swapchain.image_count, VK_NULL_HANDLE)) - - swapchain.images = std::vector<handle>(swapchain.image_count); - auto vk_images = std::vector<VkImage>(swapchain.image_count); - - VKRESULT(vkGetSwapchainImagesKHR(context.device, swapchain.handle, &swapchain.image_count, vk_images.data())) - - - VkImageSubresourceRange image_subresource_range = {}; - image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_subresource_range.baseMipLevel = 0; - image_subresource_range.levelCount = 1; - image_subresource_range.baseArrayLayer = 0; - image_subresource_range.layerCount = 1; - - VkExtent3D image_size = { - .width = swapchain.extent.width, - .height = swapchain.extent.height, - .depth = 1, - }; - - for (size_t image_index = 0; image_index < swapchain.image_count; image_index++) { - auto* current_image = new struct image(); - - current_image->handle = vk_images[image_index]; - current_image->size = image_size; - current_image->subresource_range = image_subresource_range; - current_image->usages = usages; - - - VkImageViewCreateInfo image_view_create_info = {}; - image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - image_view_create_info.pNext = nullptr; - image_view_create_info.flags = 0; - image_view_create_info.image = current_image->handle; - image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - image_view_create_info.format = swapchain.surface_format.format; - image_view_create_info.components = { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY - }; - image_view_create_info.subresourceRange = image_subresource_range; - - VKRESULT(vkCreateImageView(context.device, &image_view_create_info, nullptr, ¤t_image->view)) - - images.push_back(current_image); - - auto current_image_handle = images.size() - 1; - - if ((usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0U) { - current_image->bindless_storage_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - update_descriptor_image(current_image_handle, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - } - - if ((usages & VK_IMAGE_USAGE_SAMPLED_BIT) != 0U) { - current_image->bindless_sampled_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - update_descriptor_image(current_image_handle, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - } - - swapchain.images[image_index] = current_image_handle; - } - - return swapchain; -} - -void vkapi::destroy_swapchain(swapchain& swapchain) { - VKRESULT(vkDeviceWaitIdle(context.device)) - - for (auto& image : swapchain.images) { - // TODO: Change this - if (images[image]->bindless_storage_index != 0) - bindless_descriptor.free(images[image]->bindless_storage_index, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - if (images[image]->bindless_sampled_index != 0) - bindless_descriptor.free(images[image]->bindless_sampled_index, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - - vkDestroyImageView(context.device, images[image]->view, nullptr); - } - vkDestroySwapchainKHR(context.device, swapchain.handle, nullptr); -} - -void vkapi::update_descriptor_image(handle img, VkDescriptorType type) { - VkDescriptorImageInfo descriptor_image_info; - VkWriteDescriptorSet write_descriptor; - - auto* current_image = images[img]; - - descriptor_image_info.sampler = VK_NULL_HANDLE; - descriptor_image_info.imageView = current_image->view; - descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor.pNext = nullptr; - write_descriptor.dstSet = bindless_descriptor.set; - write_descriptor.dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1; - write_descriptor.dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? current_image->bindless_storage_index : current_image->bindless_sampled_index; - write_descriptor.descriptorCount = 1; - write_descriptor.descriptorType = type; - write_descriptor.pImageInfo = &descriptor_image_info; - write_descriptor.pBufferInfo = VK_NULL_HANDLE; - write_descriptor.pTexelBufferView = VK_NULL_HANDLE; - - vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr); -} - -void vkapi::update_descriptor_images(std::vector<handle>& handles, VkDescriptorType type) { - std::vector<VkDescriptorImageInfo> descriptor_images_info{ images.size() }; - std::vector<VkWriteDescriptorSet> writes_descriptor{ images.size() }; - - for (size_t image_index = 0; image_index < images.size(); image_index++) { - auto image = images[handles[image_index]]; - descriptor_images_info[image_index].sampler = VK_NULL_HANDLE; - descriptor_images_info[image_index].imageView = image->view; - descriptor_images_info[image_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - writes_descriptor[image_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes_descriptor[image_index].pNext = nullptr; - writes_descriptor[image_index].dstSet = bindless_descriptor.set; - writes_descriptor[image_index].dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1; - writes_descriptor[image_index].dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? image->bindless_storage_index : image->bindless_sampled_index; - writes_descriptor[image_index].descriptorCount = 1; - writes_descriptor[image_index].descriptorType = type; - writes_descriptor[image_index].pImageInfo = &descriptor_images_info[image_index]; - writes_descriptor[image_index].pBufferInfo = VK_NULL_HANDLE; - writes_descriptor[image_index].pTexelBufferView = VK_NULL_HANDLE; - } - - vkUpdateDescriptorSets(context.device, writes_descriptor.size(), writes_descriptor.data(), 0, nullptr); -} - -void vkapi::update_descriptor_sampler(handle sampler) { - VkDescriptorImageInfo descriptor_image_info; - VkWriteDescriptorSet write_descriptor; - auto current_sampler = samplers[sampler]; - - descriptor_image_info.sampler = current_sampler->handle; - descriptor_image_info.imageView = VK_NULL_HANDLE; - descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor.pNext = nullptr; - write_descriptor.dstSet = bindless_descriptor.set; - write_descriptor.dstBinding = 0; - write_descriptor.dstArrayElement = current_sampler->bindless_index; - write_descriptor.descriptorCount = 1; - write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; - write_descriptor.pImageInfo = &descriptor_image_info; - write_descriptor.pBufferInfo = VK_NULL_HANDLE; - write_descriptor.pTexelBufferView = VK_NULL_HANDLE; - - vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr); -} - -void vkapi::update_descriptor_samplers(std::vector<handle>& handles) { - std::vector<VkDescriptorImageInfo> descriptor_images_info{ samplers.size() }; - std::vector<VkWriteDescriptorSet> writes_descriptor{ samplers.size() }; - - for (size_t sampler_index = 0; sampler_index < samplers.size(); sampler_index++) { - auto sampler = samplers[handles[sampler_index]]; - descriptor_images_info[sampler_index].sampler = sampler->handle; - descriptor_images_info[sampler_index].imageView = VK_NULL_HANDLE; - descriptor_images_info[sampler_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - writes_descriptor[sampler_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes_descriptor[sampler_index].pNext = nullptr; - writes_descriptor[sampler_index].dstSet = bindless_descriptor.set; - writes_descriptor[sampler_index].dstBinding = 0; - writes_descriptor[sampler_index].dstArrayElement = sampler->bindless_index; - writes_descriptor[sampler_index].descriptorCount = 1; - writes_descriptor[sampler_index].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; - writes_descriptor[sampler_index].pImageInfo = &descriptor_images_info[sampler_index]; - writes_descriptor[sampler_index].pBufferInfo = VK_NULL_HANDLE; - writes_descriptor[sampler_index].pTexelBufferView = VK_NULL_HANDLE; - } - - vkUpdateDescriptorSets(context.device, writes_descriptor.size(), writes_descriptor.data(), 0, nullptr); -} - -void vkapi::update_constants(VkCommandBuffer command_buffer, VkShaderStageFlagBits shader_stage, off_t offset, size_t size, void* data) { - vkCmdPushConstants(command_buffer, bindless_descriptor.pipeline_layout, shader_stage, offset, size, data); -} - -void vkapi::start_record(VkCommandBuffer command_buffer) { - VkCommandBufferBeginInfo cmd_buf_begin_info = {}; - cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmd_buf_begin_info.pNext = nullptr; - cmd_buf_begin_info.flags = 0; - cmd_buf_begin_info.pInheritanceInfo = nullptr; - - vkBeginCommandBuffer(command_buffer, &cmd_buf_begin_info); -} - -void vkapi::image_barrier(VkCommandBuffer command_buffer, VkImageLayout dst_layout, VkPipelineStageFlagBits dst_stage, VkAccessFlags dst_access, handle image) { - auto* current_image = images[image]; - - VkImageMemoryBarrier image_barrier = {}; - image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - image_barrier.pNext = nullptr; - image_barrier.srcAccessMask = current_image->previous_access; - image_barrier.dstAccessMask = dst_access; - image_barrier.oldLayout = current_image->previous_layout; - image_barrier.newLayout = dst_layout; - image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - image_barrier.image = current_image->handle; - image_barrier.subresourceRange = current_image->subresource_range; - - vkCmdPipelineBarrier( - command_buffer, - current_image->previous_stage, - dst_stage, - 0, - 0, - nullptr, - 0, - nullptr, - 1, - &image_barrier); - - current_image->previous_layout = dst_layout; - current_image->previous_access = dst_access; - current_image->previous_stage = dst_stage; -} - -void vkapi::begin_render_pass(VkCommandBuffer command_buffer, VkRenderPass render_pass, std::vector<VkImageView>& attachments, framebuffer framebuffer, VkExtent2D size) { - VkRect2D render_area = { - { - 0, - 0, - }, - size - }; - - VkRenderPassAttachmentBeginInfo attachment_begin_info = {}; - attachment_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO; - attachment_begin_info.pNext = VK_NULL_HANDLE; - attachment_begin_info.attachmentCount = attachments.size(); - attachment_begin_info.pAttachments = attachments.data(); - - VkClearValue clear_value{ .color{ .float32{ 0.f, 0.f, 0.f, 1.f } } }; - VkRenderPassBeginInfo render_pass_begin_info = {}; - render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin_info.pNext = &attachment_begin_info; - render_pass_begin_info.renderPass = render_pass; - render_pass_begin_info.framebuffer = framebuffer.handle; - render_pass_begin_info.renderArea = render_area; - render_pass_begin_info.clearValueCount = 1; - render_pass_begin_info.pClearValues = &clear_value; - - vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); -} - -void vkapi::end_render_pass(VkCommandBuffer command_buffer) { - vkCmdEndRenderPass(command_buffer); -} - -void vkapi::run_compute_pipeline(VkCommandBuffer command_buffer, pipeline& pipeline, size_t group_count_x, size_t group_count_y, size_t group_count_z) { - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless_descriptor.pipeline_layout, 0, 1, &bindless_descriptor.set, 0, nullptr); - - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.handle); - - vkCmdDispatch(command_buffer, group_count_x, group_count_y, group_count_z); -} - -void vkapi::draw(VkCommandBuffer command_buffer, pipeline& pipeline, uint32_t vertex_count, uint32_t vertex_offset) { - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless_descriptor.pipeline_layout, 0, 1, &bindless_descriptor.set, 0, nullptr); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.handle); - - vkCmdDraw(command_buffer, vertex_count, 1, vertex_offset, 0); -} - -void vkapi::draw(VkCommandBuffer command_buffer, pipeline& pipeline, handle index_buffer, uint32_t index_count, uint32_t index_offset, uint32_t vertex_offset) { - vkCmdBindIndexBuffer(command_buffer, buffers[index_buffer]->handle, 0, VK_INDEX_TYPE_UINT16); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless_descriptor.pipeline_layout, 0, 1, &bindless_descriptor.set, 0, nullptr); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.handle); - - vkCmdDrawIndexed(command_buffer, index_count, 1, index_offset, vertex_offset, 0); -} - -void vkapi::blit_full(VkCommandBuffer command_buffer, handle src, handle dst) { - auto* src_image = images[src]; - auto* dst_image = images[dst]; - - VkImageSubresourceLayers images_subres_layers{ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }; - - VkOffset3D start_offset{ - .x = 0, - .y = 0, - .z = 0, - }; - VkOffset3D end_offset{ - .x = (int32_t)dst_image->size.width, - .y = (int32_t)dst_image->size.height, - .z = (int32_t)dst_image->size.depth, - }; - - VkImageBlit blit_region{ - .srcSubresource = images_subres_layers, - .srcOffsets = { start_offset, end_offset }, - .dstSubresource = images_subres_layers, - .dstOffsets = { start_offset, end_offset }, - }; - - vkCmdBlitImage(command_buffer, src_image->handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST); -} - -void vkapi::end_record(VkCommandBuffer command_buffer){ - VKRESULT(vkEndCommandBuffer(command_buffer)) -} - -VkResult vkapi::submit(VkCommandBuffer command_buffers[], size_t command_buffers_count, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence submission_fence) const { - VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - - VkSubmitInfo submit_info = {}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.waitSemaphoreCount = wait_semaphore != nullptr ? 1 : 0; - submit_info.pWaitSemaphores = &wait_semaphore; - submit_info.pWaitDstStageMask = wait_semaphore != nullptr ? &wait_stage : VK_NULL_HANDLE; - submit_info.signalSemaphoreCount = signal_semaphore != nullptr ? 1 : 0; - submit_info.pSignalSemaphores = &signal_semaphore; - submit_info.commandBufferCount = command_buffers_count; - submit_info.pCommandBuffers = command_buffers; - - return vkQueueSubmit(context.graphics_queue.handle, 1, &submit_info, submission_fence); -} - -VkResult vkapi::present(swapchain& swapchain, uint32_t image_index, VkSemaphore wait_semaphore) const { - VkPresentInfoKHR present_info = {}; - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.pNext = nullptr; - present_info.waitSemaphoreCount = 1; - present_info.pWaitSemaphores = &wait_semaphore; - present_info.swapchainCount = 1; - present_info.pSwapchains = &swapchain.handle; - present_info.pImageIndices = &image_index; - present_info.pResults = nullptr; - - return vkQueuePresentKHR(context.graphics_queue.handle, &present_info); -} - -const char* vkapi::shader_stage_extension(VkShaderStageFlags shader_stage) { - switch (shader_stage) { - case VK_SHADER_STAGE_VERTEX_BIT: { - return ".vert"; - } - case VK_SHADER_STAGE_FRAGMENT_BIT: { - return ".frag"; - } - case VK_SHADER_STAGE_COMPUTE_BIT: { - return ".comp"; - } - default: - assert(true && "Stage not supported"); - return ""; - } -} |
