Skip to content
Snippets Groups Projects
Commit 79543ffc authored by Vanessa Karolek's avatar Vanessa Karolek
Browse files

[#92] add manual allocation for the vertex & index buffers [to be checked]

parent bba814fa
Branches
Tags
1 merge request!75Resolve "RTX-Module"
Pipeline #27041 passed
......@@ -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
......@@ -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);
};
}
......@@ -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
......@@ -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);
}
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment