From c892cc73f911aa4d634af0225b4b3c6a43ecb906 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Sun, 27 Dec 2020 23:46:43 +0100 Subject: Usable compute pipeline with input buffer + mem allocator --- src/main.cpp | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 162 insertions(+), 13 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 86556f2..37aebd2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,10 @@ #include #include "vulkan-loader.hpp" + +#define VMA_IMPLEMENTATION +#include "thirdparty/vk_mem_alloc.h" + #include "rt.hpp" #include "hittable_list.hpp" @@ -207,7 +211,9 @@ void create_device() { std::cerr << "Device ready" << std::endl; } -VkPipeline compute_pipeline; +VkPipeline compute_pipeline = nullptr; +VkDescriptorSetLayout compute_shader_input_layout = nullptr; +VkPipelineLayout compute_pipeline_layout = nullptr; void create_pipeline() { std::vector shader_code = get_shader_code("./shaders/compute.comp.spv"); if (shader_code.size() == 0) { @@ -234,8 +240,9 @@ void create_pipeline() { stage_create_info.pSpecializationInfo = nullptr; VkDescriptorSetLayoutBinding binding = {}; - binding.binding = 1; + binding.binding = 0; binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + binding.descriptorCount = 1; binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; binding.pImmutableSamplers = 0; @@ -246,27 +253,25 @@ void create_pipeline() { descriptor_set_layout_create_info.bindingCount = 1; descriptor_set_layout_create_info.pBindings = &binding; - VkDescriptorSetLayout layout; - vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, &layout); + vkCreateDescriptorSetLayout(device, &descriptor_set_layout_create_info, nullptr, &compute_shader_input_layout); VkPipelineLayoutCreateInfo layout_create_info = {}; layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layout_create_info.pNext = nullptr; layout_create_info.flags = 0; layout_create_info.setLayoutCount = 1; - layout_create_info.pSetLayouts = &layout; + layout_create_info.pSetLayouts = &compute_shader_input_layout; layout_create_info.pushConstantRangeCount = 0; layout_create_info.pPushConstantRanges = nullptr; - VkPipelineLayout pipeline_layout; - vkCreatePipelineLayout(device, &layout_create_info, nullptr, &pipeline_layout); + vkCreatePipelineLayout(device, &layout_create_info, nullptr, &compute_pipeline_layout); VkComputePipelineCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; create_info.pNext = nullptr; create_info.flags = 0; create_info.stage = stage_create_info; - create_info.layout = pipeline_layout; + create_info.layout = compute_pipeline_layout; vkCreateComputePipelines( device, @@ -280,10 +285,142 @@ void create_pipeline() { std::cerr << "Compute pipeline ready" << std::endl; } +VmaAllocator allocator = nullptr; +void create_memory_allocator() { + VmaAllocatorCreateInfo allocator_info = {}; + allocator_info.vulkanApiVersion = VK_API_VERSION_1_2; + allocator_info.physicalDevice = physical_device; + allocator_info.device = device; + allocator_info.instance = instance; + + vmaCreateAllocator(&allocator_info, &allocator); +} + +VkCommandPool command_pool = nullptr; +VkCommandBuffer cmd_buf = nullptr; +void create_command_buffer() { + VkCommandPoolCreateInfo cmd_pool_create_info = {}; + cmd_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmd_pool_create_info.pNext = nullptr; + cmd_pool_create_info.flags = 0; + cmd_pool_create_info.queueFamilyIndex = compute_queue_index; + + vkCreateCommandPool(device, &cmd_pool_create_info, nullptr, &command_pool); + + VkCommandBufferAllocateInfo cmd_buf_allocate_info = {}; + cmd_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + cmd_buf_allocate_info.pNext = nullptr; + cmd_buf_allocate_info.commandPool = command_pool; + cmd_buf_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmd_buf_allocate_info.commandBufferCount = 1; + + vkAllocateCommandBuffers(device, &cmd_buf_allocate_info, &cmd_buf); +} + +VkDescriptorPool descriptor_pool = nullptr; +VkDescriptorSet compute_shader_input_set = nullptr; +void create_descriptor_set() { + VkDescriptorPoolSize descriptor_pool_size = {}; + descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptor_pool_size.descriptorCount = 1; + + VkDescriptorPoolCreateInfo descriptor_pool_create_info = {}; + descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptor_pool_create_info.pNext = nullptr; + descriptor_pool_create_info.flags = 0; + descriptor_pool_create_info.maxSets = 1; + descriptor_pool_create_info.poolSizeCount = 1; + descriptor_pool_create_info.pPoolSizes = &descriptor_pool_size; + + vkCreateDescriptorPool(device, &descriptor_pool_create_info, nullptr, &descriptor_pool); + + VkDescriptorSetAllocateInfo descriptor_set_allocate_info = {}; + descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptor_set_allocate_info.pNext = nullptr; + descriptor_set_allocate_info.descriptorPool = descriptor_pool; + descriptor_set_allocate_info.descriptorSetCount = 1; + descriptor_set_allocate_info.pSetLayouts = &compute_shader_input_layout; + + vkAllocateDescriptorSets(device, &descriptor_set_allocate_info, &compute_shader_input_set); +} + +VkBuffer compute_shader_input_buffer; +void fill_descriptor_set() { + VkBufferCreateInfo buffer_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + buffer_info.size = 65536; + buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + VmaAllocationCreateInfo alloc_create_info = {}; + alloc_create_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; + alloc_create_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + + VmaAllocation allocation; + vmaCreateBuffer(allocator, &buffer_info, &alloc_create_info, &compute_shader_input_buffer, &allocation, nullptr); + + vec3 sphere_position = {}; + void* mappedData; + vmaMapMemory(allocator, allocation, &mappedData); + memcpy(mappedData, &sphere_position, sizeof(vec3)); + vmaUnmapMemory(allocator, allocation); + + VkDescriptorBufferInfo descriptor_buf_info = {}; + descriptor_buf_info.buffer = compute_shader_input_buffer; + descriptor_buf_info.offset = 0; + descriptor_buf_info.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet write_descriptor_set = {}; + write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set.pNext = nullptr; + write_descriptor_set.dstSet = compute_shader_input_set; + write_descriptor_set.dstBinding = 0; + write_descriptor_set.dstArrayElement = 0; + write_descriptor_set.descriptorCount = 1; + write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor_set.pImageInfo = nullptr; + write_descriptor_set.pBufferInfo = &descriptor_buf_info; + write_descriptor_set.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(device, 1, &write_descriptor_set, 0, nullptr); +} + void init_vk() { create_instance(); create_device(); create_pipeline(); + create_command_buffer(); + create_descriptor_set(); + create_memory_allocator(); + fill_descriptor_set(); +} + +void compute() { + VkCommandBufferBeginInfo cmd_buf_begin_info = {}; + cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmd_buf_begin_info.pNext = nullptr; + cmd_buf_begin_info.flags = 0; + cmd_buf_begin_info.pInheritanceInfo = nullptr; + + vkBeginCommandBuffer(cmd_buf, &cmd_buf_begin_info); + + vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline_layout, 0, 1, &compute_shader_input_set, 0, nullptr); + + vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline); + + vkCmdDispatch(cmd_buf, 1, 1, 1); + + vkEndCommandBuffer(cmd_buf); + + VkSubmitInfo submit_info = {}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = nullptr; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = nullptr; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &cmd_buf; + + vkQueueSubmit(compute_queue, 1, &submit_info, VK_NULL_HANDLE); } int main() { @@ -294,8 +431,9 @@ int main() { const double aspect_ratio = 16.0 / 9.0; const size_t width = 1920; const size_t height = width / aspect_ratio; - const uint32_t samples_per_pixel = 1000; + const uint32_t samples_per_pixel = 1; const uint32_t max_depth = 100; + std::vector> image { height, std::vector { width, color {} } }; const vec3 camera_position{ 13.0, 2.0, 3.0 }; const vec3 camera_target{ 0.0, 0.0, 0.0 }; @@ -307,13 +445,24 @@ int main() { hittable_list world = random_scene(); // PPM format header - // std::cout << "P3\n" << width << '\n' << height << "\n 255" << std::endl; + std::cout << "P3\n" << width << '\n' << height << "\n 255" << std::endl; + + std::cerr << "Generating image" << std::endl; + + compute(); - // std::cerr << "Generating image" << std::endl; + //------------------------- + // GPU path tracer + //------------------------- + for (ssize_t row = height - 1; row >= 0; row--) { + for (size_t column = 0; column < width; column++) { + write_color(std::cout, image[row][column], samples_per_pixel); + } + } - // -------------------------- + //--------------------------- // CPU path tracer loop - // ------------------------- + //-------------------------- // for (ssize_t row = height - 1; row >= 0; row--) { // std::cerr << row << " lines remaining" << std::endl; // for (size_t column = 0; column < width; column++) { -- cgit v1.3