首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >升级到1.2.162.1: vkQueueWaitIdle == VK_ERROR_DEVICE_LOST之后

升级到1.2.162.1: vkQueueWaitIdle == VK_ERROR_DEVICE_LOST之后
EN

Stack Overflow用户
提问于 2021-02-14 17:48:53
回答 2查看 517关注 0票数 0

最近,我从Vulkan SDK版本1.2.148.0升级到1.2.162.1。这是必要的,因为射线追踪扩展脱离了测试版,因此现在与非beta图形驱动程序一起工作(我的RTX2070Super461.40版am)。它要求我对我的渲染器的射线跟踪方面做相当多的修改,这要感谢nvidia教程。

不幸的是,以前工作过的代码现在开始导致错误。在许多情况下,提交一个单一时间的命令会导致vkQueueWaitIdle与VK_ERROR_DEVICE_LOST一起失败,这会导致验证错误,说我试图在命令缓冲区仍在使用时释放它。这种情况发生在多种用途:转换图像布局(看起来似乎是undef),构建加速结构,复制缓冲区,但不是每次(例如从阶段到设备缓冲区,释放暂存缓冲区之后也会抛出一个错误,因为它仍然在使用,副本还没有完成).但对于其他用途,它可以正常工作。我目前无法辨认出一个共同的分母。

最后,程序崩溃是因为呈现第一个帧失败,因为它的布局是未定义的--我假设这是由前面提到的一个或多个错误引起的。

自从上次我用它以来,这件事有什么变化吗?这是违规代码(endSingleTimeCommands):

代码语言:javascript
运行
复制
    vkEndCommandBuffer(commandBuffer);

    VkSubmitInfo submitInfo{};
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &commandBuffer;

    vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
    switch (vkQueueWaitIdle(graphicsQueue)) {
        //debug output removed for brevity
    };

    vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);

其中一个失败的地方是:

代码语言:javascript
运行
复制
    //[fill the structs with info...]

    //function pointer grabbed via vkGetDeviceProcAddr
    vk::vkCmdBuildAccelerationStructuresKHR(cmd, 1, &buildInfo, &buildOffset);

    //[call to the above code here]

但是,与扩展无关的代码也会失败(有时!)比如这个:

代码语言:javascript
运行
复制
    VkCommandBuffer commandBuffer = beginSingleTimeCommands();

    VkBufferCopy copyRegion{};
    copyRegion.srcOffset = 0; // Optional
    copyRegion.dstOffset = 0; // Optional
    copyRegion.size = size;
    vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);

    endSingleTimeCommands(commandBuffer);

也许beginSingleTimeCommands也是相关的:

代码语言:javascript
运行
复制
    VkCommandBufferAllocateInfo allocInfo{};
    allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
    allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    allocInfo.commandPool = commandPool;
    allocInfo.commandBufferCount = 1;

    VkCommandBuffer commandBuffer;
    if (vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS) {
        std::cout << "beginSingleTimeCommands: could not allocate command buffer!\n";
    }

    VkCommandBufferBeginInfo beginInfo{};
    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

    if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) {
        std::cout << "beginSingleTimeCommands: could not begin command buffer!\n";
    }

    return commandBuffer;

我还收集到了一些其他信息:我在调用vkCmdBuildAccelerationStructuresKHR之前和之后使用nvidia管道检查点系统添加了一个检查点,这两个检查点都位于TOP_OF_PIPE。在第一次调用此函数之后,不再生成检查点输出,这使我相信,对构建的第一次调用在某种程度上破坏了一切。我想,如果我发现了什么,我会给你回电的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-17 18:39:41

结果,实际错误可能发生在命令缓冲区之前,该缓冲区的vkQueueWaitIdle返回DEVICE_LOST错误。在我的加速结构建筑代码中,我已经并继续有各种各样的错误。我不能很容易地调试它,因为显然验证层没有显示输入到vkCmdBuildAccelerationStructures的结构中是否存在细微的错误,而是大量的尝试和错误。

我确信,在升级前的验证层中,一个值得注意的例子是忘记设置VkAccelerationStructureBuildGeometryInfoKHR::scratchData字段,这是我必须修复的最后一个错误,以便最终运行所有的东西。

因此,我的问题的答案是:不要看触发DEVICE_LOST的命令,看看在该命令之前对队列做了什么,相反,错误是存在的。事实上,一旦发生了第一个DEVICE_LOST错误,(几乎?)所有进一步的vkQueueWaitIdle都以相同的错误(与vkQueueSubmit相同)失败。在诸如我的复制缓冲区代码是第一个失败的情况下,在队列使用之前总是会发现错误。

就像我说过的那样,我无法准确地解决我的问题,原因不止一个,到目前为止,我只解决了其中的一些问题,还有一些还没有解决。我认为这些细节与将来遇到我问题的人无关,但如果我能补充什么来帮助其他人,请告诉我。

票数 1
EN

Stack Overflow用户

发布于 2021-09-26 08:20:04

这是真的!我被这个问题纠缠了几天,结果发现当我使用VkAccelerationStructureBuildGeometryInfoKHR ()来查询大小时,vkGetAccelerationStructureBuildSizesKHR()标志与实际构建BLAS的时候不匹配!在我的例子中,我在查询大小时使用了VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR \ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,而在实际创建AS时只使用了FAST_TRACE,这导致了同样的问题!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66198321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档