Ошибка ioctl при рисовании в фреймбуфер в vulkan - PullRequest
0 голосов
/ 24 апреля 2020

Я пишу игру для 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;
...