Fix acceleration structure vertex and index flushes
authorRicardo Garcia <rgarcia@igalia.com>
Tue, 26 Apr 2022 09:48:41 +0000 (11:48 +0200)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Fri, 6 May 2022 15:43:59 +0000 (15:43 +0000)
Flush the whole allocation when updating vertex and index buffers during
ray tracing acceleration structure builds. The code currently does not
track both the offset and size align to nonCoherentAtomSize, and most
vertex and index buffer allocations are actually on coherent memory.
Flushing the whole allocation allows us to avoid several validation
errors like VUID-VkMappedMemoryRange-size-01390.

Affected tests:
dEQP-VK.ray_tracing*
dEQP-VK.ray_query*

Components: Vulkan
VK-GL-CTS issue: 3656

Change-Id: I5edbbc3b67ab46eaea568842f06dc53664e78e42

external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp

index 06e132f..285c256 100644 (file)
@@ -830,7 +830,6 @@ void updateVertexBuffer (const DeviceInterface&                                                                             vk,
 {
        const Allocation&                               geometryAlloc           = vertexBuffer->getAllocation();
        deUint8*                                                bufferStart                     = static_cast<deUint8*>(geometryAlloc.getHostPtr());
-       const VkDeviceSize                              bufferSize                      = getVertexBufferSize(geometriesData);
        VkDeviceSize                                    bufferOffset            = geometriesOffset;
 
        for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
@@ -843,7 +842,10 @@ void updateVertexBuffer (const DeviceInterface&                                                                            vk,
                bufferOffset += deAlignSize(geometryPtrSize,8);
        }
 
-       flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset()+geometriesOffset, bufferSize);
+       // Flush the whole allocation. We could flush only the interesting range, but we'd need to be sure both the offset and size
+       // align to VkPhysicalDeviceLimits::nonCoherentAtomSize, which we are not considering. Also note most code uses Coherent memory
+       // for the vertex and index buffers, so flushing is actually not needed.
+       flushAlloc(vk, device, geometryAlloc);
 }
 
 VkDeviceSize getIndexBufferSize (const std::vector<de::SharedPtr<RaytracedGeometryBase>>&      geometriesData)
@@ -886,7 +888,6 @@ void updateIndexBuffer (const DeviceInterface&                                                                              vk,
 {
        const Allocation&                               indexAlloc                      = indexBuffer->getAllocation();
        deUint8*                                                bufferStart                     = static_cast<deUint8*>(indexAlloc.getHostPtr());
-       const VkDeviceSize                              bufferSize                      = getIndexBufferSize(geometriesData);
        VkDeviceSize                                    bufferOffset            = geometriesOffset;
 
        for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx)
@@ -902,7 +903,10 @@ void updateIndexBuffer (const DeviceInterface&                                                                             vk,
                }
        }
 
-       flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset()+geometriesOffset, bufferSize);
+       // Flush the whole allocation. We could flush only the interesting range, but we'd need to be sure both the offset and size
+       // align to VkPhysicalDeviceLimits::nonCoherentAtomSize, which we are not considering. Also note most code uses Coherent memory
+       // for the vertex and index buffers, so flushing is actually not needed.
+       flushAlloc(vk, device, indexAlloc);
 }
 
 class BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure