I am writing a game for Android devices which uses the Android NDK and Vulkan if it is supported (and OpenGL otherwise). I am currently working on doing shadows in Vulkan. This requires drawing in a framebuffer and using the results in the shader that is used to draw to the screen. I noticed that when I use a framebuffer with images the same size as the swapchain images, I get a lot of slow down and an error from the backend driver saying: "ioctl... failed: errno 35 Resource deadlock would occur". Eventually I get a device lost error (VK_ERROR_DEVICE_LOST). If I use a framebuffer with images that are half the width and half the height of the swapchain images, then everything works fine. In all cases, I get no error from the Vulkan validation layers.
I also get graphics corruption in other applications after I get the device lost error in my game. This is bad news, I think. I should not be able to affect other running programs.
The full text of the error is:
W/Adreno-GSL: <gsl_ldd_control:549>: ioctl fd 54 code 0x400c0907 (IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID) failed: errno 35 Resource deadlock would occur
Does anyone know why this would be happening? Am I doing something wrong? And if it is a driver error, any ideas on how to detect it without causing graphics corruption in my game or other programs?
device details:
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
The pipeline is created with:
VkViewport viewport = {};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float) VkSurfaceCapabilitiesKHR.currentExtent.width;
viewport.height = (float) VkSurfaceCapabilitiesKHR.currentExtent.height;
The framebuffer is created with:
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;
The images are created with:
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;
Please let me know if you need any more info from these structures or other code. It is all very long :-)
Output from the android device when the problem occurs:
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
The following function is being used to allocate all images:
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);
}
The color attachment is created with:
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;
The depth attachment is created with:
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;
User contributions licensed under CC BY-SA 3.0