diff --git a/CMakeLists.txt b/CMakeLists.txt index 48c202c..42aa6d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,7 @@ add_library(${PROJECT_NAME} SHARED layer/private_data.cpp layer/surface_api.cpp layer/swapchain_api.cpp + layer/swapchain_maintenance_api.cpp util/timed_semaphore.cpp util/custom_allocator.cpp util/extension_list.cpp diff --git a/layer/VkLayer_window_system_integration.json b/layer/VkLayer_window_system_integration.json index 8ff1815..b46d181 100644 --- a/layer/VkLayer_window_system_integration.json +++ b/layer/VkLayer_window_system_integration.json @@ -36,10 +36,16 @@ "vkGetPhysicalDevicePresentRectanglesKHR" ] }, - {"name": "VK_EXT_swapchain_maintenance1", "spec_version": "1"} + { + "name": "VK_EXT_swapchain_maintenance1", + "spec_version": "1", + "entrypoints": [ + "vkReleaseSwapchainImagesEXT" + ] + } ], "disable_environment": { "DISABLE_WSI_LAYER": "1" } } -} +} \ No newline at end of file diff --git a/layer/layer.cpp b/layer/layer.cpp index f7b040c..97ebd07 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -33,6 +33,7 @@ #include "private_data.hpp" #include "surface_api.hpp" #include "swapchain_api.hpp" +#include "swapchain_maintenance_api.hpp" #include "util/extension_list.hpp" #include "util/custom_allocator.hpp" #include "wsi/wsi_factory.hpp" @@ -462,6 +463,13 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS GET_PROC_ADDR(vkCreateImage); GET_PROC_ADDR(vkBindImageMemory2); + /* VK_EXT_swapchain_maintenance1 */ + if (layer::device_private_data::get(device).is_device_extension_enabled( + VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME)) + { + GET_PROC_ADDR(vkReleaseSwapchainImagesEXT); + } + return layer::device_private_data::get(device).disp.get_user_enabled_entrypoint( device, layer::device_private_data::get(device).instance_data.api_version, funcName); } diff --git a/layer/private_data.hpp b/layer/private_data.hpp index db79999..60884b4 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -403,7 +403,9 @@ private: /* VK_KHR_get_memory_requirements2 */ \ EP(GetImageMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ EP(GetBufferMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) \ - EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, false) + EP(GetImageSparseMemoryRequirements2KHR, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1, \ + false) \ + EP(ReleaseSwapchainImagesEXT, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, VK_API_VERSION_1_1, false) /** * @brief Struct representing the device dispatch table. diff --git a/layer/swapchain_api.cpp b/layer/swapchain_api.cpp index 645befc..3183a16 100644 --- a/layer/swapchain_api.cpp +++ b/layer/swapchain_api.cpp @@ -117,7 +117,6 @@ wsi_layer_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc, uint64_t } assert(swapc != VK_NULL_HANDLE); - assert(semaphore != VK_NULL_HANDLE || fence != VK_NULL_HANDLE); assert(pImageIndex != nullptr); auto *sc = reinterpret_cast(swapc); return sc->acquire_next_image(timeout, semaphore, fence, pImageIndex); diff --git a/layer/swapchain_maintenance_api.cpp b/layer/swapchain_maintenance_api.cpp new file mode 100644 index 0000000..ad27352 --- /dev/null +++ b/layer/swapchain_maintenance_api.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file swapchain_maintenance_api.cpp + * + * @brief Contains the Vulkan entrypoints for the swapchain maintenance. + */ + +#include "swapchain_maintenance_api.hpp" +#include "private_data.hpp" + +#include +#include + +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkReleaseSwapchainImagesEXT(VkDevice device, const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo) VWL_API_POST +{ + if (pReleaseInfo == nullptr || pReleaseInfo->imageIndexCount == 0) + { + return VK_SUCCESS; + } + + assert(pReleaseInfo->pImageIndices != nullptr); + assert(pReleaseInfo->swapchain != VK_NULL_HANDLE); + + auto &device_data = layer::device_private_data::get(device); + if (!device_data.layer_owns_swapchain(pReleaseInfo->swapchain)) + { + return device_data.disp.ReleaseSwapchainImagesEXT(device, pReleaseInfo); + } + + auto *sc = reinterpret_cast(pReleaseInfo->swapchain); + sc->release_images(pReleaseInfo->imageIndexCount, pReleaseInfo->pImageIndices); + + return VK_SUCCESS; +} \ No newline at end of file diff --git a/layer/swapchain_maintenance_api.hpp b/layer/swapchain_maintenance_api.hpp new file mode 100644 index 0000000..0890ad5 --- /dev/null +++ b/layer/swapchain_maintenance_api.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file swapchain_maintenance_api.hpp + * + * @brief Contains the Vulkan entrypoints for the swapchain maintenance. + */ + +#pragma once + +#include +#include "util/macros.hpp" + +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkReleaseSwapchainImagesEXT(VkDevice device, + const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo) VWL_API_POST; \ No newline at end of file diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index fd014c3..d5654df 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -693,4 +693,16 @@ VkResult swapchain_base::wait_for_free_buffer(uint64_t timeout) return retval; } +void swapchain_base::release_images(uint32_t image_count, const uint32_t *indices) +{ + for (uint32_t i = 0; i < image_count; i++) + { + uint32_t index = indices[i]; + assert(index < m_swapchain_images.size()); + /* Applications can only pass acquired images that the device doesn't own */ + assert(m_swapchain_images[index].status == swapchain_image::ACQUIRED); + unpresent_image(index); + } +} + } /* namespace wsi */ diff --git a/wsi/swapchain_base.hpp b/wsi/swapchain_base.hpp index 3371768..553de83 100644 --- a/wsi/swapchain_base.hpp +++ b/wsi/swapchain_base.hpp @@ -214,6 +214,15 @@ public: */ VkResult get_swapchain_status(); + /** + * @brief Release all images not belonging to the device + * by making them available to be acquired again + * + * @param image_count Amount of images in the indices array + * @param indices Array of image indices + */ + void release_images(uint32_t image_count, const uint32_t *indices); + protected: layer::device_private_data &m_device_data;