diff options
| -rw-r--r-- | api-test/main.cpp | 27 | ||||
| -rw-r--r-- | api-test/vk-device.cpp | 314 | ||||
| -rw-r--r-- | include/api-test/freelist.hpp | 2 | ||||
| -rw-r--r-- | include/api-test/vk-device-types.hpp | 21 | ||||
| -rw-r--r-- | include/api-test/vk-device.hpp | 11 |
5 files changed, 221 insertions, 154 deletions
diff --git a/api-test/main.cpp b/api-test/main.cpp index 807883d..30668e2 100644 --- a/api-test/main.cpp +++ b/api-test/main.cpp @@ -83,21 +83,22 @@ int main() { ImGui::CreateContext(); ImGuiIO &io = ImGui::GetIO(); - io.DisplaySize.x = 1024.f; - io.DisplaySize.y = 1024.f; + io.DisplaySize.x = window_width; + io.DisplaySize.y = window_height; auto& device = vkdevice::get_render_device(); device.init(); - device.create_surface({ + auto surface_handle = device.create_surface({ .window_handle = wnd.handle, .surface_format = { .format = VK_FORMAT_B8G8R8A8_UNORM, .colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, }, .present_mode = VK_PRESENT_MODE_FIFO_KHR, - .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, }); + auto& surface = device.get_surface(surface_handle); constexpr size_t image_size = 1024U; constexpr size_t image_count = 4U; @@ -185,7 +186,7 @@ int main() { .cs_code = code, }); - std::array<VkFormat, 1U> formats { VK_FORMAT_R8G8B8A8_UNORM }; + std::array<VkFormat, 1U> formats { surface.surface_format.format }; auto vertex_code = read_file("shaders/api-test-ui.vert.spv"); auto fragment_code = read_file("shaders/api-test-ui.frag.spv"); auto graphics = device.create_pipeline({ @@ -197,6 +198,10 @@ int main() { auto semaphore = device.create_semaphore({ .type = VK_SEMAPHORE_TYPE_TIMELINE, }); + auto acquire_semaphore = device.create_semaphore({ + .type = VK_SEMAPHORE_TYPE_BINARY, + }); + std::array<graphics_command_buffer, 2U> command_buffers; device.allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS); @@ -244,7 +249,9 @@ int main() { RD_END_CAPTURE; std::array<struct command_buffer, 1U> ui_command_buffers = {command_buffers[1]}; - std::array<handle<device_texture>, 1U> color_attachment {gpu_texture_handle}; + // std::array<handle<device_texture>, 1U> color_attachment {gpu_texture_handle}; + surface.acquire_image_index(acquire_semaphore); + std::array<handle<device_texture>, 1U> color_attachment {surface.get_backbuffer_image()}; while(wnd.isOpen) { wnd.poll_events(); @@ -258,6 +265,7 @@ int main() { RD_START_CAPTURE; command_buffers[1].start(), + command_buffers[1].barrier(surface.get_backbuffer_image(), VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_ACCESS_2_NONE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); command_buffers[1].begin_renderpass({ .render_area = { .x = static_cast<int32_t>(draw_data->DisplayPos.x), @@ -311,11 +319,16 @@ int main() { memcpy(uniform_buffer.mapped_ptr, draws.data(), sizeof(draw_params) * draw_index); command_buffers[1].end_renderpass(); + command_buffers[1].barrier(surface.get_backbuffer_image(), VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); command_buffers[1].stop(); - device.submit(ui_command_buffers, {}, semaphore); + device.submit(ui_command_buffers, acquire_semaphore, semaphore); + device.wait(semaphore); + device.present(surface_handle, {}); RD_END_CAPTURE; + + std::system("PAUSE"); } return 0; diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp index 2258bdb..2742220 100644 --- a/api-test/vk-device.cpp +++ b/api-test/vk-device.cpp @@ -44,6 +44,10 @@ vkdevice::~vkdevice() { bindless_model::destroy_bindless_model(bindless); + for (const auto& surface : surfaces) { + destroy_surface(surface); + } + for (const auto& texture : textures) { destroy_texture(texture); } @@ -60,10 +64,6 @@ vkdevice::~vkdevice() { destroy_semaphore(semaphore); } - for (const auto& surface : surfaces) { - destroy_surface(surface); - } - vmaDestroyAllocator(gpu_allocator); for (auto& queue : queues) { @@ -80,98 +80,7 @@ vkdevice::~vkdevice() { } handle<device_texture> vkdevice::create_texture(const texture_desc& desc) { - device_texture device_texture{ - .format = desc.format, - .width = desc.width, - .height = desc.height, - .mips = desc.mips, - }; - - assert(desc.mips <= texture_desc::max_mips); - - VkImageCreateInfo create_info{ - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .imageType = desc.type, - .format = desc.format, - .extent = { - .width = desc.width, - .height = desc.height, - .depth = desc.depth }, - .mipLevels = desc.mips, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = desc.usages, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - VmaAllocationCreateInfo alloc_create_info{ - .flags = 0U, - .usage = VMA_MEMORY_USAGE_GPU_ONLY, - .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - .preferredFlags = 0U, - .memoryTypeBits = 0U, - .pool = nullptr, - .pUserData = nullptr, - }; - - VKCHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &device_texture.vk_image, &device_texture.alloc, nullptr)); - - device_texture.aspects = ((desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) - ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT - : VK_IMAGE_ASPECT_COLOR_BIT; - - create_views(desc, device_texture); - - // TODO: Handle mips views - VkDescriptorImageInfo images_info[]{ - { - nullptr, - device_texture.whole_view, - VK_IMAGE_LAYOUT_GENERAL, - }, - }; - - std::vector<VkWriteDescriptorSet> write_descriptor_sets; - if ((desc.usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0) { - device_texture.storage_index = storage_indices.add(&device_texture); - - write_descriptor_sets.push_back({ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = bindless.sets[BindlessSetType::GLOBAL], - .dstBinding = 2U, - .dstArrayElement = device_texture.storage_index, - .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo), - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .pImageInfo = images_info, - .pBufferInfo = nullptr, - .pTexelBufferView = nullptr, - }); - } - if ((desc.usages & VK_IMAGE_USAGE_SAMPLED_BIT) != 0) { - device_texture.sampled_index = sampled_indices.add(&device_texture); - - write_descriptor_sets.push_back({ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = bindless.sets[BindlessSetType::GLOBAL], - .dstBinding = 1U, - .dstArrayElement = device_texture.sampled_index, - .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo), - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .pImageInfo = images_info, - .pBufferInfo = nullptr, - .pTexelBufferView = nullptr, - }); - } - - vkUpdateDescriptorSets(device, write_descriptor_sets.size(), write_descriptor_sets.data(), 0U, nullptr); + device_texture device_texture { desc }; return { textures.add(device_texture) }; } @@ -410,10 +319,6 @@ handle<device_surface> vkdevice::create_surface(const surface_desc& desc) { create_swapchain(desc, device_surface); - vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, nullptr); - std::vector<VkImage> images {device_surface.image_count}; - vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, images.data()); - return { surfaces.add(device_surface) }; } @@ -424,7 +329,7 @@ handle<device_semaphore> vkdevice::create_semaphore(const semaphore_desc& desc) VkSemaphoreTypeCreateInfo semaphore_type_create_info{ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, .pNext = nullptr, - .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, + .semaphoreType = desc.type, .initialValue = desc.initial_value, }; @@ -493,6 +398,17 @@ void vkdevice::destroy_surface(const device_surface& surface) { void vkdevice::destroy_surface(handle<device_surface> handle) { const auto& surface = vkdevice::get_surface(handle); + for (auto texture_index{0U}; texture_index < surface.image_count; texture_index++) { + auto texture_handle = surface.swapchain_images[texture_index]; + const auto& texture = get_texture(texture_handle); + + vkDestroyImageView(device, texture.whole_view, nullptr); + + for (auto mip_index{0U}; mip_index < texture.mips; mip_index++) { + vkDestroyImageView(device, texture.mips_views[mip_index], nullptr); + } + } + vkDestroySwapchainKHR(device, surface.vk_swapchain, nullptr); vkDestroySurfaceKHR(instance, surface.vk_surface, nullptr); @@ -629,39 +545,6 @@ VkShaderModule vkdevice::create_shader_module(const std::span<uint8_t>& shader_c return shader_module; } -void vkdevice::create_views(const texture_desc& desc, device_texture& texture) { - VkImageViewCreateInfo create_info{ - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .image = texture.vk_image, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = texture.format, - .components = { - .r = VK_COMPONENT_SWIZZLE_R, - .g = VK_COMPONENT_SWIZZLE_G, - .b = VK_COMPONENT_SWIZZLE_B, - .a = VK_COMPONENT_SWIZZLE_A, - }, - .subresourceRange = { - .aspectMask = texture.aspects, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }; - - for (auto mip_index{ 0 }; mip_index < texture.mips; mip_index++) { - create_info.subresourceRange.baseMipLevel = mip_index; - VKCHECK(vkCreateImageView(device, &create_info, nullptr, &texture.mips_views[mip_index])); - } - - create_info.subresourceRange.baseMipLevel = 0; - create_info.subresourceRange.levelCount = texture.mips; - VKCHECK(vkCreateImageView(device, &create_info, nullptr, &texture.whole_view)); -} - void vkdevice::create_swapchain(const surface_desc& desc, device_surface& surface) { VkSurfaceKHR vk_surface = surface.vk_surface; @@ -752,6 +635,26 @@ void vkdevice::create_swapchain(const surface_desc& desc, device_surface& surfac }; VKCHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &surface.vk_swapchain)); + + surface.surface_format = desc.surface_format; + + vkGetSwapchainImagesKHR(device, surface.vk_swapchain, &surface.image_count, nullptr); + assert(surface.image_count <= surface_desc::max_image_count); + + std::vector<VkImage> images {surface.image_count}; + vkGetSwapchainImagesKHR(device, surface.vk_swapchain, &surface.image_count, images.data()); + + for (auto index {0U}; index < surface.image_count; index++) { + surface.swapchain_images[index] = create_texture({ + .width = extent.width, + .height = extent.height, + .depth = 1U, + .usages = desc.usages, + .format = desc.surface_format.format, + .type = VK_IMAGE_TYPE_2D, + .vk_image = images[index], + }); + } } // ----------------- vkadapter ----------------- @@ -985,6 +888,145 @@ void vkdevice::create_debug_layer_callback() { } +freelist<device_texture*> device_texture::sampled_indices = {}; +freelist<device_texture*> device_texture::storage_indices = {}; + +device_texture::device_texture(const texture_desc& desc) { + auto& render_device = vkdevice::get_render_device(); + const auto& bindless = render_device.get_bindingmodel(); + auto* device = render_device.get_device(); + + vk_image = desc.vk_image; + format = desc.format; + width = desc.width; + height = desc.height; + mips = desc.mips; + aspects = ((desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) + ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT + : VK_IMAGE_ASPECT_COLOR_BIT; + + assert(mips <= texture_desc::max_mips); + + if (vk_image == nullptr) { + VkImageCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .imageType = desc.type, + .format = desc.format, + .extent = { + .width = desc.width, + .height = desc.height, + .depth = desc.depth + }, + .mipLevels = desc.mips, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = desc.usages, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VmaAllocationCreateInfo alloc_create_info{ + .flags = 0U, + .usage = VMA_MEMORY_USAGE_GPU_ONLY, + .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + .preferredFlags = 0U, + .memoryTypeBits = 0U, + .pool = nullptr, + .pUserData = nullptr, + }; + + VKCHECK(vmaCreateImage(render_device.get_allocator(), &create_info, &alloc_create_info, &vk_image, &alloc, nullptr)); + } + + create_views(); + + // TODO: Handle mips views + VkDescriptorImageInfo images_info[]{ + { + nullptr, + whole_view, + VK_IMAGE_LAYOUT_GENERAL, + }, + }; + + std::vector<VkWriteDescriptorSet> write_descriptor_sets; + if ((desc.usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0) { + storage_index = storage_indices.add(this); + + write_descriptor_sets.push_back({ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = bindless.sets[BindlessSetType::GLOBAL], + .dstBinding = 2U, + .dstArrayElement = storage_index, + .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo), + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .pImageInfo = images_info, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, + }); + } + if ((desc.usages & VK_IMAGE_USAGE_SAMPLED_BIT) != 0) { + sampled_index = sampled_indices.add(this); + + write_descriptor_sets.push_back({ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = bindless.sets[BindlessSetType::GLOBAL], + .dstBinding = 1U, + .dstArrayElement = sampled_index, + .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo), + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .pImageInfo = images_info, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, + }); + } + + vkUpdateDescriptorSets(device, write_descriptor_sets.size(), write_descriptor_sets.data(), 0U, nullptr); +} + +void device_texture::create_views() { + auto* device = vkdevice::get_render_device().get_device(); + + VkImageViewCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .image = vk_image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = format, + .components = { + .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = { + .aspectMask = aspects, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + + for (auto mip_index{ 0 }; mip_index < mips; mip_index++) { + create_info.subresourceRange.baseMipLevel = mip_index; + VKCHECK(vkCreateImageView(device, &create_info, nullptr, &mips_views[mip_index])); + } + + create_info.subresourceRange.baseMipLevel = 0; + create_info.subresourceRange.levelCount = mips; + VKCHECK(vkCreateImageView(device, &create_info, nullptr, &whole_view)); +} + + void device_surface::acquire_image_index(handle<device_semaphore> signal_handle) { auto& render_device = vkdevice::get_render_device(); auto* device = render_device.get_device(); @@ -993,6 +1035,6 @@ void device_surface::acquire_image_index(handle<device_semaphore> signal_handle) vkAcquireNextImageKHR(device, vk_swapchain, -1, signal.vk_semaphore, nullptr, &image_index); } -handle<device_texture> device_surface::get_backbuffer_image() { - +handle<device_texture> device_surface::get_backbuffer_image() const { + return swapchain_images[image_index]; } diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp index cfe8903..3cdd55d 100644 --- a/include/api-test/freelist.hpp +++ b/include/api-test/freelist.hpp @@ -18,7 +18,7 @@ class freelist { const auto id = free.back(); free.pop_back(); - items[id] = item; + items[id] = std::move(item); return id; } diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp index bd2274a..86eb22b 100644 --- a/include/api-test/vk-device-types.hpp +++ b/include/api-test/vk-device-types.hpp @@ -4,6 +4,8 @@ #include <span> +#include "freelist.hpp" + using VmaAllocation = struct VmaAllocation_T*; struct texture_desc { @@ -14,15 +16,21 @@ struct texture_desc { VkImageUsageFlags usages; VkFormat format; VkImageType type; + VkImage vk_image = nullptr; static constexpr auto max_mips = 16U; }; struct device_texture { + device_texture() = default; + device_texture(const texture_desc& desc); + + void create_views(); + VkImage vk_image; VkImageView whole_view; - VkImageView mips_views[texture_desc::max_mips] = { VK_NULL_HANDLE }; - VkImageLayout layout; + VkImageView mips_views[texture_desc::max_mips] = { nullptr }; + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; VkAccessFlags2 access = VK_ACCESS_2_NONE; VkFormat format; @@ -37,6 +45,10 @@ struct device_texture { uint32_t sampled_index = -1; VmaAllocation alloc; + +private: + static freelist<device_texture*> storage_indices; + static freelist<device_texture*> sampled_indices; }; struct buffer_desc { @@ -97,11 +109,12 @@ struct surface_desc { struct device_surface { VkSurfaceKHR vk_surface; VkSwapchainKHR vk_swapchain; + VkSurfaceFormatKHR surface_format; - // handle<device_texture> swapchain_images; + handle<device_texture> swapchain_images[surface_desc::max_image_count]; uint32_t image_index; uint32_t image_count; void acquire_image_index(handle<device_semaphore> signal_handle); - handle<device_texture> get_backbuffer_image(); + handle<device_texture> get_backbuffer_image() const; }; diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp index fd69d60..9e42b38 100644 --- a/include/api-test/vk-device.hpp +++ b/include/api-test/vk-device.hpp @@ -72,7 +72,7 @@ class vkdevice { return pipelines[handle.id]; } - [[nodiscard]] inline const device_surface& get_surface(handle<device_surface> handle) const { + [[nodiscard]] inline device_surface& get_surface(handle<device_surface> handle) { return surfaces[handle.id]; } @@ -88,6 +88,10 @@ class vkdevice { return device; } + inline VmaAllocator get_allocator() { + return gpu_allocator; + } + void wait(handle<device_semaphore> semaphore_handle); void submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle); @@ -102,8 +106,6 @@ class vkdevice { VkShaderModule create_shader_module(const std::span<uint8_t>& shader_code); - void create_views(const texture_desc& desc, device_texture& texture); - void create_swapchain(const surface_desc& desc, device_surface& surface); // TODO: Wrap in a struct called adapter ? @@ -134,9 +136,6 @@ class vkdevice { static constexpr size_t max_allocable_command_buffers = 16; static constexpr size_t max_submitable_command_buffers = 16; - freelist<device_texture*> storage_indices; - freelist<device_texture*> sampled_indices; - freelist<device_texture> textures; freelist<device_buffer> buffers; freelist<device_pipeline> pipelines; |
