diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libs.cpp | 1 | ||||
| -rw-r--r-- | src/main.cpp | 23 | ||||
| -rw-r--r-- | src/vk-command-buffer.cpp | 19 | ||||
| -rw-r--r-- | src/vk-device.cpp | 443 |
4 files changed, 228 insertions, 258 deletions
diff --git a/src/libs.cpp b/src/libs.cpp index 1b2bf9c..83aec5b 100644 --- a/src/libs.cpp +++ b/src/libs.cpp @@ -13,5 +13,6 @@ #include <stb_image.h> #define VK_NO_PROTOTYPES +#define VMA_VULKAN_VERSION 1004000 #define VMA_IMPLEMENTATION #include <vk_mem_alloc.h> diff --git a/src/main.cpp b/src/main.cpp index d0e50c5..6b1cae3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -244,6 +244,7 @@ int main() { .usages = D3D12_RESOURCE_FLAG_NONE, .heap_type = D3D12_HEAP_TYPE_UPLOAD, #endif + .name = "staging buffer", }); const device_buffer* staging_buffer = render_device.get_buffer(staging_buffer_handle); @@ -297,7 +298,6 @@ int main() { .cs_code_size = tonemapping_code_size, }); - std::array<VkFormat, 1U> formats { surface->surface_format.format }; size_t vertex_code_size = 0U; uint8_t* vertex_code = read_file("shaders/api-test-ui.vert.spv", &vertex_code_size); size_t fragment_code_size = 0U; @@ -307,8 +307,8 @@ int main() { .vs_code_size = vertex_code_size, .fs_code = fragment_code, .fs_code_size = fragment_code_size, - .color_attachments_format = formats.data(), - .color_attachments_format_count = formats.size() + .color_attachments_format = surface->surface_format.format, + .color_attachments_format_count = 1U }); size_t transmittance_lut_code_size = 0U; @@ -328,12 +328,12 @@ int main() { int channels; uint8_t* data = stbi_load("../models/sponza/466164707995436622.jpg", &image_width, &image_height, &channels, 4); size_t size = static_cast<size_t>(image_width) * image_height * 4U; - memcpy(staging_buffer->mapped_ptr, data, size); + memcpy(staging_buffer->cpu_ptr, data, size); off_t buffer_offset = image_width * image_height * 4; data = stbi_load("../models/sponza/715093869573992647.jpg", &image_width, &image_height, &channels, 4); size = static_cast<size_t>(image_width) * image_height * 4U; - auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer->mapped_ptr) + buffer_offset); + auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer->cpu_ptr) + buffer_offset); memcpy(addr, data, size); u8 *pixels = nullptr; @@ -343,7 +343,7 @@ int main() { off_t ui_offset = 2L * buffer_offset; size = static_cast<size_t>(atlas_width) * atlas_height * 4U; - addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer->mapped_ptr) + ui_offset); + addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer->cpu_ptr) + ui_offset); memcpy(addr, pixels, size); @@ -468,7 +468,7 @@ int main() { io.Fonts->SetTexID(reinterpret_cast<void*>(static_cast<uintptr_t>(ui_texture->get_sampled_index()))); - handle<device_sampler> default_sampler = vkdevice::get().create_sampler(sampler_desc{ + handle<void> default_sampler = vkdevice::get().create_sampler(sampler_desc{ .mag_filter = VK_FILTER_LINEAR, .min_filter = VK_FILTER_LINEAR, .address_mode_u = VK_SAMPLER_ADDRESS_MODE_REPEAT, @@ -670,18 +670,17 @@ int main() { ImDrawList* cmd_list = draw_data->CmdLists[index]; size_t vertex_bytes_size = sizeof(ImDrawVert) * cmd_list->VtxBuffer.size(); - u8* vtx_ptr = static_cast<uint8_t*>(vertex_buffer->mapped_ptr) + vertex_offset; + u8* vtx_ptr = static_cast<uint8_t*>(vertex_buffer->cpu_ptr) + vertex_offset; memcpy(vtx_ptr, cmd_list->VtxBuffer.Data, vertex_bytes_size); vertex_offset += static_cast<off_t>(vertex_bytes_size); size_t index_bytes_size = sizeof(ImDrawIdx) * cmd_list->IdxBuffer.size(); - memcpy(static_cast<uint8_t*>(index_buffer->mapped_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size); + memcpy(static_cast<uint8_t*>(index_buffer->cpu_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size); index_offset += static_cast<off_t>(index_bytes_size); } } - // TODO: Refactor backbuffer acquisition - auto backbuffer = surface->swapchain_images[render_device.acquire_image_index(surface_handle)]; + handle<device_texture> backbuffer = render_device.get_swapchain_image(surface_handle); color_attachment[0] = backbuffer; // RD_START_CAPTURE; @@ -775,7 +774,7 @@ int main() { // u32 texture_index; // u32 padding; } ui_param = { - .vertex_buffer = vertex_buffer->device_address, + .vertex_buffer = vertex_buffer->gpu_ptr, // .scale { // 2.f / draw_data->DisplaySize.x, // 2.f / draw_data->DisplaySize.y, diff --git a/src/vk-command-buffer.cpp b/src/vk-command-buffer.cpp index 6b1f271..8c4ca19 100644 --- a/src/vk-command-buffer.cpp +++ b/src/vk-command-buffer.cpp @@ -13,14 +13,13 @@ void command_buffer::start() const { { device_buffer* image_heap_buffer = vkdevice::get().get_buffer(image_heap); - VkDeviceAddressRangeEXT heap_range { - .address = image_heap_buffer->device_address, - .size = image_heap_buffer->size, - }; VkBindHeapInfoEXT bind_heap_info = { .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT, .pNext = nullptr, - .heapRange = heap_range, + .heapRange = { + .address = image_heap_buffer->gpu_ptr, + .size = image_heap_buffer->size, + }, .reservedRangeOffset = image_heap_buffer->size - descriptor_heap_props.minResourceHeapReservedRange, .reservedRangeSize = descriptor_heap_props.minResourceHeapReservedRange, }; @@ -31,15 +30,13 @@ void command_buffer::start() const { { device_buffer* sampler_heap_buffer = vkdevice::get().get_buffer(sampler_heap); - VkDeviceAddressRangeEXT heap_range { - .address = sampler_heap_buffer->device_address, - .size = sampler_heap_buffer->size, - }; - VkBindHeapInfoEXT sampler_bind_heap_info = { .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT, .pNext = nullptr, - .heapRange = heap_range, + .heapRange = { + .address = sampler_heap_buffer->gpu_ptr, + .size = sampler_heap_buffer->size, + }, .reservedRangeOffset = sampler_heap_buffer->size - descriptor_heap_props.minSamplerHeapReservedRange, .reservedRangeSize = descriptor_heap_props.minSamplerHeapReservedRange, }; diff --git a/src/vk-device.cpp b/src/vk-device.cpp index c35ea05..f35d02b 100644 --- a/src/vk-device.cpp +++ b/src/vk-device.cpp @@ -2,6 +2,7 @@ #include "vk-device-types.hpp" #include "vulkan-loader.hpp" +#define VMA_VULKAN_VERSION 1004000 #include <vk_mem_alloc.h> @@ -15,6 +16,8 @@ static constexpr size_t max_samplers_count = 16U; static constexpr size_t storage_images_offset = 0U; static constexpr size_t sampled_images_offset = max_images_count / 2U; +static idlist<> sampler_list; + // TODO: Dont use handle for internally used resources handle<device_buffer> image_heap; handle<device_buffer> sampler_heap; @@ -25,14 +28,6 @@ VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptor_heap_props { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT, }; -struct physical_device_features { - VkPhysicalDeviceFeatures2 physical_device_features2; - VkPhysicalDeviceVulkan12Features physical_device_12_features; - VkPhysicalDeviceVulkan13Features physical_device_13_features; - VkPhysicalDeviceVulkan14Features physical_device_14_features; - VkPhysicalDeviceDescriptorHeapFeaturesEXT descriptor_heap_features; - VkPhysicalDeviceShaderUntypedPointersFeaturesKHR shader_untyped_pointers_features; -}; static void create_heaps(size_t max_images, size_t max_samplers) { // create image heap @@ -43,8 +38,7 @@ static void create_heaps(size_t max_images, size_t max_samplers) { image_heap = vkdevice::get().create_buffer({ .size = descriptor_heap_props.minResourceHeapReservedRange + ALIGN(max_images * descriptor_heap_props.imageDescriptorSize, alignment), - .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT | - VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | + .usages = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_TRANSFER_DST_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | @@ -57,8 +51,7 @@ static void create_heaps(size_t max_images, size_t max_samplers) { { sampler_heap = vkdevice::get().create_buffer({ .size = descriptor_heap_props.minSamplerHeapReservedRange + ALIGN(max_samplers * descriptor_heap_props.samplerDescriptorSize, descriptor_heap_props.samplerDescriptorAlignment), - .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT | - VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | + .usages = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_TRANSFER_DST_BIT, .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .memory_usage = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | @@ -212,23 +205,51 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) { return textures.add(device_texture); } -handle<device_sampler> vkdevice::create_sampler(const sampler_desc& desc) { - device_sampler device_sampler; - device_sampler.init(desc); +//TODO: Hash sampler parameters into an index and remove sampler list +handle<void> vkdevice::create_sampler(const sampler_desc& desc) { + handle<void> sampler_index = sampler_list.add(); + + VkSamplerCreateInfo sampler_create_info{ + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .magFilter = desc.mag_filter, + .minFilter = desc.min_filter, + .mipmapMode = desc.mipmap_mode, + .addressModeU = desc.address_mode_u, + .addressModeV = desc.address_mode_v, + .addressModeW = desc.address_mode_w, + .mipLodBias = desc.mip_lod_bias, + .anisotropyEnable = desc.anisotropy, + .maxAnisotropy = desc.max_anisotropy, + .compareEnable = desc.compare_enabled, + .compareOp = desc.compare_op, + .minLod = desc.min_lod, + .maxLod = desc.max_lod, + .borderColor = desc.border_color, + .unnormalizedCoordinates = desc.unnomalized_coords, + }; - return samplers.add(device_sampler); + device_buffer* sampler_heap_buffer = render_device.get_buffer(sampler_heap); + + VkHostAddressRangeEXT destination_address { + .address = ((u8*)sampler_heap_buffer->cpu_ptr) + descriptor_heap_props.samplerDescriptorSize * sampler_index.id, + .size = descriptor_heap_props.samplerDescriptorSize, + }; + VK_CHECK(vkWriteSamplerDescriptorsEXT(device, 1U, &sampler_create_info, &destination_address)); + + return sampler_index; } handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) { device_buffer device_buffer{ .size = desc.size, - .usages = desc.usages, .name = desc.name, }; VkBufferUsageFlags2CreateInfo usage_flags2 { .sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR, - .usage = desc.usages, + .usage = desc.usages | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, }; VkBufferCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -237,21 +258,12 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) { .size = desc.size, .usage = 0U, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, }; - VmaAllocatorCreateFlags alloc_create_flags = - desc.memory_usage != VMA_MEMORY_USAGE_GPU_ONLY ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0U; - VmaAllocationCreateInfo alloc_create_info{ - .flags = alloc_create_flags, + .flags = desc.memory_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0U, .usage = static_cast<VmaMemoryUsage>(desc.memory_usage), .requiredFlags = desc.memory_properties, - .preferredFlags = 0U, - .memoryTypeBits = 0U, - .pool = nullptr, - .pUserData = nullptr, }; VmaAllocationInfo alloc_info{ @@ -271,16 +283,17 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) { vkSetDebugUtilsObjectNameEXT(device, &object_name); } - if ((desc.usages & VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT) != 0U) { + // get BDA + { VkBufferDeviceAddressInfo address_info { .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .pNext = nullptr, .buffer = device_buffer.vk_buffer, }; - device_buffer.device_address = vkGetBufferDeviceAddress(device, &address_info); + device_buffer.gpu_ptr = vkGetBufferDeviceAddress(device, &address_info); } - device_buffer.mapped_ptr = alloc_info.pMappedData; + device_buffer.cpu_ptr = alloc_info.pMappedData; return buffers.add(device_buffer); } @@ -386,9 +399,15 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli .pDynamicStates = dynamic_states, }; + VkPipelineCreateFlags2CreateInfo create_flags2 { + .sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO, + .pNext = nullptr, + .flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT, + }; + VkPipelineRenderingCreateInfo pipeline_rendering_create_info{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .pNext = nullptr, + .pNext = &create_flags2, .viewMask = 0U, .colorAttachmentCount = static_cast<uint32_t>(desc.color_attachments_format_count), .pColorAttachmentFormats = desc.color_attachments_format, @@ -396,15 +415,9 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli .stencilAttachmentFormat = VK_FORMAT_UNDEFINED, }; - VkPipelineCreateFlags2CreateInfo create_flags2 { - .sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO, - .pNext = &pipeline_rendering_create_info, - .flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT, - }; - VkGraphicsPipelineCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &create_flags2, + .pNext = &pipeline_rendering_create_info, .flags = 0U, .stageCount = sizeof(shader_stages_create_info) / sizeof(VkPipelineShaderStageCreateInfo), .pStages = shader_stages_create_info, @@ -417,7 +430,7 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli .pDepthStencilState = nullptr, .pColorBlendState = &color_blend_state_create_info, .pDynamicState = &dynamic_state_create_info, - // .layout = bindless.global_layout, + .layout = nullptr, .renderPass = nullptr, .subpass = 0U, .basePipelineHandle = nullptr, @@ -510,7 +523,122 @@ handle<device_surface> vkdevice::create_surface(const surface_desc& desc) { VK_CHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &device_surface.vk_surface)); } - create_swapchain(desc, device_surface); + // swapchain creation + { + struct queue& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)]; + + { + VkBool32 supported = VK_FALSE; + VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, device_surface.vk_surface, &supported)); + + assert(supported); + } + + VkSurfaceCapabilitiesKHR surface_capabilities; + VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, device_surface.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) { + extent.width = surface_capabilities.maxImageExtent.width; + } + + if (extent.height < surface_capabilities.minImageExtent.height) { + extent.height = surface_capabilities.minImageExtent.height; + } else if (extent.height > surface_capabilities.maxImageExtent.height) { + extent.height = surface_capabilities.maxImageExtent.height; + } + + // check swapchain format is supported + { + bool supported = false; + u32 supported_formats_count = 0U; + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, device_surface.vk_surface, &supported_formats_count, nullptr)); + + VkSurfaceFormatKHR* supported_formats = static_cast<VkSurfaceFormatKHR*>(_malloca(supported_formats_count * sizeof(VkSurfaceFormatKHR))); + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, device_surface.vk_surface, &supported_formats_count, supported_formats)); + + for (u32 format_index = 0U; format_index < supported_formats_count; format_index++) { + VkSurfaceFormatKHR surface_format = supported_formats[format_index]; + if (surface_format.format == desc.surface_format.format && + surface_format.colorSpace == desc.surface_format.colorSpace) { + supported = true; + break; + } + } + + assert(supported); + } + + // check swapchain present mode is supported + { + bool supported = false; + u32 supported_present_modes_count = 0U; + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, device_surface.vk_surface, &supported_present_modes_count, nullptr)); + + VkPresentModeKHR* supported_present_modes = static_cast<VkPresentModeKHR*>(_malloca(supported_present_modes_count * sizeof(VkPresentModeKHR))); + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, device_surface.vk_surface, &supported_present_modes_count, supported_present_modes)); + + for (u32 present_mode_index = 0U; present_mode_index < supported_present_modes_count; present_mode_index++) { + VkPresentModeKHR present_mode = supported_present_modes[present_mode_index]; + if (present_mode == desc.present_mode) { + supported = true; + break; + } + } + + assert(supported); + } + + 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 = device_surface.vk_surface, + .minImageCount = desc.image_count, + .imageFormat = desc.surface_format.format, + .imageColorSpace = desc.surface_format.colorSpace, + .imageExtent = extent, + .imageArrayLayers = 1U, + .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 = desc.present_mode, + .clipped = VK_TRUE, + .oldSwapchain = nullptr, + }; + + VK_CHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &device_surface.vk_swapchain)); + + device_surface.surface_format = desc.surface_format; + + vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, nullptr); + assert(device_surface.image_count <= surface_desc::max_image_count); + + VkImage* images = static_cast<VkImage*>(_malloca(device_surface.image_count * sizeof(VkImage))); + vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, images); + + for (u32 index = 0U; index < device_surface.image_count; index++) { + device_surface.swapchain_images[index] = create_texture({ + .width = extent.width, + .height = extent.height, + .depth = 1U, + .mips = 1U, + .usages = desc.usages, + .format = desc.surface_format.format, + .type = VK_IMAGE_TYPE_2D, + .vk_image = images[index], + .name = "swapchain image" + }); + } + } assert(surface_desc::max_image_count >= device_surface.image_count); @@ -533,7 +661,23 @@ handle<device_surface> vkdevice::create_surface(const surface_desc& desc) { void vkdevice::destroy_texture(handle<device_texture> handle) { device_texture* texture = get_texture(handle); - texture->release(); + vmaDestroyImage(gpu_allocator, texture->vk_image, texture->alloc); + + vkDestroyImageView(device, texture->whole_view, nullptr); + + for (u32 mip_index = 0U; mip_index < texture->mips; mip_index++) { + const auto& mip_view = texture->mips_views[mip_index]; + vkDestroyImageView(device, mip_view, nullptr); + } + + if (texture->storage_index.is_valid()) { + device_texture::storage_indices.remove(texture->storage_index); + } + + if (texture->sampled_index.is_valid()) { + device_texture::sampled_indices.remove(texture->sampled_index); + } + textures.remove(handle); } @@ -677,24 +821,19 @@ uint64_t vkdevice::submit_before_present(handle<device_surface> surface_handle, void vkdevice::present(handle<device_surface> surface_handle) { device_surface* surface = render_device.get_surface(surface_handle); - VkResult result; + const device_semaphore& semaphore = surface->submit_semaphores[surface->frame_index]; 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, + .pResults = nullptr, }; - const device_semaphore& semaphore = surface->submit_semaphores[surface->frame_index]; - present_info.waitSemaphoreCount = 1U; - present_info.pWaitSemaphores = &semaphore.vk_semaphore; - VK_CHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info)); - - VK_CHECK(result); - surface->frame_index = (surface->frame_index + 1) % surface->image_count; } // private @@ -730,122 +869,6 @@ void vkdevice::allocate_command_buffers(command_buffer* cmd_buffers, size_t coun } } -void vkdevice::create_swapchain(const surface_desc& desc, device_surface& surface) { - VkSurfaceKHR vk_surface = surface.vk_surface; - - auto& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)]; - - { - VkBool32 supported = VK_FALSE; - VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, vk_surface, &supported)); - - assert(supported); - } - - VkSurfaceCapabilitiesKHR surface_capabilities; - VK_CHECK(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) { - extent.width = surface_capabilities.maxImageExtent.width; - } - - if (extent.height < surface_capabilities.minImageExtent.height) { - extent.height = surface_capabilities.minImageExtent.height; - } else if (extent.height > surface_capabilities.maxImageExtent.height) { - extent.height = surface_capabilities.maxImageExtent.height; - } - - { - bool supported = false; - u32 supported_formats_count = 0U; - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, nullptr)); - - VkSurfaceFormatKHR* supported_formats = static_cast<VkSurfaceFormatKHR*>(_malloca(supported_formats_count * sizeof(VkSurfaceFormatKHR))); - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, supported_formats)); - - for (u32 format_index = 0U; format_index < supported_formats_count; format_index++) { - VkSurfaceFormatKHR surface_format = supported_formats[format_index]; - if (surface_format.format == desc.surface_format.format && - surface_format.colorSpace == desc.surface_format.colorSpace) { - supported = true; - break; - } - } - - assert(supported); - } - - { - bool supported = false; - u32 supported_present_modes_count = 0U; - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, nullptr)); - - VkPresentModeKHR* supported_present_modes = static_cast<VkPresentModeKHR*>(_malloca(supported_present_modes_count * sizeof(VkPresentModeKHR))); - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, supported_present_modes)); - - for (u32 present_mode_index = 0U; present_mode_index < supported_present_modes_count; present_mode_index++) { - VkPresentModeKHR present_mode = supported_present_modes[present_mode_index]; - if (present_mode == desc.present_mode) { - supported = true; - break; - } - } - - assert(supported); - } - - 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 = vk_surface, - .minImageCount = desc.image_count, - .imageFormat = desc.surface_format.format, - .imageColorSpace = desc.surface_format.colorSpace, - .imageExtent = extent, - .imageArrayLayers = 1U, - .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 = desc.present_mode, - .clipped = VK_TRUE, - .oldSwapchain = nullptr, - }; - - VK_CHECK(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); - - VkImage* images = static_cast<VkImage*>(_malloca(surface.image_count * sizeof(VkImage))); - vkGetSwapchainImagesKHR(device, surface.vk_swapchain, &surface.image_count, images); - - for (u32 index = 0U; index < surface.image_count; index++) { - surface.swapchain_images[index] = create_texture({ - .width = extent.width, - .height = extent.height, - .depth = 1U, - .mips = 1U, - .usages = desc.usages, - .format = desc.surface_format.format, - .type = VK_IMAGE_TYPE_2D, - .vk_image = images[index], - .name = "swapchain image" - }); - } -} - // ----------------- vkadapter ----------------- void vkdevice::create_instance() { @@ -855,7 +878,7 @@ void vkdevice::create_instance() { .applicationVersion = VK_MAKE_VERSION(1, 0, 0), .pEngineName = "gpu-path-tracer", .engineVersion = VK_MAKE_VERSION(1, 0, 0), - .apiVersion = VK_API_VERSION_1_3, + .apiVersion = VK_API_VERSION_1_4, }; const char* instance_layers[]{ @@ -885,8 +908,14 @@ void vkdevice::create_instance() { } void vkdevice::create_device() { - // pick physical device - struct physical_device_features features = { + struct physical_device_features { + VkPhysicalDeviceFeatures2 physical_device_features2; + VkPhysicalDeviceVulkan12Features physical_device_12_features; + VkPhysicalDeviceVulkan13Features physical_device_13_features; + VkPhysicalDeviceVulkan14Features physical_device_14_features; + VkPhysicalDeviceDescriptorHeapFeaturesEXT descriptor_heap_features; + VkPhysicalDeviceShaderUntypedPointersFeaturesKHR shader_untyped_pointers_features; + } features = { .physical_device_features2 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, .pNext = &features.physical_device_12_features, @@ -1040,7 +1069,7 @@ void vkdevice::create_device() { .device = device, .pVulkanFunctions = &functions, .instance = instance, - .vulkanApiVersion = VK_API_VERSION_1_2, + .vulkanApiVersion = VK_API_VERSION_1_4, }; VK_CHECK(vmaCreateAllocator(&allocator_create_info, &gpu_allocator)); @@ -1052,7 +1081,6 @@ void vkdevice::create_device() { idlist<> device_texture::sampled_indices = {}; idlist<> device_texture::storage_indices = {}; -idlist<> device_sampler::sampler_indices = {}; void device_texture::init(const texture_desc& desc) { auto& render_device = vkdevice::get(); @@ -1104,6 +1132,8 @@ void device_texture::init(const texture_desc& desc) { VK_CHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &vk_image, &alloc, nullptr)); vmaSetAllocationName(gpu_allocator, alloc, desc.name); + + assert(alloc != nullptr); } if (desc.name) { @@ -1176,7 +1206,7 @@ void device_texture::init(const texture_desc& desc) { strg_index++; storage_index = storage_indices.add(); resources_address[descriptors_count] = { - .address = ((u8*)image_heap_buffer->mapped_ptr) + descriptor_heap_props.imageDescriptorSize * (strg_index + storage_images_offset), + .address = ((u8*)image_heap_buffer->cpu_ptr) + descriptor_heap_props.imageDescriptorSize * (strg_index + storage_images_offset), .size = descriptor_heap_props.imageDescriptorSize, }; @@ -1196,7 +1226,7 @@ void device_texture::init(const texture_desc& desc) { smpl_index++; sampled_index = sampled_indices.add(); resources_address[descriptors_count] = { - .address = ((u8*)image_heap_buffer->mapped_ptr) + descriptor_heap_props.imageDescriptorSize * (smpl_index + sampled_images_offset), + .address = ((u8*)image_heap_buffer->cpu_ptr) + descriptor_heap_props.imageDescriptorSize * (smpl_index + sampled_images_offset), .size = descriptor_heap_props.imageDescriptorSize, }; @@ -1206,71 +1236,14 @@ void device_texture::init(const texture_desc& desc) { VK_CHECK(vkWriteResourceDescriptorsEXT(device, static_cast<uint32_t>(descriptors_count), resource_descriptor_infos, resources_address)); } -void device_texture::release() { - if (alloc != nullptr) { - vmaDestroyImage(gpu_allocator, vk_image, alloc); - } - - vkDestroyImageView(device, whole_view, nullptr); - - for (auto mip_index{ 0U }; mip_index < mips; mip_index++) { - const auto& mip_view = mips_views[mip_index]; - vkDestroyImageView(device, mip_view, nullptr); - } - - if (storage_index.is_valid()) { - storage_indices.remove(storage_index); - } - - if (sampled_index.is_valid()) { - sampled_indices.remove(sampled_index); - } -} - void device_texture::create_views() { } +handle<device_texture> vkdevice::get_swapchain_image(handle<device_surface> surface_handle) { + device_surface* surface = get_surface(surface_handle); -void device_sampler::init(const sampler_desc& desc) { - vkdevice& render_device = vkdevice::get(); - - VkSamplerCreateInfo sampler_create_info{ - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = nullptr, - .flags = 0U, - .magFilter = desc.mag_filter, - .minFilter = desc.min_filter, - .mipmapMode = desc.mipmap_mode, - .addressModeU = desc.address_mode_u, - .addressModeV = desc.address_mode_v, - .addressModeW = desc.address_mode_w, - .mipLodBias = desc.mip_lod_bias, - .anisotropyEnable = desc.anisotropy, - .maxAnisotropy = desc.max_anisotropy, - .compareEnable = desc.compare_enabled, - .compareOp = desc.compare_op, - .minLod = desc.min_lod, - .maxLod = desc.max_lod, - .borderColor = desc.border_color, - .unnormalizedCoordinates = desc.unnomalized_coords, - }; - - VK_CHECK(vkCreateSampler(device, &sampler_create_info, nullptr, &vk_sampler)); - - sampler_index = sampler_indices.add(); - - device_buffer* sampler_heap_buffer = render_device.get_buffer(sampler_heap); - - VkHostAddressRangeEXT destination_address { - .address = ((u8*)sampler_heap_buffer->mapped_ptr) + descriptor_heap_props.samplerDescriptorSize * sampler_index.id, - .size = descriptor_heap_props.samplerDescriptorSize, - }; - VK_CHECK(vkWriteSamplerDescriptorsEXT(device, 1U, &sampler_create_info, &destination_address)); -} - + surface->frame_index = (surface->frame_index + 1U) % surface->image_count; -uint32_t vkdevice::acquire_image_index(handle<device_surface> surface_handle) { - device_surface* surface = get_surface(surface_handle); const device_semaphore& signal = surface->acquire_semaphores[surface->frame_index]; VkSemaphoreWaitInfo wait_info { @@ -1284,5 +1257,5 @@ uint32_t vkdevice::acquire_image_index(handle<device_surface> surface_handle) { vkWaitSemaphores(device, &wait_info, UINT64_MAX); VK_CHECK(vkAcquireNextImageKHR(device, surface->vk_swapchain, UINT64_MAX, signal.vk_semaphore, nullptr, &surface->image_index)); - return surface->image_index; + return surface->swapchain_images[surface->image_index]; } |
