我已經寫了一段基本的Vulkan渲染器,它工作正常。然後,它打破了(與電源有關的東西),我重新安裝Vulkan驅動程序到版本1.0.42.0,從那以後,它提供了一個錯誤VK_ERROR_DEVICE_LOST提交一個CommandBuffer單一時間使用(加載紋理等)。我已經嘗試了使用不同GPU的不同設備上的代碼,並且它工作得很好。確切的斷碼:Vulkan設備在提交單次CommandBuffer後丟失
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo =
init::SubmitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(context->transferQueue, 1, &submitInfo, VK_NULL_HANDLE);
//works fine until now
vkQueueWaitIdle(context->transferQueue);
//This gives me VK_ERROR_DEVICE_LOST
vkFreeCommandBuffers(context->device, context->cmdTempPool, 1, &commandBuffer);
//Also doesn't work since commandbuffer is still in queue
它也似乎只在初始化過程中發生的,因爲它沒有給我在運行時的任何錯誤(實際的渲染代碼),但他們在清理時再出現(刪除紋理和緩衝區) 是否有任何有關此問題的報告或解決方法?
確切的驗證層輸出爲:
ParameterValidation: vkQueueWaitIdle: returned VK_ERROR_DEVICE_LOST,
indicating that the logical device has been lost
DS: Attempt to free command buffer (0x000002D18AAF1A90) which is in use. For
more information refer to Vulkan Spec Section '5.3. Command Buffer
Allocation and Management' which states 'All elements of pCommandBuffers
must not be in the pending state'
(https://www.khronos.org/registry/vulkan/specs/1.0-
extensions/html/vkspec.html#vkFreeCommandBuffers)
ParameterValidation: vkQueueSubmit: returned VK_ERROR_DEVICE_LOST,
indicating that the logical device has been lost
編輯: 因爲它似乎轉換圖像的佈局時纔會發生,這裏是該代碼:
void util::transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout)
{
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else {
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
else {
throw std::invalid_argument("unsupported layout transition!");
}
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
endSingleTimeCommands(commandBuffer);
}
來自驗證層的任何錯誤/警告?在隊列提交時還有無信號的柵欄? –
我嘗試過使用和不使用vkQueueWaitIdle而不使用柵欄,但我現在將其刪除,但它仍然不起作用 – Dynamitos
GPU(和驅動程序)會發生這種崩潰嗎?你還可以添加更多的代碼,尤其是在你想要提交的命令緩衝區中的一個,以及與緩衝區,圖像等的隊列傳輸所有權相關的所有內容(看起來像使用專用傳輸隊列)。 –