diff --git a/modules/rtx/include/vkcv/rtx/ASManager.hpp b/modules/rtx/include/vkcv/rtx/ASManager.hpp index 49dcb92433be38ac6d8a0196012ef39ca81a2171..766db45f8f0b9c0115ce30277105d95ed0a1dbf7 100644 --- a/modules/rtx/include/vkcv/rtx/ASManager.hpp +++ b/modules/rtx/include/vkcv/rtx/ASManager.hpp @@ -16,10 +16,23 @@ namespace vkcv::rtx { ASManager(vkcv::Core *core); /** - * @brief Build a Bottom Level Acceleration Structure object from given @p vertexBuffer and @p indexBuffer. - * @param[in] vertexBuffer The vertex buffer. - * @param[in] indexBuffer The index buffer. + * @brief TODO + * TODO: kill AS, kill buffers, free memory of buffers + */ + ~ASManager() {}; + + /** + * @brief Build a Bottom Level Acceleration Structure object from given @p vertices and @p indices. + * @param[in] vertices The vertex data of type uint8_t. + * @param[in] indices The index data of type uint8_t. + */ + void buildBLAS(std::vector<uint8_t> &vertices, std::vector<uint8_t> &indices); + + /** + * @brief TODO + * @param data + * @return */ - void buildBLAS(Buffer<uint16_t> &vertexBuffer, Buffer<uint16_t> &indexBuffer); + vk::Buffer makeBuffer(std::vector<uint8_t> &data); }; } \ No newline at end of file diff --git a/modules/rtx/include/vkcv/rtx/RTX.hpp b/modules/rtx/include/vkcv/rtx/RTX.hpp index 957ce9bb3ff7eaef9cf569511dec6e6aff6e7ade..922ddecf2ebddd56897acc998e9bb38bd57411bc 100644 --- a/modules/rtx/include/vkcv/rtx/RTX.hpp +++ b/modules/rtx/include/vkcv/rtx/RTX.hpp @@ -46,10 +46,10 @@ namespace vkcv::rtx { /** * @brief TODO * @param core - * @param vertexBuffer - * @param indexBuffer + * @param vertices + * @param indices */ - void init(Core* core, Buffer<uint16_t> &vertexBuffer, Buffer<uint16_t> &indexBuffer); + void init(Core* core, std::vector<uint8_t> &vertices, std::vector<uint8_t> &indices); }; } diff --git a/modules/rtx/src/vkcv/rtx/ASManager.cpp b/modules/rtx/src/vkcv/rtx/ASManager.cpp index d732c1dadc071b69a58a8211103e052751b64a49..d4e3dbd9c92a45a3883fac531bed2ef9e1b70c33 100644 --- a/modules/rtx/src/vkcv/rtx/ASManager.cpp +++ b/modules/rtx/src/vkcv/rtx/ASManager.cpp @@ -11,16 +11,21 @@ namespace vkcv::rtx { } - void ASManager::buildBLAS(Buffer<uint16_t> &vertexBuffer, Buffer<uint16_t> &indexBuffer) { + void ASManager::buildBLAS(std::vector<uint8_t> &vertices, std::vector<uint8_t> &indices) { + uint32_t vertexCount = vertices.size(); + uint32_t indexCount = indices.size(); + vk::Buffer vertexBuffer = makeBuffer(vertices); + vk::Buffer indexBuffer = makeBuffer(indices); + // INFO: It seems that we need a dynamic dispatch loader because Vulkan is an ASs ... vk::DispatchLoaderDynamic dld( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); dld.init(m_core->getContext().getInstance()); - vk::BufferDeviceAddressInfo vertexBufferDeviceAddressInfo(vertexBuffer.getVulkanHandle()); + vk::BufferDeviceAddressInfo vertexBufferDeviceAddressInfo(vertexBuffer); vk::DeviceAddress vertexBufferAddress = m_core->getContext().getDevice().getBufferAddressKHR(vertexBufferDeviceAddressInfo, dld); vk::DeviceOrHostAddressConstKHR vertexDeviceOrHostAddressConst(vertexBufferAddress); - vk::BufferDeviceAddressInfo indexBufferDeviceAddressInfo(indexBuffer.getVulkanHandle()); + vk::BufferDeviceAddressInfo indexBufferDeviceAddressInfo(indexBuffer); vk::DeviceAddress indexBufferAddress = m_core->getContext().getDevice().getBufferAddressKHR(indexBufferDeviceAddressInfo, dld); vk::DeviceOrHostAddressConstKHR indexDeviceOrHostAddressConst(indexBufferAddress); @@ -29,7 +34,7 @@ namespace vkcv::rtx { vk::Format::eR32G32B32Sfloat, // vertex format vertexDeviceOrHostAddressConst, // vertex buffer address (vk::DeviceOrHostAddressConstKHR) 3 * sizeof(float), // vertex stride (vk::DeviceSize) - uint32_t(vertexBuffer.getCount() - 1), // maxVertex (uint32_t) + uint32_t(vertexCount - 1), // maxVertex (uint32_t) vk::IndexType::eUint16, // indexType (vk::IndexType) --> INFO: UINT16 oder UINT32! indexDeviceOrHostAddressConst, // indexData (vk::DeviceOrHostAddressConstKHR) {} // transformData (vk::DeviceOrHostAddressConstKHR) @@ -44,7 +49,7 @@ namespace vkcv::rtx { // List ranges of data for access vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo( - uint32_t(indexBuffer.getCount() / 3), // the primitiveCount (uint32_t) + uint32_t(indexCount / 3), // the primitiveCount (uint32_t) 0, // primitiveOffset (uint32_t) 0, // firstVertex (uint32_t) 0 // transformOffset (uint32_t) @@ -98,4 +103,136 @@ namespace vkcv::rtx { // TODO: destroy accelerationstructure when closing app } + vk::Buffer ASManager::makeBuffer(std::vector<uint8_t> &data) { + // make vk::Buffer of type uint16_t + + vk::Device device = m_core->getContext().getDevice(); + + // first: Staging Buffer creation + vk::DeviceSize deviceSize = sizeof(data[0]) * data.size(); + vk::BufferUsageFlags bufferUsageFlagBits = vk::BufferUsageFlagBits::eTransferSrc; + vk::BufferCreateInfo bufferCreateInfo( + vk::BufferCreateFlags(), // vk::BufferCreateFlags + deviceSize, // vk::DeviceSize + bufferUsageFlagBits, // vk::BufferUsageFlags + vk::SharingMode::eExclusive, // vk::SharingMode + {}, // uint32_t queueFamilyIndexCount + {} // uint32_t* queueFamilyIndices + ); + vk::Buffer stagingBuffer = device.createBuffer(bufferCreateInfo, nullptr); + vk::MemoryRequirements memoryRequirements = device.getBufferMemoryRequirements(stagingBuffer); + + vk::PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties = m_core->getContext().getPhysicalDevice().getMemoryProperties(); + + vk::MemoryPropertyFlags memoryPropertyFlags = vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible; + + uint32_t memoryTypeIndex = -1; + for (int x = 0; x < physicalDeviceMemoryProperties.memoryTypeCount; x++) { + if ((memoryRequirements.memoryTypeBits & (1 << x)) && (physicalDeviceMemoryProperties.memoryTypes[x].propertyFlags & memoryPropertyFlags) == memoryPropertyFlags) { + memoryTypeIndex = x; + break; + } + } + + vk::MemoryAllocateInfo memoryAllocateInfo( + memoryRequirements.size, // size of allocation in bytes + memoryTypeIndex // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure. + ); + vk::MemoryAllocateFlagsInfo allocateFlagsInfo( + vk::MemoryAllocateFlagBitsKHR::eDeviceAddress // vk::MemoryAllocateFlags + ); + memoryAllocateInfo.setPNext(&allocateFlagsInfo); // extend memory allocate info with allocate flag info + vk::DeviceMemory deviceMemory = device.allocateMemory(memoryAllocateInfo); + + uint32_t memoryOffset = 0; + device.bindBufferMemory(stagingBuffer, deviceMemory, memoryOffset); + + // fill staging buffer + void* mapped = device.mapMemory(deviceMemory, memoryOffset, deviceSize); + std::memcpy(mapped, data.data(), deviceSize); + device.unmapMemory(deviceMemory); + + // second: GPU Buffer creation + vk::BufferUsageFlags bufferUsageFlagBits2 = vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR + | vk::BufferUsageFlagBits::eTransferDst + | vk::BufferUsageFlagBits::eStorageBuffer + | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR; + vk::BufferCreateInfo bufferCreateInfo2( + vk::BufferCreateFlags(), // vk::BufferCreateFlags + deviceSize, // vk::DeviceSize + bufferUsageFlagBits2, // vk::BufferUsageFlags + vk::SharingMode::eExclusive, // vk::SharingMode + {}, // uint32_t queueFamilyIndexCount + {} // uint32_t* queueFamilyIndices + ); + vk::Buffer dataBuffer = device.createBuffer(bufferCreateInfo2, nullptr); + vk::MemoryRequirements memoryRequirements2 = device.getBufferMemoryRequirements(dataBuffer); + + vk::PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties2 = m_core->getContext().getPhysicalDevice().getMemoryProperties(); + + vk::MemoryPropertyFlags memoryPropertyFlags2 = vk::MemoryPropertyFlagBits::eDeviceLocal; + + uint32_t memoryTypeIndex2 = -1; + for (int x = 0; x < physicalDeviceMemoryProperties.memoryTypeCount; x++) { + if ((memoryRequirements2.memoryTypeBits & (1 << x)) && (physicalDeviceMemoryProperties2.memoryTypes[x].propertyFlags & memoryPropertyFlags2) == memoryPropertyFlags2) { + memoryTypeIndex2 = x; + break; + } + } + + vk::MemoryAllocateInfo memoryAllocateInfo2( + memoryRequirements2.size, // size of allocation in bytes + memoryTypeIndex2 // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure. + ); + vk::MemoryAllocateFlagsInfo allocateFlagsInfo2( + vk::MemoryAllocateFlagBitsKHR::eDeviceAddress // vk::MemoryAllocateFlags + ); + memoryAllocateInfo2.setPNext(&allocateFlagsInfo2); // extend memory allocate info with allocate flag info + vk::DeviceMemory deviceMemory2 = device.allocateMemory(memoryAllocateInfo2); + + uint32_t memoryOffset2 = 0; + device.bindBufferMemory(dataBuffer, deviceMemory2, memoryOffset2); + + // copy data from stagingBuffer to dataBuffer + vk::CommandPool commandPool; + + vk::CommandPoolCreateInfo commandPoolCreateInfo; + commandPoolCreateInfo.queueFamilyIndex = m_core->getContext().getQueueManager().getGraphicsQueues()[0].familyIndex; + + if (device.createCommandPool(&commandPoolCreateInfo, nullptr, &commandPool) != vk::Result::eSuccess) { + vkcv_log(LogLevel::ERROR, "ASManager: command pool could not be created."); + } + + vk::CommandBufferAllocateInfo bufferAllocateInfo; + bufferAllocateInfo.level = vk::CommandBufferLevel::ePrimary; + bufferAllocateInfo.commandPool = commandPool; + bufferAllocateInfo.commandBufferCount = 1; + + vk::CommandBuffer commandBuffer; + if (device.allocateCommandBuffers(&bufferAllocateInfo, &commandBuffer) != vk::Result::eSuccess) { + vkcv_log(LogLevel::ERROR, "ASManager: command buffer could not be allocated."); + } + + beginCommandBuffer(commandBuffer, vk::CommandBufferUsageFlagBits::eOneTimeSubmit); + vk::BufferCopy bufferCopy; + bufferCopy.size = deviceSize; + commandBuffer.copyBuffer(stagingBuffer, dataBuffer, 1, &bufferCopy); + commandBuffer.end(); + + vk::SubmitInfo submitInfo; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + + Queue graphicsQueue = m_core->getContext().getQueueManager().getGraphicsQueues()[0]; + + graphicsQueue.handle.submit(submitInfo); + graphicsQueue.handle.waitIdle(); + + device.freeCommandBuffers(commandPool, 1, &commandBuffer); + device.destroyBuffer(stagingBuffer); + device.freeMemory(deviceMemory); + + return dataBuffer; + } + } \ No newline at end of file diff --git a/modules/rtx/src/vkcv/rtx/RTX.cpp b/modules/rtx/src/vkcv/rtx/RTX.cpp index 7b81f4a05f2919512d7e7d677f93cca4507ff5b2..887c49f1a3288bbc3e43a6928f33aa8bcd596df9 100644 --- a/modules/rtx/src/vkcv/rtx/RTX.cpp +++ b/modules/rtx/src/vkcv/rtx/RTX.cpp @@ -113,11 +113,11 @@ namespace vkcv::rtx { }); } - void RTXModule::init(Core* core, Buffer<uint16_t> &vertexBuffer, Buffer<uint16_t> &indexBuffer) { + void RTXModule::init(Core* core, std::vector<uint8_t> &vertices, std::vector<uint8_t> &indices) { // build acceleration structures BLAS then TLAS --> see ASManager ASManager asManager(core); - asManager.buildBLAS(vertexBuffer, indexBuffer); + asManager.buildBLAS(vertices, indices); } diff --git a/projects/rtx/src/main.cpp b/projects/rtx/src/main.cpp index 72783398c758eb453b4262c94194d46ea0cfac35..4e37db64f11725cfdb81f3893a3345d5b478eb70 100644 --- a/projects/rtx/src/main.cpp +++ b/projects/rtx/src/main.cpp @@ -67,31 +67,31 @@ int main(int argc, const char** argv) { assert(!mesh.vertexGroups.empty()); - auto vertexBuffer = core.createBuffer<uint16_t>( + auto vertexBuffer = core.createBuffer<uint8_t>( vkcv::BufferType::RT_ACCELERATION_VERTEX, mesh.vertexGroups[0].vertexBuffer.data.size(), vkcv::BufferMemoryType::DEVICE_LOCAL ); - std::vector<uint16_t> vertices = {}; + std::vector<uint8_t> vertices = {}; for (size_t i=0; i<mesh.vertexGroups[0].vertexBuffer.data.size(); i++) { - vertices.emplace_back((uint16_t)mesh.vertexGroups[0].vertexBuffer.data[i]); + vertices.emplace_back(mesh.vertexGroups[0].vertexBuffer.data[i]); } vertexBuffer.fill(vertices); - auto indexBuffer = core.createBuffer<uint16_t>( + auto indexBuffer = core.createBuffer<uint8_t>( vkcv::BufferType::RT_ACCELERATION_INDEX, mesh.vertexGroups[0].indexBuffer.data.size(), vkcv::BufferMemoryType::DEVICE_LOCAL ); - std::vector<uint16_t> indices = {}; + std::vector<uint8_t> indices = {}; for (size_t i=0; i<mesh.vertexGroups[0].indexBuffer.data.size(); i++) { - indices.emplace_back((uint16_t)mesh.vertexGroups[0].indexBuffer.data[i]); + indices.emplace_back(mesh.vertexGroups[0].indexBuffer.data[i]); } indexBuffer.fill(indices); // init RTXModule - rtxModule.init(&core, vertexBuffer, indexBuffer); + rtxModule.init(&core, vertices, indices); const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE,