From 9d4485cdbb749824f27d234e7d55a3b05e02e475 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Fri, 15 May 2026 18:05:21 -0500 Subject: [PATCH 1/2] test: Check errors in InitSwapchain Also initialize count variables to zero. --- tests/vkrenderframework.cpp | 55 +++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp index c7722c12..21ef0958 100644 --- a/tests/vkrenderframework.cpp +++ b/tests/vkrenderframework.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2015-2022 The Khronos Group Inc. - * Copyright (c) 2015-2025 Valve Corporation - * Copyright (c) 2015-2025 LunarG, Inc. + * Copyright (c) 2015-2026 Valve Corporation + * Copyright (c) 2015-2027 LunarG, Inc. * Copyright (c) 2015-2022 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -681,23 +681,38 @@ bool VkRenderFramework::InitSwapchain(VkImageUsageFlags imageUsage, VkSurfaceTra bool VkRenderFramework::InitSwapchain(VkSurfaceKHR &surface, VkImageUsageFlags imageUsage, VkSurfaceTransformFlagBitsKHR preTransform) { - VkSurfaceCapabilitiesKHR capabilities; - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_device->phy().handle(), surface, &capabilities); - - uint32_t format_count; - vkGetPhysicalDeviceSurfaceFormatsKHR(m_device->phy().handle(), surface, &format_count, nullptr); + VkSurfaceCapabilitiesKHR capabilities{}; + VkResult err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_device->phy().handle(), surface, &capabilities); + if (err != VK_SUCCESS) { + return false; + } + uint32_t format_count = 0; + err = vkGetPhysicalDeviceSurfaceFormatsKHR(m_device->phy().handle(), surface, &format_count, nullptr); + if (err != VK_SUCCESS) { + return false; + } vector formats; if (format_count != 0) { formats.resize(format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(m_device->phy().handle(), surface, &format_count, formats.data()); + err = vkGetPhysicalDeviceSurfaceFormatsKHR(m_device->phy().handle(), surface, &format_count, formats.data()); + if (err != VK_SUCCESS) { + return false; + } } - uint32_t present_mode_count; - vkGetPhysicalDeviceSurfacePresentModesKHR(m_device->phy().handle(), surface, &present_mode_count, nullptr); + uint32_t present_mode_count = 0; + err = vkGetPhysicalDeviceSurfacePresentModesKHR(m_device->phy().handle(), surface, &present_mode_count, nullptr); + if (err != VK_SUCCESS) { + return false; + } vector present_modes; if (present_mode_count != 0) { present_modes.resize(present_mode_count); - vkGetPhysicalDeviceSurfacePresentModesKHR(m_device->phy().handle(), surface, &present_mode_count, present_modes.data()); + err = + vkGetPhysicalDeviceSurfacePresentModesKHR(m_device->phy().handle(), surface, &present_mode_count, present_modes.data()); + if (err != VK_SUCCESS) { + return false; + } } VkSwapchainCreateInfoKHR swapchain_create_info = {}; @@ -721,15 +736,21 @@ bool VkRenderFramework::InitSwapchain(VkSurfaceKHR &surface, VkImageUsageFlags i swapchain_create_info.clipped = VK_FALSE; swapchain_create_info.oldSwapchain = 0; - VkResult err = vkCreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain); + err = vkCreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain); if (err != VK_SUCCESS) { return false; } uint32_t imageCount = 0; - vkGetSwapchainImagesKHR(device(), m_swapchain, &imageCount, nullptr); + err = vkGetSwapchainImagesKHR(device(), m_swapchain, &imageCount, nullptr); + if (err != VK_SUCCESS) { + return false; + } vector swapchainImages; swapchainImages.resize(imageCount); - vkGetSwapchainImagesKHR(device(), m_swapchain, &imageCount, swapchainImages.data()); + err = vkGetSwapchainImagesKHR(device(), m_swapchain, &imageCount, swapchainImages.data()); + if (err != VK_SUCCESS) { + return false; + } return true; } @@ -1191,7 +1212,7 @@ void VkImageObj::ImageMemoryBarrier(VkCommandBufferObj *cmd_buf, VkImageAspectFl // write barrier to the command buffer vkCmdPipelineBarrier(cmd_buf->handle(), src_stages, dest_stages, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, - pmemory_barrier); + pmemory_barrier); } void VkImageObj::SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkImageLayout image_layout) { @@ -1983,7 +2004,7 @@ void VkCommandBufferObj::PipelineBarrier(VkPipelineStageFlags src_stages, VkPipe const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { vkCmdPipelineBarrier(handle(), src_stages, dest_stages, dependencyFlags, memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); + bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); } void VkCommandBufferObj::ClearAllBuffers(const vector> &color_objs, VkClearColorValue clear_color, @@ -2125,7 +2146,7 @@ void VkCommandBufferObj::BindDescriptorSet(VkDescriptorSetObj &descriptorSet) { // bind pipeline, vertex buffer (descriptor set) and WVP (dynamic buffer view) if (set_obj) { vkCmdBindDescriptorSets(handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, descriptorSet.GetPipelineLayout(), 0, 1, &set_obj, 0, - NULL); + NULL); } } From 9fb7e4288ff669d058673c2b19f6d0670187f92c Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Fri, 15 May 2026 09:34:13 -0500 Subject: [PATCH 2/2] tests: Support wayland in render framework Since wayland has become the default display environment, tests should create a wayland surface to better match expected running conditions. The base of the code was primarily the Vulkan-ValidationLayer test framework, which incidentally is where much of this repositories test framework is based on. --- tests/extension_layer_tests.cpp | 19 ++++++- tests/vkrenderframework.cpp | 89 ++++++++++++++++++++++++++++----- 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/tests/extension_layer_tests.cpp b/tests/extension_layer_tests.cpp index 2a75e3db..6e4fd9b5 100755 --- a/tests/extension_layer_tests.cpp +++ b/tests/extension_layer_tests.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2015-2022 The Khronos Group Inc. - * Copyright (c) 2015-2024 Valve Corporation - * Copyright (c) 2015-2024 LunarG, Inc. + * Copyright (c) 2015-2026 Valve Corporation + * Copyright (c) 2015-2026 LunarG, Inc. * Copyright (c) 2015-2022 Google, Inc. * Copyright (c) 2015-2023 Nvidia Corporation. * @@ -28,6 +28,10 @@ #include "extension_layer_tests.h" #include +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) +#include +#endif + // Global list of sType,size identifiers std::vector> custom_stype_info{}; @@ -362,6 +366,17 @@ bool VkExtensionLayerTest::AddSurfaceInstanceExtension() { bSupport = true; #endif +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (!InstanceExtensionSupported(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { + printf("%s %s extension not supported\n", kSkipPrefix, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + return false; + } + if (!bSupport && wl_display_connect(nullptr)) { + instance_extensions_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + bSupport = true; + } +#endif + #if defined(VK_USE_PLATFORM_XLIB_KHR) if (!InstanceExtensionSupported(VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) { printf("%s %s extension not supported\n", kSkipPrefix, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp index 21ef0958..34175b52 100644 --- a/tests/vkrenderframework.cpp +++ b/tests/vkrenderframework.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2015-2022 The Khronos Group Inc. * Copyright (c) 2015-2026 Valve Corporation - * Copyright (c) 2015-2027 LunarG, Inc. + * Copyright (c) 2015-2026 LunarG, Inc. * Copyright (c) 2015-2022 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,10 @@ #include +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) +#include +#endif + using std::string; using std::strncmp; using std::vector; @@ -639,21 +643,82 @@ bool VkRenderFramework::InitSurface(float width, float height) { if (err != VK_SUCCESS) return false; #endif -#if defined(VK_USE_PLATFORM_XLIB_KHR) - Display *dpy = XOpenDisplay(NULL); - if (dpy) { - int s = DefaultScreen(dpy); - Window window = XCreateSimpleWindow(dpy, RootWindow(dpy, s), 0, 0, (int)m_width, (int)m_height, 1, BlackPixel(dpy, s), - WhitePixel(dpy, s)); - VkXlibSurfaceCreateInfoKHR surface_create_info = {}; - surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - surface_create_info.dpy = dpy; - surface_create_info.window = window; - VkResult err = vkCreateXlibSurfaceKHR(instance(), &surface_create_info, nullptr, &m_surface); +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (m_surface == VK_NULL_HANDLE) { + wl_display *display = nullptr; + wl_registry *registry = nullptr; + wl_surface *surface = nullptr; + wl_compositor *compositor = nullptr; + display = wl_display_connect(nullptr); + if (!display) { + return false; + } + + auto global = [](void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { + (void)version; + const std::string_view interface_str = interface; + if (interface_str == "wl_compositor") { + auto compositor = reinterpret_cast(data); + *compositor = reinterpret_cast(wl_registry_bind(registry, id, &wl_compositor_interface, 1)); + } + }; + + auto global_remove = [](void *data, struct wl_registry *registry, uint32_t id) { + (void)data; + (void)registry; + (void)id; + }; + + registry = wl_display_get_registry(display); + if (!registry) { + return false; + } + + const wl_registry_listener registry_listener = {global, global_remove}; + + wl_registry_add_listener(registry, ®istry_listener, &compositor); + + wl_display_dispatch(display); + if (!compositor) { + return false; + } + + surface = wl_compositor_create_surface(compositor); + if (!surface) { + return false; + } + + const uint32_t version = wl_surface_get_version(surface); + if (version == 0) { + return false; + } + + VkWaylandSurfaceCreateInfoKHR surface_create_info = {}; + surface_create_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + surface_create_info.display = display; + surface_create_info.surface = surface; + VkResult err = vkCreateWaylandSurfaceKHR(instance(), &surface_create_info, nullptr, &m_surface); if (err != VK_SUCCESS) return false; } #endif +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (m_surface == VK_NULL_HANDLE) { + Display *dpy = XOpenDisplay(NULL); + if (dpy) { + int s = DefaultScreen(dpy); + Window window = XCreateSimpleWindow(dpy, RootWindow(dpy, s), 0, 0, (int)m_width, (int)m_height, 1, BlackPixel(dpy, s), + WhitePixel(dpy, s)); + VkXlibSurfaceCreateInfoKHR surface_create_info = {}; + surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + surface_create_info.dpy = dpy; + surface_create_info.window = window; + VkResult err = vkCreateXlibSurfaceKHR(instance(), &surface_create_info, nullptr, &m_surface); + if (err != VK_SUCCESS) return false; + } + } +#endif + #if defined(VK_USE_PLATFORM_XCB_KHR) if (m_surface == VK_NULL_HANDLE) { xcb_connection_t *connection = xcb_connect(NULL, NULL);