From b756f17a094c00f8f7506787ccfd3ebea9463f05 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 12 Jul 2024 22:05:52 +0200 Subject: [PATCH] Adding barriers --- src/Engine/Graphics/Vulkan/Graphics.cpp | 24 +++++- src/Engine/Graphics/Vulkan/Graphics.h | 1 + src/Engine/Graphics/Vulkan/PipelineCache.cpp | 85 ++++++++++---------- src/Engine/Graphics/Vulkan/RayTracing.cpp | 31 +++++-- src/Engine/Graphics/Vulkan/RayTracing.h | 9 ++- 5 files changed, 97 insertions(+), 53 deletions(-) diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 366a721..4b4d2b1 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -39,6 +39,7 @@ PFN_vkGetAccelerationStructureBuildSizesKHR getAccelerationStructureBuildSize; PFN_vkCreateRayTracingPipelinesKHR createRayTracingPipelines; PFN_vkGetRayTracingShaderGroupHandlesKHR getRayTracingShaderGroupHandles; PFN_vkCmdTraceRaysKHR cmdTraceRays; +PFN_vkGetAccelerationStructureDeviceAddressKHR getAccelerationStructureDeviceAddress; void vkCmdDrawMeshTasksEXT(VkCommandBuffer command, uint32 groupX, uint32 groupY, uint32 groupZ) { cmdDrawMeshTasks(command, groupX, groupY, groupZ); @@ -92,6 +93,10 @@ void vkCmdTraceRaysKHR(VkCommandBuffer commandBuffer, const VkStridedDeviceAddre width, height, depth); } +VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo) { + return getAccelerationStructureDeviceAddress(device, pInfo); +} + Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {} Graphics::~Graphics() { @@ -399,6 +404,13 @@ void Graphics::buildBottomLevelAccelerationStructures(Array OBufferAllocation transformBuffer = new BufferAllocation(this, "TransformBuffer", transformBufferInfo, transformAllocInfo, Gfx::QueueType::GRAPHICS); transformBuffer->updateContents(0, sizeof(VkTransformMatrixKHR) * matrices.size(), matrices.data()); + transformBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT); + positionBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); + indexBuffer->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); Array geometries(data.size()); Array buildGeometries(data.size()); @@ -656,7 +668,7 @@ void Graphics::setupDebugCallback() { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, .pNext = nullptr, .flags = 0, - .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, .pfnUserCallback = &debugCallback, @@ -725,6 +737,7 @@ void Graphics::pickPhysicalDevice() { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .pNext = &meshShaderFeatures, .storageBuffer8BitAccess = true, + .uniformAndStorageBuffer8BitAccess = true, .shaderUniformBufferArrayNonUniformIndexing = true, .shaderSampledImageArrayNonUniformIndexing = true, .shaderStorageBufferArrayNonUniformIndexing = true, @@ -735,9 +748,14 @@ void Graphics::pickPhysicalDevice() { .runtimeDescriptorArray = true, .bufferDeviceAddress = true, }; + features11 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + .pNext = &features12, + .uniformAndStorageBuffer16BitAccess = true, + }; features = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, - .pNext = &features12, + .pNext = &features11, .features = { .fillModeNonSolid = true, @@ -883,4 +901,6 @@ void Graphics::createDevice(GraphicsInitializer initializer) { getRayTracingShaderGroupHandles = (PFN_vkGetRayTracingShaderGroupHandlesKHR)vkGetDeviceProcAddr(handle, "vkGetRayTracingShaderGroupHandlesKHR"); cmdTraceRays = (PFN_vkCmdTraceRaysKHR)vkGetDeviceProcAddr(handle, "vkCmdTraceRaysKHR"); + getAccelerationStructureDeviceAddress = + (PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureDeviceAddressKHR"); } diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index e3ab4a9..c386cdf 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -113,6 +113,7 @@ class Graphics : public Gfx::Graphics { VkQueueFamilyProperties graphicsProps; VkPhysicalDeviceProperties2 props; VkPhysicalDeviceFeatures2 features; + VkPhysicalDeviceVulkan11Features features11; VkPhysicalDeviceVulkan12Features features12; VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures; VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationFeatures; diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index 4435a0d..dff9eca 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -610,47 +610,6 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI std::memcpy(rayGenSbt.data(), sbt.data(), handleSize); std::memcpy(rayGenSbt.data() + handleSize, createInfo.rayGenGroup.parameters.data(), createInfo.rayGenGroup.parameters.size()); - uint64 sbtOffset = handleSizeAligned; - - uint32 maxParamSize = 0; - for (auto& hitgroup : createInfo.hitGroups) { - maxParamSize = std::max(maxParamSize, hitgroup.parameters.size()); - } - uint64 hitStride = align(handleSize + maxParamSize, handleAlignment); - Array hitSbt(hitStride * createInfo.hitGroups.size()); - for (uint64 i = 0; i < createInfo.hitGroups.size(); ++i) { - std::memcpy(hitSbt.data() + i * hitStride, sbt.data() + sbtOffset, handleSize); - std::memcpy(hitSbt.data() + i * hitStride + handleSize, createInfo.hitGroups[i].parameters.data(), - createInfo.hitGroups[i].parameters.size()); - sbtOffset += handleSizeAligned; - } - - maxParamSize = 0; - for (auto& missGroup : createInfo.missGroups) { - maxParamSize = std::max(maxParamSize, missGroup.parameters.size()); - } - uint64 missStride = align(handleSize + maxParamSize, handleAlignment); - Array missSbt(missStride * createInfo.missGroups.size()); - for (uint64 i = 0; i < createInfo.missGroups.size(); ++i) { - std::memcpy(missSbt.data() + i * missStride, sbt.data() + sbtOffset, handleSize); - std::memcpy(missSbt.data() + i * missStride + handleSize, createInfo.missGroups[i].parameters.data(), - createInfo.missGroups[i].parameters.size()); - sbtOffset += handleSizeAligned; - } - - maxParamSize = 0; - for (auto& callableGroup : createInfo.callableGroups) { - maxParamSize = std::max(maxParamSize, callableGroup.parameters.size()); - } - uint64 callableStride = align(handleSize + maxParamSize, handleAlignment); - Array callableSbt(callableStride * createInfo.callableGroups.size()); - for (uint64 i = 0; i < createInfo.callableGroups.size(); ++i) { - std::memcpy(callableSbt.data() + i * callableStride, sbt.data() + sbtOffset, handleSize); - std::memcpy(callableSbt.data() + i * callableStride + handleSize, createInfo.callableGroups[i].parameters.data(), - createInfo.callableGroups[i].parameters.size()); - sbtOffset += handleSizeAligned; - } - OBufferAllocation rayGenBuffer = new BufferAllocation(graphics, "RayGenSBT", VkBufferCreateInfo{ @@ -669,6 +628,21 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI rayGenBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + uint64 sbtOffset = handleSizeAligned; + + uint32 maxParamSize = 0; + for (auto& hitgroup : createInfo.hitGroups) { + maxParamSize = std::max(maxParamSize, hitgroup.parameters.size()); + } + uint64 hitStride = align(handleSize + maxParamSize, handleAlignment); + Array hitSbt(hitStride * createInfo.hitGroups.size()); + for (uint64 i = 0; i < createInfo.hitGroups.size(); ++i) { + std::memcpy(hitSbt.data() + i * hitStride, sbt.data() + sbtOffset, handleSize); + std::memcpy(hitSbt.data() + i * hitStride + handleSize, createInfo.hitGroups[i].parameters.data(), + createInfo.hitGroups[i].parameters.size()); + sbtOffset += handleSizeAligned; + } + OBufferAllocation hitBuffer = new BufferAllocation(graphics, "HitSBT", VkBufferCreateInfo{ @@ -685,7 +659,20 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI Gfx::QueueType::GRAPHICS); hitBuffer->updateContents(0, hitSbt.size(), hitSbt.data()); hitBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, - Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + + maxParamSize = 0; + for (auto& missGroup : createInfo.missGroups) { + maxParamSize = std::max(maxParamSize, missGroup.parameters.size()); + } + uint64 missStride = align(handleSize + maxParamSize, handleAlignment); + Array missSbt(missStride * createInfo.missGroups.size()); + for (uint64 i = 0; i < createInfo.missGroups.size(); ++i) { + std::memcpy(missSbt.data() + i * missStride, sbt.data() + sbtOffset, handleSize); + std::memcpy(missSbt.data() + i * missStride + handleSize, createInfo.missGroups[i].parameters.data(), + createInfo.missGroups[i].parameters.size()); + sbtOffset += handleSizeAligned; + } OBufferAllocation missBuffer = new BufferAllocation(graphics, "MissSBT", @@ -703,8 +690,20 @@ PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateI Gfx::QueueType::GRAPHICS); missBuffer->updateContents(0, missSbt.size(), missSbt.data()); missBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, - Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); + maxParamSize = 0; + for (auto& callableGroup : createInfo.callableGroups) { + maxParamSize = std::max(maxParamSize, callableGroup.parameters.size()); + } + uint64 callableStride = align(handleSize + maxParamSize, handleAlignment); + Array callableSbt(callableStride * createInfo.callableGroups.size()); + for (uint64 i = 0; i < createInfo.callableGroups.size(); ++i) { + std::memcpy(callableSbt.data() + i * callableStride, sbt.data() + sbtOffset, handleSize); + std::memcpy(callableSbt.data() + i * callableStride + handleSize, createInfo.callableGroups[i].parameters.data(), + createInfo.callableGroups[i].parameters.size()); + sbtOffset += handleSizeAligned; + } OBufferAllocation callableBuffer = new BufferAllocation(graphics, "CallableSBT", diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index ca0e727..e9c863d 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -83,13 +83,16 @@ TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& crea .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, .pNext = nullptr, .geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR, - .geometry = {.instances = - { - .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR, - .pNext = nullptr, - .arrayOfPointers = VK_FALSE, - .data = instanceDeviceAddress, - }}, + .geometry = + { + .instances = + { + .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR, + .pNext = nullptr, + .arrayOfPointers = VK_FALSE, + .data = instanceDeviceAddress, + }, + }, .flags = VK_GEOMETRY_OPAQUE_BIT_KHR, }; VkAccelerationStructureBuildGeometryInfoKHR structureBuildGeometry = { @@ -171,7 +174,21 @@ TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& crea VkAccelerationStructureBuildRangeInfoKHR* buildRangeInfos[] = {&buildRange}; auto cmd = graphics->getGraphicsCommands()->getCommands(); + vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), 1, &buildGeometry, buildRangeInfos); + VkBufferMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + .dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = buffer->buffer, + .offset = 0, + .size = buffer->size, + }; + vkCmdPipelineBarrier(cmd->getHandle(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, 0, + nullptr, 1, &barrier, 0, nullptr); scratchBuffer->bind(); cmd->bindResource(PBufferAllocation(scratchBuffer)); graphics->getDestructionManager()->queueResourceForDestruction(std::move(scratchBuffer)); diff --git a/src/Engine/Graphics/Vulkan/RayTracing.h b/src/Engine/Graphics/Vulkan/RayTracing.h index ca39316..b7a1d10 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.h +++ b/src/Engine/Graphics/Vulkan/RayTracing.h @@ -12,7 +12,14 @@ class BottomLevelAS : public Gfx::BottomLevelAS { public: BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo); ~BottomLevelAS(); - uint64 getDeviceAddress() const { return buffer->deviceAddress; } + uint64 getDeviceAddress() const { + VkAccelerationStructureDeviceAddressInfoKHR accelerationStructureDeviceInfo{ + .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, + .pNext = nullptr, + .accelerationStructure = handle, + }; + return vkGetAccelerationStructureDeviceAddressKHR(graphics->getDevice(), &accelerationStructureDeviceInfo); + } constexpr VkTransformMatrixKHR getTransform() const { return matrix; } constexpr uint64 getIndexOffset() const { return indexOffset; } constexpr uint64 getVertexOffset() const { return vertexOffset; }