From 5508073cba0ed22175614bcc8f02bbd0e938fd40 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 25 Sep 2023 12:09:52 +0200 Subject: [PATCH] rhi: vulkan: Print vma statistics on out of device memory Following a vmaCreate* it makes sense to test for VK_ERROR_OUT_OF_DEVICE_MEMORY and print the allocator statistics in order to give an idea of the application's (video) memory usage. For instance when running on a Raspberry Pi 4, this helps to indicate that the application is just too big for the device, and is more informative then just a Failed to create image: -2 message. Pick-to: 6.5 Change-Id: I666e2358303894efab9d12d2b3a3d98f0bd3a5b6 Reviewed-by: Andy Nichols Reviewed-by: Kristoffer Skau (cherry picked from commit 9f6a2e357b55998e7022fe9640a9acff26d7c64e) Reviewed-by: Qt Cherry-pick Bot --- src/gui/rhi/qrhivulkan.cpp | 22 ++++++++++++++++++++-- src/gui/rhi/qrhivulkan_p.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 108b93b266c..ba41c8bb7cf 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -3201,6 +3201,12 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level, } } +void QRhiVulkan::printExtraErrorInfo(VkResult err) +{ + if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) + qWarning() << "Out of device memory, current allocator statistics are" << statistics(); +} + void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates) { QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates); @@ -3238,6 +3244,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat bufD->stagingAllocations[currentFrameSlot] = allocation; } else { qWarning("Failed to create staging buffer of size %u: %d", bufD->m_size, err); + printExtraErrorInfo(err); continue; } } @@ -3326,6 +3333,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat readback.stagingAlloc = allocation; } else { qWarning("Failed to create readback buffer of size %u: %d", readback.byteSize, err); + printExtraErrorInfo(err); continue; } @@ -3375,6 +3383,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat &utexD->stagingBuffers[currentFrameSlot], &allocation, nullptr); if (err != VK_SUCCESS) { qWarning("Failed to create image staging buffer of size %d: %d", int(stagingSize), err); + printExtraErrorInfo(err); continue; } utexD->stagingAllocations[currentFrameSlot] = allocation; @@ -3531,6 +3540,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat readback.stagingAlloc = allocation; } else { qWarning("Failed to create readback buffer of size %u: %d", readback.byteSize, err); + printExtraErrorInfo(err); continue; } @@ -5830,7 +5840,8 @@ bool QVkBuffer::create() } if (err != VK_SUCCESS) { - qWarning("Failed to create buffer: %d", err); + qWarning("Failed to create buffer of size %u: %d", nonZeroSize, err); + rhiD->printExtraErrorInfo(err); return false; } @@ -6243,7 +6254,14 @@ bool QVkTexture::create() VmaAllocation allocation; VkResult err = vmaCreateImage(toVmaAllocator(rhiD->allocator), &imageInfo, &allocInfo, &image, &allocation, nullptr); if (err != VK_SUCCESS) { - qWarning("Failed to create image: %d", err); + qWarning("Failed to create image (with VkImageCreateInfo %ux%u depth %u vkformat 0x%X mips %u layers %u vksamples 0x%X): %d", + imageInfo.extent.width, imageInfo.extent.height, imageInfo.extent.depth, + int(imageInfo.format), + imageInfo.mipLevels, + imageInfo.arrayLayers, + int(imageInfo.samples), + err); + rhiD->printExtraErrorInfo(err); return false; } imageAlloc = allocation; diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h index fa35dcc4667..254adaae680 100644 --- a/src/gui/rhi/qrhivulkan_p.h +++ b/src/gui/rhi/qrhivulkan_p.h @@ -816,6 +816,7 @@ public: void updateShaderResourceBindings(QRhiShaderResourceBindings *srb, int descSetIdx = -1); void ensureCommandPoolForNewFrame(); double elapsedSecondsFromTimestamp(quint64 timestamp[2], bool *ok); + void printExtraErrorInfo(VkResult err); QVulkanInstance *inst = nullptr; QWindow *maybeWindow = nullptr;