mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
synced 2024-11-05 04:10:06 +00:00
parent
b03df2880c
commit
1b0bd18053
26
.gitignore
vendored
26
.gitignore
vendored
@ -1,13 +1,13 @@
|
||||
/bin/*
|
||||
|
||||
/build/*
|
||||
!/build/src/
|
||||
/build/src/*
|
||||
!/build/src/Release/
|
||||
/build/src/Release/*
|
||||
!/build/src/Release/VmaSample.exe
|
||||
!/build/src/VmaReplay/
|
||||
/build/src/VmaReplay/*
|
||||
!/build/src/VmaReplay/Release/
|
||||
/build/src/VmaReplay/Release/*
|
||||
!/build/src/VmaReplay/Release/VmaReplay.exe
|
||||
/bin/*
|
||||
|
||||
/build/*
|
||||
!/build/src/
|
||||
/build/src/*
|
||||
!/build/src/Release/
|
||||
/build/src/Release/*
|
||||
!/build/src/Release/VmaSample.exe
|
||||
!/build/src/VmaReplay/
|
||||
/build/src/VmaReplay/*
|
||||
!/build/src/VmaReplay/Release/
|
||||
/build/src/VmaReplay/Release/*
|
||||
!/build/src/VmaReplay/Release/VmaReplay.exe
|
||||
|
74
.travis.yml
74
.travis.yml
@ -1,37 +1,37 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
before_script:
|
||||
- sudo apt-get install
|
||||
- eval "${MATRIX_EVAL}"
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y libassimp-dev libglm-dev graphviz libxcb-dri3-0 libxcb-present0 libpciaccess0 cmake libpng-dev libxcb-dri3-dev libx11-dev libx11-xcb-dev libmirclient-dev libwayland-dev libxrandr-dev
|
||||
- export VK_VERSION=1.2.131.1
|
||||
- wget -O vulkansdk-linux-x86_64-$VK_VERSION.tar.gz https://sdk.lunarg.com/sdk/download/$VK_VERSION/linux/vulkansdk-linux-x86_64-$VK_VERSION.tar.gz?Human=true
|
||||
- tar zxf vulkansdk-linux-x86_64-$VK_VERSION.tar.gz
|
||||
- export VULKAN_SDK=$TRAVIS_BUILD_DIR/$VK_VERSION/x86_64
|
||||
|
||||
script:
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- adam.sawicki@amd.com
|
||||
on_success: change
|
||||
on_failure: always
|
||||
language: cpp
|
||||
sudo: required
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
before_script:
|
||||
- sudo apt-get install
|
||||
- eval "${MATRIX_EVAL}"
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y libassimp-dev libglm-dev graphviz libxcb-dri3-0 libxcb-present0 libpciaccess0 cmake libpng-dev libxcb-dri3-dev libx11-dev libx11-xcb-dev libmirclient-dev libwayland-dev libxrandr-dev
|
||||
- export VK_VERSION=1.2.131.1
|
||||
- wget -O vulkansdk-linux-x86_64-$VK_VERSION.tar.gz https://sdk.lunarg.com/sdk/download/$VK_VERSION/linux/vulkansdk-linux-x86_64-$VK_VERSION.tar.gz?Human=true
|
||||
- tar zxf vulkansdk-linux-x86_64-$VK_VERSION.tar.gz
|
||||
- export VULKAN_SDK=$TRAVIS_BUILD_DIR/$VK_VERSION/x86_64
|
||||
|
||||
script:
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- adam.sawicki@amd.com
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
246
CHANGELOG.md
246
CHANGELOG.md
@ -1,123 +1,123 @@
|
||||
# 2.3.0 (2019-12-04)
|
||||
|
||||
Major release after a year of development in "master" branch and feature branches. Notable new features: supporting Vulkan 1.1, supporting query for memory budget.
|
||||
|
||||
Major changes:
|
||||
|
||||
- Added support for Vulkan 1.1.
|
||||
- Added member `VmaAllocatorCreateInfo::vulkanApiVersion`.
|
||||
- When Vulkan 1.1 is used, there is no need to enable VK_KHR_dedicated_allocation or VK_KHR_bind_memory2 extensions, as they are promoted to Vulkan itself.
|
||||
- Added support for query for memory budget and staying within the budget.
|
||||
- Added function `vmaGetBudget`, structure `VmaBudget`. This can also serve as simple statistics, more efficient than `vmaCalculateStats`.
|
||||
- By default the budget it is estimated based on memory heap sizes. It may be queried from the system using VK_EXT_memory_budget extension if you use `VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT` flag and `VmaAllocatorCreateInfo::instance` member.
|
||||
- Added flag `VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT` that fails an allocation if it would exceed the budget.
|
||||
- Added new memory usage options:
|
||||
- `VMA_MEMORY_USAGE_CPU_COPY` for memory that is preferably not `DEVICE_LOCAL` but not guaranteed to be `HOST_VISIBLE`.
|
||||
- `VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED` for memory that is `LAZILY_ALLOCATED`.
|
||||
- Added support for VK_KHR_bind_memory2 extension:
|
||||
- Added `VMA_ALLOCATION_CREATE_DONT_BIND_BIT` flag that lets you create both buffer/image and allocation, but don't bind them together.
|
||||
- Added flag `VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT`, functions `vmaBindBufferMemory2`, `vmaBindImageMemory2` that let you specify additional local offset and `pNext` pointer while binding.
|
||||
- Added functions `vmaSetPoolName`, `vmaGetPoolName` that let you assign string names to custom pools. JSON dump file format and VmaDumpVis tool is updated to show these names.
|
||||
- Defragmentation is legal only on buffers and images in `VK_IMAGE_TILING_LINEAR`. This is due to the way it is currently implemented in the library and the restrictions of the Vulkan specification. Clarified documentation in this regard. See discussion in #59.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Made `vmaResizeAllocation` function deprecated, always returning failure.
|
||||
- Made changes in the internal algorithm for the choice of memory type. Be careful! You may now get a type that is not `HOST_VISIBLE` or `HOST_COHERENT` if it's not stated as always ensured by some `VMA_MEMORY_USAGE_*` flag.
|
||||
- Extended VmaReplay application with more detailed statistics printed at the end.
|
||||
- Added macros `VMA_CALL_PRE`, `VMA_CALL_POST` that let you decorate declarations of all library functions if you want to e.g. export/import them as dynamically linked library.
|
||||
- Optimized `VmaAllocation` objects to be allocated out of an internal free-list allocator. This makes allocation and deallocation causing 0 dynamic CPU heap allocations on average.
|
||||
- Updated recording CSV file format version to 1.8, to support new functions.
|
||||
- Many additions and fixes in documentation. Many compatibility fixes for various compilers and platforms. Other internal bugfixes, optimizations, updates, refactoring...
|
||||
|
||||
# 2.2.0 (2018-12-13)
|
||||
|
||||
Major release after many months of development in "master" branch and feature branches. Notable new features: defragmentation of GPU memory, buddy algorithm, convenience functions for sparse binding.
|
||||
|
||||
Major changes:
|
||||
|
||||
- New, more powerful defragmentation:
|
||||
- Added structure `VmaDefragmentationInfo2`, functions `vmaDefragmentationBegin`, `vmaDefragmentationEnd`.
|
||||
- Added support for defragmentation of GPU memory.
|
||||
- Defragmentation of CPU memory now uses `memmove`, so it can move data to overlapping regions.
|
||||
- Defragmentation of CPU memory is now available for memory types that are `HOST_VISIBLE` but not `HOST_COHERENT`.
|
||||
- Added structure member `VmaVulkanFunctions::vkCmdCopyBuffer`.
|
||||
- Major internal changes in defragmentation algorithm.
|
||||
- VmaReplay: added parameters: `--DefragmentAfterLine`, `--DefragmentationFlags`.
|
||||
- Old interface (structure `VmaDefragmentationInfo`, function `vmaDefragment`) is now deprecated.
|
||||
- Added buddy algorithm, available for custom pools - flag `VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT`.
|
||||
- Added convenience functions for multiple allocations and deallocations at once, intended for sparse binding resources - functions `vmaAllocateMemoryPages`, `vmaFreeMemoryPages`.
|
||||
- Added function that tries to resize existing allocation in place: `vmaResizeAllocation`.
|
||||
- Added flags for allocation strategy: `VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT`, and their aliases: `VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT`.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Changed behavior of allocation functions to return `VK_ERROR_VALIDATION_FAILED_EXT` when trying to allocate memory of size 0, create buffer with size 0, or image with one of the dimensions 0.
|
||||
- VmaReplay: Added support for Windows end of lines.
|
||||
- Updated recording CSV file format version to 1.5, to support new functions.
|
||||
- Internal optimization: using read-write mutex on some platforms.
|
||||
- Many additions and fixes in documentation. Many compatibility fixes for various compilers. Other internal bugfixes, optimizations, refactoring, added more internal validation...
|
||||
|
||||
# 2.1.0 (2018-09-10)
|
||||
|
||||
Minor bugfixes.
|
||||
|
||||
# 2.1.0-beta.1 (2018-08-27)
|
||||
|
||||
Major release after many months of development in "development" branch and features branches. Many new features added, some bugs fixed. API stays backward-compatible.
|
||||
|
||||
Major changes:
|
||||
|
||||
- Added linear allocation algorithm, accessible for custom pools, that can be used as free-at-once, stack, double stack, or ring buffer. See "Linear allocation algorithm" documentation chapter.
|
||||
- Added `VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT`, `VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT`.
|
||||
- Added feature to record sequence of calls to the library to a file and replay it using dedicated application. See documentation chapter "Record and replay".
|
||||
- Recording: added `VmaAllocatorCreateInfo::pRecordSettings`.
|
||||
- Replaying: added VmaReplay project.
|
||||
- Recording file format: added document "docs/Recording file format.md".
|
||||
- Improved support for non-coherent memory.
|
||||
- Added functions: `vmaFlushAllocation`, `vmaInvalidateAllocation`.
|
||||
- `nonCoherentAtomSize` is now respected automatically.
|
||||
- Added `VmaVulkanFunctions::vkFlushMappedMemoryRanges`, `vkInvalidateMappedMemoryRanges`.
|
||||
- Improved debug features related to detecting incorrect mapped memory usage. See documentation chapter "Debugging incorrect memory usage".
|
||||
- Added debug macro `VMA_DEBUG_DETECT_CORRUPTION`, functions `vmaCheckCorruption`, `vmaCheckPoolCorruption`.
|
||||
- Added debug macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to initialize contents of allocations with a bit pattern.
|
||||
- Changed behavior of `VMA_DEBUG_MARGIN` macro - it now adds margin also before first and after last allocation in a block.
|
||||
- Changed format of JSON dump returned by `vmaBuildStatsString` (not backward compatible!).
|
||||
- Custom pools and memory blocks now have IDs that don't change after sorting.
|
||||
- Added properties: "CreationFrameIndex", "LastUseFrameIndex", "Usage".
|
||||
- Changed VmaDumpVis tool to use these new properties for better coloring.
|
||||
- Changed behavior of `vmaGetAllocationInfo` and `vmaTouchAllocation` to update `allocation.lastUseFrameIndex` even if allocation cannot become lost.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Changes in custom pools:
|
||||
- Added new structure member `VmaPoolStats::blockCount`.
|
||||
- Changed behavior of `VmaPoolCreateInfo::blockSize` = 0 (default) - it now means that pool may use variable block sizes, just like default pools do.
|
||||
- Improved logic of `vmaFindMemoryTypeIndex` for some cases, especially integrated GPUs.
|
||||
- VulkanSample application: Removed dependency on external library MathFu. Added own vector and matrix structures.
|
||||
- Changes that improve compatibility with various platforms, including: Visual Studio 2012, 32-bit code, C compilers.
|
||||
- Changed usage of "VK_KHR_dedicated_allocation" extension in the code to be optional, driven by macro `VMA_DEDICATED_ALLOCATION`, for compatibility with Android.
|
||||
- Many additions and fixes in documentation, including description of new features, as well as "Validation layer warnings".
|
||||
- Other bugfixes.
|
||||
|
||||
# 2.0.0 (2018-03-19)
|
||||
|
||||
A major release with many compatibility-breaking changes.
|
||||
|
||||
Notable new features:
|
||||
|
||||
- Introduction of `VmaAllocation` handle that you must retrieve from allocation functions and pass to deallocation functions next to normal `VkBuffer` and `VkImage`.
|
||||
- Introduction of `VmaAllocationInfo` structure that you can retrieve from `VmaAllocation` handle to access parameters of the allocation (like `VkDeviceMemory` and offset) instead of retrieving them directly from allocation functions.
|
||||
- Support for reference-counted mapping and persistently mapped allocations - see `vmaMapMemory`, `VMA_ALLOCATION_CREATE_MAPPED_BIT`.
|
||||
- Support for custom memory pools - see `VmaPool` handle, `VmaPoolCreateInfo` structure, `vmaCreatePool` function.
|
||||
- Support for defragmentation (compaction) of allocations - see function `vmaDefragment` and related structures.
|
||||
- Support for "lost allocations" - see appropriate chapter on documentation Main Page.
|
||||
|
||||
# 1.0.1 (2017-07-04)
|
||||
|
||||
- Fixes for Linux GCC compilation.
|
||||
- Changed "CONFIGURATION SECTION" to contain #ifndef so you can define these macros before including this header, not necessarily change them in the file.
|
||||
|
||||
# 1.0.0 (2017-06-16)
|
||||
|
||||
First public release.
|
||||
# 2.3.0 (2019-12-04)
|
||||
|
||||
Major release after a year of development in "master" branch and feature branches. Notable new features: supporting Vulkan 1.1, supporting query for memory budget.
|
||||
|
||||
Major changes:
|
||||
|
||||
- Added support for Vulkan 1.1.
|
||||
- Added member `VmaAllocatorCreateInfo::vulkanApiVersion`.
|
||||
- When Vulkan 1.1 is used, there is no need to enable VK_KHR_dedicated_allocation or VK_KHR_bind_memory2 extensions, as they are promoted to Vulkan itself.
|
||||
- Added support for query for memory budget and staying within the budget.
|
||||
- Added function `vmaGetBudget`, structure `VmaBudget`. This can also serve as simple statistics, more efficient than `vmaCalculateStats`.
|
||||
- By default the budget it is estimated based on memory heap sizes. It may be queried from the system using VK_EXT_memory_budget extension if you use `VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT` flag and `VmaAllocatorCreateInfo::instance` member.
|
||||
- Added flag `VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT` that fails an allocation if it would exceed the budget.
|
||||
- Added new memory usage options:
|
||||
- `VMA_MEMORY_USAGE_CPU_COPY` for memory that is preferably not `DEVICE_LOCAL` but not guaranteed to be `HOST_VISIBLE`.
|
||||
- `VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED` for memory that is `LAZILY_ALLOCATED`.
|
||||
- Added support for VK_KHR_bind_memory2 extension:
|
||||
- Added `VMA_ALLOCATION_CREATE_DONT_BIND_BIT` flag that lets you create both buffer/image and allocation, but don't bind them together.
|
||||
- Added flag `VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT`, functions `vmaBindBufferMemory2`, `vmaBindImageMemory2` that let you specify additional local offset and `pNext` pointer while binding.
|
||||
- Added functions `vmaSetPoolName`, `vmaGetPoolName` that let you assign string names to custom pools. JSON dump file format and VmaDumpVis tool is updated to show these names.
|
||||
- Defragmentation is legal only on buffers and images in `VK_IMAGE_TILING_LINEAR`. This is due to the way it is currently implemented in the library and the restrictions of the Vulkan specification. Clarified documentation in this regard. See discussion in #59.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Made `vmaResizeAllocation` function deprecated, always returning failure.
|
||||
- Made changes in the internal algorithm for the choice of memory type. Be careful! You may now get a type that is not `HOST_VISIBLE` or `HOST_COHERENT` if it's not stated as always ensured by some `VMA_MEMORY_USAGE_*` flag.
|
||||
- Extended VmaReplay application with more detailed statistics printed at the end.
|
||||
- Added macros `VMA_CALL_PRE`, `VMA_CALL_POST` that let you decorate declarations of all library functions if you want to e.g. export/import them as dynamically linked library.
|
||||
- Optimized `VmaAllocation` objects to be allocated out of an internal free-list allocator. This makes allocation and deallocation causing 0 dynamic CPU heap allocations on average.
|
||||
- Updated recording CSV file format version to 1.8, to support new functions.
|
||||
- Many additions and fixes in documentation. Many compatibility fixes for various compilers and platforms. Other internal bugfixes, optimizations, updates, refactoring...
|
||||
|
||||
# 2.2.0 (2018-12-13)
|
||||
|
||||
Major release after many months of development in "master" branch and feature branches. Notable new features: defragmentation of GPU memory, buddy algorithm, convenience functions for sparse binding.
|
||||
|
||||
Major changes:
|
||||
|
||||
- New, more powerful defragmentation:
|
||||
- Added structure `VmaDefragmentationInfo2`, functions `vmaDefragmentationBegin`, `vmaDefragmentationEnd`.
|
||||
- Added support for defragmentation of GPU memory.
|
||||
- Defragmentation of CPU memory now uses `memmove`, so it can move data to overlapping regions.
|
||||
- Defragmentation of CPU memory is now available for memory types that are `HOST_VISIBLE` but not `HOST_COHERENT`.
|
||||
- Added structure member `VmaVulkanFunctions::vkCmdCopyBuffer`.
|
||||
- Major internal changes in defragmentation algorithm.
|
||||
- VmaReplay: added parameters: `--DefragmentAfterLine`, `--DefragmentationFlags`.
|
||||
- Old interface (structure `VmaDefragmentationInfo`, function `vmaDefragment`) is now deprecated.
|
||||
- Added buddy algorithm, available for custom pools - flag `VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT`.
|
||||
- Added convenience functions for multiple allocations and deallocations at once, intended for sparse binding resources - functions `vmaAllocateMemoryPages`, `vmaFreeMemoryPages`.
|
||||
- Added function that tries to resize existing allocation in place: `vmaResizeAllocation`.
|
||||
- Added flags for allocation strategy: `VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT`, and their aliases: `VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT`, `VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT`.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Changed behavior of allocation functions to return `VK_ERROR_VALIDATION_FAILED_EXT` when trying to allocate memory of size 0, create buffer with size 0, or image with one of the dimensions 0.
|
||||
- VmaReplay: Added support for Windows end of lines.
|
||||
- Updated recording CSV file format version to 1.5, to support new functions.
|
||||
- Internal optimization: using read-write mutex on some platforms.
|
||||
- Many additions and fixes in documentation. Many compatibility fixes for various compilers. Other internal bugfixes, optimizations, refactoring, added more internal validation...
|
||||
|
||||
# 2.1.0 (2018-09-10)
|
||||
|
||||
Minor bugfixes.
|
||||
|
||||
# 2.1.0-beta.1 (2018-08-27)
|
||||
|
||||
Major release after many months of development in "development" branch and features branches. Many new features added, some bugs fixed. API stays backward-compatible.
|
||||
|
||||
Major changes:
|
||||
|
||||
- Added linear allocation algorithm, accessible for custom pools, that can be used as free-at-once, stack, double stack, or ring buffer. See "Linear allocation algorithm" documentation chapter.
|
||||
- Added `VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT`, `VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT`.
|
||||
- Added feature to record sequence of calls to the library to a file and replay it using dedicated application. See documentation chapter "Record and replay".
|
||||
- Recording: added `VmaAllocatorCreateInfo::pRecordSettings`.
|
||||
- Replaying: added VmaReplay project.
|
||||
- Recording file format: added document "docs/Recording file format.md".
|
||||
- Improved support for non-coherent memory.
|
||||
- Added functions: `vmaFlushAllocation`, `vmaInvalidateAllocation`.
|
||||
- `nonCoherentAtomSize` is now respected automatically.
|
||||
- Added `VmaVulkanFunctions::vkFlushMappedMemoryRanges`, `vkInvalidateMappedMemoryRanges`.
|
||||
- Improved debug features related to detecting incorrect mapped memory usage. See documentation chapter "Debugging incorrect memory usage".
|
||||
- Added debug macro `VMA_DEBUG_DETECT_CORRUPTION`, functions `vmaCheckCorruption`, `vmaCheckPoolCorruption`.
|
||||
- Added debug macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to initialize contents of allocations with a bit pattern.
|
||||
- Changed behavior of `VMA_DEBUG_MARGIN` macro - it now adds margin also before first and after last allocation in a block.
|
||||
- Changed format of JSON dump returned by `vmaBuildStatsString` (not backward compatible!).
|
||||
- Custom pools and memory blocks now have IDs that don't change after sorting.
|
||||
- Added properties: "CreationFrameIndex", "LastUseFrameIndex", "Usage".
|
||||
- Changed VmaDumpVis tool to use these new properties for better coloring.
|
||||
- Changed behavior of `vmaGetAllocationInfo` and `vmaTouchAllocation` to update `allocation.lastUseFrameIndex` even if allocation cannot become lost.
|
||||
|
||||
Minor changes:
|
||||
|
||||
- Changes in custom pools:
|
||||
- Added new structure member `VmaPoolStats::blockCount`.
|
||||
- Changed behavior of `VmaPoolCreateInfo::blockSize` = 0 (default) - it now means that pool may use variable block sizes, just like default pools do.
|
||||
- Improved logic of `vmaFindMemoryTypeIndex` for some cases, especially integrated GPUs.
|
||||
- VulkanSample application: Removed dependency on external library MathFu. Added own vector and matrix structures.
|
||||
- Changes that improve compatibility with various platforms, including: Visual Studio 2012, 32-bit code, C compilers.
|
||||
- Changed usage of "VK_KHR_dedicated_allocation" extension in the code to be optional, driven by macro `VMA_DEDICATED_ALLOCATION`, for compatibility with Android.
|
||||
- Many additions and fixes in documentation, including description of new features, as well as "Validation layer warnings".
|
||||
- Other bugfixes.
|
||||
|
||||
# 2.0.0 (2018-03-19)
|
||||
|
||||
A major release with many compatibility-breaking changes.
|
||||
|
||||
Notable new features:
|
||||
|
||||
- Introduction of `VmaAllocation` handle that you must retrieve from allocation functions and pass to deallocation functions next to normal `VkBuffer` and `VkImage`.
|
||||
- Introduction of `VmaAllocationInfo` structure that you can retrieve from `VmaAllocation` handle to access parameters of the allocation (like `VkDeviceMemory` and offset) instead of retrieving them directly from allocation functions.
|
||||
- Support for reference-counted mapping and persistently mapped allocations - see `vmaMapMemory`, `VMA_ALLOCATION_CREATE_MAPPED_BIT`.
|
||||
- Support for custom memory pools - see `VmaPool` handle, `VmaPoolCreateInfo` structure, `vmaCreatePool` function.
|
||||
- Support for defragmentation (compaction) of allocations - see function `vmaDefragment` and related structures.
|
||||
- Support for "lost allocations" - see appropriate chapter on documentation Main Page.
|
||||
|
||||
# 1.0.1 (2017-07-04)
|
||||
|
||||
- Fixes for Linux GCC compilation.
|
||||
- Changed "CONFIGURATION SECTION" to contain #ifndef so you can define these macros before including this header, not necessarily change them in the file.
|
||||
|
||||
# 1.0.0 (2017-06-16)
|
||||
|
||||
First public release.
|
||||
|
@ -1,5 +1,6 @@
|
||||
root = true
|
||||
|
||||
[**.{cpp,h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
root = true
|
||||
|
||||
[**.{cpp,h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
|
656
src/Common.cpp
656
src/Common.cpp
@ -1,328 +1,328 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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 "Common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void ReadFile(std::vector<char>& out, const char* fileName)
|
||||
{
|
||||
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
|
||||
assert(file.is_open());
|
||||
size_t fileSize = (size_t)file.tellg();
|
||||
if(fileSize > 0)
|
||||
{
|
||||
out.resize(fileSize);
|
||||
file.seekg(0);
|
||||
file.read(out.data(), fileSize);
|
||||
}
|
||||
else
|
||||
out.clear();
|
||||
}
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color)
|
||||
{
|
||||
WORD attr = 0;
|
||||
switch(color)
|
||||
{
|
||||
case CONSOLE_COLOR::INFO:
|
||||
attr = FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CONSOLE_COLOR::NORMAL:
|
||||
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
break;
|
||||
case CONSOLE_COLOR::WARNING:
|
||||
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CONSOLE_COLOR::ERROR_:
|
||||
attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
SetConsoleTextAttribute(out, attr);
|
||||
}
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg)
|
||||
{
|
||||
if(color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(color);
|
||||
|
||||
printf("%s\n", msg);
|
||||
|
||||
if (color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(CONSOLE_COLOR::NORMAL);
|
||||
}
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg)
|
||||
{
|
||||
if(color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(color);
|
||||
|
||||
wprintf(L"%s\n", msg);
|
||||
|
||||
if (color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(CONSOLE_COLOR::NORMAL);
|
||||
}
|
||||
|
||||
static const size_t CONSOLE_SMALL_BUF_SIZE = 256;
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList)
|
||||
{
|
||||
size_t dstLen = (size_t)::_vscprintf(format, argList);
|
||||
if(dstLen)
|
||||
{
|
||||
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
|
||||
char smallBuf[CONSOLE_SMALL_BUF_SIZE];
|
||||
std::vector<char> bigBuf(useSmallBuf ? 0 : dstLen + 1);
|
||||
char* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
|
||||
::vsprintf_s(bufPtr, dstLen + 1, format, argList);
|
||||
PrintMessage(color, bufPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList)
|
||||
{
|
||||
size_t dstLen = (size_t)::_vcwprintf(format, argList);
|
||||
if(dstLen)
|
||||
{
|
||||
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
|
||||
wchar_t smallBuf[CONSOLE_SMALL_BUF_SIZE];
|
||||
std::vector<wchar_t> bigBuf(useSmallBuf ? 0 : dstLen + 1);
|
||||
wchar_t* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
|
||||
::vswprintf_s(bufPtr, dstLen + 1, format, argList);
|
||||
PrintMessage(color, bufPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(color, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(color, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintWarningF(const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintWarningF(const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintErrorF(const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintErrorF(const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize)
|
||||
{
|
||||
FILE* f = nullptr;
|
||||
_wfopen_s(&f, filePath, L"wb");
|
||||
if(f)
|
||||
{
|
||||
fwrite(data, 1, dataSize, f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
std::wstring SizeToStr(size_t size)
|
||||
{
|
||||
if(size == 0)
|
||||
return L"0";
|
||||
wchar_t result[32];
|
||||
double size2 = (double)size;
|
||||
if (size2 >= 1024.0*1024.0*1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f TB", size2 / (1024.0*1024.0*1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0*1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f GB", size2 / (1024.0*1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f MB", size2 / (1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f KB", size2 / 1024.0);
|
||||
}
|
||||
else
|
||||
swprintf_s(result, L"%llu B", size);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage)
|
||||
{
|
||||
if (s.empty())
|
||||
{
|
||||
outStr->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Phase 1 - Get buffer size.
|
||||
const int size = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), NULL, 0);
|
||||
if (size == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 2 - Do conversion.
|
||||
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
|
||||
int result = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), buf.get(), size);
|
||||
if (result == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
outStr->assign(buf.get(), (size_t)size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage)
|
||||
{
|
||||
if (sCharCount == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(sCharCount <= (size_t)INT_MAX);
|
||||
|
||||
// Phase 1 - Get buffer size.
|
||||
int size = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, NULL, 0);
|
||||
if (size == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 2 - Do conversion.
|
||||
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
|
||||
int result = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, buf.get(), size);
|
||||
if (result == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
outStr->assign(buf.get(), (size_t)size);
|
||||
return true;
|
||||
}
|
||||
|
||||
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type)
|
||||
{
|
||||
// Skipping common prefix VK_PHYSICAL_DEVICE_TYPE_
|
||||
static const wchar_t* const VALUES[] = {
|
||||
L"OTHER",
|
||||
L"INTEGRATED_GPU",
|
||||
L"DISCRETE_GPU",
|
||||
L"VIRTUAL_GPU",
|
||||
L"CPU",
|
||||
};
|
||||
return (uint32_t)type < _countof(VALUES) ? VALUES[(uint32_t)type] : L"";
|
||||
}
|
||||
|
||||
const wchar_t* VendorIDToStr(uint32_t vendorID)
|
||||
{
|
||||
switch(vendorID)
|
||||
{
|
||||
// Skipping common prefix VK_VENDOR_ID_ for these:
|
||||
case 0x10001: return L"VIV";
|
||||
case 0x10002: return L"VSI";
|
||||
case 0x10003: return L"KAZAN";
|
||||
case 0x10004: return L"CODEPLAY";
|
||||
case 0x10005: return L"MESA";
|
||||
case 0x10006: return L"POCL";
|
||||
// Others...
|
||||
case VENDOR_ID_AMD: return L"AMD";
|
||||
case VENDOR_ID_NVIDIA: return L"NVIDIA";
|
||||
case VENDOR_ID_INTEL: return L"Intel";
|
||||
case 0x1010: return L"ImgTec";
|
||||
case 0x13B5: return L"ARM";
|
||||
case 0x5143: return L"Qualcomm";
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
#if VMA_VULKAN_VERSION >= 1002000
|
||||
const wchar_t* DriverIDToStr(VkDriverId driverID)
|
||||
{
|
||||
// Skipping common prefix VK_DRIVER_ID_
|
||||
static const wchar_t* const VALUES[] = {
|
||||
L"",
|
||||
L"AMD_PROPRIETARY",
|
||||
L"AMD_OPEN_SOURCE",
|
||||
L"MESA_RADV",
|
||||
L"NVIDIA_PROPRIETARY",
|
||||
L"INTEL_PROPRIETARY_WINDOWS",
|
||||
L"INTEL_OPEN_SOURCE_MESA",
|
||||
L"IMAGINATION_PROPRIETARY",
|
||||
L"QUALCOMM_PROPRIETARY",
|
||||
L"ARM_PROPRIETARY",
|
||||
L"GOOGLE_SWIFTSHADER",
|
||||
L"GGP_PROPRIETARY",
|
||||
L"BROADCOM_PROPRIETARY",
|
||||
L"MESA_LLVMPIPE",
|
||||
L"MOLTENVK",
|
||||
};
|
||||
return (uint32_t)driverID < _countof(VALUES) ? VALUES[(uint32_t)driverID] : L"";
|
||||
}
|
||||
#endif // #if VMA_VULKAN_VERSION >= 1002000
|
||||
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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 "Common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void ReadFile(std::vector<char>& out, const char* fileName)
|
||||
{
|
||||
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
|
||||
assert(file.is_open());
|
||||
size_t fileSize = (size_t)file.tellg();
|
||||
if(fileSize > 0)
|
||||
{
|
||||
out.resize(fileSize);
|
||||
file.seekg(0);
|
||||
file.read(out.data(), fileSize);
|
||||
}
|
||||
else
|
||||
out.clear();
|
||||
}
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color)
|
||||
{
|
||||
WORD attr = 0;
|
||||
switch(color)
|
||||
{
|
||||
case CONSOLE_COLOR::INFO:
|
||||
attr = FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CONSOLE_COLOR::NORMAL:
|
||||
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
break;
|
||||
case CONSOLE_COLOR::WARNING:
|
||||
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CONSOLE_COLOR::ERROR_:
|
||||
attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
SetConsoleTextAttribute(out, attr);
|
||||
}
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg)
|
||||
{
|
||||
if(color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(color);
|
||||
|
||||
printf("%s\n", msg);
|
||||
|
||||
if (color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(CONSOLE_COLOR::NORMAL);
|
||||
}
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg)
|
||||
{
|
||||
if(color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(color);
|
||||
|
||||
wprintf(L"%s\n", msg);
|
||||
|
||||
if (color != CONSOLE_COLOR::NORMAL)
|
||||
SetConsoleColor(CONSOLE_COLOR::NORMAL);
|
||||
}
|
||||
|
||||
static const size_t CONSOLE_SMALL_BUF_SIZE = 256;
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList)
|
||||
{
|
||||
size_t dstLen = (size_t)::_vscprintf(format, argList);
|
||||
if(dstLen)
|
||||
{
|
||||
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
|
||||
char smallBuf[CONSOLE_SMALL_BUF_SIZE];
|
||||
std::vector<char> bigBuf(useSmallBuf ? 0 : dstLen + 1);
|
||||
char* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
|
||||
::vsprintf_s(bufPtr, dstLen + 1, format, argList);
|
||||
PrintMessage(color, bufPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList)
|
||||
{
|
||||
size_t dstLen = (size_t)::_vcwprintf(format, argList);
|
||||
if(dstLen)
|
||||
{
|
||||
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
|
||||
wchar_t smallBuf[CONSOLE_SMALL_BUF_SIZE];
|
||||
std::vector<wchar_t> bigBuf(useSmallBuf ? 0 : dstLen + 1);
|
||||
wchar_t* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
|
||||
::vswprintf_s(bufPtr, dstLen + 1, format, argList);
|
||||
PrintMessage(color, bufPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(color, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(color, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintWarningF(const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintWarningF(const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintErrorF(const char* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void PrintErrorF(const wchar_t* format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize)
|
||||
{
|
||||
FILE* f = nullptr;
|
||||
_wfopen_s(&f, filePath, L"wb");
|
||||
if(f)
|
||||
{
|
||||
fwrite(data, 1, dataSize, f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
std::wstring SizeToStr(size_t size)
|
||||
{
|
||||
if(size == 0)
|
||||
return L"0";
|
||||
wchar_t result[32];
|
||||
double size2 = (double)size;
|
||||
if (size2 >= 1024.0*1024.0*1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f TB", size2 / (1024.0*1024.0*1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0*1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f GB", size2 / (1024.0*1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0*1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f MB", size2 / (1024.0*1024.0));
|
||||
}
|
||||
else if (size2 >= 1024.0)
|
||||
{
|
||||
swprintf_s(result, L"%.2f KB", size2 / 1024.0);
|
||||
}
|
||||
else
|
||||
swprintf_s(result, L"%llu B", size);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage)
|
||||
{
|
||||
if (s.empty())
|
||||
{
|
||||
outStr->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Phase 1 - Get buffer size.
|
||||
const int size = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), NULL, 0);
|
||||
if (size == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 2 - Do conversion.
|
||||
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
|
||||
int result = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), buf.get(), size);
|
||||
if (result == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
outStr->assign(buf.get(), (size_t)size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage)
|
||||
{
|
||||
if (sCharCount == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(sCharCount <= (size_t)INT_MAX);
|
||||
|
||||
// Phase 1 - Get buffer size.
|
||||
int size = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, NULL, 0);
|
||||
if (size == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 2 - Do conversion.
|
||||
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
|
||||
int result = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, buf.get(), size);
|
||||
if (result == 0)
|
||||
{
|
||||
outStr->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
outStr->assign(buf.get(), (size_t)size);
|
||||
return true;
|
||||
}
|
||||
|
||||
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type)
|
||||
{
|
||||
// Skipping common prefix VK_PHYSICAL_DEVICE_TYPE_
|
||||
static const wchar_t* const VALUES[] = {
|
||||
L"OTHER",
|
||||
L"INTEGRATED_GPU",
|
||||
L"DISCRETE_GPU",
|
||||
L"VIRTUAL_GPU",
|
||||
L"CPU",
|
||||
};
|
||||
return (uint32_t)type < _countof(VALUES) ? VALUES[(uint32_t)type] : L"";
|
||||
}
|
||||
|
||||
const wchar_t* VendorIDToStr(uint32_t vendorID)
|
||||
{
|
||||
switch(vendorID)
|
||||
{
|
||||
// Skipping common prefix VK_VENDOR_ID_ for these:
|
||||
case 0x10001: return L"VIV";
|
||||
case 0x10002: return L"VSI";
|
||||
case 0x10003: return L"KAZAN";
|
||||
case 0x10004: return L"CODEPLAY";
|
||||
case 0x10005: return L"MESA";
|
||||
case 0x10006: return L"POCL";
|
||||
// Others...
|
||||
case VENDOR_ID_AMD: return L"AMD";
|
||||
case VENDOR_ID_NVIDIA: return L"NVIDIA";
|
||||
case VENDOR_ID_INTEL: return L"Intel";
|
||||
case 0x1010: return L"ImgTec";
|
||||
case 0x13B5: return L"ARM";
|
||||
case 0x5143: return L"Qualcomm";
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
#if VMA_VULKAN_VERSION >= 1002000
|
||||
const wchar_t* DriverIDToStr(VkDriverId driverID)
|
||||
{
|
||||
// Skipping common prefix VK_DRIVER_ID_
|
||||
static const wchar_t* const VALUES[] = {
|
||||
L"",
|
||||
L"AMD_PROPRIETARY",
|
||||
L"AMD_OPEN_SOURCE",
|
||||
L"MESA_RADV",
|
||||
L"NVIDIA_PROPRIETARY",
|
||||
L"INTEL_PROPRIETARY_WINDOWS",
|
||||
L"INTEL_OPEN_SOURCE_MESA",
|
||||
L"IMAGINATION_PROPRIETARY",
|
||||
L"QUALCOMM_PROPRIETARY",
|
||||
L"ARM_PROPRIETARY",
|
||||
L"GOOGLE_SWIFTSHADER",
|
||||
L"GGP_PROPRIETARY",
|
||||
L"BROADCOM_PROPRIETARY",
|
||||
L"MESA_LLVMPIPE",
|
||||
L"MOLTENVK",
|
||||
};
|
||||
return (uint32_t)driverID < _countof(VALUES) ? VALUES[(uint32_t)driverID] : L"";
|
||||
}
|
||||
#endif // #if VMA_VULKAN_VERSION >= 1002000
|
||||
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
678
src/Common.h
678
src/Common.h
@ -1,339 +1,339 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include "VmaUsage.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
typedef std::chrono::high_resolution_clock::time_point time_point;
|
||||
typedef std::chrono::high_resolution_clock::duration duration;
|
||||
|
||||
#define STRINGIZE(x) STRINGIZE2(x)
|
||||
#define STRINGIZE2(x) #x
|
||||
#define LINE_STRING STRINGIZE(__LINE__)
|
||||
#define TEST(expr) do { if(!(expr)) { \
|
||||
assert(0 && #expr); \
|
||||
throw std::runtime_error(__FILE__ "(" LINE_STRING "): ( " #expr " ) == false"); \
|
||||
} } while(false)
|
||||
#define ERR_GUARD_VULKAN(expr) do { if((expr) < 0) { \
|
||||
assert(0 && #expr); \
|
||||
throw std::runtime_error(__FILE__ "(" LINE_STRING "): VkResult( " #expr " ) < 0"); \
|
||||
} } while(false)
|
||||
|
||||
static const uint32_t VENDOR_ID_AMD = 0x1002;
|
||||
static const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
|
||||
static const uint32_t VENDOR_ID_INTEL = 0x8086;
|
||||
|
||||
extern VkInstance g_hVulkanInstance;
|
||||
extern VkPhysicalDevice g_hPhysicalDevice;
|
||||
extern VkDevice g_hDevice;
|
||||
extern VkInstance g_hVulkanInstance;
|
||||
extern VmaAllocator g_hAllocator;
|
||||
extern bool VK_AMD_device_coherent_memory_enabled;
|
||||
|
||||
void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo);
|
||||
|
||||
inline float ToFloatSeconds(duration d)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T ceil_div(T x, T y)
|
||||
{
|
||||
return (x+y-1) / y;
|
||||
}
|
||||
template <typename T>
|
||||
inline T round_div(T x, T y)
|
||||
{
|
||||
return (x+y/(T)2) / y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T align_up(T val, T align)
|
||||
{
|
||||
return (val + align - 1) / align * align;
|
||||
}
|
||||
|
||||
static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
|
||||
|
||||
template<typename MainT, typename NewT>
|
||||
inline void PnextChainPushFront(MainT* mainStruct, NewT* newStruct)
|
||||
{
|
||||
newStruct->pNext = mainStruct->pNext;
|
||||
mainStruct->pNext = newStruct;
|
||||
}
|
||||
template<typename MainT, typename NewT>
|
||||
inline void PnextChainPushBack(MainT* mainStruct, NewT* newStruct)
|
||||
{
|
||||
struct VkAnyStruct
|
||||
{
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
};
|
||||
VkAnyStruct* lastStruct = (VkAnyStruct*)mainStruct;
|
||||
while(lastStruct->pNext != nullptr)
|
||||
{
|
||||
lastStruct = (VkAnyStruct*)lastStruct->pNext;
|
||||
}
|
||||
newStruct->pNext = nullptr;
|
||||
lastStruct->pNext = newStruct;
|
||||
}
|
||||
|
||||
struct vec3
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
vec3() { }
|
||||
vec3(float x, float y, float z) : x(x), y(y), z(z) { }
|
||||
|
||||
float& operator[](uint32_t index) { return *(&x + index); }
|
||||
const float& operator[](uint32_t index) const { return *(&x + index); }
|
||||
|
||||
vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
|
||||
vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
|
||||
vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }
|
||||
|
||||
vec3 Normalized() const
|
||||
{
|
||||
return (*this) * (1.f / sqrt(x * x + y * y + z * z));
|
||||
}
|
||||
};
|
||||
|
||||
inline float Dot(const vec3& lhs, const vec3& rhs)
|
||||
{
|
||||
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
|
||||
}
|
||||
inline vec3 Cross(const vec3& lhs, const vec3& rhs)
|
||||
{
|
||||
return vec3(
|
||||
lhs.y * rhs.z - lhs.z * rhs.y,
|
||||
lhs.z * rhs.x - lhs.x * rhs.z,
|
||||
lhs.x * rhs.y - lhs.y * rhs.x);
|
||||
}
|
||||
|
||||
struct vec4
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
vec4() { }
|
||||
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
|
||||
vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }
|
||||
|
||||
float& operator[](uint32_t index) { return *(&x + index); }
|
||||
const float& operator[](uint32_t index) const { return *(&x + index); }
|
||||
};
|
||||
|
||||
struct mat4
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float _11, _12, _13, _14;
|
||||
float _21, _22, _23, _24;
|
||||
float _31, _32, _33, _34;
|
||||
float _41, _42, _43, _44;
|
||||
};
|
||||
float m[4][4]; // [row][column]
|
||||
};
|
||||
|
||||
mat4() { }
|
||||
|
||||
mat4(
|
||||
float _11, float _12, float _13, float _14,
|
||||
float _21, float _22, float _23, float _24,
|
||||
float _31, float _32, float _33, float _34,
|
||||
float _41, float _42, float _43, float _44) :
|
||||
_11(_11), _12(_12), _13(_13), _14(_14),
|
||||
_21(_21), _22(_22), _23(_23), _24(_24),
|
||||
_31(_31), _32(_32), _33(_33), _34(_34),
|
||||
_41(_41), _42(_42), _43(_43), _44(_44)
|
||||
{
|
||||
}
|
||||
|
||||
mat4(
|
||||
const vec4& row1,
|
||||
const vec4& row2,
|
||||
const vec4& row3,
|
||||
const vec4& row4) :
|
||||
_11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),
|
||||
_21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),
|
||||
_31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),
|
||||
_41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)
|
||||
{
|
||||
}
|
||||
|
||||
mat4 operator*(const mat4 &rhs) const
|
||||
{
|
||||
return mat4(
|
||||
_11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,
|
||||
_11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,
|
||||
_11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,
|
||||
_11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,
|
||||
|
||||
_21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,
|
||||
_21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,
|
||||
_21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,
|
||||
_21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,
|
||||
|
||||
_31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,
|
||||
_31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,
|
||||
_31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,
|
||||
_31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,
|
||||
|
||||
_41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,
|
||||
_41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,
|
||||
_41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,
|
||||
_41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);
|
||||
}
|
||||
|
||||
static mat4 RotationY(float angle)
|
||||
{
|
||||
const float s = sin(angle), c = cos(angle);
|
||||
return mat4(
|
||||
c, 0.f, -s, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
s, 0.f, c, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)
|
||||
{
|
||||
float yScale = 1.0f / tan(fovY * 0.5f);
|
||||
float xScale = yScale / aspectRatio;
|
||||
return mat4(
|
||||
xScale, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, yScale, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
|
||||
0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);
|
||||
}
|
||||
|
||||
static mat4 LookAt(vec3 at, vec3 eye, vec3 up)
|
||||
{
|
||||
vec3 zAxis = (at - eye).Normalized();
|
||||
vec3 xAxis = Cross(up, zAxis).Normalized();
|
||||
vec3 yAxis = Cross(zAxis, xAxis);
|
||||
return mat4(
|
||||
xAxis.x, yAxis.x, zAxis.x, 0.0f,
|
||||
xAxis.y, yAxis.y, zAxis.y, 0.0f,
|
||||
xAxis.z, yAxis.z, zAxis.z, 0.0f,
|
||||
-Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
class RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
RandomNumberGenerator() : m_Value{GetTickCount()} {}
|
||||
RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
|
||||
void Seed(uint32_t seed) { m_Value = seed; }
|
||||
uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
|
||||
|
||||
private:
|
||||
uint32_t m_Value;
|
||||
uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
|
||||
};
|
||||
|
||||
// Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
|
||||
struct MyUniformRandomNumberGenerator
|
||||
{
|
||||
typedef uint32_t result_type;
|
||||
MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
|
||||
static uint32_t min() { return 0; }
|
||||
static uint32_t max() { return UINT32_MAX; }
|
||||
uint32_t operator()() { return m_Gen.Generate(); }
|
||||
|
||||
private:
|
||||
RandomNumberGenerator& m_Gen;
|
||||
};
|
||||
|
||||
void ReadFile(std::vector<char>& out, const char* fileName);
|
||||
|
||||
enum class CONSOLE_COLOR
|
||||
{
|
||||
INFO,
|
||||
NORMAL,
|
||||
WARNING,
|
||||
ERROR_,
|
||||
COUNT
|
||||
};
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color);
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg);
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
|
||||
|
||||
inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
|
||||
void PrintWarningF(const char* format, ...);
|
||||
void PrintWarningF(const wchar_t* format, ...);
|
||||
void PrintErrorF(const char* format, ...);
|
||||
void PrintErrorF(const wchar_t* format, ...);
|
||||
|
||||
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize);
|
||||
|
||||
std::wstring SizeToStr(size_t size);
|
||||
// As codePage use e.g. CP_ACP for native Windows 1-byte codepage or CP_UTF8.
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage);
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage);
|
||||
|
||||
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type);
|
||||
const wchar_t* VendorIDToStr(uint32_t vendorID);
|
||||
|
||||
#if VMA_VULKAN_VERSION >= 1002000
|
||||
const wchar_t* DriverIDToStr(VkDriverId driverID);
|
||||
#endif
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include "VmaUsage.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
typedef std::chrono::high_resolution_clock::time_point time_point;
|
||||
typedef std::chrono::high_resolution_clock::duration duration;
|
||||
|
||||
#define STRINGIZE(x) STRINGIZE2(x)
|
||||
#define STRINGIZE2(x) #x
|
||||
#define LINE_STRING STRINGIZE(__LINE__)
|
||||
#define TEST(expr) do { if(!(expr)) { \
|
||||
assert(0 && #expr); \
|
||||
throw std::runtime_error(__FILE__ "(" LINE_STRING "): ( " #expr " ) == false"); \
|
||||
} } while(false)
|
||||
#define ERR_GUARD_VULKAN(expr) do { if((expr) < 0) { \
|
||||
assert(0 && #expr); \
|
||||
throw std::runtime_error(__FILE__ "(" LINE_STRING "): VkResult( " #expr " ) < 0"); \
|
||||
} } while(false)
|
||||
|
||||
static const uint32_t VENDOR_ID_AMD = 0x1002;
|
||||
static const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
|
||||
static const uint32_t VENDOR_ID_INTEL = 0x8086;
|
||||
|
||||
extern VkInstance g_hVulkanInstance;
|
||||
extern VkPhysicalDevice g_hPhysicalDevice;
|
||||
extern VkDevice g_hDevice;
|
||||
extern VkInstance g_hVulkanInstance;
|
||||
extern VmaAllocator g_hAllocator;
|
||||
extern bool VK_AMD_device_coherent_memory_enabled;
|
||||
|
||||
void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo);
|
||||
|
||||
inline float ToFloatSeconds(duration d)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T ceil_div(T x, T y)
|
||||
{
|
||||
return (x+y-1) / y;
|
||||
}
|
||||
template <typename T>
|
||||
inline T round_div(T x, T y)
|
||||
{
|
||||
return (x+y/(T)2) / y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T align_up(T val, T align)
|
||||
{
|
||||
return (val + align - 1) / align * align;
|
||||
}
|
||||
|
||||
static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
|
||||
|
||||
template<typename MainT, typename NewT>
|
||||
inline void PnextChainPushFront(MainT* mainStruct, NewT* newStruct)
|
||||
{
|
||||
newStruct->pNext = mainStruct->pNext;
|
||||
mainStruct->pNext = newStruct;
|
||||
}
|
||||
template<typename MainT, typename NewT>
|
||||
inline void PnextChainPushBack(MainT* mainStruct, NewT* newStruct)
|
||||
{
|
||||
struct VkAnyStruct
|
||||
{
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
};
|
||||
VkAnyStruct* lastStruct = (VkAnyStruct*)mainStruct;
|
||||
while(lastStruct->pNext != nullptr)
|
||||
{
|
||||
lastStruct = (VkAnyStruct*)lastStruct->pNext;
|
||||
}
|
||||
newStruct->pNext = nullptr;
|
||||
lastStruct->pNext = newStruct;
|
||||
}
|
||||
|
||||
struct vec3
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
vec3() { }
|
||||
vec3(float x, float y, float z) : x(x), y(y), z(z) { }
|
||||
|
||||
float& operator[](uint32_t index) { return *(&x + index); }
|
||||
const float& operator[](uint32_t index) const { return *(&x + index); }
|
||||
|
||||
vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
|
||||
vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
|
||||
vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }
|
||||
|
||||
vec3 Normalized() const
|
||||
{
|
||||
return (*this) * (1.f / sqrt(x * x + y * y + z * z));
|
||||
}
|
||||
};
|
||||
|
||||
inline float Dot(const vec3& lhs, const vec3& rhs)
|
||||
{
|
||||
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
|
||||
}
|
||||
inline vec3 Cross(const vec3& lhs, const vec3& rhs)
|
||||
{
|
||||
return vec3(
|
||||
lhs.y * rhs.z - lhs.z * rhs.y,
|
||||
lhs.z * rhs.x - lhs.x * rhs.z,
|
||||
lhs.x * rhs.y - lhs.y * rhs.x);
|
||||
}
|
||||
|
||||
struct vec4
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
vec4() { }
|
||||
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
|
||||
vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }
|
||||
|
||||
float& operator[](uint32_t index) { return *(&x + index); }
|
||||
const float& operator[](uint32_t index) const { return *(&x + index); }
|
||||
};
|
||||
|
||||
struct mat4
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float _11, _12, _13, _14;
|
||||
float _21, _22, _23, _24;
|
||||
float _31, _32, _33, _34;
|
||||
float _41, _42, _43, _44;
|
||||
};
|
||||
float m[4][4]; // [row][column]
|
||||
};
|
||||
|
||||
mat4() { }
|
||||
|
||||
mat4(
|
||||
float _11, float _12, float _13, float _14,
|
||||
float _21, float _22, float _23, float _24,
|
||||
float _31, float _32, float _33, float _34,
|
||||
float _41, float _42, float _43, float _44) :
|
||||
_11(_11), _12(_12), _13(_13), _14(_14),
|
||||
_21(_21), _22(_22), _23(_23), _24(_24),
|
||||
_31(_31), _32(_32), _33(_33), _34(_34),
|
||||
_41(_41), _42(_42), _43(_43), _44(_44)
|
||||
{
|
||||
}
|
||||
|
||||
mat4(
|
||||
const vec4& row1,
|
||||
const vec4& row2,
|
||||
const vec4& row3,
|
||||
const vec4& row4) :
|
||||
_11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),
|
||||
_21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),
|
||||
_31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),
|
||||
_41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)
|
||||
{
|
||||
}
|
||||
|
||||
mat4 operator*(const mat4 &rhs) const
|
||||
{
|
||||
return mat4(
|
||||
_11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,
|
||||
_11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,
|
||||
_11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,
|
||||
_11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,
|
||||
|
||||
_21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,
|
||||
_21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,
|
||||
_21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,
|
||||
_21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,
|
||||
|
||||
_31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,
|
||||
_31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,
|
||||
_31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,
|
||||
_31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,
|
||||
|
||||
_41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,
|
||||
_41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,
|
||||
_41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,
|
||||
_41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);
|
||||
}
|
||||
|
||||
static mat4 RotationY(float angle)
|
||||
{
|
||||
const float s = sin(angle), c = cos(angle);
|
||||
return mat4(
|
||||
c, 0.f, -s, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
s, 0.f, c, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)
|
||||
{
|
||||
float yScale = 1.0f / tan(fovY * 0.5f);
|
||||
float xScale = yScale / aspectRatio;
|
||||
return mat4(
|
||||
xScale, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, yScale, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
|
||||
0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);
|
||||
}
|
||||
|
||||
static mat4 LookAt(vec3 at, vec3 eye, vec3 up)
|
||||
{
|
||||
vec3 zAxis = (at - eye).Normalized();
|
||||
vec3 xAxis = Cross(up, zAxis).Normalized();
|
||||
vec3 yAxis = Cross(zAxis, xAxis);
|
||||
return mat4(
|
||||
xAxis.x, yAxis.x, zAxis.x, 0.0f,
|
||||
xAxis.y, yAxis.y, zAxis.y, 0.0f,
|
||||
xAxis.z, yAxis.z, zAxis.z, 0.0f,
|
||||
-Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
class RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
RandomNumberGenerator() : m_Value{GetTickCount()} {}
|
||||
RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
|
||||
void Seed(uint32_t seed) { m_Value = seed; }
|
||||
uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
|
||||
|
||||
private:
|
||||
uint32_t m_Value;
|
||||
uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
|
||||
};
|
||||
|
||||
// Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
|
||||
struct MyUniformRandomNumberGenerator
|
||||
{
|
||||
typedef uint32_t result_type;
|
||||
MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
|
||||
static uint32_t min() { return 0; }
|
||||
static uint32_t max() { return UINT32_MAX; }
|
||||
uint32_t operator()() { return m_Gen.Generate(); }
|
||||
|
||||
private:
|
||||
RandomNumberGenerator& m_Gen;
|
||||
};
|
||||
|
||||
void ReadFile(std::vector<char>& out, const char* fileName);
|
||||
|
||||
enum class CONSOLE_COLOR
|
||||
{
|
||||
INFO,
|
||||
NORMAL,
|
||||
WARNING,
|
||||
ERROR_,
|
||||
COUNT
|
||||
};
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color);
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg);
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
|
||||
|
||||
inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
|
||||
void PrintWarningF(const char* format, ...);
|
||||
void PrintWarningF(const wchar_t* format, ...);
|
||||
void PrintErrorF(const char* format, ...);
|
||||
void PrintErrorF(const wchar_t* format, ...);
|
||||
|
||||
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize);
|
||||
|
||||
std::wstring SizeToStr(size_t size);
|
||||
// As codePage use e.g. CP_ACP for native Windows 1-byte codepage or CP_UTF8.
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage);
|
||||
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage);
|
||||
|
||||
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type);
|
||||
const wchar_t* VendorIDToStr(uint32_t vendorID);
|
||||
|
||||
#if VMA_VULKAN_VERSION >= 1002000
|
||||
const wchar_t* DriverIDToStr(VkDriverId driverID);
|
||||
#endif
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#endif
|
||||
|
@ -1,37 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(location = 0) in vec3 inColor;
|
||||
layout(location = 1) in vec2 inTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D texSampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = texture(texSampler, inTexCoord);
|
||||
outColor.rgb *= inColor;
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(location = 0) in vec3 inColor;
|
||||
layout(location = 1) in vec2 inTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D texSampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = texture(texSampler, inTexCoord);
|
||||
outColor.rgb *= inColor;
|
||||
}
|
||||
|
@ -1,42 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(push_constant) uniform UniformBufferObject
|
||||
{
|
||||
mat4 ModelViewProj;
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
|
||||
layout(location = 0) out vec3 outColor;
|
||||
layout(location = 1) out vec2 outTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = ubo.ModelViewProj * vec4(inPosition, 1.0);
|
||||
outColor = inColor;
|
||||
outTexCoord = inTexCoord;
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(push_constant) uniform UniformBufferObject
|
||||
{
|
||||
mat4 ModelViewProj;
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
|
||||
layout(location = 0) out vec3 outColor;
|
||||
layout(location = 1) out vec2 outTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = ubo.ModelViewProj * vec4(inPosition, 1.0);
|
||||
outColor = inColor;
|
||||
outTexCoord = inTexCoord;
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
//
|
||||
// Copyright (c) 2018-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
|
||||
|
||||
layout(binding=0) uniform sampler2D img;
|
||||
layout(binding=1) buffer buf
|
||||
{
|
||||
uint bufValues[];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 xy = ivec2(bufValues[gl_GlobalInvocationID.x * 3],
|
||||
bufValues[gl_GlobalInvocationID.x * 3 + 1]);
|
||||
vec4 color = texture(img, xy);
|
||||
bufValues[gl_GlobalInvocationID.x * 3 + 2] =
|
||||
uint(color.r * 255.0) << 24 |
|
||||
uint(color.g * 255.0) << 16 |
|
||||
uint(color.b * 255.0) << 8 |
|
||||
uint(color.a * 255.0);
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2018-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
|
||||
|
||||
layout(binding=0) uniform sampler2D img;
|
||||
layout(binding=1) buffer buf
|
||||
{
|
||||
uint bufValues[];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 xy = ivec2(bufValues[gl_GlobalInvocationID.x * 3],
|
||||
bufValues[gl_GlobalInvocationID.x * 3 + 1]);
|
||||
vec4 color = texture(img, xy);
|
||||
bufValues[gl_GlobalInvocationID.x * 3 + 2] =
|
||||
uint(color.r * 255.0) << 24 |
|
||||
uint(color.g * 255.0) << 16 |
|
||||
uint(color.b * 255.0) << 8 |
|
||||
uint(color.a * 255.0);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,29 +1,29 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void TestSparseBinding();
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void TestSparseBinding();
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
13278
src/Tests.cpp
13278
src/Tests.cpp
File diff suppressed because it is too large
Load Diff
64
src/Tests.h
64
src/Tests.h
@ -1,32 +1,32 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef TESTS_H_
|
||||
#define TESTS_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void Test();
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef TESTS_H_
|
||||
#define TESTS_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void Test();
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,426 +1,426 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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 "VmaUsage.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
typedef std::chrono::high_resolution_clock::time_point time_point;
|
||||
typedef std::chrono::high_resolution_clock::duration duration;
|
||||
|
||||
inline float ToFloatSeconds(duration d)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
|
||||
}
|
||||
|
||||
void SecondsToFriendlyStr(float seconds, std::string& out);
|
||||
|
||||
template <typename T>
|
||||
T ceil_div(T x, T y)
|
||||
{
|
||||
return (x+y-1) / y;
|
||||
}
|
||||
template <typename T>
|
||||
inline T round_div(T x, T y)
|
||||
{
|
||||
return (x+y/(T)2) / y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T align_up(T val, T align)
|
||||
{
|
||||
return (val + align - 1) / align * align;
|
||||
}
|
||||
|
||||
struct StrRange
|
||||
{
|
||||
const char* beg;
|
||||
const char* end;
|
||||
|
||||
StrRange() { }
|
||||
StrRange(const char* beg, const char* end) : beg(beg), end(end) { }
|
||||
explicit StrRange(const char* sz) : beg(sz), end(sz + strlen(sz)) { }
|
||||
explicit StrRange(const std::string& s) : beg(s.data()), end(s.data() + s.length()) { }
|
||||
|
||||
size_t length() const { return end - beg; }
|
||||
void to_str(std::string& out) const { out.assign(beg, end); }
|
||||
};
|
||||
|
||||
inline bool StrRangeEq(const StrRange& lhs, const char* rhsSz)
|
||||
{
|
||||
const size_t rhsLen = strlen(rhsSz);
|
||||
return rhsLen == lhs.length() &&
|
||||
memcmp(lhs.beg, rhsSz, rhsLen) == 0;
|
||||
}
|
||||
|
||||
inline bool StrRangeToUint(const StrRange& s, uint32_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint32_t)strtoul(s.beg, &end, 10);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToUint(const StrRange& s, uint64_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint64_t)strtoull(s.beg, &end, 10);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToPtr(const StrRange& s, uint64_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint64_t)strtoull(s.beg, &end, 16);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToFloat(const StrRange& s, float& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = strtof(s.beg, &end);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToBool(const StrRange& s, bool& out)
|
||||
{
|
||||
if(s.end - s.beg == 1)
|
||||
{
|
||||
if(*s.beg == '1')
|
||||
{
|
||||
out = true;
|
||||
}
|
||||
else if(*s.beg == '0')
|
||||
{
|
||||
out = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out);
|
||||
|
||||
class LineSplit
|
||||
{
|
||||
public:
|
||||
LineSplit(const char* data, size_t numBytes) :
|
||||
m_Data(data),
|
||||
m_NumBytes(numBytes),
|
||||
m_NextLineBeg(0),
|
||||
m_NextLineIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool GetNextLine(StrRange& out);
|
||||
size_t GetNextLineIndex() const { return m_NextLineIndex; }
|
||||
|
||||
private:
|
||||
const char* const m_Data;
|
||||
const size_t m_NumBytes;
|
||||
size_t m_NextLineBeg;
|
||||
size_t m_NextLineIndex;
|
||||
};
|
||||
|
||||
class CsvSplit
|
||||
{
|
||||
public:
|
||||
static const size_t RANGE_COUNT_MAX = 32;
|
||||
|
||||
void Set(const StrRange& line, size_t maxCount = RANGE_COUNT_MAX);
|
||||
|
||||
const StrRange& GetLine() const { return m_Line; }
|
||||
|
||||
size_t GetCount() const { return m_Count; }
|
||||
StrRange GetRange(size_t index) const
|
||||
{
|
||||
if(index < m_Count)
|
||||
{
|
||||
return StrRange {
|
||||
m_Line.beg + m_Ranges[index * 2],
|
||||
m_Line.beg + m_Ranges[index * 2 + 1] };
|
||||
}
|
||||
else
|
||||
{
|
||||
return StrRange{0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
StrRange m_Line = { nullptr, nullptr };
|
||||
size_t m_Count = 0;
|
||||
size_t m_Ranges[RANGE_COUNT_MAX * 2]; // Pairs of begin-end.
|
||||
};
|
||||
|
||||
class CmdLineParser
|
||||
{
|
||||
public:
|
||||
enum RESULT
|
||||
{
|
||||
RESULT_OPT,
|
||||
RESULT_PARAMETER,
|
||||
RESULT_END,
|
||||
RESULT_ERROR,
|
||||
};
|
||||
|
||||
CmdLineParser(int argc, char **argv);
|
||||
CmdLineParser(const char *CmdLine);
|
||||
|
||||
void RegisterOpt(uint32_t Id, char Opt, bool Parameter);
|
||||
void RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter);
|
||||
|
||||
RESULT ReadNext();
|
||||
uint32_t GetOptId();
|
||||
const std::string & GetParameter();
|
||||
|
||||
private:
|
||||
struct SHORT_OPT
|
||||
{
|
||||
uint32_t Id;
|
||||
char Opt;
|
||||
bool Parameter;
|
||||
|
||||
SHORT_OPT(uint32_t Id, char Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
|
||||
};
|
||||
|
||||
struct LONG_OPT
|
||||
{
|
||||
uint32_t Id;
|
||||
std::string Opt;
|
||||
bool Parameter;
|
||||
|
||||
LONG_OPT(uint32_t Id, std::string Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
|
||||
};
|
||||
|
||||
char **m_argv;
|
||||
const char *m_CmdLine;
|
||||
int m_argc;
|
||||
size_t m_CmdLineLength;
|
||||
size_t m_ArgIndex;
|
||||
|
||||
bool ReadNextArg(std::string *OutArg);
|
||||
|
||||
std::vector<SHORT_OPT> m_ShortOpts;
|
||||
std::vector<LONG_OPT> m_LongOpts;
|
||||
|
||||
SHORT_OPT * FindShortOpt(char Opt);
|
||||
LONG_OPT * FindLongOpt(const std::string &Opt);
|
||||
|
||||
bool m_InsideMultioption;
|
||||
std::string m_LastArg;
|
||||
size_t m_LastArgIndex;
|
||||
uint32_t m_LastOptId;
|
||||
std::string m_LastParameter;
|
||||
};
|
||||
|
||||
/*
|
||||
Parses and stores a sequence of ranges.
|
||||
|
||||
Upper range is inclusive.
|
||||
|
||||
Examples:
|
||||
|
||||
"1" -> [ {1, 1} ]
|
||||
"1,10" -> [ {1, 1}, {10, 10} ]
|
||||
"2-6" -> [ {2, 6} ]
|
||||
"-8" -> [ {MIN, 8} ]
|
||||
"12-" -> [ {12, MAX} ]
|
||||
"1-10,12,15-" -> [ {1, 10}, {12, 12}, {15, MAX} ]
|
||||
|
||||
TODO: Optimize it: Do sorting and merging while parsing. Do binary search while
|
||||
reading.
|
||||
*/
|
||||
template<typename T>
|
||||
class RangeSequence
|
||||
{
|
||||
public:
|
||||
typedef std::pair<T, T> RangeType;
|
||||
|
||||
void Clear() { m_Ranges.clear(); }
|
||||
bool Parse(const StrRange& str);
|
||||
|
||||
bool IsEmpty() const { return m_Ranges.empty(); }
|
||||
size_t GetCount() const { return m_Ranges.size(); }
|
||||
const RangeType* GetRanges() const { return m_Ranges.data(); }
|
||||
|
||||
bool Includes(T number) const;
|
||||
|
||||
private:
|
||||
std::vector<RangeType> m_Ranges;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool RangeSequence<T>::Parse(const StrRange& str)
|
||||
{
|
||||
m_Ranges.clear();
|
||||
|
||||
StrRange currRange = { str.beg, str.beg };
|
||||
while(currRange.beg < str.end)
|
||||
{
|
||||
currRange.end = currRange.beg + 1;
|
||||
// Find next ',' or the end.
|
||||
while(currRange.end < str.end && *currRange.end != ',')
|
||||
{
|
||||
++currRange.end;
|
||||
}
|
||||
|
||||
// Find '-' within this range.
|
||||
const char* hyphenPos = currRange.beg;
|
||||
while(hyphenPos < currRange.end && *hyphenPos != '-')
|
||||
{
|
||||
++hyphenPos;
|
||||
}
|
||||
|
||||
// No hyphen - single number like '10'.
|
||||
if(hyphenPos == currRange.end)
|
||||
{
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(currRange, range.first))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
range.second = range.first;
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen at the end, like '10-'.
|
||||
else if(hyphenPos + 1 == currRange.end)
|
||||
{
|
||||
const StrRange numberRange = { currRange.beg, hyphenPos };
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(numberRange, range.first))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
range.second = std::numeric_limits<T>::max();
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen at the beginning, like "-10".
|
||||
else if(hyphenPos == currRange.beg)
|
||||
{
|
||||
const StrRange numberRange = { currRange.beg + 1, currRange.end };
|
||||
RangeType range;
|
||||
range.first = std::numeric_limits<T>::min();
|
||||
if(!StrRangeToUint(numberRange, range.second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen in the middle, like "1-10".
|
||||
else
|
||||
{
|
||||
const StrRange numberRange1 = { currRange.beg, hyphenPos };
|
||||
const StrRange numberRange2 = { hyphenPos + 1, currRange.end };
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(numberRange1, range.first) ||
|
||||
!StrRangeToUint(numberRange2, range.second) ||
|
||||
range.second < range.first)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
|
||||
// Skip ','
|
||||
currRange.beg = currRange.end + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool RangeSequence<T>::Includes(T number) const
|
||||
{
|
||||
for(const auto& it : m_Ranges)
|
||||
{
|
||||
if(number >= it.first && number <= it.second)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
class RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
RandomNumberGenerator() : m_Value{GetTickCount()} {}
|
||||
RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
|
||||
void Seed(uint32_t seed) { m_Value = seed; }
|
||||
uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
|
||||
|
||||
private:
|
||||
uint32_t m_Value;
|
||||
uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
|
||||
};
|
||||
|
||||
enum class CONSOLE_COLOR
|
||||
{
|
||||
INFO,
|
||||
NORMAL,
|
||||
WARNING,
|
||||
ERROR_,
|
||||
COUNT
|
||||
};
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color);
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg);
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
|
||||
|
||||
inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
|
||||
void PrintWarningF(const char* format, ...);
|
||||
void PrintWarningF(const wchar_t* format, ...);
|
||||
void PrintErrorF(const char* format, ...);
|
||||
void PrintErrorF(const wchar_t* format, ...);
|
||||
*/
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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 "VmaUsage.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
typedef std::chrono::high_resolution_clock::time_point time_point;
|
||||
typedef std::chrono::high_resolution_clock::duration duration;
|
||||
|
||||
inline float ToFloatSeconds(duration d)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
|
||||
}
|
||||
|
||||
void SecondsToFriendlyStr(float seconds, std::string& out);
|
||||
|
||||
template <typename T>
|
||||
T ceil_div(T x, T y)
|
||||
{
|
||||
return (x+y-1) / y;
|
||||
}
|
||||
template <typename T>
|
||||
inline T round_div(T x, T y)
|
||||
{
|
||||
return (x+y/(T)2) / y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T align_up(T val, T align)
|
||||
{
|
||||
return (val + align - 1) / align * align;
|
||||
}
|
||||
|
||||
struct StrRange
|
||||
{
|
||||
const char* beg;
|
||||
const char* end;
|
||||
|
||||
StrRange() { }
|
||||
StrRange(const char* beg, const char* end) : beg(beg), end(end) { }
|
||||
explicit StrRange(const char* sz) : beg(sz), end(sz + strlen(sz)) { }
|
||||
explicit StrRange(const std::string& s) : beg(s.data()), end(s.data() + s.length()) { }
|
||||
|
||||
size_t length() const { return end - beg; }
|
||||
void to_str(std::string& out) const { out.assign(beg, end); }
|
||||
};
|
||||
|
||||
inline bool StrRangeEq(const StrRange& lhs, const char* rhsSz)
|
||||
{
|
||||
const size_t rhsLen = strlen(rhsSz);
|
||||
return rhsLen == lhs.length() &&
|
||||
memcmp(lhs.beg, rhsSz, rhsLen) == 0;
|
||||
}
|
||||
|
||||
inline bool StrRangeToUint(const StrRange& s, uint32_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint32_t)strtoul(s.beg, &end, 10);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToUint(const StrRange& s, uint64_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint64_t)strtoull(s.beg, &end, 10);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToPtr(const StrRange& s, uint64_t& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = (uint64_t)strtoull(s.beg, &end, 16);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToFloat(const StrRange& s, float& out)
|
||||
{
|
||||
char* end = (char*)s.end;
|
||||
out = strtof(s.beg, &end);
|
||||
return end == s.end;
|
||||
}
|
||||
inline bool StrRangeToBool(const StrRange& s, bool& out)
|
||||
{
|
||||
if(s.end - s.beg == 1)
|
||||
{
|
||||
if(*s.beg == '1')
|
||||
{
|
||||
out = true;
|
||||
}
|
||||
else if(*s.beg == '0')
|
||||
{
|
||||
out = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out);
|
||||
|
||||
class LineSplit
|
||||
{
|
||||
public:
|
||||
LineSplit(const char* data, size_t numBytes) :
|
||||
m_Data(data),
|
||||
m_NumBytes(numBytes),
|
||||
m_NextLineBeg(0),
|
||||
m_NextLineIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool GetNextLine(StrRange& out);
|
||||
size_t GetNextLineIndex() const { return m_NextLineIndex; }
|
||||
|
||||
private:
|
||||
const char* const m_Data;
|
||||
const size_t m_NumBytes;
|
||||
size_t m_NextLineBeg;
|
||||
size_t m_NextLineIndex;
|
||||
};
|
||||
|
||||
class CsvSplit
|
||||
{
|
||||
public:
|
||||
static const size_t RANGE_COUNT_MAX = 32;
|
||||
|
||||
void Set(const StrRange& line, size_t maxCount = RANGE_COUNT_MAX);
|
||||
|
||||
const StrRange& GetLine() const { return m_Line; }
|
||||
|
||||
size_t GetCount() const { return m_Count; }
|
||||
StrRange GetRange(size_t index) const
|
||||
{
|
||||
if(index < m_Count)
|
||||
{
|
||||
return StrRange {
|
||||
m_Line.beg + m_Ranges[index * 2],
|
||||
m_Line.beg + m_Ranges[index * 2 + 1] };
|
||||
}
|
||||
else
|
||||
{
|
||||
return StrRange{0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
StrRange m_Line = { nullptr, nullptr };
|
||||
size_t m_Count = 0;
|
||||
size_t m_Ranges[RANGE_COUNT_MAX * 2]; // Pairs of begin-end.
|
||||
};
|
||||
|
||||
class CmdLineParser
|
||||
{
|
||||
public:
|
||||
enum RESULT
|
||||
{
|
||||
RESULT_OPT,
|
||||
RESULT_PARAMETER,
|
||||
RESULT_END,
|
||||
RESULT_ERROR,
|
||||
};
|
||||
|
||||
CmdLineParser(int argc, char **argv);
|
||||
CmdLineParser(const char *CmdLine);
|
||||
|
||||
void RegisterOpt(uint32_t Id, char Opt, bool Parameter);
|
||||
void RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter);
|
||||
|
||||
RESULT ReadNext();
|
||||
uint32_t GetOptId();
|
||||
const std::string & GetParameter();
|
||||
|
||||
private:
|
||||
struct SHORT_OPT
|
||||
{
|
||||
uint32_t Id;
|
||||
char Opt;
|
||||
bool Parameter;
|
||||
|
||||
SHORT_OPT(uint32_t Id, char Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
|
||||
};
|
||||
|
||||
struct LONG_OPT
|
||||
{
|
||||
uint32_t Id;
|
||||
std::string Opt;
|
||||
bool Parameter;
|
||||
|
||||
LONG_OPT(uint32_t Id, std::string Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
|
||||
};
|
||||
|
||||
char **m_argv;
|
||||
const char *m_CmdLine;
|
||||
int m_argc;
|
||||
size_t m_CmdLineLength;
|
||||
size_t m_ArgIndex;
|
||||
|
||||
bool ReadNextArg(std::string *OutArg);
|
||||
|
||||
std::vector<SHORT_OPT> m_ShortOpts;
|
||||
std::vector<LONG_OPT> m_LongOpts;
|
||||
|
||||
SHORT_OPT * FindShortOpt(char Opt);
|
||||
LONG_OPT * FindLongOpt(const std::string &Opt);
|
||||
|
||||
bool m_InsideMultioption;
|
||||
std::string m_LastArg;
|
||||
size_t m_LastArgIndex;
|
||||
uint32_t m_LastOptId;
|
||||
std::string m_LastParameter;
|
||||
};
|
||||
|
||||
/*
|
||||
Parses and stores a sequence of ranges.
|
||||
|
||||
Upper range is inclusive.
|
||||
|
||||
Examples:
|
||||
|
||||
"1" -> [ {1, 1} ]
|
||||
"1,10" -> [ {1, 1}, {10, 10} ]
|
||||
"2-6" -> [ {2, 6} ]
|
||||
"-8" -> [ {MIN, 8} ]
|
||||
"12-" -> [ {12, MAX} ]
|
||||
"1-10,12,15-" -> [ {1, 10}, {12, 12}, {15, MAX} ]
|
||||
|
||||
TODO: Optimize it: Do sorting and merging while parsing. Do binary search while
|
||||
reading.
|
||||
*/
|
||||
template<typename T>
|
||||
class RangeSequence
|
||||
{
|
||||
public:
|
||||
typedef std::pair<T, T> RangeType;
|
||||
|
||||
void Clear() { m_Ranges.clear(); }
|
||||
bool Parse(const StrRange& str);
|
||||
|
||||
bool IsEmpty() const { return m_Ranges.empty(); }
|
||||
size_t GetCount() const { return m_Ranges.size(); }
|
||||
const RangeType* GetRanges() const { return m_Ranges.data(); }
|
||||
|
||||
bool Includes(T number) const;
|
||||
|
||||
private:
|
||||
std::vector<RangeType> m_Ranges;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool RangeSequence<T>::Parse(const StrRange& str)
|
||||
{
|
||||
m_Ranges.clear();
|
||||
|
||||
StrRange currRange = { str.beg, str.beg };
|
||||
while(currRange.beg < str.end)
|
||||
{
|
||||
currRange.end = currRange.beg + 1;
|
||||
// Find next ',' or the end.
|
||||
while(currRange.end < str.end && *currRange.end != ',')
|
||||
{
|
||||
++currRange.end;
|
||||
}
|
||||
|
||||
// Find '-' within this range.
|
||||
const char* hyphenPos = currRange.beg;
|
||||
while(hyphenPos < currRange.end && *hyphenPos != '-')
|
||||
{
|
||||
++hyphenPos;
|
||||
}
|
||||
|
||||
// No hyphen - single number like '10'.
|
||||
if(hyphenPos == currRange.end)
|
||||
{
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(currRange, range.first))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
range.second = range.first;
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen at the end, like '10-'.
|
||||
else if(hyphenPos + 1 == currRange.end)
|
||||
{
|
||||
const StrRange numberRange = { currRange.beg, hyphenPos };
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(numberRange, range.first))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
range.second = std::numeric_limits<T>::max();
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen at the beginning, like "-10".
|
||||
else if(hyphenPos == currRange.beg)
|
||||
{
|
||||
const StrRange numberRange = { currRange.beg + 1, currRange.end };
|
||||
RangeType range;
|
||||
range.first = std::numeric_limits<T>::min();
|
||||
if(!StrRangeToUint(numberRange, range.second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
// Hyphen in the middle, like "1-10".
|
||||
else
|
||||
{
|
||||
const StrRange numberRange1 = { currRange.beg, hyphenPos };
|
||||
const StrRange numberRange2 = { hyphenPos + 1, currRange.end };
|
||||
RangeType range;
|
||||
if(!StrRangeToUint(numberRange1, range.first) ||
|
||||
!StrRangeToUint(numberRange2, range.second) ||
|
||||
range.second < range.first)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Ranges.push_back(range);
|
||||
}
|
||||
|
||||
// Skip ','
|
||||
currRange.beg = currRange.end + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool RangeSequence<T>::Includes(T number) const
|
||||
{
|
||||
for(const auto& it : m_Ranges)
|
||||
{
|
||||
if(number >= it.first && number <= it.second)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
class RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
RandomNumberGenerator() : m_Value{GetTickCount()} {}
|
||||
RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
|
||||
void Seed(uint32_t seed) { m_Value = seed; }
|
||||
uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
|
||||
|
||||
private:
|
||||
uint32_t m_Value;
|
||||
uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
|
||||
};
|
||||
|
||||
enum class CONSOLE_COLOR
|
||||
{
|
||||
INFO,
|
||||
NORMAL,
|
||||
WARNING,
|
||||
ERROR_,
|
||||
COUNT
|
||||
};
|
||||
|
||||
void SetConsoleColor(CONSOLE_COLOR color);
|
||||
|
||||
void PrintMessage(CONSOLE_COLOR color, const char* msg);
|
||||
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
|
||||
|
||||
inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
||||
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
||||
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
|
||||
|
||||
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
|
||||
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
|
||||
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
|
||||
void PrintWarningF(const char* format, ...);
|
||||
void PrintWarningF(const wchar_t* format, ...);
|
||||
void PrintErrorF(const char* format, ...);
|
||||
void PrintErrorF(const wchar_t* format, ...);
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,149 +1,149 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
extern const int RESULT_EXCEPTION;
|
||||
extern const int RESULT_ERROR_COMMAND_LINE;
|
||||
extern const int RESULT_ERROR_SOURCE_FILE;
|
||||
extern const int RESULT_ERROR_FORMAT;
|
||||
extern const int RESULT_ERROR_VULKAN;
|
||||
|
||||
enum CMD_LINE_OPT
|
||||
{
|
||||
CMD_LINE_OPT_VERBOSITY,
|
||||
CMD_LINE_OPT_ITERATIONS,
|
||||
CMD_LINE_OPT_LINES,
|
||||
CMD_LINE_OPT_PHYSICAL_DEVICE,
|
||||
CMD_LINE_OPT_USER_DATA,
|
||||
CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION,
|
||||
CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET,
|
||||
CMD_LINE_OPT_VK_LAYER_KHRONOS_VALIDATION,
|
||||
CMD_LINE_OPT_MEM_STATS,
|
||||
CMD_LINE_OPT_DUMP_STATS_AFTER_LINE,
|
||||
CMD_LINE_OPT_DEFRAGMENT_AFTER_LINE,
|
||||
CMD_LINE_OPT_DEFRAGMENTATION_FLAGS,
|
||||
CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE,
|
||||
};
|
||||
|
||||
enum class VERBOSITY
|
||||
{
|
||||
MINIMUM = 0,
|
||||
DEFAULT,
|
||||
MAXIMUM,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
enum class VULKAN_EXTENSION_REQUEST
|
||||
{
|
||||
DISABLED,
|
||||
ENABLED,
|
||||
DEFAULT
|
||||
};
|
||||
|
||||
enum class OBJECT_TYPE { BUFFER, IMAGE };
|
||||
|
||||
enum class VMA_FUNCTION
|
||||
{
|
||||
CreatePool,
|
||||
DestroyPool,
|
||||
SetAllocationUserData,
|
||||
CreateBuffer,
|
||||
DestroyBuffer,
|
||||
CreateImage,
|
||||
DestroyImage,
|
||||
FreeMemory,
|
||||
FreeMemoryPages,
|
||||
CreateLostAllocation,
|
||||
AllocateMemory,
|
||||
AllocateMemoryPages,
|
||||
AllocateMemoryForBuffer,
|
||||
AllocateMemoryForImage,
|
||||
MapMemory,
|
||||
UnmapMemory,
|
||||
FlushAllocation,
|
||||
InvalidateAllocation,
|
||||
TouchAllocation,
|
||||
GetAllocationInfo,
|
||||
MakePoolAllocationsLost,
|
||||
ResizeAllocation,
|
||||
DefragmentationBegin,
|
||||
DefragmentationEnd,
|
||||
SetPoolName,
|
||||
Count
|
||||
};
|
||||
extern const char* VMA_FUNCTION_NAMES[];
|
||||
|
||||
extern const char* VMA_POOL_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VMA_POOL_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VMA_POOL_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_BUFFER_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_BUFFER_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VK_BUFFER_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_BUFFER_USAGE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_BUFFER_USAGE_FLAG_VALUES[];
|
||||
extern const size_t VK_BUFFER_USAGE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_SHARING_MODE_NAMES[];
|
||||
extern const size_t VK_SHARING_MODE_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VK_IMAGE_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TYPE_NAMES[];
|
||||
extern const size_t VK_IMAGE_TYPE_COUNT;
|
||||
|
||||
extern const char* VK_FORMAT_NAMES[];
|
||||
extern const uint32_t VK_FORMAT_VALUES[];
|
||||
extern const size_t VK_FORMAT_COUNT;
|
||||
|
||||
extern const char* VK_SAMPLE_COUNT_NAMES[];
|
||||
extern const uint32_t VK_SAMPLE_COUNT_VALUES[];
|
||||
extern const size_t VK_SAMPLE_COUNT_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TILING_NAMES[];
|
||||
extern const size_t VK_IMAGE_TILING_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_USAGE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_USAGE_FLAG_VALUES[];
|
||||
extern const size_t VK_IMAGE_USAGE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TILING_NAMES[];
|
||||
extern const size_t VK_IMAGE_TILING_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_LAYOUT_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_LAYOUT_VALUES[];
|
||||
extern const size_t VK_IMAGE_LAYOUT_COUNT;
|
||||
|
||||
extern const char* VMA_ALLOCATION_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VMA_ALLOCATION_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VMA_ALLOCATION_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VMA_MEMORY_USAGE_NAMES[];
|
||||
extern const size_t VMA_MEMORY_USAGE_COUNT;
|
||||
|
||||
extern const char* VK_MEMORY_PROPERTY_FLAG_NAMES[];
|
||||
extern const uint32_t VK_MEMORY_PROPERTY_FLAG_VALUES[];
|
||||
extern const size_t VK_MEMORY_PROPERTY_FLAG_COUNT;
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
extern const int RESULT_EXCEPTION;
|
||||
extern const int RESULT_ERROR_COMMAND_LINE;
|
||||
extern const int RESULT_ERROR_SOURCE_FILE;
|
||||
extern const int RESULT_ERROR_FORMAT;
|
||||
extern const int RESULT_ERROR_VULKAN;
|
||||
|
||||
enum CMD_LINE_OPT
|
||||
{
|
||||
CMD_LINE_OPT_VERBOSITY,
|
||||
CMD_LINE_OPT_ITERATIONS,
|
||||
CMD_LINE_OPT_LINES,
|
||||
CMD_LINE_OPT_PHYSICAL_DEVICE,
|
||||
CMD_LINE_OPT_USER_DATA,
|
||||
CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION,
|
||||
CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET,
|
||||
CMD_LINE_OPT_VK_LAYER_KHRONOS_VALIDATION,
|
||||
CMD_LINE_OPT_MEM_STATS,
|
||||
CMD_LINE_OPT_DUMP_STATS_AFTER_LINE,
|
||||
CMD_LINE_OPT_DEFRAGMENT_AFTER_LINE,
|
||||
CMD_LINE_OPT_DEFRAGMENTATION_FLAGS,
|
||||
CMD_LINE_OPT_DUMP_DETAILED_STATS_AFTER_LINE,
|
||||
};
|
||||
|
||||
enum class VERBOSITY
|
||||
{
|
||||
MINIMUM = 0,
|
||||
DEFAULT,
|
||||
MAXIMUM,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
enum class VULKAN_EXTENSION_REQUEST
|
||||
{
|
||||
DISABLED,
|
||||
ENABLED,
|
||||
DEFAULT
|
||||
};
|
||||
|
||||
enum class OBJECT_TYPE { BUFFER, IMAGE };
|
||||
|
||||
enum class VMA_FUNCTION
|
||||
{
|
||||
CreatePool,
|
||||
DestroyPool,
|
||||
SetAllocationUserData,
|
||||
CreateBuffer,
|
||||
DestroyBuffer,
|
||||
CreateImage,
|
||||
DestroyImage,
|
||||
FreeMemory,
|
||||
FreeMemoryPages,
|
||||
CreateLostAllocation,
|
||||
AllocateMemory,
|
||||
AllocateMemoryPages,
|
||||
AllocateMemoryForBuffer,
|
||||
AllocateMemoryForImage,
|
||||
MapMemory,
|
||||
UnmapMemory,
|
||||
FlushAllocation,
|
||||
InvalidateAllocation,
|
||||
TouchAllocation,
|
||||
GetAllocationInfo,
|
||||
MakePoolAllocationsLost,
|
||||
ResizeAllocation,
|
||||
DefragmentationBegin,
|
||||
DefragmentationEnd,
|
||||
SetPoolName,
|
||||
Count
|
||||
};
|
||||
extern const char* VMA_FUNCTION_NAMES[];
|
||||
|
||||
extern const char* VMA_POOL_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VMA_POOL_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VMA_POOL_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_BUFFER_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_BUFFER_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VK_BUFFER_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_BUFFER_USAGE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_BUFFER_USAGE_FLAG_VALUES[];
|
||||
extern const size_t VK_BUFFER_USAGE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_SHARING_MODE_NAMES[];
|
||||
extern const size_t VK_SHARING_MODE_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VK_IMAGE_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TYPE_NAMES[];
|
||||
extern const size_t VK_IMAGE_TYPE_COUNT;
|
||||
|
||||
extern const char* VK_FORMAT_NAMES[];
|
||||
extern const uint32_t VK_FORMAT_VALUES[];
|
||||
extern const size_t VK_FORMAT_COUNT;
|
||||
|
||||
extern const char* VK_SAMPLE_COUNT_NAMES[];
|
||||
extern const uint32_t VK_SAMPLE_COUNT_VALUES[];
|
||||
extern const size_t VK_SAMPLE_COUNT_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TILING_NAMES[];
|
||||
extern const size_t VK_IMAGE_TILING_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_USAGE_FLAG_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_USAGE_FLAG_VALUES[];
|
||||
extern const size_t VK_IMAGE_USAGE_FLAG_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_TILING_NAMES[];
|
||||
extern const size_t VK_IMAGE_TILING_COUNT;
|
||||
|
||||
extern const char* VK_IMAGE_LAYOUT_NAMES[];
|
||||
extern const uint32_t VK_IMAGE_LAYOUT_VALUES[];
|
||||
extern const size_t VK_IMAGE_LAYOUT_COUNT;
|
||||
|
||||
extern const char* VMA_ALLOCATION_CREATE_FLAG_NAMES[];
|
||||
extern const uint32_t VMA_ALLOCATION_CREATE_FLAG_VALUES[];
|
||||
extern const size_t VMA_ALLOCATION_CREATE_FLAG_COUNT;
|
||||
|
||||
extern const char* VMA_MEMORY_USAGE_NAMES[];
|
||||
extern const size_t VMA_MEMORY_USAGE_COUNT;
|
||||
|
||||
extern const char* VK_MEMORY_PROPERTY_FLAG_NAMES[];
|
||||
extern const uint32_t VK_MEMORY_PROPERTY_FLAG_VALUES[];
|
||||
extern const size_t VK_MEMORY_PROPERTY_FLAG_COUNT;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,24 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "VmaUsage.h"
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "VmaUsage.h"
|
||||
|
@ -1,52 +1,52 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif // #if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
//#define VMA_USE_STL_CONTAINERS 1
|
||||
|
||||
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
||||
|
||||
//#define VMA_DEDICATED_ALLOCATION 0
|
||||
|
||||
//#define VMA_DEBUG_MARGIN 16
|
||||
//#define VMA_DEBUG_DETECT_CORRUPTION 1
|
||||
//#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1
|
||||
|
||||
#pragma warning(push, 4)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#pragma warning(disable: 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable: 4189) // local variable is initialized but not referenced
|
||||
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
|
||||
|
||||
#include "../../include/vk_mem_alloc.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif // #if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
//#define VMA_USE_STL_CONTAINERS 1
|
||||
|
||||
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
||||
|
||||
//#define VMA_DEDICATED_ALLOCATION 0
|
||||
|
||||
//#define VMA_DEBUG_MARGIN 16
|
||||
//#define VMA_DEBUG_DETECT_CORRUPTION 1
|
||||
//#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1
|
||||
|
||||
#pragma warning(push, 4)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#pragma warning(disable: 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable: 4189) // local variable is initialized but not referenced
|
||||
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
|
||||
|
||||
#include "../../include/vk_mem_alloc.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
|
@ -1,30 +1,30 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
/*
|
||||
In exactly one CPP file define macro VMA_IMPLEMENTATION and then include
|
||||
vk_mem_alloc.h to include definitions of its internal implementation
|
||||
*/
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#include "VmaUsage.h"
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
/*
|
||||
In exactly one CPP file define macro VMA_IMPLEMENTATION and then include
|
||||
vk_mem_alloc.h to include definitions of its internal implementation
|
||||
*/
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#include "VmaUsage.h"
|
||||
|
196
src/VmaUsage.h
196
src/VmaUsage.h
@ -1,98 +1,98 @@
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef VMA_USAGE_H_
|
||||
#define VMA_USAGE_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif // #if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
|
||||
#else // #ifdef _WIN32
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
|
||||
// Uncomment to test including `vulkan.h` on your own before including VMA.
|
||||
//#include <vulkan/vulkan.h>
|
||||
|
||||
/*
|
||||
In every place where you want to use Vulkan Memory Allocator, define appropriate
|
||||
macros if you want to configure the library and then include its header to
|
||||
include all public interface declarations. Example:
|
||||
*/
|
||||
|
||||
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
||||
//#define VMA_DEDICATED_ALLOCATION 0
|
||||
//#define VMA_DEBUG_MARGIN 16
|
||||
//#define VMA_DEBUG_DETECT_CORRUPTION 1
|
||||
//#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY 256
|
||||
//#define VMA_USE_STL_SHARED_MUTEX 0
|
||||
//#define VMA_MEMORY_BUDGET 0
|
||||
|
||||
#define VMA_VULKAN_VERSION 1002000 // Vulkan 1.2
|
||||
//#define VMA_VULKAN_VERSION 1001000 // Vulkan 1.1
|
||||
//#define VMA_VULKAN_VERSION 1000000 // Vulkan 1.0
|
||||
|
||||
/*
|
||||
#define VMA_DEBUG_LOG(format, ...) do { \
|
||||
printf(format, __VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} while(false)
|
||||
*/
|
||||
|
||||
#pragma warning(push, 4)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#pragma warning(disable: 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable: 4189) // local variable is initialized but not referenced
|
||||
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
|
||||
|
||||
#endif // #ifdef _MSVC_LANG
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare" // comparison of unsigned expression < 0 is always false
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wnullability-completeness"
|
||||
#endif
|
||||
|
||||
#include "../include/vk_mem_alloc.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. 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.
|
||||
//
|
||||
|
||||
#ifndef VMA_USAGE_H_
|
||||
#define VMA_USAGE_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif // #if !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
|
||||
#else // #ifdef _WIN32
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
|
||||
// Uncomment to test including `vulkan.h` on your own before including VMA.
|
||||
//#include <vulkan/vulkan.h>
|
||||
|
||||
/*
|
||||
In every place where you want to use Vulkan Memory Allocator, define appropriate
|
||||
macros if you want to configure the library and then include its header to
|
||||
include all public interface declarations. Example:
|
||||
*/
|
||||
|
||||
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
|
||||
//#define VMA_DEDICATED_ALLOCATION 0
|
||||
//#define VMA_DEBUG_MARGIN 16
|
||||
//#define VMA_DEBUG_DETECT_CORRUPTION 1
|
||||
//#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY 256
|
||||
//#define VMA_USE_STL_SHARED_MUTEX 0
|
||||
//#define VMA_MEMORY_BUDGET 0
|
||||
|
||||
#define VMA_VULKAN_VERSION 1002000 // Vulkan 1.2
|
||||
//#define VMA_VULKAN_VERSION 1001000 // Vulkan 1.1
|
||||
//#define VMA_VULKAN_VERSION 1000000 // Vulkan 1.0
|
||||
|
||||
/*
|
||||
#define VMA_DEBUG_LOG(format, ...) do { \
|
||||
printf(format, __VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} while(false)
|
||||
*/
|
||||
|
||||
#pragma warning(push, 4)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#pragma warning(disable: 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable: 4189) // local variable is initialized but not referenced
|
||||
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
|
||||
|
||||
#endif // #ifdef _MSVC_LANG
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare" // comparison of unsigned expression < 0 is always false
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wnullability-completeness"
|
||||
#endif
|
||||
|
||||
#include "../include/vk_mem_alloc.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
5230
src/VulkanSample.cpp
5230
src/VulkanSample.cpp
File diff suppressed because it is too large
Load Diff
@ -1,40 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="VmaRawList<*>">
|
||||
<DisplayString>{{ Count={m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_Count</Item>
|
||||
<LinkedListItems>
|
||||
<Size>m_Count</Size>
|
||||
<HeadPointer>m_pFront</HeadPointer>
|
||||
<NextPointer>pNext</NextPointer>
|
||||
<ValueNode>Value</ValueNode>
|
||||
</LinkedListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="VmaList<*>">
|
||||
<DisplayString>{{ Count={m_RawList.m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_RawList.m_Count</Item>
|
||||
<LinkedListItems>
|
||||
<Size>m_RawList.m_Count</Size>
|
||||
<HeadPointer>m_RawList.m_pFront</HeadPointer>
|
||||
<NextPointer>pNext</NextPointer>
|
||||
<ValueNode>Value</ValueNode>
|
||||
</LinkedListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="VmaVector<*>">
|
||||
<DisplayString>{{ Count={m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_Count</Item>
|
||||
<Item Name="[Capacity]">m_Capacity</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_Count</Size>
|
||||
<ValuePointer>m_pArray</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="VmaRawList<*>">
|
||||
<DisplayString>{{ Count={m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_Count</Item>
|
||||
<LinkedListItems>
|
||||
<Size>m_Count</Size>
|
||||
<HeadPointer>m_pFront</HeadPointer>
|
||||
<NextPointer>pNext</NextPointer>
|
||||
<ValueNode>Value</ValueNode>
|
||||
</LinkedListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="VmaList<*>">
|
||||
<DisplayString>{{ Count={m_RawList.m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_RawList.m_Count</Item>
|
||||
<LinkedListItems>
|
||||
<Size>m_RawList.m_Count</Size>
|
||||
<HeadPointer>m_RawList.m_pFront</HeadPointer>
|
||||
<NextPointer>pNext</NextPointer>
|
||||
<ValueNode>Value</ValueNode>
|
||||
</LinkedListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="VmaVector<*>">
|
||||
<DisplayString>{{ Count={m_Count} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[Count]">m_Count</Item>
|
||||
<Item Name="[Capacity]">m_Capacity</Item>
|
||||
<ArrayItems>
|
||||
<Size>m_Count</Size>
|
||||
<ValuePointer>m_pArray</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
@ -1,42 +1,42 @@
|
||||
# VMA Dump Vis
|
||||
|
||||
Vulkan Memory Allocator Dump Visualization. It is an auxiliary tool that can visualize internal state of [Vulkan Memory Allocator](../../README.md) library on a picture. It is a Python script that must be launched from command line with appropriate parameters.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3 installed
|
||||
- [Pillow](http://python-pillow.org/) - Python Imaging Library (Fork) installed
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
python VmaDumpVis.py -o OUTPUT_FILE INPUT_FILE
|
||||
```
|
||||
|
||||
* `INPUT_FILE` - path to source file to be read, containing dump of internal state of the VMA library in JSON format (encoding: UTF-8), generated using `vmaBuildStatsString()` function.
|
||||
* `OUTPUT_FILE` - path to destination file to be written that will contain generated image. Image format is automatically recognized based on file extension. List of supported formats can be found [here](http://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html) and includes: BMP, GIF, JPEG, PNG, TGA.
|
||||
|
||||
You can also use typical options:
|
||||
|
||||
* `-h` - to see help on command line syntax
|
||||
* `-v` - to see program version number
|
||||
|
||||
## Example output
|
||||
|
||||
![Example output](README_files/ExampleOutput.png "Example output")
|
||||
|
||||
## Legend
|
||||
|
||||
* ![Free space](README_files/Legend_Bkg.png "Free space") Light gray without border - a space in Vulkan device memory block unused by any allocation.
|
||||
* ![Buffer 1](README_files/Legend_Buffer_1.png "Buffer 1") Buffer with usage containing INDIRECT_BUFFER, VERTEX_BUFFER, or INDEX_BUFFER.
|
||||
* ![Buffer 2](README_files/Legend_Buffer_2.png "Buffer 2") Buffer with usage containing STORAGE_BUFFER or STORAGE_TEXEL_BUFFER.
|
||||
* ![Buffer 3](README_files/Legend_Buffer_3.png "Buffer 3") Buffer with usage containing UNIFORM_BUFFER or UNIFORM_TEXEL_BUFFER.
|
||||
* ![Buffer 4](README_files/Legend_Buffer_4.png "Buffer 4") Other buffer.
|
||||
* ![Image 1](README_files/Legend_Image_1.png "Image 1") Image with OPTIMAL tiling and usage containing DEPTH_STENCIL_ATTACHMENT.
|
||||
* ![Image 2](README_files/Legend_Image_2.png "Image 2") Image with OPTIMAL tiling and usage containing INPUT_ATTACHMENT, TRANSIENT_ATTACHMENT, or COLOR_ATTACHMENT.
|
||||
* ![Image 3](README_files/Legend_Image_3.png "Image 3") Image with OPTIMAL tiling and usage containing SAMPLED.
|
||||
* ![Image 4](README_files/Legend_Image_4.png "Image 4") Other image with OPTIMAL tiling.
|
||||
* ![Image Linear](README_files/Legend_Image_Linear.png "Image Linear") Image with LINEAR tiling.
|
||||
* ![Image Unknown](README_files/Legend_Image_Unknown.png "Image Unknown") Image with tiling unknown to the allocator.
|
||||
* ![Unknown](README_files/Legend_Unknown.png "Unknown") Allocation of unknown type.
|
||||
* ![Details](README_files/Legend_Details.png "Details") Black bar - one or more allocations of any kind too small to be visualized as filled rectangles.
|
||||
# VMA Dump Vis
|
||||
|
||||
Vulkan Memory Allocator Dump Visualization. It is an auxiliary tool that can visualize internal state of [Vulkan Memory Allocator](../../README.md) library on a picture. It is a Python script that must be launched from command line with appropriate parameters.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3 installed
|
||||
- [Pillow](http://python-pillow.org/) - Python Imaging Library (Fork) installed
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
python VmaDumpVis.py -o OUTPUT_FILE INPUT_FILE
|
||||
```
|
||||
|
||||
* `INPUT_FILE` - path to source file to be read, containing dump of internal state of the VMA library in JSON format (encoding: UTF-8), generated using `vmaBuildStatsString()` function.
|
||||
* `OUTPUT_FILE` - path to destination file to be written that will contain generated image. Image format is automatically recognized based on file extension. List of supported formats can be found [here](http://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html) and includes: BMP, GIF, JPEG, PNG, TGA.
|
||||
|
||||
You can also use typical options:
|
||||
|
||||
* `-h` - to see help on command line syntax
|
||||
* `-v` - to see program version number
|
||||
|
||||
## Example output
|
||||
|
||||
![Example output](README_files/ExampleOutput.png "Example output")
|
||||
|
||||
## Legend
|
||||
|
||||
* ![Free space](README_files/Legend_Bkg.png "Free space") Light gray without border - a space in Vulkan device memory block unused by any allocation.
|
||||
* ![Buffer 1](README_files/Legend_Buffer_1.png "Buffer 1") Buffer with usage containing INDIRECT_BUFFER, VERTEX_BUFFER, or INDEX_BUFFER.
|
||||
* ![Buffer 2](README_files/Legend_Buffer_2.png "Buffer 2") Buffer with usage containing STORAGE_BUFFER or STORAGE_TEXEL_BUFFER.
|
||||
* ![Buffer 3](README_files/Legend_Buffer_3.png "Buffer 3") Buffer with usage containing UNIFORM_BUFFER or UNIFORM_TEXEL_BUFFER.
|
||||
* ![Buffer 4](README_files/Legend_Buffer_4.png "Buffer 4") Other buffer.
|
||||
* ![Image 1](README_files/Legend_Image_1.png "Image 1") Image with OPTIMAL tiling and usage containing DEPTH_STENCIL_ATTACHMENT.
|
||||
* ![Image 2](README_files/Legend_Image_2.png "Image 2") Image with OPTIMAL tiling and usage containing INPUT_ATTACHMENT, TRANSIENT_ATTACHMENT, or COLOR_ATTACHMENT.
|
||||
* ![Image 3](README_files/Legend_Image_3.png "Image 3") Image with OPTIMAL tiling and usage containing SAMPLED.
|
||||
* ![Image 4](README_files/Legend_Image_4.png "Image 4") Other image with OPTIMAL tiling.
|
||||
* ![Image Linear](README_files/Legend_Image_Linear.png "Image Linear") Image with LINEAR tiling.
|
||||
* ![Image Unknown](README_files/Legend_Image_Unknown.png "Image Unknown") Image with tiling unknown to the allocator.
|
||||
* ![Unknown](README_files/Legend_Unknown.png "Unknown") Allocation of unknown type.
|
||||
* ![Details](README_files/Legend_Details.png "Details") Black bar - one or more allocations of any kind too small to be visualized as filled rectangles.
|
||||
|
@ -1,102 +1,102 @@
|
||||
{
|
||||
"Total": {
|
||||
"Blocks": 2,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 3,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 59046740,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 19682247, "Max": 33554432}
|
||||
},
|
||||
"Heap 0": {
|
||||
"Size": 8304721920,
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 25492308,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 12746154, "Max": 25427600}
|
||||
},
|
||||
"Type 0": {
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 25492308,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 12746154, "Max": 25427600}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Heap 1": {
|
||||
"Size": 8285323264,
|
||||
"Flags": [],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"UsedBytes": 0,
|
||||
"UnusedBytes": 33554432
|
||||
},
|
||||
"Type 1": {
|
||||
"Flags": ["HOST_VISIBLE", "HOST_COHERENT"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"UsedBytes": 0,
|
||||
"UnusedBytes": 33554432
|
||||
}
|
||||
},
|
||||
"Type 3": {
|
||||
"Flags": ["HOST_VISIBLE", "HOST_COHERENT", "HOST_CACHED"]
|
||||
}
|
||||
},
|
||||
"Heap 2": {
|
||||
"Size": 268435456,
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Type 2": {
|
||||
"Flags": ["DEVICE_LOCAL", "HOST_VISIBLE", "HOST_COHERENT"]
|
||||
}
|
||||
},
|
||||
"DefaultPools": {
|
||||
"Type 0": {
|
||||
"PreferredBlockSize": 268435456,
|
||||
"Blocks": {
|
||||
"0": {
|
||||
"TotalBytes": 33554432,
|
||||
"UnusedBytes": 25492308,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"Suballocations": [
|
||||
{"Offset": 0, "Type": "IMAGE_OPTIMAL", "Size": 65536, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 6},
|
||||
{"Offset": 65536, "Type": "BUFFER", "Size": 768, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 130},
|
||||
{"Offset": 66304, "Type": "BUFFER", "Size": 60, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 66},
|
||||
{"Offset": 66364, "Type": "FREE", "Size": 64708},
|
||||
{"Offset": 131072, "Type": "IMAGE_OPTIMAL", "Size": 7995760, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 32},
|
||||
{"Offset": 8126832, "Type": "FREE", "Size": 25427600}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Type 1": {
|
||||
"PreferredBlockSize": 268435456,
|
||||
"Blocks": {
|
||||
"0": {
|
||||
"TotalBytes": 33554432,
|
||||
"UnusedBytes": 33554432,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"Suballocations": [
|
||||
{"Offset": 0, "Type": "FREE", "Size": 33554432}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"Total": {
|
||||
"Blocks": 2,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 3,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 59046740,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 19682247, "Max": 33554432}
|
||||
},
|
||||
"Heap 0": {
|
||||
"Size": 8304721920,
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 25492308,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 12746154, "Max": 25427600}
|
||||
},
|
||||
"Type 0": {
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"UsedBytes": 8062124,
|
||||
"UnusedBytes": 25492308,
|
||||
"AllocationSize": {"Min": 60, "Avg": 2015531, "Max": 7995760},
|
||||
"UnusedRangeSize": {"Min": 64708, "Avg": 12746154, "Max": 25427600}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Heap 1": {
|
||||
"Size": 8285323264,
|
||||
"Flags": [],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"UsedBytes": 0,
|
||||
"UnusedBytes": 33554432
|
||||
},
|
||||
"Type 1": {
|
||||
"Flags": ["HOST_VISIBLE", "HOST_COHERENT"],
|
||||
"Stats": {
|
||||
"Blocks": 1,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"UsedBytes": 0,
|
||||
"UnusedBytes": 33554432
|
||||
}
|
||||
},
|
||||
"Type 3": {
|
||||
"Flags": ["HOST_VISIBLE", "HOST_COHERENT", "HOST_CACHED"]
|
||||
}
|
||||
},
|
||||
"Heap 2": {
|
||||
"Size": 268435456,
|
||||
"Flags": ["DEVICE_LOCAL"],
|
||||
"Type 2": {
|
||||
"Flags": ["DEVICE_LOCAL", "HOST_VISIBLE", "HOST_COHERENT"]
|
||||
}
|
||||
},
|
||||
"DefaultPools": {
|
||||
"Type 0": {
|
||||
"PreferredBlockSize": 268435456,
|
||||
"Blocks": {
|
||||
"0": {
|
||||
"TotalBytes": 33554432,
|
||||
"UnusedBytes": 25492308,
|
||||
"Allocations": 4,
|
||||
"UnusedRanges": 2,
|
||||
"Suballocations": [
|
||||
{"Offset": 0, "Type": "IMAGE_OPTIMAL", "Size": 65536, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 6},
|
||||
{"Offset": 65536, "Type": "BUFFER", "Size": 768, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 130},
|
||||
{"Offset": 66304, "Type": "BUFFER", "Size": 60, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 66},
|
||||
{"Offset": 66364, "Type": "FREE", "Size": 64708},
|
||||
{"Offset": 131072, "Type": "IMAGE_OPTIMAL", "Size": 7995760, "CreationFrameIndex": 0, "LastUseFrameIndex": 0, "Usage": 32},
|
||||
{"Offset": 8126832, "Type": "FREE", "Size": 25427600}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Type 1": {
|
||||
"PreferredBlockSize": 268435456,
|
||||
"Blocks": {
|
||||
"0": {
|
||||
"TotalBytes": 33554432,
|
||||
"UnusedBytes": 33554432,
|
||||
"Allocations": 0,
|
||||
"UnusedRanges": 1,
|
||||
"Suballocations": [
|
||||
{"Offset": 0, "Type": "FREE", "Size": 33554432}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,305 +1,305 @@
|
||||
#
|
||||
# Copyright (c) 2018-2021 Advanced Micro Devices, Inc. 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 argparse
|
||||
import json
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
|
||||
PROGRAM_VERSION = 'VMA Dump Visualization 2.0.1'
|
||||
IMG_SIZE_X = 1200
|
||||
IMG_MARGIN = 8
|
||||
FONT_SIZE = 10
|
||||
MAP_SIZE = 24
|
||||
COLOR_TEXT_H1 = (0, 0, 0, 255)
|
||||
COLOR_TEXT_H2 = (150, 150, 150, 255)
|
||||
COLOR_OUTLINE = (155, 155, 155, 255)
|
||||
COLOR_OUTLINE_HARD = (0, 0, 0, 255)
|
||||
COLOR_GRID_LINE = (224, 224, 224, 255)
|
||||
|
||||
|
||||
argParser = argparse.ArgumentParser(description='Visualization of Vulkan Memory Allocator JSON dump.')
|
||||
argParser.add_argument('DumpFile', type=argparse.FileType(mode='r', encoding='UTF-8'), help='Path to source JSON file with memory dump created by Vulkan Memory Allocator library')
|
||||
argParser.add_argument('-v', '--version', action='version', version=PROGRAM_VERSION)
|
||||
argParser.add_argument('-o', '--output', required=True, help='Path to destination image file (e.g. PNG)')
|
||||
args = argParser.parse_args()
|
||||
|
||||
data = {}
|
||||
|
||||
|
||||
def ProcessBlock(dstBlockList, iBlockId, objBlock, sAlgorithm):
|
||||
iBlockSize = int(objBlock['TotalBytes'])
|
||||
arrSuballocs = objBlock['Suballocations']
|
||||
dstBlockObj = {'ID': iBlockId, 'Size':iBlockSize, 'Suballocations':[]}
|
||||
dstBlockObj['Algorithm'] = sAlgorithm
|
||||
for objSuballoc in arrSuballocs:
|
||||
dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size']), int(objSuballoc['Usage']) if ('Usage' in objSuballoc) else 0))
|
||||
dstBlockList.append(dstBlockObj)
|
||||
|
||||
|
||||
def GetDataForMemoryType(iMemTypeIndex):
|
||||
global data
|
||||
if iMemTypeIndex in data:
|
||||
return data[iMemTypeIndex]
|
||||
else:
|
||||
newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPools':{}}
|
||||
data[iMemTypeIndex] = newMemTypeData
|
||||
return newMemTypeData
|
||||
|
||||
|
||||
def IsDataEmpty():
|
||||
global data
|
||||
for dictMemType in data.values():
|
||||
if 'DedicatedAllocations' in dictMemType and len(dictMemType['DedicatedAllocations']) > 0:
|
||||
return False
|
||||
if 'DefaultPoolBlocks' in dictMemType and len(dictMemType['DefaultPoolBlocks']) > 0:
|
||||
return False
|
||||
if 'CustomPools' in dictMemType:
|
||||
for lBlockList in dictMemType['CustomPools'].values():
|
||||
if len(lBlockList) > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# Returns tuple:
|
||||
# [0] image height : integer
|
||||
# [1] pixels per byte : float
|
||||
def CalcParams():
|
||||
global data
|
||||
iImgSizeY = IMG_MARGIN
|
||||
iImgSizeY += FONT_SIZE + IMG_MARGIN # Grid lines legend - sizes
|
||||
iMaxBlockSize = 0
|
||||
for dictMemType in data.values():
|
||||
iImgSizeY += IMG_MARGIN + FONT_SIZE
|
||||
lDedicatedAllocations = dictMemType['DedicatedAllocations']
|
||||
iImgSizeY += len(lDedicatedAllocations) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for tDedicatedAlloc in lDedicatedAllocations:
|
||||
iMaxBlockSize = max(iMaxBlockSize, tDedicatedAlloc[1])
|
||||
lDefaultPoolBlocks = dictMemType['DefaultPoolBlocks']
|
||||
iImgSizeY += len(lDefaultPoolBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for objBlock in lDefaultPoolBlocks:
|
||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||
dCustomPools = dictMemType['CustomPools']
|
||||
for lBlocks in dCustomPools.values():
|
||||
iImgSizeY += len(lBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for objBlock in lBlocks:
|
||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||
fPixelsPerByte = (IMG_SIZE_X - IMG_MARGIN * 2) / float(iMaxBlockSize)
|
||||
return iImgSizeY, fPixelsPerByte
|
||||
|
||||
|
||||
def TypeToColor(sType, iUsage):
|
||||
if sType == 'FREE':
|
||||
return 220, 220, 220, 255
|
||||
elif sType == 'BUFFER':
|
||||
if (iUsage & 0x1C0) != 0: # INDIRECT_BUFFER | VERTEX_BUFFER | INDEX_BUFFER
|
||||
return 255, 148, 148, 255 # Red
|
||||
elif (iUsage & 0x28) != 0: # STORAGE_BUFFER | STORAGE_TEXEL_BUFFER
|
||||
return 255, 187, 121, 255 # Orange
|
||||
elif (iUsage & 0x14) != 0: # UNIFORM_BUFFER | UNIFORM_TEXEL_BUFFER
|
||||
return 255, 255, 0, 255 # Yellow
|
||||
else:
|
||||
return 255, 255, 165, 255 # Light yellow
|
||||
elif sType == 'IMAGE_OPTIMAL':
|
||||
if (iUsage & 0x20) != 0: # DEPTH_STENCIL_ATTACHMENT
|
||||
return 246, 128, 255, 255 # Pink
|
||||
elif (iUsage & 0xD0) != 0: # INPUT_ATTACHMENT | TRANSIENT_ATTACHMENT | COLOR_ATTACHMENT
|
||||
return 179, 179, 255, 255 # Blue
|
||||
elif (iUsage & 0x4) != 0: # SAMPLED
|
||||
return 0, 255, 255, 255 # Aqua
|
||||
else:
|
||||
return 183, 255, 255, 255 # Light aqua
|
||||
elif sType == 'IMAGE_LINEAR':
|
||||
return 0, 255, 0, 255 # Green
|
||||
elif sType == 'IMAGE_UNKNOWN':
|
||||
return 0, 255, 164, 255 # Green/aqua
|
||||
elif sType == 'UNKNOWN':
|
||||
return 175, 175, 175, 255 # Gray
|
||||
assert False
|
||||
return 0, 0, 0, 255
|
||||
|
||||
|
||||
def DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc):
|
||||
global fPixelsPerByte
|
||||
iSizeBytes = tDedicatedAlloc[1]
|
||||
iSizePixels = int(iSizeBytes * fPixelsPerByte)
|
||||
draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor(tDedicatedAlloc[0], tDedicatedAlloc[2]), outline=COLOR_OUTLINE)
|
||||
|
||||
|
||||
def DrawBlock(draw, y, objBlock):
|
||||
global fPixelsPerByte
|
||||
iSizeBytes = objBlock['Size']
|
||||
iSizePixels = int(iSizeBytes * fPixelsPerByte)
|
||||
draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor('FREE', 0), outline=None)
|
||||
iByte = 0
|
||||
iX = 0
|
||||
iLastHardLineX = -1
|
||||
for tSuballoc in objBlock['Suballocations']:
|
||||
sType = tSuballoc[0]
|
||||
iByteEnd = iByte + tSuballoc[1]
|
||||
iXEnd = int(iByteEnd * fPixelsPerByte)
|
||||
if sType != 'FREE':
|
||||
if iXEnd > iX + 1:
|
||||
iUsage = tSuballoc[2]
|
||||
draw.rectangle([IMG_MARGIN + iX, y, IMG_MARGIN + iXEnd, y + MAP_SIZE], fill=TypeToColor(sType, iUsage), outline=COLOR_OUTLINE)
|
||||
# Hard line was been overwritten by rectangle outline: redraw it.
|
||||
if iLastHardLineX == iX:
|
||||
draw.line([IMG_MARGIN + iX, y, IMG_MARGIN + iX, y + MAP_SIZE], fill=COLOR_OUTLINE_HARD)
|
||||
else:
|
||||
draw.line([IMG_MARGIN + iX, y, IMG_MARGIN + iX, y + MAP_SIZE], fill=COLOR_OUTLINE_HARD)
|
||||
iLastHardLineX = iX
|
||||
iByte = iByteEnd
|
||||
iX = iXEnd
|
||||
|
||||
|
||||
def BytesToStr(iBytes):
|
||||
if iBytes < 1024:
|
||||
return "%d B" % iBytes
|
||||
iBytes /= 1024
|
||||
if iBytes < 1024:
|
||||
return "%d KiB" % iBytes
|
||||
iBytes /= 1024
|
||||
if iBytes < 1024:
|
||||
return "%d MiB" % iBytes
|
||||
iBytes /= 1024
|
||||
return "%d GiB" % iBytes
|
||||
|
||||
|
||||
jsonSrc = json.load(args.DumpFile)
|
||||
if 'DedicatedAllocations' in jsonSrc:
|
||||
for tType in jsonSrc['DedicatedAllocations'].items():
|
||||
sType = tType[0]
|
||||
assert sType[:5] == 'Type '
|
||||
iType = int(sType[5:])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
for objAlloc in tType[1]:
|
||||
typeData['DedicatedAllocations'].append((objAlloc['Type'], int(objAlloc['Size']), int(objAlloc['Usage']) if ('Usage' in objAlloc) else 0))
|
||||
if 'DefaultPools' in jsonSrc:
|
||||
for tType in jsonSrc['DefaultPools'].items():
|
||||
sType = tType[0]
|
||||
assert sType[:5] == 'Type '
|
||||
iType = int(sType[5:])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
for sBlockId, objBlock in tType[1]['Blocks'].items():
|
||||
ProcessBlock(typeData['DefaultPoolBlocks'], int(sBlockId), objBlock, '')
|
||||
if 'Pools' in jsonSrc:
|
||||
objPools = jsonSrc['Pools']
|
||||
for sPoolId, objPool in objPools.items():
|
||||
iType = int(objPool['MemoryTypeIndex'])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
objBlocks = objPool['Blocks']
|
||||
sAlgorithm = objPool.get('Algorithm', '')
|
||||
sName = objPool.get('Name', None)
|
||||
if sName:
|
||||
sFullName = sPoolId + ' "' + sName + '"'
|
||||
else:
|
||||
sFullName = sPoolId
|
||||
dstBlockArray = []
|
||||
typeData['CustomPools'][sFullName] = dstBlockArray
|
||||
for sBlockId, objBlock in objBlocks.items():
|
||||
ProcessBlock(dstBlockArray, int(sBlockId), objBlock, sAlgorithm)
|
||||
|
||||
if IsDataEmpty():
|
||||
print("There is nothing to put on the image. Please make sure you generated the stats string with detailed map enabled.")
|
||||
exit(1)
|
||||
|
||||
iImgSizeY, fPixelsPerByte = CalcParams()
|
||||
|
||||
img = Image.new('RGB', (IMG_SIZE_X, iImgSizeY), 'white')
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
try:
|
||||
font = ImageFont.truetype('segoeuib.ttf')
|
||||
except:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
y = IMG_MARGIN
|
||||
|
||||
# Draw grid lines
|
||||
iBytesBetweenGridLines = 32
|
||||
while iBytesBetweenGridLines * fPixelsPerByte < 64:
|
||||
iBytesBetweenGridLines *= 2
|
||||
iByte = 0
|
||||
TEXT_MARGIN = 4
|
||||
while True:
|
||||
iX = int(iByte * fPixelsPerByte)
|
||||
if iX > IMG_SIZE_X - 2 * IMG_MARGIN:
|
||||
break
|
||||
draw.line([iX + IMG_MARGIN, 0, iX + IMG_MARGIN, iImgSizeY], fill=COLOR_GRID_LINE)
|
||||
if iByte == 0:
|
||||
draw.text((iX + IMG_MARGIN + TEXT_MARGIN, y), "0", fill=COLOR_TEXT_H2, font=font)
|
||||
else:
|
||||
text = BytesToStr(iByte)
|
||||
textSize = draw.textsize(text, font=font)
|
||||
draw.text((iX + IMG_MARGIN - textSize[0] - TEXT_MARGIN, y), text, fill=COLOR_TEXT_H2, font=font)
|
||||
iByte += iBytesBetweenGridLines
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
|
||||
# Draw main content
|
||||
for iMemTypeIndex in sorted(data.keys()):
|
||||
dictMemType = data[iMemTypeIndex]
|
||||
draw.text((IMG_MARGIN, y), "Memory type %d" % iMemTypeIndex, fill=COLOR_TEXT_H1, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
index = 0
|
||||
for tDedicatedAlloc in dictMemType['DedicatedAllocations']:
|
||||
draw.text((IMG_MARGIN, y), "Dedicated allocation %d" % index, fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index += 1
|
||||
for objBlock in dictMemType['DefaultPoolBlocks']:
|
||||
draw.text((IMG_MARGIN, y), "Default pool block %d" % objBlock['ID'], fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawBlock(draw, y, objBlock)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index = 0
|
||||
for sPoolName, listPool in dictMemType['CustomPools'].items():
|
||||
for objBlock in listPool:
|
||||
if 'Algorithm' in objBlock and objBlock['Algorithm']:
|
||||
sAlgorithm = ' (Algorithm: %s)' % (objBlock['Algorithm'])
|
||||
else:
|
||||
sAlgorithm = ''
|
||||
draw.text((IMG_MARGIN, y), "Custom pool %s%s block %d" % (sPoolName, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawBlock(draw, y, objBlock)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index += 1
|
||||
del draw
|
||||
img.save(args.output)
|
||||
|
||||
"""
|
||||
Main data structure - variable `data` - is a dictionary. Key is integer - memory type index. Value is dictionary of:
|
||||
- Fixed key 'DedicatedAllocations'. Value is list of tuples, each containing:
|
||||
- [0]: Type : string
|
||||
- [1]: Size : integer
|
||||
- [2]: Usage : integer (0 if unknown)
|
||||
- Fixed key 'DefaultPoolBlocks'. Value is list of objects, each containing dictionary with:
|
||||
- Fixed key 'ID'. Value is int.
|
||||
- Fixed key 'Size'. Value is int.
|
||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||
- Fixed key 'CustomPools'. Value is dictionary.
|
||||
- Key is string with pool ID/name. Value is list of objects representing memory blocks, each containing dictionary with:
|
||||
- Fixed key 'ID'. Value is int.
|
||||
- Fixed key 'Size'. Value is int.
|
||||
- Fixed key 'Algorithm'. Optional. Value is string.
|
||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||
"""
|
||||
#
|
||||
# Copyright (c) 2018-2021 Advanced Micro Devices, Inc. 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 argparse
|
||||
import json
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
|
||||
PROGRAM_VERSION = 'VMA Dump Visualization 2.0.1'
|
||||
IMG_SIZE_X = 1200
|
||||
IMG_MARGIN = 8
|
||||
FONT_SIZE = 10
|
||||
MAP_SIZE = 24
|
||||
COLOR_TEXT_H1 = (0, 0, 0, 255)
|
||||
COLOR_TEXT_H2 = (150, 150, 150, 255)
|
||||
COLOR_OUTLINE = (155, 155, 155, 255)
|
||||
COLOR_OUTLINE_HARD = (0, 0, 0, 255)
|
||||
COLOR_GRID_LINE = (224, 224, 224, 255)
|
||||
|
||||
|
||||
argParser = argparse.ArgumentParser(description='Visualization of Vulkan Memory Allocator JSON dump.')
|
||||
argParser.add_argument('DumpFile', type=argparse.FileType(mode='r', encoding='UTF-8'), help='Path to source JSON file with memory dump created by Vulkan Memory Allocator library')
|
||||
argParser.add_argument('-v', '--version', action='version', version=PROGRAM_VERSION)
|
||||
argParser.add_argument('-o', '--output', required=True, help='Path to destination image file (e.g. PNG)')
|
||||
args = argParser.parse_args()
|
||||
|
||||
data = {}
|
||||
|
||||
|
||||
def ProcessBlock(dstBlockList, iBlockId, objBlock, sAlgorithm):
|
||||
iBlockSize = int(objBlock['TotalBytes'])
|
||||
arrSuballocs = objBlock['Suballocations']
|
||||
dstBlockObj = {'ID': iBlockId, 'Size':iBlockSize, 'Suballocations':[]}
|
||||
dstBlockObj['Algorithm'] = sAlgorithm
|
||||
for objSuballoc in arrSuballocs:
|
||||
dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size']), int(objSuballoc['Usage']) if ('Usage' in objSuballoc) else 0))
|
||||
dstBlockList.append(dstBlockObj)
|
||||
|
||||
|
||||
def GetDataForMemoryType(iMemTypeIndex):
|
||||
global data
|
||||
if iMemTypeIndex in data:
|
||||
return data[iMemTypeIndex]
|
||||
else:
|
||||
newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPools':{}}
|
||||
data[iMemTypeIndex] = newMemTypeData
|
||||
return newMemTypeData
|
||||
|
||||
|
||||
def IsDataEmpty():
|
||||
global data
|
||||
for dictMemType in data.values():
|
||||
if 'DedicatedAllocations' in dictMemType and len(dictMemType['DedicatedAllocations']) > 0:
|
||||
return False
|
||||
if 'DefaultPoolBlocks' in dictMemType and len(dictMemType['DefaultPoolBlocks']) > 0:
|
||||
return False
|
||||
if 'CustomPools' in dictMemType:
|
||||
for lBlockList in dictMemType['CustomPools'].values():
|
||||
if len(lBlockList) > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# Returns tuple:
|
||||
# [0] image height : integer
|
||||
# [1] pixels per byte : float
|
||||
def CalcParams():
|
||||
global data
|
||||
iImgSizeY = IMG_MARGIN
|
||||
iImgSizeY += FONT_SIZE + IMG_MARGIN # Grid lines legend - sizes
|
||||
iMaxBlockSize = 0
|
||||
for dictMemType in data.values():
|
||||
iImgSizeY += IMG_MARGIN + FONT_SIZE
|
||||
lDedicatedAllocations = dictMemType['DedicatedAllocations']
|
||||
iImgSizeY += len(lDedicatedAllocations) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for tDedicatedAlloc in lDedicatedAllocations:
|
||||
iMaxBlockSize = max(iMaxBlockSize, tDedicatedAlloc[1])
|
||||
lDefaultPoolBlocks = dictMemType['DefaultPoolBlocks']
|
||||
iImgSizeY += len(lDefaultPoolBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for objBlock in lDefaultPoolBlocks:
|
||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||
dCustomPools = dictMemType['CustomPools']
|
||||
for lBlocks in dCustomPools.values():
|
||||
iImgSizeY += len(lBlocks) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||
for objBlock in lBlocks:
|
||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||
fPixelsPerByte = (IMG_SIZE_X - IMG_MARGIN * 2) / float(iMaxBlockSize)
|
||||
return iImgSizeY, fPixelsPerByte
|
||||
|
||||
|
||||
def TypeToColor(sType, iUsage):
|
||||
if sType == 'FREE':
|
||||
return 220, 220, 220, 255
|
||||
elif sType == 'BUFFER':
|
||||
if (iUsage & 0x1C0) != 0: # INDIRECT_BUFFER | VERTEX_BUFFER | INDEX_BUFFER
|
||||
return 255, 148, 148, 255 # Red
|
||||
elif (iUsage & 0x28) != 0: # STORAGE_BUFFER | STORAGE_TEXEL_BUFFER
|
||||
return 255, 187, 121, 255 # Orange
|
||||
elif (iUsage & 0x14) != 0: # UNIFORM_BUFFER | UNIFORM_TEXEL_BUFFER
|
||||
return 255, 255, 0, 255 # Yellow
|
||||
else:
|
||||
return 255, 255, 165, 255 # Light yellow
|
||||
elif sType == 'IMAGE_OPTIMAL':
|
||||
if (iUsage & 0x20) != 0: # DEPTH_STENCIL_ATTACHMENT
|
||||
return 246, 128, 255, 255 # Pink
|
||||
elif (iUsage & 0xD0) != 0: # INPUT_ATTACHMENT | TRANSIENT_ATTACHMENT | COLOR_ATTACHMENT
|
||||
return 179, 179, 255, 255 # Blue
|
||||
elif (iUsage & 0x4) != 0: # SAMPLED
|
||||
return 0, 255, 255, 255 # Aqua
|
||||
else:
|
||||
return 183, 255, 255, 255 # Light aqua
|
||||
elif sType == 'IMAGE_LINEAR':
|
||||
return 0, 255, 0, 255 # Green
|
||||
elif sType == 'IMAGE_UNKNOWN':
|
||||
return 0, 255, 164, 255 # Green/aqua
|
||||
elif sType == 'UNKNOWN':
|
||||
return 175, 175, 175, 255 # Gray
|
||||
assert False
|
||||
return 0, 0, 0, 255
|
||||
|
||||
|
||||
def DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc):
|
||||
global fPixelsPerByte
|
||||
iSizeBytes = tDedicatedAlloc[1]
|
||||
iSizePixels = int(iSizeBytes * fPixelsPerByte)
|
||||
draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor(tDedicatedAlloc[0], tDedicatedAlloc[2]), outline=COLOR_OUTLINE)
|
||||
|
||||
|
||||
def DrawBlock(draw, y, objBlock):
|
||||
global fPixelsPerByte
|
||||
iSizeBytes = objBlock['Size']
|
||||
iSizePixels = int(iSizeBytes * fPixelsPerByte)
|
||||
draw.rectangle([IMG_MARGIN, y, IMG_MARGIN + iSizePixels, y + MAP_SIZE], fill=TypeToColor('FREE', 0), outline=None)
|
||||
iByte = 0
|
||||
iX = 0
|
||||
iLastHardLineX = -1
|
||||
for tSuballoc in objBlock['Suballocations']:
|
||||
sType = tSuballoc[0]
|
||||
iByteEnd = iByte + tSuballoc[1]
|
||||
iXEnd = int(iByteEnd * fPixelsPerByte)
|
||||
if sType != 'FREE':
|
||||
if iXEnd > iX + 1:
|
||||
iUsage = tSuballoc[2]
|
||||
draw.rectangle([IMG_MARGIN + iX, y, IMG_MARGIN + iXEnd, y + MAP_SIZE], fill=TypeToColor(sType, iUsage), outline=COLOR_OUTLINE)
|
||||
# Hard line was been overwritten by rectangle outline: redraw it.
|
||||
if iLastHardLineX == iX:
|
||||
draw.line([IMG_MARGIN + iX, y, IMG_MARGIN + iX, y + MAP_SIZE], fill=COLOR_OUTLINE_HARD)
|
||||
else:
|
||||
draw.line([IMG_MARGIN + iX, y, IMG_MARGIN + iX, y + MAP_SIZE], fill=COLOR_OUTLINE_HARD)
|
||||
iLastHardLineX = iX
|
||||
iByte = iByteEnd
|
||||
iX = iXEnd
|
||||
|
||||
|
||||
def BytesToStr(iBytes):
|
||||
if iBytes < 1024:
|
||||
return "%d B" % iBytes
|
||||
iBytes /= 1024
|
||||
if iBytes < 1024:
|
||||
return "%d KiB" % iBytes
|
||||
iBytes /= 1024
|
||||
if iBytes < 1024:
|
||||
return "%d MiB" % iBytes
|
||||
iBytes /= 1024
|
||||
return "%d GiB" % iBytes
|
||||
|
||||
|
||||
jsonSrc = json.load(args.DumpFile)
|
||||
if 'DedicatedAllocations' in jsonSrc:
|
||||
for tType in jsonSrc['DedicatedAllocations'].items():
|
||||
sType = tType[0]
|
||||
assert sType[:5] == 'Type '
|
||||
iType = int(sType[5:])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
for objAlloc in tType[1]:
|
||||
typeData['DedicatedAllocations'].append((objAlloc['Type'], int(objAlloc['Size']), int(objAlloc['Usage']) if ('Usage' in objAlloc) else 0))
|
||||
if 'DefaultPools' in jsonSrc:
|
||||
for tType in jsonSrc['DefaultPools'].items():
|
||||
sType = tType[0]
|
||||
assert sType[:5] == 'Type '
|
||||
iType = int(sType[5:])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
for sBlockId, objBlock in tType[1]['Blocks'].items():
|
||||
ProcessBlock(typeData['DefaultPoolBlocks'], int(sBlockId), objBlock, '')
|
||||
if 'Pools' in jsonSrc:
|
||||
objPools = jsonSrc['Pools']
|
||||
for sPoolId, objPool in objPools.items():
|
||||
iType = int(objPool['MemoryTypeIndex'])
|
||||
typeData = GetDataForMemoryType(iType)
|
||||
objBlocks = objPool['Blocks']
|
||||
sAlgorithm = objPool.get('Algorithm', '')
|
||||
sName = objPool.get('Name', None)
|
||||
if sName:
|
||||
sFullName = sPoolId + ' "' + sName + '"'
|
||||
else:
|
||||
sFullName = sPoolId
|
||||
dstBlockArray = []
|
||||
typeData['CustomPools'][sFullName] = dstBlockArray
|
||||
for sBlockId, objBlock in objBlocks.items():
|
||||
ProcessBlock(dstBlockArray, int(sBlockId), objBlock, sAlgorithm)
|
||||
|
||||
if IsDataEmpty():
|
||||
print("There is nothing to put on the image. Please make sure you generated the stats string with detailed map enabled.")
|
||||
exit(1)
|
||||
|
||||
iImgSizeY, fPixelsPerByte = CalcParams()
|
||||
|
||||
img = Image.new('RGB', (IMG_SIZE_X, iImgSizeY), 'white')
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
try:
|
||||
font = ImageFont.truetype('segoeuib.ttf')
|
||||
except:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
y = IMG_MARGIN
|
||||
|
||||
# Draw grid lines
|
||||
iBytesBetweenGridLines = 32
|
||||
while iBytesBetweenGridLines * fPixelsPerByte < 64:
|
||||
iBytesBetweenGridLines *= 2
|
||||
iByte = 0
|
||||
TEXT_MARGIN = 4
|
||||
while True:
|
||||
iX = int(iByte * fPixelsPerByte)
|
||||
if iX > IMG_SIZE_X - 2 * IMG_MARGIN:
|
||||
break
|
||||
draw.line([iX + IMG_MARGIN, 0, iX + IMG_MARGIN, iImgSizeY], fill=COLOR_GRID_LINE)
|
||||
if iByte == 0:
|
||||
draw.text((iX + IMG_MARGIN + TEXT_MARGIN, y), "0", fill=COLOR_TEXT_H2, font=font)
|
||||
else:
|
||||
text = BytesToStr(iByte)
|
||||
textSize = draw.textsize(text, font=font)
|
||||
draw.text((iX + IMG_MARGIN - textSize[0] - TEXT_MARGIN, y), text, fill=COLOR_TEXT_H2, font=font)
|
||||
iByte += iBytesBetweenGridLines
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
|
||||
# Draw main content
|
||||
for iMemTypeIndex in sorted(data.keys()):
|
||||
dictMemType = data[iMemTypeIndex]
|
||||
draw.text((IMG_MARGIN, y), "Memory type %d" % iMemTypeIndex, fill=COLOR_TEXT_H1, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
index = 0
|
||||
for tDedicatedAlloc in dictMemType['DedicatedAllocations']:
|
||||
draw.text((IMG_MARGIN, y), "Dedicated allocation %d" % index, fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index += 1
|
||||
for objBlock in dictMemType['DefaultPoolBlocks']:
|
||||
draw.text((IMG_MARGIN, y), "Default pool block %d" % objBlock['ID'], fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawBlock(draw, y, objBlock)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index = 0
|
||||
for sPoolName, listPool in dictMemType['CustomPools'].items():
|
||||
for objBlock in listPool:
|
||||
if 'Algorithm' in objBlock and objBlock['Algorithm']:
|
||||
sAlgorithm = ' (Algorithm: %s)' % (objBlock['Algorithm'])
|
||||
else:
|
||||
sAlgorithm = ''
|
||||
draw.text((IMG_MARGIN, y), "Custom pool %s%s block %d" % (sPoolName, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)
|
||||
y += FONT_SIZE + IMG_MARGIN
|
||||
DrawBlock(draw, y, objBlock)
|
||||
y += MAP_SIZE + IMG_MARGIN
|
||||
index += 1
|
||||
del draw
|
||||
img.save(args.output)
|
||||
|
||||
"""
|
||||
Main data structure - variable `data` - is a dictionary. Key is integer - memory type index. Value is dictionary of:
|
||||
- Fixed key 'DedicatedAllocations'. Value is list of tuples, each containing:
|
||||
- [0]: Type : string
|
||||
- [1]: Size : integer
|
||||
- [2]: Usage : integer (0 if unknown)
|
||||
- Fixed key 'DefaultPoolBlocks'. Value is list of objects, each containing dictionary with:
|
||||
- Fixed key 'ID'. Value is int.
|
||||
- Fixed key 'Size'. Value is int.
|
||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||
- Fixed key 'CustomPools'. Value is dictionary.
|
||||
- Key is string with pool ID/name. Value is list of objects representing memory blocks, each containing dictionary with:
|
||||
- Fixed key 'ID'. Value is int.
|
||||
- Fixed key 'Size'. Value is int.
|
||||
- Fixed key 'Algorithm'. Optional. Value is string.
|
||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user