2017-07-05 50 views
0

我已經寫了一段基本的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); 
} 
+2

來自驗證層的任何錯誤/警告?在隊列提交時還有無信號的柵欄? –

+0

我嘗試過使用和不使用vkQueueWaitIdle而不使用柵欄,但我現在將其刪除,但它仍然不起作用 – Dynamitos

+1

GPU(和驅動程序)會發生這種崩潰嗎?你還可以添加更多的代碼,尤其是在你想要提交的命令緩衝區中的一個,以及與緩衝區,圖像等的隊列傳輸所有權相關的所有內容(看起來像使用專用傳輸隊列)。 –

回答

1

如前所述在評論中你需要跟蹤圖片的所有權,尤其是如果你使用不同的隊列系列。

因此,如果您使用的是VK_SHARING_MODE_CONCURRENT,請確保您指定在創建時訪問圖像的所有隊列家族索引(VkImageCreateInfo.pQueueFamilyIndicesVkImageCreateInfo.queueFamilyIndexCount)。如果您不需要對圖像進行併發隊列訪問,則也可以使用VK_SHARING_MODE_EXCLUSIVE,而無需指定隊列系列索引。

當不同的隊列指數系列處理(圖形和計算如)也很重要通過在兩個方向上的srcQueueFamilyIndexdstQueueFamilyIndex成員做你的障礙,適當的隊列家族所有權的轉移。