diff --git a/.gitmodules b/.gitmodules index 2eed470..4a30702 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,12 @@ [submodule "khronos/vulkan"] path = source_third_party/khronos/vulkan url = https://github.com/KhronosGroup/Vulkan-Headers -[submodule "khronos/opengles"] - path = source_third_party/khronos/opengles - url = https://github.com/KhronosGroup/OpenGL-Registry -[submodule "khronos/egl"] - path = source_third_party/khronos/egl - url = https://github.com/KhronosGroup/EGL-Registry [submodule "source_third_party/gtest"] path = source_third_party/gtest url = https://github.com/google/googletest [submodule "source_third_party/protopuf"] path = source_third_party/protopuf url = https://github.com/PragmaTwice/protopuf.git +[submodule "source_third_party/khronos/vulkan-utilities"] + path = source_third_party/khronos/vulkan-utilities + url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries/ diff --git a/generator/vk_codegen/source_CMakeLists.txt b/generator/vk_codegen/source_CMakeLists.txt index eb6e595..12df760 100644 --- a/generator/vk_codegen/source_CMakeLists.txt +++ b/generator/vk_codegen/source_CMakeLists.txt @@ -53,7 +53,8 @@ target_include_directories( target_include_directories( ${VK_LAYER} SYSTEM PRIVATE - ../../source_third_party/khronos/vulkan/include/) + ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${VK_LAYER}) diff --git a/layer_example/source/CMakeLists.txt b/layer_example/source/CMakeLists.txt index 46a95d1..adfa709 100644 --- a/layer_example/source/CMakeLists.txt +++ b/layer_example/source/CMakeLists.txt @@ -54,7 +54,8 @@ target_include_directories( target_include_directories( ${VK_LAYER} SYSTEM PRIVATE - ../../source_third_party/khronos/vulkan/include/) + ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${VK_LAYER}) diff --git a/layer_gpu_support/source/CMakeLists.txt b/layer_gpu_support/source/CMakeLists.txt index 0b3338b..4b224de 100644 --- a/layer_gpu_support/source/CMakeLists.txt +++ b/layer_gpu_support/source/CMakeLists.txt @@ -62,7 +62,8 @@ target_include_directories( target_include_directories( ${VK_LAYER} SYSTEM PRIVATE ../../source_third_party/ - ../../source_third_party/khronos/vulkan/include/) + ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${VK_LAYER}) diff --git a/layer_gpu_support/source/layer_device_functions_image.cpp b/layer_gpu_support/source/layer_device_functions_image.cpp index f29851c..c7c9b6d 100644 --- a/layer_gpu_support/source/layer_device_functions_image.cpp +++ b/layer_gpu_support/source/layer_device_functions_image.cpp @@ -22,6 +22,8 @@ * IN THE SOFTWARE. * ---------------------------------------------------------------------------- */ +#include +#include #include "device.hpp" #include "framework/device_dispatch_table.hpp" @@ -119,40 +121,36 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateImage(VkDevice device, } } - VkImageCreateInfo newCreateInfo = *pCreateInfo; - - VkImageCompressionControlEXT newCompressionControl; - // TODO: This currently relies on const_cast to make user struct writable - // We should replace this with a generic clone (issue #56) - auto* userCompressionControl = - searchNextList(VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT, - pCreateInfo->pNext); + // Create modifiable structures we can patch + vku::safe_VkImageCreateInfo newCreateInfoSafe(pCreateInfo); + auto* newCreateInfo = reinterpret_cast(&newCreateInfoSafe); + void* pNextBase = const_cast(newCreateInfoSafe.pNext); + // Create extra structures we allocate here, but populate elsewhere + VkImageCompressionControlEXT newCompressionControl = vku::InitStructHelper(); VkImageCompressionControlEXT* compressionControl = &newCompressionControl; + + auto* userCompressionControl = vku::FindStructInPNextChain(pNextBase); if (userCompressionControl) { compressionControl = userCompressionControl; } bool patchNeeded = compressionControl != userCompressionControl; - if (forceDisable) { - compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT; compressionControl->flags = VK_IMAGE_COMPRESSION_DISABLED_EXT; compressionControl->compressionControlPlaneCount = 0; compressionControl->pFixedRateFlags = nullptr; } else if (forceDefault) { - compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT; compressionControl->flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT; compressionControl->compressionControlPlaneCount = 0; compressionControl->pFixedRateFlags = nullptr; } else if (selectedLevel) { - compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT; compressionControl->flags = VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT; compressionControl->compressionControlPlaneCount = 1; compressionControl->pFixedRateFlags = reinterpret_cast(&selectedLevel); @@ -162,12 +160,11 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateImage(VkDevice device, patchNeeded = false; } - // If this is new, patch it in to the pNext chain + // Add a config if not already configured by the application if (patchNeeded) { - compressionControl->pNext = newCreateInfo.pNext; - newCreateInfo.pNext = reinterpret_cast(compressionControl); + vku::AddToPnext(newCreateInfoSafe, *compressionControl); } - return layer->driver.vkCreateImage(device, &newCreateInfo, pAllocator, pImage); + return layer->driver.vkCreateImage(device, newCreateInfo, pAllocator, pImage); } diff --git a/layer_gpu_timeline/source/CMakeLists.txt b/layer_gpu_timeline/source/CMakeLists.txt index 6b626a5..a8b575f 100644 --- a/layer_gpu_timeline/source/CMakeLists.txt +++ b/layer_gpu_timeline/source/CMakeLists.txt @@ -66,6 +66,7 @@ target_include_directories( ${VK_LAYER} SYSTEM PRIVATE ../../source_third_party/ ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/ ../../source_third_party/protopuf/include/) lgl_set_build_options(${VK_LAYER}) diff --git a/source_common/comms/CMakeLists.txt b/source_common/comms/CMakeLists.txt index 6bccecb..5b521e5 100644 --- a/source_common/comms/CMakeLists.txt +++ b/source_common/comms/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # ----------------------------------------------------------------------------- -# Copyright (c) 2024 Arm Limited +# Copyright (c) 2024-2025 Arm Limited # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -33,7 +33,8 @@ add_library( target_include_directories( ${LIB_BINARY} PRIVATE ../ - ../../source_third_party/khronos/vulkan/include/) + ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${LIB_BINARY}) @@ -41,4 +42,4 @@ if(${LGL_UNITTEST}) add_subdirectory(test) endif() -add_clang_tools() \ No newline at end of file +add_clang_tools() diff --git a/source_common/comms/test/CMakeLists.txt b/source_common/comms/test/CMakeLists.txt index 8c77684..8fc0756 100644 --- a/source_common/comms/test/CMakeLists.txt +++ b/source_common/comms/test/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # ----------------------------------------------------------------------------- -# Copyright (c) 2024 Arm Limited +# Copyright (c) 2024-2025 Arm Limited # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -34,6 +34,7 @@ target_include_directories( ../../ ../../../source_third_party/ ../../../source_third_party/khronos/vulkan/include + ../../source_third_party/khronos/vulkan-utilities/include/ ${gtest_SOURCE_DIR}/include) target_link_libraries( @@ -76,4 +77,4 @@ install( TARGETS ${TEST_BINARY} DESTINATION bin) -add_clang_tools() \ No newline at end of file +add_clang_tools() diff --git a/source_common/framework/CMakeLists.txt b/source_common/framework/CMakeLists.txt index a6de453..b3242f6 100644 --- a/source_common/framework/CMakeLists.txt +++ b/source_common/framework/CMakeLists.txt @@ -26,9 +26,14 @@ set(LIB_BINARY lib_layer_framework) add_library( ${LIB_BINARY} STATIC device_functions.cpp - device_query.cpp instance_functions.cpp - manual_functions.cpp) + manual_functions.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_core.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_ext.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_khr.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_manual.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_utils.cpp + ../../source_third_party/khronos/vulkan-utilities/src/vulkan/vk_safe_struct_vendor.cpp) target_include_directories( ${LIB_BINARY} PRIVATE @@ -41,8 +46,9 @@ target_include_directories( ${LIB_BINARY} SYSTEM PRIVATE ../ ../../source_third_party/ - ../../source_third_party/khronos/vulkan/include/) + ../../source_third_party/khronos/vulkan/include/ + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${LIB_BINARY}) -add_clang_tools() \ No newline at end of file +add_clang_tools() diff --git a/source_common/framework/device_query.cpp b/source_common/framework/device_query.cpp deleted file mode 100644 index 974f48c..0000000 --- a/source_common/framework/device_query.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * ---------------------------------------------------------------------------- - * Copyright (c) 2025 Arm Limited - * - * 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. - * ---------------------------------------------------------------------------- - */ - -#include "utils/misc.hpp" - -#include - -/** See header for documentation. */ -bool isEnabledVkKhrTimelineSemaphore(const VkDeviceCreateInfo& createInfo) -{ - // Check Vulkan 1.2 core feature first - auto* coreFeature = - searchNextList(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - createInfo.pNext); - if (coreFeature) - { - return coreFeature->timelineSemaphore; - } - - // Check the extension second - bool extEnabled = isInExtensionList(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, - createInfo.enabledExtensionCount, - createInfo.ppEnabledExtensionNames); - if (!extEnabled) - { - return false; - } - - auto* extFeature = searchNextList( - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, - createInfo.pNext); - if (extFeature) - { - return extFeature->timelineSemaphore; - } - - return false; -} diff --git a/source_common/framework/device_query.hpp b/source_common/framework/device_query.hpp deleted file mode 100644 index d939016..0000000 --- a/source_common/framework/device_query.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * ---------------------------------------------------------------------------- - * Copyright (c) 2025 Arm Limited - * - * 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 - * This module implements device property query functions. - */ - -#pragma once - -#include "utils/misc.hpp" - -#include - -/** - * Test if VK_KHR_timeline_semaphore (or equivalent core feature) is enabled. - * - * @param createInfo The device creation configuration. - * - * @return @c true if enabled, @c false otherwise. - */ -bool isEnabledVkKhrTimelineSemaphore(const VkDeviceCreateInfo& createInfo0); diff --git a/source_common/framework/manual_functions.cpp b/source_common/framework/manual_functions.cpp index 5a35e19..ac30a8e 100644 --- a/source_common/framework/manual_functions.cpp +++ b/source_common/framework/manual_functions.cpp @@ -29,9 +29,10 @@ * implemented as library code which can be swapped for alternative * implementations on a per-layer basis if needed. */ +#include +#include #include "framework/manual_functions.hpp" - #include "utils/misc.hpp" /** @@ -342,10 +343,11 @@ std::vector cloneExtensionList(uint32_t extensionCount, const char* * * Enabling this requires passing the extension string to vkCreateInstance(). * - * @param supported The list of supported extension, or empty if unknown. - * @param active The list of active extensions. + * @param createInfo The createInfo we can search to find user config. + * @param supported The list of supported extension, or empty if unknown. */ -static void enableInstanceVkExtDebugUtils(const std::vector& supported, std::vector& active) +static void enableInstanceVkExtDebugUtils(vku::safe_VkInstanceCreateInfo& createInfo, + const std::vector& supported) { static const std::string target {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}; @@ -357,16 +359,15 @@ static void enableInstanceVkExtDebugUtils(const std::vector& suppor return; } - // If it is already enabled then do nothing - if (isIn(target, active)) + // Enable the extension - this will skip adding if already enabled + if (vku::AddExtension(createInfo, target.c_str())) + { + LAYER_LOG("Instance extension added: %s", target.c_str()); + } + else { LAYER_LOG("Instance extension already enabled: %s", target.c_str()); - return; } - - // Else add it to the list of enable extensions - LAYER_LOG("Instance extension added: %s", target.c_str()); - active.push_back(target.c_str()); } /** @@ -381,15 +382,15 @@ static void enableInstanceVkExtDebugUtils(const std::vector& suppor * * @param createInfo The createInfo we can search to find user config. * @param supported The list of supported extensions. - * @param active The list of active extensions. * @param newFeatures Pre-allocated struct we can use if we need to add it. */ -static void enableDeviceVkKhrTimelineSemaphore(VkDeviceCreateInfo& createInfo, - std::vector& supported, - std::vector& active, - VkPhysicalDeviceTimelineSemaphoreFeatures newFeatures) +static void enableDeviceVkKhrTimelineSemaphore(vku::safe_VkDeviceCreateInfo& createInfo, + const std::vector& supported, + VkPhysicalDeviceTimelineSemaphoreFeatures& newFeatures) { static const std::string target {VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME}; + // We know we can const-cast here because this is a safe struct clone + void* pNextBase = const_cast(createInfo.pNext); // Test if the desired extension is supported if (!isIn(target, supported)) @@ -398,20 +399,14 @@ static void enableDeviceVkKhrTimelineSemaphore(VkDeviceCreateInfo& createInfo, return; } - // If it is not already enabled then add to the list - if (!isIn(target, active)) + // Enable the extension - this will skip adding if already enabled + if (vku::AddExtension(createInfo, target.c_str())) { LAYER_LOG("Device extension added: %s", target.c_str()); - active.push_back(target.c_str()); } // Check if user provided a VkPhysicalDeviceTimelineSemaphoreFeatures - // TODO: This currently relies on const_cast to make user struct writable - // We should replace this with a generic clone (issue #56) - auto* config1 = searchNextList( - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, - createInfo.pNext); - + auto* config1 = vku::FindStructInPNextChain(pNextBase); if (config1) { if (!config1->timelineSemaphore) @@ -426,12 +421,7 @@ static void enableDeviceVkKhrTimelineSemaphore(VkDeviceCreateInfo& createInfo, } // Check if user provided a VkPhysicalDeviceVulkan12Features - // TODO: This currently relies on const_cast to make user struct writable - // We should replace this with a generic clone (issue #56) - auto* config2 = - searchNextList(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - createInfo.pNext); - + auto* config2 = vku::FindStructInPNextChain(pNextBase); if (config2) { if (!config2->timelineSemaphore) @@ -448,10 +438,8 @@ static void enableDeviceVkKhrTimelineSemaphore(VkDeviceCreateInfo& createInfo, // Add a config if not configured by the application if (!config1 && !config2) { - newFeatures.pNext = const_cast(createInfo.pNext); - newFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES; newFeatures.timelineSemaphore = true; - createInfo.pNext = reinterpret_cast(&newFeatures); + vku::AddToPnext(createInfo, newFeatures); LAYER_LOG("Device extension config added: %s", target.c_str()); } } @@ -467,15 +455,15 @@ static void enableDeviceVkKhrTimelineSemaphore(VkDeviceCreateInfo& createInfo, * * @param createInfo The createInfo we can search to find user config. * @param supported The list of supported extensions. - * @param active The list of active extensions. * @param newFeatures Pre-allocated struct we can use if we need to add it. */ -static void enableDeviceVkExtImageCompressionControl(VkDeviceCreateInfo& createInfo, +static void enableDeviceVkExtImageCompressionControl(vku::safe_VkDeviceCreateInfo& createInfo, std::vector& supported, - std::vector& active, - VkPhysicalDeviceImageCompressionControlFeaturesEXT newFeatures) + VkPhysicalDeviceImageCompressionControlFeaturesEXT& newFeatures) { static const std::string target {VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME}; + // We know we can const-cast here because this is a safe struct clone + void* pNextBase = const_cast(createInfo.pNext); // Test if the desired extension is supported if (!isIn(target, supported)) @@ -484,20 +472,14 @@ static void enableDeviceVkExtImageCompressionControl(VkDeviceCreateInfo& createI return; } - // If it is not already enabled then add to the list - if (!isIn(target, active)) + // Enable the extension - this will skip adding if already enabled + if (vku::AddExtension(createInfo, target.c_str())) { LAYER_LOG("Device extension added: %s", target.c_str()); - active.push_back(target.c_str()); } // Check if user provided a VkPhysicalDeviceImageCompressionControlFeaturesEXT - // TODO: This currently relies on const_cast to make user struct writable - // We should replace this with a generic clone (issue #56) - auto* config = searchNextList( - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, - createInfo.pNext); - + auto* config = vku::FindStructInPNextChain(pNextBase); if (config) { if (!config->imageCompressionControl) @@ -514,11 +496,8 @@ static void enableDeviceVkExtImageCompressionControl(VkDeviceCreateInfo& createI // Add a config if not already configured by the application if (!config) { - newFeatures.pNext = const_cast(createInfo.pNext); - newFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT; newFeatures.imageCompressionControl = true; - - createInfo.pNext = reinterpret_cast(&newFeatures); + vku::AddToPnext(createInfo, newFeatures); LAYER_LOG("Device extension config added: %s", target.c_str()); } } @@ -718,26 +697,19 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateInstance_default(const VkInstanceCr return VK_ERROR_INITIALIZATION_FAILED; } - // Create structure copies we can modify - VkInstanceCreateInfo newCreateInfo = *pCreateInfo; - VkApplicationInfo newAppInfo = *pCreateInfo->pApplicationInfo; - - // Write the new application info - newAppInfo.apiVersion = VK_MAKE_API_VERSION(0, newVersion.first, newVersion.second, 0); - newCreateInfo.pApplicationInfo = &newAppInfo; + // Create modifiable structures we can patch + vku::safe_VkInstanceCreateInfo newCreateInfoSafe(pCreateInfo); + auto* newCreateInfo = reinterpret_cast(&newCreateInfoSafe); - // Create a copy of the extension list we can patch - std::vector newExtensions; - const auto start = pCreateInfo->ppEnabledExtensionNames; - const auto end = pCreateInfo->ppEnabledExtensionNames + pCreateInfo->enabledExtensionCount; - newExtensions.insert(newExtensions.end(), start, end); + // Patch updated application info + newCreateInfoSafe.pApplicationInfo->apiVersion = VK_MAKE_API_VERSION(0, newVersion.first, newVersion.second, 0); // Enable extra extensions for (const auto& newExt : Instance::extraExtensions) { if (newExt == VK_EXT_DEBUG_UTILS_EXTENSION_NAME) { - enableInstanceVkExtDebugUtils(supportedExtensions, newExtensions); + enableInstanceVkExtDebugUtils(newCreateInfoSafe, supportedExtensions); } else { @@ -745,20 +717,14 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateInstance_default(const VkInstanceCr } } - // Patch extension pointer and size after extending it - newCreateInfo.enabledExtensionCount = newExtensions.size(); - newCreateInfo.ppEnabledExtensionNames = newExtensions.data(); - - // Log it for debug purposes - unsigned int i = 0; - for (auto ext : newExtensions) + // Log extensions for debug purposes + for (uint32_t i = 0; i < newCreateInfo->enabledExtensionCount; i++) { - LAYER_LOG("Requested instance extension list: [%u] = %s", i, ext); - i++; + LAYER_LOG("Requested instance extension list: [%u] = %s", i, newCreateInfo->ppEnabledExtensionNames[i]); } chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext; - auto result = fpCreateInstance(&newCreateInfo, pAllocator, pInstance); + auto result = fpCreateInstance(newCreateInfo, pAllocator, pInstance); if (result != VK_SUCCESS) { return result; @@ -818,34 +784,30 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateDevice_default(VkPhysicalDevice phy // Log this for support purposes ... APIVersion apiVersion = getDeviceAPIVersion(fpGetInstanceProcAddr, layer->instance, physicalDevice); - LAYER_LOG("Device API version %u.%u", apiVersion.first, apiVersion.second); - // Create structure copies we can modify - VkDeviceCreateInfo newCreateInfo = *pCreateInfo; + // Create a modifiable structure we can patch + vku::safe_VkDeviceCreateInfo newCreateInfoSafe(pCreateInfo); + auto* newCreateInfo = reinterpret_cast(&newCreateInfoSafe); - // Create structures we allocate here, but populated elsewhere - VkPhysicalDeviceTimelineSemaphoreFeatures newTimelineFeatures; - VkPhysicalDeviceImageCompressionControlFeaturesEXT newCompressionControlFeatures; - - // Create a copy of the extension list we can patch - std::vector newExtensions; - const auto start = pCreateInfo->ppEnabledExtensionNames; - const auto end = pCreateInfo->ppEnabledExtensionNames + pCreateInfo->enabledExtensionCount; - newExtensions.insert(newExtensions.end(), start, end); + // Create extra structures we allocate here, but populate elsewhere + VkPhysicalDeviceTimelineSemaphoreFeatures newTimelineFeatures = vku::InitStructHelper(); + VkPhysicalDeviceImageCompressionControlFeaturesEXT newCompressionControlFeatures = vku::InitStructHelper(); // Enable extra extensions for (const auto& newExt : Device::extraExtensions) { if (newExt == VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME) { - enableDeviceVkKhrTimelineSemaphore(newCreateInfo, supportedExtensions, newExtensions, newTimelineFeatures); + + enableDeviceVkKhrTimelineSemaphore(newCreateInfoSafe, + supportedExtensions, + newTimelineFeatures); } else if (newExt == VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME) { - enableDeviceVkExtImageCompressionControl(newCreateInfo, + enableDeviceVkExtImageCompressionControl(newCreateInfoSafe, supportedExtensions, - newExtensions, newCompressionControlFeatures); } else @@ -854,16 +816,10 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateDevice_default(VkPhysicalDevice phy } } - // Patch extension pointer and size after extending it - newCreateInfo.enabledExtensionCount = newExtensions.size(); - newCreateInfo.ppEnabledExtensionNames = newExtensions.data(); - - // Log it for debug purposes - unsigned int i = 0; - for (auto ext : newExtensions) + // Log extensions for debug purposes + for (uint32_t i = 0; i < newCreateInfo->enabledExtensionCount; i++) { - LAYER_LOG("Requested device extension list: [%u] = %s", i, ext); - i++; + LAYER_LOG("Requested device extension list: [%u] = %s", i, newCreateInfo->ppEnabledExtensionNames[i]); } auto fpCreateDeviceRaw = fpGetInstanceProcAddr(layer->instance, "vkCreateDevice"); @@ -875,13 +831,13 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateDevice_default(VkPhysicalDevice phy // Advance the link info for the next element on the chain chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext; - auto res = fpCreateDevice(physicalDevice, &newCreateInfo, pAllocator, pDevice); + auto res = fpCreateDevice(physicalDevice, newCreateInfo, pAllocator, pDevice); if (res != VK_SUCCESS) { return res; } - auto device = std::make_unique(layer, physicalDevice, *pDevice, fpGetDeviceProcAddr, newCreateInfo); + auto device = std::make_unique(layer, physicalDevice, *pDevice, fpGetDeviceProcAddr, *newCreateInfo); // Retake the lock to access layer-wide global store lock.lock(); diff --git a/source_common/trackers/CMakeLists.txt b/source_common/trackers/CMakeLists.txt index 868e9fd..5781009 100644 --- a/source_common/trackers/CMakeLists.txt +++ b/source_common/trackers/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # ----------------------------------------------------------------------------- -# Copyright (c) 2024 Arm Limited +# Copyright (c) 2024-2025 Arm Limited # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -35,13 +35,9 @@ target_include_directories( ${LIB_BINARY} PRIVATE ../ ../../source_third_party/ - ../../source_third_party/khronos/vulkan/include) + ../../source_third_party/khronos/vulkan/include + ../../source_third_party/khronos/vulkan-utilities/include/) lgl_set_build_options(${LIB_BINARY}) -# No unit tests for this module yet -#if(${LGL_UNITTEST}) -# add_subdirectory(test) -#endif() - -add_clang_tools() \ No newline at end of file +add_clang_tools() diff --git a/source_common/utils/misc.hpp b/source_common/utils/misc.hpp index 166c1e3..8cb4ffb 100644 --- a/source_common/utils/misc.hpp +++ b/source_common/utils/misc.hpp @@ -174,29 +174,6 @@ static inline bool isInExtensionList( return false; } -/** - * @brief Helper to search a Vulkan "pNext" list for a matching structure. - */ -template -T* searchNextList( - VkStructureType sType, - const void* pNext -) { - const auto* pStruct = reinterpret_cast(pNext); - while(pStruct) - { - if (pStruct->sType == sType) - { - break; - } - pStruct = reinterpret_cast(pStruct->pNext); - } - - // Const cast is not ideal here but we don't have functionality to - // clone a writable copy of the entire pNext chain yet ... - return const_cast(pStruct); -} - /** * @brief Get a displayable pointer. * diff --git a/source_third_party/khronos/egl b/source_third_party/khronos/egl deleted file mode 160000 index 29c4314..0000000 --- a/source_third_party/khronos/egl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 29c4314e0ef04c730992d295f91b76635019fbba diff --git a/source_third_party/khronos/opengles b/source_third_party/khronos/opengles deleted file mode 160000 index 9da9631..0000000 --- a/source_third_party/khronos/opengles +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9da96319b5180c55bab6f0231d384941f4d57200 diff --git a/source_third_party/khronos/vulkan-utilities b/source_third_party/khronos/vulkan-utilities new file mode 160000 index 0000000..54c9baf --- /dev/null +++ b/source_third_party/khronos/vulkan-utilities @@ -0,0 +1 @@ +Subproject commit 54c9baf20802a13279e23fa4cb0528dd5cf16064