diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9b30e58 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/launch.json b/.vscode/launch.json index 2320da7..dd72174 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/RayTracer", "args": [], "stopAtEntry": false, - "cwd": "${fileDirname}", + "cwd": "${workspaceFolder}/build", "environment": [], "externalConsole": false, "MIMode": "lldb" diff --git a/res/.DS_Store b/res/.DS_Store new file mode 100644 index 0000000..3ad73d8 Binary files /dev/null and b/res/.DS_Store differ diff --git a/src/gpu/GPURenderer.cpp b/src/gpu/GPURenderer.cpp index 047c346..7edf934 100644 --- a/src/gpu/GPURenderer.cpp +++ b/src/gpu/GPURenderer.cpp @@ -1,4 +1,8 @@ #include "GPURenderer.h" +#include "vulkan/vulkan_enums.hpp" +#include "vulkan/vulkan_handles.hpp" +#include "vulkan/vulkan_raii.hpp" +#include "vulkan/vulkan_structs.hpp" #include #include #define VMA_IMPLEMENTATION @@ -63,7 +67,6 @@ void GPURenderer::createDevice() allocatorCreateInfo.instance = *instance; allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions; - VmaAllocator allocator; vmaCreateAllocator(&allocatorCreateInfo, &allocator); } @@ -71,10 +74,6 @@ void GPURenderer::createCommands() { vk::CommandPoolCreateInfo commandPoolCreateInfo({}, computeQueueFamily); cmdPool = CommandPool(device, commandPoolCreateInfo); - - // allocate a CommandBuffer from the CommandPool - vk::CommandBufferAllocateInfo commandBufferAllocateInfo(cmdPool, vk::CommandBufferLevel::ePrimary, 10); - cmdBuffers = vk::raii::CommandBuffers(device, commandBufferAllocateInfo); } void GPURenderer::createDescriptors() @@ -121,6 +120,14 @@ void GPURenderer::createDescriptors() vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo({}, bindings); descriptorLayout = DescriptorSetLayout(device, descriptorSetLayoutCreateInfo); + auto descriptorPoolSizes = { +vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1), +vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1), +vk::DescriptorPoolSize(vk::DescriptorType::eStorageImage, 2), +vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 8), + }; + descriptorPool = DescriptorPool(device, vk::DescriptorPoolCreateInfo({}, 4, descriptorPoolSizes)); + // create a PipelineLayout using that DescriptorSetLayout vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo({}, *descriptorLayout); pipelineLayout = PipelineLayout(device, pipelineLayoutCreateInfo); @@ -307,7 +314,10 @@ void GPURenderer::render(Camera cam, RenderParameter param) .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &radianceAccumulator, &radianceAllocation, nullptr); + VkImage radianceImg; + vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &radianceImg, &radianceAllocation, nullptr); + radianceAccumulator = Image(device, radianceImg); + radianceView = device.createImageView(vk::ImageViewCreateInfo({}, *radianceAccumulator, vk::ImageViewType::e2D, vk::Format::eR32G32B32A32Sfloat)); } // image { @@ -333,6 +343,98 @@ void GPURenderer::render(Camera cam, RenderParameter param) .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &image, &imageAllocation, nullptr); + VkImage img; + vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &img, &imageAllocation, nullptr); + image = Image(device, img); + radianceView = device.createImageView(vk::ImageViewCreateInfo({}, *image, vk::ImageViewType::e2D, vk::Format::eR32G32B32A32Sfloat)); + } + + DescriptorSet descriptorSet = std::move(device.allocateDescriptorSets(vk::DescriptorSetAllocateInfo(*descriptorPool, *descriptorLayout)).front()); + std::vector writes; + // have to use lists so the pointers arent invalidated by push + std::list buffers; + std::list accel; + std::list images; + uint32_t bindingCounter = 0; + { + buffers.push_back(vk::DescriptorBufferInfo(cameraBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &buffers.back(), nullptr)); + } + { + accel.push_back(vk::WriteDescriptorSetAccelerationStructureKHR(1, scene->accelerationStructure)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eAccelerationStructureKHR, nullptr, nullptr, nullptr, &accel.back())); + } + { + images.push_back(vk::DescriptorImageInfo({}, radianceView, vk::ImageLayout::eGeneral)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageImage, &images.back(), nullptr, nullptr)); + } + { + images.push_back(vk::DescriptorImageInfo({}, imageView, vk::ImageLayout::eGeneral)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageImage, &images.back(), nullptr, nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->modelBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->materialBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->positionsBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->texCoordsBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->normalsBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->directionalLightsBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->pointLightsBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + { + buffers.push_back(vk::DescriptorBufferInfo(scene->indexBuffer)); + writes.push_back(vk::WriteDescriptorSet(*descriptorSet, bindingCounter++, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &buffers.back(), nullptr)); + } + device.updateDescriptorSets(writes, {}); + + semaphores.resize(param.numSamples); + fences.resize(param.numSamples); + for (uint32_t samp = 0; samp < param.numSamples; ++samp) + { + semaphores[samp] = device.createSemaphore(vk::SemaphoreCreateInfo()); + fences[samp] = device.createFence(vk::FenceCreateInfo()); + } + // allocate a CommandBuffer from the CommandPool + vk::CommandBufferAllocateInfo commandBufferAllocateInfo(*cmdPool, vk::CommandBufferLevel::ePrimary, param.numSamples); + cmdBuffers = CommandBuffers(device, commandBufferAllocateInfo); + for (uint32_t samp = 0; samp < param.numSamples; ++samp) + { + auto& cmd = cmdBuffers[samp]; + cmd.begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit)); + cmd.bindPipeline(vk::PipelineBindPoint::eRayTracingKHR, *pipeline); + cmd.bindDescriptorSets(vk::PipelineBindPoint::eRayTracingKHR, pipelineLayout, 0, descriptorSet, {}); + cmd.traceRays(param.width, param.height, 1); + cmd.end(); + if (samp == 0) + { + queue.submit(vk::SubmitInfo({}, cmd, semaphores[samp]), fences[samp]); + } + else + { + queue.submit(vk::SubmitInfo(semaphores[samp-1], vk::PipelineStageFlagBits::eRayTracingShaderKHR, cmd, semaphores[samp]), fences[samp]); + } + } + for (uint32_t samp = 0; samp < param.numSamples; ++samp) + { + device.waitForFences(fences[samp], true, 1000000); } } \ No newline at end of file diff --git a/src/gpu/GPURenderer.h b/src/gpu/GPURenderer.h index cc4fcc6..20d355b 100644 --- a/src/gpu/GPURenderer.h +++ b/src/gpu/GPURenderer.h @@ -1,4 +1,5 @@ #pragma once +#include "gpu/GPUScene.h" #include "scene/Renderer.h" #include #include @@ -29,6 +30,8 @@ private: void createDescriptors(); void createShaders(); + std::unique_ptr scene; + Context context; Instance instance; PhysicalDevice physicalDevice; @@ -39,6 +42,8 @@ private: uint32_t computeQueueFamily; CommandPool cmdPool; CommandBuffers cmdBuffers; + std::vector semaphores; + std::vector fences; DescriptorSetLayout descriptorLayout; DescriptorSet descriptorSet; @@ -51,13 +56,15 @@ private: Pipeline pipeline; - VkBuffer cameraBuffer; + Buffer cameraBuffer; VmaAllocation cameraAllocation; - VkImage radianceAccumulator; + Image radianceAccumulator; + ImageView radianceView; VmaAllocation radianceAllocation; - VkImage image; + Image image; + ImageView imageView; VmaAllocation imageAllocation; virtual void render(Camera cam, RenderParameter param); diff --git a/src/gpu/GPUScene.cpp b/src/gpu/GPUScene.cpp index 0c6c25e..7cd6a4a 100644 --- a/src/gpu/GPUScene.cpp +++ b/src/gpu/GPUScene.cpp @@ -96,7 +96,7 @@ void GPUScene::generate() }; buildRangePointers[i] = &buildRanges[i]; } - vk::CommandBufferAllocateInfo commandBufferAllocateInfo(cmdPool, vk::CommandBufferLevel::ePrimary, 10); + vk::CommandBufferAllocateInfo commandBufferAllocateInfo(*cmdPool, vk::CommandBufferLevel::ePrimary, 10); CommandBuffer cmdBuffer = std::move(CommandBuffers(device, commandBufferAllocateInfo).front()); vk::FenceCreateInfo fenceCreateInfo; Fence fence = Fence(device, fenceCreateInfo); @@ -104,8 +104,8 @@ void GPUScene::generate() cmdBuffer.buildAccelerationStructuresKHR(buildGeometries, buildRangePointers); cmdBuffer.end(); vk::SubmitInfo submitInfo; - queue.submit(submitInfo, fence); - assert(device.waitForFences({fence}, true, 1000000) == VK_SUCCESS); + queue.submit(submitInfo, *fence); + assert(device.waitForFences({*fence}, true, 1000000) == vk::Result::eSuccess); } void GPUScene::createStorageBuffer(VkBuffer& buffer, VmaAllocation& alloc, void* data, size_t size) diff --git a/src/gpu/GPUScene.h b/src/gpu/GPUScene.h index 0af28f8..ea03328 100644 --- a/src/gpu/GPUScene.h +++ b/src/gpu/GPUScene.h @@ -57,4 +57,5 @@ private: VkBuffer indexBuffer; VmaAllocation indexAllocation; + friend class GPURenderer; }; \ No newline at end of file