2017-07-05 4 views
0

Ich habe eine grundlegende Vulkan Renderer eine Weile geschrieben und es hat gut funktioniert. Es ist dann kaputt gegangen (etwas mit dem Netzteil) und ich habe die Vulkan-Treiber auf Version 1.0.42.0 neu installiert und seither gibt es mir den Fehler VK_ERROR_DEVICE_LOST, wenn ich einen CommandBuffer für den einmaligen Gebrauch (Laden von Texturen usw.) abschicke. Ich habe den Code auf einem anderen Gerät mit einer anderen GPU ausprobiert, und dort funktioniert es ganz gut. Der genaue Bruchcode:Vulkan Device Verloren nach dem Einreichen von Single 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 

Es scheint auch nur während der Initialisierung geschehen, da es nicht mir keine Fehler während der Laufzeit (tatsächlicher Rendering-Code) geben, aber sie treten wieder während der Bereinigung (Löschen von Texturen und Puffern) Gab es Berichte oder Problemumgehungen für dieses Problem?

Die genaue Validierungsschicht ausgegeben wird:

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 

EDIT: da es nur scheint zu passieren, wenn Bild-Layout übergeht, hier ist der Code dafür:

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

Alle Fehler/Warnungen von den Validierungsebenen? Ist der Zaun auch bei der Queue-Submission-Zeit nicht signiert? –

+0

Ich habe es mit und ohne einen Zaun anstelle der vkQueueWaitIdle versucht, aber ich habe es jetzt entfernt, und es funktioniert immer noch nicht – Dynamitos

+1

Welche GPU (und Treiber) passiert dieser Absturz? Und könntest du auch noch mehr Code hinzufügen, insb. dasjenige, das sich innerhalb des Befehlspuffers befindet, den Sie übergeben möchten, und alles, was mit der Warteschlangenübertragung zusammenhängt, ist der Besitz Ihrer Puffer, Images usw. (es sieht so aus, als ob Sie eine dedizierte Übertragungswarteschlange verwenden). –

Antwort

1

Wie bereits erwähnt In den Kommentaren müssen Sie den Bildbesitz verfolgen, insb. wenn Sie mit verschiedenen Warteschlangenfamilien arbeiten.

So stellen Sie sicher, dass Sie alle Warteschlange familiy Indizes angeben, die ein Bild zum Zeitpunkt der Erstellung zugreifen (VkImageCreateInfo.pQueueFamilyIndices und VkImageCreateInfo.queueFamilyIndexCount), wenn Sie VK_SHARING_MODE_CONCURRENT verwenden. Wenn Sie keinen gleichzeitigen Warteschlangenzugriff auf die Bilder benötigen, können Sie auch VK_SHARING_MODE_EXCLUSIVE verwenden, ohne dass Warteschlangenfamilienindizes angegeben werden müssen.

Wenn Sie mit verschiedenen Warteschlangenfamilienindizes (Grafiken und Rechenoperationen) arbeiten, ist es auch wichtig, in Ihren Barrieren über ihre srcQueueFamilyIndex- und dstQueueFamilyIndex-Mitglieder in beiden Richtungen eine ordnungsgemäße Warteschlangenfamilienbesitzübertragung durchzuführen.

Verwandte Themen