Я пишу игру для Android устройств , которая использует Android NDK и Vulkan , если это поддерживается (и OpenGL в противном случае). В настоящее время я работаю над созданием теней в Вулкане. Для этого требуется рисование в буфере кадров и использование результатов в шейдере, который используется для рисования на экране. Я заметил, что когда я использую кадровый буфер с изображениями того же размера, что и образы подкачки, я сильно замедляюсь и из-за драйвера бэкэнда выдает ошибку: «ioctl ... fail: errno 35 Возникнет тупик ресурсов». В конце концов я получаю сообщение об ошибке устройства (VK_ERROR_DEVICE_LOST). Если я использую framebuffer с изображениями, которые имеют половину ширины и половину высоты изображений swapchain, то все работает нормально. Во всех случаях я не получаю ошибки от слоев проверки Vulkan.
Я также получаю повреждение графики в других приложениях после того, как в моей игре произошла ошибка потери устройства. Это плохие новости, я думаю. Я не должен иметь возможности влиять на другие работающие программы.
Полный текст ошибки:
W/Adreno-GSL: <gsl_ldd_control:549>: ioctl fd 54 code 0x400c0907 (IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID) failed: errno 35 Resource deadlock would occur
Кто-нибудь знает, почему это происходит? Я делаю что-то неправильно? И если это ошибка драйвера, есть идеи, как ее обнаружить, не вызывая повреждения графики в моей игре или других программах?
сведения об устройстве:
name: Pixel 4XL phone
Vulkan API version: 1.1.87
Vulkan device name: Adreno (TM) 640
NDK version: I tried 20.1.5948944 and 21.0.6113669. They both have the problem.
Android version: 10
VkPhysicalDeviceProperties.limits.maxImageDimension2D = 16384
VkPhysicalDeviceProperties.limits.maxFramebufferWidth = 16384
VkPhysicalDeviceProperties.limits.maxFramebufferHeight = 16384
VkSurfaceCapabilitiesKHR.currentExtent.width = 1440
VkSurfaceCapabilitiesKHR.currentExtent.height = 2690
Width of the images in the framebuffer when the problem occurred: 1440
Height of the images in the framebuffer when the problem occurred: 2690
Конвейер создается с помощью:
VkViewport viewport = {};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float) VkSurfaceCapabilitiesKHR.currentExtent.width;
viewport.height = (float) VkSurfaceCapabilitiesKHR.currentExtent.height;
Framebuffer создается с помощью:
VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = inRenderPass->renderPass().get();
framebufferInfo.attachmentCount = static_cast<uint32_t>(inAttachments.size());
framebufferInfo.pAttachments = inAttachments.data();
framebufferInfo.width = VkSurfaceCapabilitiesKHR.currentExtent.width;
framebufferInfo.height = VkSurfaceCapabilitiesKHR.currentExtent.height;
framebufferInfo.layers = 1;
Изображения создаются с помощью:
VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = VkSurfaceCapabilitiesKHR.currentExtent.width;
imageInfo.extent.height = VkSurfaceCapabilitiesKHR.currentExtent.height;
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация от эти структуры или другой код. Все это очень долго: -)
Вывод с устройства android при возникновении проблемы:
04/23 21:09:22: Launching 'app' on Google Pixel 4 XL.
$ adb shell am start -n "com.quasar.cerulean.amazinglabyrinth/com.quasar.cerulean.amazinglabyrinth.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Waiting for process to come online...
Connected to process 7507 on device 'google-pixel_4_xl-**************'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
W/mazinglabyrint: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/mazinglabyrint: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
I/Adreno: QUALCOMM build : 9b214d0, Ibc75db1fca
Build Date : 06/30/19
OpenGL ES Shader Compiler Version: EV031.26.06.00
Local Branch : AU124
Remote Branch :
Remote Branch :
Reconstruct Branch :
Build Config : S P 8.0.6 AArch64
I/Adreno: PFP: 0x016ee185, ME: 0x00000000
D/vulkan: searching for layers in '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64'
D/vulkan: added global layer 'VK_LAYER_LUNARG_parameter_validation' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_parameter_validation.so'
D/vulkan: added global layer 'VK_LAYER_KHRONOS_validation' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_khronos_validation.so'
D/vulkan: added global layer 'VK_LAYER_GOOGLE_unique_objects' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_unique_objects.so'
D/vulkan: added global layer 'VK_LAYER_GOOGLE_threading' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_threading.so'
D/vulkan: added global layer 'VK_LAYER_LUNARG_object_tracker' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_object_tracker.so'
D/vulkan: added global layer 'VK_LAYER_LUNARG_core_validation' from library '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/lib/arm64/libVkLayer_core_validation.so'
D/vulkan: searching for layers in '/data/app/com.quasar.cerulean.amazinglabyrinth-************************/base.apk!/lib/arm64-v8a'
I/vulkan: Loaded layer VK_LAYER_KHRONOS_validation
I/Adreno: QUALCOMM build : 9b214d0, Ibc75db1fca
Build Date : 06/30/19
Shader Compiler Version : EV031.26.06.00
Local Branch : AU124
Remote Branch :
Remote Branch :
Reconstruct Branch :
Build Config : S P 8.0.6 AArch64
E/Looper: Invalid attempt to set NULL callback but not allowed for this looper.
W/Adreno-GSL: <gsl_ldd_control:549>: ioctl fd 54 code 0x400c0907 (IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID) failed: errno 35 Resource deadlock would occur
<log_gpu_snapshot:458>: panel.gpuSnapshotPath is not set.not generating user snapshot
Следующая функция используется для выделения всех изображений:
void Image::createImage(VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage,
VkMemoryPropertyFlags properties) {
VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = m_width;
imageInfo.extent.height = m_height;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.format = format;
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = usage;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
VkImage imageRaw;
if (vkCreateImage(m_device->logicalDevice().get(), &imageInfo, nullptr, &imageRaw) != VK_SUCCESS) {
throw std::runtime_error("failed to create image!");
}
auto const &capDevice = m_device;
auto imageDeleter = [capDevice](VkImage imageRaw) {
vkDestroyImage(capDevice->logicalDevice().get(), imageRaw, nullptr);
};
m_image.reset(imageRaw, imageDeleter);
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(m_device->logicalDevice().get(), m_image.get(), &memRequirements);
VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = m_device->findMemoryType(memRequirements.memoryTypeBits, properties);
VkDeviceMemory imageMemoryRaw;
if (vkAllocateMemory(m_device->logicalDevice().get(), &allocInfo, nullptr, &imageMemoryRaw) !=
VK_SUCCESS) {
throw std::runtime_error("failed to allocate image memory!");
}
auto memoryDeleter = [capDevice](VkDeviceMemory imageMemoryRaw) {
vkFreeMemory(capDevice->logicalDevice().get(), imageMemoryRaw, nullptr);
};
m_imageMemory.reset(imageMemoryRaw, memoryDeleter);
vkBindImageMemory(m_device->logicalDevice().get(), m_image.get(), m_imageMemory.get(), 0);
}
Цветовое вложение создается с помощью:
createImage(
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
m_width = m_swapChain->extent().width;
m_height = m_swapChain->extent().height;
Глубинное вложение создается с помощью:
createImage(
VK_FORMAT_D32_SFLOAT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
m_width = m_swapChain->extent().width;
m_height = m_swapChain->extent().height;