Я использую Vulkan и GLFW, чтобы нарисовать окно. Когда я изменяю его размер несколько раз, сначала создание цепочки обмена каждый раз начинает давать сбой, а затем, после неопределенного количества ошибок, X11 просто вылетает из моего окна и печатает ошибки. Я использую Linux 6.18.13-arch1-1, EndeavourOS, KDE 6, драйвер mesa для графического процессора AMD.
[dbg::LOG_INFO] GLFW required instance extensions:
[dbg::LOG_INFO] VK_KHR_surface
[dbg::LOG_INFO] VK_KHR_xcb_surface
[dbg::LOG_INFO] Selected physical device: AMD Radeon RX 7600 (RADV NAVI33)
[dbg::LOG_INFO] VulkanNRI initialized with device: AMD Radeon RX 7600 (RADV NAVI33)
[dbg::LOG_INFO] Chosen surface format: B8G8R8A8Unorm, color space: SrgbNonlinear
[dbg::LOG_INFO] Creating swapchain for window with size 800x600
... logs loading fonts, will skip
[dbg::LOG_INFO] Creating swapchain for window with size 789x626
... 284 logs of me resizing the window
[dbg::LOG_INFO] Creating swapchain for window with size 438x531
[dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain
[dbg::LOG_INFO] Creating swapchain for window with size 524x503
[dbg::LOG_INFO] Creating swapchain for window with size 605x482
[dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain
[dbg::LOG_INFO] Creating swapchain for window with size 667x466
[dbg::LOG_INFO] Creating swapchain for window with size 698x456
[dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain
... 33 errors like this total
[dbg::LOG_INFO] Creating swapchain for window with size 958x497
[dbg::LOG_INFO] Creating swapchain for window with size 885x507
[dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 149 ()
Minor opcode of failed request: 4
Value in failed request: 0x6000e74
Serial number of failed request: 12370
Current serial number in output stream: 12386
void VulkanWindow::createSwapChain(uint32_t &width, uint32_t &height) {
this->width = width;
this->height = height;
auto &nri = static_cast(this->nri);
if (this->surface == nullptr) { THROW_RUNTIME_ERR("surface is not set for VulkanWindow!"); }
vk::SurfaceCapabilitiesKHR capabilities;
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(nri.getPhysicalDevice(), *surface,
(VkSurfaceCapabilitiesKHR *)&capabilities);
if (res != VK_SUCCESS) {
if (swapChain) vkDestroySwapchainKHR(nri.getDevice(), swapChain, nullptr);
swapChain = vkb::Swapchain();
return;
}
width = capabilities.maxImageExtent.width;
height = capabilities.maxImageExtent.height;
dbLog(dbg::LOG_INFO, "Creating swapchain for window with size ", width, "x", height);
vkb::SwapchainBuilder swapchainBuilder{nri.getPhysicalDevice(), nri.getDevice(), *surface};
swapchainBuilder.set_desired_present_mode((VkPresentModeKHR)vk::PresentModeKHR::eFifo);
swapchainBuilder.set_desired_format((VkSurfaceFormatKHR)vk::SurfaceFormatKHR(surfaceFormat, surfaceColorSpace));
swapchainBuilder.set_desired_extent(width, height);
swapchainBuilder.set_desired_min_image_count(capabilities.minImageCount + 1);
swapchainBuilder.set_required_min_image_count(capabilities.minImageCount);
if (swapChain != VK_NULL_HANDLE) swapchainBuilder.set_old_swapchain(swapChain);
swapchainBuilder.set_image_usage_flags(
VkImageUsageFlags(vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst));
swapchainBuilder.set_pre_transform_flags(VkSurfaceTransformFlagBitsKHR(vk::SurfaceTransformFlagBitsKHR::eIdentity));
auto swapchainResult = swapchainBuilder.build();
if (!swapchainResult.has_value()) {
dbLog(dbg::LOG_ERROR, "Failed to create swapchain: ", swapchainResult.error().message());
if (swapChain) vkDestroySwapchainKHR(nri.getDevice(), swapChain, nullptr);
this->swapChainImages.clear();
swapChain = vkb::Swapchain();
return;
}
swapChain = std::move(swapchainResult.value());
this->swapChainImages.clear();
std::vector swapChainImages;
uint32_t imageCount;
vkGetSwapchainImagesKHR(nri.getDevice(), swapChain, &imageCount, nullptr);
swapChainImages.resize(imageCount);
vkGetSwapchainImagesKHR(nri.getDevice(), swapChain, &imageCount, (VkImage *)swapChainImages.data());
for (const auto &image : swapChainImages) {
VulkanImage2D nriImage = VulkanImage2D(nri, image, vk::ImageLayout::eUndefined, vk::Format::eB8G8R8A8Unorm,
nri.getDevice(), width, height);
VulkanRenderTarget renderTarget = VulkanRenderTarget(nri, nriImage);
this->swapChainImages.emplace_back(std::move(nriImage), std::move(renderTarget));
this->swapChainImages.back().image.transitionLayout(
*commandBuffer, vk::ImageLayout::ePresentSrcKHR, vk::AccessFlagBits::eNone, vk::AccessFlagBits::eNone,
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eBottomOfPipe);
}
}
Вообще не самый чистый метод. Всегда создает цепочку обмена с максимально возможным разрешением. Здесь «NRI» — это моя концепция собственного интерфейса.
В начале кадра я делаю эквивалент:
glfwPollEvents();
if (swapChain == nullptr) {
createSwapChain(width, height);
// skip frame
} else {
// render everything and present. If present fails or returns SUBOPTIMAL, call createSwapChain()
}
Поиск в Интернете подсказал мне, что, возможно, у меня есть утечка рисуемых поверхностей X11, но я уничтожаю свои старые цепочки обмена. Пожалуйста помогите, буду очень благодарен.
Я использую Vulkan и GLFW, чтобы нарисовать окно. Когда я изменяю его размер несколько раз, сначала создание цепочки обмена каждый раз начинает давать сбой, а затем, после неопределенного количества ошибок, X11 просто вылетает из моего окна и печатает ошибки. Я использую Linux 6.18.13-arch1-1, EndeavourOS, KDE 6, драйвер mesa для графического процессора AMD. [code][dbg::LOG_INFO] GLFW required instance extensions: [dbg::LOG_INFO] VK_KHR_surface [dbg::LOG_INFO] VK_KHR_xcb_surface [dbg::LOG_INFO] Selected physical device: AMD Radeon RX 7600 (RADV NAVI33) [dbg::LOG_INFO] VulkanNRI initialized with device: AMD Radeon RX 7600 (RADV NAVI33) [dbg::LOG_INFO] Chosen surface format: B8G8R8A8Unorm, color space: SrgbNonlinear [dbg::LOG_INFO] Creating swapchain for window with size 800x600 ... logs loading fonts, will skip [dbg::LOG_INFO] Creating swapchain for window with size 789x626 ... 284 logs of me resizing the window [dbg::LOG_INFO] Creating swapchain for window with size 438x531 [dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain [dbg::LOG_INFO] Creating swapchain for window with size 524x503 [dbg::LOG_INFO] Creating swapchain for window with size 605x482 [dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain [dbg::LOG_INFO] Creating swapchain for window with size 667x466 [dbg::LOG_INFO] Creating swapchain for window with size 698x456 [dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain ... 33 errors like this total [dbg::LOG_INFO] Creating swapchain for window with size 958x497 [dbg::LOG_INFO] Creating swapchain for window with size 885x507 [dbg::LOG_ERROR] Failed to create swapchain: failed_create_swapchain X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 149 () Minor opcode of failed request: 4 Value in failed request: 0x6000e74 Serial number of failed request: 12370 Current serial number in output stream: 12386 [/code] Мой код для создания цепочки обмена: [code]void VulkanWindow::createSwapChain(uint32_t &width, uint32_t &height) { this->width = width; this->height = height; auto &nri = static_cast(this->nri); if (this->surface == nullptr) { THROW_RUNTIME_ERR("surface is not set for VulkanWindow!"); }
vk::SurfaceCapabilitiesKHR capabilities; VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(nri.getPhysicalDevice(), *surface, (VkSurfaceCapabilitiesKHR *)&capabilities); if (res != VK_SUCCESS) { if (swapChain) vkDestroySwapchainKHR(nri.getDevice(), swapChain, nullptr); swapChain = vkb::Swapchain(); return; }
width = capabilities.maxImageExtent.width; height = capabilities.maxImageExtent.height; dbLog(dbg::LOG_INFO, "Creating swapchain for window with size ", width, "x", height);
this->swapChainImages.emplace_back(std::move(nriImage), std::move(renderTarget)); this->swapChainImages.back().image.transitionLayout( *commandBuffer, vk::ImageLayout::ePresentSrcKHR, vk::AccessFlagBits::eNone, vk::AccessFlagBits::eNone, vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eBottomOfPipe); } } [/code] Вообще не самый чистый метод. Всегда создает цепочку обмена с максимально возможным разрешением. Здесь «NRI» — это моя концепция собственного интерфейса. В начале кадра я делаю эквивалент: [code]glfwPollEvents(); if (swapChain == nullptr) { createSwapChain(width, height); // skip frame } else { // render everything and present. If present fails or returns SUBOPTIMAL, call createSwapChain() } [/code] Поиск в Интернете подсказал мне, что, возможно, у меня есть утечка рисуемых поверхностей X11, но я уничтожаю свои старые цепочки обмена. Пожалуйста помогите, буду очень благодарен.