VK_ERROR_DEVICE_LOST on create acceleration structure and possible ways to debug it

43 views Asked by At

i'm trying to make a ray tracer in vulkan, so i need to make an acceleration structure. i've seen similar questions and understood that the VK_ERROR_DEVCE_LOST shows up on calling vkQueueWaitIdle when something is wrong with creating the acceleration structure, but i can't figure out what am i doing wrong, validation layers don't help either. the error occurs when creating bottom level acceleration structure. i'm trying to create it like this

    VkAccelerationStructureGeometryTrianglesDataKHR geometryData = {};
    geometryData.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
    geometryData.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;

    VkBufferDeviceAddressInfo bufferAddressInfo = {};
    bufferAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
    bufferAddressInfo.buffer = vertexBuffer;
    
    geometryData.vertexData.deviceAddress = vkGetBufferDeviceAddress(device, &bufferAddressInfo);
    geometryData.maxVertex = vertices.size()-1;
    geometryData.vertexStride = 0;
    geometryData.indexType = VK_INDEX_TYPE_UINT32;

    bufferAddressInfo.buffer = indexBuffer;
    geometryData.indexData.deviceAddress = vkGetBufferDeviceAddress(device, &bufferAddressInfo);

    VkAccelerationStructureGeometryKHR accelGeometry = {};
    accelGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
    accelGeometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
    accelGeometry.geometry.triangles = geometryData;
    accelGeometry.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;

    VkAccelerationStructureBuildRangeInfoKHR offset;
    offset.firstVertex = 0;
    offset.primitiveCount = vertices.size() / 3;
    offset.primitiveOffset = 0;
    offset.transformOffset = 0;

    VkAccelerationStructureBuildGeometryInfoKHR accelGeometryBuild = {};
    accelGeometryBuild.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
    accelGeometryBuild.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
    accelGeometryBuild.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
    accelGeometryBuild.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
    accelGeometryBuild.geometryCount = 1;
    accelGeometryBuild.pGeometries = &accelGeometry;

    VkAccelerationStructureBuildSizesInfoKHR accelSize;
    accelSize.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
    vkGetAccelerationStructureBuildSizesKHR(device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &accelGeometryBuild, &offset.primitiveCount, &accelSize);

    VkBuffer scratchBuffer;
    VkDeviceMemory scratchBufferMemory;
    createBuffer(accelSize.buildScratchSize, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, scratchBuffer, scratchBufferMemory);

    VkAccelerationStructureCreateInfoKHR accelCreateInfo = {};
    accelCreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
    accelCreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
    accelCreateInfo.size = accelSize.accelerationStructureSize;

    createBuffer(accelCreateInfo.size, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, blAccelStructureBuffer, blAccelStructureBufferMemory);

    accelCreateInfo.buffer = blAccelStructureBuffer;

    if (vkCreateAccelerationStructureKHR(device, &accelCreateInfo, nullptr, &blAccelStructure) != VK_SUCCESS)
        log_fatal(std::runtime_error("failed to create a bottom level acceleration structure"));

    accelGeometryBuild.dstAccelerationStructure = blAccelStructure;

    bufferAddressInfo.buffer = scratchBuffer;
    accelGeometryBuild.scratchData.deviceAddress = vkGetBufferDeviceAddress(device, &bufferAddressInfo);

    VkCommandBuffer cmdBuffer = getSingleTimeCmdBuffer();

    std::array<VkAccelerationStructureBuildRangeInfoKHR*, 1> offsets = {&offset};

    vkCmdBuildAccelerationStructuresKHR(cmdBuffer, 1, &accelGeometryBuild, offsets.data());

    submitSingleTimeCmdBuffer(cmdBuffer);

    vkDestroyBuffer(device, scratchBuffer, nullptr);
    vkFreeMemory(device, scratchBufferMemory, nullptr);
}

In submitSingleTimeCmdBuffer there's a call to vkQueueWaitIdle which returns VK_ERROR_DEVICE_LOST. vertexBuffer and indexBuffer were both working fine with regilar graphics pipeline in the same code before adding acceleration structure building, also both of them contain VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT flags. vertices is a vector of glm::vec3 which is used to create vertexBuffer object. createBuffer function is an abstraction to create a VkBuffer with corresponding VkDeviceMemory of given size with given usage flags and memory properties.

Also by any chance, is there any way to debug this? validation layers don't say anything useful there.

0

There are 0 answers