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);
}
Alle Fehler/Warnungen von den Validierungsebenen? Ist der Zaun auch bei der Queue-Submission-Zeit nicht signiert? –
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
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). –