diff --git a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp index 586311d4c..3dd0cb0e3 100644 --- a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp @@ -107,13 +107,21 @@ void VkRaytrace::CreateVertexAndIndexBuffers() transferBuffer->Unmap(); vertexBuffer = BufferBuilder() - .Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + .Usage( + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR) .Size(vertexbuffersize) .DebugName("vertexBuffer") .Create(fb->device); indexBuffer = BufferBuilder() - .Usage(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + .Usage( + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR) .Size(indexbuffersize) .DebugName("indexBuffer") .Create(fb->device); @@ -135,12 +143,6 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure() VkAccelerationStructureBuildRangeInfoKHR rangeInfo = {}; VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo }; - buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; - buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; - buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; - buildInfo.geometryCount = 1; - buildInfo.ppGeometries = geometries; - accelStructBLDesc.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; accelStructBLDesc.flags = VK_GEOMETRY_OPAQUE_BIT_KHR; accelStructBLDesc.geometry.triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR }; @@ -150,10 +152,14 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure() accelStructBLDesc.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32; accelStructBLDesc.geometry.triangles.indexData.deviceAddress = indexBuffer->GetDeviceAddress(); accelStructBLDesc.geometry.triangles.maxVertex = Mesh->MeshVertices.Size() - 1; - //accelStructBLDesc.geometry.triangles.transformData = transformAddress; // optional; VkTransformMatrixKHR transfered to a buffer? - rangeInfo.primitiveCount = Mesh->MeshElements.Size() / 3; - uint32_t maxPrimitiveCount = rangeInfo.primitiveCount; + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; + buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; + buildInfo.geometryCount = 1; + buildInfo.ppGeometries = geometries; + + uint32_t maxPrimitiveCount = Mesh->MeshElements.Size() / 3; VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR }; vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxPrimitiveCount, &sizeInfo); @@ -164,16 +170,11 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure() .DebugName("blAccelStructBuffer") .Create(fb->device); - VkAccelerationStructureKHR blAccelStructHandle = {}; - VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR }; - createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; - createInfo.buffer = blAccelStructBuffer->buffer; - createInfo.size = sizeInfo.accelerationStructureSize; - VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &blAccelStructHandle); - if (result != VK_SUCCESS) - throw std::runtime_error("vkCreateAccelerationStructureKHR failed"); - blAccelStruct = std::make_unique(fb->device, blAccelStructHandle); - blAccelStruct->SetDebugName("blAccelStruct"); + blAccelStruct = AccelerationStructureBuilder() + .Type(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) + .Buffer(blAccelStructBuffer.get(), sizeInfo.accelerationStructureSize) + .DebugName("blAccelStruct") + .Create(fb->device); blScratchBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) @@ -183,6 +184,7 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure() buildInfo.dstAccelerationStructure = blAccelStruct->accelstruct; buildInfo.scratchData.deviceAddress = blScratchBuffer->GetDeviceAddress(); + rangeInfo.primitiveCount = maxPrimitiveCount; fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos); @@ -221,10 +223,9 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() fb->GetCommands()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get()); // Finish transfering before using it as input - VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; - fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr); + PipelineBarrier() + .AddMemory(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT) + .Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR); VkAccelerationStructureBuildGeometryInfoKHR buildInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR }; VkAccelerationStructureGeometryKHR accelStructTLDesc = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR }; @@ -232,19 +233,17 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() VkAccelerationStructureBuildRangeInfoKHR rangeInfo = {}; VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo }; + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; buildInfo.geometryCount = 1; buildInfo.ppGeometries = geometries; - buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; - buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; - buildInfo.srcAccelerationStructure = VK_NULL_HANDLE; accelStructTLDesc.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; accelStructTLDesc.geometry.instances = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR }; accelStructTLDesc.geometry.instances.data.deviceAddress = tlInstanceBuffer->GetDeviceAddress(); uint32_t maxInstanceCount = 1; - rangeInfo.primitiveCount = 1; VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR }; vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxInstanceCount, &sizeInfo); @@ -255,15 +254,11 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() .DebugName("tlAccelStructBuffer") .Create(fb->device); - VkAccelerationStructureKHR tlAccelStructHandle = {}; - VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR }; - createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; - createInfo.buffer = tlAccelStructBuffer->buffer; - createInfo.size = sizeInfo.accelerationStructureSize; - VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &tlAccelStructHandle); - if (result != VK_SUCCESS) - throw std::runtime_error("vkCreateAccelerationStructureKHR failed"); - tlAccelStruct = std::make_unique(fb->device, tlAccelStructHandle); + tlAccelStruct = AccelerationStructureBuilder() + .Type(VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) + .Buffer(tlAccelStructBuffer.get(), sizeInfo.accelerationStructureSize) + .DebugName("tlAccelStruct") + .Create(fb->device); tlScratchBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) @@ -273,6 +268,7 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() buildInfo.dstAccelerationStructure = tlAccelStruct->accelstruct; buildInfo.scratchData.deviceAddress = tlScratchBuffer->GetDeviceAddress(); + rangeInfo.primitiveCount = 1; fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos); diff --git a/src/common/rendering/vulkan/system/vk_builders.cpp b/src/common/rendering/vulkan/system/vk_builders.cpp index b2bc2a42c..aff0de50a 100644 --- a/src/common/rendering/vulkan/system/vk_builders.cpp +++ b/src/common/rendering/vulkan/system/vk_builders.cpp @@ -545,6 +545,46 @@ std::unique_ptr BufferBuilder::Create(VulkanDevice* device) ///////////////////////////////////////////////////////////////////////////// +AccelerationStructureBuilder::AccelerationStructureBuilder() +{ +} + +AccelerationStructureBuilder& AccelerationStructureBuilder::Type(VkAccelerationStructureTypeKHR type) +{ + createInfo.type = type; + return *this; +} + +AccelerationStructureBuilder& AccelerationStructureBuilder::Buffer(VulkanBuffer* buffer, VkDeviceSize size) +{ + createInfo.buffer = buffer->buffer; + createInfo.offset = 0; + createInfo.size = size; + return *this; +} + +AccelerationStructureBuilder& AccelerationStructureBuilder::Buffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size) +{ + createInfo.buffer = buffer->buffer; + createInfo.offset = offset; + createInfo.size = size; + return *this; +} + +std::unique_ptr AccelerationStructureBuilder::Create(VulkanDevice* device) +{ + VkAccelerationStructureKHR hande = {}; + VkResult result = vkCreateAccelerationStructureKHR(device->device, &createInfo, nullptr, &hande); + if (result != VK_SUCCESS) + throw std::runtime_error("vkCreateAccelerationStructureKHR failed"); + auto obj = std::make_unique(device, hande); + if (debugName) + obj->SetDebugName(debugName); + return obj; +} + +///////////////////////////////////////////////////////////////////////////// + ComputePipelineBuilder::ComputePipelineBuilder() { pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; diff --git a/src/common/rendering/vulkan/system/vk_builders.h b/src/common/rendering/vulkan/system/vk_builders.h index 2f47942cb..db3528bb5 100644 --- a/src/common/rendering/vulkan/system/vk_builders.h +++ b/src/common/rendering/vulkan/system/vk_builders.h @@ -100,6 +100,23 @@ private: const char* debugName = nullptr; }; +class AccelerationStructureBuilder +{ +public: + AccelerationStructureBuilder(); + + AccelerationStructureBuilder& Type(VkAccelerationStructureTypeKHR type); + AccelerationStructureBuilder& Buffer(VulkanBuffer* buffer, VkDeviceSize size); + AccelerationStructureBuilder& Buffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size); + AccelerationStructureBuilder& DebugName(const char* name) { debugName = name; return *this; } + + std::unique_ptr Create(VulkanDevice* device); + +private: + VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR }; + const char* debugName = nullptr; +}; + class ComputePipelineBuilder { public: