From 1bc814710e71b17c1b78381fbc36a3df94264289 Mon Sep 17 00:00:00 2001 From: qiaojbao Date: Mon, 13 May 2024 16:41:53 +0800 Subject: [PATCH] Remove the cache_creator since amdvlk removed pre-navi10. --- .github/CODEOWNERS | 7 +- .../check-formatting-cache-creator.yml | 38 -- .github/workflows/check-xgl-docker.yml | 2 +- CMakeLists.txt | 8 - cmake/XglOptions.cmake | 2 - cmake/XglOverrides.cmake | 3 - .../docker => docker}/check_xgl.Dockerfile | 8 +- tools/cache_creator/.clang-format | 13 - tools/cache_creator/CMakeLists.txt | 110 ----- tools/cache_creator/cache_creator.cpp | 396 ------------------ tools/cache_creator/cache_creator.h | 114 ----- tools/cache_creator/cache_creator_main.cpp | 150 ------- tools/cache_creator/cache_info.cpp | 271 ------------ tools/cache_creator/cache_info.h | 116 ----- tools/cache_creator/cache_info_main.cpp | 110 ----- .../test/BasicCacheCreation.spvasm | 213 ---------- tools/cache_creator/test/CMakeLists.txt | 53 --- .../test/NonRelocatableShader.pipe | 43 -- .../test/RequiredCacheCreatorArguments.spvasm | 28 -- .../cache_creator/test/RunLitCommands.spvasm | 44 -- tools/cache_creator/test/lit.cfg.py | 60 --- tools/cache_creator/test/lit.site.cfg.py.in | 31 -- tools/cache_creator/unittests/CMakeLists.txt | 80 ---- .../unittests/cache_creator_tests.cpp | 175 -------- .../unittests/cache_info_tests.cpp | 251 ----------- tools/cache_creator/unittests/lit.cfg.py | 60 --- .../unittests/lit.site.cfg.py.in | 22 - 27 files changed, 4 insertions(+), 2404 deletions(-) delete mode 100644 .github/workflows/check-formatting-cache-creator.yml rename {tools/cache_creator/docker => docker}/check_xgl.Dockerfile (83%) delete mode 100644 tools/cache_creator/.clang-format delete mode 100644 tools/cache_creator/CMakeLists.txt delete mode 100644 tools/cache_creator/cache_creator.cpp delete mode 100644 tools/cache_creator/cache_creator.h delete mode 100644 tools/cache_creator/cache_creator_main.cpp delete mode 100644 tools/cache_creator/cache_info.cpp delete mode 100644 tools/cache_creator/cache_info.h delete mode 100644 tools/cache_creator/cache_info_main.cpp delete mode 100644 tools/cache_creator/test/BasicCacheCreation.spvasm delete mode 100644 tools/cache_creator/test/CMakeLists.txt delete mode 100644 tools/cache_creator/test/NonRelocatableShader.pipe delete mode 100644 tools/cache_creator/test/RequiredCacheCreatorArguments.spvasm delete mode 100644 tools/cache_creator/test/RunLitCommands.spvasm delete mode 100644 tools/cache_creator/test/lit.cfg.py delete mode 100644 tools/cache_creator/test/lit.site.cfg.py.in delete mode 100644 tools/cache_creator/unittests/CMakeLists.txt delete mode 100644 tools/cache_creator/unittests/cache_creator_tests.cpp delete mode 100644 tools/cache_creator/unittests/cache_info_tests.cpp delete mode 100644 tools/cache_creator/unittests/lit.cfg.py delete mode 100644 tools/cache_creator/unittests/lit.site.cfg.py.in diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index db21eb30..92fe6998 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,2 @@ # Global owners -* @WenqingLiAMD -# Order is important; the last matching pattern takes the most -# precedence. When someone opens a pull request that only -# modifies files under icd, only @JaxLinAMD and not the global -# owner(s) will be requested for a review. -/icd/ @JonCampbell407 +* @GPUOpen-Drivers/xglapprovers \ No newline at end of file diff --git a/.github/workflows/check-formatting-cache-creator.yml b/.github/workflows/check-formatting-cache-creator.yml deleted file mode 100644 index 2391feff..00000000 --- a/.github/workflows/check-formatting-cache-creator.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Cache Creator code formatting - -on: - pull_request: - -jobs: - clang-format-check: - name: clang-format - runs-on: "ubuntu-20.04" - steps: - - name: Setup environment - run: | - sudo apt-get install -yqq clang-format-11 - - name: Checkout XGL - run: | - git clone https://github.com/${GITHUB_REPOSITORY}.git . - git fetch origin +${GITHUB_SHA}:${GITHUB_REF} --update-head-ok - git checkout ${GITHUB_SHA} - - name: Run clang-format - run: | - git diff ${{ github.base_ref }} -U0 --no-color -- 'tools/cache_creator/**/*.cpp' 'tools/cache_creator/**/*.h' \ - | clang-format-diff-11 -p1 >not-formatted.diff 2>&1 - - name: Check formatting - run: | - if ! grep -q '[^[:space:]]' not-formatted.diff ; then - echo "Code formatted. Success." - else - echo "Code not formatted." - echo "Please run clang-format-diff on your changes and push again:" - echo " git diff ${{ github.base_ref }} -U0 --no-color | clang-format-diff -p1 -i" - echo "" - echo "Tip: you can disable clang-format checks: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#disabling-formatting-on-a-piece-of-code" - echo "" - echo "Diff:" - cat not-formatted.diff - echo "" - exit 3 - fi diff --git a/.github/workflows/check-xgl-docker.yml b/.github/workflows/check-xgl-docker.yml index 74e67fa0..6b21844a 100644 --- a/.github/workflows/check-xgl-docker.yml +++ b/.github/workflows/check-xgl-docker.yml @@ -34,7 +34,7 @@ jobs: - name: Fetch the latest prebuilt AMDVLK run: docker pull "amdvlkadmin/$IMAGE_TAG" - name: Build and Test with Docker - run: docker build . --file tools/cache_creator/docker/check_xgl.Dockerfile + run: docker build . --file docker/check_xgl.Dockerfile --build-arg AMDVLK_IMAGE="amdvlkadmin/$IMAGE_TAG" --build-arg XGL_REPO_NAME="${GITHUB_REPOSITORY}" --build-arg XGL_REPO_REF="${GITHUB_REF}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c4841b2..adc8c7bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -307,14 +307,6 @@ add_subdirectory(icd) # VKGC compiler add_subdirectory(${XGL_VKGC_PATH} ${CMAKE_BINARY_DIR}/compiler) -# Cache-creator tool -if(XGL_BUILD_CACHE_CREATOR) - if(NOT ICD_BUILD_LLPC) - message(FATAL_ERROR "Cannot build cache-creator tools without LLPC") - endif() - add_subdirectory(${XGL_CACHE_CREATOR_PATH} ${CMAKE_BINARY_DIR}/tools) -endif() - ### Generate Packages ################################################################################################# if(UNIX) generateInstallTargets() diff --git a/cmake/XglOptions.cmake b/cmake/XglOptions.cmake index f89534a1..7fb621aa 100644 --- a/cmake/XglOptions.cmake +++ b/cmake/XglOptions.cmake @@ -67,8 +67,6 @@ macro(xgl_options) option(XGL_BUILD_TOOLS "Build tools?" OFF) - option(XGL_BUILD_CACHE_CREATOR "Build cache-creator tools?" OFF) - #if VKI_RAY_TRACING option(VKI_RAY_TRACING "Build vulkan with RAY_TRACING" ON) #endif diff --git a/cmake/XglOverrides.cmake b/cmake/XglOverrides.cmake index c80e77f7..d0b4a87f 100644 --- a/cmake/XglOverrides.cmake +++ b/cmake/XglOverrides.cmake @@ -29,9 +29,6 @@ macro(xgl_get_path) # icd path set(XGL_ICD_PATH ${PROJECT_SOURCE_DIR}/icd CACHE PATH "The path of xgl, it is read-only.") - # XGL cache creator tool - set(XGL_CACHE_CREATOR_PATH ${PROJECT_SOURCE_DIR}/tools/cache_creator CACHE PATH "Path to the cache creator tool") - # PAL path if(EXISTS ${PROJECT_SOURCE_DIR}/icd/imported/pal) set(XGL_PAL_PATH ${PROJECT_SOURCE_DIR}/icd/imported/pal CACHE PATH "Specify the path to the PAL project.") diff --git a/tools/cache_creator/docker/check_xgl.Dockerfile b/docker/check_xgl.Dockerfile similarity index 83% rename from tools/cache_creator/docker/check_xgl.Dockerfile rename to docker/check_xgl.Dockerfile index e73b3c59..0b9f66b3 100644 --- a/tools/cache_creator/docker/check_xgl.Dockerfile +++ b/docker/check_xgl.Dockerfile @@ -1,7 +1,7 @@ # # Dockerfile for public XGL CI with GitHub Actions. # Sample invocation: -# docker build . --file tools/cache_creator/docker/check_xgl.Dockerfile \ +# docker build . --file docker/check_xgl.Dockerfile \ # --build-arg AMDVLK_IMAGE=gcr.io/stadia-open-source/amdvlk:nightly \ # --build-arg XGL_REPO_NAME=GPUOpen-Drivers/xgl \ # --build-arg XGL_REPO_REF= \ @@ -38,8 +38,4 @@ WORKDIR /vulkandriver/builds/ci-build RUN source /vulkandriver/env.sh \ && cmake . \ && cmake --build . \ - && cmake --build . --target amdvlk64.so cache-creator - -# Run cache-creator tests. -RUN source /vulkandriver/env.sh \ - && cmake --build . --target check-cache-creator check-cache-creator-units + && cmake --build . --target amdvlk64.so diff --git a/tools/cache_creator/.clang-format b/tools/cache_creator/.clang-format deleted file mode 100644 index 096f8939..00000000 --- a/tools/cache_creator/.clang-format +++ /dev/null @@ -1,13 +0,0 @@ -BasedOnStyle: LLVM -ColumnLimit: 120 -AllowShortFunctionsOnASingleLine: InlineOnly -IncludeBlocks: Merge -IncludeCategories: - - Regex: '^"include/' - Priority: 2 - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 3 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 4 - - Regex: '.*' - Priority: 1 diff --git a/tools/cache_creator/CMakeLists.txt b/tools/cache_creator/CMakeLists.txt deleted file mode 100644 index 7ee164c3..00000000 --- a/tools/cache_creator/CMakeLists.txt +++ /dev/null @@ -1,110 +0,0 @@ -## - ####################################################################################################################### - # - # Copyright (c) 2021 Google LLC. All Rights Reserved. - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - # - ####################################################################################################################### - -# Cache creator is a tool for building pipeline binary cache files out of shader/pipeline elf files. -# These input elf files can be compiled offline and packaged as cache file on a host machine without a GPU. -# The "XGL_BUILD_CACHE_CREATOR" CMake option enables the cache creator targets. - -# This interface library is intended be used by cache-creator, cache-info, and by the related unit tests. -add_library(cache_creator_lib INTERFACE) - -list(APPEND CMAKE_MODULE_PATH "${XGL_LLVM_BUILD_PATH}/${CMAKE_CFG_INTDIR}/lib/cmake/llvm") -include(LLVMConfig) - -# Find all the LLVM libraries necessary to use the LLVM components that we use. -# See https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project. -llvm_map_components_to_libnames(llvm_libs Object Support) -target_link_libraries(cache_creator_lib INTERFACE pal xgl_cache_support ${llvm_libs} llpc_version) - -target_include_directories(cache_creator_lib INTERFACE - ${XGL_LLVM_SRC_PATH}/include - ${LLVM_INCLUDE_DIRS} # This is necessary to discover the auto-generated llvm-config.h header. - ${XGL_VKGC_PATH}/include -) - -get_target_property(XGL_COMPILE_OPTIONS xgl COMPILE_OPTIONS) -get_target_property(XGL_COMPILE_DEFINITIONS xgl COMPILE_DEFINITIONS) - -# Compile with the same flags and definitions as the ICD and LLVM. -target_compile_definitions(cache_creator_lib INTERFACE - ${LLVM_DEFINITIONS} - ${XGL_COMPILE_DEFINITIONS} -) -target_compile_options(cache_creator_lib INTERFACE ${XGL_COMPILE_OPTIONS}) -if(NOT LLVM_ENABLE_EH) - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(cache_creator_lib INTERFACE $<$: -fno-exceptions>) - endif() -endif() -if(NOT LLVM_ENABLE_RTTI) - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(cache_creator_lib INTERFACE $<$: -fno-rtti>) - endif() -endif() - -if(CMAKE_BUILD_TYPE_RELEASE AND XGL_ENABLE_LTO) -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - #target_link_options(xgl PRIVATE -Wno-stringop-overflow) - execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if (GCC_VERSION VERSION_GREATER 5.3 OR GCC_VERSION VERSION_EQUAL 5.3) - target_link_libraries(cache_creator_lib INTERFACE -flto=4 -fuse-linker-plugin -Wno-odr) - message(WARNING "LTO enabled for Linking") - endif() -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - # LTO enabled for final Linking (clang) - target_link_libraries(cache_creator_lib INTERFACE -flto=thin) -endif() -endif() - -target_sources(cache_creator_lib INTERFACE cache_creator.cpp cache_info.cpp) - -# This executable takes AMDGPU elf files as input and outputs a Vulkan cache file blob -# that can be later loaded by the ICD. -# The `cache-creator` binary follows the standard llvm-based tool naming convention. -# Note that running the cache-creator tool doesn't require a Vulkan device to be installed. -add_executable(cache-creator) -target_sources(cache-creator PRIVATE cache_creator_main.cpp) -llvm_map_components_to_libnames(llvm_libs - BinaryFormat -) -target_link_libraries(cache-creator PRIVATE cache_creator_lib ${llvm_libs}) - -# This executable analyzes pipeline binary cache files produced either by the ICD or by the cache-creator tool. -# We use the output in automated regression tests but it may also be useful in manual analysis/debugging. -# The `cache-info` binary follows the standard llvm-based tool naming convention. -# Note that running the cache-info tool doesn't require a Vulkan device to be installed. -add_executable(cache-info) -target_sources(cache-info PRIVATE cache_info_main.cpp) -target_link_libraries(cache-info PRIVATE cache_creator_lib ${llvm_libs}) - -# Build cache creator tools whenever we build XGL. -add_dependencies(xgl cache-creator cache-info) - -if(XGL_BUILD_TESTS) - message(STATUS "Building cache creator tests") - set(CACHE_CREATOR_TOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") - add_subdirectory(test "${CMAKE_CURRENT_BINARY_DIR}/test/cache-creator/lit") - add_subdirectory(unittests "${CMAKE_CURRENT_BINARY_DIR}/test/cache-creator/unittests") -endif() diff --git a/tools/cache_creator/cache_creator.cpp b/tools/cache_creator/cache_creator.cpp deleted file mode 100644 index 99b51f5b..00000000 --- a/tools/cache_creator/cache_creator.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2020-2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#include "cache_creator.h" -#include "palPlatformKey.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/BinaryFormat/MsgPackDocument.h" -#include "llvm/Object/ELFObjectFile.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/Regex.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include - -#if _POSIX_C_SOURCE >= 200112L -#include -#endif - -namespace cc { - -namespace { -void *VKAPI_PTR defaultAllocFunc(void *userData, size_t size, size_t alignment, VkSystemAllocationScope allocType) { - // On both POSIX and Windows, alignment is required to be a power of 2. - // See https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc, - // and https://linux.die.net/man/3/aligned_alloc. - const size_t requiredAlignment = llvm::PowerOf2Ceil(std::max(alignment, sizeof(void *))); -#if defined(_WIN32) - return _aligned_malloc(size, requiredAlignment); -#elif _POSIX_C_SOURCE >= 200112L - void *mem = nullptr; - if (posix_memalign(&mem, requiredAlignment, size) != 0) - return nullptr; - return mem; -#else -#error Platform not handled -#endif -} - -void *VKAPI_PTR defaultReallocFunc(void *userData, void *original, size_t size, size_t alignment, - VkSystemAllocationScope allocType) { - llvm_unreachable("Reallocation not supported"); // See https://github.com/GPUOpen-Drivers/xgl/issues/70. -} - -void VKAPI_PTR defaultFreeFunc(void *userData, void *mem) { -#if defined(_WIN32) - return _aligned_free(mem); -#elif _POSIX_C_SOURCE >= 200112L - free(mem); -#else -#error Platform not handled -#endif -} - -void VKAPI_PTR defaultAllocNotification(void *userData, size_t size, VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope) { - // No notification required. -} - -void VKAPI_PTR defaultFreeNotification(void *userData, size_t size, VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope) { - // No notification required. -} -} // namespace - -// ===================================================================================================================== -// Provides the default allocation callbacks, used by XGL code. -// -// @returns : Vulkan allocation callbacks -VkAllocationCallbacks &getDefaultAllocCallbacks() { - static VkAllocationCallbacks defaultCallbacks = { - nullptr, defaultAllocFunc, defaultReallocFunc, defaultFreeFunc, defaultAllocNotification, defaultFreeNotification, - }; - return defaultCallbacks; -} - -AllocCallbacksDeleter::AllocCallbacksDeleter(VkAllocationCallbacks &callbacks) : m_callbacks(&callbacks) { -} - -void AllocCallbacksDeleter::operator()(void *mem) { - m_callbacks->pfnFree(m_callbacks->pUserData, mem); -} - -static bool isValidHexUUIDStr(llvm::StringRef hexStr) { - // Sample valid UUID string: 12345678-abcd-ef00-ffff-0123456789ab, - // see: https://en.wikipedia.org/wiki/Universally_unique_identifier. - static const llvm::Regex uuidRegex("^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$"); - return hexStr.size() == UuidLength && uuidRegex.match(hexStr); -} - -// ===================================================================================================================== -// Serializes given UUID into a printable string. -// -// @param uuid : The input UUID in the binary format -// @returns : UUID string in the printable format -UuidString uuidToHexString(llvm::ArrayRef uuid) { - assert(uuid.size() == VK_UUID_SIZE); - - UuidString res; - llvm::raw_svector_ostream os(res); - for (size_t groupSize : {4, 2, 2, 2, 6}) { - os << llvm::format_bytes(uuid.take_front(groupSize), std::nullopt, - /* NumPerLine = */ 16, /* BytesPerLine = */ 6); - uuid = uuid.drop_front(groupSize); - if (!uuid.empty()) - os << '-'; - } - assert(isValidHexUUIDStr(res)); - return res; -} - -static uint8_t hexDigitToNum(char c) { - assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')); - return (c >= '0' && c <= '9') ? c - '0' : 10 + (c - 'a'); -} - -// ===================================================================================================================== -// Converts a UUID string into its binary representation. -// -// @param hexStr : The input hex string in the UUID format -// @param [out] outUuid : The output buffer where de-serialized UUID gets written to -// @returns : `true` on success, `false` when the passed `hexStr` is not valid -bool hexStringToUuid(llvm::StringRef hexStr, llvm::MutableArrayRef outUuid) { - assert(outUuid.size() == VK_UUID_SIZE); - if (!isValidHexUUIDStr(hexStr)) - return false; - - // Go over all hex digits and write out a nibble at a time. - // Updates `outUuid` so that the current byte is always at the front. - for (auto &&posAndHexDigit : llvm::enumerate(llvm::make_filter_range(hexStr, [](char c) { return c != '-'; }))) { - const uint8_t num = hexDigitToNum(posAndHexDigit.value()); - if (posAndHexDigit.index() % 2 == 0) { - outUuid.front() = num << 4; - } else { - outUuid.front() |= num; - outUuid = outUuid.drop_front(); - } - } - - return true; -} - -static llvm::Error createBadPalMetadataError() { - return llvm::createStringError(llvm::object::object_error::invalid_file_type, "Unexpected PAL metadata format"); -} - -static llvm::Expected getXglCacheInfoNode(llvm::msgpack::Document &document) { - llvm::msgpack::DocNode node = document.getRoot(); - if (!node.isMap()) - return createBadPalMetadataError(); - node = node.getMap(false)["amdpal.pipelines"]; - if (!node.isArray()) - return createBadPalMetadataError(); - node = node.getArray(false)[0]; - if (!node.isMap()) - return createBadPalMetadataError(); - node = node.getMap(false)[".xgl_cache_info"]; - if (!node.isMap()) - return createBadPalMetadataError(); - return node.getMap(false); -} - -static llvm::Expected extractCacheHash(llvm::msgpack::MapDocNode &cacheInfoNode) { - llvm::msgpack::DocNode node = cacheInfoNode[".128_bit_cache_hash"]; - if (!node.isArray()) - return createBadPalMetadataError(); - llvm::msgpack::ArrayDocNode hashNode = node.getArray(false); - if (hashNode[0].getKind() != llvm::msgpack::Type::UInt || hashNode[1].getKind() != llvm::msgpack::Type::UInt) - return createBadPalMetadataError(); - Util::MetroHash::Hash hash = {}; - hash.qwords[0] = hashNode[0].getUInt(); - hash.qwords[1] = hashNode[1].getUInt(); - return hash; -} - -static llvm::Expected extractLlpcVersion(llvm::msgpack::MapDocNode &cacheInfoNode) { - llvm::msgpack::DocNode node = cacheInfoNode[".llpc_version"]; - if (!node.isString()) - return createBadPalMetadataError(); - llvm::VersionTuple versionTuple; - if (versionTuple.tryParse(node.getString())) - return createBadPalMetadataError(); - if (!versionTuple.getMinor().has_value()) - return createBadPalMetadataError(); - return versionTuple; -} - -// ===================================================================================================================== -// Tries to extract cache hash and LLPC version from a PAL metadata note blob. -// -// @param noteBlob : The input metadata blob -// @returns : The cache info on success, or error on failure -llvm::Expected getCacheInfoFromMetadataBlob(llvm::StringRef noteBlob) { - llvm::msgpack::Document document; - if (!document.readFromBlob(noteBlob, false)) - return createBadPalMetadataError(); - - auto cacheInfoNodeOrErr = getXglCacheInfoNode(document); - if (auto err = cacheInfoNodeOrErr.takeError()) - return std::move(err); - llvm::msgpack::MapDocNode cacheInfoNode = cacheInfoNodeOrErr.get(); - - auto hashOrErr = extractCacheHash(cacheInfoNode); - if (auto err = hashOrErr.takeError()) - return std::move(err); - - auto llpcVersionOrErr = extractLlpcVersion(cacheInfoNode); - if (auto err = llpcVersionOrErr.takeError()) - return std::move(err); - - return ElfLlpcCacheInfo{*hashOrErr, *llpcVersionOrErr}; -} - -// ===================================================================================================================== -// Tries to extract cache hash and LLPC version from the elf file. -// -// @param elfBuffer : The input elf -// @returns : The hash found on success, or error on failure -llvm::Expected getElfLlpcCacheInfo(llvm::MemoryBufferRef elfBuffer) { - auto elfObjectOrErr = llvm::object::ELF64LEObjectFile::create(elfBuffer); - if (auto err = elfObjectOrErr.takeError()) - return std::move(err); - - using ElfFileTy = llvm::object::ELF64LEFile; - const ElfFileTy &elfFile = elfObjectOrErr->getELFFile(); - - auto sectionsOrErr = elfFile.sections(); - if (auto err = sectionsOrErr.takeError()) - return std::move(err); - - for (const auto §ionHeader : *sectionsOrErr) { - if (sectionHeader.sh_type != llvm::ELF::SHT_NOTE) - continue; - - auto sectionNameOrErr = elfFile.getSectionName(sectionHeader); - if (auto err = sectionNameOrErr.takeError()) { - llvm::consumeError(std::move(err)); - continue; - } - if (!sectionNameOrErr->startswith(".note")) - continue; - - llvm::Error notesError(llvm::Error::success()); - auto noteRange = elfFile.notes(sectionHeader, notesError); - if (notesError) - return std::move(notesError); - - for (const ElfFileTy::Elf_Note ¬e : noteRange) { - if (note.getType() == llvm::ELF::NT_AMDGPU_METADATA) -#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 460558 - // Old version of the code - return getCacheInfoFromMetadataBlob(note.getDescAsStringRef()); -#else - // New version of the code (also handles unknown version, which we treat as latest) - return getCacheInfoFromMetadataBlob(note.getDescAsStringRef(sectionHeader.sh_addralign)); -#endif - } - } - - return llvm::createStringError(llvm::object::object_error::invalid_file_type, - "Could not find shader/pipeline elf hash"); -} - -// ===================================================================================================================== -// Computed the total size necessary to serialize a portable PipelineBinaryCache file. -// -// @param inputelfSizes : Sizes of input elf files (in bytes) -// @returns : Total size required to create cache file (in bytes) -size_t RelocatableCacheCreator::CalculateAnticipatedCacheFileSize(llvm::ArrayRef inputElfSizes) { - const size_t totalFileContentsSize = std::accumulate(inputElfSizes.begin(), inputElfSizes.end(), 0); - const size_t numFiles = inputElfSizes.size(); - const size_t anticipatedBlobSize = - vk::PipelineBinaryCacheSerializer::CalculateAnticipatedCacheBlobSize(numFiles, totalFileContentsSize); - return vk::VkPipelineCacheHeaderDataSize + anticipatedBlobSize; -} - -// ===================================================================================================================== -// Initializes a RelocatableCacheCreator object. -// -// @param deviceId : The device identifier of the target GPU -// @param uuid : Pipeline cache UUID in the binary format -// @param fingerprint : Initial data used to initialize the platform key. This should include information about the -// target GPU and the driver/compiler stack used to construct the cache and later consume it. -// @param [in/out] outputBuffer : Memory buffer where the pipeline cache data will be written -// @returns : A RelocatableCacheCreator object on success, error when initialization failures -llvm::Expected RelocatableCacheCreator::Create(uint32_t deviceId, llvm::ArrayRef uuid, - llvm::ArrayRef fingerprint, - llvm::MutableArrayRef outputBuffer) { - VkAllocationCallbacks &callbacks = cc::getDefaultAllocCallbacks(); - - const Util::HashAlgorithm hashAlgo = Util::HashAlgorithm::Sha1; - const size_t keyMemSize = Util::GetPlatformKeySize(hashAlgo); - void *keyMem = callbacks.pfnAllocation(callbacks.pUserData, keyMemSize, 16, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - assert(keyMem); - - uint8_t *initialData = fingerprint.empty() ? nullptr : const_cast(fingerprint.data()); - Util::IPlatformKey *key = nullptr; - if (Util::CreatePlatformKey(hashAlgo, initialData, fingerprint.size(), keyMem, &key) != Util::Result::Success) - return llvm::createStringError(std::errc::state_not_recoverable, "Failed to create platform key"); - - assert(key); - std::unique_ptr managedKey(key, {callbacks}); - - size_t vkHeaderBytes = 0; - if (vk::WriteVkPipelineCacheHeaderData(outputBuffer.data(), outputBuffer.size(), cc::AMDVendorId, deviceId, - const_cast(uuid.data()), uuid.size(), - &vkHeaderBytes) != Util::Result::Success) - return llvm::createStringError(std::errc::state_not_recoverable, "Failed to write Vulkan Pipeline Cache header"); - assert(vkHeaderBytes == vk::VkPipelineCacheHeaderDataSize); - - llvm::MutableArrayRef privateCacheData = outputBuffer.drop_front(vkHeaderBytes); - auto serializer = std::make_unique(); - assert(serializer); - - if (serializer->Initialize(privateCacheData.size(), privateCacheData.data()) != Util::Result::Success) - return llvm::createStringError(std::errc::state_not_recoverable, - "Failed to initialize PipelineBinaryCacheSerializer"); - - return RelocatableCacheCreator(std::move(managedKey), std::move(serializer), outputBuffer, callbacks); -} - -// ===================================================================================================================== -// Adds a new cache entry with the provided elf file. -// -// @param elfBuffer : Buffer with a relocatable shader elf compiled with LLPC -// @returns : Error if it's not possible to process the elf or append it to the output buffer, or success -llvm::Error RelocatableCacheCreator::addElf(llvm::MemoryBufferRef elfBuffer) { - auto elfLlpcInfoOrErr = cc::getElfLlpcCacheInfo(elfBuffer); - if (auto err = elfLlpcInfoOrErr.takeError()) - return llvm::createFileError(elfBuffer.getBufferIdentifier(), std::move(err)); - - vk::BinaryCacheEntry entry = {}; - entry.dataSize = elfBuffer.getBufferSize(); - entry.hashId = elfLlpcInfoOrErr->cacheHash; - - llvm::VersionTuple llpcBuildVersion(BuildLlpcMajorVersion, BuildLlpcMinorVersion); - if (elfLlpcInfoOrErr->llpcVersion != llpcBuildVersion) { - return llvm::createFileError( - elfBuffer.getBufferIdentifier(), - llvm::createStringError( - std::errc::state_not_recoverable, "Elf LLPC version (%s) not compatible with the tool LLPC version (%s)", - elfLlpcInfoOrErr->llpcVersion.getAsString().c_str(), llpcBuildVersion.getAsString().c_str())); - } - - if (m_serializer->AddPipelineBinary(&entry, elfBuffer.getBufferStart()) != Util::Result::Success) - return llvm::createFileError( - elfBuffer.getBufferIdentifier(), - llvm::createStringError(std::errc::state_not_recoverable, "Failed to add cache entry")); - - return llvm::Error::success(); -} - -// ===================================================================================================================== -// Finalizes the cache file and writes remaining validation data. -// -// @param [out] outTotalNumEntries : (Optional) Variable to store the total number of cache entries added -// @param [out] outTotalSize: (Optional) Variable to store the final cache blob size -// @returns : Error if it's not possible to finish cache serialization, or success. -llvm::Error RelocatableCacheCreator::finalize(size_t *outTotalNumEntries, size_t *outTotalSize) { - size_t actualNumEntries = 0; - size_t actualCacheSize = 0; - if (m_serializer->Finalize(m_callbacks, m_platformKey.get(), &actualNumEntries, &actualCacheSize) != - Util::Result::Success) - return llvm::createStringError(std::errc::state_not_recoverable, "Failed to serialize cache"); - - if (outTotalNumEntries) - *outTotalNumEntries = actualNumEntries; - if (outTotalSize) - *outTotalSize = actualCacheSize + vk::VkPipelineCacheHeaderDataSize; - - return llvm::Error::success(); -} - -} // namespace cc diff --git a/tools/cache_creator/cache_creator.h b/tools/cache_creator/cache_creator.h deleted file mode 100644 index e6da0d67..00000000 --- a/tools/cache_creator/cache_creator.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2020-2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#pragma once - -#include "util/palMetroHash.h" -#include "vkgcDefs.h" -#include "include/binary_cache_serialization.h" - -// These Xlib defines conflict with LLVM. -#undef Bool -#undef Status - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/MemoryBufferRef.h" -#include "llvm/Support/VersionTuple.h" - -namespace cc { - -constexpr uint32_t AMDVendorId = 0x1002; // See https://pci-ids.ucw.cz/read/PC/1002. - -// The LLPC version number in the current source tree. -constexpr uint32_t BuildLlpcMajorVersion = LLPC_INTERFACE_MAJOR_VERSION; -constexpr uint32_t BuildLlpcMinorVersion = LLPC_INTERFACE_MINOR_VERSION; - -VkAllocationCallbacks &getDefaultAllocCallbacks(); - -// Deleter class that enables PAL/XGL types allocated with VkAllocationCallbacks to be used with std::unique_ptr. -// This deleter calles the free function from the given callback, instead of using a plain `delete` operator. -struct AllocCallbacksDeleter { - AllocCallbacksDeleter(VkAllocationCallbacks &callbacks); - void operator()(void *mem); - -private: - VkAllocationCallbacks *m_callbacks; -}; - -constexpr size_t UuidLength = 36; -using UuidString = llvm::SmallString; - -// Serializes given UUID into a printable string. -UuidString uuidToHexString(llvm::ArrayRef uuid); - -// Converts a UUID string into its binary representation. -bool hexStringToUuid(llvm::StringRef hexStr, llvm::MutableArrayRef outUuid); - -struct ElfLlpcCacheInfo { - Util::MetroHash::Hash cacheHash; - llvm::VersionTuple llpcVersion; // Both major and minor version must be provided -}; - -// Tries to extract cache hash and LLPC version from a PAL metadata note blob. -llvm::Expected getCacheInfoFromMetadataBlob(llvm::StringRef noteBlob); - -// Tries to extract cache hash and LLPC version from the elf file. -llvm::Expected getElfLlpcCacheInfo(llvm::MemoryBufferRef elfBuffer); - -// Creates portable PipelineBinaryCache files from relocatable LLPC elf files. -// This class is moveable but not copyable. -class RelocatableCacheCreator { -public: - static size_t CalculateAnticipatedCacheFileSize(llvm::ArrayRef inputElfSizes); - static llvm::Expected Create(uint32_t deviceId, llvm::ArrayRef uuid, - llvm::ArrayRef fingerprint, - llvm::MutableArrayRef outputBuffer); - - RelocatableCacheCreator() = delete; - RelocatableCacheCreator(const RelocatableCacheCreator &) = delete; - RelocatableCacheCreator &operator=(const RelocatableCacheCreator &) = delete; - - RelocatableCacheCreator(RelocatableCacheCreator &&) = default; - RelocatableCacheCreator &operator=(RelocatableCacheCreator &&) = default; - - llvm::Error addElf(llvm::MemoryBufferRef elfBuffer); - llvm::Error finalize(size_t *outTotalNumEntries, size_t *outTotalSize); - -private: - RelocatableCacheCreator(std::unique_ptr platformKey, - std::unique_ptr serializer, - llvm::MutableArrayRef outputBuffer, VkAllocationCallbacks &callbacks) - : m_platformKey(std::move(platformKey)), m_serializer(std::move(serializer)), m_outputBuffer(outputBuffer), - m_callbacks(&callbacks) {} - - std::unique_ptr m_platformKey; - std::unique_ptr m_serializer; - llvm::MutableArrayRef m_outputBuffer; - VkAllocationCallbacks *m_callbacks; -}; - -} // namespace cc diff --git a/tools/cache_creator/cache_creator_main.cpp b/tools/cache_creator/cache_creator_main.cpp deleted file mode 100644 index aac7defe..00000000 --- a/tools/cache_creator/cache_creator_main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2020-2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#include "cache_creator.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileOutputBuffer.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include - -namespace { -llvm::cl::OptionCategory CacheCreatorCat("Cache Creator Options"); - -llvm::cl::list InFiles(llvm::cl::Positional, llvm::cl::OneOrMore, llvm::cl::ValueRequired, - llvm::cl::cat(CacheCreatorCat), llvm::cl::desc("")); -llvm::cl::opt OutFileName("o", llvm::cl::desc("Output cache file"), llvm::cl::cat(CacheCreatorCat), - llvm::cl::value_desc("filename.bin"), llvm::cl::Required); -llvm::cl::opt DeviceId("device-id", llvm::cl::desc("Devide ID. This must match the target GPU."), - llvm::cl::value_desc("number"), llvm::cl::cat(CacheCreatorCat), llvm::cl::Required); - -// This UUID is generated in vk_physical_device.cpp::Initialize. -llvm::cl::opt - UuidStr("uuid", - llvm::cl::desc( - "Pipeline cache UUID for the specific driver and machine, e.g., 00000000-12345-6789-abcd-ef0000000042"), - llvm::cl::value_desc("hex string"), llvm::cl::cat(CacheCreatorCat), llvm::cl::Required); - -llvm::cl::opt Verbose("verbose", llvm::cl::desc("Enable verbose output"), llvm::cl::init(false), - llvm::cl::cat(CacheCreatorCat)); - -// ===================================================================================================================== -// Returns an ostream for printing output info messages. -// -// @returns : Output stream writing to STDOUT if `--verbose` is enabled, or a stream that doesn't print anything if not -llvm::raw_ostream &infos() { - if (Verbose) - return llvm::outs(); - - static llvm::raw_null_ostream blackHole; - return blackHole; -} -} // namespace - -namespace fs = llvm::sys::fs; - -static llvm::Error getFileSizes(llvm::ArrayRef filenames, llvm::MutableArrayRef outFileSizes) { - assert(filenames.size() == outFileSizes.size()); - for (auto &&nameSizePair : llvm::zip(filenames, outFileSizes)) { - const std::string &filename = std::get<0>(nameSizePair); - if (std::error_code err = fs::file_size(filename, std::get<1>(nameSizePair))) - return llvm::createFileError(filename, llvm::createStringError(err, "Failed to read file size")); - } - return llvm::Error::success(); -} - -int main(int argc, char **argv) { - llvm::cl::ParseCommandLineOptions(argc, argv); - - llvm::outs() << "NOTE: cache-creator is still under development. Things may not work as expected.\n\n"; - - std::array uuid = {}; - if (!cc::hexStringToUuid(UuidStr, uuid)) { - llvm::errs() << "Failed to parse pipeline cache UUID (--uuid). See `cache-creator --help` for usage details.\n"; - return 2; - } - - const size_t numFiles = InFiles.size(); - llvm::SmallVector fileSizes(numFiles); - if (auto err = getFileSizes(InFiles, fileSizes)) { - llvm::errs() << err << "\n"; - llvm::consumeError(std::move(err)); - return 3; - } - - const size_t cacheBlobSize = cc::RelocatableCacheCreator::CalculateAnticipatedCacheFileSize(fileSizes); - infos() << "Num inputs: " << numFiles << ", anticipated cache size: " << cacheBlobSize << "\n"; - - auto outFileBufferOrErr = llvm::FileOutputBuffer::create(OutFileName, cacheBlobSize); - if (auto err = outFileBufferOrErr.takeError()) { - llvm::errs() << "Failed to create the output file " << OutFileName << ". Error:\t" << err << "\n"; - llvm::consumeError(std::move(err)); - return 4; - } - - // TODO(kuhar): Initialize the platform key properly by providing the `fingerprint` parameter instead of an empty - // array. This is so that the cache can pass validation and be consumed by the ICD. Note that this also requires - // ICD-side changes. - auto cacheCreatorOrErr = cc::RelocatableCacheCreator::Create( - DeviceId, uuid, {}, - llvm::MutableArrayRef((*outFileBufferOrErr)->getBufferStart(), (*outFileBufferOrErr)->getBufferSize())); - if (auto err = cacheCreatorOrErr.takeError()) { - llvm::errs() << "Error:\t" << err << "\n"; - llvm::consumeError(std::move(err)); - return 4; - } - cc::RelocatableCacheCreator &cacheCreator = *cacheCreatorOrErr; - - for (const std::string &filename : InFiles) { - llvm::ErrorOr> inputBufferOrErr = llvm::MemoryBuffer::getFile(filename); - if (std::error_code err = inputBufferOrErr.getError()) { - llvm::errs() << "Failed to read input file " << filename << ": " << err.message() << "\n"; - return 3; - } - infos() << "Read: " << filename << "\n"; - - if (auto err = cacheCreator.addElf(**inputBufferOrErr)) { - llvm::errs() << "Error:\t" << err << "\n"; - llvm::consumeError(std::move(err)); - return 4; - } - } - - size_t actualNumEntries = 0; - size_t actualCacheSize = 0; - if (auto err = cacheCreator.finalize(&actualNumEntries, &actualCacheSize)) { - llvm::errs() << "Error:\t" << err << "\n"; - llvm::consumeError(std::move(err)); - return 4; - } - infos() << "Num entries written: " << actualNumEntries << ", actual cache size: " << actualCacheSize << " B\n"; - - if ((*outFileBufferOrErr)->commit()) { - llvm::errs() << "Failed to commit the serialized cache to the output file\n"; - return 4; - } - llvm::outs() << "Cache successfully written to: " << (*outFileBufferOrErr)->getPath() << "\n"; - - return 0; -} diff --git a/tools/cache_creator/cache_info.cpp b/tools/cache_creator/cache_info.cpp deleted file mode 100644 index 2d56f9a8..00000000 --- a/tools/cache_creator/cache_info.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#include "cache_info.h" -#include "cache_creator.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/MD5.h" -#include -#include - -namespace { - -// ===================================================================================================================== -// Annotates the base error with the blob identifier. -// -// @param blob : Cache blob -// @param err : Base error -// @returns : Error annotated with the blob identifier -llvm::Error createBlobError(llvm::MemoryBufferRef blob, llvm::Error err) { - return llvm::createFileError(blob.getBufferIdentifier(), std::move(err)); -} - -// ===================================================================================================================== -// Creates a string error referencing the blob identifier. -// -// @param blob : Cache blob. -// @param format : Format specifier (printf-style) -// @param vals : Values for the format specifier -// @returns : Error annotated with the blob identifier -template -llvm::Error createBlobError(llvm::MemoryBufferRef blob, const char *format, const Ts &...vals) { - return createBlobError(blob, llvm::createStringError(std::errc::state_not_recoverable, format, vals...)); -} - -} // namespace - -namespace cc { - -// ===================================================================================================================== -// Creates a CacheBlobInfo object. -// -// @param cacheBlob : Pipeline Cache blob -// @returns : CacheBlobInfo object on success, error if the cacheBlob cannot be a valid PipelineBinaryCache blob -llvm::Expected CacheBlobInfo::create(llvm::MemoryBufferRef cacheBlob) { - constexpr size_t minCacheBlobSize = vk::VkPipelineCacheHeaderDataSize + sizeof(vk::PipelineBinaryCachePrivateHeader); - const size_t bufferSize = cacheBlob.getBufferSize(); - - if (bufferSize < minCacheBlobSize) { - return createBlobError(cacheBlob, "Input buffer too small to be a valid Pipeline Binary Cache blob: %zu B < %zu B", - bufferSize, minCacheBlobSize); - } - - assert(cacheBlob.getBufferStart()); - return CacheBlobInfo{cacheBlob}; -} - -// ===================================================================================================================== -// Reads the public Vulkan Pipeline Cache header. -// -// @returns : PublicVkHeaderInfo object on success, error if the cache blob does not have a valid public header -llvm::Expected CacheBlobInfo::readPublicVkHeaderInfo() const { - PublicVkHeaderInfo res = {}; - res.publicHeader = reinterpret_cast(m_cacheBlob.getBufferStart()); - - const uint32_t headerLength = res.publicHeader->headerLength; - if (headerLength < vk::VkPipelineCacheHeaderDataSize) { - return createBlobError(m_cacheBlob, - "Vulkan Pipeline Cache header length too small to be a valid header: %zu B < %zu B", - size_t(headerLength), vk::VkPipelineCacheHeaderDataSize); - } - if (headerLength >= m_cacheBlob.getBufferSize()) { - return createBlobError(m_cacheBlob, "Vulkan Pipeline Cache header length greater than blob size: %zu B >= %zu B", - size_t(headerLength), m_cacheBlob.getBufferSize()); - } - - res.trailingSpaceBeforePrivateBlob = headerLength - vk::VkPipelineCacheHeaderDataSize; - return res; -} - -// ===================================================================================================================== -// Finds the start offset of the private PipelineBinaryCache header. -// -// @returns : Private header offset on success, error if the cache blob does not have a valid private header -llvm::Expected CacheBlobInfo::getPrivateHeaderOffset() const { - auto *publicHeader = reinterpret_cast(m_cacheBlob.getBufferStart()); - size_t privateHeaderOffset = publicHeader->headerLength; - - if (privateHeaderOffset < vk::VkPipelineCacheHeaderDataSize) - return createBlobError(m_cacheBlob, "Vulkan Pipeline Cache header length less than expected"); - - if (privateHeaderOffset + sizeof(vk::PipelineBinaryCachePrivateHeader) > m_cacheBlob.getBufferSize()) - return createBlobError(m_cacheBlob, "Insufficient buffer size for the Pipeline Binary Cache private header"); - - // Make sure that this is an AMD pipeline cache blob. If not, we cannot read the private header. - if (publicHeader->vendorID != AMDVendorId) - return createBlobError(m_cacheBlob, "Vendor is not AMD. Unknown cache blob format."); - - return privateHeaderOffset; -} - -// ===================================================================================================================== -// Reads the private PipelineBinaryCache header. -// -// @returns : BinaryCachePrivateHeader info on success, error if the cache blob does not have a valid private header -llvm::Expected CacheBlobInfo::readBinaryCachePrivateHeaderInfo() const { - auto privateHeaderOffsetOrErr = getPrivateHeaderOffset(); - if (auto err = privateHeaderOffsetOrErr.takeError()) - return std::move(err); - - BinaryCachePrivateHeaderInfo res = {}; - res.privateHeader = reinterpret_cast(m_cacheBlob.getBufferStart() + - *privateHeaderOffsetOrErr); - res.contentBlobSize = - m_cacheBlob.getBufferSize() - (*privateHeaderOffsetOrErr + sizeof(vk::PipelineBinaryCachePrivateHeader)); - return res; -} - -// ===================================================================================================================== -// Finds the start offset of the cache content. -// -// @returns : Cache content offset on success, error if the cache blob does not have any valid content (not even empty) -llvm::Expected CacheBlobInfo::getCacheContentOffset() const { - auto privateHeaderOffsetOrErr = getPrivateHeaderOffset(); - if (auto err = privateHeaderOffsetOrErr.takeError()) - return std::move(err); - - return *privateHeaderOffsetOrErr + sizeof(vk::PipelineBinaryCachePrivateHeader); -} - -// ===================================================================================================================== -// Reads all PipelineBinaryCache entries. For each entry, calculates information about its location within the cache -// blob, and computes the MD5 sum of the entry's content. -// -// @param [out] entriesInfoOut : The cache entries found -// @returns : Error if the cache blob does not have a valid content section, success otherwise -llvm::Error -CacheBlobInfo::readBinaryCacheEntriesInfo(llvm::SmallVectorImpl &entriesInfoOut) const { - auto contentOffsetOrErr = getCacheContentOffset(); - if (auto err = contentOffsetOrErr.takeError()) - return err; - - constexpr size_t EntrySize = sizeof(vk::BinaryCacheEntry); - const uint8_t *const blobStart = reinterpret_cast(m_cacheBlob.getBufferStart()); - const uint8_t *const blobEnd = reinterpret_cast(m_cacheBlob.getBufferEnd()); - const uint8_t *currData = blobStart + *contentOffsetOrErr; - - for (size_t entryIdx = 0; currData < blobEnd; ++entryIdx) { - const size_t currEntryOffset = currData - blobStart; - if (currData + EntrySize > blobEnd) { - return createBlobError(m_cacheBlob, "Insufficient buffer size for cache entry header #%zu at offset %zu", - entryIdx, currEntryOffset); - } - - BinaryCacheEntryInfo currEntryInfo = {}; - currEntryInfo.entryHeader = currData; - memcpy(&currEntryInfo.entryHeaderData, currData, EntrySize); - currEntryInfo.idx = entryIdx; - - const size_t currEntryBlobSize = currEntryInfo.entryHeaderData.dataSize; - if (currData + EntrySize + currEntryBlobSize > blobEnd) { - return createBlobError(m_cacheBlob, "Insufficient buffer size for cache entry content #%zu at offset %zu", - entryIdx, currEntryOffset); - } - - currData += EntrySize; - currEntryInfo.entryBlob = {currData, currEntryBlobSize}; - currData += currEntryBlobSize; - - llvm::MD5 md5; - md5.update(currEntryInfo.entryBlob); - llvm::MD5::MD5Result result = {}; - md5.final(result); - currEntryInfo.entryMD5Sum = result.digest(); - - entriesInfoOut.push_back(std::move(currEntryInfo)); - } - - return llvm::Error::success(); -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const PublicVkHeaderInfo &info) { - assert(info.publicHeader); - const vk::PipelineCacheHeaderData &header = *info.publicHeader; - - os << "=== Vulkan Pipeline Cache Header ===\n" - << "header length:\t\t" << header.headerLength << "\n" - << "header version:\t\t" << header.headerVersion << "\n" - << "vendor ID:\t\t" << llvm::format("0x%" PRIx32, header.vendorID) << "\n" - << "device ID:\t\t" << llvm::format("0x%" PRIx32, header.deviceID) << "\n" - << "pipeline cache UUID:\t" << cc::uuidToHexString(header.UUID) << "\n" - << "trailing space:\t" << info.trailingSpaceBeforePrivateBlob << "\n"; - return os; -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const BinaryCachePrivateHeaderInfo &info) { - assert(info.privateHeader); - const vk::PipelineBinaryCachePrivateHeader &header = *info.privateHeader; - - os << "=== Pipeline Binary Cache Private Header ===\n" - << "header length:\t" << sizeof(header) << "\n" - << "hash ID:\t" << llvm::format_bytes(header.hashId, std::nullopt, sizeof(header.hashId)) << "\n" - << "content size:\t" << info.contentBlobSize << "\n"; - return os; -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const BinaryCacheEntryInfo &info) { - assert(info.entryHeader); - const vk::BinaryCacheEntry &header = info.entryHeaderData; - - os << "\t*** Entry " << info.idx << " ***\n" - << "\thash ID:\t\t" - << "0x" << llvm::format_hex_no_prefix(header.hashId.qwords[0], sizeof(uint64_t) * 2) << " 0x" - << llvm::format_hex_no_prefix(header.hashId.qwords[1], sizeof(uint64_t) * 2) << '\n' - << "\tdata size:\t\t" << header.dataSize << "\n" - << "\tcalculated MD5 sum:\t" << info.entryMD5Sum << "\n"; - return os; -} - -// ===================================================================================================================== -// Returns a map from the MD5 sum of a files contents to the file's path for every '.elf' file in `dir` or any of its -// subdirectories. -// If there are multiple '.elf' files sharing the same MD5, a single (arbitrary) file path is kept as the value of that -// map entry. -// -// @param dir : The directory to search -// @returns : Map from ELF MD5 sums to their paths on disk -llvm::StringMap mapMD5SumsToElfFilePath(llvm::Twine dir) { - namespace fs = llvm::sys::fs; - llvm::StringMap md5ToElfPath; - - std::error_code ec{}; - for (fs::recursive_directory_iterator it{dir, ec}, e{}; it != e && !ec; it.increment(ec)) { - const std::string &path(it->path()); - if (!llvm::StringRef(path).endswith(".elf") || fs::is_directory(path)) - continue; - - llvm::ErrorOr elfMD5OrErr = fs::md5_contents(path); - if (std::error_code err = elfMD5OrErr.getError()) { - llvm::errs() << "[WARN]: Can not read source ELF file " << path << ": " << err.message() << "\n"; - continue; - } - - md5ToElfPath.insert({elfMD5OrErr->digest(), path}); - } - - return md5ToElfPath; -} - -} // namespace cc diff --git a/tools/cache_creator/cache_info.h b/tools/cache_creator/cache_info.h deleted file mode 100644 index e71e6080..00000000 --- a/tools/cache_creator/cache_info.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#pragma once - -#include "include/binary_cache_serialization.h" - -// These Xlib defines conflict with LLVM. -#undef Bool -#undef Status - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/MemoryBufferRef.h" -#include "llvm/Support/raw_ostream.h" -#include - -namespace cc { - -// ===================================================================================================================== -// -// This API allows to analyze and print XGL's PipelineBinaryCache blobs. It is not meant to work with other -// Vulkan Pipeline Cache blob formats. -// -// PipelineBinaryCache consist of 3 parts: -// - Public Vulkan Pipeline Cache header -// - Private PipelineBinaryCache header -// - Sequence of PipelineBinaryCache entries -// -// For detailed information about PipelineBinaryCache structure, see -// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPipelineCacheData.html and -// `xgl/icd/api/include/binary_cache_serialization.h`. -// -// ===================================================================================================================== - -// Represents printable information about the public Vulkan Pipeline Cache header. -struct PublicVkHeaderInfo { - const vk::PipelineCacheHeaderData *publicHeader; - size_t trailingSpaceBeforePrivateBlob; -}; - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const PublicVkHeaderInfo &info); - -// Represents printable information about the private Pipeline Binary Cache header. -struct BinaryCachePrivateHeaderInfo { - const vk::PipelineBinaryCachePrivateHeader *privateHeader; - size_t contentBlobSize; -}; - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const BinaryCachePrivateHeaderInfo &info); - -using MD5DigestStr = llvm::SmallString<32>; - -// Represents printable information about a Pipeline Binary Cache entry, its location within the cache blob, and -// calculated MD5 sum of the entry content. -struct BinaryCacheEntryInfo { - // We do not store the header as `vk::BinaryCacheEntry *` because the address may not be properly aligned. - const uint8_t *entryHeader; - vk::BinaryCacheEntry entryHeaderData; - size_t idx; - llvm::ArrayRef entryBlob; - MD5DigestStr entryMD5Sum; -}; - -llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const BinaryCacheEntryInfo &info); - -// Given a directory, returns a map from ELF MD5 sums their paths. Files without the '.elf' extension ignored. -llvm::StringMap mapMD5SumsToElfFilePath(llvm::Twine dir); - -// Analyzes given PipelineBinaryCache file. It it valid to use it with invalid or partially-valid cache blobs. -// Note: Member functions do not have to be called in any particular order. -class CacheBlobInfo { -public: - static llvm::Expected create(llvm::MemoryBufferRef cacheBlob); - - llvm::Expected readPublicVkHeaderInfo() const; - - llvm::Expected readBinaryCachePrivateHeaderInfo() const; - - llvm::Error readBinaryCacheEntriesInfo(llvm::SmallVectorImpl &entriesInfoOut) const; - - llvm::Expected getPrivateHeaderOffset() const; - llvm::Expected getCacheContentOffset() const; - -private: - CacheBlobInfo(llvm::MemoryBufferRef cacheBlob) : m_cacheBlob(cacheBlob) {} - - llvm::MemoryBufferRef m_cacheBlob; -}; - -} // namespace cc diff --git a/tools/cache_creator/cache_info_main.cpp b/tools/cache_creator/cache_info_main.cpp deleted file mode 100644 index d5c047b6..00000000 --- a/tools/cache_creator/cache_info_main.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ - -#include "cache_info.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include - -namespace { -llvm::cl::OptionCategory CacheInfoCat("Cache Info Options"); - -llvm::cl::opt InFile(llvm::cl::Positional, llvm::cl::ValueRequired, llvm::cl::cat(CacheInfoCat), - llvm::cl::desc("")); -llvm::cl::opt ElfSourceDir("elf-source-dir", llvm::cl::desc("(Optional) Directory with source ELF files"), - llvm::cl::cat(CacheInfoCat), llvm::cl::value_desc("directory")); - -int reportAndConsumeError(llvm::Error err, int exitCode) { - llvm::errs() << "[ERROR]: " << err << "\n"; - llvm::consumeError(std::move(err)); - return exitCode; -} -} // namespace - -namespace fs = llvm::sys::fs; - -int main(int argc, char **argv) { - llvm::cl::ParseCommandLineOptions(argc, argv); - - llvm::ErrorOr> inputBufferOrErr = llvm::MemoryBuffer::getFile(InFile); - if (auto err = inputBufferOrErr.getError()) { - llvm::errs() << "Failed to read input file " << InFile << ": " << err.message() << "\n"; - return 3; - } - llvm::outs() << "Read: " << InFile << ", " << (*inputBufferOrErr)->getBufferSize() << " B\n\n"; - - auto blobInfoOrErr = cc::CacheBlobInfo::create(**inputBufferOrErr); - if (auto err = blobInfoOrErr.takeError()) - return reportAndConsumeError(std::move(err), 4); - const cc::CacheBlobInfo &blobInfo = *blobInfoOrErr; - - auto publicHeaderInfoOrErr = blobInfo.readPublicVkHeaderInfo(); - if (auto err = publicHeaderInfoOrErr.takeError()) - return reportAndConsumeError(std::move(err), 4); - llvm::outs() << *publicHeaderInfoOrErr << "\n"; - - auto privateHeaderInfoOrErr = blobInfo.readBinaryCachePrivateHeaderInfo(); - if (auto err = privateHeaderInfoOrErr.takeError()) - return reportAndConsumeError(std::move(err), 4); - llvm::outs() << *privateHeaderInfoOrErr << "\n"; - - llvm::StringMap elfMD5ToFilePath; - if (!ElfSourceDir.empty()) { - llvm::SmallVector rawElfSourceDir; - if (std::error_code err = fs::real_path(ElfSourceDir, rawElfSourceDir, /* expand_tilde = */ true)) { - llvm::errs() << "[ERROR]: --elf-source-dir: " << ElfSourceDir << "could not be expanded: " << err.message() - << "\n"; - return 3; - } - llvm::StringRef elfSourceDirReal(rawElfSourceDir.begin(), rawElfSourceDir.size()); - - if (!fs::is_directory(elfSourceDirReal)) { - llvm::errs() << "[ERROR]: --elf-source-dir: " << elfSourceDirReal << " is not a directory!\n"; - return 3; - } - elfMD5ToFilePath = cc::mapMD5SumsToElfFilePath(elfSourceDirReal); - } - - llvm::SmallVector entries; - if (auto cacheEntriesReadErr = blobInfo.readBinaryCacheEntriesInfo(entries)) - return reportAndConsumeError(std::move(cacheEntriesReadErr), 4); - - llvm::outs() << "=== Cache Content Info ===\n" - << "total num entries: " << entries.size() << "\n" - << "entry header length: " << sizeof(vk::BinaryCacheEntry) << "\n\n"; - - for (const cc::BinaryCacheEntryInfo &entryInfo : entries) { - llvm::StringRef sourceFilePath = ""; - auto sourceElfIt = elfMD5ToFilePath.find(entryInfo.entryMD5Sum); - if (sourceElfIt != elfMD5ToFilePath.end()) - sourceFilePath = sourceElfIt->second; - - llvm::outs() << entryInfo << "\tmatched source file:\t" << sourceFilePath << "\n\n"; - } - - llvm::outs() << "\n=== Cache Info analysis finished ===\n"; - return 0; -} diff --git a/tools/cache_creator/test/BasicCacheCreation.spvasm b/tools/cache_creator/test/BasicCacheCreation.spvasm deleted file mode 100644 index 27399bd4..00000000 --- a/tools/cache_creator/test/BasicCacheCreation.spvasm +++ /dev/null @@ -1,213 +0,0 @@ -; Check that cache-creator can create cache files from one or two elf entries, -; and that cache-info can read them. - -; Split the test into two .spvasm temporary inputs. -; RUN: split-file %s %t - -; Compile the vertex shader into a relocatable ELF. Save the compilation output to a log so that other test can refer to it. -; RUN: amdllpc %t/vert.spvasm %gfxip %reloc -v -o %t.vert.elf > %t.vert.amdllpc.log 2>&1 \ -; RUN: && cat %t.vert.amdllpc.log | FileCheck --match-full-lines --check-prefix=LLPC-VERT %s -; LLPC-VERT-LABEL: // LLPC SPIRV-to-LLVM translation results -; LLPC-VERT-LABEL: ===== AMDLLPC SUCCESS ===== - -; Compile the fragment shader into a relocatable ELF. Save the compilation output to a log so that other test can refer to it. -; RUN: amdllpc %t/frag.spvasm %gfxip %reloc -v -o %t.frag.elf > %t.frag.amdllpc.log 2>&1 \ -; RUN: && cat %t.frag.amdllpc.log | FileCheck --match-full-lines --check-prefix=LLPC-FRAG %s -; LLPC-FRAG-LABEL: // LLPC SPIRV-to-LLVM translation results -; LLPC-FRAG-LABEL: ===== AMDLLPC SUCCESS ===== - - -; Test 1: Create a cache file with one input. Check that the cache contents have the right format -; and are read back as expected. -; RUN: cache-creator %t.vert.elf --uuid=00000001-0020-0300-4000-50000000000f --device-id=0x6080 \ -; RUN: -o %t.vert.bin --verbose > %t.vert.cc.log 2>&1 \ -; RUN: && cache-info %t.vert.bin > %t.vert.ci.log 2>&1 \ -; RUN: && cat %t.vert.cc.log %t.vert.ci.log %t.vert.amdllpc.log \ -; RUN: | FileCheck --match-full-lines --check-prefix=CC-VERT %s -; Part 1a: Check cache-creator output. -; CC-VERT: Num inputs: 1, anticipated cache size: [[#vert_cache_size:]] -; CC-VERT-NEXT: Read: {{.*}}.vert.elf -; CC-VERT: Num entries written: 1, actual cache size: [[#vert_cache_size]] B -; CC-VERT: Cache successfully written to: [[cache_file_path:.*\.vert\.bin]] -; -; Part 1b: Check cache-info output. -; CC-VERT: Read: [[cache_file_path]], [[#vert_cache_size]] B -; -; CC-VERT-LABEL: === Vulkan Pipeline Cache Header === -; CC-VERT-NEXT: header length: [[#vk_header_len:32]] -; CC-VERT-NEXT: header version: 1 -; CC-VERT-NEXT: vendor ID: 0x1002 -; CC-VERT-NEXT: device ID: 0x6080 -; CC-VERT-NEXT: pipeline cache UUID: 00000001-0020-0300-4000-50000000000f -; CC-VERT-NEXT: trailing space: 0 -; -; CC-VERT-LABEL: === Pipeline Binary Cache Private Header === -; CC-VERT-NEXT: header length: [[#pbc_header_len:20]] -; CC-VERT-NEXT: hash ID: {{([0-9a-f]{8} ?){5}$}} -; CC-VERT-NEXT: content size: [[#vert_cache_size - vk_header_len - pbc_header_len]] -; -; CC-VERT-LABEL: === Cache Content Info === -; CC-VERT-NEXT: total num entries: 1 -; CC-VERT-NEXT: entry header length: [[#entry_header_len:24]] -; CC-VERT-LABEL: *** Entry 0 *** -; CC-VERT-NEXT: hash ID: [[vert_cache_hash:(0x[0-9a-f]{16} ?){2}]] -; CC-VERT-NEXT: data size: [[#vert_cache_size - vk_header_len - pbc_header_len - entry_header_len]] -; CC-VERT-NEXT: calculated MD5 sum: {{[0-9a-f]{32}$}} -; CC-VERT-NEXT: matched source file: -; -; CC-VERT-LABEL: === Cache Info analysis finished === -; -; Part 1c: Check amdllpc output to see that the entry hash ID from 1b matches the compiler vertex cache hash. -; CC-VERT: SPIR-V disassembly for {{.*}}vert.spvasm: -; CC-VERT-LABEL: // LLPC calculated hash results (graphics pipeline) -; CC-VERT: Finalized hash for vertex stage cache lookup: [[vert_cache_hash]] - - -; Test 2: Create a cache file with two inputs. Check that both ELFs are present in the cache file. -; RUN: cache-creator %t.vert.elf %t.frag.elf --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 \ -; RUN: -o %t.vert-frag.bin --verbose > %t.vert-frag.cc.log 2>&1 \ -; RUN: && cache-info %t.vert-frag.bin --elf-source-dir=%T > %t.vert-frag.ci.log 2>&1 \ -; RUN: && cat %t.vert-frag.cc.log %t.vert-frag.ci.log %t.vert.amdllpc.log %t.frag.amdllpc.log \ -; RUN: | FileCheck --match-full-lines --check-prefix=CC-TWO %s -; Part 2a: Check cache-creator output. -; CC-TWO: Num inputs: 2, anticipated cache size: [[#two_cache_size:]] -; CC-TWO-NEXT: Read: [[vert_elf_path:.*\.vert\.elf]] -; CC-TWO: Read: [[frag_elf_path:.*\.frag\.elf]] -; CC-TWO: Num entries written: 2, actual cache size: [[#two_cache_size]] B -; CC-TWO: Cache successfully written to: [[cache_file_path:.*\.vert-frag\.bin]] -; -; Part 2b: Check cache-info output. -; CC-TWO: Read: {{.*}}.vert-frag.bin, [[#two_cache_size]] B -; -; CC-TWO-LABEL: === Vulkan Pipeline Cache Header === -; CC-TWO-NEXT: header length: [[#vk_header_len:32]] -; CC-TWO: trailing space: 0 -; -; CC-TWO-LABEL: === Pipeline Binary Cache Private Header === -; CC-TWO-NEXT: header length: [[#pbc_header_len:20]] -; CC-TWO: content size: [[#two_cache_size - vk_header_len - pbc_header_len]] -; -; CC-TWO-LABEL: === Cache Content Info === -; CC-TWO-NEXT: total num entries: 2 -; CC-TWO-NEXT: entry header length: [[#entry_header_len:24]] -; -; CC-TWO-LABEL: *** Entry 0 *** -; CC-TWO-NEXT: hash ID: [[vert_cache_hash:(0x[0-9a-f]{16} ?){2}]] -; CC-TWO-NEXT: data size: [[#vert_entry_data_size:]] -; CC-TWO-NEXT: calculated MD5 sum: {{[0-9a-f]{32}$}} -; CC-TWO-NEXT: matched source file: [[vert_elf_path]] -; -; CC-TWO-LABEL: *** Entry 1 *** -; CC-TWO-NEXT: hash ID: [[frag_cache_hash:(0x[0-9a-f]{16} ?){2}]] -; CC-TWO-NEXT: data size: [[#two_cache_size - vk_header_len - pbc_header_len - entry_header_len - vert_entry_data_size - entry_header_len]] -; CC-TWO-NEXT: calculated MD5 sum: {{[0-9a-f]{32}$}} -; CC-TWO-NEXT: matched source file: [[frag_elf_path]] -; -; Part 2c: Check amdllpc output to see that the entry hash IDs from 2b match the compiler vertex and fragment cache hashes. -; CC-TWO: SPIR-V disassembly for {{.*}}vert.spvasm: -; CC-TWO-LABEL: // LLPC calculated hash results (graphics pipeline) -; CC-TWO: Finalized hash for vertex stage cache lookup: [[vert_cache_hash]] -; -; CC-TWO: SPIR-V disassembly for {{.*}}frag.spvasm: -; CC-TWO-LABEL: // LLPC calculated hash results (graphics pipeline) -; CC-TWO: Finalized hash for fragment stage cache lookup: [[frag_cache_hash]] - - -; Test 3: Create a cache file with one input repeated twice. -; In this case, we simply add it twice and do not attempt to de-duplicate inputs. -; RUN: cache-creator %t.vert.elf %t.vert.elf --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 \ -; RUN: -o %t.vert-vert.bin --verbose > %t.vert-vert.cc.log 2>&1 \ -; RUN: && cache-info %t.vert-vert.bin --elf-source-dir=%T > %t.vert-vert.ci.log 2>&1 \ -; RUN: && cat %t.vert-vert.cc.log %t.vert-vert.ci.log %t.vert.amdllpc.log \ -; RUN: | FileCheck --match-full-lines --check-prefix=CC-DUP %s -; Part 3a: Check cache-creator output. -; CC-DUP: Num inputs: 2, anticipated cache size: [[#dup_cache_size:]] -; CC-DUP-NEXT: Read: [[vert_elf_path:.*\.vert\.elf]] -; CC-DUP: Read: [[vert_elf_path]] -; CC-DUP: Num entries written: 2, actual cache size: [[#dup_cache_size]] B -; CC-DUP: Cache successfully written to: [[cache_file_path:.*\.vert-vert\.bin]] -; -; Part 3b: Check cache-info output. -; CC-DUP: Read: [[cache_file_path]], [[#dup_cache_size]] B -; -; CC-DUP-LABEL: === Cache Content Info === -; CC-DUP-NEXT: total num entries: 2 -; -; CC-DUP-LABEL: *** Entry 0 *** -; CC-DUP-NEXT: hash ID: [[vert_cache_hash:(0x[0-9a-f]{16} ?){2}]] -; CC-DUP-NEXT: data size: [[#vert_entry_data_size:]] -; CC-DUP-NEXT: calculated MD5 sum: [[vert_md5_sum:[0-9a-f]{32}]] -; CC-DUP-NEXT: matched source file: [[vert_elf_path]] -; -; CC-DUP-LABEL: *** Entry 1 *** -; CC-DUP-NEXT: hash ID: [[vert_cache_hash]] -; CC-DUP-NEXT: data size: [[#vert_entry_data_size]] -; CC-DUP-NEXT: calculated MD5 sum: [[vert_md5_sum]] -; CC-DUP-NEXT: matched source file: [[vert_elf_path]] -; -; Part 3c: Check amdllpc output to see that the entry hash ID from 2b matches the compiler vertex cache hash. -; CC-DUP: SPIR-V disassembly for {{.*}}vert.spvasm: -; CC-DUP-LABEL: // LLPC calculated hash results (graphics pipeline) -; CC-DUP: Finalized hash for vertex stage cache lookup: [[vert_cache_hash]] - - -;--- vert.spvasm -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 10 -; Bound: 28 -; Schema: 0 - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %input_color %_entryPointOutput - OpSource HLSL 500 - OpName %main "main" - OpName %input_color "input.color" - OpName %_entryPointOutput "@entryPointOutput" - OpDecorate %input_color Location 0 - OpDecorate %_entryPointOutput Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%input_color = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float -%_entryPointOutput = OpVariable %_ptr_Output_v4float Output - %main = OpFunction %void None %3 - %5 = OpLabel - %24 = OpLoad %v4float %input_color - OpStore %_entryPointOutput %24 - OpReturn - OpFunctionEnd - - -;--- frag.spvasm -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 10 -; Bound: 12 -; Schema: 0 - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %fragColor - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 460 - OpName %main "main" - OpName %fragColor "fragColor" - OpDecorate %fragColor Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %fragColor = OpVariable %_ptr_Output_v4float Output - %float_0 = OpConstant %float 0 - %11 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 - %main = OpFunction %void None %3 - %5 = OpLabel - OpStore %fragColor %11 - OpReturn - OpFunctionEnd diff --git a/tools/cache_creator/test/CMakeLists.txt b/tools/cache_creator/test/CMakeLists.txt deleted file mode 100644 index b2ee02e3..00000000 --- a/tools/cache_creator/test/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -## - ####################################################################################################################### - # - # Copyright (c) 2021 Google LLC. All Rights Reserved. - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - # - ####################################################################################################################### - -# Set up the LIT testing environment. See https://llvm.org/docs/CommandGuide/lit.html. - -# These constants are used to fill in lit.site.cfg.py.in and propagate the project configuration to LIT. -set(CACHE_CREATOR_TEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(CACHE_CREATOR_TEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -set(CACHE_CREATOR_AMDLLPC_DIR ${LLPC_BINARY_DIR}) -set(CACHE_CREATOR_DEFAULT_GFXIP "9") - -# Check if the SPVGEN binary dir is defined and not empty. -if(XGL_SPVGEN_BUILD_PATH STREQUAL "") - message(FATAL_ERROR "SPVGEN is required for XGL Cache Creator LIT test but cannot be found.") -endif() -set(CACHE_CREATOR_SPVGEN_DIR ${XGL_SPVGEN_BUILD_PATH}) - -# Required by configure_lit_site_cfg; this allows it to find the llvm-lit executable. -set(LLVM_LIT_OUTPUT_DIR ${LLVM_TOOLS_BINARY_DIR}) -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py - MAIN_CONFIG - ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py -) - -# You can execute test by building the `check-cache-creator` target, e.g., `ninja check-cache-creator`. -add_lit_testsuite(check-cache-creator "Running the XGL cache creator regression tests" - ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS cache-creator cache-info amdllpc FileCheck count not split-file llvm-objdump llvm-readelf -) diff --git a/tools/cache_creator/test/NonRelocatableShader.pipe b/tools/cache_creator/test/NonRelocatableShader.pipe deleted file mode 100644 index 8505240e..00000000 --- a/tools/cache_creator/test/NonRelocatableShader.pipe +++ /dev/null @@ -1,43 +0,0 @@ -; Check that cache-creator handles non-relocatable ELFs (i.e., in full pipeline compilation). - -; Compile the full pipeline to a non-relocatable ELF. -; RUN: amdllpc -v %gfxip %s -o %t.elf | FileCheck -check-prefix=CHECK-LLPC %s -; CHECK-LLPC: {{^// LLPC}} SPIRV-to-LLVM translation results -; CHECK-LLPC: AMDLLPC SUCCESS - -; Create a cache file with the ELF input and verify that it is written successfully. -; RUN: cache-creator %t.elf --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 -o %t.bin 2>&1 \ -; RUN: | FileCheck --check-prefix=CHECK-CC %s -; CHECK-CC: {{^Cache}} successfully written to: {{.*\.bin$}} - -[CsGlsl] -#version 450 - -layout(binding = 0, std430) buffer OUT -{ - uvec4 o; -}; -layout(binding = 1, std430) buffer IN -{ - uvec4 i; -}; - -layout(local_size_x = 2, local_size_y = 3) in; -void main() -{ - o = i; -} - - -[CsInfo] -entryPoint = main -userDataNode[0].type = DescriptorBuffer -userDataNode[0].offsetInDwords = 0 -userDataNode[0].sizeInDwords = 4 -userDataNode[0].set = 0 -userDataNode[0].binding = 0 -userDataNode[1].type = DescriptorBuffer -userDataNode[1].offsetInDwords = 4 -userDataNode[1].sizeInDwords = 4 -userDataNode[1].set = 0 -userDataNode[1].binding = 1 diff --git a/tools/cache_creator/test/RequiredCacheCreatorArguments.spvasm b/tools/cache_creator/test/RequiredCacheCreatorArguments.spvasm deleted file mode 100644 index b7c6186d..00000000 --- a/tools/cache_creator/test/RequiredCacheCreatorArguments.spvasm +++ /dev/null @@ -1,28 +0,0 @@ -; Check that cache-creator requires all the necessary arguments to create a valid cache file. -; These tests doesn't require SPIR-V input, but we use .spvasm as the file extension so that LIT can pick it up. - -; Test 1: Empty input ELF list. -; RUN: not cache-creator -o %t.bin --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 2>&1 | FileCheck --check-prefix=CHECK-ELFS %s -; CHECK-ELFS: Not enough positional command line arguments specified! -; CHECK-ELFS-NEXT: Must specify at least 1 positional argument - -; Test 2: No UUID provided. -; RUN: not cache-creator -o %t.bin --device-id=0x6080 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-UUID %s -; CHECK-NO-UUID: for the --uuid option: must be specified at least once! - -; Test 3: Invalid UUID provided. -; RUN: not cache-creator -o %t.bin --uuid=42 --device-id=0x6080 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-UUID %s -; CHECK-INVALID-UUID: Failed to parse pipeline cache UUID - -; Test 4: No device ID provided. -; RUN: not cache-creator -o %t.bin --uuid=00000000-0000-0000-0000-000000000000 2>&1 | FileCheck --check-prefix=CHECK-NO-DID %s -; CHECK-NO-DID: for the --device-id option: must be specified at least once! - -; Test 5: No output file specified. -; RUN: not cache-creator --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-OUT %s -; CHECK-NO-OUT: for the -o option: must be specified at least once! - -; Test 6: Specified input file does not exist. -; RUN: not cache-creator -o %t.bin --uuid=00000000-0000-0000-0000-000000000000 --device-id=0x6080 %t.does.not.exist.elf 2>&1 \ -; RUN: | FileCheck --check-prefix=CHECK-BAD-IN %s -; CHECK-BAD-IN: Failed to read file size diff --git a/tools/cache_creator/test/RunLitCommands.spvasm b/tools/cache_creator/test/RunLitCommands.spvasm deleted file mode 100644 index 01412292..00000000 --- a/tools/cache_creator/test/RunLitCommands.spvasm +++ /dev/null @@ -1,44 +0,0 @@ -; Check if lit is configured properly and that all basic tools run. -; RUN: amdllpc %s %gfxip %reloc -v -o %t.elf | FileCheck --check-prefix=CHECK-LLPC %s -; CHECK-LLPC: {{^// LLPC}} SPIRV-to-LLVM translation results -; CHECK-LLPC: AMDLLPC SUCCESS - -; RUN: cache-creator --help | FileCheck -check-prefix=CHECK-CC %s -; CHECK-CC: Cache Creator Options - -; RUN: cache-info --help | FileCheck -check-prefix=CHECK-CI %s -; CHECK-CI: Cache Info Options - -; RUN: llvm-objdump --version | FileCheck -check-prefix=CHECK-OBJDUMP %s -; CHECK-OBJDUMP: Registered Targets - -; RUN: llvm-readelf --version | FileCheck -check-prefix=CHECK-READELF %s -; CHECK-READELF: LLVM version - -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 10 -; Bound: 12 -; Schema: 0 - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %fragColor - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 460 - OpName %main "main" - OpName %fragColor "fragColor" - OpDecorate %fragColor Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %fragColor = OpVariable %_ptr_Output_v4float Output - %float_1 = OpConstant %float 1 - %11 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 - %main = OpFunction %void None %3 - %5 = OpLabel - OpStore %fragColor %11 - OpReturn - OpFunctionEnd diff --git a/tools/cache_creator/test/lit.cfg.py b/tools/cache_creator/test/lit.cfg.py deleted file mode 100644 index 06cb8046..00000000 --- a/tools/cache_creator/test/lit.cfg.py +++ /dev/null @@ -1,60 +0,0 @@ -## - ####################################################################################################################### - # - # Copyright (c) 2021 Google LLC. All Rights Reserved. - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - # - ####################################################################################################################### - -import lit.util -import lit.formats - -from lit.llvm import llvm_config -from lit.llvm.subst import FindTool -from lit.llvm.subst import ToolSubst - -# name: The name of this test suite. -config.name = 'cache creator' - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) - -# suffixes: A list of file extensions to treat as test files. This is overridden -# by individual lit.local.cfg files in the test subdirectories. -config.suffixes = ['.spvasm', '.pipe'] - -# excludes: A list of directories to exclude from the testsuite. -config.excludes = [] - -# test_source_root: The root path where tests are located. -config.test_source_root = os.path.dirname(__file__) - -# test_exec_root: The root path where tests should be run. -config.test_exec_root = os.path.join(config.test_run_dir, 'test_output') - -llvm_config.use_default_substitutions() - -config.substitutions.append(('%PATH%', config.environment['PATH'])) -config.substitutions.append(('%gfxip', '-gfxip=' + config.gfxip)) -config.substitutions.append(('%reloc', '-unlinked -enable-relocatable-shader-elf')) - -tool_dirs = [config.cache_creator_tools_dir, config.amdllpc_dir, config.llvm_tools_dir] -tools = ['amdllpc', 'cache-creator', 'cache-info', 'llvm-objdump', 'llvm-readelf', 'count', 'not', 'split-file'] -llvm_config.add_tool_substitutions(tools, tool_dirs) diff --git a/tools/cache_creator/test/lit.site.cfg.py.in b/tools/cache_creator/test/lit.site.cfg.py.in deleted file mode 100644 index 000e9523..00000000 --- a/tools/cache_creator/test/lit.site.cfg.py.in +++ /dev/null @@ -1,31 +0,0 @@ -@LIT_SITE_CFG_IN_HEADER@ - -import sys - -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.lit_tools_dir = "@LLVM_TOOLS_DIR@" -config.python_executable = "@PYTHON_EXECUTABLE@" - -config.llvm_assertions = "@LLVM_ENABLE_ASSERTIONS@" - -config.cache_creator_tools_dir = "@CACHE_CREATOR_TOOLS_BINARY_DIR@" -config.amdllpc_dir = "@CACHE_CREATOR_AMDLLPC_DIR@" -config.gfxip = "@CACHE_CREATOR_DEFAULT_GFXIP@" -config.test_run_dir = "@CACHE_CREATOR_TEST_BINARY_DIR@" - -# Support substitution of the tools_dir with user parameters. This is -# used when we can't determine the tool dir at configuration time. -try: - config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params -except KeyError: - e = sys.exc_info()[1] - key, = e.args - lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) - -import lit.llvm -lit.llvm.initialize(lit_config, config) - -# Let the main config do the real work. -lit_config.load_config(config, "@CACHE_CREATOR_TEST_SOURCE_DIR@/lit.cfg.py") diff --git a/tools/cache_creator/unittests/CMakeLists.txt b/tools/cache_creator/unittests/CMakeLists.txt deleted file mode 100644 index 61de1a69..00000000 --- a/tools/cache_creator/unittests/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -## - ####################################################################################################################### - # - # Copyright (c) 2021 Google LLC. All Rights Reserved. - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - # - ####################################################################################################################### - -# XGL Cache Creator Tools unit tests. -# To execute all cache-creator tools unit tests, run: -# cmake --build . --target check-cache-creator-units - -# Required to use LIT on Windows. -find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION} REQUIRED - COMPONENTS Interpreter) - -# Find the TestingSupport library name that we will link with. -llvm_map_components_to_libnames(llvm_testing_support_lib TestingSupport) - -# Use the gtest support provided by llvm -set(LLVM_GTEST_LIBS llvm_gtest llvm_gtest_main ${llvm_testing_support_lib}) -if(LLVM_PTHREAD_LIB) - list(APPEND LLVM_GTEST_LIBS pthread) -endif() - -add_executable(CacheCreatorUnitTests) -target_sources(CacheCreatorUnitTests PRIVATE - cache_creator_tests.cpp - cache_info_tests.cpp -) - -llvm_map_components_to_libnames(llvm_libs - BinaryFormat -) -target_link_libraries(CacheCreatorUnitTests PRIVATE - ${LLVM_GTEST_LIBS} - ${llvm_libs} - cache_creator_lib -) -target_include_directories(CacheCreatorUnitTests PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/.. -) - -# Add a LIT target to execute all unit tests. -# Required by lit.site.cfg.py.in. -set(XGL_CACHE_CREATOR_UNIT_TEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(XGL_CACHE_CREATOR_UNIT_TEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -# Required by configure_lit_site_cfg. -set(LLVM_LIT_OUTPUT_DIR ${LLVM_TOOLS_BINARY_DIR}) - -# Main config for unit tests. -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py - MAIN_CONFIG - ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py -) - -add_lit_testsuite(check-cache-creator-units "Running the XGL cache-creator tools unit tests" - ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS - CacheCreatorUnitTests -) diff --git a/tools/cache_creator/unittests/cache_creator_tests.cpp b/tools/cache_creator/unittests/cache_creator_tests.cpp deleted file mode 100644 index 3ea198cc..00000000 --- a/tools/cache_creator/unittests/cache_creator_tests.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#include "cache_creator.h" -#include "llvm/BinaryFormat/MsgPackDocument.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" -#include - -namespace { - -using llvm::Failed; -using llvm::Succeeded; - -TEST(CacheCreatorTest, PlaceholderTestPass) { - EXPECT_TRUE(true); -} - -using UuidArray = std::array; - -TEST(CacheCreatorTest, BasicUuidToString) { - UuidArray uuid; - - uuid.fill(0); - EXPECT_EQ(cc::uuidToHexString(uuid), "00000000-0000-0000-0000-000000000000"); - - uuid[0] = 16; - EXPECT_EQ(cc::uuidToHexString(uuid), "10000000-0000-0000-0000-000000000000"); - - uuid[0] = 255; - EXPECT_EQ(cc::uuidToHexString(uuid), "ff000000-0000-0000-0000-000000000000"); - - uuid[0] = 0; - uuid.back() = 1; - EXPECT_EQ(cc::uuidToHexString(uuid), "00000000-0000-0000-0000-000000000001"); - - uuid.back() = 15; - EXPECT_EQ(cc::uuidToHexString(uuid), "00000000-0000-0000-0000-00000000000f"); - - uuid.back() = 255; - EXPECT_EQ(cc::uuidToHexString(uuid), "00000000-0000-0000-0000-0000000000ff"); - - uuid[0] = 255; - EXPECT_EQ(cc::uuidToHexString(uuid), "ff000000-0000-0000-0000-0000000000ff"); -} - -TEST(CacheCreatorTest, BasicHexStringToUuid) { - UuidArray allZeros = {}; - UuidArray allOnes = {}; - allOnes.fill(255); - - UuidArray out = {}; - EXPECT_TRUE(cc::hexStringToUuid("00000000-0000-0000-0000-000000000000", out)); - EXPECT_EQ(out, allZeros); - - EXPECT_TRUE(cc::hexStringToUuid("10000000-0000-0000-0000-000000000000", out)); - EXPECT_EQ(out.front(), 16); - EXPECT_EQ(out.back(), 0); - - EXPECT_TRUE(cc::hexStringToUuid("f0000000-0000-0000-0000-000000000000", out)); - EXPECT_EQ(out.front(), 240); - EXPECT_EQ(out.back(), 0); - - EXPECT_TRUE(cc::hexStringToUuid("ff000000-0000-0000-0000-000000000000", out)); - EXPECT_EQ(out.front(), 255); - EXPECT_EQ(out.back(), 0); - - EXPECT_TRUE(cc::hexStringToUuid("00000000-0000-0000-0000-000000000001", out)); - EXPECT_EQ(out.front(), 0); - EXPECT_EQ(out.back(), 1); - - EXPECT_TRUE(cc::hexStringToUuid("00000000-0000-0000-0000-00000000000f", out)); - EXPECT_EQ(out.front(), 0); - EXPECT_EQ(out.back(), 15); - - EXPECT_TRUE(cc::hexStringToUuid("00000000-0000-0000-0000-0000000000ff", out)); - EXPECT_EQ(out.front(), 0); - EXPECT_EQ(out.back(), 255); - - EXPECT_TRUE(cc::hexStringToUuid("ffffffff-ffff-ffff-ffff-ffffffffffff", out)); - EXPECT_EQ(out, allOnes); -} - -TEST(CacheCreatorTest, BadHexStringUuids) { - UuidArray out = {}; - - EXPECT_FALSE(cc::hexStringToUuid("", out)); - EXPECT_FALSE(cc::hexStringToUuid("----", out)); - - EXPECT_FALSE(cc::hexStringToUuid("ffffffffffffffffffffffffffffffff", out)); - EXPECT_FALSE(cc::hexStringToUuid("fffffff-ffff-ffff-ffff-ffffffffffff", out)); - EXPECT_FALSE(cc::hexStringToUuid("0ffffffff-ffff-ffff-ffff-ffffffffffff", out)); - EXPECT_FALSE(cc::hexStringToUuid("ffffffff-ffff-ffff-ffff-ffffffffffff0", out)); - EXPECT_FALSE(cc::hexStringToUuid("ffffffff-ffff-ffff-ffff0ffffffffffff", out)); - EXPECT_FALSE(cc::hexStringToUuid("ffffffff-ffff-ffff-ffff-ffffffffffff-", out)); - - EXPECT_FALSE(cc::hexStringToUuid("ffffffff\0-ffff-ffff-ffff-ffffffffffff", out)); - EXPECT_FALSE(cc::hexStringToUuid("gfffffff-ffff-ffff-ffff-ffffffffffff", out)); - - EXPECT_FALSE(cc::hexStringToUuid("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF", out)); - - EXPECT_FALSE(cc::hexStringToUuid("Hey, what's up?", out)); - - UuidArray allZeros = {}; - EXPECT_EQ(out, allZeros); -} - -TEST(CacheCreatorTest, FullUuidRoundtrip) { - UuidArray uuid = {16, 2, 104, 108, 0, 3, 0, 0, 213, 232, 11, 199, 227, 23, 129, 116}; - cc::UuidString hexStr = cc::uuidToHexString(uuid); - EXPECT_EQ(hexStr, "1002686c-0003-0000-d5e8-0bc7e3178174"); - - UuidArray dumped = {}; - EXPECT_TRUE(cc::hexStringToUuid(hexStr, dumped)); - EXPECT_EQ(dumped, uuid); -} - -TEST(CacheCreatorTest, GetCacheInfoFromInvalidPalMetadataBlob) { - char badMetadata[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - llvm::StringRef noteBlob(badMetadata, sizeof(badMetadata)); - llvm::Expected cacheInfoOrErr = cc::getCacheInfoFromMetadataBlob(noteBlob); - EXPECT_THAT_EXPECTED(cacheInfoOrErr, Failed()); -} - -TEST(CacheCreatorTest, GetCacheInfoFromValidPalMetadataBlob) { - const char *sampleMetadata = R"(--- -amdpal.pipelines: - - .xgl_cache_info: - .128_bit_cache_hash: - - 17226562260713912943 - - 15513868906143827149 - .llpc_version: !str '46.1' -... -)"; - - llvm::msgpack::Document document; - const bool parsingSucceeded = document.fromYAML(sampleMetadata); - ASSERT_TRUE(parsingSucceeded) << "Failed to parse sample metadata"; - std::string noteBlob; - document.writeToBlob(noteBlob); - - llvm::Expected cacheInfoOrErr = cc::getCacheInfoFromMetadataBlob(noteBlob); - ASSERT_THAT_EXPECTED(cacheInfoOrErr, Succeeded()); - - cc::ElfLlpcCacheInfo &elfLlpcInfo = *cacheInfoOrErr; - EXPECT_EQ(elfLlpcInfo.cacheHash.qwords[0], 17226562260713912943u); - EXPECT_EQ(elfLlpcInfo.cacheHash.qwords[1], 15513868906143827149u); - EXPECT_EQ(elfLlpcInfo.llpcVersion.getMajor(), 46u); - ASSERT_TRUE(elfLlpcInfo.llpcVersion.getMinor().has_value()); - EXPECT_EQ(*elfLlpcInfo.llpcVersion.getMinor(), 1u); -} - -} // namespace diff --git a/tools/cache_creator/unittests/cache_info_tests.cpp b/tools/cache_creator/unittests/cache_info_tests.cpp deleted file mode 100644 index 80a79f0b..00000000 --- a/tools/cache_creator/unittests/cache_info_tests.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - *********************************************************************************************************************** - * - * Copyright (c) 2021 Google LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - **********************************************************************************************************************/ -#include "cache_creator.h" -#include "cache_info.h" -#include "include/binary_cache_serialization.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MD5.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Testing/Support/Error.h" -#include "gmock/gmock.h" -#include -#include -#include -#include - -namespace { - -using llvm::Failed; -using llvm::FailedWithMessage; -using llvm::Succeeded; - -using ::testing::HasSubstr; - -TEST(CacheInfoTest, EmptyCacheBlob) { - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef{}, "empty", false); - assert(blobPtr); - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - EXPECT_THAT_EXPECTED(blobInfoOrErr, Failed()); -} - -TEST(CacheInfoTest, LargeZeroBlob) { - llvm::SmallVector zeros(512u); - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::toStringRef(zeros), "zeros", false); - assert(blobPtr); - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - ASSERT_THAT_EXPECTED(blobInfoOrErr, Succeeded()); - - // This should fail as the self-declared header length is 0. - auto publicHeaderInfoOrErr = blobInfoOrErr->readPublicVkHeaderInfo(); - EXPECT_THAT_EXPECTED(publicHeaderInfoOrErr, Failed()); - - // This should fail as the self-declared header length is 0. - auto privateHeaderOffsetOrErr = blobInfoOrErr->getPrivateHeaderOffset(); - EXPECT_THAT_EXPECTED(privateHeaderOffsetOrErr, Failed()); -} - -TEST(CacheInfoTest, PublicHeaderOnly) { - vk::PipelineCacheHeaderData publicHeader = {}; - publicHeader.headerLength = sizeof(publicHeader); - auto blobPtr = llvm::MemoryBuffer::getMemBuffer( - llvm::StringRef(reinterpret_cast(&publicHeader), sizeof(publicHeader)), "public_header", false); - assert(blobPtr); - - // These should fail as the blob is not big enough to contain both a public and a private header. - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - EXPECT_THAT_EXPECTED(blobInfoOrErr, Failed()); -} - -TEST(CacheInfoTest, PublicHeaderLengthTooLong) { - llvm::SmallVector buffer(vk::VkPipelineCacheHeaderDataSize + sizeof(vk::PipelineBinaryCachePrivateHeader)); - auto *publicHeader = new (buffer.data()) vk::PipelineCacheHeaderData(); - publicHeader->headerLength = vk::VkPipelineCacheHeaderDataSize + 1; - - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::toStringRef(buffer), "public_header_len", false); - assert(blobPtr); - - // This should succeed because we don't parse the public header at this point and don't know the public header length. - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - ASSERT_THAT_EXPECTED(blobInfoOrErr, Succeeded()); - - // This should succeed as the public header can be fully parsed. - auto publicHeaderInfoOrErr = blobInfoOrErr->readPublicVkHeaderInfo(); - ASSERT_THAT_EXPECTED(publicHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(publicHeaderInfoOrErr->publicHeader, publicHeader); - EXPECT_EQ(publicHeaderInfoOrErr->trailingSpaceBeforePrivateBlob, 1u); - - // This should fail as the self-declared header length is too long to fit the private header. - auto privateHeaderOffsetOrErr = blobInfoOrErr->getPrivateHeaderOffset(); - EXPECT_THAT_EXPECTED(privateHeaderOffsetOrErr, Failed()); - - // This should fail as the self-declared header length is too long to fit the private header. - auto privateHeaderInfoOrErr = blobInfoOrErr->readBinaryCachePrivateHeaderInfo(); - EXPECT_THAT_EXPECTED(privateHeaderInfoOrErr, Failed()); -} - -TEST(CacheInfoTest, PrivateBlobWrongVendorId) { - llvm::SmallVector buffer(vk::VkPipelineCacheHeaderDataSize + sizeof(vk::PipelineBinaryCachePrivateHeader)); - auto *publicHeader = new (buffer.data()) vk::PipelineCacheHeaderData(); - publicHeader->vendorID = 0x14u; - publicHeader->headerLength = vk::VkPipelineCacheHeaderDataSize; - - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::toStringRef(buffer), "wrong_vendor_id", false); - assert(blobPtr); - - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - ASSERT_THAT_EXPECTED(blobInfoOrErr, Succeeded()); - - auto publicHeaderInfoOrErr = blobInfoOrErr->readPublicVkHeaderInfo(); - ASSERT_THAT_EXPECTED(publicHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(publicHeaderInfoOrErr->publicHeader, publicHeader); - EXPECT_EQ(publicHeaderInfoOrErr->trailingSpaceBeforePrivateBlob, 0u); - - auto privateHeaderOffsetOrErr = blobInfoOrErr->getPrivateHeaderOffset(); - EXPECT_THAT_EXPECTED(privateHeaderOffsetOrErr, FailedWithMessage(HasSubstr("Vendor is not AMD"))); -} - -TEST(CacheInfoTest, ValidBlobNoEntries) { - llvm::SmallVector buffer(vk::VkPipelineCacheHeaderDataSize + sizeof(vk::PipelineBinaryCachePrivateHeader)); - auto *publicHeader = new (buffer.data()) vk::PipelineCacheHeaderData(); - publicHeader->vendorID = cc::AMDVendorId; - publicHeader->headerLength = vk::VkPipelineCacheHeaderDataSize; - auto *privateHeader = new (buffer.data() + vk::VkPipelineCacheHeaderDataSize) vk::PipelineBinaryCachePrivateHeader(); - - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::toStringRef(buffer), "valid_no_entries", false); - assert(blobPtr); - - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - ASSERT_THAT_EXPECTED(blobInfoOrErr, Succeeded()); - - // These should succeed as both headers can be fully parsed. - auto publicHeaderInfoOrErr = blobInfoOrErr->readPublicVkHeaderInfo(); - ASSERT_THAT_EXPECTED(publicHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(publicHeaderInfoOrErr->publicHeader, publicHeader); - EXPECT_EQ(publicHeaderInfoOrErr->trailingSpaceBeforePrivateBlob, 0u); - - auto privateHeaderOffsetOrErr = blobInfoOrErr->getPrivateHeaderOffset(); - ASSERT_THAT_EXPECTED(privateHeaderOffsetOrErr, Succeeded()); - EXPECT_EQ(*privateHeaderOffsetOrErr, vk::VkPipelineCacheHeaderDataSize); - - auto privateHeaderInfoOrErr = blobInfoOrErr->readBinaryCachePrivateHeaderInfo(); - ASSERT_THAT_EXPECTED(privateHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(privateHeaderInfoOrErr->privateHeader, privateHeader); - EXPECT_EQ(privateHeaderInfoOrErr->contentBlobSize, 0u); - - auto contentOffsetOrErr = blobInfoOrErr->getCacheContentOffset(); - ASSERT_THAT_EXPECTED(contentOffsetOrErr, Succeeded()); - EXPECT_EQ(*contentOffsetOrErr, buffer.size()); - - // This should succeed as it is valid to have an empty cache content, i.e., zero entries. - llvm::SmallVector entries; - auto err = blobInfoOrErr->readBinaryCacheEntriesInfo(entries); - EXPECT_THAT_ERROR(std::move(err), Succeeded()); - EXPECT_TRUE(entries.empty()); -} - -cc::MD5DigestStr calculateMD5Sum(llvm::ArrayRef data) { - llvm::MD5 md5; - md5.update(data); - llvm::MD5::MD5Result result = {}; - md5.final(result); - return result.digest(); -} - -// ===================================================================================================================== -// Copies the contents of `value` to the buffer and returns the next position in the buffer. The caller must ensure that -// the buffer sufficiently large to fit `value`. -// -// @param value : Value to add to the buffer. -// @param [out] currData : Current position in the buffer. This does *not* have to be aligned to `alignof(T)`. -// @returns : Next position in the buffer. -template uint8_t *appendRawData(T value, uint8_t *currData) { - static_assert(std::is_standard_layout::value, "Incompatible type"); - assert(currData); - memcpy(currData, &value, sizeof(T)); // Use memcpy instead of reinterpret_cast to avoid unaligned writes. - return currData + sizeof(T); -} - -TEST(CacheInfoTest, ValidBlobOneEntry) { - const size_t trailingSpace = 16; - const size_t entrySize = sizeof(uint32_t); - const size_t bufferSize = vk::VkPipelineCacheHeaderDataSize + trailingSpace + - sizeof(vk::PipelineBinaryCachePrivateHeader) + sizeof(vk::BinaryCacheEntry) + entrySize; - std::vector buffer(bufferSize); - uint8_t *currData = buffer.data(); - - uint8_t *const publicHeader = currData; - vk::PipelineCacheHeaderData publicHeaderData = {}; - publicHeaderData.headerLength = vk::VkPipelineCacheHeaderDataSize + trailingSpace; - publicHeaderData.vendorID = cc::AMDVendorId; - currData = appendRawData(publicHeaderData, currData) + trailingSpace; - - uint8_t *const privateHeader = currData; - currData = appendRawData(vk::PipelineBinaryCachePrivateHeader{}, currData); - - uint8_t *const entryHeader = currData; - vk::BinaryCacheEntry cacheEntry = {}; - cacheEntry.dataSize = entrySize; - currData = appendRawData(cacheEntry, currData); - - const uint32_t content = 42; - uint8_t *entryContent = currData; - currData = appendRawData(content, currData); - llvm::ArrayRef entryBlob(entryContent, entrySize); - - EXPECT_EQ(currData, buffer.data() + bufferSize); - - auto blobPtr = llvm::MemoryBuffer::getMemBuffer(llvm::toStringRef(buffer), "valid_one_entry", false); - assert(blobPtr); - - auto blobInfoOrErr = cc::CacheBlobInfo::create(*blobPtr); - ASSERT_THAT_EXPECTED(blobInfoOrErr, Succeeded()); - - // These should all succeed as both headers can be fully parsed and there's one valid entry. - auto publicHeaderInfoOrErr = blobInfoOrErr->readPublicVkHeaderInfo(); - ASSERT_THAT_EXPECTED(publicHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(reinterpret_cast(publicHeaderInfoOrErr->publicHeader), publicHeader); - EXPECT_EQ(publicHeaderInfoOrErr->publicHeader->headerLength, publicHeaderData.headerLength); - EXPECT_EQ(publicHeaderInfoOrErr->trailingSpaceBeforePrivateBlob, trailingSpace); - - auto privateHeaderInfoOrErr = blobInfoOrErr->readBinaryCachePrivateHeaderInfo(); - ASSERT_THAT_EXPECTED(privateHeaderInfoOrErr, Succeeded()); - EXPECT_EQ(reinterpret_cast(privateHeaderInfoOrErr->privateHeader), privateHeader); - EXPECT_EQ(privateHeaderInfoOrErr->contentBlobSize, sizeof(vk::BinaryCacheEntry) + entrySize); - - llvm::SmallVector entries; - auto err = blobInfoOrErr->readBinaryCacheEntriesInfo(entries); - ASSERT_THAT_ERROR(std::move(err), Succeeded()); - EXPECT_EQ(entries.size(), 1u); - - cc::BinaryCacheEntryInfo &entry = entries.front(); - EXPECT_EQ(entry.entryHeader, entryHeader); - EXPECT_EQ(entry.entryHeaderData.dataSize, cacheEntry.dataSize); - EXPECT_EQ(entry.idx, 0u); - EXPECT_EQ(entry.entryBlob.data(), entryBlob.data()); - EXPECT_EQ(entry.entryBlob.size(), entryBlob.size()); - EXPECT_EQ(entry.entryMD5Sum, calculateMD5Sum(entryBlob)); -} - -} // namespace diff --git a/tools/cache_creator/unittests/lit.cfg.py b/tools/cache_creator/unittests/lit.cfg.py deleted file mode 100644 index b341da45..00000000 --- a/tools/cache_creator/unittests/lit.cfg.py +++ /dev/null @@ -1,60 +0,0 @@ -## - ####################################################################################################################### - # - # Copyright (c) 2021 Google LLC. All Rights Reserved. - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - # - ####################################################################################################################### - -# Configuration file for the 'lit' test runner for llpc unit tests. Based on the MLIR unit test config. -import os - -import lit.formats - -# name: The name of this test suite. -config.name = 'CacheCreator_Unit' - -# suffixes: A list of file extensions to treat as test files. -config.suffixes = [] - -# test_source_root: The root path where tests are located. -# test_exec_root: The root path where tests should be run. -config.test_exec_root = config.cache_creator_unit_test_binary_dir -config.test_source_root = config.test_exec_root - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') - -# Propagate the temp directory. Windows requires this because it uses \Windows\ -# if none of these are present. -if 'TMP' in os.environ: - config.environment['TMP'] = os.environ['TMP'] -if 'TEMP' in os.environ: - config.environment['TEMP'] = os.environ['TEMP'] - -# Propagate HOME as it can be used to override incorrect homedir in passwd -# that causes the tests to fail. -if 'HOME' in os.environ: - config.environment['HOME'] = os.environ['HOME'] - -# Propagate path to symbolizer for ASan/MSan. -for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']: - if symbolizer in os.environ: - config.environment[symbolizer] = os.environ[symbolizer] diff --git a/tools/cache_creator/unittests/lit.site.cfg.py.in b/tools/cache_creator/unittests/lit.site.cfg.py.in deleted file mode 100644 index 82116305..00000000 --- a/tools/cache_creator/unittests/lit.site.cfg.py.in +++ /dev/null @@ -1,22 +0,0 @@ -@LIT_SITE_CFG_IN_HEADER@ - -import sys - -config.llvm_src_root = "@LLVM_BUILD_MAIN_SRC_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.cache_creator_unit_test_binary_dir = "@XGL_CACHE_CREATOR_UNIT_TEST_BINARY_DIR@" - -# Support substitution of the tools and libs dirs with user parameters. This is -# used when we can't determine the tool dir at configuration time. -try: - config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params - config.llvm_build_mode = config.llvm_build_mode % lit_config.params -except KeyError: - e = sys.exc_info()[1] - key, = e.args - lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) - -# Let the main config do the real work. -lit_config.load_config(config, "@XGL_CACHE_CREATOR_UNIT_TEST_SOURCE_DIR@/lit.cfg.py")