diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2023-02-07 23:53:55 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2023-02-07 23:53:55 +0100 |
| commit | 74a223d1a9d23369c6c20457424b34cf17da95ab (patch) | |
| tree | 18ccf56b8ddc6274410150e7ad4b986e6cb7dbc5 | |
| parent | 9286a3db4f529f435ea4270ffc2ca7a7a1da922d (diff) | |
Remove presentation stuff from device class
Device instance is no more a pointer
Remove desc member in device structs
| -rw-r--r-- | api-test/command-buffer.cpp | 41 | ||||
| -rw-r--r-- | api-test/main.cpp | 62 | ||||
| -rw-r--r-- | api-test/vk-bindless.cpp | 20 | ||||
| -rw-r--r-- | api-test/vk-device.cpp | 381 | ||||
| -rw-r--r-- | include/api-test/command-buffer.hpp | 2 | ||||
| -rw-r--r-- | include/api-test/freelist.hpp | 12 | ||||
| -rw-r--r-- | include/api-test/handle.hpp | 6 | ||||
| -rw-r--r-- | include/api-test/vk-device-types.hpp | 85 | ||||
| -rw-r--r-- | include/api-test/vk-device.hpp | 123 |
9 files changed, 385 insertions, 347 deletions
diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp index 78b1505..79b8aef 100644 --- a/api-test/command-buffer.cpp +++ b/api-test/command-buffer.cpp @@ -18,7 +18,7 @@ void command_buffer::start() const { VKCHECK(vkBeginCommandBuffer(vk_command_buffer, &begin_info)); - const auto& bindless = vkdevice::get_render_device()->get_bindingmodel(); + const auto& bindless = vkdevice::get_render_device().get_bindingmodel(); const auto* global_set = &bindless.sets[BindlessSetType::GLOBAL]; if (queue_type == QueueType::GRAPHICS) { vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.layout, 0, 1U, global_set, 0U, nullptr); @@ -33,13 +33,10 @@ void command_buffer::stop() const { } void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const { - auto& texture = vkdevice::get_render_device()->get_texture(texture_handle); - VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) - ? VK_IMAGE_ASPECT_DEPTH_BIT - : VK_IMAGE_ASPECT_COLOR_BIT; + auto& texture = vkdevice::get_render_device().get_texture(texture_handle); VkImageSubresourceRange subresource_range{ - .aspectMask = aspect_mask, + .aspectMask = texture.aspects, .baseMipLevel = 0U, .levelCount = 1U, .baseArrayLayer = 0U, @@ -80,14 +77,12 @@ void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineSt } void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle, VkDeviceSize offset) const { - auto* device = vkdevice::get_render_device(); - const auto& buffer = device->get_buffer(buffer_handle); - const auto& texture = device->get_texture(texture_handle); - VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) - ? VK_IMAGE_ASPECT_DEPTH_BIT - : VK_IMAGE_ASPECT_COLOR_BIT; + auto& device = vkdevice::get_render_device(); + const auto& buffer = device.get_buffer(buffer_handle); + const auto& texture = device.get_texture(texture_handle); + VkImageSubresourceLayers image_subresource_layers{ - .aspectMask = aspect_mask, + .aspectMask = texture.aspects, .mipLevel = 0, .baseArrayLayer = 0, .layerCount = 1, @@ -100,9 +95,9 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t .imageSubresource = image_subresource_layers, .imageOffset = { .x = 0, .y = 0, .z = 0 }, .imageExtent = { - .width = texture.desc.width, - .height = texture.desc.height, - .depth = texture.desc.depth, + .width = texture.width, + .height = texture.height, + .depth = texture.depth, }, }; @@ -110,8 +105,8 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t } void graphics_command_buffer::dispatch(const dispatch_params& params) const { - const auto& pipeline = vkdevice::get_render_device()->get_pipeline(params.pipeline); - const auto& bindless = vkdevice::get_render_device()->get_bindingmodel(); + const auto& pipeline = vkdevice::get_render_device().get_pipeline(params.pipeline); + const auto& bindless = vkdevice::get_render_device().get_bindingmodel(); vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::INSTANCES_UNIFORMS), 1U, &bindless.sets[BindlessSetType::INSTANCES_UNIFORMS], 1U, ¶ms.uniforms_offset); vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::DRAWS_UNIFORMS), 1U, &bindless.sets[BindlessSetType::DRAWS_UNIFORMS], 1U, ¶ms.uniforms_offset); @@ -125,7 +120,7 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params) for (auto index{ 0U }; index < params.color_attachments.size(); index++) { auto& attachment_info = attachments_info[index]; - auto& attachment = vkdevice::get_render_device()->get_texture(params.color_attachments[index]); + auto& attachment = vkdevice::get_render_device().get_texture(params.color_attachments[index]); attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; attachment_info.pNext = nullptr; @@ -180,16 +175,16 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params) } void graphics_command_buffer::render(const draw_params& params) const { - auto* device = vkdevice::get_render_device(); - const auto& pipeline = device->get_pipeline(params.pipeline); + auto& device = vkdevice::get_render_device(); + const auto& pipeline = device.get_pipeline(params.pipeline); - const auto& bindless = device->get_bindingmodel(); + const auto& bindless = device.get_bindingmodel(); vkCmdBindDescriptorSets(vk_command_buffer, pipeline.bind_point, bindless.layout, static_cast<uint32_t>(BindlessSetType::DRAWS_UNIFORMS), 1U, &bindless.sets[BindlessSetType::DRAWS_UNIFORMS], 1U, ¶ms.uniforms_offset); vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline); if (params.index_buffer.is_valid()) { - const auto& index_buffer = device->get_buffer(params.index_buffer); + const auto& index_buffer = device.get_buffer(params.index_buffer); vkCmdBindIndexBuffer(vk_command_buffer, index_buffer.vk_buffer, 0U, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(vk_command_buffer, params.vertex_count, params.instance_count, params.index_offset, static_cast<int32_t>(params.vertex_offset), 0U); } else { diff --git a/api-test/main.cpp b/api-test/main.cpp index 7f30fda..807883d 100644 --- a/api-test/main.cpp +++ b/api-test/main.cpp @@ -9,6 +9,7 @@ #include "imgui.h" +#include "handle.hpp" #include "window.hpp" #include "vk-device.hpp" #include "utils.hpp" @@ -85,17 +86,28 @@ int main() { io.DisplaySize.x = 1024.f; io.DisplaySize.y = 1024.f; - auto* device = vkdevice::init_device(wnd); + auto& device = vkdevice::get_render_device(); + device.init(); + + 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, + }); constexpr size_t image_size = 1024U; constexpr size_t image_count = 4U; - auto staging_buffer_handle = device->create_buffer({ + auto staging_buffer_handle = device.create_buffer({ .size = image_size * image_size * sizeof(uint32_t) * image_count, .usages = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, }); - const auto& staging_buffer = device->get_buffer(staging_buffer_handle); + const auto& staging_buffer = device.get_buffer(staging_buffer_handle); int width; int height; @@ -104,7 +116,7 @@ int main() { size_t size = static_cast<size_t>(width) * height * 4U; memcpy(staging_buffer.mapped_ptr, data, size); - auto gpu_texture_handle = device->create_texture({ + auto gpu_texture_handle = device.create_texture({ .width = static_cast<uint32_t>(width), .height = static_cast<uint32_t>(height), .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, @@ -118,7 +130,7 @@ int main() { auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + offset); memcpy(addr, data, size); - auto second_texture = device->create_texture({ + auto second_texture = device.create_texture({ .width = static_cast<uint32_t>(width), .height = static_cast<uint32_t>(height), .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT, @@ -126,7 +138,7 @@ int main() { .type = VK_IMAGE_TYPE_2D, }); - auto output_texture_handle = device->create_texture({ + auto output_texture_handle = device.create_texture({ .width = static_cast<uint32_t>(width), .height = static_cast<uint32_t>(height), .usages = VK_IMAGE_USAGE_STORAGE_BIT, @@ -138,14 +150,14 @@ int main() { int atlas_width; int atlas_height; io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height); - const auto ui_texture_handle = device->create_texture({ + const auto ui_texture_handle = device.create_texture({ .width = static_cast<uint32_t>(atlas_width), .height = static_cast<uint32_t>(atlas_height), .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, .format = VK_FORMAT_R8G8B8A8_UNORM, .type = VK_IMAGE_TYPE_2D, }); - const auto& ui_texture = device->get_texture(ui_texture_handle); + const auto& ui_texture = device.get_texture(ui_texture_handle); io.Fonts->SetTexID(*(void **)&ui_texture_handle.id); off_t ui_offset = 2L * offset; @@ -153,38 +165,40 @@ int main() { addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + ui_offset); memcpy(addr, pixels, size); - auto vertex_buffer = device->get_buffer(device->create_buffer({ + auto vertex_buffer = device.get_buffer(device.create_buffer({ .size = 1024U * 1024U * sizeof(uint32_t), .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, })); - auto index_buffer_handle = device->create_buffer({ + auto index_buffer_handle = device.create_buffer({ .size = 1024U * 1024U * sizeof(uint32_t), .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, }); - auto index_buffer = device->get_buffer(index_buffer_handle); + auto index_buffer = device.get_buffer(index_buffer_handle); auto code = read_file("shaders/test.comp.spv"); - auto compute = device->create_pipeline({ + auto compute = device.create_pipeline({ .cs_code = code, }); std::array<VkFormat, 1U> formats { VK_FORMAT_R8G8B8A8_UNORM }; 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({ + auto graphics = device.create_pipeline({ .vs_code = vertex_code, .fs_code = fragment_code, .color_attachments_format = formats }); - auto semaphore = device->create_semaphore(); + auto semaphore = device.create_semaphore({ + .type = VK_SEMAPHORE_TYPE_TIMELINE, + }); std::array<graphics_command_buffer, 2U> command_buffers; - device->allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS); + device.allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS); RD_START_CAPTURE; @@ -205,11 +219,11 @@ int main() { uint32_t input2; uint32_t output; }; - const auto& uniform_buffer = device->get_bindingmodel().get_uniform_buffer(); + const auto& uniform_buffer = device.get_bindingmodel().get_uniform_buffer(); compute_params params { - device->get_texture(second_texture).storage_index, - device->get_texture(gpu_texture_handle).storage_index, - device->get_texture(output_texture_handle).storage_index, + device.get_texture(second_texture).storage_index, + device.get_texture(gpu_texture_handle).storage_index, + device.get_texture(output_texture_handle).storage_index, }; memcpy(uniform_buffer.mapped_ptr, ¶ms, sizeof(params)); @@ -225,7 +239,7 @@ int main() { command_buffers[0].stop(); std::array<struct command_buffer, 1U> compute_command_buffers = {command_buffers[0]}; - device->submit(compute_command_buffers, nullptr, &semaphore); + device.submit(compute_command_buffers, {}, semaphore); RD_END_CAPTURE; @@ -239,7 +253,7 @@ int main() { auto* draw_data = ImGui::GetDrawData(); update_buffers(draw_data, vertex_buffer, index_buffer); - device->wait(semaphore); + device.wait(semaphore); RD_START_CAPTURE; command_buffers[1].start(), @@ -261,8 +275,6 @@ int main() { uint32_t texture_index; }; - printf("%llu\n", sizeof(ImDrawVert)); - uint32_t draw_index = 0U; std::array<draw_params, 100U> draws; for (auto index {0U} ; index < draw_data->CmdListsCount; index++) { @@ -302,10 +314,8 @@ int main() { command_buffers[1].stop(); - device->submit(ui_command_buffers, nullptr, &semaphore); + device.submit(ui_command_buffers, {}, semaphore); RD_END_CAPTURE; - - break; } return 0; diff --git a/api-test/vk-bindless.cpp b/api-test/vk-bindless.cpp index 654ce0c..c48aea1 100644 --- a/api-test/vk-bindless.cpp +++ b/api-test/vk-bindless.cpp @@ -1,20 +1,20 @@ #include "vk-bindless.hpp" -#include <vma/vk_mem_alloc.h> +#include <vk_mem_alloc.h> #include "vk-device.hpp" #include "vk-utils.hpp" #include "vulkan-loader.hpp" const device_buffer& bindless_model::get_uniform_buffer() const { - auto* render_device = vkdevice::get_render_device(); - return render_device->get_buffer(draws_uniform_buffer_handle); + auto& render_device = vkdevice::get_render_device(); + return render_device.get_buffer(draws_uniform_buffer_handle); } bindless_model bindless_model::create_bindless_model() { bindless_model bindless; - auto* render_device = vkdevice::get_render_device(); - auto* device = render_device->get_device(); + auto& render_device = vkdevice::get_render_device(); + auto* device = render_device.get_device(); #ifndef USE_VK_DESCRIPTOR_BUFFER bindless.create_immutable_samplers(device); bindless.create_layout(device); @@ -24,14 +24,14 @@ bindless_model bindless_model::create_bindless_model() { VkWriteDescriptorSet writes_descriptor_set[2U]; { - bindless.instances_uniform_buffer_handle = render_device->create_buffer({ + bindless.instances_uniform_buffer_handle = render_device.create_buffer({ .size = instances_uniform_buffer_size, .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, }); - const auto& buffer = render_device->get_buffer(bindless.instances_uniform_buffer_handle); + const auto& buffer = render_device.get_buffer(bindless.instances_uniform_buffer_handle); VkDescriptorBufferInfo buffer_info { .buffer = buffer.vk_buffer, .offset = 0U, @@ -53,14 +53,14 @@ bindless_model bindless_model::create_bindless_model() { } { - bindless.draws_uniform_buffer_handle = render_device->create_buffer({ + bindless.draws_uniform_buffer_handle = render_device.create_buffer({ .size = draws_uniform_buffer_size, .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, }); - const auto& buffer = render_device->get_buffer(bindless.draws_uniform_buffer_handle); + const auto& buffer = render_device.get_buffer(bindless.draws_uniform_buffer_handle); VkDescriptorBufferInfo buffer_info { .buffer = buffer.vk_buffer, .offset = 0U, @@ -118,7 +118,7 @@ bindless_model bindless_model::create_bindless_model() { } void bindless_model::destroy_bindless_model(bindless_model& bindless) { - auto* device = vkdevice::get_render_device()->get_device(); + auto* device = vkdevice::get_render_device().get_device(); vkDestroyDescriptorPool(device, bindless.descriptor_pool, nullptr); for (auto index{ 0U }; index < BindlessSetType::MAX; index++) { diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp index 502143a..2258bdb 100644 --- a/api-test/vk-device.cpp +++ b/api-test/vk-device.cpp @@ -8,30 +8,26 @@ #include "vk-utils.hpp" #include "vulkan-loader.hpp" -#include "window.hpp" -vkdevice* vkdevice::render_device = nullptr; +vkdevice vkdevice::render_device = vkdevice(); + +void vkdevice::init() { + queues[0U] = { + .usages = VK_QUEUE_GRAPHICS_BIT | + VK_QUEUE_COMPUTE_BIT | + VK_QUEUE_TRANSFER_BIT, + }; + queues[1U] = { + .usages = VK_QUEUE_COMPUTE_BIT, + }; + queues[2U] = { + .usages = VK_QUEUE_TRANSFER_BIT, + }; -vkdevice::vkdevice(const window& window) - : queues{ - { - .usages = VK_QUEUE_GRAPHICS_BIT | - VK_QUEUE_COMPUTE_BIT | - VK_QUEUE_TRANSFER_BIT, - }, - { - .usages = VK_QUEUE_COMPUTE_BIT, - }, - { - .usages = VK_QUEUE_TRANSFER_BIT, - }, - } { load_vulkan(); create_instance(); - create_surface(window); - #ifdef _DEBUG create_debug_layer_callback(); #endif // _DEBUG @@ -40,41 +36,32 @@ vkdevice::vkdevice(const window& window) create_memory_allocator(); - create_swapchain(); - bindless = bindless_model::create_bindless_model(); } -vkdevice* vkdevice::init_device(const window& window) { - vkdevice::render_device = static_cast<vkdevice*>(malloc(sizeof(vkdevice))); - vkdevice::render_device = new (vkdevice::render_device) vkdevice(window); - return render_device; -} - -void vkdevice::free_device() { - delete render_device; - render_device = nullptr; -} - vkdevice::~vkdevice() { vkDeviceWaitIdle(device); bindless_model::destroy_bindless_model(bindless); - for (auto& texture : textures) { + for (const auto& texture : textures) { destroy_texture(texture); } - for (auto& buffer : buffers) { + for (const auto& buffer : buffers) { destroy_buffer(buffer); } - for (auto& pipeline : pipelines) { + for (const auto& pipeline : pipelines) { destroy_pipeline(pipeline); } - if (swapchain != nullptr) { - vkDestroySwapchainKHR(device, swapchain, nullptr); + for (const auto& semaphore : semaphores) { + destroy_semaphore(semaphore); + } + + for (const auto& surface : surfaces) { + destroy_surface(surface); } vmaDestroyAllocator(gpu_allocator); @@ -89,15 +76,15 @@ vkdevice::~vkdevice() { vkDestroyDebugUtilsMessengerEXT(instance, debug_messenger, nullptr); #endif // _DEBUG - if (surface != nullptr) { - vkDestroySurfaceKHR(instance, surface, nullptr); - } vkDestroyInstance(instance, nullptr); } handle<device_texture> vkdevice::create_texture(const texture_desc& desc) { device_texture device_texture{ - .desc = desc, + .format = desc.format, + .width = desc.width, + .height = desc.height, + .mips = desc.mips, }; assert(desc.mips <= texture_desc::max_mips); @@ -135,7 +122,11 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) { VKCHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &device_texture.vk_image, &device_texture.alloc, nullptr)); - create_views(device_texture); + 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[]{ @@ -187,7 +178,6 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) { handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) { device_buffer device_buffer{ - .desc = desc, }; VkBufferCreateInfo create_info{ @@ -234,29 +224,14 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) { handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) { device_pipeline device_pipeline{ - .desc = desc, }; if (!desc.cs_code.empty()) { - VkShaderModule shader_module; - { - const auto& code = desc.cs_code; - VkShaderModuleCreateInfo create_info{ - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .codeSize = code.size(), - .pCode = (uint32_t*)code.data(), - }; - - VKCHECK(vkCreateShaderModule(device, &create_info, nullptr, &shader_module)); - } - VkPipelineShaderStageCreateInfo stage_create_info{ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, .flags = 0U, .stage = VK_SHADER_STAGE_COMPUTE_BIT, - .module = shader_module, + .module = create_shader_module(desc.cs_code), .pName = "main", .pSpecializationInfo = nullptr, }; @@ -274,7 +249,7 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) { device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; VKCHECK(vkCreateComputePipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline)); - vkDestroyShaderModule(device, shader_module, nullptr); + vkDestroyShaderModule(device, stage_create_info.module, nullptr); } else { VkPipelineShaderStageCreateInfo shader_stages_create_info[2U]{ { @@ -282,6 +257,7 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) { .pNext = nullptr, .flags = 0U, .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = create_shader_module(desc.vs_code), .pName = "main", .pSpecializationInfo = nullptr, }, @@ -290,36 +266,12 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) { .pNext = nullptr, .flags = 0U, .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = create_shader_module(desc.fs_code), .pName = "main", .pSpecializationInfo = nullptr, }, }; - { - const auto& code = desc.vs_code; - VkShaderModuleCreateInfo module_create_info{ - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .codeSize = code.size(), - .pCode = (uint32_t*)code.data(), - }; - - VKCHECK(vkCreateShaderModule(device, &module_create_info, nullptr, &shader_stages_create_info[0U].module)); - } - { - const auto& code = desc.fs_code; - VkShaderModuleCreateInfo module_create_info{ - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .codeSize = code.size(), - .pCode = (uint32_t*)code.data(), - }; - - VKCHECK(vkCreateShaderModule(device, &module_create_info, nullptr, &shader_stages_create_info[1U].module)); - } - VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{ .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, }; @@ -431,20 +383,49 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) { device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; VKCHECK(vkCreateGraphicsPipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline)); + + for(auto& stage_create_info : shader_stages_create_info) { + vkDestroyShaderModule(device, stage_create_info.module, nullptr); + } } return { pipelines.add(device_pipeline) }; } -vksemaphore vkdevice::create_semaphore() { - vksemaphore semaphore{ - .value = 0, +handle<device_surface> vkdevice::create_surface(const surface_desc& desc) { + device_surface device_surface { + }; + + { + VkWin32SurfaceCreateInfoKHR create_info{ + .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0U, + .hinstance = GetModuleHandle(nullptr), + .hwnd = desc.window_handle, + }; + + VKCHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &device_surface.vk_surface)); + } + + 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) }; +} + +handle<device_semaphore> vkdevice::create_semaphore(const semaphore_desc& desc) { + device_semaphore semaphore { + .value = desc.initial_value, }; VkSemaphoreTypeCreateInfo semaphore_type_create_info{ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, .pNext = nullptr, .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, - .initialValue = 0U, + .initialValue = desc.initial_value, }; VkSemaphoreCreateInfo create_info{ @@ -455,7 +436,7 @@ vksemaphore vkdevice::create_semaphore() { VKCHECK(vkCreateSemaphore(device, &create_info, nullptr, &semaphore.vk_semaphore)); - return semaphore; + return { semaphores.add(semaphore) }; } void vkdevice::destroy_texture(const device_texture& texture) { @@ -495,7 +476,30 @@ void vkdevice::destroy_pipeline(handle<device_pipeline> handle) { vkDestroyPipeline(device, pipeline.vk_pipeline, nullptr); } -void vkdevice::wait(vksemaphore& semaphore) { +void vkdevice::destroy_semaphore(const device_semaphore& semaphore) { + destroy_semaphore({ .id = semaphores.find(semaphore)}); +} + +void vkdevice::destroy_semaphore(handle<device_semaphore> handle) { + auto& semaphore = vkdevice::get_semaphore(handle); + + vkDestroySemaphore(device, semaphore.vk_semaphore, nullptr); +} + +void vkdevice::destroy_surface(const device_surface& surface) { + destroy_surface({ .id = surfaces.find(surface)}); +} + +void vkdevice::destroy_surface(handle<device_surface> handle) { + const auto& surface = vkdevice::get_surface(handle); + + vkDestroySwapchainKHR(device, surface.vk_swapchain, nullptr); + + vkDestroySurfaceKHR(instance, surface.vk_surface, nullptr); +} + +void vkdevice::wait(handle<device_semaphore> semaphore_handle) { + const auto& semaphore = vkdevice::get_render_device().get_semaphore(semaphore_handle); VkSemaphoreWaitInfo wait_info { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, .pNext = nullptr, @@ -507,32 +511,10 @@ void vkdevice::wait(vksemaphore& semaphore) { VKCHECK(vkWaitSemaphores(device, &wait_info, -1)); } -void vkdevice::submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal) { -#define USE_SUBMIT2 +void vkdevice::submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle) { assert((max_submitable_command_buffers - buffers.size()) >= 0); const auto queue_type = buffers[0].queue_type; -#ifndef USE_SUBMIT2 - VkCommandBuffer to_submit[max_submitable_command_buffers]; - - for (auto index{ 0U }; index < count; index++) { - assert(queue_type == buffers[index].queue_type); - to_submit[index] = buffers[index].vk_command_buffer; - } - VkSubmitInfo submit_info{ - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = nullptr, - .waitSemaphoreCount = 0U, - .pWaitSemaphores = nullptr, - .pWaitDstStageMask = nullptr, - .commandBufferCount = static_cast<uint32_t>(count), - .pCommandBuffers = to_submit, - .signalSemaphoreCount = 0U, - .pSignalSemaphores = nullptr, - }; - - VKCHECK(vkQueueSubmit(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr)); -#else VkCommandBufferSubmitInfo command_buffers_info[buffers.size()]; for (auto index{ 0U }; index < buffers.size(); index++) { @@ -567,38 +549,44 @@ void vkdevice::submit(std::span<command_buffer> buffers, vksemaphore* wait, vkse .pCommandBufferInfos = command_buffers_info, }; - if (wait != nullptr) { - wait_semaphore_info.semaphore = wait->vk_semaphore; - wait_semaphore_info.value = wait->value; + if (wait_handle.is_valid()) { + const auto& wait = vkdevice::get_render_device().get_semaphore(wait_handle); + wait_semaphore_info.semaphore = wait.vk_semaphore; + wait_semaphore_info.value = wait.value; submit_info.waitSemaphoreInfoCount = 1U; submit_info.pWaitSemaphoreInfos = &wait_semaphore_info; } - if (signal != nullptr) { - signal_semaphore_info.semaphore = signal->vk_semaphore; - signal_semaphore_info.value = ++signal->value; + if (signal_handle.is_valid()) { + auto& signal = vkdevice::get_render_device().get_semaphore(signal_handle); + signal_semaphore_info.semaphore = signal.vk_semaphore; + signal_semaphore_info.value = ++signal.value; submit_info.signalSemaphoreInfoCount = 1U; submit_info.pSignalSemaphoreInfos = &signal_semaphore_info; } VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr)); -#endif } -void vkdevice::present(device_surface& surface, const vksemaphore& semaphore) { +void vkdevice::present(handle<device_surface> surface_handle, handle<device_semaphore> semaphore_handle) { + const auto& surface = vkdevice::get_render_device().get_surface(surface_handle); VkResult result; VkPresentInfoKHR present_info{ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .pNext = nullptr, - .waitSemaphoreCount = 1U, - .pWaitSemaphores = &semaphore.vk_semaphore, .swapchainCount = 1U, .pSwapchains = &surface.vk_swapchain, .pImageIndices = &surface.image_index, .pResults = &result, }; + if (semaphore_handle.is_valid()) { + const auto& semaphore = vkdevice::get_render_device().get_semaphore(semaphore_handle); + present_info.waitSemaphoreCount = 1U; + present_info.pWaitSemaphores = &semaphore.vk_semaphore; + } + VKCHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info)); VKCHECK(result); @@ -626,17 +614,29 @@ void vkdevice::allocate_command_buffers(command_buffer* buffers, size_t count, Q } } -void vkdevice::create_views(device_texture& texture) { - VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) - ? VK_IMAGE_ASPECT_DEPTH_BIT - : VK_IMAGE_ASPECT_COLOR_BIT; +VkShaderModule vkdevice::create_shader_module(const std::span<uint8_t>& shader_code) { + VkShaderModule shader_module; + const auto& code = shader_code; + VkShaderModuleCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .codeSize = code.size(), + .pCode = reinterpret_cast<uint32_t*>(code.data()), + }; + + VKCHECK(vkCreateShaderModule(device, &create_info, nullptr, &shader_module)); + 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.desc.format, + .format = texture.format, .components = { .r = VK_COMPONENT_SWIZZLE_R, .g = VK_COMPONENT_SWIZZLE_G, @@ -644,7 +644,7 @@ void vkdevice::create_views(device_texture& texture) { .a = VK_COMPONENT_SWIZZLE_A, }, .subresourceRange = { - .aspectMask = aspect_mask, + .aspectMask = texture.aspects, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, @@ -652,41 +652,32 @@ void vkdevice::create_views(device_texture& texture) { }, }; - for (auto mip_index{ 0 }; mip_index < texture.desc.mips; mip_index++) { + 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.desc.mips; + create_info.subresourceRange.levelCount = texture.mips; VKCHECK(vkCreateImageView(device, &create_info, nullptr, &texture.whole_view)); } -// Presentation stuff -void vkdevice::create_surface(const window& window) { - VkWin32SurfaceCreateInfoKHR create_info{ - .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, - .pNext = nullptr, - .flags = 0U, - .hinstance = GetModuleHandle(nullptr), - .hwnd = window.handle, - }; - - VKCHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &surface)); -} +void vkdevice::create_swapchain(const surface_desc& desc, device_surface& surface) { + VkSurfaceKHR vk_surface = surface.vk_surface; -void vkdevice::create_swapchain() { - VkBool32 supported = VK_FALSE; auto& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)]; - VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, surface, &supported)); - assert(supported); + { + VkBool32 supported = VK_FALSE; + VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, vk_surface, &supported)); + + assert(supported); + } - VkSurfaceCapabilitiesKHR surface_capabilities = {}; - VKCHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_capabilities)); + VkSurfaceCapabilitiesKHR surface_capabilities; + VKCHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, vk_surface, &surface_capabilities)); VkExtent2D extent = surface_capabilities.currentExtent; - if (extent.width < surface_capabilities.minImageExtent.width) { extent.width = surface_capabilities.minImageExtent.width; } else if (extent.width > surface_capabilities.maxImageExtent.width) { @@ -699,65 +690,68 @@ void vkdevice::create_swapchain() { extent.height = surface_capabilities.maxImageExtent.height; } - auto supported_formats_count = 0U; - VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &supported_formats_count, nullptr)); + { + auto supported = false; + auto supported_formats_count = 0U; + VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, nullptr)); - std::vector<VkSurfaceFormatKHR> supported_formats{ supported_formats_count }; - VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &supported_formats_count, supported_formats.data())); + std::vector<VkSurfaceFormatKHR> supported_formats{ supported_formats_count }; + VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, supported_formats.data())); + for (auto& surface_format : supported_formats) { + if (surface_format.format == desc.surface_format.format && + surface_format.colorSpace == desc.surface_format.colorSpace) { + supported = true; + break; + } + } + + assert(supported); + } + + { + auto supported = false; + auto supported_present_modes_count = 0U; + VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, nullptr)); - auto supported_present_modes_count = 0U; - VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &supported_present_modes_count, nullptr)); + std::vector<VkPresentModeKHR> supported_present_modes{ supported_present_modes_count }; + VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, supported_present_modes.data())); - std::vector<VkPresentModeKHR> supported_present_modes{ supported_present_modes_count }; + for (auto& present_mode : supported_present_modes) { + if (present_mode == desc.present_mode) { + supported = true; + break; + } + } - VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &supported_present_modes_count, supported_present_modes.data())); + assert(supported); + } - auto min_image_count = (surface_capabilities.minImageCount <= virtual_frames_count) ? virtual_frames_count : surface_capabilities.minImageCount; + assert(desc.image_count >= surface_capabilities.minImageCount); + assert(desc.image_count <= surface_capabilities.maxImageCount); VkSwapchainCreateInfoKHR create_info = { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, .pNext = nullptr, .flags = 0U, - .surface = surface, - .minImageCount = min_image_count, - .imageFormat = supported_formats[0].format, - .imageColorSpace = supported_formats[0].colorSpace, + .surface = vk_surface, + .minImageCount = desc.image_count, + .imageFormat = desc.surface_format.format, + .imageColorSpace = desc.surface_format.colorSpace, .imageExtent = extent, .imageArrayLayers = 1U, - .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .imageUsage = desc.usages, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 0U, .pQueueFamilyIndices = nullptr, .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = supported_present_modes[0], + .presentMode = desc.present_mode, .clipped = VK_TRUE, .oldSwapchain = nullptr, }; - VKCHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &swapchain)); -} - -void vkdevice::create_virtual_frames() { - for (auto index{ 0U }; index < virtual_frames_count; index++) { - { - VkSemaphoreTypeCreateInfo semaphore_type_create_info{ - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, - .pNext = nullptr, - .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, - .initialValue = 0U, - }; - - VkSemaphoreCreateInfo create_info{ - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .pNext = &semaphore_type_create_info, - .flags = 0U, - }; - - VKCHECK(vkCreateSemaphore(device, &create_info, nullptr, &semaphores[index])); - } - } + VKCHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &surface.vk_swapchain)); } // ----------------- vkadapter ----------------- @@ -989,3 +983,16 @@ void vkdevice::create_debug_layer_callback() { VKCHECK(vkCreateDebugUtilsMessengerEXT(instance, &create_info, nullptr, &debug_messenger)); } + + +void device_surface::acquire_image_index(handle<device_semaphore> signal_handle) { + auto& render_device = vkdevice::get_render_device(); + auto* device = render_device.get_device(); + const auto& signal = render_device.get_semaphore(signal_handle); + + vkAcquireNextImageKHR(device, vk_swapchain, -1, signal.vk_semaphore, nullptr, &image_index); +} + +handle<device_texture> device_surface::get_backbuffer_image() { + +} diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp index 31b1254..f7a18b0 100644 --- a/include/api-test/command-buffer.hpp +++ b/include/api-test/command-buffer.hpp @@ -40,8 +40,6 @@ private: public: rect render_area; std::span<handle<device_texture>> color_attachments; - // rect viewport; - // rect scissor; }; struct draw_params { handle<device_pipeline> pipeline; diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp index b231d9a..cfe8903 100644 --- a/include/api-test/freelist.hpp +++ b/include/api-test/freelist.hpp @@ -1,6 +1,7 @@ +#pragma once #include <numeric> #include <vector> - +#include <cassert> static constexpr uint32_t default_element_count = 1024U; @@ -27,6 +28,11 @@ class freelist { } T& operator[](uint32_t index) { + assert(index >= 0); + return items[index]; + } + + const T& operator[](uint32_t index) const { return items[index]; } @@ -41,11 +47,11 @@ class freelist { return invalid_id; } - auto begin() { + auto begin() const { return items.begin(); } - auto end() { + auto end() const { return items.end(); } diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp index 956739d..a81480a 100644 --- a/include/api-test/handle.hpp +++ b/include/api-test/handle.hpp @@ -4,9 +4,9 @@ template<typename T> struct handle { - uint32_t id = handle::invalid_handle; + uint32_t id = handle::invalid_id; - [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_handle; } + [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_id; } - static constexpr uint32_t invalid_handle = -1; + static constexpr uint32_t invalid_id = -1U; }; diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp index b069883..bd2274a 100644 --- a/include/api-test/vk-device-types.hpp +++ b/include/api-test/vk-device-types.hpp @@ -4,18 +4,16 @@ #include <span> -#include "vk-bindless.hpp" - using VmaAllocation = struct VmaAllocation_T*; struct texture_desc { - uint32_t width = 1U; - uint32_t height = 1U; - uint32_t depth = 1U; - uint32_t mips = 1U; - VkImageUsageFlags usages; - VkFormat format; - VkImageType type; + uint32_t width = 1U; + uint32_t height = 1U; + uint32_t depth = 1U; + uint32_t mips = 1U; + VkImageUsageFlags usages; + VkFormat format; + VkImageType type; static constexpr auto max_mips = 16U; }; @@ -25,24 +23,27 @@ struct device_texture { VkImageView whole_view; VkImageView mips_views[texture_desc::max_mips] = { VK_NULL_HANDLE }; VkImageLayout layout; - VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkAccessFlags2 access = VK_ACCESS_2_NONE; + VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkAccessFlags2 access = VK_ACCESS_2_NONE; + VkFormat format; + VkImageAspectFlags aspects; + + uint32_t width = 1U; + uint32_t height = 1U; + uint32_t depth = 1U; + uint32_t mips = 1U; uint32_t storage_index = -1; uint32_t sampled_index = -1; - uint32_t sampler_index = -1; VmaAllocation alloc; - - texture_desc desc; }; - struct buffer_desc { - size_t size; - VkBufferUsageFlags usages; - VkMemoryPropertyFlags memory_properties; - uint32_t memory_usage; + size_t size; + VkBufferUsageFlags usages; + VkMemoryPropertyFlags memory_properties; + uint32_t memory_usage; }; struct device_buffer { @@ -50,37 +51,57 @@ struct device_buffer { VmaAllocation alloc; VkDeviceAddress device_address = 0U; void* mapped_ptr; - - buffer_desc desc; + size_t size; }; struct pipeline_desc { - std::span<uint8_t> vs_code; - std::span<uint8_t> fs_code; - std::span<uint8_t> cs_code; + std::span<uint8_t> cs_code; + std::span<uint8_t> vs_code; + std::span<uint8_t> fs_code; std::span<VkFormat> color_attachments_format; - VkFormat depth_attachment_format; - VkFormat stencil_attachment_format; + VkFormat depth_attachment_format; + VkFormat stencil_attachment_format; }; struct device_pipeline { VkPipeline vk_pipeline; VkPipelineBindPoint bind_point; - pipeline_desc desc; +}; - // bindless_model* bindless = nullptr; + +struct semaphore_desc { + VkSemaphoreType type; + uint64_t initial_value = 0U; +}; + +struct device_semaphore { + VkSemaphore vk_semaphore = nullptr; + uint64_t value; }; +typedef struct HWND__* HWND; + struct surface_desc { + HWND window_handle; + VkSurfaceFormatKHR surface_format; + VkPresentModeKHR present_mode; + VkImageUsageFlags usages; + uint32_t image_count = surface_desc::default_image_count; + static constexpr uint32_t max_image_count = 3U; + static constexpr uint32_t default_image_count = 3U; }; struct device_surface { - VkSurfaceKHR vk_surface; - VkSwapchainKHR vk_swapchain; + VkSurfaceKHR vk_surface; + VkSwapchainKHR vk_swapchain; + + // handle<device_texture> swapchain_images; + uint32_t image_index; + uint32_t image_count; - handle<device_texture> swapchain_images; - uint32_t image_index; + void acquire_image_index(handle<device_semaphore> signal_handle); + handle<device_texture> get_backbuffer_image(); }; diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp index 5b71529..fd69d60 100644 --- a/include/api-test/vk-device.hpp +++ b/include/api-test/vk-device.hpp @@ -15,11 +15,6 @@ using VmaAllocator = struct VmaAllocator_T*; class window; -struct vksemaphore { - VkSemaphore vk_semaphore = nullptr; - uint64_t value = 0U; -}; - class vkdevice { struct queue { VkQueue vk_queue; @@ -29,49 +24,63 @@ class vkdevice { }; public: - static vkdevice* init_device(const window& window); + void init(); - static void free_device(); - - static inline vkdevice* get_render_device() { + static inline vkdevice& get_render_device() { return render_device; } - handle<device_texture> create_texture(const texture_desc& desc); + handle<device_texture> create_texture(const texture_desc& desc); + + handle<device_buffer> create_buffer(const buffer_desc& desc); - handle<device_buffer> create_buffer(const buffer_desc& desc); + handle<device_pipeline> create_pipeline(const pipeline_desc& desc); - handle<device_pipeline> create_pipeline(const pipeline_desc& desc); + handle<device_surface> create_surface(const surface_desc& desc); - vksemaphore create_semaphore(); + handle<device_semaphore> create_semaphore(const semaphore_desc& desc); - void destroy_texture(const device_texture& texture); - void destroy_texture(handle<device_texture> handle); + void destroy_texture(const device_texture& texture); + void destroy_texture(handle<device_texture> handle); - void destroy_buffer(const device_buffer& buffer); - void destroy_buffer(handle<device_buffer> handle); + void destroy_buffer(const device_buffer& buffer); + void destroy_buffer(handle<device_buffer> handle); - void destroy_pipeline(const device_pipeline& pipeline); - void destroy_pipeline(handle<device_pipeline> handle); + void destroy_pipeline(const device_pipeline& pipeline); + void destroy_pipeline(handle<device_pipeline> handle); + + void destroy_semaphore(const device_semaphore& semaphore); + void destroy_semaphore(handle<device_semaphore> handle); + + void destroy_surface(const device_surface& surface); + void destroy_surface(handle<device_surface> handle); template<typename cmd_buf_type> void allocate_command_buffers(cmd_buf_type* buffers, size_t count, QueueType queue_type) { allocate_command_buffers(static_cast<command_buffer*>(buffers), count, queue_type); } - inline device_texture& get_texture(handle<device_texture> handle) { + [[nodiscard]] inline device_texture& get_texture(handle<device_texture> handle) { return textures[handle.id]; } - inline const device_buffer& get_buffer(handle<device_buffer> handle) { + [[nodiscard]] inline const device_buffer& get_buffer(handle<device_buffer> handle) const { return buffers[handle.id]; } - inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) { + [[nodiscard]] inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) const { return pipelines[handle.id]; } - inline const bindless_model& get_bindingmodel() { + [[nodiscard]] inline const device_surface& get_surface(handle<device_surface> handle) const { + return surfaces[handle.id]; + } + + [[nodiscard]] inline device_semaphore& get_semaphore(handle<device_semaphore> handle) { + return semaphores[handle.id]; + } + + [[nodiscard]] inline const bindless_model& get_bindingmodel() const { return bindless; } @@ -79,70 +88,62 @@ class vkdevice { return device; } - void wait(vksemaphore& semaphore); + void wait(handle<device_semaphore> semaphore_handle); - void submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal); + void submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle); - void present(device_surface& surface, const vksemaphore& semaphore); + void present(handle<device_surface> surface_handle, handle<device_semaphore> semaphore_handle); private: - vkdevice(const window& window); + vkdevice() = default; ~vkdevice(); void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type); - void create_views(device_texture& texture); + VkShaderModule create_shader_module(const std::span<uint8_t>& shader_code); - // Presentation stuff - void create_surface(const window& window); + void create_views(const texture_desc& desc, device_texture& texture); - void create_swapchain(); - - void create_virtual_frames(); - - VkSurfaceKHR surface = nullptr; - VkSwapchainKHR swapchain = nullptr; + void create_swapchain(const surface_desc& desc, device_surface& surface); // TODO: Wrap in a struct called adapter ? - void create_instance(); - - void create_device(); + void create_instance(); - void create_memory_allocator(); + void create_device(); - void create_command_pools(); + void create_memory_allocator(); - void pick_physical_device(); + void create_command_pools(); - static bool device_support_features(VkPhysicalDevice physical_dev); + void pick_physical_device(); - void create_debug_layer_callback(); + static bool device_support_features(VkPhysicalDevice physical_dev); - // Virtual frames resources - static constexpr uint32_t virtual_frames_count = 3U; - VkSemaphore semaphores[virtual_frames_count]; + void create_debug_layer_callback(); - queue queues[static_cast<uint32_t>(QueueType::MAX)]; + queue queues[static_cast<uint32_t>(QueueType::MAX)]; - VkInstance instance; - VkPhysicalDevice physical_device; - VkDevice device; + VkInstance instance; + VkPhysicalDevice physical_device; + VkDevice device; - VmaAllocator gpu_allocator; + VmaAllocator gpu_allocator; - bindless_model bindless; + bindless_model bindless; - static constexpr size_t max_allocable_command_buffers = 16; - static constexpr size_t max_submitable_command_buffers = 16; + 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*> storage_indices; + freelist<device_texture*> sampled_indices; - freelist<device_texture> textures; - freelist<device_buffer> buffers; - freelist<device_pipeline> pipelines; + freelist<device_texture> textures; + freelist<device_buffer> buffers; + freelist<device_pipeline> pipelines; + freelist<device_surface> surfaces; + freelist<device_semaphore> semaphores; - static vkdevice* render_device; + static vkdevice render_device; #ifdef _DEBUG VkDebugUtilsMessengerEXT debug_messenger; |
