From ec7de3ee11943f687b2e56995d951a9e864c1cd8 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Wed, 21 Aug 2024 15:20:03 +0800 Subject: [PATCH 01/14] use ohos sdk compile Signed-off-by: andrew0229 --- CMakeLists.txt | 6 ++-- layers/CMakeLists.txt | 6 ++++ layers/VkLayer_khronos_validation-ohos.map | 12 +++++++ layers/vulkan/generated/vk_safe_struct.h | 4 ++- .../generated/vk_safe_struct_vendor.cpp | 34 +++++++------------ scripts/known_good.json | 4 +-- 6 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 layers/VkLayer_khronos_validation-ohos.map diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ccef46f8..646f5cde6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ~~~ -cmake_minimum_required(VERSION 3.17.2) +cmake_minimum_required(VERSION 3.16.5) project(VVL LANGUAGES CXX) @@ -36,7 +36,9 @@ include(GNUInstallDirs) set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Remove when min is 3.26, see CMP0143 add_compile_definitions(VK_ENABLE_BETA_EXTENSIONS) -if(WIN32) +if(OHOS) + add_compile_definitions(VK_USE_PLATFORM_OHOS) +elseif(WIN32) add_compile_definitions(VK_USE_PLATFORM_WIN32_KHR) # Allow usage of unsafe CRT functions and minimize what Windows.h leaks diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index 55ad67774..2b3e66a7e 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -322,6 +322,8 @@ elseif(MINGW) elseif(APPLE) set_target_properties(vvl PROPERTIES SUFFIX ".dylib") target_link_options(vvl PRIVATE -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/${LAYER_NAME}.exp) +elseif(OHOS) + target_link_options(vvl PRIVATE LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/${LAYER_NAME}-ohos.map) elseif(ANDROID) target_link_options(vvl PRIVATE LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/${LAYER_NAME}-android.map) else() @@ -356,6 +358,10 @@ target_link_libraries(vvl PRIVATE target_include_directories(vvl SYSTEM PRIVATE external) +if (OHOS) + return() +endif() + if (ANDROID) # https://gitlab.kitware.com/cmake/cmake/issues/18787 # https://github.com/android-ndk/ndk/issues/463 diff --git a/layers/VkLayer_khronos_validation-ohos.map b/layers/VkLayer_khronos_validation-ohos.map new file mode 100644 index 000000000..1f8fe1918 --- /dev/null +++ b/layers/VkLayer_khronos_validation-ohos.map @@ -0,0 +1,12 @@ +{ + global: + vkGetInstanceProcAddr; + vkGetDeviceProcAddr; + vkEnumerateInstanceLayerProperties; + vkEnumerateInstanceExtensionProperties; + vkNegotiateLoaderLayerInterfaceVersion; + vkEnumerateDeviceLayerProperties; + vkEnumerateDeviceExtensionProperties; + local: + *; +}; diff --git a/layers/vulkan/generated/vk_safe_struct.h b/layers/vulkan/generated/vk_safe_struct.h index 1d310529d..2631781ff 100644 --- a/layers/vulkan/generated/vk_safe_struct.h +++ b/layers/vulkan/generated/vk_safe_struct.h @@ -17705,10 +17705,11 @@ struct safe_VkSurfaceCreateInfoOHOS { VkSurfaceCreateInfoOHOS* ptr() { return reinterpret_cast(this); } VkSurfaceCreateInfoOHOS const* ptr() const { return reinterpret_cast(this); } }; +/* struct safe_VkNativeBufferOHOS { VkStructureType sType; const void* pNext{}; - BufferHandle* handle{}; + OHBufferHandle* handle{}; safe_VkNativeBufferOHOS(const VkNativeBufferOHOS* in_struct, PNextCopyState* copy_state = {}, bool copy_pnext = true); safe_VkNativeBufferOHOS(const safe_VkNativeBufferOHOS& copy_src); @@ -17720,6 +17721,7 @@ struct safe_VkNativeBufferOHOS { VkNativeBufferOHOS* ptr() { return reinterpret_cast(this); } VkNativeBufferOHOS const* ptr() const { return reinterpret_cast(this); } }; +*/ struct safe_VkSwapchainImageCreateInfoOHOS { VkStructureType sType; const void* pNext{}; diff --git a/layers/vulkan/generated/vk_safe_struct_vendor.cpp b/layers/vulkan/generated/vk_safe_struct_vendor.cpp index 1ab373145..cafdfc3e9 100644 --- a/layers/vulkan/generated/vk_safe_struct_vendor.cpp +++ b/layers/vulkan/generated/vk_safe_struct_vendor.cpp @@ -15264,7 +15264,7 @@ void safe_VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV::initialize( pNext = SafePnextCopy(copy_src->pNext); } #ifdef VK_USE_PLATFORM_OHOS - +/* safe_VkSurfaceCreateInfoOHOS::safe_VkSurfaceCreateInfoOHOS(const VkSurfaceCreateInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state, bool copy_pnext) : sType(in_struct->sType), flags(in_struct->flags), window(nullptr) { @@ -15346,7 +15346,7 @@ safe_VkNativeBufferOHOS::safe_VkNativeBufferOHOS(const VkNativeBufferOHOS* in_st pNext = SafePnextCopy(in_struct->pNext, copy_state); } if (in_struct->handle) { - handle = new BufferHandle(*in_struct->handle); + handle = new OHBufferHandle(*in_struct->handle); } } @@ -15358,7 +15358,7 @@ safe_VkNativeBufferOHOS::safe_VkNativeBufferOHOS(const safe_VkNativeBufferOHOS& pNext = SafePnextCopy(copy_src.pNext); if (copy_src.handle) { - handle = new BufferHandle(*copy_src.handle); + handle = new OHBufferHandle(*copy_src.handle); } } @@ -15373,7 +15373,7 @@ safe_VkNativeBufferOHOS& safe_VkNativeBufferOHOS::operator=(const safe_VkNativeB pNext = SafePnextCopy(copy_src.pNext); if (copy_src.handle) { - handle = new BufferHandle(*copy_src.handle); + handle = new OHBufferHandle(*copy_src.handle); } return *this; @@ -15392,7 +15392,7 @@ void safe_VkNativeBufferOHOS::initialize(const VkNativeBufferOHOS* in_struct, [[ pNext = SafePnextCopy(in_struct->pNext, copy_state); if (in_struct->handle) { - handle = new BufferHandle(*in_struct->handle); + handle = new OHBufferHandle(*in_struct->handle); } } @@ -15402,10 +15402,10 @@ void safe_VkNativeBufferOHOS::initialize(const safe_VkNativeBufferOHOS* copy_src pNext = SafePnextCopy(copy_src->pNext); if (copy_src->handle) { - handle = new BufferHandle(*copy_src->handle); + handle = new OHBufferHandle(*copy_src->handle); } } - +*/ safe_VkSwapchainImageCreateInfoOHOS::safe_VkSwapchainImageCreateInfoOHOS(const VkSwapchainImageCreateInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state, bool copy_pnext) @@ -15697,9 +15697,7 @@ safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS(const VkImp if (copy_pnext) { pNext = SafePnextCopy(in_struct->pNext, copy_state); } - if (in_struct->buffer) { - buffer = new OH_NativeBuffer(*in_struct->buffer); - } + buffer = in_struct->buffer; } safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS() @@ -15710,9 +15708,7 @@ safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS(const safe_ buffer = nullptr; pNext = SafePnextCopy(copy_src.pNext); - if (copy_src.buffer) { - buffer = new OH_NativeBuffer(*copy_src.buffer); - } + buffer = copy_src.buffer; } safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=(const safe_VkImportNativeBufferInfoOHOS& copy_src) { @@ -15725,9 +15721,7 @@ safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=( buffer = nullptr; pNext = SafePnextCopy(copy_src.pNext); - if (copy_src.buffer) { - buffer = new OH_NativeBuffer(*copy_src.buffer); - } + buffer = copy_src.buffer; return *this; } @@ -15745,9 +15739,7 @@ void safe_VkImportNativeBufferInfoOHOS::initialize(const VkImportNativeBufferInf buffer = nullptr; pNext = SafePnextCopy(in_struct->pNext, copy_state); - if (in_struct->buffer) { - buffer = new OH_NativeBuffer(*in_struct->buffer); - } + buffer = in_struct->buffer; } void safe_VkImportNativeBufferInfoOHOS::initialize(const safe_VkImportNativeBufferInfoOHOS* copy_src, @@ -15756,9 +15748,7 @@ void safe_VkImportNativeBufferInfoOHOS::initialize(const safe_VkImportNativeBuff buffer = nullptr; pNext = SafePnextCopy(copy_src->pNext); - if (copy_src->buffer) { - buffer = new OH_NativeBuffer(*copy_src->buffer); - } + buffer = copy_src->buffer; } safe_VkMemoryGetNativeBufferInfoOHOS::safe_VkMemoryGetNativeBufferInfoOHOS(const VkMemoryGetNativeBufferInfoOHOS* in_struct, diff --git a/scripts/known_good.json b/scripts/known_good.json index a009dfb88..ed07ddc9f 100755 --- a/scripts/known_good.json +++ b/scripts/known_good.json @@ -3,11 +3,11 @@ { "name": "Vulkan-Headers", "api": "vulkan", - "url": "https://github.com/KhronosGroup/Vulkan-Headers.git", + "url": "https://gitee.com/openharmony/third_party_vulkan-headers.git", "sub_dir": "Vulkan-Headers", "build_dir": "Vulkan-Headers/build", "install_dir": "Vulkan-Headers/build/install", - "commit": "v1.3.275" + "commit": "de4b2f2aa09145801017580787d5090f6d24d9f5" }, { "name": "Vulkan-Utility-Libraries", -- Gitee From a2024eea0b9d874e3cc6249ac4222ee81a91650d Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Wed, 21 Aug 2024 16:38:53 +0800 Subject: [PATCH 02/14] add blur Signed-off-by: andrew0229 --- compile.bat | 59 +++++++++++++++++++ layers/vulkan/generated/chassis.cpp | 7 +++ .../generated/layer_chassis_dispatch.cpp | 18 ++++++ .../vulkan/generated/layer_chassis_dispatch.h | 2 +- .../generated/vk_dispatch_table_helper.h | 7 +++ .../generated/vk_layer_dispatch_table.h | 1 + layers/vulkan/generated/vk_safe_struct.h | 19 ++++++ .../vulkan/generated/vk_safe_struct_core.cpp | 35 +++++++++++ 8 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 compile.bat diff --git a/compile.bat b/compile.bat new file mode 100644 index 000000000..580afdf36 --- /dev/null +++ b/compile.bat @@ -0,0 +1,59 @@ +@echo off +cls + +set OHOS_SDK=C:/Users/Administrator/AppData/Local/OpenHarmony/Sdk/12/native +set VVL_DIR=E:/WorkSpace/Vulkan/VVL/third_party_vulkan-validationlayers +set BUILD_THREADS=8 + +REM ----------------------------------------------------------------------------------------------------- + +set buildDir=%VVL_DIR%/build-ohos/intermediate +set libDir=%VVL_DIR%/build-ohos/libs + +REM Using CMake from OHOS SDK... + +set PATH=%OHOS_SDK%/build-tools/cmake/bin;%PATH% + +REM Making project files... + +cd /d %VVL_DIR% + +cmake ^ + -S . ^ + -B %buildDir% ^ + -G Ninja ^ + -D OHOS_STL=c++_static ^ + -D CMAKE_INSTALL_LIBDIR=%libDir% ^ + -D CMAKE_TOOLCHAIN_FILE=%OHOS_SDK%/build/cmake/ohos.toolchain.cmake ^ + -D CMAKE_BUILD_TYPE=Release ^ + -D VVL_CODEGEN=OFF ^ + -D UPDATE_DEPS=OFF ^ + -D UPDATE_DEPS_DIR=%buildDir% + +REM Codegen boilerplate code from Vulkan registry (vk.xml from Vulkan-Headers)... + +cmake ^ + --build %buildDir% ^ + --target vvl_codegen + +REM Building projects... + +cmake ^ + --build %buildDir% ^ + --parallel %BUILD_THREADS% + +REM Stripping binaries and copying them into final directory... + +if not exist "%libDir%" ( + mkdir "%libDir%" +) + +cd /d %OHOS_SDK%/llvm/bin + +llvm-strip ^ + -d ^ + -s ^ + -o "%libDir%/libVkLayer_khronos_validation.so" ^ + "%buildDir%/layers/libVkLayer_khronos_validation.so" + +echo Done. diff --git a/layers/vulkan/generated/chassis.cpp b/layers/vulkan/generated/chassis.cpp index 461d8e768..ca089c31b 100644 --- a/layers/vulkan/generated/chassis.cpp +++ b/layers/vulkan/generated/chassis.cpp @@ -17172,6 +17172,12 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer comm } } +VKAPI_ATTR void VKAPI_CALL CmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) +{ + DispatchCmdDrawBlurImageHUAWEI(commandBuffer, drawBlurImageInfo); +} + + // Map of intercepted ApiName to its associated function data #ifdef _MSC_VER #pragma warning(suppress : 6262) // VS analysis: this uses more than 16 kiB, which is fine here at global scope @@ -17913,6 +17919,7 @@ const vvl::unordered_map name_to_funcptr_map = { {"vkCmdDrawMeshTasksEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksEXT}}, {"vkCmdDrawMeshTasksIndirectEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectEXT}}, {"vkCmdDrawMeshTasksIndirectCountEXT", {kFuncTypeDev, (void*)CmdDrawMeshTasksIndirectCountEXT}}, + {"vkCmdDrawBlurImageHUAWEI", {kFuncTypeDev, (void*)CmdDrawBlurImageHUAWEI}}, }; } // namespace vulkan_layer_chassis // clang-format on diff --git a/layers/vulkan/generated/layer_chassis_dispatch.cpp b/layers/vulkan/generated/layer_chassis_dispatch.cpp index 2d33b68c8..23820ce07 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.cpp +++ b/layers/vulkan/generated/layer_chassis_dispatch.cpp @@ -9284,4 +9284,22 @@ void DispatchCmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer commandBuffer, VkB countBufferOffset, maxDrawCount, stride); } +void DispatchCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) { + auto layer_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); + if (!wrap_handles) + return layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, drawBlurImageInfo); + safe_VkDrawBlurImageInfoHUAWEI var_local_drawBlurImageInfo; + safe_VkDrawBlurImageInfoHUAWEI *local_drawBlurImageInfo = nullptr; + { + if (drawBlurImageInfo) { + local_drawBlurImageInfo = &var_local_drawBlurImageInfo; + local_drawBlurImageInfo->initialize(drawBlurImageInfo); + } + if (drawBlurImageInfo->srcImageView) { + local_drawBlurImageInfo->srcImageView = layer_data->Unwrap(drawBlurImageInfo->srcImageView); + } + } + layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, (const VkDrawBlurImageInfoHUAWEI*)local_drawBlurImageInfo); +} + // NOLINTEND diff --git a/layers/vulkan/generated/layer_chassis_dispatch.h b/layers/vulkan/generated/layer_chassis_dispatch.h index aedacd02f..220cc09cf 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.h +++ b/layers/vulkan/generated/layer_chassis_dispatch.h @@ -1246,5 +1246,5 @@ void DispatchCmdDrawMeshTasksIndirectEXT(VkCommandBuffer commandBuffer, VkBuffer void DispatchCmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); - +void DispatchCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo); // NOLINTEND diff --git a/layers/vulkan/generated/vk_dispatch_table_helper.h b/layers/vulkan/generated/vk_dispatch_table_helper.h index 97ed3b17a..33557428a 100644 --- a/layers/vulkan/generated/vk_dispatch_table_helper.h +++ b/layers/vulkan/generated/vk_dispatch_table_helper.h @@ -1813,6 +1813,8 @@ static VKAPI_ATTR void VKAPI_CALL StubCmdDrawMeshTasksIndirectCountEXT(VkCommand VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {} +static VKAPI_ATTR void VKAPI_CALL StubCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, + const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) {} const vvl::unordered_map> api_extension_map{ {"vkBindBufferMemory2", {"VK_VERSION_1_1"}}, @@ -4464,6 +4466,11 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp if (table->CmdDrawMeshTasksIndirectCountEXT == nullptr) { table->CmdDrawMeshTasksIndirectCountEXT = (PFN_vkCmdDrawMeshTasksIndirectCountEXT)StubCmdDrawMeshTasksIndirectCountEXT; } + table->CmdDrawBlurImageHUAWEI = + (PFN_vkCmdDrawBlurImageHUAWEI)gpa(device, "vkCmdDrawBlurImageHUAWEI"); + if (table->CmdDrawBlurImageHUAWEI == nullptr) { + table->CmdDrawBlurImageHUAWEI = (PFN_vkCmdDrawBlurImageHUAWEI)StubCmdDrawBlurImageHUAWEI; + } } static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable* table, diff --git a/layers/vulkan/generated/vk_layer_dispatch_table.h b/layers/vulkan/generated/vk_layer_dispatch_table.h index ff815d5dd..73dd80855 100644 --- a/layers/vulkan/generated/vk_layer_dispatch_table.h +++ b/layers/vulkan/generated/vk_layer_dispatch_table.h @@ -774,5 +774,6 @@ typedef struct VkLayerDispatchTable_ { PFN_vkCmdDrawMeshTasksEXT CmdDrawMeshTasksEXT; PFN_vkCmdDrawMeshTasksIndirectEXT CmdDrawMeshTasksIndirectEXT; PFN_vkCmdDrawMeshTasksIndirectCountEXT CmdDrawMeshTasksIndirectCountEXT; + PFN_vkCmdDrawBlurImageHUAWEI CmdDrawBlurImageHUAWEI; } VkLayerDispatchTable; // clang-format on// NOLINTEND diff --git a/layers/vulkan/generated/vk_safe_struct.h b/layers/vulkan/generated/vk_safe_struct.h index 2631781ff..8f40aa968 100644 --- a/layers/vulkan/generated/vk_safe_struct.h +++ b/layers/vulkan/generated/vk_safe_struct.h @@ -18418,4 +18418,23 @@ struct safe_VkPhysicalDeviceMeshShaderPropertiesEXT { } }; +struct safe_VkDrawBlurImageInfoHUAWEI { + VkStructureTypeHUAWEI sType; + const void* pNext{}; + float sigma; + VkRect2D srcRegion; + VkRect2D dstRegion; + VkImageView srcImageView; + + safe_VkDrawBlurImageInfoHUAWEI(const VkDrawBlurImageInfoHUAWEI* in_struct, PNextCopyState* copy_state = {}, bool copy_pnext = true); + safe_VkDrawBlurImageInfoHUAWEI(const safe_VkDrawBlurImageInfoHUAWEI& copy_src); + safe_VkDrawBlurImageInfoHUAWEI& operator=(const safe_VkDrawBlurImageInfoHUAWEI& copy_src); + safe_VkDrawBlurImageInfoHUAWEI(); + ~safe_VkDrawBlurImageInfoHUAWEI(); + void initialize(const VkDrawBlurImageInfoHUAWEI* in_struct, PNextCopyState* copy_state = {}); + void initialize(const safe_VkDrawBlurImageInfoHUAWEI* copy_src, PNextCopyState* copy_state = {}); + VkDrawBlurImageInfoHUAWEI* ptr() { return reinterpret_cast(this); } + VkDrawBlurImageInfoHUAWEI const* ptr() const { return reinterpret_cast(this); } +}; + // NOLINTEND diff --git a/layers/vulkan/generated/vk_safe_struct_core.cpp b/layers/vulkan/generated/vk_safe_struct_core.cpp index 63a54377a..7829ec8e3 100644 --- a/layers/vulkan/generated/vk_safe_struct_core.cpp +++ b/layers/vulkan/generated/vk_safe_struct_core.cpp @@ -19396,4 +19396,39 @@ void safe_VkDeviceImageMemoryRequirements::initialize(const safe_VkDeviceImageMe if (copy_src->pCreateInfo) pCreateInfo = new safe_VkImageCreateInfo(*copy_src->pCreateInfo); } +safe_VkDrawBlurImageInfoHUAWEI::safe_VkDrawBlurImageInfoHUAWEI() + : sType(VK_STRUCTURE_TYPE_DRAW_BLUR_IMAGE_INFO_HUAWEI), + pNext(nullptr), + sigma(), + srcRegion(), + dstRegion(), + srcImageView() {} + +safe_VkDrawBlurImageInfoHUAWEI& safe_VkDrawBlurImageInfoHUAWEI::operator=(const safe_VkDrawBlurImageInfoHUAWEI& copy_src) { + if (©_src == this) return *this; + + FreePnextChain(pNext); + + sType = copy_src.sType; + sigma = copy_src.sigma; + srcRegion = copy_src.srcRegion; + dstRegion = copy_src.dstRegion; + srcImageView = copy_src.srcImageView; + pNext = SafePnextCopy(copy_src.pNext); + + return *this; +} + +safe_VkDrawBlurImageInfoHUAWEI::~safe_VkDrawBlurImageInfoHUAWEI() { FreePnextChain(pNext); } + +void safe_VkDrawBlurImageInfoHUAWEI::initialize(const VkDrawBlurImageInfoHUAWEI* in_struct, [[maybe_unused]] PNextCopyState* copy_state) { + FreePnextChain(pNext); + sType = in_struct->sType; + sigma = in_struct->sigma; + srcRegion = in_struct->srcRegion; + dstRegion = in_struct->dstRegion; + srcImageView = in_struct->srcImageView; + pNext = SafePnextCopy(in_struct->pNext, copy_state); +} + // NOLINTEND -- Gitee From f262ab448d84cf8a894666744ad6ff081590e92d Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Wed, 21 Aug 2024 16:39:57 +0800 Subject: [PATCH 03/14] update OAT Signed-off-by: andrew0229 --- OAT.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OAT.xml b/OAT.xml index 6ac6eb7bc..a422f0db7 100644 --- a/OAT.xml +++ b/OAT.xml @@ -22,7 +22,8 @@ LICENSE.txt - + + -- Gitee From 4bb3291022bc4e7026abbed922e5cc0d90570b53 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 16:36:36 +0800 Subject: [PATCH 04/14] add hilog Signed-off-by: andrew0229 --- layers/error_message/logging.h | 5 +++ layers/error_message/vvllog.h | 30 ++++++++++++++++++ layers/state_tracker/state_tracker.cpp | 10 ++++++ layers/state_tracker/state_tracker.h | 6 +++- .../generated/layer_chassis_dispatch.cpp | 6 ++-- layers/vulkan/generated/vk_safe_struct.h | 2 -- .../generated/vk_safe_struct_vendor.cpp | 31 ++++++------------- 7 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 layers/error_message/vvllog.h diff --git a/layers/error_message/logging.h b/layers/error_message/logging.h index ce31564a9..cc6df9e99 100644 --- a/layers/error_message/logging.h +++ b/layers/error_message/logging.h @@ -39,6 +39,11 @@ [[maybe_unused]] static const char *kForceDefaultCallbackKey = "debug.vvl.forcelayerlog"; #endif +#if defined (__OHOS__) +#include "vvllog.h" +#endif + + extern const char *kVUIDUndefined; typedef enum DebugCallbackStatusBits { diff --git a/layers/error_message/vvllog.h b/layers/error_message/vvllog.h new file mode 100644 index 000000000..bfc597d14 --- /dev/null +++ b/layers/error_message/vvllog.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include + + +#define APP_LOG_DOMAIN 0x0001 +#define APP_LOG_TAG "XComponent_Native" +#define ALOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define ALOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define ALOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define ALOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) + +#define VVL_LOGV(...) + +#define VVL_LOGD(...) \ + do { \ + ALOGFD(__VA_ARGS__); \ + } while (0) +#define VVL_LOGI(...) \ + do { \ + ALOGI(__VA_ARGS__); \ + } while (0) +#define VVL_LOGW(...) \ + do { \ + ALOGW(__VA_ARGS__); \ + } while (0) +#define VVL_LOGE(...) \ + do { \ + ALOGE(__VA_ARGS__); \ + } while (0) \ No newline at end of file diff --git a/layers/state_tracker/state_tracker.cpp b/layers/state_tracker/state_tracker.cpp index 4edbd112e..47f32a11f 100644 --- a/layers/state_tracker/state_tracker.cpp +++ b/layers/state_tracker/state_tracker.cpp @@ -3946,6 +3946,16 @@ void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance i RecordVulkanSurface(pSurface); } +#ifdef VK_USE_PLATFORM_OHOS +void ValidationStateTracker::PostCallRecordCreateSurfaceOHOS(VkInstance instance, + const VkSurfaceCreateInfoOHOS *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface, + const RecordObject &record_obj) { + if (VK_SUCCESS != record_obj.result) return; + RecordVulkanSurface(pSurface); +} +#endif // VK_USE_PLATFORM_ANDROID_KHR + void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities, diff --git a/layers/state_tracker/state_tracker.h b/layers/state_tracker/state_tracker.h index 9596614d6..7ff33c6e8 100644 --- a/layers/state_tracker/state_tracker.h +++ b/layers/state_tracker/state_tracker.h @@ -1499,7 +1499,11 @@ class ValidationStateTracker : public ValidationObject { void PostCallRecordCreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface, const RecordObject& record_obj) override; - +#ifdef VK_USE_PLATFORM_OHOS + void PostCallRecordCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface, + const RecordObject &record_obj) override; +#endif // VK_USE_PLATFORM_ANDROID_KHR // State Utilty functions std::vector> GetAttachmentViews(const VkRenderPassBeginInfo& rp_begin, const vvl::Framebuffer& fb_state) const; diff --git a/layers/vulkan/generated/layer_chassis_dispatch.cpp b/layers/vulkan/generated/layer_chassis_dispatch.cpp index 23820ce07..49f0a5e04 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.cpp +++ b/layers/vulkan/generated/layer_chassis_dispatch.cpp @@ -9294,9 +9294,9 @@ void DispatchCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawB if (drawBlurImageInfo) { local_drawBlurImageInfo = &var_local_drawBlurImageInfo; local_drawBlurImageInfo->initialize(drawBlurImageInfo); - } - if (drawBlurImageInfo->srcImageView) { - local_drawBlurImageInfo->srcImageView = layer_data->Unwrap(drawBlurImageInfo->srcImageView); + if (drawBlurImageInfo->srcImageView) { + local_drawBlurImageInfo->srcImageView = layer_data->Unwrap(drawBlurImageInfo->srcImageView); + } } } layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, (const VkDrawBlurImageInfoHUAWEI*)local_drawBlurImageInfo); diff --git a/layers/vulkan/generated/vk_safe_struct.h b/layers/vulkan/generated/vk_safe_struct.h index 8f40aa968..dc3b26e6f 100644 --- a/layers/vulkan/generated/vk_safe_struct.h +++ b/layers/vulkan/generated/vk_safe_struct.h @@ -17705,7 +17705,6 @@ struct safe_VkSurfaceCreateInfoOHOS { VkSurfaceCreateInfoOHOS* ptr() { return reinterpret_cast(this); } VkSurfaceCreateInfoOHOS const* ptr() const { return reinterpret_cast(this); } }; -/* struct safe_VkNativeBufferOHOS { VkStructureType sType; const void* pNext{}; @@ -17721,7 +17720,6 @@ struct safe_VkNativeBufferOHOS { VkNativeBufferOHOS* ptr() { return reinterpret_cast(this); } VkNativeBufferOHOS const* ptr() const { return reinterpret_cast(this); } }; -*/ struct safe_VkSwapchainImageCreateInfoOHOS { VkStructureType sType; const void* pNext{}; diff --git a/layers/vulkan/generated/vk_safe_struct_vendor.cpp b/layers/vulkan/generated/vk_safe_struct_vendor.cpp index cafdfc3e9..fdc5b3f6e 100644 --- a/layers/vulkan/generated/vk_safe_struct_vendor.cpp +++ b/layers/vulkan/generated/vk_safe_struct_vendor.cpp @@ -15264,7 +15264,6 @@ void safe_VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV::initialize( pNext = SafePnextCopy(copy_src->pNext); } #ifdef VK_USE_PLATFORM_OHOS -/* safe_VkSurfaceCreateInfoOHOS::safe_VkSurfaceCreateInfoOHOS(const VkSurfaceCreateInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state, bool copy_pnext) : sType(in_struct->sType), flags(in_struct->flags), window(nullptr) { @@ -15272,7 +15271,7 @@ safe_VkSurfaceCreateInfoOHOS::safe_VkSurfaceCreateInfoOHOS(const VkSurfaceCreate pNext = SafePnextCopy(in_struct->pNext, copy_state); } if (in_struct->window) { - window = new OHNativeWindow(*in_struct->window); + window =in_struct->window; } } @@ -15286,14 +15285,13 @@ safe_VkSurfaceCreateInfoOHOS::safe_VkSurfaceCreateInfoOHOS(const safe_VkSurfaceC pNext = SafePnextCopy(copy_src.pNext); if (copy_src.window) { - window = new OHNativeWindow(*copy_src.window); + window = copy_src.window; } } safe_VkSurfaceCreateInfoOHOS& safe_VkSurfaceCreateInfoOHOS::operator=(const safe_VkSurfaceCreateInfoOHOS& copy_src) { if (©_src == this) return *this; - if (window) delete window; FreePnextChain(pNext); sType = copy_src.sType; @@ -15302,20 +15300,18 @@ safe_VkSurfaceCreateInfoOHOS& safe_VkSurfaceCreateInfoOHOS::operator=(const safe pNext = SafePnextCopy(copy_src.pNext); if (copy_src.window) { - window = new OHNativeWindow(*copy_src.window); + window = copy_src.window; } return *this; } safe_VkSurfaceCreateInfoOHOS::~safe_VkSurfaceCreateInfoOHOS() { - if (window) delete window; FreePnextChain(pNext); } void safe_VkSurfaceCreateInfoOHOS::initialize(const VkSurfaceCreateInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state) { - if (window) delete window; FreePnextChain(pNext); sType = in_struct->sType; flags = in_struct->flags; @@ -15323,7 +15319,7 @@ void safe_VkSurfaceCreateInfoOHOS::initialize(const VkSurfaceCreateInfoOHOS* in_ pNext = SafePnextCopy(in_struct->pNext, copy_state); if (in_struct->window) { - window = new OHNativeWindow(*in_struct->window); + window = in_struct->window; } } @@ -15335,7 +15331,7 @@ void safe_VkSurfaceCreateInfoOHOS::initialize(const safe_VkSurfaceCreateInfoOHOS pNext = SafePnextCopy(copy_src->pNext); if (copy_src->window) { - window = new OHNativeWindow(*copy_src->window); + window = copy_src->window; } } @@ -15346,7 +15342,7 @@ safe_VkNativeBufferOHOS::safe_VkNativeBufferOHOS(const VkNativeBufferOHOS* in_st pNext = SafePnextCopy(in_struct->pNext, copy_state); } if (in_struct->handle) { - handle = new OHBufferHandle(*in_struct->handle); + handle = in_struct->handle; } } @@ -15358,14 +15354,13 @@ safe_VkNativeBufferOHOS::safe_VkNativeBufferOHOS(const safe_VkNativeBufferOHOS& pNext = SafePnextCopy(copy_src.pNext); if (copy_src.handle) { - handle = new OHBufferHandle(*copy_src.handle); + handle = copy_src.handle; } } safe_VkNativeBufferOHOS& safe_VkNativeBufferOHOS::operator=(const safe_VkNativeBufferOHOS& copy_src) { if (©_src == this) return *this; - if (handle) delete handle; FreePnextChain(pNext); sType = copy_src.sType; @@ -15373,26 +15368,24 @@ safe_VkNativeBufferOHOS& safe_VkNativeBufferOHOS::operator=(const safe_VkNativeB pNext = SafePnextCopy(copy_src.pNext); if (copy_src.handle) { - handle = new OHBufferHandle(*copy_src.handle); + handle = copy_src.handle; } return *this; } safe_VkNativeBufferOHOS::~safe_VkNativeBufferOHOS() { - if (handle) delete handle; FreePnextChain(pNext); } void safe_VkNativeBufferOHOS::initialize(const VkNativeBufferOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state) { - if (handle) delete handle; FreePnextChain(pNext); sType = in_struct->sType; handle = nullptr; pNext = SafePnextCopy(in_struct->pNext, copy_state); if (in_struct->handle) { - handle = new OHBufferHandle(*in_struct->handle); + handle = in_struct->handle; } } @@ -15402,10 +15395,9 @@ void safe_VkNativeBufferOHOS::initialize(const safe_VkNativeBufferOHOS* copy_src pNext = SafePnextCopy(copy_src->pNext); if (copy_src->handle) { - handle = new OHBufferHandle(*copy_src->handle); + handle = copy_src->handle; } } -*/ safe_VkSwapchainImageCreateInfoOHOS::safe_VkSwapchainImageCreateInfoOHOS(const VkSwapchainImageCreateInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state, bool copy_pnext) @@ -15714,7 +15706,6 @@ safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS(const safe_ safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=(const safe_VkImportNativeBufferInfoOHOS& copy_src) { if (©_src == this) return *this; - if (buffer) delete buffer; FreePnextChain(pNext); sType = copy_src.sType; @@ -15727,13 +15718,11 @@ safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=( } safe_VkImportNativeBufferInfoOHOS::~safe_VkImportNativeBufferInfoOHOS() { - if (buffer) delete buffer; FreePnextChain(pNext); } void safe_VkImportNativeBufferInfoOHOS::initialize(const VkImportNativeBufferInfoOHOS* in_struct, [[maybe_unused]] PNextCopyState* copy_state) { - if (buffer) delete buffer; FreePnextChain(pNext); sType = in_struct->sType; buffer = nullptr; -- Gitee From af28b940186b491d70e86e345b4646d293127a74 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 18:43:57 +0800 Subject: [PATCH 05/14] add hilog deps Signed-off-by: andrew0229 --- layers/CMakeLists.txt | 2 ++ layers/error_message/logging.cpp | 1 + layers/error_message/logging.h | 2 +- layers/error_message/ohos_log.h | 30 +++++++++++++++++++ layers/error_message/vvllog.h | 30 ------------------- layers/state_tracker/state_tracker.cpp | 2 +- layers/state_tracker/state_tracker.h | 2 +- .../generated/vk_safe_struct_vendor.cpp | 24 +++++++++------ 8 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 layers/error_message/ohos_log.h delete mode 100644 layers/error_message/vvllog.h diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index 2b3e66a7e..372f02b9a 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -359,6 +359,8 @@ target_link_libraries(vvl PRIVATE target_include_directories(vvl SYSTEM PRIVATE external) if (OHOS) + # Required for OH_LOG_Print. Marking as PUBLIC since the tests use OH_LOG_Print as well. + target_link_libraries(VkLayer_utils PUBLIC hilog_ndk.z) return() endif() diff --git a/layers/error_message/logging.cpp b/layers/error_message/logging.cpp index d3e83cf00..1fb032409 100644 --- a/layers/error_message/logging.cpp +++ b/layers/error_message/logging.cpp @@ -186,6 +186,7 @@ static bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags } oss << "| MessageID = 0x" << std::hex << message_id_number << " | " << message; std::string composite = oss.str(); + VVL_LOGE("%{public}s", composite.c_str()); const auto callback_list = &debug_data->debug_callback_list; // We only output to default callbacks if there are no non-default callbacks diff --git a/layers/error_message/logging.h b/layers/error_message/logging.h index cc6df9e99..4654057a7 100644 --- a/layers/error_message/logging.h +++ b/layers/error_message/logging.h @@ -40,7 +40,7 @@ #endif #if defined (__OHOS__) -#include "vvllog.h" +#include "ohos_log.h" #endif diff --git a/layers/error_message/ohos_log.h b/layers/error_message/ohos_log.h new file mode 100644 index 000000000..0d59a424d --- /dev/null +++ b/layers/error_message/ohos_log.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD001405 +#define LOG_TAG "VulkanValidationLayer" + +// #define VKHILOGD(fmt, ...) OH_LOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) +// #define VKHILOGE(fmt, ...) OH_LOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) + +// #define VVL_LOGV(...) + +// #define VVL_LOGD(...) \ +// do { \ +// VKHILOGD(__VA_ARGS__); \ +// } while (0) +// #define VVL_LOGI(...) \ +// do { \ +// VKHILOGI(__VA_ARGS__); \ +// } while (0) +// #define VVL_LOGW(...) \ +// do { \ +// VKHILOGW(__VA_ARGS__); \ +// } while (0) +#define VVL_LOGE(...) \ + do { \ + OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ + } while (0) \ No newline at end of file diff --git a/layers/error_message/vvllog.h b/layers/error_message/vvllog.h deleted file mode 100644 index bfc597d14..000000000 --- a/layers/error_message/vvllog.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include -#include - - -#define APP_LOG_DOMAIN 0x0001 -#define APP_LOG_TAG "XComponent_Native" -#define ALOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) -#define ALOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) -#define ALOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) -#define ALOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) - -#define VVL_LOGV(...) - -#define VVL_LOGD(...) \ - do { \ - ALOGFD(__VA_ARGS__); \ - } while (0) -#define VVL_LOGI(...) \ - do { \ - ALOGI(__VA_ARGS__); \ - } while (0) -#define VVL_LOGW(...) \ - do { \ - ALOGW(__VA_ARGS__); \ - } while (0) -#define VVL_LOGE(...) \ - do { \ - ALOGE(__VA_ARGS__); \ - } while (0) \ No newline at end of file diff --git a/layers/state_tracker/state_tracker.cpp b/layers/state_tracker/state_tracker.cpp index 47f32a11f..f4506fc33 100644 --- a/layers/state_tracker/state_tracker.cpp +++ b/layers/state_tracker/state_tracker.cpp @@ -3954,7 +3954,7 @@ void ValidationStateTracker::PostCallRecordCreateSurfaceOHOS(VkInstance instance if (VK_SUCCESS != record_obj.result) return; RecordVulkanSurface(pSurface); } -#endif // VK_USE_PLATFORM_ANDROID_KHR +#endif // VK_USE_PLATFORM_OHOS void ValidationStateTracker::PostCallRecordGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, diff --git a/layers/state_tracker/state_tracker.h b/layers/state_tracker/state_tracker.h index 7ff33c6e8..9e4fcdb24 100644 --- a/layers/state_tracker/state_tracker.h +++ b/layers/state_tracker/state_tracker.h @@ -1503,7 +1503,7 @@ class ValidationStateTracker : public ValidationObject { void PostCallRecordCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface, const RecordObject &record_obj) override; -#endif // VK_USE_PLATFORM_ANDROID_KHR +#endif // VK_USE_PLATFORM_OHOS // State Utilty functions std::vector> GetAttachmentViews(const VkRenderPassBeginInfo& rp_begin, const vvl::Framebuffer& fb_state) const; diff --git a/layers/vulkan/generated/vk_safe_struct_vendor.cpp b/layers/vulkan/generated/vk_safe_struct_vendor.cpp index fdc5b3f6e..a70ecd225 100644 --- a/layers/vulkan/generated/vk_safe_struct_vendor.cpp +++ b/layers/vulkan/generated/vk_safe_struct_vendor.cpp @@ -15689,7 +15689,9 @@ safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS(const VkImp if (copy_pnext) { pNext = SafePnextCopy(in_struct->pNext, copy_state); } - buffer = in_struct->buffer; + if (in_struct->buffer) { + buffer = in_struct->buffer; + } } safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS() @@ -15699,8 +15701,9 @@ safe_VkImportNativeBufferInfoOHOS::safe_VkImportNativeBufferInfoOHOS(const safe_ sType = copy_src.sType; buffer = nullptr; pNext = SafePnextCopy(copy_src.pNext); - - buffer = copy_src.buffer; + if (copy_src.buffer) { + buffer = copy_src.buffer; + } } safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=(const safe_VkImportNativeBufferInfoOHOS& copy_src) { @@ -15711,8 +15714,9 @@ safe_VkImportNativeBufferInfoOHOS& safe_VkImportNativeBufferInfoOHOS::operator=( sType = copy_src.sType; buffer = nullptr; pNext = SafePnextCopy(copy_src.pNext); - - buffer = copy_src.buffer; + if (copy_src.buffer) { + buffer = copy_src.buffer; + } return *this; } @@ -15727,8 +15731,9 @@ void safe_VkImportNativeBufferInfoOHOS::initialize(const VkImportNativeBufferInf sType = in_struct->sType; buffer = nullptr; pNext = SafePnextCopy(in_struct->pNext, copy_state); - - buffer = in_struct->buffer; + if (in_struct->buffer) { + buffer = in_struct->buffer; + } } void safe_VkImportNativeBufferInfoOHOS::initialize(const safe_VkImportNativeBufferInfoOHOS* copy_src, @@ -15736,8 +15741,9 @@ void safe_VkImportNativeBufferInfoOHOS::initialize(const safe_VkImportNativeBuff sType = copy_src->sType; buffer = nullptr; pNext = SafePnextCopy(copy_src->pNext); - - buffer = copy_src->buffer; + if (copy_src->buffer) { + buffer = copy_src->buffer; + } } safe_VkMemoryGetNativeBufferInfoOHOS::safe_VkMemoryGetNativeBufferInfoOHOS(const VkMemoryGetNativeBufferInfoOHOS* in_struct, -- Gitee From 75a0a929c817a282adc3f281fcaf324da272ab55 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 19:32:21 +0800 Subject: [PATCH 06/14] clang format Signed-off-by: andrew0229 --- layers/error_message/logging.h | 3 +-- layers/error_message/ohos_log.h | 6 +++--- layers/state_tracker/state_tracker.cpp | 3 +-- layers/state_tracker/state_tracker.h | 6 +++--- layers/vulkan/generated/chassis.cpp | 5 ++--- layers/vulkan/generated/layer_chassis_dispatch.cpp | 8 ++++---- layers/vulkan/generated/vk_dispatch_table_helper.h | 5 ++--- layers/vulkan/generated/vk_safe_struct.h | 3 ++- layers/vulkan/generated/vk_safe_struct_core.cpp | 10 +++------- layers/vulkan/generated/vk_safe_struct_vendor.cpp | 2 +- 10 files changed, 22 insertions(+), 29 deletions(-) diff --git a/layers/error_message/logging.h b/layers/error_message/logging.h index 4654057a7..857ec77b4 100644 --- a/layers/error_message/logging.h +++ b/layers/error_message/logging.h @@ -39,11 +39,10 @@ [[maybe_unused]] static const char *kForceDefaultCallbackKey = "debug.vvl.forcelayerlog"; #endif -#if defined (__OHOS__) +#if defined(__OHOS__) #include "ohos_log.h" #endif - extern const char *kVUIDUndefined; typedef enum DebugCallbackStatusBits { diff --git a/layers/error_message/ohos_log.h b/layers/error_message/ohos_log.h index 0d59a424d..c6e8b49d2 100644 --- a/layers/error_message/ohos_log.h +++ b/layers/error_message/ohos_log.h @@ -24,7 +24,7 @@ // do { \ // VKHILOGW(__VA_ARGS__); \ // } while (0) -#define VVL_LOGE(...) \ - do { \ - OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ +#define VVL_LOGE(...) \ + do { \ + OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ } while (0) \ No newline at end of file diff --git a/layers/state_tracker/state_tracker.cpp b/layers/state_tracker/state_tracker.cpp index f4506fc33..db57b5568 100644 --- a/layers/state_tracker/state_tracker.cpp +++ b/layers/state_tracker/state_tracker.cpp @@ -3947,8 +3947,7 @@ void ValidationStateTracker::PostCallRecordCreateHeadlessSurfaceEXT(VkInstance i } #ifdef VK_USE_PLATFORM_OHOS -void ValidationStateTracker::PostCallRecordCreateSurfaceOHOS(VkInstance instance, - const VkSurfaceCreateInfoOHOS *pCreateInfo, +void ValidationStateTracker::PostCallRecordCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface, const RecordObject &record_obj) { if (VK_SUCCESS != record_obj.result) return; diff --git a/layers/state_tracker/state_tracker.h b/layers/state_tracker/state_tracker.h index 9e4fcdb24..668e75c9f 100644 --- a/layers/state_tracker/state_tracker.h +++ b/layers/state_tracker/state_tracker.h @@ -1500,9 +1500,9 @@ class ValidationStateTracker : public ValidationObject { const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface, const RecordObject& record_obj) override; #ifdef VK_USE_PLATFORM_OHOS - void PostCallRecordCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface, - const RecordObject &record_obj) override; + void PostCallRecordCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface, + const RecordObject& record_obj) override; #endif // VK_USE_PLATFORM_OHOS // State Utilty functions std::vector> GetAttachmentViews(const VkRenderPassBeginInfo& rp_begin, diff --git a/layers/vulkan/generated/chassis.cpp b/layers/vulkan/generated/chassis.cpp index ca089c31b..7ebeadbc0 100644 --- a/layers/vulkan/generated/chassis.cpp +++ b/layers/vulkan/generated/chassis.cpp @@ -17172,12 +17172,11 @@ VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer comm } } -VKAPI_ATTR void VKAPI_CALL CmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) -{ +VKAPI_ATTR void VKAPI_CALL CmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, + const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) { DispatchCmdDrawBlurImageHUAWEI(commandBuffer, drawBlurImageInfo); } - // Map of intercepted ApiName to its associated function data #ifdef _MSC_VER #pragma warning(suppress : 6262) // VS analysis: this uses more than 16 kiB, which is fine here at global scope diff --git a/layers/vulkan/generated/layer_chassis_dispatch.cpp b/layers/vulkan/generated/layer_chassis_dispatch.cpp index 49f0a5e04..45dfad194 100644 --- a/layers/vulkan/generated/layer_chassis_dispatch.cpp +++ b/layers/vulkan/generated/layer_chassis_dispatch.cpp @@ -9286,10 +9286,9 @@ void DispatchCmdDrawMeshTasksIndirectCountEXT(VkCommandBuffer commandBuffer, VkB void DispatchCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) { auto layer_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); - if (!wrap_handles) - return layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, drawBlurImageInfo); + if (!wrap_handles) return layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, drawBlurImageInfo); safe_VkDrawBlurImageInfoHUAWEI var_local_drawBlurImageInfo; - safe_VkDrawBlurImageInfoHUAWEI *local_drawBlurImageInfo = nullptr; + safe_VkDrawBlurImageInfoHUAWEI* local_drawBlurImageInfo = nullptr; { if (drawBlurImageInfo) { local_drawBlurImageInfo = &var_local_drawBlurImageInfo; @@ -9299,7 +9298,8 @@ void DispatchCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, const VkDrawB } } } - layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, (const VkDrawBlurImageInfoHUAWEI*)local_drawBlurImageInfo); + layer_data->device_dispatch_table.CmdDrawBlurImageHUAWEI(commandBuffer, + (const VkDrawBlurImageInfoHUAWEI*)local_drawBlurImageInfo); } // NOLINTEND diff --git a/layers/vulkan/generated/vk_dispatch_table_helper.h b/layers/vulkan/generated/vk_dispatch_table_helper.h index 33557428a..23c6879b5 100644 --- a/layers/vulkan/generated/vk_dispatch_table_helper.h +++ b/layers/vulkan/generated/vk_dispatch_table_helper.h @@ -1814,7 +1814,7 @@ static VKAPI_ATTR void VKAPI_CALL StubCmdDrawMeshTasksIndirectCountEXT(VkCommand VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) {} static VKAPI_ATTR void VKAPI_CALL StubCmdDrawBlurImageHUAWEI(VkCommandBuffer commandBuffer, - const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) {} + const VkDrawBlurImageInfoHUAWEI* drawBlurImageInfo) {} const vvl::unordered_map> api_extension_map{ {"vkBindBufferMemory2", {"VK_VERSION_1_1"}}, @@ -4466,8 +4466,7 @@ static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDisp if (table->CmdDrawMeshTasksIndirectCountEXT == nullptr) { table->CmdDrawMeshTasksIndirectCountEXT = (PFN_vkCmdDrawMeshTasksIndirectCountEXT)StubCmdDrawMeshTasksIndirectCountEXT; } - table->CmdDrawBlurImageHUAWEI = - (PFN_vkCmdDrawBlurImageHUAWEI)gpa(device, "vkCmdDrawBlurImageHUAWEI"); + table->CmdDrawBlurImageHUAWEI = (PFN_vkCmdDrawBlurImageHUAWEI)gpa(device, "vkCmdDrawBlurImageHUAWEI"); if (table->CmdDrawBlurImageHUAWEI == nullptr) { table->CmdDrawBlurImageHUAWEI = (PFN_vkCmdDrawBlurImageHUAWEI)StubCmdDrawBlurImageHUAWEI; } diff --git a/layers/vulkan/generated/vk_safe_struct.h b/layers/vulkan/generated/vk_safe_struct.h index dc3b26e6f..e5c38b51e 100644 --- a/layers/vulkan/generated/vk_safe_struct.h +++ b/layers/vulkan/generated/vk_safe_struct.h @@ -18424,7 +18424,8 @@ struct safe_VkDrawBlurImageInfoHUAWEI { VkRect2D dstRegion; VkImageView srcImageView; - safe_VkDrawBlurImageInfoHUAWEI(const VkDrawBlurImageInfoHUAWEI* in_struct, PNextCopyState* copy_state = {}, bool copy_pnext = true); + safe_VkDrawBlurImageInfoHUAWEI(const VkDrawBlurImageInfoHUAWEI* in_struct, PNextCopyState* copy_state = {}, + bool copy_pnext = true); safe_VkDrawBlurImageInfoHUAWEI(const safe_VkDrawBlurImageInfoHUAWEI& copy_src); safe_VkDrawBlurImageInfoHUAWEI& operator=(const safe_VkDrawBlurImageInfoHUAWEI& copy_src); safe_VkDrawBlurImageInfoHUAWEI(); diff --git a/layers/vulkan/generated/vk_safe_struct_core.cpp b/layers/vulkan/generated/vk_safe_struct_core.cpp index 7829ec8e3..f31172a85 100644 --- a/layers/vulkan/generated/vk_safe_struct_core.cpp +++ b/layers/vulkan/generated/vk_safe_struct_core.cpp @@ -19397,12 +19397,7 @@ void safe_VkDeviceImageMemoryRequirements::initialize(const safe_VkDeviceImageMe } safe_VkDrawBlurImageInfoHUAWEI::safe_VkDrawBlurImageInfoHUAWEI() - : sType(VK_STRUCTURE_TYPE_DRAW_BLUR_IMAGE_INFO_HUAWEI), - pNext(nullptr), - sigma(), - srcRegion(), - dstRegion(), - srcImageView() {} + : sType(VK_STRUCTURE_TYPE_DRAW_BLUR_IMAGE_INFO_HUAWEI), pNext(nullptr), sigma(), srcRegion(), dstRegion(), srcImageView() {} safe_VkDrawBlurImageInfoHUAWEI& safe_VkDrawBlurImageInfoHUAWEI::operator=(const safe_VkDrawBlurImageInfoHUAWEI& copy_src) { if (©_src == this) return *this; @@ -19421,7 +19416,8 @@ safe_VkDrawBlurImageInfoHUAWEI& safe_VkDrawBlurImageInfoHUAWEI::operator=(const safe_VkDrawBlurImageInfoHUAWEI::~safe_VkDrawBlurImageInfoHUAWEI() { FreePnextChain(pNext); } -void safe_VkDrawBlurImageInfoHUAWEI::initialize(const VkDrawBlurImageInfoHUAWEI* in_struct, [[maybe_unused]] PNextCopyState* copy_state) { +void safe_VkDrawBlurImageInfoHUAWEI::initialize(const VkDrawBlurImageInfoHUAWEI* in_struct, + [[maybe_unused]] PNextCopyState* copy_state) { FreePnextChain(pNext); sType = in_struct->sType; sigma = in_struct->sigma; diff --git a/layers/vulkan/generated/vk_safe_struct_vendor.cpp b/layers/vulkan/generated/vk_safe_struct_vendor.cpp index a70ecd225..530d87824 100644 --- a/layers/vulkan/generated/vk_safe_struct_vendor.cpp +++ b/layers/vulkan/generated/vk_safe_struct_vendor.cpp @@ -15271,7 +15271,7 @@ safe_VkSurfaceCreateInfoOHOS::safe_VkSurfaceCreateInfoOHOS(const VkSurfaceCreate pNext = SafePnextCopy(in_struct->pNext, copy_state); } if (in_struct->window) { - window =in_struct->window; + window = in_struct->window; } } -- Gitee From b1eb9abe4505b4c732b1462075078d3fa3707b40 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 19:37:24 +0800 Subject: [PATCH 07/14] add deps patches Signed-off-by: andrew0229 --- layers/error_message/ohos_log.h | 17 ----------------- scripts/ohos-patches/SPIRV-Headers.patch | Bin 0 -> 830 bytes scripts/ohos-patches/SPIRV-Tools.patch | Bin 0 -> 8834 bytes scripts/ohos-patches/Vulkan-Headers.patch | Bin 0 -> 9936 bytes .../Vulkan-Utility-Libraries.patch | Bin 0 -> 2078 bytes scripts/ohos-patches/glslang.patch | Bin 0 -> 10876 bytes 6 files changed, 17 deletions(-) create mode 100644 scripts/ohos-patches/SPIRV-Headers.patch create mode 100644 scripts/ohos-patches/SPIRV-Tools.patch create mode 100644 scripts/ohos-patches/Vulkan-Headers.patch create mode 100644 scripts/ohos-patches/Vulkan-Utility-Libraries.patch create mode 100644 scripts/ohos-patches/glslang.patch diff --git a/layers/error_message/ohos_log.h b/layers/error_message/ohos_log.h index c6e8b49d2..c350788b2 100644 --- a/layers/error_message/ohos_log.h +++ b/layers/error_message/ohos_log.h @@ -7,23 +7,6 @@ #define LOG_DOMAIN 0xD001405 #define LOG_TAG "VulkanValidationLayer" -// #define VKHILOGD(fmt, ...) OH_LOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) -// #define VKHILOGE(fmt, ...) OH_LOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) - -// #define VVL_LOGV(...) - -// #define VVL_LOGD(...) \ -// do { \ -// VKHILOGD(__VA_ARGS__); \ -// } while (0) -// #define VVL_LOGI(...) \ -// do { \ -// VKHILOGI(__VA_ARGS__); \ -// } while (0) -// #define VVL_LOGW(...) \ -// do { \ -// VKHILOGW(__VA_ARGS__); \ -// } while (0) #define VVL_LOGE(...) \ do { \ OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ diff --git a/scripts/ohos-patches/SPIRV-Headers.patch b/scripts/ohos-patches/SPIRV-Headers.patch new file mode 100644 index 0000000000000000000000000000000000000000..3539b5de4a3d6f37b8bf7694c414baec8d90a152 GIT binary patch literal 830 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 AtpET3 literal 0 HcmV?d00001 -- Gitee From 7aae892d3bae10c6ac5513a04d4d598e1cf54800 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 19:51:59 +0800 Subject: [PATCH 08/14] remove build patch Signed-off-by: andrew0229 --- build.patch | 13 ---------- graphic_2d.patch | 24 ------------------- .../ohos-patches/compile.bat | 0 3 files changed, 37 deletions(-) delete mode 100644 build.patch delete mode 100644 graphic_2d.patch rename compile.bat => scripts/ohos-patches/compile.bat (100%) diff --git a/build.patch b/build.patch deleted file mode 100644 index 488f0e19c..000000000 --- a/build.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/compile_standard_whitelist.json b/compile_standard_whitelist.json -index b0bee416..e1177539 100644 ---- a/compile_standard_whitelist.json -+++ b/compile_standard_whitelist.json -@@ -692,6 +692,8 @@ - "//third_party/vk-gl-cts/modules/gles3:libdeqp-gles3", - "//third_party/vk-gl-cts/modules/glshared:deqp-gl-shared_source", - "//third_party/vk-gl-cts/modules/glshared:libdeqp-gl-shared", -+ "//third_party/vulkan-validationlayers:VkLayer_khronos_validation", -+ "//third_party/vulkan-validationlayers:vulkan_layer_utils", - "//third_party/rust/crates/rust-openssl/openssl-sys:lib" - ] - } diff --git a/graphic_2d.patch b/graphic_2d.patch deleted file mode 100644 index 4cd33f06d..000000000 --- a/graphic_2d.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/bundle.json b/bundle.json -index 3c54d54bb1..f6f0e08efb 100644 ---- a/bundle.json -+++ b/bundle.json -@@ -113,7 +113,8 @@ - "egl", - "opengles", - "vulkan-headers", -- "vulkan-loader" -+ "vulkan-loader", -+ "vulkan-validationlayers" - ] - }, - "build": { -@@ -138,7 +139,8 @@ - "//foundation/graphic/graphic_2d/rosen/modules/texgine:libtexgine", - "//foundation/graphic/graphic_2d/frameworks/vulkan_layers:vulkan_swapchain_layer", - "//foundation/graphic/graphic_2d/frameworks/vulkan_layers:vulkan_swapchain_layer_json", -- "//foundation/graphic/graphic_2d/rosen/modules/graphics_effect:libgraphics_effect" -+ "//foundation/graphic/graphic_2d/rosen/modules/graphics_effect:libgraphics_effect", -+ "//third_party/vulkan-validationlayers:VkLayer_khronos_validation" - ], - "fwk_group": [ - "//foundation/graphic/graphic_2d/rosen/modules/render_service_base:librender_service_base", diff --git a/compile.bat b/scripts/ohos-patches/compile.bat similarity index 100% rename from compile.bat rename to scripts/ohos-patches/compile.bat -- Gitee From 2f55ae7e0b04b0a4090555fab6df7ba1a418e654 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 20:06:54 +0800 Subject: [PATCH 09/14] update patches Signed-off-by: andrew0229 --- scripts/ohos-patches/SPIRV-Headers.patch | Bin 830 -> 0 bytes scripts/ohos-patches/SPIRV-Tools.patch | Bin 8834 -> 970 bytes .../Vulkan-Utility-Libraries.patch | Bin 2078 -> 1472 bytes scripts/ohos-patches/glslang.patch | Bin 10876 -> 444 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 scripts/ohos-patches/SPIRV-Headers.patch diff --git a/scripts/ohos-patches/SPIRV-Headers.patch b/scripts/ohos-patches/SPIRV-Headers.patch deleted file mode 100644 index 3539b5de4a3d6f37b8bf7694c414baec8d90a152..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 830 zcmd6lTMEK35Jm5|;2ydGU*KZ}g1aawsj=8rv5LBR^&}_~@Iy)wxzJ2z?qrxl?>DPL zYm{h!9JeE}(TH=0N;SlpPE<-+t&~%>d=Jk`p&ExHQ-`dfGgpe+ka2XHP))TV|Lz@X zuPd{%pUvv47dEm?t%&>%rg z7o?pT9p;?*Ql4dCnp>_Qem`Hv-_Ye!NlQH`*!)(|c$wl845k|#rCDNGNj#X02P7~Y z3?^r1nrWH`Dw<&!hf1>vNxr7<_naP?yXXg;V2eIsbkwqT(TH}S zs05*lQng6ZuZgHQ&wsR7Y;r6J#>CQ0o`LT8A&`mJcn*tgzYVxc;5EDO+PR6?J)5sr MZG0r-{bC8UpXyg7;s5{u literal 8834 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 AtpET3 -- Gitee From 7ebc4c2b3d4a20f2380dfb6dd7fbc2887cd85189 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 20:22:32 +0800 Subject: [PATCH 10/14] add json for ohos Signed-off-by: andrew0229 --- .../VkLayer_khronos_validation.json | 1426 +++++++++++++++++ 1 file changed, 1426 insertions(+) create mode 100644 scripts/ohos-patches/VkLayer_khronos_validation.json diff --git a/scripts/ohos-patches/VkLayer_khronos_validation.json b/scripts/ohos-patches/VkLayer_khronos_validation.json new file mode 100644 index 000000000..4b0c58bf5 --- /dev/null +++ b/scripts/ohos-patches/VkLayer_khronos_validation.json @@ -0,0 +1,1426 @@ +{ + "file_format_version": "1.2.0", + "layer": { + "name": "VK_LAYER_KHRONOS_validation", + "type": "GLOBAL", + "library_path": "libVkLayer_khronos_validation.so", + "api_version": "1.3.275", + "implementation_version": "1", + "description": "Khronos Validation Layer", + "introduction": "The main, comprehensive Khronos validation layer.\n\nVulkan is an Explicit API, enabling direct control over how GPUs actually work. By design, minimal error checking is done inside a Vulkan driver. Applications have full control and responsibility for correct operation. Any errors in how Vulkan is used can result in a crash. \n\nThe Khronos Valiation Layer can be enabled to assist development by enabling developers to verify their applications correctly use the Vulkan API.", + "platforms": [ + "WINDOWS", + "LINUX", + "ANDROID", + "MACOS", + "OHOS" + ], + "url": "https://vulkan.lunarg.com/doc/sdk/latest/windows/khronos_validation_layer.html", + "instance_extensions": [ + { + "name": "VK_EXT_debug_report", + "spec_version": "9" + }, + { + "name": "VK_EXT_debug_utils", + "spec_version": "1" + }, + { + "name": "VK_EXT_validation_features", + "spec_version": "2" + } + ], + "device_extensions": [ + { + "name": "VK_EXT_debug_marker", + "spec_version": "4", + "entrypoints": [ + "vkDebugMarkerSetObjectTagEXT", + "vkDebugMarkerSetObjectNameEXT", + "vkCmdDebugMarkerBeginEXT", + "vkCmdDebugMarkerEndEXT", + "vkCmdDebugMarkerInsertEXT" + ] + }, + { + "name": "VK_EXT_validation_cache", + "spec_version": "1", + "entrypoints": [ + "vkCreateValidationCacheEXT", + "vkDestroyValidationCacheEXT", + "vkGetValidationCacheDataEXT", + "vkMergeValidationCachesEXT" + ] + }, + { + "name": "VK_EXT_tooling_info", + "spec_version": "1", + "entrypoints": [ + "vkGetPhysicalDeviceToolPropertiesEXT" + ] + } + ], + "features": { + "presets": [ + { + "label": "Standard", + "description": "Good default validation setup that balance validation coverage and performance.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": true + }, + { + "key": "check_image_layout", + "value": true + }, + { + "key": "check_command_buffer", + "value": true + }, + { + "key": "check_object_in_use", + "value": true + }, + { + "key": "check_query", + "value": true + }, + { + "key": "check_shaders", + "value": true + }, + { + "key": "check_shaders_caching", + "value": true + }, + { + "key": "unique_handles", + "value": true + }, + { + "key": "object_lifetime", + "value": true + }, + { + "key": "stateless_param", + "value": true + }, + { + "key": "thread_safety", + "value": false + }, + { + "key": "validate_sync", + "value": false + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_NONE" + }, + { + "key": "validate_best_practices", + "value": false + } + ] + }, + { + "label": "Reduced-Overhead", + "description": "Disables some checks in the interest of better performance.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": true + }, + { + "key": "check_image_layout", + "value": false + }, + { + "key": "check_command_buffer", + "value": false + }, + { + "key": "check_object_in_use", + "value": false + }, + { + "key": "check_query", + "value": false + }, + { + "key": "check_shaders", + "value": true + }, + { + "key": "check_shaders_caching", + "value": true + }, + { + "key": "unique_handles", + "value": false + }, + { + "key": "object_lifetime", + "value": true + }, + { + "key": "stateless_param", + "value": true + }, + { + "key": "thread_safety", + "value": false + }, + { + "key": "validate_sync", + "value": false + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_NONE" + }, + { + "key": "validate_best_practices", + "value": false + } + ] + }, + { + "label": "Best Practices", + "description": "Provides warnings on valid API usage that is potential API misuse.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": false + }, + { + "key": "check_image_layout", + "value": false + }, + { + "key": "check_command_buffer", + "value": false + }, + { + "key": "check_object_in_use", + "value": false + }, + { + "key": "check_query", + "value": false + }, + { + "key": "check_shaders", + "value": false + }, + { + "key": "check_shaders_caching", + "value": false + }, + { + "key": "unique_handles", + "value": false + }, + { + "key": "object_lifetime", + "value": false + }, + { + "key": "stateless_param", + "value": false + }, + { + "key": "thread_safety", + "value": false + }, + { + "key": "validate_sync", + "value": false + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_NONE" + }, + { + "key": "validate_best_practices", + "value": true + } + ] + }, + { + "label": "Synchronization", + "description": "Identify resource access conflicts due to missing or incorrect synchronization operations between actions reading or writing the same regions of memory.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": false + }, + { + "key": "check_image_layout", + "value": false + }, + { + "key": "check_command_buffer", + "value": false + }, + { + "key": "check_object_in_use", + "value": false + }, + { + "key": "check_query", + "value": false + }, + { + "key": "check_shaders", + "value": false + }, + { + "key": "check_shaders_caching", + "value": false + }, + { + "key": "unique_handles", + "value": false + }, + { + "key": "object_lifetime", + "value": false + }, + { + "key": "stateless_param", + "value": false + }, + { + "key": "thread_safety", + "value": true + }, + { + "key": "validate_sync", + "value": true + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_NONE" + }, + { + "key": "validate_best_practices", + "value": false + } + ] + }, + { + "label": "GPU-Assisted", + "description": "Check for API usage errors at shader execution time.", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": false + }, + { + "key": "check_image_layout", + "value": false + }, + { + "key": "check_command_buffer", + "value": false + }, + { + "key": "check_object_in_use", + "value": false + }, + { + "key": "check_query", + "value": false + }, + { + "key": "check_shaders", + "value": false + }, + { + "key": "check_shaders_caching", + "value": false + }, + { + "key": "unique_handles", + "value": false + }, + { + "key": "object_lifetime", + "value": false + }, + { + "key": "stateless_param", + "value": false + }, + { + "key": "thread_safety", + "value": false + }, + { + "key": "validate_sync", + "value": false + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + }, + { + "key": "reserve_binding_slot", + "value": true + }, + { + "key": "validate_best_practices", + "value": false + } + ] + }, + { + "label": "Debug Printf", + "description": "Debug shader code by \"printing\" any values of interest to the debug callback or stdout.", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "status": "STABLE", + "settings": [ + { + "key": "validate_core", + "value": false + }, + { + "key": "check_image_layout", + "value": false + }, + { + "key": "check_command_buffer", + "value": false + }, + { + "key": "check_object_in_use", + "value": false + }, + { + "key": "check_query", + "value": false + }, + { + "key": "check_shaders", + "value": false + }, + { + "key": "check_shaders_caching", + "value": false + }, + { + "key": "unique_handles", + "value": false + }, + { + "key": "object_lifetime", + "value": false + }, + { + "key": "stateless_param", + "value": false + }, + { + "key": "thread_safety", + "value": false + }, + { + "key": "validate_sync", + "value": false + }, + { + "key": "validate_gpu_based", + "value": "GPU_BASED_DEBUG_PRINTF" + }, + { + "key": "validate_best_practices", + "value": false + } + ] + } + ], + "settings": [ + { + "key": "validation_control", + "label": "Validation Areas", + "description": "Control of the Validation layer validation", + "type": "GROUP", + "expanded": true, + "settings": [ + { + "key": "fine_grained_locking", + "env": "VK_LAYER_FINE_GRAINED_LOCKING", + "label": "Fine Grained Locking", + "description": "Enable fine grained locking for Core Validation, which should improve performance in multithreaded applications. This setting allows the optimization to be disabled for debugging.", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "validate_core", + "label": "Core", + "description": "The main, heavy-duty validation checks. This may be valuable early in the development cycle to reduce validation output while correcting parameter/object usage errors.", + "type": "BOOL", + "default": true, + "settings": [ + { + "key": "check_image_layout", + "label": "Image Layout", + "description": "Check that the layout of each image subresource is correct whenever it is used by a command buffer. These checks are very CPU intensive for some applications.", + "type": "BOOL", + "default": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + } + ] + } + }, + { + "key": "check_command_buffer", + "label": "Command Buffer State", + "description": "Check that all Vulkan objects used by a command buffer have not been destroyed. These checks can be CPU intensive for some applications.", + "type": "BOOL", + "default": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + } + ] + } + }, + { + "key": "check_object_in_use", + "label": "Object in Use", + "description": "Check that Vulkan objects are not in use by a command buffer when they are destroyed.", + "type": "BOOL", + "default": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + } + ] + } + }, + { + "key": "check_query", + "label": "Query", + "description": "Checks for commands that use VkQueryPool objects.", + "type": "BOOL", + "default": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + } + ] + } + }, + { + "key": "check_shaders", + "label": "Shader", + "description": "Shader checks. These checks can be CPU intensive during application start up, especially if Shader Validation Caching is also disabled.", + "type": "BOOL", + "default": true, + "expanded": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + } + ] + }, + "settings": [ + { + "key": "check_shaders_caching", + "label": "Caching", + "description": "Enable caching of shader validation results.", + "type": "BOOL", + "default": true, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_core", + "value": true + }, + { + "key": "check_shaders", + "value": true + } + ] + } + } + ] + } + ] + }, + { + "key": "unique_handles", + "label": "Handle Wrapping", + "description": "Handle wrapping checks. Disable this feature if you are exerience crashes when creating new extensions or developing new Vulkan objects/structures.", + "type": "BOOL", + "default": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "object_lifetime", + "label": "Object Lifetime", + "description": "Object tracking checks. This may not always be necessary late in a development cycle.", + "type": "BOOL", + "default": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "stateless_param", + "label": "Stateless Parameter", + "description": "Stateless parameter checks. This may not always be necessary late in a development cycle.", + "type": "BOOL", + "default": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "thread_safety", + "label": "Thread Safety", + "description": "Thread checks. In order to not degrade performance, it might be best to run your program with thread-checking disabled most of the time, enabling it occasionally for a quick sanity check or when debugging difficult application behaviors.", + "type": "BOOL", + "default": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "validate_sync", + "label": "Synchronization", + "description": "Enable synchronization validation during command buffers recording. This feature reports resource access conflicts due to missing or incorrect synchronization operations between actions (Draw, Copy, Dispatch, Blit) reading or writing the same regions of memory.", + "url": "${LUNARG_SDK}/synchronization_usage.html", + "type": "BOOL", + "default": false, + "expanded": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "settings": [ + { + "key": "sync_queue_submit", + "label": "QueueSubmit Synchronization Validation", + "description": "Enable synchronization validation between submitted command buffers when Synchronization Validation is enabled. This option will increase the synchronization performance cost.", + "type": "BOOL", + "default": true, + "status": "STABLE", + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_sync", + "value": true + } + ] + } + } + ] + }, + { + "key": "validate_gpu_based", + "label": "GPU Base", + "description": "Setting an option here will enable specialized areas of validation", + "type": "ENUM", + "default": "GPU_BASED_NONE", + "expanded": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "flags": [ + { + "key": "GPU_BASED_NONE", + "label": "None", + "description": "No GPU-based validation." + }, + { + "key": "GPU_BASED_DEBUG_PRINTF", + "label": "Debug Printf", + "description": "Enables processing of debug printf instructions in shaders and sending debug strings to the debug callback.", + "url": "${LUNARG_SDK}/debug_printf.html", + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "settings": [ + { + "key": "printf_to_stdout", + "label": "Redirect Printf messages to stdout", + "description": "Enable redirection of Debug Printf messages from the debug callback to stdout", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_DEBUG_PRINTF" + } + ] + } + }, + { + "key": "printf_verbose", + "label": "Printf verbose", + "description": "Set the verbosity of debug printf messages", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_DEBUG_PRINTF" + } + ] + } + }, + { + "key": "printf_buffer_size", + "label": "Printf buffer size", + "description": "Set the size in bytes of the buffer used by debug printf", + "type": "INT", + "default": 1024, + "range": { + "min": 128, + "max": 1048576 + }, + "unit": "bytes", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_DEBUG_PRINTF" + } + ] + } + } + ] + }, + { + "key": "GPU_BASED_GPU_ASSISTED", + "label": "GPU-Assisted", + "description": "Check for API usage errors at shader execution time.", + "url": "${LUNARG_SDK}/gpu_validation.html", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "settings": [ + { + "key": "reserve_binding_slot", + "label": "Reserve Descriptor Set Binding Slot", + "type": "BOOL", + "default": true, + "description": "Specifies that the validation layers reserve a descriptor set binding slot for their own use. The layer reports a value for VkPhysicalDeviceLimits::maxBoundDescriptorSets that is one less than the value reported by the device. If the device supports the binding of only one descriptor set, the validation layer does not perform GPU-assisted validation.", + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + }, + { + "key": "vma_linear_output", + "label": "Linear Memory Allocation Mode", + "description": "Use VMA linear memory allocations for GPU-AV output buffers instead of finding best place for new allocations among free regions to optimize memory usage. Enabling this setting reduces performance cost but disabling this method minimizes memory usage.", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "status": "STABLE", + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + }, + { + "key": "gpuav_descriptor_checks", + "label": "Descriptor and OOB Checks", + "description": "Enable descriptor and buffer out of bounds checking", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + }, + "settings": [ + { + "key": "warn_on_robust_oob", + "label": "Generate warning on out of bounds accesses even if buffer robustness is enabled", + "description": "Warn on out of bounds accesses even if robustness is enabled", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "gpuav_descriptor_checks", + "value": true + } + ] + } + } + ] + }, + { + "key": "validate_indirect_buffer", + "label": "Check Draw/Dispatch/TraceRays Indirect buffers", + "description": "Enable draw/dispatch/traceRays indirect checking", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + }, + { + "key": "use_instrumented_shader_cache", + "label": "Cache instrumented shaders rather than instrumenting them on every run", + "description": "Enable instrumented shader caching", + "type": "BOOL", + "default": true, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + }, + { + "key": "select_instrumented_shaders", + "label": "Enable instrumenting shaders selectively", + "description": "Select which shaders to instrument passing a VkValidationFeaturesEXT struct with GPU-AV enabled in the VkShaderModuleCreateInfo pNext", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + }, + { + "key": "gpuav_max_buffer_device_addresses", + "label": "Specify the maximum number of buffer device addresses in use at one time", + "description": "Specify maximum number of buffer device addresses", + "type": "INT", + "default": 10000, + "platforms": [ + "WINDOWS", + "LINUX" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_gpu_based", + "value": "GPU_BASED_GPU_ASSISTED" + } + ] + } + } + ] + } + ] + }, + { + "key": "validate_best_practices", + "label": "Best Practices", + "description": "Outputs warnings related to common misuse of the API, but which are not explicitly prohibited by the specification.", + "url": "${LUNARG_SDK}/best_practices.html", + "type": "BOOL", + "default": false, + "expanded": true, + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "settings": [ + { + "key": "validate_best_practices_arm", + "label": "ARM-specific best practices", + "description": "Outputs warnings for spec-conforming but non-ideal code on ARM GPUs.", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_best_practices", + "value": true + } + ] + } + }, + { + "key": "validate_best_practices_amd", + "label": "AMD-specific best practices", + "description": "Outputs warnings for spec-conforming but non-ideal code on AMD GPUs.", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_best_practices", + "value": true + } + ] + } + }, + { + "key": "validate_best_practices_img", + "label": "IMG-specific best practices", + "description": "Outputs warnings for spec-conforming but non-ideal code on Imagination GPUs.", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_best_practices", + "value": true + } + ] + } + }, + { + "key": "validate_best_practices_nvidia", + "label": "NVIDIA-specific best practices", + "description": "Outputs warnings for spec-conforming but non-ideal code on NVIDIA GPUs.", + "type": "BOOL", + "default": false, + "platforms": [ + "WINDOWS", + "LINUX", + "ANDROID", + "OHOS" + ], + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "validate_best_practices", + "value": true + } + ] + } + } + ] + } + ] + }, + { + "key": "debug_action", + "label": "Debug Action", + "description": "Specifies what action is to be taken when a layer reports information", + "type": "FLAGS", + "flags": [ + { + "key": "VK_DBG_LAYER_ACTION_LOG_MSG", + "label": "Log Message", + "description": "Log a txt message to stdout or to a log filename.", + "settings": [ + { + "key": "log_filename", + "label": "Log Filename", + "description": "Specifies the output filename", + "type": "SAVE_FILE", + "default": "stdout", + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "debug_action", + "value": [ + "VK_DBG_LAYER_ACTION_LOG_MSG" + ] + } + ] + } + } + ] + }, + { + "key": "VK_DBG_LAYER_ACTION_CALLBACK", + "label": "Callback", + "description": "Call user defined callback function(s) that have been registered via the VK_EXT_debug_report extension. Since application must register callback, this is a NOOP for the settings file.", + "view": "HIDDEN" + }, + { + "key": "VK_DBG_LAYER_ACTION_DEBUG_OUTPUT", + "label": "Debug Output", + "description": "Log a txt message using the Windows OutputDebugString function.", + "platforms": [ + "WINDOWS" + ] + }, + { + "key": "VK_DBG_LAYER_ACTION_BREAK", + "label": "Break", + "description": "Trigger a breakpoint if a debugger is in use." + } + ], + "default": [ + "VK_DBG_LAYER_ACTION_LOG_MSG" + ] + }, + { + "key": "report_flags", + "label": "Message Severity", + "description": "Comma-delineated list of options specifying the types of messages to be reported", + "type": "FLAGS", + "flags": [ + { + "key": "info", + "label": "Info", + "description": "Report informational messages." + }, + { + "key": "warn", + "label": "Warning", + "description": "Report warnings from using the API in a manner which may lead to undefined behavior or to warn the user of common trouble spots. A warning does NOT necessarily signify illegal application behavior." + }, + { + "key": "perf", + "label": "Performance", + "description": "Report usage of the API that may cause suboptimal performance." + }, + { + "key": "error", + "label": "Error", + "description": "Report errors in API usage." + }, + { + "key": "debug", + "label": "Debug", + "description": "For layer development. Report messages for debugging layer behavior.", + "view": "HIDDEN" + } + ], + "default": [ + "error" + ] + }, + { + "key": "enable_message_limit", + "label": "Limit Duplicated Messages", + "description": "Enable limiting of duplicate messages.", + "type": "BOOL", + "default": true, + "settings": [ + { + "key": "duplicate_message_limit", + "env": "VK_LAYER_DUPLICATE_MESSAGE_LIMIT", + "label": "Max Duplicated Messages", + "description": "Maximum number of times any single validation message should be reported.", + "type": "INT", + "default": 10, + "range": { + "min": 1 + }, + "dependence": { + "mode": "ALL", + "settings": [ + { + "key": "enable_message_limit", + "value": true + } + ] + } + } + ] + }, + { + "key": "message_id_filter", + "label": "Mute Message VUIDs", + "description": "List of VUIDs and VUID identifers which are to be IGNORED by the validation layer", + "type": "LIST", + "env": "VK_LAYER_MESSAGE_ID_FILTER", + "default": [] + }, + { + "key": "disables", + "label": "Disables", + "description": "Specify areas of validation to be disabled", + "type": "FLAGS", + "env": "VK_LAYER_DISABLES", + "flags": [ + { + "key": "VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT", + "label": "Thread Safety", + "description": "Thread checks. In order to not degrade performance, it might be best to run your program with thread-checking disabled most of the time, enabling it occasionally for a quick sanity check or when debugging difficult application behaviors." + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT", + "label": "Stateless Parameter", + "description": "Stateless parameter checks. This may not always be necessary late in a development cycle." + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT", + "label": "Object Lifetime", + "description": "Object tracking checks. This may not always be necessary late in a development cycle." + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT", + "label": "Core", + "description": "The main, heavy-duty validation checks. This may be valuable early in the development cycle to reduce validation output while correcting parameter/object usage errors." + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT", + "label": "Handle Wrapping", + "description": "Handle wrapping checks. Disable this feature if you are exerience crashes when creating new extensions or developing new Vulkan objects/structures." + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT", + "label": "Shader Validation", + "description": "Shader checks. These checks can be CPU intensive during application start up, especially if Shader Validation Caching is also disabled.", + "view": "ADVANCED" + }, + { + "key": "VALIDATION_CHECK_DISABLE_COMMAND_BUFFER_STATE", + "label": "Command Buffer State", + "description": "Check that all Vulkan objects used by a command buffer have not been destroyed. These checks can be CPU intensive for some applications.", + "view": "ADVANCED" + }, + { + "key": "VALIDATION_CHECK_DISABLE_IMAGE_LAYOUT_VALIDATION", + "label": "Image Layout", + "description": "Check that the layout of each image subresource is correct whenever it is used by a command buffer. These checks are very CPU intensive for some applications.", + "view": "ADVANCED" + }, + { + "key": "VALIDATION_CHECK_DISABLE_QUERY_VALIDATION", + "label": "Query", + "description": "Checks for commands that use VkQueryPool objects.", + "view": "ADVANCED" + }, + { + "key": "VALIDATION_CHECK_DISABLE_OBJECT_IN_USE", + "label": "Object in Use", + "description": "Check that Vulkan objects are not in use by a command buffer when they are destroyed.", + "view": "ADVANCED" + }, + { + "key": "VALIDATION_CHECK_DISABLE_SYNCHRONIZATION_VALIDATION_QUEUE_SUBMIT", + "label": "QueueSubmit Synchronization Validation", + "description": "Check synchronization validation between submitted command buffers when Synchronization Validation is enabled.", + "view": "ADVANCED" + }, + { + "key": "VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT", + "label": "Shader Validation Caching", + "description": "Disable caching of shader validation results.", + "view": "ADVANCED" + } + ], + "default": [ + "VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT" + ] + }, + { + "key": "enables", + "label": "Enables", + "description": "Setting an option here will enable specialized areas of validation", + "type": "FLAGS", + "env": "VK_LAYER_ENABLES", + "flags": [ + { + "key": "VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT", + "label": "Synchronization", + "description": "This feature reports resource access conflicts due to missing or incorrect synchronization operations between actions (Draw, Copy, Dispatch, Blit) reading or writing the same regions of memory.", + "url": "${LUNARG_SDK}/synchronization_usage.html", + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT", + "label": "Debug Printf", + "description": "Enables processing of debug printf instructions in shaders and sending debug strings to the debug callback.", + "url": "${LUNARG_SDK}/debug_printf.html", + "status": "STABLE", + "platforms": [ + "WINDOWS", + "LINUX" + ] + }, + { + "key": "VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT", + "label": "GPU-Assisted", + "description": "Check for API usage errors at shader execution time.", + "url": "${LUNARG_SDK}/gpu_validation.html", + "platforms": [ + "WINDOWS", + "LINUX" + ] + }, + { + "key": "VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT", + "label": "Reserve Descriptor Set Binding Slot", + "description": "Specifies that the validation layers reserve a descriptor set binding slot for their own use. The layer reports a value for VkPhysicalDeviceLimits::maxBoundDescriptorSets that is one less than the value reported by the device. If the device supports the binding of only one descriptor set, the validation layer does not perform GPU-assisted validation.", + "platforms": [ + "WINDOWS", + "LINUX" + ] + }, + { + "key": "VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT", + "label": "Best Practices", + "description": "Activating this feature enables the output of warnings related to common misuse of the API, but which are not explicitly prohibited by the specification.", + "url": "${LUNARG_SDK}/best_practices.html", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_ARM", + "label": "ARM-specific best practices", + "description": "Activating this feature enables the output of warnings related to ARM-specific misuse of the API, but which are not explicitly prohibited by the specification.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS", + "ANDROID", + "OHOS" + ] + }, + { + "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD", + "label": "AMD-specific best practices", + "description": "Adds check for spec-conforming but non-ideal code on AMD GPUs.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS" + ] + }, + { + "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_IMG", + "label": "IMG-specific best practices", + "description": "Adds check for spec-conforming but non-ideal code on Imagination GPUs.", + "platforms": [ + "WINDOWS", + "LINUX", + "MACOS" + ] + }, + { + "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA", + "label": "NVIDIA-specific best practices", + "description": "Activating this feature enables the output of warnings related to NVIDIA-specific misuse of the API, but which are not explicitly prohibited by the specification.", + "platforms": [ + "WINDOWS", + "LINUX", + "ANDROID", + "OHOS" + ] + }, + { + "key": "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_ALL", + "label": "Hardware specific best practices", + "description": "Activating this feature enables all vendor specific best practices.", + "platforms": [ + "WINDOWS", + "LINUX", + "ANDROID", + "OHOS" + ] + } + ], + "default": [] + } + ] + } + } +} \ No newline at end of file -- Gitee From c6829e09b19c79f0430da071ebc9991bec0ce4ab Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Thu, 22 Aug 2024 22:00:11 +0800 Subject: [PATCH 11/14] update readme Signed-off-by: andrew0229 --- ...an-validationlayers_architecture_in_OH.png | Bin 9348 -> 13023 bytes ...vulkan-validationlayers_load_way_in_OH.png | Bin 13873 -> 21664 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/vulkan-validationlayers_architecture_in_OH.png b/docs/images/vulkan-validationlayers_architecture_in_OH.png index c32d6be35785db3beb749edfa3daef7926e5a526..ccc1760fe46d516315614401ca4d8854676ddc66 100644 GIT binary patch literal 13023 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 literal 13873 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 Date: Fri, 23 Aug 2024 15:35:43 +0800 Subject: [PATCH 12/14] update build readme Signed-off-by: andrew0229 --- README_OpenHarmony.md | 190 ++++++++++++++---- docs/images/usermode-use-debug-layer-1.jpg | Bin 0 -> 14970 bytes docs/images/usermode-use-debug-layer-2.jpg | Bin 0 -> 51570 bytes docs/images/usermode-use-debug-layer-3.jpg | Bin 0 -> 11576 bytes .../VkLayer_khronos_validation.json | 5 +- scripts/ohos-patches/compile.bat | 2 +- 6 files changed, 160 insertions(+), 37 deletions(-) create mode 100644 docs/images/usermode-use-debug-layer-1.jpg create mode 100644 docs/images/usermode-use-debug-layer-2.jpg create mode 100644 docs/images/usermode-use-debug-layer-3.jpg diff --git a/README_OpenHarmony.md b/README_OpenHarmony.md index c7763a982..44d0ba694 100644 --- a/README_OpenHarmony.md +++ b/README_OpenHarmony.md @@ -2,68 +2,188 @@ 本仓库包含开源软件Vulkan-ValidationLayers,为OpenHarmony提供了Vulkan验证层,Vulkan验证层可以在应用程序开发期间为开发者提供一些错误检查,帮助开发者正确使用Vulkan API。Vulkan-ValidationLayers的功能请参考[Vulkan-ValidationLayers](docs/khronos_validation_layer.md) -## Vulkan-ValidationLayers的实现方式 +## Vulkan-ValidationLayers在系统中的位置 Vulkan-ValidationLayers被实现为一个Vulkan Layer,由Vulkan-Loader加载并使用,Vulkan-Loader的功能请参考[Vulkan-Loader](https://gitee.com/openharmony/third_party_vulkan-loader/blob/master/README_OpenHarmony.md)。 ![vulkan-validationlayers_architecture_in_OH](docs/images/vulkan-validationlayers_architecture_in_OH.png) -## Vulkan-Loader加载验证层的方式 +## Vulkan-ValidationLayers的使用方式 -### 系统侧 -Vulkan-ValidationLayers在系统目录下会提供一个json配置文件`VkLayer_khronos_validation.json`和一个so文件`libVkLayer_khronos_validation.so`。 +本项目提供一个json配置文件`VkLayer_khronos_validation.json`和一个动态连接库二进制文件`libVkLayer_khronos_validation.so`。 [Vulkan-Loader](https://gitee.com/openharmony/third_party_vulkan-loader/blob/master/README_OpenHarmony.md)会扫描指定目录下的json配置文件,解析出so的位置并加载对应的so文件。 ![vulkan-validationlayers_load_way_in_OH](docs/images/vulkan-validationlayers_load_way_in_OH.png) -### 应用侧 +### 系统应用 + +系统应用采用隐式层(implicity layer)默认加载的方式 + +``` + hdc target mount #root模式下,开启权限 + hdc shell mkdir /system/etc/vulkan/implicity.d/ #为隐式层创建文件夹 + hdc file push VkLayer_khronos_validation.json /system/etc/vulkan/implicity.d/ #推送json文件到隐式层下 + hdc file push libVkLayer_khronos_validation.so /system/lib{64} + hdc shell reboot #重启设备 +``` +### 三方应用 + `在调试过程中开启ValidationLayers, 正式版本请不要开启。` -开启ValidationLayers的示例代码如下 +#### 隐式层方式 + +##### 1. json文件中指定so的位置 + +将[VkLayer_khronos_validation.json](scripts/ohos-patches/VkLayer_khronos_validation.json)中的`library_path`修改为`/data/storage/el1/bundle/lib/arm64/libVkLayer_khronos_validation.so` + +![usermode-use-debug-layer-2.jpg](docs/images/usermode-use-debug-layer-2.jpg) + + + +##### 2. 将json文件打包到hap中 + +![usermode-use-debug-layer-1.jpg](docs/images/usermode-use-debug-layer-1.jpg) + +工程中路径:{your_project}\entry\src\main\resources\rawfile\VkLayer_khronos_validation.json + +hdc开发视角下json文件的路径:/data/app/el2/100/base/{your_pakage_name}/file/VkLayer_khronos_validation.json + +[应用视角](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/file-management/send-file-to-app-sandbox.md#%E5%88%87%E6%8D%A2%E5%BA%94%E7%94%A8%E6%B2%99%E7%AE%B1%E8%A7%86%E8%A7%92)下json文件的路径:/data/storage/el2/base/haps/entry/files/VkLayer_khronos_validation.json +##### 3. 将so文件打包到hap中 + +![usermode-use-debug-layer-3.jpg](docs/images/usermode-use-debug-layer-3.jpg) + +工程中路径:{your_project}\entry\libs\arm64-v8a\libVkLayer_khronos_validation.so + +hdc开发视角下so文件的路径:/data/app/el1/bundle/public/{your_pakage_name}/libs/arm64/libVkLayer_khronos_validation.so + +[应用视角](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/file-management/send-file-to-app-sandbox.md#%E5%88%87%E6%8D%A2%E5%BA%94%E7%94%A8%E6%B2%99%E7%AE%B1%E8%A7%86%E8%A7%92)下json文件的路径:/data/storage/el1/bundle/libs/arm64/libVkLayer_khronos_validation.so + +应用视角下的so的路径与json文件中描述的路径一致 + +##### 4. 运行前设置环境变量 + +开启layer: 需要`同时`设置两个参数 + +``` + hdc shell param set debug.graphic.debug_layer VkLayer_khronos_validation #与json文件的名字一致 + hdc shell param set debug.graphic.debug_hap {your_pakage_name} #包名 ``` - // Check if this layer is available at instance level - const char* validationLayerName = "VK_LAYER_KHRONOS_validation"; - uint32_t instanceLayerCount; - vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr); - std::vector instanceLayerProperties(instanceLayerCount); - vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayerProperties.data()); - bool validationLayerPresent = false; - for (VkLayerProperties layer : instanceLayerProperties) { - if (strcmp(layer.layerName, validationLayerName) == 0) { - validationLayerPresent = true; - break; - } - } - if (validationLayerPresent) { - instanceCreateInfo.ppEnabledLayerNames = &validationLayerName; - instanceCreateInfo.enabledLayerCount = 1; - } else { - std::cerr << "Validation layer VK_LAYER_KHRONOS_validation not present, validation is disabled"; - } - - VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance); + +关闭layer: 将两个变量设置成空字符 + ``` + hdc shell param set debug.graphic.debug_layer '' + hdc shell param set debug.graphic.debug_hap '' +``` + + ## 构建指导 -适配OpenHarmony平台的编译脚本请见:[build-openharmony/BUILD.gn](build-openharmony/BUILD.gn) +适配OpenHarmony平台的编译脚本请参考:[compile.bat](scripts/ohos-patches/compile.bat) -由于graphic_2d模块的编译脚本中包含了Vulkan-ValidationLayers(详见:[bundle.json](https://gitee.com/openharmony/graphic_graphic_2d/blob/master/bundle.json)),所以编译graphic_2d模块可以将Vulkan-ValidationLayers同时编译出来,以rk3568平台为例,编译命令: +### 环境要求 -```shell -./build.sh --product-name rk3568 --ccache --build-target graphic_2d +- Windows 10+ +- Python 3.11+ +- OpenHarmony SDK + +### 编译步骤 + +##### 1. 下载源码到`VVL_DIR` + +[third_party_vulkan-validationlayers](https://gitee.com/openharmony-sig/third_party_vulkan-validationlayers) + +##### 2. 下载OpenHarmony SDK到`OHOS_SDK` + +可使用DevEco Studio NEXT Developer [下载](https://developer.huawei.com/consumer/cn/download/ ) + +##### 3. 配置cmd环境变量 + +e.g.: +``` + set OHOS_SDK=C:/Users/Administrator/AppData/Local/OpenHarmony/Sdk/12/native + set VVL_DIR=E:/WorkSpace/Vulkan/VVL/third_party_vulkan-validationlayers + set BUILD_THREADS=8 + set buildDir=%VVL_DIR%/build-ohos/intermediate + set libDir=%VVL_DIR%/build-ohos/libs + set PATH=%OHOS_SDK%/build-tools/cmake/bin;%PATH% ``` -也可以单独编译Vulkan-ValidationLayers: +##### 4. 下载依赖仓并打补丁 -```shell -./build.sh --product-name rk3568 --ccache --build-target VkLayer_khronos_validation +使用下述命令下载依赖仓 + +``` + cd /d %VVL_DIR% + + cmake -S . ^ + -B %buildDir% ^ + -G Ninja ^ + -D OHOS_STL=c++_static ^ + -D CMAKE_INSTALL_LIBDIR=%libDir% ^ + -D CMAKE_TOOLCHAIN_FILE=%OHOS_SDK%/build/cmake/ohos.toolchain.cmake ^ + -D CMAKE_BUILD_TYPE=Release ^ + -D VVL_CODEGEN=OFF ^ + -D UPDATE_DEPS=ON ^ + -D UPDATE_DEPS_DIR=%buildDir% ``` -编译完成后会在`out/rk3568/graphic/graphic_2d`目录下生成`libVkLayer_khronos_validation.so` +将[patches](scripts/ohos-patches)逐一应用到对应的依赖仓中 + +e.g.: +``` + cd build-ohos\intermediate\Vulkan-Headers + git apply Vulkan-Headers.patch +``` + + + +##### 5. 编译得到so文件 + +so生成位置:build-ohos\libs + +``` + cmake ^ + -S . ^ + -B %buildDir% ^ + -G Ninja ^ + -D OHOS_STL=c++_static ^ + -D CMAKE_INSTALL_LIBDIR=%libDir% ^ + -D CMAKE_TOOLCHAIN_FILE=%OHOS_SDK%/build/cmake/ohos.toolchain.cmake ^ + -D CMAKE_BUILD_TYPE=Release ^ + -D VVL_CODEGEN=OFF ^ + -D UPDATE_DEPS=ON ^ + -D UPDATE_DEPS_DIR=%buildDir% + + + cmake ^ + --build %buildDir% ^ + --target vvl_codegen + + + cmake ^ + --build %buildDir% ^ + --parallel %BUILD_THREADS% + + + if not exist "%libDir%" ( + mkdir "%libDir%" + ) + + cd /d %OHOS_SDK%/llvm/bin + + llvm-strip ^ + -d ^ + -s ^ + -o "%libDir%/libVkLayer_khronos_validation.so" ^ + "%buildDir%/layers/libVkLayer_khronos_validation.so" + +``` ## License diff --git a/docs/images/usermode-use-debug-layer-1.jpg b/docs/images/usermode-use-debug-layer-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e1cd4c9c3ddcd7412157f8e8e3f03fe9df6a0f4 GIT binary patch literal 14970 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 EH{26V&;S4c literal 0 HcmV?d00001 diff --git a/docs/images/usermode-use-debug-layer-3.jpg b/docs/images/usermode-use-debug-layer-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..28463cc43effc99e805bbd1fab8d95f07c4f7707 GIT binary patch literal 11576 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 CTUwj| literal 0 HcmV?d00001 diff --git a/scripts/ohos-patches/VkLayer_khronos_validation.json b/scripts/ohos-patches/VkLayer_khronos_validation.json index 4b0c58bf5..6f8ff1a42 100644 --- a/scripts/ohos-patches/VkLayer_khronos_validation.json +++ b/scripts/ohos-patches/VkLayer_khronos_validation.json @@ -3,10 +3,13 @@ "layer": { "name": "VK_LAYER_KHRONOS_validation", "type": "GLOBAL", - "library_path": "libVkLayer_khronos_validation.so", + "library_path": "/data/storage/el1/bundle/lib/arm64/libVkLayer_khronos_validation.so", "api_version": "1.3.275", "implementation_version": "1", "description": "Khronos Validation Layer", + "disable_environment": { + "DISBALE_OHOS_VALIDATION_LAYER": "1" + }, "introduction": "The main, comprehensive Khronos validation layer.\n\nVulkan is an Explicit API, enabling direct control over how GPUs actually work. By design, minimal error checking is done inside a Vulkan driver. Applications have full control and responsibility for correct operation. Any errors in how Vulkan is used can result in a crash. \n\nThe Khronos Valiation Layer can be enabled to assist development by enabling developers to verify their applications correctly use the Vulkan API.", "platforms": [ "WINDOWS", diff --git a/scripts/ohos-patches/compile.bat b/scripts/ohos-patches/compile.bat index 580afdf36..00c1e7373 100644 --- a/scripts/ohos-patches/compile.bat +++ b/scripts/ohos-patches/compile.bat @@ -27,7 +27,7 @@ cmake ^ -D CMAKE_TOOLCHAIN_FILE=%OHOS_SDK%/build/cmake/ohos.toolchain.cmake ^ -D CMAKE_BUILD_TYPE=Release ^ -D VVL_CODEGEN=OFF ^ - -D UPDATE_DEPS=OFF ^ + -D UPDATE_DEPS=ON ^ -D UPDATE_DEPS_DIR=%buildDir% REM Codegen boilerplate code from Vulkan registry (vk.xml from Vulkan-Headers)... -- Gitee From 888421886f146d0aa83477fe89d5a6b9a3f80bf2 Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Fri, 23 Aug 2024 16:31:27 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=89=88=E6=9D=83=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: andrew0229 --- layers/error_message/ohos_log.h | 18 +++++++++++++++++- scripts/ohos-patches/compile.bat | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/layers/error_message/ohos_log.h b/layers/error_message/ohos_log.h index c350788b2..517046674 100644 --- a/layers/error_message/ohos_log.h +++ b/layers/error_message/ohos_log.h @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #pragma once #include #include @@ -10,4 +26,4 @@ #define VVL_LOGE(...) \ do { \ OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ - } while (0) \ No newline at end of file + } while (0) diff --git a/scripts/ohos-patches/compile.bat b/scripts/ohos-patches/compile.bat index 00c1e7373..4dd3082b9 100644 --- a/scripts/ohos-patches/compile.bat +++ b/scripts/ohos-patches/compile.bat @@ -1,3 +1,17 @@ +REM Copyright (c) 2024 Huawei Device Co., Ltd. +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + + @echo off cls -- Gitee From d398aeafa667ff2aadb2bf9364bccd68973b4dda Mon Sep 17 00:00:00 2001 From: andrew0229 Date: Fri, 23 Aug 2024 16:52:55 +0800 Subject: [PATCH 14/14] update oat Signed-off-by: andrew0229 --- OAT.xml | 1 + layers/error_message/ohos_log.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/OAT.xml b/OAT.xml index a422f0db7..3e34271f6 100644 --- a/OAT.xml +++ b/OAT.xml @@ -23,6 +23,7 @@ + diff --git a/layers/error_message/ohos_log.h b/layers/error_message/ohos_log.h index 517046674..0a5cad487 100644 --- a/layers/error_message/ohos_log.h +++ b/layers/error_message/ohos_log.h @@ -13,8 +13,9 @@ * limitations under the License. */ +#ifndef VVL_HILOG_H +#define VVL_HILOG_H -#pragma once #include #include @@ -27,3 +28,5 @@ do { \ OH_LOG_ERROR(LOG_APP, __VA_ARGS__); \ } while (0) + +#endif // VVL_HILOG_H -- Gitee