Fixing SBT alignment

This commit is contained in:
mklefrancois 2020-05-27 16:50:02 +02:00
parent ccdc90f35c
commit 41d6bbeea4
2 changed files with 48 additions and 29 deletions

View file

@ -1238,9 +1238,9 @@ group for that instance.
The SBT is an array containing the handles to the shader groups used in the ray tracing pipeline. In our example, we
will create a buffer for the three groups: raygen, miss and closest hit. The size of the handle is given by the
`shaderGroupHandleSize` member of the ray tracing properties. We will then allocate a buffer of size `3 *
shaderGroupHandleSize` and will consecutively write the handle of each shader group. To retrieve all the handles, we
will call `vkGetRayTracingShaderGroupHandlesKHR`.
`shaderGroupHandleSize` member of the ray tracing properties, but the offset need to be aligned on `shaderGroupBaseAlignment`.
We will then allocate a buffer of size `3 * shaderGroupBaseAlignment` and will consecutively write the handle of each shader group.
To retrieve all the handles, we will call `vkGetRayTracingShaderGroupHandlesKHR`.
The buffer will have the following information, which will later be used when calling `vkCmdTraceRaysKHR`:
@ -1279,9 +1279,10 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
uint32_t baseAlignment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
uint32_t sbtSize = groupCount * groupHandleSize;
uint32_t sbtSize = groupCount * baseAlignment;
````
We then fetch the handles to the shader groups of the pipeline, and let the allocator allocate the device memory and
@ -1291,16 +1292,21 @@ copy the handles into the SBT:
std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data());
// Write the handles in the SBT
m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
// Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
m_rtSBTBuffer =
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT");
genCmdBuf.submitAndWait(cmdBuf);
void* mapped = m_alloc.map(m_rtSBTBuffer);
auto* pData = reinterpret_cast<uint8_t*>(mapped);
for(uint32_t g = 0; g < groupCount; g++)
{
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
pData += baseAlignment;
}
m_alloc.unmap(m_rtSBTBuffer);
m_alloc.finalizeAndReleaseStaging();
}
@ -1360,7 +1366,7 @@ each shader. In our case the stride is simply the size of a shader group handle,
shader-group-specific data within the SBT, resulting in a larger stride.
```` C
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
vk::DeviceSize progSize = m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier
vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize missStride = progSize;