diff --git a/.clang-format-ignore b/.clang-format-ignore index 57ece50d7..160b1067e 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -1,3 +1,2 @@ # Ignore third-party headers that crash the parser src/include/wisdom/util/xxhash.h -docs/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ece5ad56..b377a4136 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: - name: Configure CMake run: cmake --preset win-msvc-release - + - name: Build run: cmake --build --preset win-msvc-release diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 0f005e884..c90fcb0b9 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -53,7 +53,50 @@ jobs: shell: pwsh run: | $format = '${{ github.event.inputs.format }}' - .\package.ps1 -Format $format -Clean -OutputDir './artifacts' + .\package.ps1 -Format $format -Configuration both -Clean -OutputDir './artifacts' + + - name: Validate package contents + shell: pwsh + run: | + Add-Type -AssemblyName System.IO.Compression.FileSystem + $format = '${{ github.event.inputs.format }}' + + if ($format -in @('nuget', 'all')) { + $nugetPackage = Get-ChildItem -Path artifacts/*.nupkg | Select-Object -First 1 + if (-not $nugetPackage) { + throw "NuGet package was not generated." + } + + $nugetArchive = [System.IO.Compression.ZipFile]::OpenRead($nugetPackage.FullName) + try { + $hasAgility = $nugetArchive.Entries | Where-Object { $_.FullName -match '(?i)D3D12Core\.dll|d3d12SDKLayers\.dll|d3dx12/' } + if ($hasAgility) { + throw "NuGet package must not include Agility SDK files." + } + } + finally { + $nugetArchive.Dispose() + } + } + + if ($format -in @('zip', 'all')) { + $zipPackage = Get-ChildItem -Path artifacts/*.zip | Select-Object -First 1 + if (-not $zipPackage) { + throw "ZIP package was not generated." + } + + $zipArchive = [System.IO.Compression.ZipFile]::OpenRead($zipPackage.FullName) + try { + $hasCore = $zipArchive.Entries | Where-Object { $_.FullName -match '(?i)D3D12Core\.dll' } + $hasLayers = $zipArchive.Entries | Where-Object { $_.FullName -match '(?i)d3d12SDKLayers\.dll' } + if (-not $hasCore -or -not $hasLayers) { + throw "ZIP package must include Agility SDK runtime files (D3D12Core.dll and d3d12SDKLayers.dll)." + } + } + finally { + $zipArchive.Dispose() + } + } - name: Upload NuGet Package uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8f3bccb9..0bbcd30a7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -220,7 +220,45 @@ jobs: - name: Build and Package shell: pwsh run: | - .\package.ps1 -Format all -Clean -OutputDir './artifacts' + .\scripts\package.ps1 -Format all -Configuration both -Clean -OutputDir './artifacts' + + - name: Validate package contents + shell: pwsh + run: | + Add-Type -AssemblyName System.IO.Compression.FileSystem + + $nugetPackage = Get-ChildItem -Path artifacts/*.nupkg | Select-Object -First 1 + if (-not $nugetPackage) { + throw "NuGet package was not generated." + } + + $nugetArchive = [System.IO.Compression.ZipFile]::OpenRead($nugetPackage.FullName) + try { + $nugetHasAgility = $nugetArchive.Entries | Where-Object { $_.FullName -match '(?i)D3D12Core\.dll|d3d12SDKLayers\.dll|d3dx12/' } + if ($nugetHasAgility) { + throw "NuGet package must not include Agility SDK files." + } + } + finally { + $nugetArchive.Dispose() + } + + $zipPackage = Get-ChildItem -Path artifacts/*.zip | Select-Object -First 1 + if (-not $zipPackage) { + throw "ZIP package was not generated." + } + + $zipArchive = [System.IO.Compression.ZipFile]::OpenRead($zipPackage.FullName) + try { + $zipHasCore = $zipArchive.Entries | Where-Object { $_.FullName -match '(?i)D3D12Core\.dll' } + $zipHasLayers = $zipArchive.Entries | Where-Object { $_.FullName -match '(?i)d3d12SDKLayers\.dll' } + if (-not $zipHasCore -or -not $zipHasLayers) { + throw "ZIP package must include Agility SDK runtime files (D3D12Core.dll and d3d12SDKLayers.dll)." + } + } + finally { + $zipArchive.Dispose() + } - name: Upload NuGet Package uses: actions/upload-artifact@v4 @@ -262,13 +300,13 @@ jobs: uses: lukka/get-cmake@latest - name: Configure CMake (Debug) - run: cmake --preset linux-gcc-debug-lib -DWISDOM_VULKAN_HEADER_PATH=${{ github.workspace }}/vulkan-headers/include + run: cmake --preset linux-gcc-debug-lib -DWISDOM_VULKAN_HEADER_PATH=${{ github.workspace }}/vulkan-headers/include -DCMAKE_UNITY_BUILD=ON - name: Build (Debug) run: cmake --build --preset linux-gcc-debug-lib - name: Configure CMake (Release) - run: cmake --preset linux-gcc-lib -DWISDOM_VULKAN_HEADER_PATH=${{ github.workspace }}/vulkan-headers/include + run: cmake --preset linux-gcc-lib -DWISDOM_VULKAN_HEADER_PATH=${{ github.workspace }}/vulkan-headers/include -DCMAKE_UNITY_BUILD=ON - name: Build (Release) run: cmake --build --preset linux-gcc-lib @@ -333,6 +371,8 @@ jobs: needs: [version, release] if: ${{ !failure() && !cancelled() && needs.version.outputs.publish_nuget == 'true' }} runs-on: windows-latest + permissions: + id-token: write steps: - name: Download NuGet Package @@ -347,9 +387,15 @@ jobs: shell: pwsh run: | Get-ChildItem -Path . -Recurse | Select-Object FullName - + + - name: NuGet login (OIDC → temp API key) + uses: NuGet/login@v1 + id: login + with: + user: Agrael + - name: Publish to NuGet.org - run: dotnet nuget push wisdom.*.nupkg --api-key "${{ secrets.NUGET_APIKEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate + run: dotnet nuget push wisdom.*.nupkg --api-key ${{steps.login.outputs.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json --skip-duplicate # Step 6: Build and deploy documentation docs: diff --git a/.github/workflows/restyled.yml b/.github/workflows/restyled.yml index b9ca76465..c92331faa 100644 --- a/.github/workflows/restyled.yml +++ b/.github/workflows/restyled.yml @@ -11,7 +11,7 @@ jobs: restyled: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.head.ref }} @@ -25,7 +25,7 @@ jobs: !cancelled() && steps.restyler.outputs.success == 'true' && github.event.pull_request.head.repo.full_name == github.repository - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v8 with: base: ${{ steps.restyler.outputs.restyled-base }} branch: ${{ steps.restyler.outputs.restyled-head }} diff --git a/.gitignore b/.gitignore index 123b20c4c..abc2d212d 100644 --- a/.gitignore +++ b/.gitignore @@ -376,3 +376,4 @@ FodyWeavers.xsd # Package artifacts /artifacts/ +/tests/integration/cmake/extracted/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c0979886..6b9fd782c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,16 +11,6 @@ include(GenerateExportHeader) include(cmake/functions.cmake) wisdom_detect_platform() -# Determine which options to use by default -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" - AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "13" - OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "16") - set(LOCAL_USE_FMTLIB TRUE) -else() - set(LOCAL_USE_FMTLIB FALSE) -endif() - if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(WTOP ON) else() @@ -28,7 +18,6 @@ else() endif() # Options -option(WISDOM_USE_FMT "Build Wisdom with fmtlib" ${LOCAL_USE_FMTLIB}) option(WISDOM_FORCE_VULKAN "Force Vulkan support" OFF) option(WISDOM_BUILD_EXAMPLES "Build the example project." ${WTOP}) option(WISDOM_BUILD_TESTS "Build the tests." ${WTOP}) @@ -36,15 +25,20 @@ option(WISDOM_BUILD_STATIC "Build the static lib." ON) option(WISDOM_BUILD_SHARED "Build the dynamic lib." ON) option(WISDOM_BUILD_PLATFORM "Build unified platform extension library." ON) option(WISDOM_BUILD_DOCS "Build the documentation." OFF) +option(WISDOM_USE_AGILITY_SDK "Download and use DirectX 12 Agility SDK." ON) +option(WISDOM_USE_CONAN + "Use Conan to manage dependencies. Only for library builds." OFF) # DXC deployment options -set(WISDOM_DXC_PATH - "" - CACHE PATH "Path to custom DXC installation (optional)") set(WISDOM_VULKAN_HEADER_PATH "" CACHE PATH "Path to custom Vulkan Headers (optional)") +# Conan includes Vulkan Headers. +if(WISDOM_USE_CONAN) + set(WISDOM_VULKAN ON) +endif() + # Load all dependencies include(cmake/deps.cmake) include(cmake/doc.cmake) @@ -55,7 +49,6 @@ message( WISDOM_VULKAN: ${WISDOM_VULKAN} WISDOM_VULKAN_VERSION: ${WISDOM_VULKAN_VERSION} WISDOM_DX12: ${WISDOM_DX12} - WISDOM_USE_FMT: ${WISDOM_USE_FMT} WISDOM_VERSION: ${WISDOM_VERSION} WISDOM_PLATFORM: ${WISDOM_PLATFORM} @@ -65,13 +58,10 @@ message( WISDOM_BUILD_STATIC: ${WISDOM_BUILD_STATIC} WISDOM_BUILD_SHARED: ${WISDOM_BUILD_SHARED} WISDOM_BUILD_PLATFORM: ${WISDOM_BUILD_PLATFORM} + WISDOM_USE_AGILITY_SDK: ${WISDOM_USE_AGILITY_SDK} + WISDOM_USE_CONAN: ${WISDOM_USE_CONAN} - WISDOM_VULKAN_HEADER_PATH: ${WISDOM_VULKAN_HEADER_PATH} - - DXC Configuration: - Custom Path: ${WISDOM_DXC_PATH} - Executable: ${DXC_EXECUTABLE} - ") + WISDOM_VULKAN_HEADER_PATH: ${WISDOM_VULKAN_HEADER_PATH}") if(WISDOM_BUILD_EXAMPLES AND WISDOM_BUILD_TESTS) add_subdirectory(generator) @@ -105,4 +95,22 @@ configure_package_config_file( install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wisdom-config-version.cmake ${CMAKE_CURRENT_BINARY_DIR}/wisdom-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wisdom) -include(cmake/install/nuget.cmake) + +# Set up package metadata +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_VENDOR "Agrael") +set(CPACK_NUGET_PACKAGE_AUTHORS "Agrael") +set(CPACK_PACKAGE_DESCRIPTION + "A Low-level thin multiplatform and extensible Graphics API layer over Vulkan and DX12" +) +set(CPACK_PACKAGE_HOMEPAGE_URL "https://agrael1.github.io/Wisdom/") +set(CPACK_NUGET_PACKAGE_REPOSITORY_URL "https://github.com/Agrael1/Wisdom.git") +set(CPACK_NUGET_PACKAGE_ICON "favicon.png") # pulled from installed files +set(CPACK_NUGET_PACKAGE_REPOSITORY_TYPE git) +set(CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION "MIT") +set(CPACK_NUGET_PACKAGE_README "README.md") # pulled from installed files +set(CPACK_PROJECT_CONFIG_FILE + "${CMAKE_CURRENT_LIST_DIR}/cmake/install/cpack-options.cmake") + +include(CPack) diff --git a/README.md b/README.md index 31b58801e..4ea711622 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Vulkan library is loaded dynamically, so it is not required to have Vulkan SDK i - `WISDOM_BUILD_STATIC=ON` build static library version. - `WISDOM_BUILD_SHARED=ON` build shared/dynamic library version. - `WISDOM_BUILD_PLATFORM=ON` build unified platform extension library. +- `WISDOM_USE_AGILITY_SDK=OFF` download and build with Agility SDK instead of Windows SDK, this allows using latest DirectX 12 features on older Windows versions, but requires additional setup and dependencies. Default is `OFF`, which uses Windows SDK that comes with the system and DirectX-Headers. - `WISDOM_BUILD_DOCS=OFF` build documentation with Doxygen, default is dependent on whether you are building the library as a top project (ON) or as a part/dep for other (OFF) - `WISDOM_DXC_PATH="Path/to/dxc"` use system DXC compiler instead of the one provided with the library (default uses the one provided) @@ -115,8 +116,8 @@ To link library simply use `target_link_libraries(${YOUR_TARGET} PUBLIC wis::wis Available targets are: -- `wis::wisdom | wis::wisdom-headers` - functional library -- `wis::platform | wis::wisdom-platform-headers` - platform specific extensions (Surface) +- `wis::wisdom | wis::wisdom-headers | wis::wisdom-shared` - functional library +- `wis::platform | wis::wisdom-platform-headers | wis::wisdom-platform-shared` - platform specific extensions (Surface) There is also Conan package available for consumption, it can't be loaded to Conan Center yet, but you can add it manually by downloading the repo and executing `conan create .` command in the root of the repository. diff --git a/cmake/deps.cmake b/cmake/deps.cmake index 082239a8c..bb22e82b4 100644 --- a/cmake/deps.cmake +++ b/cmake/deps.cmake @@ -1,44 +1,37 @@ -include(FetchContent) -set(FETCHCONTENT_UPDATES_DISCONNECTED ON) -set(CPM_DONT_UPDATE_MODULE_PATH ON) -set(GET_CPM_FILE "${CMAKE_CURRENT_LIST_DIR}/deps/get_cpm.cmake") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) - -# Set CPM source cache -if (NOT CPM_SOURCE_CACHE) - set(CPM_SOURCE_CACHE "${CMAKE_CURRENT_BINARY_DIR}/_deps_cache") -endif () +# Block CPM if already using Conan, otherwise fetch dependencies using CPM +if(NOT WISDOM_USE_CONAN) + include(FetchContent) + set(FETCHCONTENT_UPDATES_DISCONNECTED ON) + set(CPM_DONT_UPDATE_MODULE_PATH ON) + set(GET_CPM_FILE "${CMAKE_CURRENT_LIST_DIR}/deps/get_cpm.cmake") + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + + # Set CPM source cache + if (NOT CPM_SOURCE_CACHE) + set(CPM_SOURCE_CACHE "${CMAKE_CURRENT_BINARY_DIR}/_deps_cache") + endif () -if (NOT EXISTS ${GET_CPM_FILE}) - file(DOWNLOAD - https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake - "${GET_CPM_FILE}" - ) -endif () -include(${GET_CPM_FILE}) + if (NOT EXISTS ${GET_CPM_FILE}) + file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake + "${GET_CPM_FILE}" + ) + endif () + include(${GET_CPM_FILE}) +endif() if (WISDOM_WINDOWS) - include(${CMAKE_CURRENT_LIST_DIR}/deps/deps_win.cmake) + if (WISDOM_USE_CONAN) # This prevents accidental blockade of Agility SDK + find_package(D3D12MemoryAllocator CONFIG QUIET) + if (NOT D3D12MemoryAllocator_FOUND) + message(FATAL_ERROR "D3D12MemoryAllocator not found. Please install it using Conan or disable WISDOM_USE_CONAN.") + endif() + else() + include(${CMAKE_CURRENT_LIST_DIR}/deps/deps_win.cmake) + endif() endif () -# Use fmtlib -if (WISDOM_USE_FMT) - find_package(fmt CONFIG QUIET) - if (fmt_FOUND) - message("fmtlib found, skipping download.") - else () - message("Loading latest fmtlib...") - CPMAddPackage( - NAME fmt - GITHUB_REPOSITORY fmtlib/fmt - GIT_TAG 12.1.0) - endif () -endif () - -# DXCompiler for HLSL compilation -include(${CMAKE_CURRENT_LIST_DIR}/deps/dxc.cmake) - # Vulkan dependencies if (WISDOM_VULKAN) include(${CMAKE_CURRENT_LIST_DIR}/deps/deps_vulkan.cmake) diff --git a/cmake/deps/deps_vulkan.cmake b/cmake/deps/deps_vulkan.cmake index 5a79db4be..164731525 100644 --- a/cmake/deps/deps_vulkan.cmake +++ b/cmake/deps/deps_vulkan.cmake @@ -1,14 +1,21 @@ -if (NOT vkma_SOURCE_DIR) - CPMAddPackage( - NAME vkma - GITHUB_REPOSITORY GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator - GIT_TAG v3.3.0 - DOWNLOAD_ONLY TRUE - ) - set(vkma_SOURCE_DIR ${vkma_SOURCE_DIR} CACHE INTERNAL "") -else () - message("Vulkan Memory Allocator found, skipping download.") -endif () +if (WISDOM_USE_CONAN) + find_package(VulkanMemoryAllocator CONFIG QUIET) + if (NOT VulkanMemoryAllocator_FOUND) + message(FATAL_ERROR "Vulkan Memory Allocator not found. Please install it using Conan or disable WISDOM_USE_CONAN.") + endif() +else() + if (NOT vkma_SOURCE_DIR) + CPMAddPackage( + NAME vkma + GITHUB_REPOSITORY GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator + GIT_TAG v3.3.0 + DOWNLOAD_ONLY TRUE + ) + set(vkma_SOURCE_DIR ${vkma_SOURCE_DIR} CACHE INTERNAL "") + else () + message("Vulkan Memory Allocator found, skipping download.") + endif () +endif() # Generate a cpp file that includes the implementation if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/vma.cpp) @@ -16,19 +23,16 @@ if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/vma.cpp) "#define VMA_IMPLEMENTATION\n#include \"vk_mem_alloc.h\"\n") endif () -add_library(vkma STATIC ${vkma_SOURCE_DIR}/include/vk_mem_alloc.h ${CMAKE_CURRENT_BINARY_DIR}/vma.cpp) -target_link_libraries(vkma PUBLIC Vulkan::Headers) +add_library(vkma STATIC ${CMAKE_CURRENT_BINARY_DIR}/vma.cpp) target_compile_definitions( vkma PRIVATE VK_NO_PROTOTYPES VMA_STATIC_VULKAN_FUNCTIONS=0 VMA_DYNAMIC_VULKAN_FUNCTIONS=0) + if (WISDOM_WINDOWS) target_compile_definitions(vkma PUBLIC VK_USE_PLATFORM_WIN32_KHR VMA_EXTERNAL_MEMORY_WIN32) endif (WISDOM_WINDOWS) -target_include_directories( - vkma PUBLIC $ - $) set_target_properties(vkma PROPERTIES CXX_STANDARD 20 DEBUG_POSTFIX d @@ -44,5 +48,14 @@ install( LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(DIRECTORY ${vkma_SOURCE_DIR}/include/ +if (WISDOM_USE_CONAN) + # Conan already links Vulkan::Headers + target_link_libraries(vkma PUBLIC GPUOpen::VulkanMemoryAllocator) +else() + target_link_libraries(vkma PUBLIC Vulkan::Headers) + target_include_directories( + vkma PUBLIC $ + $) + install(DIRECTORY ${vkma_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vkma) +endif() diff --git a/cmake/deps/deps_win.cmake b/cmake/deps/deps_win.cmake index e56cd8bed..2f761521c 100644 --- a/cmake/deps/deps_win.cmake +++ b/cmake/deps/deps_win.cmake @@ -1,81 +1,55 @@ -include(${CMAKE_CURRENT_LIST_DIR}/nuget.cmake) +if (WISDOM_USE_AGILITY_SDK) + wis_load_agility_sdk() -_ww_find_nuget() + # Create helpers library + add_library(DX12Helpers INTERFACE) + add_library(wis::DX12Helpers ALIAS DX12Helpers) -# DirectX 12 Agility SDK -message("Setting up DirectX 12 Agility...") -_ww_load_nuget_dependency(${NUGET_EXE} "Microsoft.Direct3D.D3D12" DXA - ${CMAKE_CURRENT_BINARY_DIR}) - -string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)$" VERSION_MATCH ${DXA_DIR}) - -message("Agility version: ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") -set(DXA_VERSION - ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3} - CACHE INTERNAL "") -set(VERSION_MINOR - ${CMAKE_MATCH_2} - CACHE INTERNAL "") + target_link_libraries(DX12Helpers INTERFACE + DX12Agility) + install( + TARGETS DX12Helpers + EXPORT wisdom-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +else() + message("DirectX 12 Agility SDK not enabled. Using Headers instead.") -set(DXA_HEADERS ${DXA_DIR}/build/native/include) -set(DXA_SRC ${DXA_DIR}/build/native/src) -set(DXA_BIN ${DXA_DIR}/build/native/bin/x64) -set(DXAGILITY_DLL - ${DXA_BIN}/D3D12Core.dll - CACHE INTERNAL "") -set(DXAGILITY_DEBUG_DLL - ${DXA_BIN}/d3d12SDKLayers.dll - CACHE INTERNAL "") + # Create helpers library + add_library(DX12Helpers INTERFACE) + add_library(wis::DX12Helpers ALIAS DX12Helpers) -add_library(DX12AgilityCore MODULE IMPORTED GLOBAL) -set_property(TARGET DX12AgilityCore PROPERTY IMPORTED_LOCATION - ${DXAGILITY_DLL}) + target_compile_definitions(DX12Helpers INTERFACE + D3D12MA_USING_DIRECTX_HEADERS=1 + ) -add_library(DX12AgilitySDKLayers MODULE IMPORTED GLOBAL) -set_property(TARGET DX12AgilitySDKLayers PROPERTY IMPORTED_LOCATION - ${DXAGILITY_DEBUG_DLL}) + # Guaranteed backwards compatibility. + # Using origin/main to ensure we get the latest headers, + # which are compatible with the latest SDKs. + CPMAddPackage( + NAME dxheaders + GITHUB_REPOSITORY microsoft/DirectX-Headers + GIT_TAG origin/main + ) -# Header interface library -add_library(DX12Agility STATIC) -add_library(wis::DX12Agility ALIAS DX12Agility) + target_link_libraries(DX12Helpers INTERFACE + DirectX-Headers + DirectX-Guids) -target_include_directories( - DX12Agility SYSTEM BEFORE - PUBLIC $ $ - PRIVATE $) -target_sources(DX12Agility - PRIVATE ${DXA_SRC}/d3dx12/d3dx12_property_format_table.cpp) - -install( - TARGETS DX12Agility + install(DIRECTORY ${dxheaders_SOURCE_DIR}/include/directx DESTINATION include) + install(DIRECTORY ${dxheaders_SOURCE_DIR}/include/dxguids DESTINATION include) + install( + TARGETS DirectX-Headers DirectX-Guids EXPORT wisdom-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install( - IMPORTED_RUNTIME_ARTIFACTS - DX12AgilityCore - DX12AgilitySDKLayers - RUNTIME - DESTINATION - ${CMAKE_INSTALL_BINDIR} - LIBRARY - DESTINATION - ${CMAKE_INSTALL_BINDIR}) - -install(DIRECTORY ${DXA_HEADERS}/ DESTINATION include/d3dx12) - -set_target_properties(DX12Agility PROPERTIES - DX12SDKVER ${VERSION_MINOR} - DEBUG_POSTFIX d -) - -set_property( - TARGET DX12Agility - APPEND - PROPERTY EXPORT_PROPERTIES DX12SDKVER) + install(TARGETS DX12Helpers EXPORT wisdom-targets) +endif() # DirectX 12 Memory Allocator @@ -94,19 +68,21 @@ else () endif () -add_library(DX12Allocator STATIC ${dxma_SOURCE_DIR}/include/D3D12MemAlloc.h) -target_sources(DX12Allocator PRIVATE ${dxma_SOURCE_DIR}/src/D3D12MemAlloc.cpp) -target_link_libraries(DX12Allocator PRIVATE DX12Agility) -target_compile_definitions(DX12Allocator PRIVATE D3D12MA_OPTIONS16_SUPPORTED) +add_library(D3D12MemoryAllocator STATIC ${dxma_SOURCE_DIR}/include/D3D12MemAlloc.h) +add_library(GPUOpen::D3D12MemoryAllocator ALIAS D3D12MemoryAllocator) +target_sources(D3D12MemoryAllocator PRIVATE ${dxma_SOURCE_DIR}/src/D3D12MemAlloc.cpp) +target_link_libraries(D3D12MemoryAllocator PUBLIC DX12Helpers) + target_include_directories( - DX12Allocator PUBLIC $ + D3D12MemoryAllocator PUBLIC $ $) -set_target_properties(DX12Allocator PROPERTIES + +set_target_properties(D3D12MemoryAllocator PROPERTIES CXX_STANDARD 20 DEBUG_POSTFIX d ) install( - TARGETS DX12Allocator + TARGETS D3D12MemoryAllocator EXPORT wisdom-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/cmake/deps/dxc.cmake b/cmake/deps/dxc.cmake deleted file mode 100644 index 1eadd22b9..000000000 --- a/cmake/deps/dxc.cmake +++ /dev/null @@ -1,120 +0,0 @@ -# DXC Deployment Options -# Priority: 1. Custom path -> 2. Vulkan SDK -> 3. Auto-download - -# Option 1: Custom DXC path (highest priority) -# Users can specify WISDOM_DXC_PATH to use their own DXC installation -# Example: cmake -DWISDOM_DXC_PATH="C:/custom/dxc" .. -if (WISDOM_DXC_PATH) - message(STATUS "Using custom DXC path: ${WISDOM_DXC_PATH}") - - if (WIN32) - set(DXC_EXECUTABLE "${WISDOM_DXC_PATH}/bin/dxc.exe" CACHE INTERNAL "") - set(DXC_DLLS - "${WISDOM_DXC_PATH}/bin/dxcompiler.dll" - "${WISDOM_DXC_PATH}/bin/dxil.dll") - else () - set(DXC_EXECUTABLE "${WISDOM_DXC_PATH}/bin/dxc" CACHE INTERNAL "") - set(DXC_DLLS - "${WISDOM_DXC_PATH}/lib/libdxcompiler.so" - "${WISDOM_DXC_PATH}/lib/libdxil.so") - endif () - - # Verify that the executable exists - if (NOT EXISTS ${DXC_EXECUTABLE}) - message(WARNING "Custom DXC executable not found at: ${DXC_EXECUTABLE}") - message(WARNING "Please verify WISDOM_DXC_PATH is correct") - else () - message(STATUS "Found custom DXC executable: ${DXC_EXECUTABLE}") - endif () - - # Option 2: Try to use Vulkan SDK's DXC (if WISDOM_VULKAN is enabled and no custom path) -elseif (WISDOM_VULKAN AND Vulkan_dxc_EXECUTABLE) - message(STATUS "Using DXC from Vulkan SDK") - - # Use Vulkan SDK's DXC - find_program(DXCOMPILER dxc HINTS ${Vulkan_dxc_EXECUTABLE} ENV VULKAN_SDK PATH_SUFFIXES bin) - - if (DXCOMPILER) - message(STATUS "Found Vulkan SDK DXC: ${DXCOMPILER}") - set(DXC_EXECUTABLE ${DXCOMPILER} CACHE INTERNAL "") - - # Try to find DLLs alongside the executable for deployment - get_filename_component(DXC_BIN_DIR ${DXCOMPILER} DIRECTORY) - - if (WIN32) - set(DXC_DLLS - "${DXC_BIN_DIR}/dxcompiler.dll" - "${DXC_BIN_DIR}/dxil.dll") - else () - # On Linux, libraries might be in ../lib relative to bin - get_filename_component(DXC_SDK_DIR ${DXC_BIN_DIR} DIRECTORY) - set(DXC_DLLS - "${DXC_SDK_DIR}/lib/libdxcompiler.so" - "${DXC_SDK_DIR}/lib/libdxil.so") - endif () - else () - message(STATUS "Vulkan SDK DXC not found, falling back to download") - set(WISDOM_DOWNLOAD_DXC ON) - endif () - - # Option 3: Auto-download latest DXC (fallback) -else () - message(STATUS "Auto-downloading DXC...") - set(WISDOM_DOWNLOAD_DXC ON) -endif () - -# Download DXC if needed -if (WISDOM_DOWNLOAD_DXC) - if (NOT dxc_SOURCE_DIR) - if (WISDOM_WINDOWS) - set(DXC_FILE - https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.9.2602/dxc_2026_02_20.zip - ) - else () - set(DXC_FILE - https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.9.2602/linux_dxc_2026_02_20.x86_64.tar.gz - ) - endif () - - # Download DXC using CPM - CPMAddPackage( - NAME dxc - URL ${DXC_FILE} - ) - set(dxc_SOURCE_DIR ${dxc_SOURCE_DIR} CACHE INTERNAL "") - else () - message(STATUS "DXC already downloaded, skipping.") - endif () - - if (WIN32) - set(DXC_EXECUTABLE - ${dxc_SOURCE_DIR}/bin/x64/dxc.exe - CACHE INTERNAL "") - set(DXC_DLLS - ${dxc_SOURCE_DIR}/bin/x64/dxcompiler.dll - ${dxc_SOURCE_DIR}/bin/x64/dxil.dll) - else () - set(DXC_EXECUTABLE - ${dxc_SOURCE_DIR}/bin/dxc - CACHE INTERNAL "") - set(DXC_DLLS - ${dxc_SOURCE_DIR}/lib/libdxcompiler.so - ${dxc_SOURCE_DIR}/lib/libdxil.so) - endif () -endif () - -# Install DXC for deployment -if (WIN32) - install(PROGRAMS ${DXC_EXECUTABLE} DESTINATION bin COMPONENT dxc) - install(FILES ${DXC_DLLS} DESTINATION bin COMPONENT dxc) -else () - install(PROGRAMS ${DXC_EXECUTABLE} DESTINATION bin COMPONENT dxc) - install(FILES ${DXC_DLLS} DESTINATION lib COMPONENT dxc) -endif () - -# Verify DLLs exist (warning only) -foreach (dll ${DXC_DLLS}) - if (NOT EXISTS ${dll}) - message(WARNING "DXC library not found: ${dll}") - endif () -endforeach () diff --git a/cmake/deps/nuget.cmake b/cmake/deps/nuget.cmake deleted file mode 100644 index 5592ea301..000000000 --- a/cmake/deps/nuget.cmake +++ /dev/null @@ -1,79 +0,0 @@ -# Load NuGet.exe for Windows builds -function(_ww_load_nuget) - # Latest NuGet is at https://dist.nuget.org/win-x86-commandline/latest/nuget.exe - # Secure download with hash verification - set(FILE_URL "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe") - set(FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/NuGet/NuGet.exe") - file(DOWNLOAD - ${FILE_URL} - ${FILE_PATH} - STATUS download_status - LOG download_log - TIMEOUT 300 - TLS_VERIFY ON - TLS_VERSION 1.2 - ) - - # Check download status - list(GET download_status 0 status_code) - if (NOT status_code EQUAL 0) - list(GET download_status 1 status_string) - message(FATAL_ERROR "Download failed: ${status_string}") - else () - message(STATUS "File downloaded successfully to ${FILE_PATH}") - endif () -endfunction(_ww_load_nuget) - -# Find NuGet executable -function(_ww_find_nuget) - if (NOT WISDOM_WINDOWS) - return() - endif () - - find_program( - NUGET_EXE - NAMES nuget) - - if (NOT NUGET_EXE) - message("NUGET.EXE not found. Downloading...") - find_program( - NUGET_EXE - NAMES nuget - PATHS ${CMAKE_CURRENT_BINARY_DIR}/NuGet) - - if (NOT NUGET_EXE) - _ww_load_nuget() - set(NUGET_EXE "${CMAKE_CURRENT_BINARY_DIR}/NuGet/NuGet.exe" CACHE INTERNAL "Path to NuGet.exe") - endif () - else () - message("NUGET.EXE found: ${NUGET_EXE}") - endif () -endfunction(_ww_find_nuget) - -# Load a NuGet dependency -function(_ww_load_nuget_dependency NUGET PLUGIN_NAME ALIAS OUT_DIR) - if (${ALIAS}_DIR) - message("${ALIAS}_DIR already set, skipping download.") - return() - endif () - - execute_process(COMMAND ${NUGET} install "${PLUGIN_NAME}" -OutputDirectory ${OUT_DIR}) - file(GLOB PLUGIN_DIRS ${OUT_DIR}/${PLUGIN_NAME}.*) - list(LENGTH PLUGIN_DIRS PLUGIN_DIRS_L) - if (${PLUGIN_DIRS_L} GREATER 1) - #Sort directories by version in descending order, so the first dir is top version - list(SORT PLUGIN_DIRS COMPARE NATURAL ORDER DESCENDING) - list(GET PLUGIN_DIRS 0 PLUGIN_DIRX) - - #Remove older version - MATH(EXPR PLUGIN_DIRS_L "${PLUGIN_DIRS_L}-1") - foreach (I RANGE 1 ${PLUGIN_DIRS_L}) - list(GET PLUGIN_DIRS ${I} OLD) - file(REMOVE_RECURSE ${OLD}) - endforeach () - else () - list(GET PLUGIN_DIRS 0 PLUGIN_DIRX) - endif () - - set(${ALIAS}_DIR ${PLUGIN_DIRX} CACHE STRING "${PLUGIN_NAME} PATH" FORCE) -endfunction(_ww_load_nuget_dependency) diff --git a/cmake/functions.cmake b/cmake/functions.cmake index df9fe88e9..6b775ea14 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -1,3 +1,163 @@ +if (WIN32) + # Load NuGet.exe for Windows builds + function(_ww_load_nuget) + # Latest NuGet is at https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + # Secure download with hash verification + set(FILE_URL "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe") + set(FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/NuGet/NuGet.exe") + file(DOWNLOAD + ${FILE_URL} + ${FILE_PATH} + STATUS download_status + LOG download_log + TIMEOUT 300 + TLS_VERIFY ON + TLS_VERSION 1.2 + ) + + # Check download status + list(GET download_status 0 status_code) + if (NOT status_code EQUAL 0) + list(GET download_status 1 status_string) + message(FATAL_ERROR "Download failed: ${status_string}") + else () + message(STATUS "File downloaded successfully to ${FILE_PATH}") + endif () + endfunction(_ww_load_nuget) + + # Find NuGet executable + function(_ww_find_nuget) + if (NOT WISDOM_WINDOWS) + return() + endif () + + # Check provided with WISDOM_NUGET_PATH + if (WISDOM_NUGET_PATH) + find_program( + NUGET_EXE + NAMES nuget + PATHS ${WISDOM_NUGET_PATH}) + if (NUGET_EXE) + message("NUGET.EXE found at WISDOM_NUGET_PATH: ${NUGET_EXE}") + return() + endif () + endif() + + find_program( + NUGET_EXE + NAMES nuget) + if (NUGET_EXE) + message("NUGET.EXE found: ${NUGET_EXE}") + return() + endif() + + message("NUGET.EXE not found. Downloading...") + find_program( + NUGET_EXE + NAMES nuget + PATHS ${CMAKE_CURRENT_BINARY_DIR}/NuGet) + + if (NOT NUGET_EXE) + _ww_load_nuget() + set(NUGET_EXE "${CMAKE_CURRENT_BINARY_DIR}/NuGet/NuGet.exe" CACHE INTERNAL "Path to NuGet.exe") + endif () + endfunction(_ww_find_nuget) + + # Load a NuGet dependency + function(_ww_load_nuget_dependency NUGET PLUGIN_NAME ALIAS OUT_DIR) + if (${ALIAS}_DIR) + message("${ALIAS}_DIR already set, skipping download.") + return() + endif () + + execute_process(COMMAND ${NUGET} install "${PLUGIN_NAME}" -OutputDirectory ${OUT_DIR}) + file(GLOB PLUGIN_DIRS ${OUT_DIR}/${PLUGIN_NAME}.*) + list(LENGTH PLUGIN_DIRS PLUGIN_DIRS_L) + if (${PLUGIN_DIRS_L} GREATER 1) + #Sort directories by version in descending order, so the first dir is top version + list(SORT PLUGIN_DIRS COMPARE NATURAL ORDER DESCENDING) + list(GET PLUGIN_DIRS 0 PLUGIN_DIRX) + + #Remove older version + MATH(EXPR PLUGIN_DIRS_L "${PLUGIN_DIRS_L}-1") + foreach (I RANGE 1 ${PLUGIN_DIRS_L}) + list(GET PLUGIN_DIRS ${I} OLD) + file(REMOVE_RECURSE ${OLD}) + endforeach () + else () + list(GET PLUGIN_DIRS 0 PLUGIN_DIRX) + endif () + + set(${ALIAS}_DIR ${PLUGIN_DIRX} CACHE STRING "${PLUGIN_NAME} PATH" FORCE) + endfunction(_ww_load_nuget_dependency) +endif() + +# Function to download the latest DXC release from GitHub API +function(_ww_load_latest_dxc) + if (dxc_SOURCE_DIR) + message(STATUS "DXC already downloaded, skipping.") + return() + endif () + + set(DXC_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/dxc_latest_api.json") + file(DOWNLOAD + "https://api.github.com/repos/microsoft/DirectXShaderCompiler/releases/latest" + "${DXC_API_FILE}" + STATUS api_status + ) + + list(GET api_status 0 api_err) + if(api_err) + message(WARNING "Wisdom: Failed to query DXC latest release from GitHub API: ${api_status}") + endif() + + file(READ "${DXC_API_FILE}" DXC_JSON) + + # Take the first URL that ends with .zip (Windows release) from the JSON response + if(DXC_JSON AND DXC_JSON MATCHES "\"browser_download_url\":[ \t\r\n]*\"([^\"]+\\.zip)\"") + set(DXC_WINDOWS_LINK "${CMAKE_MATCH_1}") + else() + message(WARNING "Wisdom: Could not parse DXC zip URL from GitHub API response.") + set(DXC_WINDOWS_LINK "https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.9.2602/dxc_2026_02_20.zip") + endif() + + # Take the first URL that ends with .tar.gz (Linux release) from the JSON response + if(DXC_JSON AND DXC_JSON MATCHES "\"browser_download_url\":[ \t\r\n]*\"([^\"]+\\.tar\\.gz)\"") + set(DXC_LINUX_LINK "${CMAKE_MATCH_1}") + else() + message(WARNING "Wisdom: Could not parse DXC tar.gz URL from GitHub API response.") + set(DXC_LINUX_LINK "https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.9.2602/linux_dxc_2026_02_20.x86_64.tar.gz") + endif() + + if (WISDOM_WINDOWS) + set(DXC_LINK ${DXC_WINDOWS_LINK}) + else () + set(DXC_LINK ${DXC_LINUX_LINK}) + endif () + + + # Download DXC using CPM + include(FetchContent) + FetchContent_Declare( + dxc + URL "${DXC_LINK}" + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + FetchContent_MakeAvailable(dxc) + set(dxc_SOURCE_DIR ${dxc_SOURCE_DIR} CACHE INTERNAL "") + + if (WIN32) + set(DXC_EXECUTABLE + ${dxc_SOURCE_DIR}/bin/x64/dxc.exe + CACHE INTERNAL "") + else () + set(DXC_EXECUTABLE + ${dxc_SOURCE_DIR}/bin/dxc + CACHE INTERNAL "") + endif () +endfunction() + + # Function to detect platform and set relevant variables function(wisdom_detect_platform) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/ecm") @@ -76,86 +236,68 @@ function(wisdom_detect_platform) endfunction() -# Function for installing DirectX SDK for UWP -function(wis_export_agility_file) - set(options) - set(oneValueArgs PATH) - set(multiValueArgs) - - cmake_parse_arguments(wis_export_agility_file - "${options}" "${oneValueArgs}" "${multiValueArgs}" - ${ARGN}) - - get_property(DX12SDKVER TARGET wis::DX12Agility PROPERTY DX12SDKVER) - - set(EXPORT_AGILITY "_declspec(dllexport) const unsigned D3D12SDKVersion = ${DX12SDKVER}; - _declspec(dllexport) const char* D3D12SDKPath = \".\\\\D3D12\\\\\";" - ) - file(WRITE ${wis_export_agility_file_PATH} "${EXPORT_AGILITY}") -endfunction() -function(wis_make_exports_dx PROJECT) - wis_export_agility_file(PATH ${CMAKE_CURRENT_BINARY_DIR}/exports.c) - - target_sources(${PROJECT} PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/exports.c - ) -endfunction() - -function(wis_install_dx_uwp PROJECT) - message("Installing DirectX Agility SDK Dependency") - wis_export_agility_file(PATH "${CMAKE_CURRENT_BINARY_DIR}/exports.c") - - target_sources(${PROJECT} PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/exports.c - ) - - message("DX12AgilityCore: ${DXAGILITY_DLL}") - set_property(SOURCE ${DXAGILITY_DLL} PROPERTY VS_DEPLOYMENT_CONTENT 1) - set_property(SOURCE ${DXAGILITY_DLL} PROPERTY VS_DEPLOYMENT_LOCATION "D3D12") - target_sources(${PROJECT} PRIVATE ${DXAGILITY_DLL}) - - message("DX12AgilitySDKLayers: ${DXAGILITY_DEBUG_DLL}") - set_property(SOURCE ${DXAGILITY_DEBUG_DLL} PROPERTY VS_DEPLOYMENT_CONTENT 1) - set_property(SOURCE ${DXAGILITY_DEBUG_DLL} PROPERTY VS_DEPLOYMENT_LOCATION "D3D12") - target_sources(${PROJECT} PRIVATE ${DXAGILITY_DEBUG_DLL}) -endfunction() - -# Function for installing DirectX SDK -function(wis_install_dx_win32 PROJECT) - message("Installing DirectX Agility SDK Dependency") - wis_export_agility_file(PATH "${CMAKE_CURRENT_BINARY_DIR}/exports.c") +# Function to load DXC +# Arguments: +# DOWNLOAD_LATEST: Download the latest DXC from GitHub +# DXC_PATH: Custom path to DXC installation (should contain bin/dxc.exe or bin/dxc) +function(wis_load_dxc) + set(options DOWNLOAD_LATEST) + set(oneValueArgs DXC_PATH) + set(multiValueArgs) + cmake_parse_arguments(wis_load_dxc "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN}) - target_sources(${PROJECT} PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/exports.c - ) + # If DXC is already configured, skip loading + if (DXC_EXECUTABLE) + return() + endif() + + # Error if none of the above are available + + # Option 1: DOWNLOAD_LATEST (highest priority) + if (wis_load_dxc_DOWNLOAD_LATEST) + message(STATUS "DOWNLOAD_LATEST option enabled, downloading latest DXC from GitHub") + _ww_load_latest_dxc() + return() + endif() + + # Option 2: Custom DXC path (DXC_PATH) + if (WISDOM_DXC_PATH) + # Verify that the executable exists + if (NOT EXISTS ${DXC_EXECUTABLE}) + message(WARNING "Custom DXC executable not found at: ${DXC_EXECUTABLE}") + message(FATAL_ERROR "Please verify WISDOM_DXC_PATH is correct") + else () + message(STATUS "Found custom DXC executable: ${DXC_EXECUTABLE}") + endif () - get_filename_component(DXAGILITY_DLL_NAME ${DXAGILITY_DLL} NAME) - add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DXAGILITY_DLL} $/D3D12/${DXAGILITY_DLL_NAME} - COMMAND_EXPAND_LISTS - COMMENT "Copying DX12 Agility Core..." - ) + message(STATUS "Using custom DXC path: ${WISDOM_DXC_PATH}") + if (WIN32) + set(DXC_EXECUTABLE "${WISDOM_DXC_PATH}/bin/dxc.exe" CACHE INTERNAL "") + else () + set(DXC_EXECUTABLE "${WISDOM_DXC_PATH}/bin/dxc" CACHE INTERNAL "") + endif () + return() + endif() + # Option 3: Try to use Vulkan SDK's DXC (if WISDOM_VULKAN is enabled and no custom path) + if (WISDOM_VULKAN AND Vulkan_dxc_EXECUTABLE) + # Use Vulkan SDK's DXC + find_program(DXCOMPILER dxc HINTS ${Vulkan_dxc_EXECUTABLE} ENV VULKAN_SDK PATH_SUFFIXES bin) - get_filename_component(DXAGILITY_DEBUG_DLL_NAME ${DXAGILITY_DEBUG_DLL} NAME) - add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${DXAGILITY_DEBUG_DLL} $/D3D12/${DXAGILITY_DEBUG_DLL_NAME} - COMMAND_EXPAND_LISTS - COMMENT "Copying DX12 Agility SDKLayers..." - ) -endfunction() + if (DXCOMPILER) + message(STATUS "Found Vulkan SDK DXC: ${DXCOMPILER}") + set(DXC_EXECUTABLE ${DXCOMPILER} CACHE INTERNAL "") + else () + message(FATAL_ERROR "Vulkan SDK DXC not found in Vulkan SDK") + endif () + endif() -# Function for installing Wisdom Dependencies -function(wis_install_deps PROJECT) - if (WIN32 AND NOT WINDOWS_STORE) - wis_install_dx_win32(${PROJECT}) - elseif (WINDOWS_STORE) - wis_install_dx_uwp(${PROJECT}) - endif (WIN32 AND NOT WINDOWS_STORE) + # Error if DXC_EXECUTABLE is still not set + message(FATAL_ERROR "DXC executable not found. Please configure DXC using wis_load_dxc() with either DOWNLOAD_LATEST or DXC_PATH options, or ensure that the Vulkan SDK is installed and contains DXC.") endfunction() - # Function for compiling shaders # Arguments: # DXC: Path to the DXC executable (default: stored in ${DXC_EXECUTABLE} then in PATH) @@ -174,12 +316,13 @@ function(wis_compile_shader) cmake_parse_arguments(wis_compile_shader "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if (NOT wis_compile_shader_DXC) - if (NOT DXC_EXECUTABLE) - find_program(wis_compile_shader_DXC dxc) + if (NOT wis_compile_shader_DXC OR NOT EXISTS ${wis_compile_shader_DXC}) + if (DXC_EXECUTABLE) + set (wis_compile_shader_DXC ${DXC_EXECUTABLE}) else () - set(wis_compile_shader_DXC ${DXC_EXECUTABLE}) - endif () + message(FATAL_ERROR "wis_compile_shader: DXC not found. " + "Please configure DXC using wis_load_dxc(), or provide a valid DXC path via DXC argument.") + endif() endif () if (NOT wis_compile_shader_TARGET) @@ -280,3 +423,170 @@ function(wis_compile_shader) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} VERBATIM) endfunction() + +# Function to load DirectX 12 Agility SDK using NuGet +# Creates 3 targets: +# - DX12AgilityCore: The core Agility DLL (D3D12Core.dll) +# - DX12AgilitySDKLayers: The SDK Layers DLL (d3d12SDKLayers.dll) +# - DX12Agility: A helper static library that includes the Agility headers, for easy consumption by users. This is the main target that users should link against. +function(wis_load_agility_sdk) + if (NOT WISDOM_WINDOWS) + return() + endif () + + _ww_find_nuget() + + # DirectX 12 Agility SDK + message("Setting up DirectX 12 Agility...") + _ww_load_nuget_dependency(${NUGET_EXE} "Microsoft.Direct3D.D3D12" DXA + ${CMAKE_CURRENT_BINARY_DIR}) + + string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)$" VERSION_MATCH ${DXA_DIR}) + + message("Agility version: ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + set(DXA_VERSION + ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3} + CACHE INTERNAL "") + set(VERSION_MINOR + ${CMAKE_MATCH_2} + CACHE INTERNAL "") + + set(DXA_HEADERS ${DXA_DIR}/build/native/include) + set(DXA_SRC ${DXA_DIR}/build/native/src) + set(DXA_BIN ${DXA_DIR}/build/native/bin/x64) + set(DXAGILITY_DLL + ${DXA_BIN}/D3D12Core.dll + CACHE INTERNAL "") + set(DXAGILITY_DEBUG_DLL + ${DXA_BIN}/d3d12SDKLayers.dll + CACHE INTERNAL "") + + add_library(DX12AgilityCore MODULE IMPORTED GLOBAL) + set_property(TARGET DX12AgilityCore PROPERTY IMPORTED_LOCATION + ${DXAGILITY_DLL}) + + add_library(DX12AgilitySDKLayers MODULE IMPORTED GLOBAL) + set_property(TARGET DX12AgilitySDKLayers PROPERTY IMPORTED_LOCATION + ${DXAGILITY_DEBUG_DLL}) + + # Header interface library + add_library(DX12Agility STATIC) + add_library(wis::DX12Agility ALIAS DX12Agility) + + target_include_directories( + DX12Agility SYSTEM BEFORE + PUBLIC $ $ + PRIVATE $) + target_sources(DX12Agility + PRIVATE ${DXA_SRC}/d3dx12/d3dx12_property_format_table.cpp) + target_compile_definitions(DX12Agility PUBLIC + DX12SDKVER=${VERSION_MINOR} + ) + install( + TARGETS DX12Agility + EXPORT wisdom-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + install( + IMPORTED_RUNTIME_ARTIFACTS + DX12AgilityCore + DX12AgilitySDKLayers + RUNTIME + DESTINATION + ${CMAKE_INSTALL_BINDIR} + LIBRARY + DESTINATION + ${CMAKE_INSTALL_BINDIR}) + + install(DIRECTORY ${DXA_HEADERS}/ DESTINATION include/d3dx12) + + set_target_properties(DX12Agility PROPERTIES + DX12SDKVER ${VERSION_MINOR} + DEBUG_POSTFIX d + ) + + set_property( + TARGET DX12Agility + APPEND + PROPERTY EXPORT_PROPERTIES DX12SDKVER) + +endfunction() + +# Function for patching executable to export DX12 Agility symbols on Windows +function(wis_patch_agility_executable TARGET EXPORT_PATH) + if (NOT WISDOM_WINDOWS) + return() + endif() + + get_target_property(target_type ${TARGET} TYPE) + + if(NOT target_type STREQUAL "EXECUTABLE") + message(FATAL_ERROR "Target ${TARGET} is not an executable. DX12 Agility patching can only be applied to executables.") + endif() + + # Check if the DX12Agility target is available + if (NOT TARGET DX12Agility) + message(FATAL_ERROR "DX12Agility target not found. Make sure to call wis_load_agility_sdk() before patching the executable.") + endif() + + # Generate a source file that exports the required symbols for the DX12 Agility SDK. This is necessary to ensure that the application can load the Agility DLLs at runtime. + get_property(DX12SDKVER TARGET DX12Agility PROPERTY DX12SDKVER) + set(EXPORT_AGILITY "_declspec(dllexport) const unsigned D3D12SDKVersion = ${DX12SDKVER}; + _declspec(dllexport) const char* D3D12SDKPath = \".\\\\D3D12\\\\\";" + ) + file(WRITE ${EXPORT_PATH} "${EXPORT_AGILITY}") + + # Add the generated file to the target sources to ensure it's compiled and linked into the executable + target_sources(${TARGET} PRIVATE ${EXPORT_PATH}) +endfunction() + +# Function for installing DirectX SDK +# Arguments: +# TARGET: Target to copy the DLLs to +# PATCH_EXE: Whether to patch the executable to export the DX12 Agility symbols (default: OFF) +function(wis_install_agility_win32) + cmake_parse_arguments(wis_install_agility_win32 "PATCH_EXE" "TARGET" + "" ${ARGN}) + + # Check if project is an executable + if (NOT TARGET ${wis_install_agility_win32_TARGET}) + message(FATAL_ERROR "Target ${wis_install_agility_win32_TARGET} not found") + endif() + + get_target_property(target_type ${wis_install_agility_win32_TARGET} TYPE) + + if(NOT target_type STREQUAL "EXECUTABLE") + message(FATAL_ERROR "Target ${wis_install_agility_win32_TARGET} is not an executable. DX12 Agility patching can only be applied to executables.") + endif() + + message("Installing DirectX Agility SDK Dependency") + if (EXISTS ${DXAGILITY_DLL}) + message("DX12 Agility Core found: ${DXAGILITY_DLL}") + get_filename_component(DXAGILITY_DLL_NAME ${DXAGILITY_DLL} NAME) + add_custom_command(TARGET ${wis_install_agility_win32_TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DXAGILITY_DLL} $/D3D12/${DXAGILITY_DLL_NAME} + COMMAND_EXPAND_LISTS + COMMENT "Copying DX12 Agility Core..." + ) + endif() + + if (EXISTS ${DXAGILITY_DEBUG_DLL}) + message("DX12 Agility SDKLayers found: ${DXAGILITY_DEBUG_DLL}") + get_filename_component(DXAGILITY_DEBUG_DLL_NAME ${DXAGILITY_DEBUG_DLL} NAME) + add_custom_command(TARGET ${wis_install_agility_win32_TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${DXAGILITY_DEBUG_DLL} $/D3D12/${DXAGILITY_DEBUG_DLL_NAME} + COMMAND_EXPAND_LISTS + COMMENT "Copying DX12 Agility SDKLayers..." + ) + endif() + + if (wis_install_agility_win32_PATCH_EXE) + wis_patch_agility_executable( + ${wis_install_agility_win32_TARGET} + ${CMAKE_CURRENT_BINARY_DIR}/export_agility.c + ) + endif() +endfunction() diff --git a/cmake/install/cpack-options.cmake b/cmake/install/cpack-options.cmake new file mode 100644 index 000000000..160a7b8d9 --- /dev/null +++ b/cmake/install/cpack-options.cmake @@ -0,0 +1,8 @@ +if(CPACK_GENERATOR MATCHES "NuGet") + message(STATUS "Wisdom CPack: NuGet generator detected. Injecting pre-build script.") + set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/nuget-prepare.cmake") + set(CPACK_INSTALL_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/gen-targets.cmake") +elseif(CPACK_GENERATOR MATCHES "ZIP") + message(STATUS "Wisdom CPack: ZIP generator detected. Proceeding with standard layout.") + # No pre-build script needed! The CMake folders stay intact. +endif() diff --git a/cmake/install/multi-config-nuget.cmake b/cmake/install/multi-config-nuget.cmake index be8ea9d03..b10708050 100644 --- a/cmake/install/multi-config-nuget.cmake +++ b/cmake/install/multi-config-nuget.cmake @@ -1,14 +1,15 @@ # NuGet-specific multi-config - excludes DXC component # Users should install Microsoft.Direct3D.DXC NuGet package separately +# NuGet package is built without Agility SDK # Include the release config as base (contains package metadata) -include("${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release/CPackConfig.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release-nuget/CPackConfig.cmake") # Only include the default component, excluding 'dxc' component set(CPACK_COMPONENTS_ALL Unspecified) # Install from both Debug and Release builds (Unspecified component only) set(CPACK_INSTALL_CMAKE_PROJECTS - "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-debug;wisdom;Unspecified;/" - "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release;wisdom;Unspecified;/" + "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-debug-nuget;wisdom;Unspecified;/" + "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release-nuget;wisdom;Unspecified;/" ) diff --git a/cmake/install/multi-config.cmake b/cmake/install/multi-config.cmake index b7c44cbdf..f6b9232ac 100644 --- a/cmake/install/multi-config.cmake +++ b/cmake/install/multi-config.cmake @@ -1,8 +1,8 @@ # Include the release config as base (contains package metadata) -include("${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release/CPackConfig.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release-zip/CPackConfig.cmake") -# Install from both Debug and Release builds +# Install from both Debug and Release builds (ZIP includes Agility SDK) set(CPACK_INSTALL_CMAKE_PROJECTS - "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-debug;wisdom;ALL;/" - "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release;wisdom;ALL;/" + "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-debug-zip;wisdom;ALL;/" + "${CMAKE_CURRENT_LIST_DIR}/../../build/msvc-release-zip;wisdom;ALL;/" ) diff --git a/cmake/install/nuget-prepare.cmake b/cmake/install/nuget-prepare.cmake new file mode 100644 index 000000000..43cebf0ce --- /dev/null +++ b/cmake/install/nuget-prepare.cmake @@ -0,0 +1,28 @@ +# CPack sets this variable to the root of the staging directory right before packaging. +set(STAGING_DIR "${CPACK_TEMPORARY_INSTALL_DIRECTORY}") +set(NUGET_NATIVE_LIB_DIR "${STAGING_DIR}/lib/native/x64") +file(MAKE_DIRECTORY "${NUGET_NATIVE_LIB_DIR}") + +message(STATUS "Wisdom CPack: Reorganizing staging directory at ${STAGING_DIR}") + +# 1. Strip out the CMake configs +if(EXISTS "${STAGING_DIR}/lib/cmake") + file(REMOVE_RECURSE "${STAGING_DIR}/lib/cmake") +endif() + +# 2. Ensure /lib exists +file(MAKE_DIRECTORY "${STAGING_DIR}/lib") + +# 3. Move the DLLs from /bin to /lib +file(GLOB _wisdom_native_dlls "${STAGING_DIR}/bin/*.dll") +foreach(_dll IN LISTS _wisdom_native_dlls) + get_filename_component(_dll_name "${_dll}" NAME) + file(RENAME "${_dll}" "${NUGET_NATIVE_LIB_DIR}/${_dll_name}") +endforeach() + +# 3. (Optional but recommended) Move your static .libs / import .libs there too! +file(GLOB _wisdom_static_libs "${STAGING_DIR}/lib/*.lib") +foreach(_lib IN LISTS _wisdom_static_libs) + get_filename_component(_lib_name "${_lib}" NAME) + file(RENAME "${_lib}" "${NUGET_NATIVE_LIB_DIR}/${_lib_name}") +endforeach() diff --git a/cmake/install/nuget.cmake b/cmake/install/nuget.cmake deleted file mode 100644 index 7727ebbf3..000000000 --- a/cmake/install/nuget.cmake +++ /dev/null @@ -1,20 +0,0 @@ -set(CPACK_GENERATOR NuGet) -# Set up package metadata -set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") -set(CPACK_PACKAGE_VENDOR "Arcom Inc.") -set(CPACK_NUGET_PACKAGE_AUTHORS "Agrael") -set(CPACK_PACKAGE_DESCRIPTION "A Low-level thin multiplatform and extensible Graphics API layer over Vulkan and DX12") -set(CPACK_PACKAGE_HOMEPAGE_URL "https://agrael1.github.io/Wisdom/") -set(CPACK_NUGET_PACKAGE_REPOSITORY_URL "https://github.com/Agrael1/Wisdom.git") -set(CPACK_NUGET_PACKAGE_ICON "favicon.png") # pulled from installed files -set(CPACK_NUGET_PACKAGE_REPOSITORY_TYPE git) -set(CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION "MIT") -set(CPACK_NUGET_PACKAGE_README "README.md") # pulled from installed files -set(CPACK_INSTALL_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/gen-targets.cmake") - -# NuGet dependencies - D3D12 Agility SDK is required, DXC is optional for runtime shader compilation -set(CPACK_NUGET_PACKAGE_DEPENDENCIES "Microsoft.Direct3D.D3D12;Microsoft.Direct3D.DXC") -set("CPACK_NUGET_PACKAGE_DEPENDENCIES_Microsoft.Direct3D.D3D12_VERSION" "${DXA_VERSION}") -set("CPACK_NUGET_PACKAGE_DEPENDENCIES_Microsoft.Direct3D.DXC_VERSION" "[1.8,)") -include(CPack) diff --git a/cmake/install/wisdom.targets b/cmake/install/wisdom.targets index 8d25ef4a0..60f98027c 100644 --- a/cmake/install/wisdom.targets +++ b/cmake/install/wisdom.targets @@ -5,12 +5,13 @@ - $(MSBuildThisFileDirectory)..\..\include\;$(MSBuildThisFileDirectory)..\..\include\dxma;$(MSBuildThisFileDirectory)..\..\include\d3dx12;%(AdditionalIncludeDirectories) + $(MSBuildThisFileDirectory)..\..\include\;$(MSBuildThisFileDirectory)..\..\include\dxma;%(AdditionalIncludeDirectories) $(MSBuildThisFileDirectory)..\..\include\vkma;%(AdditionalIncludeDirectories) $(WisdomVulkanSDKPath);%(AdditionalIncludeDirectories) - WISDOM_VULKAN=1;%(PreprocessorDefinitions) - WISDOM_DX12=1;WISDOM_WINDOWS=1;%(PreprocessorDefinitions) + + WISDOM_VULKAN=1;VK_USE_PLATFORM_WIN32_KHR=1;VMA_EXTERNAL_MEMORY_WIN32=1;%(PreprocessorDefinitions) + WISDOM_DX12=1;WISDOM_WINDOWS=1;D3D12MA_USING_DIRECTX_HEADERS=1;NOMINMAX=1;%(PreprocessorDefinitions) WISDOM_FORCE_VULKAN=1;%(PreprocessorDefinitions) WISDOM_SHARED_LIBRARY=1;%(PreprocessorDefinitions) @@ -20,29 +21,29 @@ - $(MSBuildThisFileDirectory)..\..\lib\wisdom$(LP).lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\lib\wisdom-shared$(LP).lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\lib\wisdom-platform$(LP).lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\lib\wisdom-platform-shared$(LP).lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\lib\vkma$(LP).lib;%(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\lib\DX12Allocator$(LP).lib;$(MSBuildThisFileDirectory)..\..\lib\DX12Agility$(LP).lib;dxguid.lib;DXGI.lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\wisdom$(LP).lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\wisdom-shared$(LP).lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\wisdom-platform$(LP).lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\wisdom-platform-shared$(LP).lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\vkma$(LP).lib;%(AdditionalDependencies) + $(MSBuildThisFileDirectory)..\..\lib\native\x64\D3D12MemoryAllocator$(LP).lib;$(MSBuildThisFileDirectory)..\..\lib\native\x64\DirectX-Headers$(LP).lib;$(MSBuildThisFileDirectory)..\..\lib\native\x64\DirectX-Guids$(LP).lib;dxguid.lib;DXGI.lib;d3d12.lib;%(AdditionalDependencies) + - - - - wisdom-shared$(LP).dll - PreserveNewest - - true - - - wisdom-platform-shared$(LP).dll - PreserveNewest - - true - - + + + + wisdom-shared$(LP).dll + PreserveNewest + + true + + + wisdom-platform-shared$(LP).dll + PreserveNewest + + true + + - diff --git a/conanfile.py b/conanfile.py index 8937bfdf0..a16d8e92c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,16 +1,18 @@ +import os + from conan import ConanFile from conan.tools.cmake import CMake from conan.tools.cmake import cmake_layout +from conan.tools.cmake import CMakeDeps from conan.tools.cmake import CMakeToolchain -from conan.tools.files import collect_libs from conan.tools.files import copy +from conan.tools.files import load class WisdomConan(ConanFile): """ """ name = "wisdom" - version = "0.7.0" package_type = "library" license = "MIT" @@ -25,11 +27,30 @@ class WisdomConan(ConanFile): "build_platform": [True, False], } default_options = { - "shared": False, + "shared": True, "fPIC": True, "build_platform": True, } + # keep it for now, but remove when we are at CCI + def set_version(self): + """ """ + version_file_path = os.path.join(self.recipe_folder, "version/VERSION") + + try: + self.version = load(self, version_file_path).strip() + except Exception as e: + self.output.warning(f"Could not read version file: {e}") + self.version = "0.0.0" + + def requirements(self): + """ """ + # If windows platform support is enabled, we need to require the D3D12 Memory Allocator + if self.settings.os == "Windows": + self.requires("d3d12-memory-allocator/[>=3.0.1 <4]", + transitive_headers=True) + self.requires("vulkan-memory-allocator/3.3.0", transitive_headers=True) + def export_sources(self): """ """ copy( @@ -68,19 +89,30 @@ def layout(self): def generate(self): """ """ + deps = CMakeDeps(self) + deps.generate() + self.output.warning( "This recipe currently relies on the project's CPM/NuGet dependency loading during CMake configure. " "For Conan Center, those dependencies should be provided as Conan requirements or vendored sources." ) tc = CMakeToolchain(self) - tc.generator = "Ninja" tc.variables["WISDOM_BUILD_EXAMPLES"] = False tc.variables["WISDOM_BUILD_TESTS"] = False tc.variables["WISDOM_BUILD_DOCS"] = False - tc.variables["WISDOM_BUILD_STATIC"] = not self.options.shared - tc.variables["WISDOM_BUILD_SHARED"] = self.options.shared + tc.variables["WISDOM_BUILD_STATIC"] = not self.options.get_safe( + "shared") + tc.variables["WISDOM_BUILD_SHARED"] = self.options.get_safe("shared") tc.variables["WISDOM_BUILD_PLATFORM"] = self.options.build_platform + tc.variables["WISDOM_USE_AGILITY_SDK"] = False + tc.variables["WISDOM_USE_CONAN"] = True + tc.variables["WISDOM_DOWNLOAD_DXC"] = False + tc.variables["CMAKE_UNITY_BUILD"] = True + + if self.settings.os == "Windows": + tc.preprocessor_definitions["VK_USE_PLATFORM_WIN32_KHR"] = "1" + tc.generate() def build(self): @@ -96,33 +128,54 @@ def package(self): def package_info(self): """ """ - self.cpp_info.set_property("cmake_file_name", "wisdom") - self.cpp_info.builddirs.append("lib/cmake/wisdom") - - all_libs = collect_libs(self) - - core_target = "wis::wisdom-shared" if self.options.shared else "wis::wisdom" - core_lib_hints = {"wisdom-shared", "wisdom"} - core_libs = [ - lib for lib in all_libs if any(h in lib for h in core_lib_hints) + # The overarching file namespace (find_package(wisdom)) + self.cpp_info.set_property("cmake_file_name", "Wisdom") + + build_modules = ["lib/cmake/wisdom/functions.cmake"] + self.cpp_info.set_property("cmake_build_modules", build_modules) + + # Targets: + suffix = "d" if self.settings.build_type == "Debug" else "" + if self.options.get_safe("shared"): + # Core Shared + self.cpp_info.components["core"].set_property( + "cmake_target_name", "wis::wisdom-shared") + self.cpp_info.components["core"].libs = [f"wisdom-shared{suffix}"] + + # Platform Shared + if self.options.build_platform: + self.cpp_info.components["platform"].set_property( + "cmake_target_name", "wis::wisdom-platform-shared") + self.cpp_info.components["platform"].requires = ["core"] + self.cpp_info.components["platform"].libs = [ + f"wisdom-platform-shared{suffix}" + ] + else: + # Core Static + self.cpp_info.components["core"].set_property( + "cmake_target_name", "wis::wisdom") + self.cpp_info.components["core"].libs = [ + f"wisdom{suffix}", f"vkma{suffix}" + ] + + # Platform Static + if self.options.build_platform: + self.cpp_info.components["platform"].set_property( + "cmake_target_name", "wis::wisdom-platform") + self.cpp_info.components["platform"].requires = ["core"] + self.cpp_info.components["platform"].libs = [ + f"wisdom-platform{suffix}" + ] + + self.cpp_info.components["core"].requires = [ + "vulkan-memory-allocator::vulkan-memory-allocator" ] - platform_libs = [lib for lib in all_libs if "platform" in lib] - - self.cpp_info.components["headers"].set_property( - "cmake_target_name", "wis::wisdom-headers") - - self.cpp_info.components["core"].set_property("cmake_target_name", - core_target) - self.cpp_info.components["core"].requires = ["headers"] - self.cpp_info.components["core"].libs = core_libs - - self.cpp_info.components["platform_headers"].set_property( - "cmake_target_name", "wis::wisdom-platform-headers") - self.cpp_info.components["platform_headers"].requires = ["headers"] - - self.cpp_info.components["platform"].set_property( - "cmake_target_name", "wis::wisdom-platform") - self.cpp_info.components["platform"].requires = [ - "core", "platform_headers" - ] - self.cpp_info.components["platform"].libs = platform_libs + if self.settings.os == "Windows": + self.cpp_info.components["core"].defines.extend([ + "D3D12MA_USING_DIRECTX_HEADERS=1", + "VK_USE_PLATFORM_WIN32_KHR=1", + ]) + self.cpp_info.components["core"].requires.extend( + ["d3d12-memory-allocator::d3d12-memory-allocator"]) + self.cpp_info.components["core"].system_libs.extend( + ["dxgi", "DXGUID"]) diff --git a/docs/platform/func/destroy_u_w_p_extension_function.h b/docs/platform/func/destroy_u_w_p_extension_function.h index 9d6414963..a7a023059 100644 --- a/docs/platform/func/destroy_u_w_p_extension_function.h +++ b/docs/platform/func/destroy_u_w_p_extension_function.h @@ -9,18 +9,18 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisDestroyUWPExtension(WisUWPExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * void wisDX12DestroyUWPExtension(WisDX12UWPExtension* self); * ``` *
- * + * * \endcond * * @section wisDestroyUWPExtension_memb Parameters diff --git a/docs/platform/func/destroy_wayland_extension_function.h b/docs/platform/func/destroy_wayland_extension_function.h index e53565099..8ef7842e6 100644 --- a/docs/platform/func/destroy_wayland_extension_function.h +++ b/docs/platform/func/destroy_wayland_extension_function.h @@ -9,18 +9,18 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisDestroyWaylandExtension(WisWaylandExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKDestroyWaylandExtension(WisVKWaylandExtension* self); - * + * * ``` *
- * + * * \endcond * * @section wisDestroyWaylandExtension_memb Parameters diff --git a/docs/platform/func/destroy_win32_extension_function.h b/docs/platform/func/destroy_win32_extension_function.h index dd47243b6..a43e03443 100644 --- a/docs/platform/func/destroy_win32_extension_function.h +++ b/docs/platform/func/destroy_win32_extension_function.h @@ -9,20 +9,20 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisDestroyWin32Extension(WisWin32Extension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKDestroyWin32Extension(WisVKWin32Extension* self); - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * void wisDX12DestroyWin32Extension(WisDX12Win32Extension* self); * ``` *
- * + * * \endcond * * @section wisDestroyWin32Extension_memb Parameters diff --git a/docs/platform/func/destroy_x_c_b_extension_function.h b/docs/platform/func/destroy_x_c_b_extension_function.h index b44ac9dc5..e92b3bbce 100644 --- a/docs/platform/func/destroy_x_c_b_extension_function.h +++ b/docs/platform/func/destroy_x_c_b_extension_function.h @@ -9,18 +9,18 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisDestroyXCBExtension(WisXCBExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKDestroyXCBExtension(WisVKXCBExtension* self); - * + * * ``` *
- * + * * \endcond * * @section wisDestroyXCBExtension_memb Parameters diff --git a/docs/platform/func/destroy_xlib_extension_function.h b/docs/platform/func/destroy_xlib_extension_function.h index 2d9e70297..277e3e47d 100644 --- a/docs/platform/func/destroy_xlib_extension_function.h +++ b/docs/platform/func/destroy_xlib_extension_function.h @@ -9,18 +9,18 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisDestroyXlibExtension(WisXlibExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKDestroyXlibExtension(WisVKXlibExtension* self); - * + * * ``` *
- * + * * \endcond * * @section wisDestroyXlibExtension_memb Parameters diff --git a/docs/platform/func/init_u_w_p_extension_function.h b/docs/platform/func/init_u_w_p_extension_function.h index 4ff2e4355..c429d5c2e 100644 --- a/docs/platform/func/init_u_w_p_extension_function.h +++ b/docs/platform/func/init_u_w_p_extension_function.h @@ -9,23 +9,23 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisInitUWPExtension(WisUWPExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * void wisDX12InitUWPExtension(WisDX12UWPExtension* self); * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void DX12UWPExtension::InitUWPExtension() noexcept; + * // Provided by Wisdom 0.7.0. + * DX12UWPExtension::DX12UWPExtension() noexcept; * } * ``` * \endcond @@ -33,7 +33,8 @@ * @section wisInitUWPExtension_memb Parameters *
* \cond WIS_GEN_DESC - * - **this** `self` is a pointer to uninitialized WisUWPExtension instance memory. It will be initialized by this function. + * - **this** `self` is a pointer to uninitialized WisUWPExtension instance memory. It will be initialized by this + * function. * **note** The corresponding destroy function is `wisDestroyUWPExtension`. * \endcond * diff --git a/docs/platform/func/init_wayland_extension_function.h b/docs/platform/func/init_wayland_extension_function.h index fed3c3cae..8b9ad7bd1 100644 --- a/docs/platform/func/init_wayland_extension_function.h +++ b/docs/platform/func/init_wayland_extension_function.h @@ -9,23 +9,23 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisInitWaylandExtension(WisWaylandExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKInitWaylandExtension(WisVKWaylandExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void VKWaylandExtension::InitWaylandExtension() noexcept; + * // Provided by Wisdom 0.7.0. + * VKWaylandExtension::VKWaylandExtension() noexcept; * } * ``` * \endcond @@ -33,7 +33,8 @@ * @section wisInitWaylandExtension_memb Parameters *
* \cond WIS_GEN_DESC - * - **this** `self` is a pointer to uninitialized WisWaylandExtension instance memory. It will be initialized by this function. + * - **this** `self` is a pointer to uninitialized WisWaylandExtension instance memory. It will be initialized by this + * function. * **note** The corresponding destroy function is `wisDestroyWaylandExtension`. * \endcond * diff --git a/docs/platform/func/init_win32_extension_function.h b/docs/platform/func/init_win32_extension_function.h index 3d560aa64..45b57d70c 100644 --- a/docs/platform/func/init_win32_extension_function.h +++ b/docs/platform/func/init_win32_extension_function.h @@ -9,36 +9,36 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisInitWin32Extension(WisWin32Extension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKInitWin32Extension(WisVKWin32Extension* self); - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * void wisDX12InitWin32Extension(WisDX12Win32Extension* self); * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void Win32Extension::InitWin32Extension() noexcept; + * // Provided by Wisdom 0.7.0. + * Win32Extension::Win32Extension() noexcept; * } * ``` *
* C++ Implementation Specific Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void VKWin32Extension::InitWin32Extension() noexcept; - * - * // Provided by Wisdom 0.7.0. - * void DX12Win32Extension::InitWin32Extension() noexcept; + * // Provided by Wisdom 0.7.0. + * VKWin32Extension::VKWin32Extension() noexcept; + * + * // Provided by Wisdom 0.7.0. + * DX12Win32Extension::DX12Win32Extension() noexcept; * } * ``` *
@@ -47,7 +47,8 @@ * @section wisInitWin32Extension_memb Parameters *
* \cond WIS_GEN_DESC - * - **this** `self` is a pointer to uninitialized WisWin32Extension instance memory. It will be initialized by this function. + * - **this** `self` is a pointer to uninitialized WisWin32Extension instance memory. It will be initialized by this + * function. * **note** The corresponding destroy function is `wisDestroyWin32Extension`. * \endcond * diff --git a/docs/platform/func/init_x_c_b_extension_function.h b/docs/platform/func/init_x_c_b_extension_function.h index 1621ac666..24e9d14e2 100644 --- a/docs/platform/func/init_x_c_b_extension_function.h +++ b/docs/platform/func/init_x_c_b_extension_function.h @@ -9,23 +9,23 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisInitXCBExtension(WisXCBExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKInitXCBExtension(WisVKXCBExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void VKXCBExtension::InitXCBExtension() noexcept; + * // Provided by Wisdom 0.7.0. + * VKXCBExtension::VKXCBExtension() noexcept; * } * ``` * \endcond @@ -33,7 +33,8 @@ * @section wisInitXCBExtension_memb Parameters *
* \cond WIS_GEN_DESC - * - **this** `self` is a pointer to uninitialized WisXCBExtension instance memory. It will be initialized by this function. + * - **this** `self` is a pointer to uninitialized WisXCBExtension instance memory. It will be initialized by this + * function. * **note** The corresponding destroy function is `wisDestroyXCBExtension`. * \endcond * diff --git a/docs/platform/func/init_xlib_extension_function.h b/docs/platform/func/init_xlib_extension_function.h index 7b6625df6..add1ed0ac 100644 --- a/docs/platform/func/init_xlib_extension_function.h +++ b/docs/platform/func/init_xlib_extension_function.h @@ -9,23 +9,23 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisInitXlibExtension(WisXlibExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * void wisVKInitXlibExtension(WisVKXlibExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. - * void VKXlibExtension::InitXlibExtension() noexcept; + * // Provided by Wisdom 0.7.0. + * VKXlibExtension::VKXlibExtension() noexcept; * } * ``` * \endcond @@ -33,7 +33,8 @@ * @section wisInitXlibExtension_memb Parameters *
* \cond WIS_GEN_DESC - * - **this** `self` is a pointer to uninitialized WisXlibExtension instance memory. It will be initialized by this function. + * - **this** `self` is a pointer to uninitialized WisXlibExtension instance memory. It will be initialized by this + * function. * **note** The corresponding destroy function is `wisDestroyXlibExtension`. * \endcond * diff --git a/docs/platform/func/u_w_p_extension_create_surface_function.h b/docs/platform/func/u_w_p_extension_create_surface_function.h index cb3f84156..1c18dcb2c 100644 --- a/docs/platform/func/u_w_p_extension_create_surface_function.h +++ b/docs/platform/func/u_w_p_extension_create_surface_function.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisUWPExtensionCreateSurface(WisUWPExtension* self, * const WisUWPWindowDesc* info, * WisSurface* surface); @@ -17,18 +17,18 @@ *
* C Implementation Specific Version: * ```c - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * WisResult wisDX12UWPExtensionCreateSurface(WisDX12UWPExtension* self, * const WisUWPWindowDesc* info, * WisDX12Surface* surface); * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::DX12Surface DX12UWPExtension::CreateSurface(const wis::UWPWindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -41,7 +41,7 @@ * - **this** `self` self is a pointer to the valid WisUWPExtension instance. * - `info` UWP windowing data. * - `surface` points to WisSurface, initialized on success. - * + * * - **return** denoting the outcome of operation. * \endcond * diff --git a/docs/platform/func/wayland_extension_create_surface_function.h b/docs/platform/func/wayland_extension_create_surface_function.h index d96c8ee0e..8ffe7bf36 100644 --- a/docs/platform/func/wayland_extension_create_surface_function.h +++ b/docs/platform/func/wayland_extension_create_surface_function.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisWaylandExtensionCreateSurface(WisWaylandExtension* self, * const WisWaylandWindowDesc* info, * WisSurface* surface); @@ -17,18 +17,18 @@ *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisVKWaylandExtensionCreateSurface(WisVKWaylandExtension* self, * const WisWaylandWindowDesc* info, * WisVKSurface* surface); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::VKSurface VKWaylandExtension::CreateSurface(const wis::WaylandWindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -41,7 +41,7 @@ * - **this** `self` self is a pointer to the valid WisWaylandExtension instance. * - `info` Wayland windowing data. * - `surface` points to WisSurface, initialized on success. - * + * * - **return** denoting the outcome of operation. * \endcond * diff --git a/docs/platform/func/wayland_extension_supported_function.h b/docs/platform/func/wayland_extension_supported_function.h index 0e83f2d18..92ad8f0ec 100644 --- a/docs/platform/func/wayland_extension_supported_function.h +++ b/docs/platform/func/wayland_extension_supported_function.h @@ -9,22 +9,22 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisWaylandExtensionSupported(WisWaylandExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisVKWaylandExtensionSupported(WisVKWaylandExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool VKWaylandExtension::Supported() noexcept; * } * ``` @@ -34,7 +34,7 @@ *
* \cond WIS_GEN_DESC * - **this** `self` self is a pointer to the valid WisWaylandExtension instance. - * + * * - **return** true if the extension is supported, false otherwise. * \endcond * @@ -48,4 +48,4 @@ *
* \cond WIS_GEN_REFS * \endcond - */ \ No newline at end of file + */ diff --git a/docs/platform/func/win32_extension_create_surface_function.h b/docs/platform/func/win32_extension_create_surface_function.h index 7f05387cc..361678fff 100644 --- a/docs/platform/func/win32_extension_create_surface_function.h +++ b/docs/platform/func/win32_extension_create_surface_function.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisWin32ExtensionCreateSurface(WisWin32Extension* self, * const WisWin32WindowDesc* info, * WisSurface* surface); @@ -17,22 +17,22 @@ *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisVKWin32ExtensionCreateSurface(WisVKWin32Extension* self, * const WisWin32WindowDesc* info, * WisVKSurface* surface); - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * WisResult wisDX12Win32ExtensionCreateSurface(WisDX12Win32Extension* self, * const WisWin32WindowDesc* info, * WisDX12Surface* surface); * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::Surface Win32Extension::CreateSurface(const wis::Win32WindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -41,11 +41,11 @@ * C++ Implementation Specific Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::VKSurface VKWin32Extension::CreateSurface(const wis::Win32WindowDesc& info, * wis::Result& out_result) noexcept; - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::DX12Surface DX12Win32Extension::CreateSurface(const wis::Win32WindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -59,7 +59,7 @@ * - **this** `self` self is a pointer to the valid WisWin32Extension instance. * - `info` Win32 windowing data. * - `surface` points to WisSurface, initialized on success. - * + * * - **return** denoting the outcome of operation. * \endcond * diff --git a/docs/platform/func/win32_extension_supported_function.h b/docs/platform/func/win32_extension_supported_function.h index ebb0af710..7d64a7906 100644 --- a/docs/platform/func/win32_extension_supported_function.h +++ b/docs/platform/func/win32_extension_supported_function.h @@ -9,24 +9,24 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisWin32ExtensionSupported(WisWin32Extension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisVKWin32ExtensionSupported(WisVKWin32Extension* self); - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * bool wisDX12Win32ExtensionSupported(WisDX12Win32Extension* self); * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool Win32Extension::Supported() noexcept; * } * ``` @@ -34,10 +34,10 @@ * C++ Implementation Specific Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool VKWin32Extension::Supported() noexcept; - * - * // Provided by Wisdom 0.7.0. + * + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool DX12Win32Extension::Supported() noexcept; * } * ``` @@ -48,7 +48,7 @@ *
* \cond WIS_GEN_DESC * - **this** `self` self is a pointer to the valid WisWin32Extension instance. - * + * * - **return** true if the extension is supported, false otherwise. * \endcond * @@ -62,4 +62,4 @@ *
* \cond WIS_GEN_REFS * \endcond - */ \ No newline at end of file + */ diff --git a/docs/platform/func/x_c_b_extension_create_surface_function.h b/docs/platform/func/x_c_b_extension_create_surface_function.h index 1c31581c7..681cfea8b 100644 --- a/docs/platform/func/x_c_b_extension_create_surface_function.h +++ b/docs/platform/func/x_c_b_extension_create_surface_function.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisXCBExtensionCreateSurface(WisXCBExtension* self, * const WisXCBWindowDesc* info, * WisSurface* surface); @@ -17,18 +17,18 @@ *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisVKXCBExtensionCreateSurface(WisVKXCBExtension* self, * const WisXCBWindowDesc* info, * WisVKSurface* surface); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::VKSurface VKXCBExtension::CreateSurface(const wis::XCBWindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -41,7 +41,7 @@ * - **this** `self` self is a pointer to the valid WisXCBExtension instance. * - `info` XCB windowing data. * - `surface` points to WisSurface, initialized on success. - * + * * - **return** denoting the outcome of operation. * \endcond * diff --git a/docs/platform/func/x_c_b_extension_supported_function.h b/docs/platform/func/x_c_b_extension_supported_function.h index baed003fe..03822ab34 100644 --- a/docs/platform/func/x_c_b_extension_supported_function.h +++ b/docs/platform/func/x_c_b_extension_supported_function.h @@ -9,22 +9,22 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisXCBExtensionSupported(WisXCBExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisVKXCBExtensionSupported(WisVKXCBExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool VKXCBExtension::Supported() noexcept; * } * ``` @@ -34,7 +34,7 @@ *
* \cond WIS_GEN_DESC * - **this** `self` self is a pointer to the valid WisXCBExtension instance. - * + * * - **return** true if the extension is supported, false otherwise. * \endcond * @@ -48,4 +48,4 @@ *
* \cond WIS_GEN_REFS * \endcond - */ \ No newline at end of file + */ diff --git a/docs/platform/func/xlib_extension_create_surface_function.h b/docs/platform/func/xlib_extension_create_surface_function.h index 9e3cef911..085918247 100644 --- a/docs/platform/func/xlib_extension_create_surface_function.h +++ b/docs/platform/func/xlib_extension_create_surface_function.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisXlibExtensionCreateSurface(WisXlibExtension* self, * const WisXlibWindowDesc* info, * WisSurface* surface); @@ -17,18 +17,18 @@ *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WisResult wisVKXlibExtensionCreateSurface(WisVKXlibExtension* self, * const WisXlibWindowDesc* info, * WisVKSurface* surface); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD wis::VKSurface VKXlibExtension::CreateSurface(const wis::XlibWindowDesc& info, * wis::Result& out_result) noexcept; * } @@ -41,7 +41,7 @@ * - **this** `self` self is a pointer to the valid WisXlibExtension instance. * - `info` Xlib windowing data. * - `surface` points to WisSurface, initialized on success. - * + * * - **return** denoting the outcome of operation. * \endcond * diff --git a/docs/platform/func/xlib_extension_supported_function.h b/docs/platform/func/xlib_extension_supported_function.h index 6cfb5efc7..a31605835 100644 --- a/docs/platform/func/xlib_extension_supported_function.h +++ b/docs/platform/func/xlib_extension_supported_function.h @@ -9,22 +9,22 @@ * \cond WIS_GEN_CODE * C Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisXlibExtensionSupported(WisXlibExtension* self); * ``` *
* C Implementation Specific Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * bool wisVKXlibExtensionSupported(WisVKXlibExtension* self); - * + * * ``` *
- * + * * C++ Version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_NODISCARD bool VKXlibExtension::Supported() noexcept; * } * ``` @@ -34,7 +34,7 @@ *
* \cond WIS_GEN_DESC * - **this** `self` self is a pointer to the valid WisXlibExtension instance. - * + * * - **return** true if the extension is supported, false otherwise. * \endcond * @@ -48,4 +48,4 @@ *
* \cond WIS_GEN_REFS * \endcond - */ \ No newline at end of file + */ diff --git a/docs/platform/handle/u_w_p_extension_handle.h b/docs/platform/handle/u_w_p_extension_handle.h index 71f767cfd..f64aa387c 100644 --- a/docs/platform/handle/u_w_p_extension_handle.h +++ b/docs/platform/handle/u_w_p_extension_handle.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * DX12 Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_DX12_INSTANCE_EXT_HANDLE(WisDX12UWPExtension,1); * ``` * \endcond diff --git a/docs/platform/handle/wayland_extension_handle.h b/docs/platform/handle/wayland_extension_handle.h index 3d355d74e..c97647f7e 100644 --- a/docs/platform/handle/wayland_extension_handle.h +++ b/docs/platform/handle/wayland_extension_handle.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * Vulkan Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_VK_INSTANCE_EXT_HANDLE(WisVKWaylandExtension,2); * ``` * \endcond diff --git a/docs/platform/handle/win32_extension_handle.h b/docs/platform/handle/win32_extension_handle.h index 650e9f215..91f0235bd 100644 --- a/docs/platform/handle/win32_extension_handle.h +++ b/docs/platform/handle/win32_extension_handle.h @@ -9,12 +9,12 @@ * \cond WIS_GEN_CODE * Vulkan Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_VK_INSTANCE_EXT_HANDLE(WisVKWin32Extension,2); * ``` * DX12 Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_DX12_INSTANCE_EXT_HANDLE(WisDX12Win32Extension,1); * ``` * \endcond diff --git a/docs/platform/handle/x_c_b_extension_handle.h b/docs/platform/handle/x_c_b_extension_handle.h index 3cb07a738..bd18ffa3a 100644 --- a/docs/platform/handle/x_c_b_extension_handle.h +++ b/docs/platform/handle/x_c_b_extension_handle.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * Vulkan Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_VK_INSTANCE_EXT_HANDLE(WisVKXCBExtension,2); * ``` * \endcond diff --git a/docs/platform/handle/xlib_extension_handle.h b/docs/platform/handle/xlib_extension_handle.h index ce14edf3e..245a1ec6b 100644 --- a/docs/platform/handle/xlib_extension_handle.h +++ b/docs/platform/handle/xlib_extension_handle.h @@ -9,7 +9,7 @@ * \cond WIS_GEN_CODE * Vulkan Version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * WIS_DEFINE_VK_INSTANCE_EXT_HANDLE(WisVKXlibExtension,2); * ``` * \endcond diff --git a/docs/platform/struct/u_w_p_window_desc_struct.h b/docs/platform/struct/u_w_p_window_desc_struct.h index e9a9b058e..5d70d65d7 100644 --- a/docs/platform/struct/u_w_p_window_desc_struct.h +++ b/docs/platform/struct/u_w_p_window_desc_struct.h @@ -9,16 +9,16 @@ * \cond WIS_GEN_CODE * C version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * typedef struct WisUWPWindowDesc { * void* core_window; * } WisUWPWindowDesc; - * + * * ``` * C++ version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * struct UWPWindowDesc { * void* core_window; * }; diff --git a/docs/platform/struct/wayland_window_desc_struct.h b/docs/platform/struct/wayland_window_desc_struct.h index 96ab2c420..7ee632182 100644 --- a/docs/platform/struct/wayland_window_desc_struct.h +++ b/docs/platform/struct/wayland_window_desc_struct.h @@ -9,17 +9,17 @@ * \cond WIS_GEN_CODE * C version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * typedef struct WisWaylandWindowDesc { * void* display; * void* surface; * } WisWaylandWindowDesc; - * + * * ``` * C++ version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * struct WaylandWindowDesc { * void* display; * void* surface; diff --git a/docs/platform/struct/win32_window_desc_struct.h b/docs/platform/struct/win32_window_desc_struct.h index 589960d98..fa7fbc6f9 100644 --- a/docs/platform/struct/win32_window_desc_struct.h +++ b/docs/platform/struct/win32_window_desc_struct.h @@ -9,17 +9,17 @@ * \cond WIS_GEN_CODE * C version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * typedef struct WisWin32WindowDesc { * void* hinstance; * void* hwnd; * } WisWin32WindowDesc; - * + * * ``` * C++ version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * struct Win32WindowDesc { * void* hinstance; * void* hwnd; diff --git a/docs/platform/struct/x_c_b_window_desc_struct.h b/docs/platform/struct/x_c_b_window_desc_struct.h index f2b5f928b..6c222c1fe 100644 --- a/docs/platform/struct/x_c_b_window_desc_struct.h +++ b/docs/platform/struct/x_c_b_window_desc_struct.h @@ -9,17 +9,17 @@ * \cond WIS_GEN_CODE * C version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * typedef struct WisXCBWindowDesc { * void* connection; * uint32_t window; * } WisXCBWindowDesc; - * + * * ``` * C++ version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * struct XCBWindowDesc { * void* connection; * std::uint32_t window; diff --git a/docs/platform/struct/xlib_window_desc_struct.h b/docs/platform/struct/xlib_window_desc_struct.h index 4c7754245..539cae3cb 100644 --- a/docs/platform/struct/xlib_window_desc_struct.h +++ b/docs/platform/struct/xlib_window_desc_struct.h @@ -9,17 +9,17 @@ * \cond WIS_GEN_CODE * C version: * ```c - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * typedef struct WisXlibWindowDesc { * void* display; * uint64_t window; * } WisXlibWindowDesc; - * + * * ``` * C++ version: * ```cpp * namespace wis{ - * // Provided by Wisdom 0.7.0. + * // Provided by Wisdom 0.7.0. * struct XlibWindowDesc { * void* display; * std::uint64_t window; diff --git a/docs/wisdom/contributing.h b/docs/wisdom/contributing.h index cbeb06583..5212ec66b 100644 --- a/docs/wisdom/contributing.h +++ b/docs/wisdom/contributing.h @@ -259,3 +259,87 @@ * @note Thank you for your interest in contributing to Wisdom! Your contributions help make this library better for * everyone. */ + +/** + * @page agility_page Agility SDK + * This page is dedicated to providing information about using the Agility SDK with Wisdom for DirectX 12 development on + * Windows. The Agility SDK allows developers to access the latest DirectX 12 features on older Windows versions, but it + * requires additional setup and dependencies compared to using the Windows SDK. + * + * @section what_happened_sec What Happened to the Agility SDK? + * + * If you have used Wisdom before, you may have noticed that the Agility SDK is no longer included as a default option + * for DirectX 12 development. This change was made to simplify the build process and reduce the number of dependencies. + * This in turn was done for a few reasons: + * - The Agility SDK breaks the Conan package, because it is not available as a Conan package and it requires manual + * installation and setup. This makes it difficult to maintain and use in a consistent way across different + * environments. + * - The Agility SDK is not required for the build, as the Windows SDK provides access to the latest DirectX 12 + * features on Windows 11 and Windows 10 (with the latest updates). For users who need to support older Windows + * versions, the Agility SDK can still be used by enabling the `WISDOM_USE_AGILITY_SDK` CMake option and following the + * setup instructions below. + * - The Agility SDK break transparency of the library, because it requires additional setup and exports were hidden + * behind a CMake command. This makes it difficult to use the library in a consistent way across different environments + * and platforms. + * + * @section using_agility_sec Using the Agility SDK with Wisdom + * + * Because the Agility SDK can be tricky to set up (requiring specific DLL placement and symbol exports), Wisdom + * provides different usage paths depending on how you consume the library. + * + * @subsection path_nuget NuGet + * If you are consuming Wisdom via NuGet, install the `Microsoft.Direct3D.D3D12` package to use the Agility SDK. Wisdom + * does not bundle it for NuGet to avoid issues with UWP builds (Windows App Certification Kit). The NuGet package + * should handle copying the required DLLs to the output directory. + * + * @subsection path_cmake CMake + * If you are using CMake, Wisdom provides several helpers depending on your integration method: + * + * - **Sources (FetchContent / CPM)**: Set the CMake option `WISDOM_USE_AGILITY_SDK=ON` before integrating the library. + * Wisdom will handle the SDK download and link it automatically. + * - **.ZIP Distribution**: The Agility SDK is included automatically. + * - **Conan Package (Future)**: You will need to explicitly call the CMake function `wis_load_agility_sdk()` provided + * by Wisdom, or handle it yourself. + * + * **Installing the DLLs & Exporting Symbols in CMake**: + * To run your application, the Agility SDK DLLs (`D3D12Core.dll` and `D3DSDKLayers.dll`) must be copied to your output + * directory. Wisdom provides a CMake helper for this: + * ```cmake + * wis_install_agility_win32(YOUR_TARGET_NAME PATCH_EXE) + * ``` + * If you pass the `PATCH_EXE` argument, Wisdom will automatically call `wis_patch_agility_executable()` to export the + * required Agility SDK symbols directly in the compiled binary. **If you do this, you do not need to use any C++ + * macros.** + * + * @subsection path_manual Non-CMake / Manual Integration + * If you are using Conan with a build system other than CMake, or integrating manually: + * 1. Ensure the Agility SDK is downloaded. + * 2. Copy the DLLs to your output directory. + * 3. Export the symbols using the C++ macros described below. + * + * @section exporting_symbols_sec Exporting Symbols (C++ Macros) + * + * If you did **not** use the CMake `PATCH_EXE` method to automatically export symbols, you must export them in your + * source code (usually in `main.cpp`). + * + * - **When Wisdom loads Agility via CMake** (`WISDOM_USE_AGILITY_SDK=ON` or `.zip`): Use the standard macro. + * ```cpp + * WISDOM_EXPORT_AGILITY_SYMBOLS(); + * ``` + * + * - **When integrating manually** (or using NuGet / Conan without CMake): Use the custom macro with your specific SDK + * version. + * ```cpp + * WISDOM_EXPORT_AGILITY_CUSTOM(619); // Replace 619 with your Agility SDK version + * ``` + * + * Alternatively, you can directly export the symbols using the `extern "C" __declspec(dllexport)` approach as + * documented by Microsoft. + * + * @section agility_conclusion_sec Conclusion + * + * Providing these helpers drastically simplifies the setup compared to the manual Agility SDK installation process. + * While the multiple paths may seem complex at a glance, formatting them by package manager/method ensures that whether + * you use FetchContent, Conan, NuGet, or manual integration, there is a clear and accessible route to access modern + * DirectX 12 features. + */ diff --git a/docs/wisdom/enum/adapter_preference_enum.h b/docs/wisdom/enum/adapter_preference_enum.h index 66a658980..ee3e18d9b 100644 --- a/docs/wisdom/enum/adapter_preference_enum.h +++ b/docs/wisdom/enum/adapter_preference_enum.h @@ -43,7 +43,8 @@ * - `WisAdapterPreferenceMinConsumption = 1`: List the adapters from low power consumption to high. DirectX 12: * Integrated, Discrete, External, Software. Vulkan: Integrated GPU, Discrete GPU, Virtual GPU, CPU. * - `WisAdapterPreferencePerformance = 2`: List the adapters from high performance to low. DirectX 12: External, - * Discrete, Integrated, Software. Vulkan: Discrete GPU, Integrated GPU, Virtual GPU, CPU. \endcond + * Discrete, Integrated, Software. Vulkan: Discrete GPU, Integrated GPU, Virtual GPU, CPU. + * \endcond * * GPU order @wis_may vary between the implementations due to differing heuristics. * diff --git a/docs/wisdom/enum/address_mode_enum.h b/docs/wisdom/enum/address_mode_enum.h index e205c7443..e6e718724 100644 --- a/docs/wisdom/enum/address_mode_enum.h +++ b/docs/wisdom/enum/address_mode_enum.h @@ -5,6 +5,9 @@ * @section WisAddressMode_spec Specification *
* + * Possible values for texture address mode. Used in `WisSamplerDesc` to specify how texture coordinates outside the [0, + * 1] range are handled. + * * \cond WIS_GEN_CODE * C version: * ```c diff --git a/docs/wisdom/enum/barrier_flags_enum.h b/docs/wisdom/enum/barrier_flags_enum.h index 5ea6891b3..d6afc1a46 100644 --- a/docs/wisdom/enum/barrier_flags_enum.h +++ b/docs/wisdom/enum/barrier_flags_enum.h @@ -47,7 +47,8 @@ * the specified subresource range. If set, the subresource range is ignored and the transition is applied to all * subresources of the resource. * - `WisBarrierFlagsPlanarImage = (1 << 3)`: Resource is a planar image. If the flag is not set, plane slices in - * WisSubresourceRange are ignored. \endcond + * WisSubresourceRange are ignored. + * \endcond * * * @section WisBarrierFlags_see_also See Also diff --git a/docs/wisdom/enum/buffer_usage_flags_enum.h b/docs/wisdom/enum/buffer_usage_flags_enum.h index 4b70b0645..e1597323c 100644 --- a/docs/wisdom/enum/buffer_usage_flags_enum.h +++ b/docs/wisdom/enum/buffer_usage_flags_enum.h @@ -21,6 +21,8 @@ * WisBufferUsageFlagsAccelerationStructureBuffer = (1u << 7), * WisBufferUsageFlagsAccelerationStructureInput = (1u << 8), * WisBufferUsageFlagsShaderBindingTable = (1u << 9), + * WisBufferUsageFlagsVideoDecodeDst = (1u << 10), + * WisBufferUsageFlagsVideoDecodeSrc = (1u << 11), * } WisBufferUsageFlags; * ``` * C++ version: @@ -39,6 +41,8 @@ * AccelerationStructureBuffer = (1u << 7), * AccelerationStructureInput = (1u << 8), * ShaderBindingTable = (1u << 9), + * VideoDecodeDst = (1u << 10), + * VideoDecodeSrc = (1u << 11), * }; * } * ``` @@ -65,6 +69,8 @@ * - `WisBufferUsageFlagsAccelerationStructureInput = (1 << 8)`: Buffer is used as a read only acceleration instance * input buffer. * - `WisBufferUsageFlagsShaderBindingTable = (1 << 9)`: Buffer is used as a shader binding table buffer. + * - `WisBufferUsageFlagsVideoDecodeDst = (1 << 10)`: Buffer is used as an output of the video decoding operation. + * - `WisBufferUsageFlagsVideoDecodeSrc = (1 << 11)`: Buffer is used as an input of the video decoding operation. * \endcond * * diff --git a/docs/wisdom/enum/command_queue_priority_enum.h b/docs/wisdom/enum/command_queue_priority_enum.h index 3b28f056b..f68ffae45 100644 --- a/docs/wisdom/enum/command_queue_priority_enum.h +++ b/docs/wisdom/enum/command_queue_priority_enum.h @@ -40,7 +40,8 @@ * - `WisCommandQueuePriorityNormal = 0`: Normal queue priority. * - `WisCommandQueuePriorityHigh = 1`: High queue priority. * - `WisCommandQueuePriorityRealtime = 2`: Global realtime queue priority. Requires special GPU support and @wis_may - * cause performance issues if used on unsupported hardware. \endcond + * cause performance issues if used on unsupported hardware. + * \endcond * * * @section WisCommandQueuePriority_see_also See Also diff --git a/docs/wisdom/enum/composite_alpha_enum.h b/docs/wisdom/enum/composite_alpha_enum.h index 8edc0a73d..ed55b6cde 100644 --- a/docs/wisdom/enum/composite_alpha_enum.h +++ b/docs/wisdom/enum/composite_alpha_enum.h @@ -45,7 +45,8 @@ * - `WisCompositeAlphaPostMultiplied = 2`: The alpha channel, if it exists, is respected and used in compositing. The * postmultiplied alpha format is expected. * - `WisCompositeAlphaInherit = 3`: The alpha channel, if it exists, is respected and used in compositing based on the - * platform's default behavior. \endcond + * platform's default behavior. + * \endcond * * * @section WisCompositeAlpha_see_also See Also diff --git a/docs/wisdom/enum/data_format_enum.h b/docs/wisdom/enum/data_format_enum.h index 1d355601e..15301c358 100644 --- a/docs/wisdom/enum/data_format_enum.h +++ b/docs/wisdom/enum/data_format_enum.h @@ -78,6 +78,10 @@ * WisDataFormatBC7RGBAUnorm = 98, * WisDataFormatBC7RGBAUnormSrgb = 99, * WisDataFormatBGRA4Unorm = 115, + * // Provided by Wisdom 0.7.1. WisDataFormatNV12 = 256, + * // Provided by Wisdom 0.7.1. WisDataFormatP010 = 257, + * // Provided by Wisdom 0.7.1. WisDataFormatP012 = 258, + * // Provided by Wisdom 0.7.1. WisDataFormatP016 = 259, * } WisDataFormat; * ``` * C++ version: @@ -153,6 +157,10 @@ * BC7RGBAUnorm = 98, * BC7RGBAUnormSrgb = 99, * BGRA4Unorm = 115, + * // Provided by Wisdom 0.7.1. NV12 = 256, + * // Provided by Wisdom 0.7.1. P010 = 257, + * // Provided by Wisdom 0.7.1. P012 = 258, + * // Provided by Wisdom 0.7.1. P016 = 259, * }; * } * ``` @@ -472,6 +480,23 @@ * a 4-bit G component in bits 4..7, * a 4-bit R component in bits 8..11, * a 4-bit A component in bits 12..15. + * - `WisDataFormatNV12 = 256`: NV12 video format. + * A two-plane format with a single 8-bit Y plane followed by an interleaved UV plane, where the U and V components are + * subsampled by a factor of 2 in both dimensions. The Y plane contains the luma (brightness) information, while the UV + * plane contains the chroma (color) information. This format is commonly used for video encoding and decoding + * applications. + * - `WisDataFormatP010 = 257`: P010 video format. + * A two-plane format similar to NV12, but with 10 bits per channel instead of 8. The Y plane contains 10-bit luma + * information, and the UV plane contains interleaved 10-bit chroma information. This format is used for high-quality + * video encoding and decoding, providing improved color fidelity compared to NV12. + * - `WisDataFormatP012 = 258`: P012 video format. + * A two-plane format similar to P010, but with 12 bits per channel instead of 10. The Y plane contains 12-bit luma + * information, and the UV plane contains interleaved 12-bit chroma information. This format is used for professional + * video applications that require higher color fidelity and dynamic range than P010. + * - `WisDataFormatP016 = 259`: P016 video format. + * A two-plane format similar to P010, but with 16 bits per channel instead of 10. The Y plane contains 16-bit luma + * information, and the UV plane contains interleaved 16-bit chroma information. This format is used for professional + * video applications that require the highest color fidelity and dynamic range. * \endcond * * @@ -482,5 +507,6 @@ * @see Structs: * WisTextureDesc, WisTextureBinding, WisInputAttributeDesc, WisRenderAttachmentsDesc, WisRenderTargetDesc, * WisSwapchainDesc, WisSwapchainUpdateDesc Functions: wisDeviceGetFormatPresentationSupport, - * wisDeviceGetFormatProperties \endcond + * wisDeviceGetFormatProperties + * \endcond */ diff --git a/docs/wisdom/enum/depth_stencil_flags_enum.h b/docs/wisdom/enum/depth_stencil_flags_enum.h index 85bc4ada1..30d64e856 100644 --- a/docs/wisdom/enum/depth_stencil_flags_enum.h +++ b/docs/wisdom/enum/depth_stencil_flags_enum.h @@ -45,7 +45,8 @@ * - `WisDepthStencilFlagsReadOnlyDepth = (1 << 2)`: Depth part is read only. Texture @wis_must be in either read state, * depending on the format. * - `WisDepthStencilFlagsReadOnlyStencil = (1 << 3)`: Stencil part is read only. Texture @wis_must be in either read - * state, depending on the format. \endcond + * state, depending on the format. + * \endcond * * * @section WisDepthStencilFlags_see_also See Also diff --git a/docs/wisdom/enum/descriptor_heap_flags_enum.h b/docs/wisdom/enum/descriptor_heap_flags_enum.h index 5a6caf9ab..48298814f 100644 --- a/docs/wisdom/enum/descriptor_heap_flags_enum.h +++ b/docs/wisdom/enum/descriptor_heap_flags_enum.h @@ -35,7 +35,8 @@ * - `WisDescriptorHeapFlagsNone = 0`: No flags set. * - `WisDescriptorHeapFlagsDisallowEmbeddedSamplers = (1 << 1)`: Heap is used in full for dynamic samplers. There * @wis_mustnot be any shader that use embedded samplers that uses that heap. User @wis_may allocate more samplers in - * the heap than it would normally be. \endcond + * the heap than it would normally be. + * \endcond * * * @section WisDescriptorHeapFlags_see_also See Also diff --git a/docs/wisdom/enum/descriptor_memory_type_enum.h b/docs/wisdom/enum/descriptor_memory_type_enum.h index fee0601ac..12c4dfd59 100644 --- a/docs/wisdom/enum/descriptor_memory_type_enum.h +++ b/docs/wisdom/enum/descriptor_memory_type_enum.h @@ -37,7 +37,8 @@ * - `WisDescriptorMemoryTypeCpuOnly = 0`: Descriptors are only visible to CPU. May be used for copying descriptors to * the GPU visible pool. * - `WisDescriptorMemoryTypeShaderVisible = 1`: Descriptors are visible to GPU. Descriptors can be bound to the GPU - * pipeline directly, but can't be copied from. \endcond + * pipeline directly, but can't be copied from. + * \endcond * * * @section WisDescriptorMemoryType_see_also See Also diff --git a/docs/wisdom/enum/pipeline_flags_enum.h b/docs/wisdom/enum/pipeline_flags_enum.h index fcc2ff347..7fd53c7ae 100644 --- a/docs/wisdom/enum/pipeline_flags_enum.h +++ b/docs/wisdom/enum/pipeline_flags_enum.h @@ -43,7 +43,8 @@ * - `WisPipelineFlagsEnablePrimitiveRestart = (1 << 1)`: Enable primitive restart for graphics pipelines. If not set, * primitive restart is disabled and the implementation @wis_may choose to ignore restart indices in draw calls. * - `WisPipelineFlagsDynamicDepthBias = (1 << 2)`: Enable dynamic depth bias for graphics pipelines. If not set, depth - * bias is static and @wis_must be specified at pipeline creation time. \endcond + * bias is static and @wis_must be specified at pipeline creation time. + * \endcond * * * @section WisPipelineFlags_see_also See Also diff --git a/docs/wisdom/enum/present_flags_enum.h b/docs/wisdom/enum/present_flags_enum.h index 2ffee517d..fa0b0247c 100644 --- a/docs/wisdom/enum/present_flags_enum.h +++ b/docs/wisdom/enum/present_flags_enum.h @@ -36,7 +36,8 @@ * Values: * - `WisPresentFlagsNone = 0`: No flags set. Swapchain is regular. * - `WisPresentFlagsTimeoutOnBlock = (1 << 0)`: Fail present if the presentation engine is busy. If not set, the - * implementation @wis_may choose to block until the presentation engine is available. \endcond + * implementation @wis_may choose to block until the presentation engine is available. + * \endcond * * * @section WisPresentFlags_see_also See Also diff --git a/docs/wisdom/enum/query_property_type_enum.h b/docs/wisdom/enum/query_property_type_enum.h index a6fade280..a66619811 100644 --- a/docs/wisdom/enum/query_property_type_enum.h +++ b/docs/wisdom/enum/query_property_type_enum.h @@ -43,7 +43,8 @@ * - `WisQueryPropertyTypeDeviceMemoryProperties = 2`: Properties of the device descriptor heap. Expects a * WisDeviceMemoryProperties struct. * - `WisQueryPropertyTypeDeviceBindingProperties = 3`: Properties of the device resource binding. Expects a - * WisDeviceBindingProperties struct. \endcond + * WisDeviceBindingProperties struct. + * \endcond * * * @section WisQueryPropertyType_see_also See Also @@ -52,5 +53,6 @@ * \cond WIS_GEN_REFS * @see Structs: * WisQueryStructHeader, WisDeviceBindingProperties, WisDeviceDescriptorHeapProperties, WisDeviceCommandQueueProperties, - * WisDeviceMemoryProperties \endcond + * WisDeviceMemoryProperties + * \endcond */ diff --git a/docs/wisdom/enum/render_pass_flags_enum.h b/docs/wisdom/enum/render_pass_flags_enum.h index c02cda66a..9b6104a84 100644 --- a/docs/wisdom/enum/render_pass_flags_enum.h +++ b/docs/wisdom/enum/render_pass_flags_enum.h @@ -45,7 +45,8 @@ * - `WisRenderPassFlagsResuming = (1 << 2)`: Render pass is resuming. * - `WisRenderPassFlagsAllowUAVWrites = (1 << 3)`: Allow UAV writes. If set, unordered access view (UAV) writes are * allowed during the render pass. If not set, UAV writes are not allowed and @wis_may result in undefined behavior if - * attempted. \endcond + * attempted. + * \endcond * * * @section WisRenderPassFlags_see_also See Also diff --git a/docs/wisdom/enum/swapchain_flags_enum.h b/docs/wisdom/enum/swapchain_flags_enum.h index da0a9a5f5..246e8b4d7 100644 --- a/docs/wisdom/enum/swapchain_flags_enum.h +++ b/docs/wisdom/enum/swapchain_flags_enum.h @@ -41,7 +41,8 @@ * - `WisSwapchainFlagsVSync = (1 << 1)`: Present with vertical sync. If set, the swapchain is presented with vertical * sync pulse. * - `WisSwapchainFlagsStereo = (1 << 2)`: Stereo swapchain. If set, the swapchain is created for stereo rendering. If - * not set, the swapchain is created for mono rendering. \endcond + * not set, the swapchain is created for mono rendering. + * \endcond * * * @section WisSwapchainFlags_see_also See Also diff --git a/docs/wisdom/enum/swapchain_scaling_enum.h b/docs/wisdom/enum/swapchain_scaling_enum.h index 6de51d63e..d2ad922a2 100644 --- a/docs/wisdom/enum/swapchain_scaling_enum.h +++ b/docs/wisdom/enum/swapchain_scaling_enum.h @@ -40,7 +40,8 @@ * - `WisSwapchainScalingNone = 0`: No scaling. The swapchain size is equal to the window size. * - `WisSwapchainScalingStretch = 1`: Stretch scaling. The swapchain size is stretched to the window size. * - `WisSwapchainScalingAspect = 2`: Aspect scaling. The swapchain size is scaled to the window size with aspect ratio - * preserved. \endcond + * preserved. + * \endcond * * * @section WisSwapchainScaling_see_also See Also diff --git a/docs/wisdom/enum/texture_binding_flags_enum.h b/docs/wisdom/enum/texture_binding_flags_enum.h index 899eda74c..31819a8bf 100644 --- a/docs/wisdom/enum/texture_binding_flags_enum.h +++ b/docs/wisdom/enum/texture_binding_flags_enum.h @@ -39,7 +39,8 @@ * feature depth and stencil. The bound texture @wis_must be in TODO: specific layout before being used by shader. * - `WisTextureBindingFlagsStencilView = (1 << 1)`: Texture view is used to read stencil. Used for special formats that * feature depth and stencil. The bound texture @wis_must be in TODO: specific layout before being used by shader. - * Cannot be combined with `WisTextureBindingFlagsDepthView`. \endcond + * Cannot be combined with `WisTextureBindingFlagsDepthView`. + * \endcond * * * @section WisTextureBindingFlags_see_also See Also diff --git a/docs/wisdom/enum/texture_layout_enum.h b/docs/wisdom/enum/texture_layout_enum.h index fc7ff226b..58fb43e08 100644 --- a/docs/wisdom/enum/texture_layout_enum.h +++ b/docs/wisdom/enum/texture_layout_enum.h @@ -55,7 +55,8 @@ * - `WisTextureLayoutTexture3D = 8`: Texture is 3D volume. * - `WisTextureLayoutTextureCube = 9`: Texture is a cube map. Behaves similarly to Texture2DArray with 6 layers. * - `WisTextureLayoutTextureCubeArray = 10`: Texture is an array of cube maps. Behaves similarly to Texture2DArray with - * 6 layers per cube map. \endcond + * 6 layers per cube map. + * \endcond * * * @section WisTextureLayout_see_also See Also diff --git a/docs/wisdom/enum/texture_state_enum.h b/docs/wisdom/enum/texture_state_enum.h index 2ccfd8baf..8a3ed01c2 100644 --- a/docs/wisdom/enum/texture_state_enum.h +++ b/docs/wisdom/enum/texture_state_enum.h @@ -28,6 +28,7 @@ * WisTextureStateVideoDecodeWrite = 14, * WisTextureStateResolveDepthStensilDst = 15, * WisTextureStateResolveRenderTargetDst = 16, + * WisTextureStateVideoDecodeDPB = 17, * } WisTextureState; * ``` * C++ version: @@ -53,6 +54,7 @@ * VideoDecodeWrite = 14, * ResolveDepthStensilDst = 15, * ResolveRenderTargetDst = 16, + * VideoDecodeDPB = 17, * }; * } * ``` @@ -85,6 +87,8 @@ * - `WisTextureStateVideoDecodeWrite = 14`: Video Decode Write state. * - `WisTextureStateResolveDepthStensilDst = 15`: Depth Stencil Resolve Destination state. * - `WisTextureStateResolveRenderTargetDst = 16`: Render Target Resolve Destination state. + * - `WisTextureStateVideoDecodeDPB = 17`: Video Decode DPB (Decoded Picture Buffer) state. Used for reference frame + * storage during video decoding. Vulkan only, maps to the same video decode read on other APIs. * \endcond * * diff --git a/docs/wisdom/enum/texture_usage_flags_enum.h b/docs/wisdom/enum/texture_usage_flags_enum.h index 2399836b8..10ea52408 100644 --- a/docs/wisdom/enum/texture_usage_flags_enum.h +++ b/docs/wisdom/enum/texture_usage_flags_enum.h @@ -18,6 +18,9 @@ * WisTextureUsageFlagsShaderResource = (1u << 4), * WisTextureUsageFlagsUnorderedAccess = (1u << 5), * WisTextureUsageFlagsHostCopy = (1u << 7), + * WisTextureUsageFlagsVideoDecodeDst = (1u << 6), + * WisTextureUsageFlagsVideoDecodeSrc = (1u << 8), + * WisTextureUsageFlagsVideoDecodeDpb = (1u << 9), * } WisTextureUsageFlags; * ``` * C++ version: @@ -33,6 +36,9 @@ * ShaderResource = (1u << 4), * UnorderedAccess = (1u << 5), * HostCopy = (1u << 7), + * VideoDecodeDst = (1u << 6), + * VideoDecodeSrc = (1u << 8), + * VideoDecodeDpb = (1u << 9), * }; * } * ``` @@ -55,6 +61,9 @@ * - `WisTextureUsageFlagsShaderResource = (1 << 4)`: Texture is used as a shader resource. * - `WisTextureUsageFlagsUnorderedAccess = (1 << 5)`: Texture is used as an unordered access resource. * - `WisTextureUsageFlagsHostCopy = (1 << 7)`: Texture is used for host copy operations. Works with GPUUpload heap. + * - `WisTextureUsageFlagsVideoDecodeDst = (1 << 6)`: Texture is used as a destination for video decode operations. + * - `WisTextureUsageFlagsVideoDecodeSrc = (1 << 8)`: Texture is used as a source for video decode operations. + * - `WisTextureUsageFlagsVideoDecodeDpb = (1 << 9)`: Texture is used as a DPB storage for video decode. * \endcond * * diff --git a/docs/wisdom/enum/view_heap_flags_enum.h b/docs/wisdom/enum/view_heap_flags_enum.h index 354de29a4..fe7c24af7 100644 --- a/docs/wisdom/enum/view_heap_flags_enum.h +++ b/docs/wisdom/enum/view_heap_flags_enum.h @@ -12,6 +12,7 @@ * typedef enum WisViewHeapFlags { * WisViewHeapFlagsNone = 0, * WisViewHeapFlagsAllowMultisample = (1u << 0), + * WisViewHeapFlagsAllowVideoTargets = (1u << 0), * } WisViewHeapFlags; * ``` * C++ version: @@ -21,6 +22,7 @@ * enum class ViewHeapFlags : uint32_t { * None = 0, * AllowMultisample = (1u << 0), + * AllowVideoTargets = (1u << 0), * }; * } * ``` @@ -36,7 +38,10 @@ * Values: * - `WisViewHeapFlagsNone = 0`: No flags set. View heap is regular. * - `WisViewHeapFlagsAllowMultisample = (1 << 0)`: Allows the view heap to be used with multisampled resources. If not - * set, the view heap does not enable multisample-related usage. \endcond + * set, the view heap does not enable multisample-related usage. + * - `WisViewHeapFlagsAllowVideoTargets = (1 << 0)`: Allows the view heap to be used with video targets. If not set, the + * view heap does not enable video target-related usage. + * \endcond * * * @section WisViewHeapFlags_see_also See Also diff --git a/docs/wisdom/func/command_list_set_index_buffer2_function.h b/docs/wisdom/func/command_list_set_index_buffer2_function.h index 57ab8b3ef..dc75e0572 100644 --- a/docs/wisdom/func/command_list_set_index_buffer2_function.h +++ b/docs/wisdom/func/command_list_set_index_buffer2_function.h @@ -59,7 +59,8 @@ * - **this** `self` self is a pointer to the valid WisCommandList instance. * - `buffer` The index buffer to set. * - `index_type` Defines index type. Used to determine the size of each index in the buffer. Must be either - * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. \endcond + * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. + * \endcond * * @section wisCommandListSetIndexBuffer2_descr Description *
diff --git a/docs/wisdom/func/command_list_set_index_buffer_function.h b/docs/wisdom/func/command_list_set_index_buffer_function.h index d55a4ed19..05dc126ba 100644 --- a/docs/wisdom/func/command_list_set_index_buffer_function.h +++ b/docs/wisdom/func/command_list_set_index_buffer_function.h @@ -59,7 +59,8 @@ * - **this** `self` self is a pointer to the valid WisCommandList instance. * - `buffer` The index buffer to set. * - `index_type` Defines index type. Used to determine the size of each index in the buffer. Must be either - * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. \endcond + * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. + * \endcond * * @section wisCommandListSetIndexBuffer_descr Description *
diff --git a/docs/wisdom/func/view_heap_write_video_decode_target_function.h b/docs/wisdom/func/view_heap_write_video_decode_target_function.h new file mode 100644 index 000000000..e37f37320 --- /dev/null +++ b/docs/wisdom/func/view_heap_write_video_decode_target_function.h @@ -0,0 +1,83 @@ +/** + * @struct wisViewHeapWriteVideoDecodeTarget + * @ingroup Functions Core + * + * + * @section wisViewHeapWriteVideoDecodeTarget_spec Specification + *
+ * + * \cond WIS_GEN_CODE + * C Version: + * ```c + * // Provided by Wisdom 0.7.1. + * uint64_t wisViewHeapWriteVideoDecodeTarget(const WisViewHeap* self, + * const WisTexture* texture, + * const WisRenderTargetDesc* render_target, + * uint32_t index); + * ``` + *
+ * C Implementation Specific Version: + * ```c + * // Provided by Wisdom 0.7.1. + * uint64_t wisVKViewHeapWriteVideoDecodeTarget(const WisVKViewHeap* self, + * const WisVKTexture* texture, + * const WisRenderTargetDesc* render_target, + * uint32_t index); + * + * // Provided by Wisdom 0.7.1. + * uint64_t wisDX12ViewHeapWriteVideoDecodeTarget(const WisDX12ViewHeap* self, + * const WisDX12Texture* texture, + * const WisRenderTargetDesc* render_target, + * uint32_t index); + * ``` + *
+ * + * C++ Version: + * ```cpp + * namespace wis{ + * // Provided by Wisdom 0.7.1. + * WIS_NODISCARD std::uint64_t ViewHeap::WriteVideoDecodeTarget(const wis::Texture& texture, + * const wis::RenderTargetDesc& render_target, + * std::uint32_t index) const noexcept; + * } + * ``` + *
+ * C++ Implementation Specific Version: + * ```cpp + * namespace wis{ + * // Provided by Wisdom 0.7.1. + * WIS_NODISCARD std::uint64_t VKViewHeap::WriteVideoDecodeTarget(const wis::VKTexture& texture, + * const wis::RenderTargetDesc& render_target, + * std::uint32_t index) const noexcept; + * + * // Provided by Wisdom 0.7.1. + * WIS_NODISCARD std::uint64_t DX12ViewHeap::WriteVideoDecodeTarget(const wis::DX12Texture& texture, + * const wis::RenderTargetDesc& render_target, + * std::uint32_t index) const noexcept; + * } + * ``` + *
+ * \endcond + * + * @section wisViewHeapWriteVideoDecodeTarget_memb Parameters + *
+ * \cond WIS_GEN_DESC + * - **this** `self` self is a pointer to the valid WisViewHeap instance. + * - `texture` describes a pointer to WisTexture to write the view for. + * - `render_target` specifies a pointer to WisRenderTargetDesc, which describes the texture view to write. + * - `index` defines the index in the view heap to write the view to. + * + * - **return** CPU descriptor handle for the view heap. + * \endcond + * + * @section wisViewHeapWriteVideoDecodeTarget_descr Description + *
+ * + * \cond WIS_GEN_WIS_IDS + * \endcond + * + * @section wisViewHeapWriteVideoDecodeTarget_see_also See Also + *
+ * \cond WIS_GEN_REFS + * \endcond + */ diff --git a/docs/wisdom/getting_started.h b/docs/wisdom/getting_started.h index ccc31266d..f1620579e 100644 --- a/docs/wisdom/getting_started.h +++ b/docs/wisdom/getting_started.h @@ -126,6 +126,9 @@ * - `WISDOM_BUILD_TESTS=ON/OFF` build tests * - `WISDOM_BUILD_DOCS=ON/OFF` build Doxygen documentation * - `WISDOM_DXC_PATH=` custom DXC location + * - `WISDOM_USE_AGILITY_SDK=OFF` download and build with Agility SDK instead of Windows SDK, this allows using latest + * DirectX 12 features on older Windows versions, but requires additional setup and dependencies. Default is `OFF`, + * which uses Windows SDK that comes with the system and DirectX-Headers. * - `WISDOM_VULKAN_HEADER_PATH=` custom Vulkan-Headers location * * @section nuget NuGet Package diff --git a/docs/wisdom/handle/adapter_query_handle.h b/docs/wisdom/handle/adapter_query_handle.h index d914f9a21..1829feba8 100644 --- a/docs/wisdom/handle/adapter_query_handle.h +++ b/docs/wisdom/handle/adapter_query_handle.h @@ -28,5 +28,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyAdapterQuery, wisInstanceQueryAdapters, wisAdapterQueryGetAdapterCount, wisAdapterQueryGetAdapterDesc, - * wisAdapterQueryGetSurfaceSupport, wisAdapterQueryCreateDevice \endcond + * wisAdapterQueryGetSurfaceSupport, wisAdapterQueryCreateDevice + * \endcond */ diff --git a/docs/wisdom/handle/command_allocator_handle.h b/docs/wisdom/handle/command_allocator_handle.h index 3c89e47bf..fc0eb0475 100644 --- a/docs/wisdom/handle/command_allocator_handle.h +++ b/docs/wisdom/handle/command_allocator_handle.h @@ -24,5 +24,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyCommandAllocator, wisDeviceCreateCommandAllocator, wisCommandAllocatorReset, - * wisCommandAllocatorCreateCommandList \endcond + * wisCommandAllocatorCreateCommandList + * \endcond */ diff --git a/docs/wisdom/handle/command_list_handle.h b/docs/wisdom/handle/command_list_handle.h index 898d74576..7e0e59bfd 100644 --- a/docs/wisdom/handle/command_list_handle.h +++ b/docs/wisdom/handle/command_list_handle.h @@ -33,5 +33,6 @@ * wisCommandListDrawIndexed, wisCommandListBeginRenderPass, wisCommandListEndRenderPass, wisCommandListCopyBuffer, * wisCommandListCopyBufferToTexture, wisCommandListCopyTextureToBuffer, wisCommandListCopyTexture, * wisCommandListSetVertexBuffers, wisCommandListSetVertexBuffers2, wisCommandListSetIndexBuffer, - * wisCommandListSetIndexBuffer2, wisCommandListSetBlendFactors \endcond + * wisCommandListSetIndexBuffer2, wisCommandListSetBlendFactors + * \endcond */ diff --git a/docs/wisdom/handle/command_queue_handle.h b/docs/wisdom/handle/command_queue_handle.h index aef26a747..1c93793ef 100644 --- a/docs/wisdom/handle/command_queue_handle.h +++ b/docs/wisdom/handle/command_queue_handle.h @@ -24,5 +24,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyCommandQueue, wisDeviceCreateCommandQueue, wisDeviceCreateSwapchain, wisCommandQueueSubmit, - * wisCommandQueueSignalFence, wisCommandQueueWaitFence \endcond + * wisCommandQueueSignalFence, wisCommandQueueWaitFence + * \endcond */ diff --git a/docs/wisdom/handle/descriptor_heap_handle.h b/docs/wisdom/handle/descriptor_heap_handle.h index b1aa9edb1..9ae0e1a8c 100644 --- a/docs/wisdom/handle/descriptor_heap_handle.h +++ b/docs/wisdom/handle/descriptor_heap_handle.h @@ -27,5 +27,6 @@ * wisDescriptorHeapWriteConstantBuffer, wisDescriptorHeapWriteStructuredBuffer, * wisDescriptorHeapWriteRWStructuredBuffer, wisDescriptorHeapWriteSampler, wisDescriptorHeapWriteTexture, * wisDescriptorHeapWriteRWTexture, wisDescriptorHeapWriteAccelerationStructure, wisDescriptorHeapCopyDescriptors, - * wisCommandListSetDescriptorHeaps \endcond + * wisCommandListSetDescriptorHeaps + * \endcond */ diff --git a/docs/wisdom/handle/device_handle.h b/docs/wisdom/handle/device_handle.h index c5fd337b7..4e5f6ece9 100644 --- a/docs/wisdom/handle/device_handle.h +++ b/docs/wisdom/handle/device_handle.h @@ -28,5 +28,6 @@ * wisDeviceCreateViewHeap, wisDeviceQueryProperties, wisDeviceWaitForMultipleFences, wisDeviceCreatePipelineCache, * wisDeviceCreateShader, wisDeviceCreateComputePipeline, wisDeviceCreateGraphicsPipeline, * wisDeviceGetFormatPresentationSupport, wisDeviceGetSurfaceParameters, wisDeviceCreateSwapchain, - * wisDeviceGetFormatProperties \endcond + * wisDeviceGetFormatProperties + * \endcond */ diff --git a/docs/wisdom/handle/pipeline_handle.h b/docs/wisdom/handle/pipeline_handle.h index a56d29a73..d94883998 100644 --- a/docs/wisdom/handle/pipeline_handle.h +++ b/docs/wisdom/handle/pipeline_handle.h @@ -10,13 +10,13 @@ * Vulkan Version: * ```c * // Provided by Wisdom 0.7.0. - * WIS_DEFINE_HANDLE(WisVKPipeline,2); + * WIS_DEFINE_HANDLE(WisVKPipeline,3); * WIS_DEFINE_HANDLE_VIEW(WisVKPipeline,1); * ``` * DX12 Version: * ```c * // Provided by Wisdom 0.7.0. - * WIS_DEFINE_HANDLE(WisDX12Pipeline,1); + * WIS_DEFINE_HANDLE(WisDX12Pipeline,2); * WIS_DEFINE_HANDLE_VIEW(WisDX12Pipeline,1); * ``` * \endcond diff --git a/docs/wisdom/handle/resource_allocator_handle.h b/docs/wisdom/handle/resource_allocator_handle.h index 82519d944..3102dbfa5 100644 --- a/docs/wisdom/handle/resource_allocator_handle.h +++ b/docs/wisdom/handle/resource_allocator_handle.h @@ -24,5 +24,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyResourceAllocator, wisDeviceGetResourceAllocator, wisResourceAllocatorCreateBuffer, - * wisResourceAllocatorCreateTexture \endcond + * wisResourceAllocatorCreateTexture + * \endcond */ diff --git a/docs/wisdom/handle/swapchain_handle.h b/docs/wisdom/handle/swapchain_handle.h index 5ce4788aa..fcf57ec18 100644 --- a/docs/wisdom/handle/swapchain_handle.h +++ b/docs/wisdom/handle/swapchain_handle.h @@ -24,5 +24,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroySwapchain, wisDeviceCreateSwapchain, wisSwapchainPresent, wisSwapchainGetCurrentIndex, wisSwapchainUpdate, - * wisSwapchainGetTextures \endcond + * wisSwapchainGetTextures + * \endcond */ diff --git a/docs/wisdom/handle/texture_handle.h b/docs/wisdom/handle/texture_handle.h index 34e5e355e..e31fcb262 100644 --- a/docs/wisdom/handle/texture_handle.h +++ b/docs/wisdom/handle/texture_handle.h @@ -26,5 +26,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyTexture, wisResourceAllocatorCreateTexture, wisTextureWriteSubresource, wisViewHeapWriteRenderTarget, - * wisViewHeapWriteDepthStencil, wisSwapchainGetTextures \endcond + * wisViewHeapWriteDepthStencil, wisViewHeapWriteVideoDecodeTarget, wisSwapchainGetTextures + * \endcond */ diff --git a/docs/wisdom/handle/view_heap_handle.h b/docs/wisdom/handle/view_heap_handle.h index 21d92c9f8..d4f119cb5 100644 --- a/docs/wisdom/handle/view_heap_handle.h +++ b/docs/wisdom/handle/view_heap_handle.h @@ -24,5 +24,6 @@ * \cond WIS_GEN_REFS * @see Functions: * wisDestroyViewHeap, wisDeviceCreateViewHeap, wisViewHeapWriteRenderTarget, wisViewHeapWriteDepthStencil, - * wisViewHeapGetViewAddress, wisViewHeapCopyViews, wisViewHeapGetCPUHandle \endcond + * wisViewHeapWriteVideoDecodeTarget, wisViewHeapGetViewAddress, wisViewHeapCopyViews, wisViewHeapGetCPUHandle + * \endcond */ diff --git a/docs/wisdom/main_page.h b/docs/wisdom/main_page.h index bb57be33e..81202a4f1 100644 --- a/docs/wisdom/main_page.h +++ b/docs/wisdom/main_page.h @@ -48,6 +48,8 @@ * Some additional pages: * - @ref contributing_page "Contributing" - Contribution guidelines and how to get involved * - @ref why_page "Why Wisdom?" - Explanation of the motivation and goals behind the project + * - @ref agility_page "Agility SDK" - Information about using the Agility SDK for DirectX 12 features on older Windows + * versions * * @section features_sec Key Features * diff --git a/docs/wisdom/struct/buffer_barrier_struct.h b/docs/wisdom/struct/buffer_barrier_struct.h index 8549ef5e3..d7ef640f7 100644 --- a/docs/wisdom/struct/buffer_barrier_struct.h +++ b/docs/wisdom/struct/buffer_barrier_struct.h @@ -117,7 +117,8 @@ * - `queue_type_before` defines type of the queue the barrier is executed on before the synchronization point. Used for * cross-queue barriers. * - `queue_type_after` indicates type of the queue the barrier is executed on after the synchronization point. Used for - * cross-queue barriers. \endcond + * cross-queue barriers. + * \endcond * * @section WisBufferBarrier_descr Description *
diff --git a/docs/wisdom/struct/descriptor_table_data_desc_struct.h b/docs/wisdom/struct/descriptor_table_data_desc_struct.h index 7197587d7..6a0d979f8 100644 --- a/docs/wisdom/struct/descriptor_table_data_desc_struct.h +++ b/docs/wisdom/struct/descriptor_table_data_desc_struct.h @@ -39,7 +39,8 @@ * - `root_index` indicates the root index in the root signature to set the push descriptors for. * - `heap_type` indicates the type of the descriptor heap to bind. * - `heap_offset` defines the offset in descriptors from the start of the heap to set the descriptor table to. Used for - * calculating descriptor indices when binding descriptor tables. \endcond + * calculating descriptor indices when binding descriptor tables. + * \endcond * * @section WisDescriptorTableDataDesc_descr Description *
diff --git a/docs/wisdom/struct/descriptor_table_entry_struct.h b/docs/wisdom/struct/descriptor_table_entry_struct.h index 1cb45e6f5..eb02560be 100644 --- a/docs/wisdom/struct/descriptor_table_entry_struct.h +++ b/docs/wisdom/struct/descriptor_table_entry_struct.h @@ -43,7 +43,8 @@ * - `count` describes descriptor count for Array descriptors. UINT32_MAX means unbounded array. 0 means single * register, same as 1. * - `descriptor_offset` describes offset in descriptors from the heap start. Used for calculating descriptor indices - * when binding descriptor tables. \endcond + * when binding descriptor tables. + * \endcond * * @section WisDescriptorTableEntry_descr Description *
diff --git a/docs/wisdom/struct/device_binding_properties_struct.h b/docs/wisdom/struct/device_binding_properties_struct.h index b3b92e47c..a0a60d310 100644 --- a/docs/wisdom/struct/device_binding_properties_struct.h +++ b/docs/wisdom/struct/device_binding_properties_struct.h @@ -49,7 +49,8 @@ * - `multiple_viewports_supported` indicates if multiple viewports are supported. If true, the device supports up to 16 * viewports and scissor rectangles. If false, only one viewport and scissor rectangle is supported. * - `address_commands_supported` indicates if commands with buffer addresses are supported. If true, the device - * supports commands that take buffer addresses directly, such as wisCommandListSetVertexBuffers2. \endcond + * supports commands that take buffer addresses directly, such as wisCommandListSetVertexBuffers2. + * \endcond * * @section WisDeviceBindingProperties_descr Description *
diff --git a/docs/wisdom/struct/device_command_queue_properties_struct.h b/docs/wisdom/struct/device_command_queue_properties_struct.h index c24324544..99dbadc1a 100644 --- a/docs/wisdom/struct/device_command_queue_properties_struct.h +++ b/docs/wisdom/struct/device_command_queue_properties_struct.h @@ -46,7 +46,8 @@ * buffers is used on a different queue type. It is supported on Windows 10 22H2 and later with WDDM 3.0 or later. On * Vulkan it requires `VK_KHR_maintenance9` extension. * - `max_queue_priority` indicates an array of maximum supported priorities for each queue type. If a queue type is not - * supported, the value is `0`. Order of queue types is the same as in WisCommandQueueType enum. \endcond + * supported, the value is `0`. Order of queue types is the same as in WisCommandQueueType enum. + * \endcond * * @section WisDeviceCommandQueueProperties_descr Description *
diff --git a/docs/wisdom/struct/device_descriptor_heap_properties_struct.h b/docs/wisdom/struct/device_descriptor_heap_properties_struct.h index 8acfb6752..931d29ef0 100644 --- a/docs/wisdom/struct/device_descriptor_heap_properties_struct.h +++ b/docs/wisdom/struct/device_descriptor_heap_properties_struct.h @@ -67,7 +67,8 @@ * - `render_target_with_ms_increment_size` defines size of a single render target view descriptor in the descriptor * heap with multisample targets enabled. Used for calculating render target view descriptor offsets. * - `depth_stencil_with_ms_increment_size` defines size of a single depth stencil view descriptor in the descriptor - * heap with multisample targets enabled. Used for calculating depth stencil view descriptor offsets. \endcond + * heap with multisample targets enabled. Used for calculating depth stencil view descriptor offsets. + * \endcond * * @section WisDeviceDescriptorHeapProperties_descr Description *
diff --git a/docs/wisdom/struct/device_memory_properties_struct.h b/docs/wisdom/struct/device_memory_properties_struct.h index 1f4dbd491..2c3d2e831 100644 --- a/docs/wisdom/struct/device_memory_properties_struct.h +++ b/docs/wisdom/struct/device_memory_properties_struct.h @@ -2,6 +2,8 @@ * @struct WisDeviceMemoryProperties * @ingroup Structures Core * + * Structure describing memory properties of the device. + * Pass it to `wisDeviceQueryProperties` either directly or chained to another query structure for it to be filled. * * @section WisDeviceMemoryProperties_spec Specification *
@@ -15,7 +17,6 @@ * void* next_in_chain; * bool gpu_upload_supported; * bool host_image_copy_supported; - * uint32_t supported_initial_transitions; * } WisDeviceMemoryProperties; * * ``` @@ -28,7 +29,6 @@ * void* next_in_chain; * bool gpu_upload_supported; * bool host_image_copy_supported; - * std::uint32_t supported_initial_transitions; * }; * } * ``` @@ -47,13 +47,28 @@ * from CPU memory to optimal tiled image layout on GPU, without the need for an intermediate staging buffer. It is * supported on Windows 10 22H2 and later with WDDM 3.0 or later. On Vulkan it requires `VK_EXT_host_image_copy` * extension. - * - `supported_initial_transitions` defines bitfield of supported initial resource state transitions for buffers and - * textures. If a transition is supported, the corresponding bit is set to `1`, otherwise `0`. Bit positions are the - * same as in WisTextureState enum. `WisTextureStateUndefined` is always supported. \endcond + * \endcond * * @section WisDeviceMemoryProperties_descr Description *
* + * `gpu_upload_supported` means that the device has a memory type that is both HOST_VISIBLE and DEVICE_LOCAL. That + * allows writes to memory directly using CPU mapping. + * `host_image_copy_supported` means that the device supports copying data directly from CPU memory to optimal tiled + * image layout on GPU, without the need for an intermediate staging buffer. This can improve performance and reduce + * memory usage when uploading textures from CPU to GPU. + * + * DirectX 12 supports both of these feature simultaneusly. That means that on DirectX 12, if `gpu_upload_supported` is + * true, then `host_image_copy_supported` will also be true. On Vulkan, these features are independent and may be + * supported separately. On Vulkan, `host_image_copy_supported` requires the `VK_EXT_host_image_copy` extension, while + * `gpu_upload_supported` depends on the presence of a memory type that is both HOST_VISIBLE and DEVICE_LOCAL. + * + * If `gpu_upload_supported` is true, `WisMemoryTypeGPUUpload` memory type can be used for resource allocation. This + * memory type allows mapping the memory and writing to it from CPU, while being accessible from GPU. + * + * If `host_image_copy_supported` is true, `wisTextureWriteSubresource` function can be used to write texture data + * directly from CPU memory to optimal tiled image layout on GPU. + * * \cond WIS_GEN_WIS_IDS * \endcond * diff --git a/docs/wisdom/struct/device_requirements_struct.h b/docs/wisdom/struct/device_requirements_struct.h index 0a1d1ef01..3ca6b5372 100644 --- a/docs/wisdom/struct/device_requirements_struct.h +++ b/docs/wisdom/struct/device_requirements_struct.h @@ -76,7 +76,8 @@ * queue_descs array. * - `extensions` points to an array of extensions that are to be initialized with pointers to WisDeviceExtensionHeader. * - `extension_count` describes the number of the number of extensions in the wisAdapterQueryCreateDevice extensions - * array. \endcond + * array. + * \endcond * * @section WisDeviceRequirements_descr Description *
diff --git a/docs/wisdom/struct/format_properties_struct.h b/docs/wisdom/struct/format_properties_struct.h index 0c1a6f2ca..4a8733707 100644 --- a/docs/wisdom/struct/format_properties_struct.h +++ b/docs/wisdom/struct/format_properties_struct.h @@ -33,7 +33,8 @@ * \cond WIS_GEN_DESC * - `format_support_flags` specifies bitmask of supported features for the format. * - `max_sample_count` defines maximum supported sample count for the format. If the format does not support - * multisampling, the value is `S1`. \endcond + * multisampling, the value is `S1`. + * \endcond * * @section WisFormatProperties_descr Description *
diff --git a/docs/wisdom/struct/push_constant_data_desc_struct.h b/docs/wisdom/struct/push_constant_data_desc_struct.h index 0c935dbee..4e6a26cda 100644 --- a/docs/wisdom/struct/push_constant_data_desc_struct.h +++ b/docs/wisdom/struct/push_constant_data_desc_struct.h @@ -43,7 +43,8 @@ * - `data_size` defines the size of the data in bytes. It @wis_must be less than or equal to the maximum push constant * size defined by the device and 4-byte aligned. * - `push_offset` specifies the offset in bytes from the start of the push constant root parameter to set the data to. - * It @wis_must be less than the maximum push constant size defined by the device and 4-byte aligned. \endcond + * It @wis_must be less than the maximum push constant size defined by the device and 4-byte aligned. + * \endcond * * @section WisPushConstantDataDesc_descr Description *
diff --git a/docs/wisdom/struct/rasterizer_desc_struct.h b/docs/wisdom/struct/rasterizer_desc_struct.h index 54aa2485a..10a1abb71 100644 --- a/docs/wisdom/struct/rasterizer_desc_struct.h +++ b/docs/wisdom/struct/rasterizer_desc_struct.h @@ -58,7 +58,8 @@ * - `depth_clip_enable` specifies depth clip enable. Default is true. * - `line_rasterization` specifies line rasterization mode. Default is `WisLineRasterizationDefault`. * - `conservative_rasterization` indicates conservative rasterization mode. Default is - * `WisConservativeRasterizationOff`. \endcond + * `WisConservativeRasterizationOff`. + * \endcond * * @section WisRasterizerDesc_descr Description *
diff --git a/docs/wisdom/struct/render_attachments_desc_struct.h b/docs/wisdom/struct/render_attachments_desc_struct.h index 589576b9f..23ec76c20 100644 --- a/docs/wisdom/struct/render_attachments_desc_struct.h +++ b/docs/wisdom/struct/render_attachments_desc_struct.h @@ -39,7 +39,8 @@ * - `attachments_count` defines attachment formats count. Max is 8. * - `depth_attachment` describes depth attachment format. Describes the format of the depth buffer. * - `view_mask` specifies view mask for multiview rendering. Each bit represents a view that can be rendered to with - * the pipeline. Default is 0, meaning no multiview support. \endcond + * the pipeline. Default is 0, meaning no multiview support. + * \endcond * * @section WisRenderAttachmentsDesc_descr Description *
diff --git a/docs/wisdom/struct/render_pass_desc_struct.h b/docs/wisdom/struct/render_pass_desc_struct.h index 7e02bcf2b..2b12085d7 100644 --- a/docs/wisdom/struct/render_pass_desc_struct.h +++ b/docs/wisdom/struct/render_pass_desc_struct.h @@ -43,7 +43,8 @@ * - `view_mask` specifies view mask for multiview rendering. Each bit represents a view that can be rendered to with * the render pass. Default is 0, meaning no multiview support. * - `depth_stencil` specifies depth stencil description; if depth stencil is not used, the target field @wis_must be - * set to 0. \endcond + * set to 0. + * \endcond * * @section WisRenderPassDesc_descr Description *
diff --git a/docs/wisdom/struct/render_target_desc_struct.h b/docs/wisdom/struct/render_target_desc_struct.h index e46eb7492..5b4d40270 100644 --- a/docs/wisdom/struct/render_target_desc_struct.h +++ b/docs/wisdom/struct/render_target_desc_struct.h @@ -59,6 +59,6 @@ *
* \cond WIS_GEN_REFS * @see Functions: - * wisViewHeapWriteRenderTarget, wisViewHeapWriteDepthStencil + * wisViewHeapWriteRenderTarget, wisViewHeapWriteDepthStencil, wisViewHeapWriteVideoDecodeTarget * \endcond */ diff --git a/docs/wisdom/struct/root_signature_desc_struct.h b/docs/wisdom/struct/root_signature_desc_struct.h index 865002b06..462840076 100644 --- a/docs/wisdom/struct/root_signature_desc_struct.h +++ b/docs/wisdom/struct/root_signature_desc_struct.h @@ -44,7 +44,8 @@ * `WisRootSignatureDesc::push_descriptors` array. * - `descriptor_tables` points to an array of WisDescriptorTable. * - `descriptor_table_count` specifies the number of the number of descriptor tables in the - * `WisRootSignatureDesc::descriptor_tables` array. \endcond + * `WisRootSignatureDesc::descriptor_tables` array. + * \endcond * * @section WisRootSignatureDesc_descr Description *
diff --git a/docs/wisdom/struct/subresource_range_struct.h b/docs/wisdom/struct/subresource_range_struct.h index 71ab9a57d..43ce2dbe3 100644 --- a/docs/wisdom/struct/subresource_range_struct.h +++ b/docs/wisdom/struct/subresource_range_struct.h @@ -46,7 +46,8 @@ * of depth slices. * - `plane_slice` indicates base depth slice of the subresource. Used only for 2D textures (YUV). * - `plane_slice_count` indicates number of depth slices in the subresource. Used only for 2D textures (YUV). Max value - * is 3. \endcond + * is 3. + * \endcond * * @section WisSubresourceRange_descr Description *
diff --git a/docs/wisdom/struct/surface_parameters_struct.h b/docs/wisdom/struct/surface_parameters_struct.h index e8b0d425d..a7541441d 100644 --- a/docs/wisdom/struct/surface_parameters_struct.h +++ b/docs/wisdom/struct/surface_parameters_struct.h @@ -43,7 +43,8 @@ * different alpha mode. Used to determine the supported alpha modes for the swapchain. * - `texture_usage_flags_supported` specifies bitmask of supported texture usage flags for the swapchain images. * - `stereo_supported` indicates if stereo rendering is supported. If true, the surface can be used to create a - * swapchain with stereo support. \endcond + * swapchain with stereo support. + * \endcond * * @section WisSurfaceParameters_descr Description *
diff --git a/docs/wisdom/struct/swapchain_desc_struct.h b/docs/wisdom/struct/swapchain_desc_struct.h index e52e7067b..ca9141955 100644 --- a/docs/wisdom/struct/swapchain_desc_struct.h +++ b/docs/wisdom/struct/swapchain_desc_struct.h @@ -52,7 +52,8 @@ * - `scaling` describes swapchain scaling mode. * - `flags` describes swapchain flags. Describe additional options for the swapchain. * - `composite_alpha` defines composite alpha mode. Describe how the alpha channel of the swapchain images is treated - * during compositing. \endcond + * during compositing. + * \endcond * * @section WisSwapchainDesc_descr Description *
diff --git a/docs/wisdom/struct/swapchain_update_desc_struct.h b/docs/wisdom/struct/swapchain_update_desc_struct.h index cba0dd45d..c030504b2 100644 --- a/docs/wisdom/struct/swapchain_update_desc_struct.h +++ b/docs/wisdom/struct/swapchain_update_desc_struct.h @@ -42,7 +42,8 @@ * - `image_count` indicates number of images in the swapchain. * - `format` describes swapchain image format. * - `vsync` indicates controls vsync; when true, presentation is synchronized to the vertical blanking interval to - * reduce tearing, whereas false can improve frame rate but can introduce tearing. \endcond + * reduce tearing, whereas false can improve frame rate but can introduce tearing. + * \endcond * * @section WisSwapchainUpdateDesc_descr Description *
diff --git a/docs/wisdom/struct/texture_barrier_struct.h b/docs/wisdom/struct/texture_barrier_struct.h index 07ec81949..e25dadab0 100644 --- a/docs/wisdom/struct/texture_barrier_struct.h +++ b/docs/wisdom/struct/texture_barrier_struct.h @@ -131,7 +131,8 @@ * - `queue_type_before` defines type of the queue the barrier is executed on before the synchronization point. Used for * cross-queue barriers. * - `queue_type_after` indicates type of the queue the barrier is executed on after the synchronization point. Used for - * cross-queue barriers. \endcond + * cross-queue barriers. + * \endcond * * @section WisTextureBarrier_descr Description *
diff --git a/docs/wisdom/struct/texture_desc_struct.h b/docs/wisdom/struct/texture_desc_struct.h index debe86545..e992f3acd 100644 --- a/docs/wisdom/struct/texture_desc_struct.h +++ b/docs/wisdom/struct/texture_desc_struct.h @@ -22,6 +22,8 @@ * WisTextureFlags flags; * WisMemoryType memory_type; * WisMemoryFlags memory_flags; + * const WisDataFormat* cast_formats; + * size_t cast_format_count; * } WisTextureDesc; * * ``` @@ -30,17 +32,18 @@ * namespace wis{ * // Provided by Wisdom 0.7.0. * struct TextureDesc { - * std::uint32_t width; - * std::uint32_t height; - * std::uint16_t depth_or_array_size; - * std::uint16_t mip_levels; - * wis::DataFormat format; - * wis::SampleCount sample_count; - * wis::TextureLayout layout; - * wis::TextureUsageFlags usage_flags; - * wis::TextureFlags flags; - * wis::MemoryType memory_type; - * wis::MemoryFlags memory_flags; + * std::uint32_t width; + * std::uint32_t height; + * std::uint16_t depth_or_array_size; + * std::uint16_t mip_levels; + * wis::DataFormat format; + * wis::SampleCount sample_count; + * wis::TextureLayout layout; + * wis::TextureUsageFlags usage_flags; + * wis::TextureFlags flags; + * wis::MemoryType memory_type; + * wis::MemoryFlags memory_flags; + * wis::span cast_formats; * }; * } * ``` @@ -60,6 +63,9 @@ * - `flags` describes texture flags. Describe additional options for the texture. * - `memory_type` specifies where the texture will be allocated. * - `memory_flags` describes the flags of the memory to allocate for the texture. + * - `cast_formats` points to an array of formats that can be used to cast the texture to another format. Used for + * format casting in shaders. + * - `cast_format_count` defines the number of the number of cast formats in the `WisTextureDesc::cast_formats` array. * \endcond * * @section WisTextureDesc_descr Description diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d8314746c..1bac29159 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -29,6 +29,7 @@ endif() # compile shaders from folder shaders and put them in the binary output # directory +wis_load_dxc(DOWNLOAD_LATEST) add_custom_target(wis_test_compile_shaders) file(GLOB SHADERS ${CMAKE_CURRENT_SOURCE_DIR}/shaders/*) @@ -47,6 +48,13 @@ add_custom_target( include(cmake/deps.cmake) +# Copy assets folder +add_custom_target( + copy_assets + COMMAND ${CMAKE_COMMAND} -E echo "Copying assets to example binaries..." + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/assets + ${EXAMPLE_BIN_OUTPUT}/assets) + add_example_suite(backend) add_example_suite(compute_particles_c) add_example_suite(hello_triangle) diff --git a/examples/assets/avif_sample.avif b/examples/assets/avif_sample.avif new file mode 100644 index 000000000..2bae4c713 Binary files /dev/null and b/examples/assets/avif_sample.avif differ diff --git a/examples/assets/hevc_sample.heic b/examples/assets/hevc_sample.heic new file mode 100644 index 000000000..c1460f7c1 Binary files /dev/null and b/examples/assets/hevc_sample.heic differ diff --git a/examples/cmake/deps.cmake b/examples/cmake/deps.cmake index 4aca08d80..82715b0d4 100644 --- a/examples/cmake/deps.cmake +++ b/examples/cmake/deps.cmake @@ -7,9 +7,71 @@ CPMAddPackage( "SDL_WERROR OFF" ) -# glm -CPMAddPackage( - NAME glm - GITHUB_REPOSITORY g-truc/glm - GIT_TAG origin/master -) +if (WISDOM_BUILD_VIDEO) + # h265nal sets GCC-specific -W flags in debug mode unconditionally, + # which MSVC rejects (/Wextra -> D8021 invalid numeric argument). + # Use DOWNLOAD_ONLY to fetch the source, patch it, then add_subdirectory manually. + if(MSVC) + CPMAddPackage( + NAME h265nal + GITHUB_REPOSITORY chemag/h265nal + GIT_TAG master + DOWNLOAD_ONLY YES + OPTIONS + "BUILD_H265_TESTS OFF" + ) + + # Patch GCC debug flags -> MSVC-compatible equivalents + foreach(CMAKE_FILE + "${h265nal_SOURCE_DIR}/CMakeLists.txt" + "${h265nal_SOURCE_DIR}/src/CMakeLists.txt" + ) + file(READ "${CMAKE_FILE}" _content) + string(REPLACE + "-g -O0 -Wall -Wextra -Wunused-parameter -Wshadow -Wformat -Wextra-semi -Wsign-conversion -Werror" + "/Od /W3" + _content "${_content}" + ) + string(REPLACE + "option(H265NAL_SMALL_FOOTPRINT, \"xmall footprint build\")" + "option(H265NAL_SMALL_FOOTPRINT \"small footprint build\")" + _content "${_content}" + ) + file(WRITE "${CMAKE_FILE}" "${_content}") + endforeach() + + set(BUILD_H265_TESTS OFF) + add_subdirectory("${h265nal_SOURCE_DIR}" "${h265nal_BINARY_DIR}") + else() + CPMAddPackage( + NAME h265nal + GITHUB_REPOSITORY chemag/h265nal + GIT_TAG master + DOWNLOAD_ONLY YES + OPTIONS + "BUILD_H265_TESTS OFF" + ) + + # Patch debug flags (same as MSVC patch but for clang on Windows) + foreach(CMAKE_FILE + "${h265nal_SOURCE_DIR}/CMakeLists.txt" + "${h265nal_SOURCE_DIR}/src/CMakeLists.txt" + ) + file(READ "${CMAKE_FILE}" _content) + string(REPLACE + "-g -O0 -Wall -Wextra -Wunused-parameter -Wshadow -Wformat -Wextra-semi -Wsign-conversion -Werror" + "-g -O0 -Wall -Wextra -Wunused-parameter -Wshadow -Wformat -Wextra-semi -Wsign-conversion -Werror -Wno-deprecated-declarations" + _content "${_content}" + ) + string(REPLACE + "option(H265NAL_SMALL_FOOTPRINT, \"xmall footprint build\")" + "option(H265NAL_SMALL_FOOTPRINT \"small footprint build\")" + _content "${_content}" + ) + file(WRITE "${CMAKE_FILE}" "${_content}") + endforeach() + + set(BUILD_H265_TESTS OFF) + add_subdirectory("${h265nal_SOURCE_DIR}" "${h265nal_BINARY_DIR}") + endif() +endif() diff --git a/examples/compute_particles_c/CMakeLists.txt b/examples/compute_particles_c/CMakeLists.txt index e82ea80fa..892c30313 100644 --- a/examples/compute_particles_c/CMakeLists.txt +++ b/examples/compute_particles_c/CMakeLists.txt @@ -33,6 +33,6 @@ if(WISDOM_BUILD_SHARED) wis_test_compile_shaders) endif() -if(POSTFIX STREQUAL "dx12") - wis_install_deps(${PROJECT_NAME}) +if(POSTFIX STREQUAL "dx12" AND WISDOM_USE_AGILITY_SDK) + wis_install_agility_win32(TARGET ${PROJECT_NAME}) endif() diff --git a/examples/compute_particles_c/entry_main.c b/examples/compute_particles_c/entry_main.c index becbe2eca..e2f7e8cb3 100644 --- a/examples/compute_particles_c/entry_main.c +++ b/examples/compute_particles_c/entry_main.c @@ -4,6 +4,10 @@ #include +// Export the symbols for the Agility SDK. +// This is required when linking against the Agility SDK on Windows. +WISDOM_EXPORT_AGILITY_SYMBOLS(); + #define FRAMES_IN_FLIGHT 2 #define SWAPCHAIN_FRAMES 3 #define PARTICLE_COUNT 256 diff --git a/examples/hello_triangle/CMakeLists.txt b/examples/hello_triangle/CMakeLists.txt index 04521da8f..c7aec17c1 100644 --- a/examples/hello_triangle/CMakeLists.txt +++ b/examples/hello_triangle/CMakeLists.txt @@ -64,7 +64,9 @@ target_compile_definitions(${PROJECT_NAME}-cpp-headers PUBLIC ${ADD_DEFINITIONS}) add_dependencies(${PROJECT_NAME}-cpp-headers copy_sdl wis_test_compile_shaders) -if(POSTFIX STREQUAL "dx12" AND WISDOM_BUILD_STATIC) - wis_install_deps(${PROJECT_NAME}-c) - wis_install_deps(${PROJECT_NAME}-cpp) +if(POSTFIX STREQUAL "dx12" + AND WISDOM_BUILD_STATIC + AND WISDOM_USE_AGILITY_SDK) + wis_install_agility_win32(TARGET ${PROJECT_NAME}-cpp) + wis_install_agility_win32(TARGET ${PROJECT_NAME}-c) endif() diff --git a/examples/hello_triangle/entry_main.c b/examples/hello_triangle/entry_main.c index 0f6f88b3d..0bb39ee2b 100644 --- a/examples/hello_triangle/entry_main.c +++ b/examples/hello_triangle/entry_main.c @@ -10,6 +10,10 @@ #include +// Export the symbols for the Agility SDK. +// This is required when linking against the Agility SDK on Windows. +WISDOM_EXPORT_AGILITY_SYMBOLS(); + #define FRAMES_IN_FLIGHT 2 #define SWAPCHAIN_FRAMES 3 diff --git a/examples/hello_triangle/entry_main.cpp b/examples/hello_triangle/entry_main.cpp index 1aeb490a2..1f03d8e7f 100644 --- a/examples/hello_triangle/entry_main.cpp +++ b/examples/hello_triangle/entry_main.cpp @@ -13,6 +13,10 @@ #include +// Export the symbols for the Agility SDK. +// This is required when linking against the Agility SDK on Windows. +WISDOM_EXPORT_AGILITY_SYMBOLS(); + #define FRAMES_IN_FLIGHT 2 #define SWAPCHAIN_FRAMES 3 diff --git a/examples/multisampling/CMakeLists.txt b/examples/multisampling/CMakeLists.txt index 73476f808..3c18978ba 100644 --- a/examples/multisampling/CMakeLists.txt +++ b/examples/multisampling/CMakeLists.txt @@ -13,6 +13,6 @@ set_target_properties( target_compile_definitions(${PROJECT_NAME}-cpp PUBLIC ${ADD_DEFINITIONS}) add_dependencies(${PROJECT_NAME}-cpp copy_sdl wis_test_compile_shaders) -if(POSTFIX STREQUAL "dx12") - wis_install_deps(${PROJECT_NAME}-cpp) +if(POSTFIX STREQUAL "dx12" AND WISDOM_USE_AGILITY_SDK) + wis_install_agility_win32(TARGET ${PROJECT_NAME}-cpp PATCH_EXE) endif() diff --git a/examples/shaders/fullscreen.vs.hlsl b/examples/shaders/fullscreen.vs.hlsl new file mode 100644 index 000000000..ddb82e55d --- /dev/null +++ b/examples/shaders/fullscreen.vs.hlsl @@ -0,0 +1,12 @@ +struct VSQuadOut +{ + float2 texcoord : TexCoord; + float4 position : SV_Position; +}; +VSQuadOut main(uint VertexID : SV_VertexID) +{ // ouputs a full screen quad with tex coords + VSQuadOut Out; + Out.texcoord = float2((VertexID << 1) & 2, VertexID & 2); + Out.position = float4(Out.texcoord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f); + return Out; +} diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index fd20c6aa0..432cf2c4b 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.22) project(generator) include(format.cmake) @@ -48,3 +49,12 @@ endif() set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 20) target_precompile_headers(${PROJECT_NAME} PRIVATE "pch.hpp") + +# Also generate video extension API by running generator with "video" argument +add_custom_target( + generate-video-api + COMMAND ${PROJECT_NAME} video + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.. + COMMENT "Generating Video extension API" + DEPENDS ${PROJECT_NAME} + VERBATIM) diff --git a/generator/bitmask.cpp b/generator/bitmask.cpp index 28de84e6e..2692c5cac 100644 --- a/generator/bitmask.cpp +++ b/generator/bitmask.cpp @@ -49,7 +49,7 @@ void Generator::ParseBitmask(tinyxml2::XMLElement* type) if (auto* size = type->FindAttribute("version")) { ref.version = size->Value(); } else { - throw std::runtime_error(wis::format("Enum {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Enum {} is missing version attribute.", name)); } for (auto* impl_type = type->FirstChildElement("impl_type"); impl_type; @@ -104,11 +104,11 @@ void Generator::ParseBitmask(tinyxml2::XMLElement* type) std::string Generator::MakeCBitmask(const WisBitmask& s, DocKind kind) { auto full_name = GetCFullTypename(s.name, Backend::Any); - std::string st_decl = wis::format("typedef enum {} {{\n", full_name); + std::string st_decl = std::format("typedef enum {} {{\n", full_name); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } for (auto& m : s.values) { @@ -116,44 +116,44 @@ std::string Generator::MakeCBitmask(const WisBitmask& s, DocKind kind) st_decl += MakeValueDocumentation( s, m, - wis::format(" Wis{}{} = (1u << {}),", s.name, m.name, m.value_or_bit), + std::format(" Wis{}{} = (1u << {}),", s.name, m.name, m.value_or_bit), kind ); continue; } - st_decl += MakeValueDocumentation(s, m, wis::format(" Wis{}{} = {},", s.name, m.name, m.value_or_bit), kind); + st_decl += MakeValueDocumentation(s, m, std::format(" Wis{}{} = {},", s.name, m.name, m.value_or_bit), kind); } - st_decl += wis::format("}} {};\n", full_name); + st_decl += std::format("}} {};\n", full_name); return st_decl; } //---------------------------------------------------------------------------------------------------------------------- std::string Generator::MakeCPPBitmask(const WisBitmask& s, DocKind kind) { - std::string st_decl = wis::format("enum class {} : uint32_t {{\n", s.name); + std::string st_decl = std::format("enum class {} : uint32_t {{\n", s.name); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } for (auto& m : s.values) { if (m.is_bit) { st_decl += MakeValueDocumentation( s, m, - wis::format(" {} = (1u << {}),", m.name, m.value_or_bit), + std::format(" {} = (1u << {}),", m.name, m.value_or_bit), kind ); continue; } - st_decl += MakeValueDocumentation(s, m, wis::format(" {} = {},", m.name, m.value_or_bit), kind); + st_decl += MakeValueDocumentation(s, m, std::format(" {} = {},", m.name, m.value_or_bit), kind); } st_decl += "};\n"; if (kind == DocKind::VersionOnly) { return st_decl; } - st_decl += wis::format("WISDOM_DEFINE_ENUM_OPERATORS({})\n\n", s.name); + st_decl += std::format("WISDOM_DEFINE_ENUM_OPERATORS({})\n\n", s.name); return st_decl; } @@ -179,7 +179,7 @@ std::string Generator::MakeBitmaskDescription(const WisBitmask& s) if (has_translate) { translates += ", "; } - translates += wis::format("{} as {}", impl_names[i], cvt.value); + translates += std::format("{} as {}", impl_names[i], cvt.value); has_translate = true; } if (has_translate) { @@ -188,10 +188,10 @@ std::string Generator::MakeBitmaskDescription(const WisBitmask& s) description += "Values:\n"; for (auto& m : s.values) { if (m.is_bit) { - description += wis::format("- `Wis{}{} = (1 << {})`: {}\n", s.name, m.name, m.value_or_bit, m.doc); + description += std::format("- `Wis{}{} = (1 << {})`: {}\n", s.name, m.name, m.value_or_bit, m.doc); continue; } - description += wis::format("- `Wis{}{} = {}`: {}\n", s.name, m.name, m.value_or_bit, m.doc); + description += std::format("- `Wis{}{} = {}`: {}\n", s.name, m.name, m.value_or_bit, m.doc); } return description; } @@ -209,7 +209,7 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend auto wisdom_type = GetCFullTypename(s.name, Backend::Any); if (cvt.direct) { - converters = wis::format( + converters = std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n return static_cast<{}>(value);\n}}\n\n", cvt.value, backend_tag, @@ -217,7 +217,7 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend cvt.value ); } else { - converters = wis::format( + converters = std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n", cvt.value, backend_tag, @@ -225,14 +225,14 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend ); // Start with default value - converters += wis::format(" {} result = static_cast<{}>(0);\n", cvt.value, cvt.value); + converters += std::format(" {} result = static_cast<{}>(0);\n", cvt.value, cvt.value); if (auto nam = cvt.value.find("::"); nam != std::string::npos) { for (auto& m : s.values) { auto convert_value = m.converts[static_cast(backend)]; if (convert_value.empty()) { continue; } - converters += wis::format( + converters += std::format( " if (value & {}{}) {{ result = static_cast<{}>(result | {}); }}\n", GetCFullTypename(s.name, backend), m.name, @@ -246,7 +246,7 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend if (convert_value.empty()) { continue; } - converters += wis::format( + converters += std::format( " if (value & {}{}) {{ result |= {}; }}\n", GetCFullTypename(s.name, backend), m.name, @@ -255,12 +255,12 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend } } - converters += wis::format(" return result;\n}}\n\n"); + converters += std::format(" return result;\n}}\n\n"); } if (cvt.convert_back) { if (cvt.direct) { - converters += wis::format( + converters += std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n return static_cast<{}>(value);\n}}\n\n", wisdom_type, backend_tag, @@ -268,20 +268,20 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend wisdom_type ); } else { - converters += wis::format( + converters += std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n", wisdom_type, backend_tag, cvt.value ); - converters += wis::format(" {} result = static_cast<{}>(0);\n", wisdom_type, wisdom_type); + converters += std::format(" {} result = static_cast<{}>(0);\n", wisdom_type, wisdom_type); for (auto& m : s.values) { auto convert_value = m.converts[static_cast(backend)]; if (convert_value.empty()) { continue; } - converters += wis::format( + converters += std::format( " if (value & {}) {{ result = static_cast<{}>(result | {}{}); }}\n", convert_value, wisdom_type, @@ -290,7 +290,7 @@ std::string Generator::MakeBitmaskConverter(const WisBitmask& s, Backend backend ); } - converters += wis::format(" return result;\n}}\n\n"); + converters += std::format(" return result;\n}}\n\n"); } } @@ -304,16 +304,18 @@ void Generator::WriteBitmaskDocumentation(std::filesystem::path enum_output_path auto& bitmask_names = module_map.at(active_module_name).bitmasks_in_order; for (auto& enum_name : bitmask_names) { // Make a folder for enums starting with this letter - std::filesystem::path enum_file_path = enum_output_path / wis::format("{}_enum.h", MakeSnakeCase(enum_name)); + std::filesystem::path enum_file_path = enum_output_path / std::format("{}_enum.h", MakeSnakeCase(enum_name)); auto& enum_ref = bitmask_map[enum_name]; - std::string enum_template_content = wis::format( + files.push_back(enum_file_path); + + std::string enum_template_content = std::format( " * C version:\n```c\n{}```\n" "C++ version:\n```cpp\nnamespace wis{{\n{}}}\n```\n", MakeCBitmask(enum_ref, DocKind::VersionOnly), MakeCPPBitmask(enum_ref, DocKind::VersionOnly) ); - std::string enum_description = wis::format(" * {}", MakeBitmaskDescription(enum_ref)); + std::string enum_description = std::format(" * {}", MakeBitmaskDescription(enum_ref)); std::string enum_refs = GetRefs(enum_name); ReplaceAll(enum_template_content, "\n", "\n * "); ReplaceAll(enum_description, "\n", "\n * "); diff --git a/generator/constant.cpp b/generator/constant.cpp index 4ac171184..5272582ae 100644 --- a/generator/constant.cpp +++ b/generator/constant.cpp @@ -58,11 +58,11 @@ std::string Generator::MakeCConstant(const WisConstant& c, DocKind kind) } std::string define_name = "WIS_" + MakeUpperSnakeCase(c.name); - std::string st_decl = wis::format("#define {} (({}{}){})\n", define_name, type_str, mod_str, c.value); + std::string st_decl = std::format("#define {} (({}{}){})\n", define_name, type_str, mod_str, c.value); if (!c.doc.empty() && kind == DocKind::Full) { std::string version_info = MakeVersionString(c.version); - std::string documentation = wis::format("/// @brief {}{}\n", version_info, c.doc); + std::string documentation = std::format("/// @brief {}{}\n", version_info, c.doc); documentation = FinalizeCDocumentation(documentation, c.name); st_decl = documentation + st_decl; } @@ -81,11 +81,11 @@ std::string Generator::MakeCPPConstant(const WisConstant& c, DocKind kind) type_str = "const " + type_str; } - std::string st_decl = wis::format("static constexpr {}{} {} = {};\n", type_str, mod_str, c.name, c.value); + std::string st_decl = std::format("static constexpr {}{} {} = {};\n", type_str, mod_str, c.name, c.value); if (!c.doc.empty() && kind == DocKind::Full) { std::string version_info = MakeVersionString(c.version); - std::string documentation = wis::format("/// @brief {}{}\n", version_info, c.doc); + std::string documentation = std::format("/// @brief {}{}\n", version_info, c.doc); documentation = FinalizeCPPDocumentation(documentation, c.name); st_decl = documentation + st_decl; } @@ -101,8 +101,8 @@ std::string Generator::MakeConstantDescription(const WisConstant& c) } std::string type_str = GetCFullTypename(c.type, Backend::Any); - description += wis::format("Type: `{}`\n", type_str); - description += wis::format("Value: `{}`\n", c.value); + description += std::format("Type: `{}`\n", type_str); + description += std::format("Value: `{}`\n", c.value); return description; } @@ -135,6 +135,8 @@ void Generator::WriteConstantDocumentation(std::filesystem::path const_output_pa return; } + files.push_back(const_file_path); + for (auto& const_name : constant_names) { auto& const_ref = constant_map[const_name]; all_c_code += MakeCConstant(const_ref, DocKind::VersionOnly); @@ -146,7 +148,7 @@ void Generator::WriteConstantDocumentation(std::filesystem::path const_output_pa WriteDocumentation( const_file_path, template_constant, - wis::format("{}Constants", active_module_name), + std::format("{}Constants", active_module_name), const_template_content, empty_doc, empty_doc, diff --git a/generator/entry_main.cpp b/generator/entry_main.cpp index 210dbf8b8..5e0c425b5 100644 --- a/generator/entry_main.cpp +++ b/generator/entry_main.cpp @@ -1,5 +1,4 @@ #include -#include "../src/include/wisdom/bridge/format.hpp" #include "generator.hpp" constexpr inline std::string_view clang_format_exe = CLANG_FORMAT_EXECUTABLE; @@ -11,19 +10,25 @@ void FormatFiles(std::span files) if (clang_format_exe.empty()) { return; } - std::string cmd; - for (auto f : files) { - cmd += f.string(); - cmd += ' '; - } - std::cout << "Wisdom Vk Utils: Formatting:\n" << cmd << '\n'; - std::string command = wis::format("\"{}\" -i --style=file {}", clang_format_exe, cmd); - int ret = 0; - for (uint32_t i = 0; (ret = std::system(command.c_str())) != 0 && i < repeats; ++i) - ; - if (ret != 0) { - std::cout << "Wisdom Vk Utils: failed to format files with error <" << ret << ">\n"; + // break into chunks of 16 files to avoid command line length limits on some platforms + for (size_t i = 0; i < files.size(); i += 16) { + auto chunk_end = std::min(16ull, files.size() - i); + + std::string cmd; + for (auto f : files.subspan(i, chunk_end)) { + cmd += f.string(); + cmd += ' '; + } + std::cout << "Wisdom Vk Utils: Formatting:\n" << cmd << '\n'; + std::string command = std::format("\"{}\" -i --style=file {}", clang_format_exe, cmd); + + int ret = 0; + for (uint32_t i = 0; (ret = std::system(command.c_str())) != 0 && i < repeats; ++i) + ; + if (ret != 0) { + std::cout << "Wisdom Vk Utils: failed to format files with error <" << ret << ">\n"; + } } } diff --git a/generator/enum.cpp b/generator/enum.cpp index 4f5bd4191..a301b5cdd 100644 --- a/generator/enum.cpp +++ b/generator/enum.cpp @@ -49,7 +49,7 @@ void Generator::ParseEnum(tinyxml2::XMLElement* type) if (auto* size = type->FindAttribute("version")) { ref.version = size->Value(); } else { - throw std::runtime_error(wis::format("Enum {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Enum {} is missing version attribute.", name)); } for (auto* impl_type = type->FirstChildElement("impl_type"); impl_type; @@ -76,7 +76,7 @@ void Generator::ParseEnum(tinyxml2::XMLElement* type) auto& m = ref.values.emplace_back(); m.name = member->FindAttribute("name")->Value(); - m.value = std::stoll(member->FindAttribute("value")->Value()); + m.value = member->FindAttribute("value")->Value(); if (auto* doc = member->FindAttribute("doc")) { m.doc = doc->Value(); } @@ -99,33 +99,33 @@ void Generator::ParseEnum(tinyxml2::XMLElement* type) std::string Generator::MakeCEnum(const WisEnum& s, DocKind kind) { auto full_name = GetCFullTypename(s.name, Backend::Any); - std::string st_decl = wis::format("typedef enum {} {{\n", full_name); + std::string st_decl = std::format("typedef enum {} {{\n", full_name); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } for (auto& m : s.values) { - st_decl += MakeValueDocumentation(s, m, wis::format(" Wis{}{} = {},", s.name, m.name, m.value), kind); + st_decl += MakeValueDocumentation(s, m, std::format(" Wis{}{} = {},", s.name, m.name, m.value), kind); } - st_decl += wis::format("}} {};\n", full_name); + st_decl += std::format("}} {};\n", full_name); return st_decl; } //---------------------------------------------------------------------------------------------------------------------- std::string Generator::MakeCPPEnum(const WisEnum& s, DocKind kind) { - std::string st_decl = wis::format("enum class {} {{\n", s.name); + std::string st_decl = std::format("enum class {} {{\n", s.name); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } for (auto& m : s.values) { - st_decl += MakeValueDocumentation(s, m, wis::format(" {} = {},", m.name, m.value), kind); + st_decl += MakeValueDocumentation(s, m, std::format(" {} = {},", m.name, m.value), kind); } st_decl += "};\n"; @@ -139,16 +139,18 @@ void Generator::WriteEnumDocumentation(std::filesystem::path enum_output_path) auto& enum_names = module_map.at(active_module_name).enums_in_order; for (auto& enum_name : enum_names) { // Make a folder for enums starting with this letter - std::filesystem::path enum_file_path = enum_output_path / wis::format("{}_enum.h", MakeSnakeCase(enum_name)); + std::filesystem::path enum_file_path = enum_output_path / std::format("{}_enum.h", MakeSnakeCase(enum_name)); auto& enum_ref = enum_map[enum_name]; - std::string enum_template_content = wis::format( + files.push_back(enum_file_path); + + std::string enum_template_content = std::format( " * C version:\n```c\n{}```\n" "C++ version:\n```cpp\nnamespace wis{{\n{}}}\n```\n", MakeCEnum(enum_ref, DocKind::VersionOnly), MakeCPPEnum(enum_ref, DocKind::VersionOnly) ); - std::string enum_description = wis::format(" * {}", MakeEnumDescription(enum_ref)); + std::string enum_description = std::format(" * {}", MakeEnumDescription(enum_ref)); std::string enum_refs = GetRefs(enum_name); ReplaceAll(enum_template_content, "\n", "\n * "); ReplaceAll(enum_description, "\n", "\n * "); @@ -189,7 +191,7 @@ std::string Generator::MakeEnumDescription(const WisEnum& s) continue; } - translates += wis::format( + translates += std::format( "{} `{}` for {} implementation", has_translate ? ", and" : "", cvt.value, @@ -203,7 +205,7 @@ std::string Generator::MakeEnumDescription(const WisEnum& s) description += "Values:\n"; for (auto& m : s.values) { - description += wis::format("- `Wis{}{} = {}`: {}\n", s.name, m.name, m.value, m.doc); + description += std::format("- `Wis{}{} = {}`: {}\n", s.name, m.name, m.value, m.doc); } return description; } @@ -220,7 +222,7 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) auto wisdom_type = GetCFullTypename(s.name, Backend::Any); if (cvt.direct) { - converters = wis::format( + converters = std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n return static_cast<{}>(value);\n}}\n\n", cvt.value, backend_tag, @@ -228,7 +230,7 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) cvt.value ); } else { - converters = wis::format( + converters = std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n switch(value) {{\n", cvt.value, backend_tag, @@ -239,23 +241,23 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) if (convert_value.empty()) { continue; } - converters += wis::format( + converters += std::format( " case {}: return {};\n", - wis::format("{}{}", GetCFullTypename(s.name, backend), m.name), + std::format("{}{}", GetCFullTypename(s.name, backend), m.name), convert_value ); } if (!cvt.default_value.empty()) { - converters += wis::format(" default: return {};\n }}\n}}\n\n", cvt.default_value); + converters += std::format(" default: return {};\n }}\n}}\n\n", cvt.default_value); } else { - converters += wis::format(" default: return static_cast<{}>(0);\n }}\n}}\n\n", cvt.value); + converters += std::format(" default: return static_cast<{}>(0);\n }}\n}}\n\n", cvt.value); } } if (cvt.convert_back) { if (cvt.direct) { - converters += wis::format( + converters += std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n return static_cast<{}>(value);\n}}\n\n", wisdom_type, backend_tag, @@ -263,7 +265,7 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) wisdom_type ); } else { - converters += wis::format( + converters += std::format( "constexpr inline {} {}Convert({} value) noexcept {{\n", wisdom_type, backend_tag, @@ -275,7 +277,7 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) if (convert_value.empty()) { continue; } - converters += wis::format( + converters += std::format( " if (value == {}) {{ return {}{}; }}\n", convert_value, wisdom_type, @@ -283,7 +285,7 @@ std::string Generator::MakeEnumConverter(const WisEnum& s, Backend backend) ); } - converters += wis::format(" return static_cast<{}>(0);\n}}\n\n", wisdom_type); + converters += std::format(" return static_cast<{}>(0);\n}}\n\n", wisdom_type); } } diff --git a/generator/function.cpp b/generator/function.cpp index 0c15a172b..3ecc1284c 100644 --- a/generator/function.cpp +++ b/generator/function.cpp @@ -50,7 +50,7 @@ void Generator::ParseFunctions(tinyxml2::XMLElement* type) if (auto* version = func->FindAttribute("version")) { ref.version = version->Value(); } else { - throw std::runtime_error(wis::format("Function {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Function {} is missing version attribute.", name)); } if (this_type) { @@ -110,7 +110,7 @@ void Generator::ParseFunctions(tinyxml2::XMLElement* type) if (auto* name_attr = param->FindAttribute("name")) { p.name = name_attr->Value(); } else { - throw std::runtime_error(wis::format("Function {} has a parameter with no name.", name)); + throw std::runtime_error(std::format("Function {} has a parameter with no name.", name)); } if (auto* def = param->FindAttribute("default")) { p.default_value = def->Value(); @@ -139,7 +139,7 @@ void Generator::ParseDelegate(tinyxml2::XMLElement* func) if (auto* version = func->FindAttribute("version")) { ref.version = version->Value(); } else { - throw std::runtime_error(wis::format("Delegate {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Delegate {} is missing version attribute.", name)); } if (auto* doc = func->FindAttribute("doc")) { @@ -159,7 +159,7 @@ void Generator::ParseDelegate(tinyxml2::XMLElement* func) if (auto* name_attr = param->FindAttribute("name")) { p.name = name_attr->Value(); } else { - throw std::runtime_error(wis::format("Function {} has a parameter with no name.", name)); + throw std::runtime_error(std::format("Function {} has a parameter with no name.", name)); } if (auto* def = param->FindAttribute("default")) { p.default_value = def->Value(); @@ -186,7 +186,7 @@ std::string Generator::MakeCFunctionProto( std::string full_return_type; std::string post_return; - std::string function_full_name = wis::format("wis{}{}{}", re_impl, func.IsCD() ? "" : func.this_type, func.name); + std::string function_full_name = std::format("wis{}{}{}", re_impl, func.IsCD() ? "" : func.this_type, func.name); size_t post_return_length = 0; if (func.return_type.IsVoid()) { @@ -196,7 +196,7 @@ std::string Generator::MakeCFunctionProto( } else if (func.return_type.has_result) { full_return_type = GetCFullTypename("Result", Backend::Any); std::string arg_name = func.return_type.opt_name.empty() - ? wis::format("out_{}", MakeSnakeCase(func.return_type.type)) + ? std::format("out_{}", MakeSnakeCase(func.return_type.type)) : std::string(func.return_type.opt_name); std::string prefix = ""; @@ -207,7 +207,7 @@ std::string Generator::MakeCFunctionProto( } std::string type_str = GetMemberTypeString(func.return_type, backend); - post_return = wis::format("{}{}*{{}}{}", prefix, type_str, arg_name); + post_return = std::format("{}{}*{{}}{}", prefix, type_str, arg_name); post_return_length = type_str.size(); } else { full_return_type = GetMemberTypeString(func.return_type, backend); @@ -223,7 +223,7 @@ std::string Generator::MakeCFunctionProto( this_param.modifier = Modifier(Modifier::Pointer | func.modifier & Modifier::Const); auto full_this_type = GetMemberTypeString(this_param, backend); - this_arg = wis::format("{} {}", full_this_type, this_param.name); + this_arg = std::format("{} {}", full_this_type, this_param.name); if (func.parameters.size() > 0) { this_arg += ",\n"; } @@ -254,14 +254,14 @@ std::string Generator::MakeCFunctionProto( size_t pad_length = max_arg_length > type_str.length() ? max_arg_length - type_str.length() : 0; padding = std::string(pad_length, ' '); - params += wis::format("{}{}{} {}", prefix_spaces, type_str, padding, p.name); + params += std::format("{}{}{} {}", prefix_spaces, type_str, padding, p.name); if (i < func.parameters.size() - 1) { params += ",\n"; } max_arg_length = std::max(max_arg_length, type_str.length()); } - return wis::format( + return std::format( "{}{} {}({}{}{});\n", pre_decl, full_return_type, @@ -290,7 +290,7 @@ std::string Generator::MakeCPPFunctionProto( auto func_prefix = type != ProtoType::Prefixed ? "" : re_impl; std::string xclass_code; if (!func.this_type.empty() && kind != DocKind::Full) { - xclass_code = wis::format("{}::", func.this_type); + xclass_code = std::format("{}::", func.this_type); } std::string full_return_type; @@ -327,7 +327,7 @@ std::string Generator::MakeCPPFunctionProto( } std::string type_str = "wis::Result&"; std::string arg_name = "out_result"; - post_return = wis::format("{}{} {{}}{}", prefix, type_str, arg_name); + post_return = std::format("{}{} {{}}{}", prefix, type_str, arg_name); post_return_length = type_str.size(); } break; @@ -377,7 +377,7 @@ std::string Generator::MakeCPPFunctionProto( size_t pad_length = max_arg_length > type_str.length() ? max_arg_length - type_str.length() : 0; padding = std::string(pad_length, ' '); - params += wis::format("{}{}{} {}", prefix_spaces, type_str, padding, p.name); + params += std::format("{}{}{} {}", prefix_spaces, type_str, padding, p.name); // edge case for spans - if last argument was a span, skip the next one (the size) // That means we need to check if i(func, kind); - func_decl = wis::format("{}\n{}", xdoc, func_decl); + func_decl = std::format("{}\n{}", xdoc, func_decl); } if (kind != DocKind::Full) { return func_decl; } auto re_impl = GetBackendSuffix(backend); - auto c_name = wis::format("wis{}{}{}", re_impl, func.IsCD() ? "" : func.this_type, func.name); + auto c_name = std::format("wis{}{}{}", re_impl, func.IsCD() ? "" : func.this_type, func.name); // Convert args and call C function std::string body = "{\n"; constexpr static std::string_view arg_prefix = ",\n "; - auto set_params = [&]() { - for (size_t i = 0; i < func.parameters.size(); ++i) { - auto& p = func.parameters[i]; - - if (p.modifier & Modifier::Span) { - body += wis::format( - "reinterpret_cast<{}>({}.data()), {}.size()", - GetMemberTypeString(p, backend), - p.name, - p.name - ); - i++; // skip next parameter (the size) - if (i < func.parameters.size() - 1) { - body += arg_prefix; - } - continue; - } - - switch (GetType(p.type)) { - case TypeKind::Enum: - case TypeKind::Bitmask: - body += wis::format("static_cast<{}>({})", GetMemberTypeString(p, backend), p.name); - break; - case TypeKind::None: - case TypeKind::View: - case TypeKind::Base: - body += p.name; - break; - default: - if (p.modifier & Modifier::Reference) { - body += wis::format("reinterpret_cast<{}>(&{})", GetMemberTypeString(p, backend), p.name); - break; - } - body += wis::format("reinterpret_cast<{}>({})", GetMemberTypeString(p, backend), p.name); - break; - } - - if (i < func.parameters.size() - 1) { - body += arg_prefix; - } - } - }; - switch (func.return_type.GetKind()) { case ReturnTypeKind::ResultAndValue: { auto ret_value_name = func.return_type.opt_name.empty() - ? wis::format("out_{}", MakeSnakeCase(func.return_type.type)) + ? std::format("out_{}", MakeSnakeCase(func.return_type.type)) : std::string(func.return_type.opt_name); // Prepare out parameter - body += wis::format(" {} {};\n", GetMemberTypeString(func.return_type, backend), ret_value_name); + body += std::format( + " {} {}{{}};\n", + GetMemberTypeString(func.return_type, backend), + ret_value_name + ); - body += wis::format( + body += std::format( " const WisResult wis_result = ::{}({}", c_name, func.this_type.empty() ? "" : "&_impl_storage" @@ -530,14 +502,14 @@ std::string Generator::MakeCPPFunctionImpl( body += arg_prefix; } - set_params(); + body += GetFunctionCallParameters(func, backend); auto ret_type = GetType(func.return_type.type); if (ret_type == TypeKind::Handle) { - body += wis::format(", {}.GetStorage());\n", ret_value_name); + body += std::format(", {}.GetStorage());\n", ret_value_name); } else { - body += wis::format( + body += std::format( ", reinterpret_cast<{}*>(&{}));\n", GetMemberTypeString(func.return_type, backend), ret_value_name @@ -545,10 +517,10 @@ std::string Generator::MakeCPPFunctionImpl( } body += " out_result = wis::Result{ static_cast(wis_result.status), wis_result.platform_code, " "wis_result.error };\n"; - body += wis::format(" return {};\n", ret_value_name); + body += std::format(" return {};\n", ret_value_name); } break; case ReturnTypeKind::ResultOnly: { - body += wis::format( + body += std::format( " const WisResult wis_result = ::{}({}", c_name, func.this_type.empty() ? "" : "&_impl_storage" @@ -557,7 +529,7 @@ std::string Generator::MakeCPPFunctionImpl( if (func.parameters.size() > 0 && !func.this_type.empty()) { body += arg_prefix; } - set_params(); + body += GetFunctionCallParameters(func, backend); body += ");\n"; body += " return wis::Result{ static_cast(wis_result.status), wis_result.platform_code, " "wis_result.error };\n"; @@ -570,22 +542,22 @@ std::string Generator::MakeCPPFunctionImpl( break; case TypeKind::Enum: case TypeKind::Bitmask: - return_cast = wis::format("static_cast<{}>", GetMemberTypeString(func.return_type, backend)); + return_cast = std::format("static_cast<{}>", GetMemberTypeString(func.return_type, backend)); break; case TypeKind::Handle: throw std::runtime_error( - wis::format("Function {} return type cannot be a handle in direct return.", func.name) + std::format("Function {} return type cannot be a handle in direct return.", func.name) ); break; default: - return_cast = wis::format( + return_cast = std::format( "reinterpret_cast<{}>", GetMemberTypeString(func.return_type, backend) ); break; } - body += wis::format( + body += std::format( " return {}(::{}({}", return_cast, c_name, @@ -595,16 +567,16 @@ std::string Generator::MakeCPPFunctionImpl( if (func.parameters.size() > 0 && !func.this_type.empty()) { body += arg_prefix; } - set_params(); + body += GetFunctionCallParameters(func, backend); body += "));\n"; } break; case ReturnTypeKind::Void: { - body += wis::format(" ::{}({}", c_name, func.this_type.empty() ? "" : "&_impl_storage"); + body += std::format(" ::{}({}", c_name, func.this_type.empty() ? "" : "&_impl_storage"); constexpr static std::string_view arg_prefix = ",\n "; if (func.parameters.size() > 0 && !func.this_type.empty()) { body += arg_prefix; } - set_params(); + body += GetFunctionCallParameters(func, backend); body += ");\n"; } break; default: @@ -627,15 +599,15 @@ std::string Generator::MakeCPPDelegate(const WisFunction& func, DocKind kind) for (size_t i = 0; i < func.parameters.size(); ++i) { const auto& p = func.parameters[i]; std::string type_str = GetMemberTypeString(p, Backend::Any); - params += wis::format("{} {}", type_str, p.name); + params += std::format("{} {}", type_str, p.name); if (i < func.parameters.size() - 1) { params += ", "; } } - std::string delegate_decl = wis::format("using {} = void (*)({});\n", func.name, params); + std::string delegate_decl = std::format("using {} = void (*)({});\n", func.name, params); if (!func.doc.empty()) { std::string xdoc = MakeTypeDocumentation(func, kind); - delegate_decl = wis::format("{}\n{}", xdoc, delegate_decl); + delegate_decl = std::format("{}\n{}", xdoc, delegate_decl); } return delegate_decl; } @@ -646,16 +618,16 @@ std::string Generator::MakeFunctionDescription(const WisFunction& s) std::string description = " * "; if (!s.this_type.empty()) { if (s.modifier & Modifier::Construct) { - description += wis::format( + description += std::format( "- **this** `self` is a pointer to uninitialized {{{}::}} instance memory. It will be initialized by " "this function.\n", s.this_type ); // There must also be a note about the destroy function in the description - description += wis::format("**note** The corresponding destroy function is `wisDestroy{}`.\n", s.this_type); + description += std::format("**note** The corresponding destroy function is `wisDestroy{}`.\n", s.this_type); } else { - description += wis::format( + description += std::format( "- **this** `self` self is a pointer to the valid {{{}::}} instance.\n", s.this_type ); @@ -663,28 +635,28 @@ std::string Generator::MakeFunctionDescription(const WisFunction& s) } for (auto& p : s.parameters) { - description += wis::format("- `{}` {}\n", p.name, p.doc.empty() ? "No description." : p.doc); + description += std::format("- `{}` {}\n", p.name, p.doc.empty() ? "No description." : p.doc); } switch (s.return_type.GetKind()) { case ReturnTypeKind::Direct: - description += wis::format( + description += std::format( "\n- **return** {}\n", s.return_type.doc.empty() ? "No description." : s.return_type.doc ); break; case ReturnTypeKind::ResultOnly: - description += wis::format("\n- **return** denoting the outcome of operation.\n"); + description += std::format("\n- **return** denoting the outcome of operation.\n"); break; case ReturnTypeKind::ResultAndValue: { - std::string arg_name = s.return_type.opt_name.empty() ? wis::format("out_{}", MakeSnakeCase(s.return_type.type)) + std::string arg_name = s.return_type.opt_name.empty() ? std::format("out_{}", MakeSnakeCase(s.return_type.type)) : std::string(s.return_type.opt_name); - description += wis::format( + description += std::format( "- `{}` {}\n", s.return_type.opt_name.empty() ? "value" : s.return_type.opt_name, s.return_type.doc.empty() ? "No description." : s.return_type.doc ); - description += wis::format("\n- **return** denoting the outcome of operation.\n"); + description += std::format("\n- **return** denoting the outcome of operation.\n"); break; } default: @@ -699,7 +671,7 @@ std::string Generator::MakeDelegateDescription(const WisFunction& s) { std::string description = " * "; for (auto& p : s.parameters) { - description += wis::format("- `{}` {}\n", p.name, p.doc.empty() ? "No description." : p.doc); + description += std::format("- `{}` {}\n", p.name, p.doc.empty() ? "No description." : p.doc); } return description; } @@ -711,12 +683,14 @@ void Generator::WriteFunctionDocumentation(std::filesystem::path func_output_pat auto& function_names = module_map.at(active_module_name).functions_in_order; for (auto& func_name : function_names) { auto& func_def = function_map[func_name]; - std::string full_func_name = wis::format( + std::string full_func_name = std::format( "wis{}{}", func_def.modifier & (Destroy | Construct) ? "" : func_def.this_type, func_def.name ); - auto func_doc_path = func_output_path / wis::format("{}_function.h", MakeSnakeCase(full_func_name.substr(3))); + auto func_doc_path = func_output_path / std::format("{}_function.h", MakeSnakeCase(full_func_name.substr(3))); + + files.push_back(func_doc_path); auto supports_vk = has(func_def.backend, Backend::Vulkan); auto supports_dx = has(func_def.backend, Backend::DX12); @@ -775,8 +749,9 @@ void Generator::WriteDelegateDocumentation(std::filesystem::path func_output_pat for (auto& delegate_name : module_map.at(active_module_name).delegates_in_order) { auto full_delegate_name = GetCFullTypename(delegate_name, Backend::Any); auto delegate_doc_path = func_output_path - / wis::format("{}_delegate.h", MakeSnakeCase(full_delegate_name.substr(3))); + / std::format("{}_delegate.h", MakeSnakeCase(full_delegate_name.substr(3))); auto& delegate_def = delegate_map[delegate_name]; + files.push_back(delegate_doc_path); std::string regular_code = MakeCDelegate(delegate_def, DocKind::VersionOnly); std::string regular_code_cpp = MakeCPPDelegate(delegate_def, DocKind::VersionOnly); diff --git a/generator/generator.cpp b/generator/generator.cpp index 0d6bac37b..1f454c7f3 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -186,7 +186,7 @@ void Generator::WriteCAPI(std::filesystem::path dir) bool has_independent_api = !module.enums_in_order.empty() || !module.bitmasks_in_order.empty() || !module.structs_in_order.empty() || !module.constants_in_order.empty() - || !module.delegates_in_order.empty(); + || !module.delegates_in_order.empty() || !module.functions_in_order.empty(); auto path = dir / "c_api.h"; if (!has_independent_api) { @@ -211,11 +211,12 @@ void Generator::WriteCAPI(std::filesystem::path dir) #include "wisdom_exports.h" )"; - auto api_macro = module.name == "Core" ? "WISDOM_API " : wis::format("WISDOM_{}_API ", header_guard); + auto api_macro = module.name == "Core" ? "WIS_INLINE WISDOM_API " + : std::format("WIS_INLINE WISDOM_{}_API ", header_guard); // Write header // clang-format off - file << wis::format(R"(// This file is generated. Do not edit directly. + file << std::format(R"(// This file is generated. Do not edit directly. #ifndef WISDOM_{0}_C_API_H #define WISDOM_{0}_C_API_H {1} @@ -354,7 +355,7 @@ extern "C" {{ // Write footer // clang-format off - file << wis::format(R"( + file << std::format(R"( #ifdef __cplusplus }} #endif // __cplusplus @@ -368,7 +369,7 @@ void Generator::WriteCPPAPI(std::filesystem::path dir) auto& module = module_map.at(active_module_name); bool has_independent_api = !module.enums_in_order.empty() || !module.bitmasks_in_order.empty() || !module.structs_in_order.empty() || !module.constants_in_order.empty() - || !module.delegates_in_order.empty(); + || !module.delegates_in_order.empty() || !module.functions_in_order.empty(); auto path = dir / "cpp_api.hpp"; if (!has_independent_api) { @@ -396,7 +397,7 @@ void Generator::WriteCPPAPI(std::filesystem::path dir) // Write header // clang-format off - file << wis::format(R"(// This file is generated. Do not edit directly. + file << std::format(R"(// This file is generated. Do not edit directly. #ifndef WISDOM_{0}_CPP_API_HPP #define WISDOM_{0}_CPP_API_HPP #ifndef __cplusplus @@ -465,7 +466,7 @@ namespace wis {{ } } - file << wis::format( + file << std::format( R"( }} // namespace wis @@ -515,7 +516,7 @@ namespace wis {{ } } - file << wis::format( + file << std::format( R"( }} // namespace wis #endif // WISDOM_DX12 @@ -568,7 +569,7 @@ namespace wis {{ // Write footer // clang-format off - file << wis::format(R"( + file << std::format(R"( }} // namespace wis #endif // WISDOM_VULKAN @@ -584,15 +585,15 @@ void Generator::WriteCIndependentAPI(std::filesystem::path dir) auto& module = module_map.at(active_module_name); auto independent_name = module.name == "Core" ? std::string("wisdom") - : wis::format("wisdom_{}", MakeSnakeCase(module.name)); + : std::format("wisdom_{}", MakeSnakeCase(module.name)); auto module_folder = std::filesystem::path(module.gen_path).filename().generic_string(); if (module_folder.empty()) { module_folder = std::filesystem::path(module.gen_path).parent_path().filename().generic_string(); } auto backend_include = module_folder == "wisdom" ? std::string("generated/c_api.h") - : wis::format("../{}/generated/c_api.h", module_folder); - auto header_guard = wis::format("WISDOM_{}_H", MakeUpperSnakeCase(module.name)); + : std::format("../{}/generated/c_api.h", module_folder); + auto header_guard = std::format("WISDOM_{}_H", MakeUpperSnakeCase(module.name)); std::filesystem::path path_w = dir / (independent_name + ".h"); files.push_back(path_w); @@ -603,7 +604,7 @@ void Generator::WriteCIndependentAPI(std::filesystem::path dir) } // Write header - file_w << wis::format( + file_w << std::format( R"(// This file is generated. Do not edit directly. #ifndef {0} #define {0} @@ -667,7 +668,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::DX12)) { - file_w << wis::format( + file_w << std::format( "typedef struct {} {};\n", GetCFullTypename(handle_def.name, Backend::DX12), GetCFullTypename(handle_def.name) @@ -679,7 +680,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.views_in_order) { auto& handle_def = handle_map[handle_name]; if (handle_def.GetViewSize(Backend::DX12) > 0) { - file_w << wis::format( + file_w << std::format( "typedef struct {}View {}View;\n", GetCFullTypename(handle_def.name, Backend::DX12), GetCFullTypename(handle_def.name) @@ -697,7 +698,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& variant_name : module.variants_in_order) { auto& variant_def = variant_map[variant_name]; if (has(variant_def.backend, Backend::DX12)) { - file_w << wis::format( + file_w << std::format( "typedef struct {} {};\n", GetCFullTypename(variant_def.name, Backend::DX12), GetCFullTypename(variant_def.name) @@ -714,7 +715,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::DX12) && handle_def.GetViewSize(Backend::DX12) > 0) { - file_w << wis::format( + file_w << std::format( "#define wisGet{}View wisGet{}{}View\n", handle_def.name, GetBackendSuffix(Backend::DX12), @@ -727,7 +728,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& func_name : module.functions_in_order) { auto& func_def = function_map[func_name]; if (has(func_def.backend, Backend::DX12)) { - file_w << wis::format( + file_w << std::format( "#define {} {}\n", GetCFullFunctionName(func_name), GetCFullFunctionName(func_name, Backend::DX12) @@ -776,7 +777,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::Vulkan)) { - file_w << wis::format( + file_w << std::format( "typedef struct {} {};\n", GetCFullTypename(handle_def.name, Backend::Vulkan), GetCFullTypename(handle_def.name) @@ -788,7 +789,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.views_in_order) { auto& handle_def = handle_map[handle_name]; if (handle_def.GetViewSize(Backend::Vulkan) > 0) { - file_w << wis::format( + file_w << std::format( "typedef struct {}View {}View;\n", GetCFullTypename(handle_def.name, Backend::Vulkan), GetCFullTypename(handle_def.name) @@ -806,7 +807,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& variant_name : module.variants_in_order) { auto& variant_def = variant_map[variant_name]; if (has(variant_def.backend, Backend::Vulkan)) { - file_w << wis::format( + file_w << std::format( "typedef struct {} {};\n", GetCFullTypename(variant_def.name, Backend::Vulkan), GetCFullTypename(variant_def.name) @@ -823,7 +824,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::Vulkan) && handle_def.GetViewSize(Backend::Vulkan) > 0) { - file_w << wis::format( + file_w << std::format( "#define wisGet{}View wisGet{}{}View\n", handle_def.name, GetBackendSuffix(Backend::Vulkan), @@ -836,7 +837,7 @@ static_assert(WISDOM_UWP && _WIN32, "Platform error"); for (auto& func_name : module.functions_in_order) { auto& func_def = function_map[func_name]; if (has(func_def.backend, Backend::Vulkan)) { - file_w << wis::format( + file_w << std::format( "#define {} {}\n", GetCFullFunctionName(func_name), GetCFullFunctionName(func_name, Backend::Vulkan) @@ -859,7 +860,7 @@ static inline bool wisHandleValid(const void* handle) { #endif // WISDOM_HANDLE_VALID_DEFINED )"; - file_w << wis::format("#endif // {}\n", header_guard); + file_w << std::format("#endif // {}\n", header_guard); } //---------------------------------------------------------------------------------------------------------------------- @@ -868,15 +869,15 @@ void Generator::WriteCPPIndependentAPI(std::filesystem::path dir) auto& module = module_map.at(active_module_name); auto independent_name = module.name == "Core" ? std::string("wisdom") - : wis::format("wisdom_{}", MakeSnakeCase(module.name)); + : std::format("wisdom_{}", MakeSnakeCase(module.name)); auto module_folder = std::filesystem::path(module.gen_path).filename().generic_string(); if (module_folder.empty()) { module_folder = std::filesystem::path(module.gen_path).parent_path().filename().generic_string(); } auto backend_include = module_folder == "wisdom" ? std::string("generated/cpp_api.hpp") - : wis::format("../{}/generated/cpp_api.hpp", module_folder); - auto header_guard = wis::format("WISDOM_{}_HPP", MakeUpperSnakeCase(module.name)); + : std::format("../{}/generated/cpp_api.hpp", module_folder); + auto header_guard = std::format("WISDOM_{}_HPP", MakeUpperSnakeCase(module.name)); std::filesystem::path path_w = dir / (independent_name + ".hpp"); files.push_back(path_w); @@ -887,7 +888,7 @@ void Generator::WriteCPPIndependentAPI(std::filesystem::path dir) } // Write header - file_w << wis::format( + file_w << std::format( R"(// This file is generated. Do not edit directly. #ifndef {0} #define {0} @@ -960,7 +961,7 @@ namespace wis {{ for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::DX12)) { - file_w << wis::format( + file_w << std::format( "using {} = {};\n", handle_def.name, GetCPPFullTypename(handle_def.name, Backend::DX12) @@ -972,7 +973,7 @@ namespace wis {{ for (auto& handle_name : module.views_in_order) { auto& handle_def = handle_map[handle_name]; if (handle_def.GetViewSize(Backend::DX12) > 0) { - file_w << wis::format( + file_w << std::format( "using {}View = {};\n", handle_def.name, GetCPPFullTypename(handle_def.name, Backend::DX12) + "View" @@ -990,7 +991,7 @@ namespace wis {{ for (auto& variant_name : module.variants_in_order) { auto& variant_def = variant_map[variant_name]; if (has(variant_def.backend, Backend::DX12)) { - file_w << wis::format( + file_w << std::format( "using {} = {};\n", variant_def.name, GetCPPFullTypename(variant_def.name, Backend::DX12) @@ -1069,7 +1070,7 @@ namespace wis { for (auto& handle_name : module.handles_in_order) { auto& handle_def = handle_map[handle_name]; if (has(handle_def.GetBackend(), Backend::Vulkan)) { - file_w << wis::format( + file_w << std::format( "using {} = {};\n", handle_def.name, GetCPPFullTypename(handle_def.name, Backend::Vulkan) @@ -1081,7 +1082,7 @@ namespace wis { for (auto& handle_name : module.views_in_order) { auto& handle_def = handle_map[handle_name]; if (handle_def.GetViewSize(Backend::Vulkan) > 0) { - file_w << wis::format( + file_w << std::format( "using {}View = {};\n", handle_def.name, GetCPPFullTypename(handle_def.name, Backend::Vulkan) + "View" @@ -1099,7 +1100,7 @@ namespace wis { for (auto& variant_name : module.variants_in_order) { auto& variant_def = variant_map[variant_name]; if (has(variant_def.backend, Backend::Vulkan)) { - file_w << wis::format( + file_w << std::format( "using {} = {};\n", variant_def.name, GetCPPFullTypename(variant_def.name, Backend::Vulkan) @@ -1131,7 +1132,7 @@ namespace wis { #error "No API selected for Wisdom. Define WISDOM_DX12 or WISDOM_VULKAN." #endif // API selection )"; - file_w << wis::format("#endif // {}\n", header_guard); + file_w << std::format("#endif // {}\n", header_guard); } void Generator::WriteConversions(std::filesystem::path dir) @@ -1159,7 +1160,7 @@ void Generator::WriteConversions(std::filesystem::path dir) auto header_guard = MakeUpperSnakeCase(module.name); // Write header - file_dx << wis::format( + file_dx << std::format( R"(// This file is generated. Do not edit directly. #ifndef WISDOM_{0}_CPP_DX12_CONVERT_HPP #define WISDOM_{0}_CPP_DX12_CONVERT_HPP @@ -1169,14 +1170,13 @@ void Generator::WriteConversions(std::filesystem::path dir) #include "c_api.h" #include -#include #include namespace wis{{ namespace detail {{ )", header_guard ); - file_vk << wis::format( + file_vk << std::format( R"(// This file is generated. Do not edit directly. #ifndef WISDOM_{0}_CPP_VK_CONVERT_HPP #define WISDOM_{0}_CPP_VK_CONVERT_HPP @@ -1186,6 +1186,7 @@ namespace wis{{ namespace detail {{ #include "c_api.h" #include +#include namespace wis{{ namespace detail {{ )", @@ -1210,14 +1211,14 @@ namespace wis{{ namespace detail {{ } // Write footer - file_dx << wis::format( + file_dx << std::format( R"( }}}} #endif // WISDOM_{}_CPP_DX12_CONVERT_HPP )", header_guard ); - file_vk << wis::format( + file_vk << std::format( R"( }}}} #endif // WISDOM_{}_CPP_VK_CONVERT_HPP @@ -1245,9 +1246,9 @@ void Generator::WriteDocumentation( std::fstream enum_file{doc_output_path, file_exists ? std::ios::in | std::ios::out : std::ios::out}; if (!file_exists) { - std::string xenum = wis::vformat( + std::string xenum = std::vformat( doc_template, - wis::make_format_args(object_name, code, desc, active_module_name) + std::make_format_args(object_name, code, desc, active_module_name) ); enum_file << FinalizeCDocumentation(xenum, object_name); @@ -1374,12 +1375,12 @@ std::string Generator::GetCFullTypename(std::string_view type, Backend backend) case TypeKind::Bitmask: case TypeKind::FuncPointer: case TypeKind::Struct: - return wis::format("Wis{}", type); + return std::format("Wis{}", type); case TypeKind::Handle: case TypeKind::View: case TypeKind::Function: case TypeKind::Variant: - return wis::format("Wis{}{}", suffix, type); + return std::format("Wis{}{}", suffix, type); } return ""; } @@ -1387,9 +1388,9 @@ std::string Generator::GetCFullFunctionName(FunctionKey type, Backend backend) { auto& func_def = function_map[type]; if (func_def.IsCD()) { - return wis::format("wis{}{}", GetBackendSuffix(backend), func_def.name); + return std::format("wis{}{}", GetBackendSuffix(backend), func_def.name); } else { - return wis::format("wis{}{}{}", GetBackendSuffix(backend), func_def.this_type, func_def.name); + return std::format("wis{}{}{}", GetBackendSuffix(backend), func_def.this_type, func_def.name); } } std::string Generator::GetCPPFullTypename(std::string_view type, Backend backend) @@ -1405,12 +1406,12 @@ std::string Generator::GetCPPFullTypename(std::string_view type, Backend backend case TypeKind::Bitmask: case TypeKind::Struct: case TypeKind::Enum: - return wis::format("wis::{}", type); + return std::format("wis::{}", type); case TypeKind::Variant: case TypeKind::Handle: case TypeKind::View: case TypeKind::Function: - return wis::format("wis::{}{}", suffix, type); + return std::format("wis::{}{}", suffix, type); case TypeKind::Union: break; case TypeKind::Alias: @@ -1422,9 +1423,9 @@ std::string Generator::GetCPPFullFunctionName(FunctionKey type, Backend backend) { auto& func_def = function_map[type]; if (func_def.IsCD()) { - return wis::format("wis::{}{}", GetBackendSuffix(backend), func_def.name); + return std::format("wis::{}{}", GetBackendSuffix(backend), func_def.name); } else { - return wis::format("wis::{}{}::{}", GetBackendSuffix(backend), func_def.this_type, func_def.name); + return std::format("wis::{}{}::{}", GetBackendSuffix(backend), func_def.this_type, func_def.name); } } std::string Generator::FinalizeCDocumentation(std::string doc, std::string_view this_type, Backend backend) @@ -1457,35 +1458,35 @@ std::string Generator::FinalizeCDocumentation(std::string doc, std::string_view case TypeKind::Enum: { auto& x = enum_map.at(this_type_view); auto evalue = x.HasValue(value); - replacement = evalue ? wis::format("`{}{}`", GetCFullTypename(x.name, backend), evalue->name) + replacement = evalue ? std::format("`{}{}`", GetCFullTypename(x.name, backend), evalue->name) : GetCFullTypename(x.name, backend); break; } case TypeKind::Bitmask: { auto& b = bitmask_map.at(this_type_view); auto evalue = b.HasValue(value); - replacement = evalue ? wis::format("`{}{}`", GetCFullTypename(b.name, backend), evalue->name) + replacement = evalue ? std::format("`{}{}`", GetCFullTypename(b.name, backend), evalue->name) : GetCFullTypename(b.name, backend); break; } case TypeKind::Struct: { auto& s = struct_map.at(this_type_view); auto member = s.HasValue(value); - replacement = member ? wis::format("`{}::{}`", GetCFullTypename(s.name, backend), member->name) + replacement = member ? std::format("`{}::{}`", GetCFullTypename(s.name, backend), member->name) : GetCFullTypename(s.name, backend); break; } case TypeKind::Variant: { auto& v = variant_map.at(this_type_view); auto m = v.HasValue(value); - replacement = m ? wis::format("`{}::{}`", GetCFullTypename(v.name, backend), m->name) + replacement = m ? std::format("`{}::{}`", GetCFullTypename(v.name, backend), m->name) : GetCFullTypename(v.name, backend); break; } case TypeKind::FuncPointer: { auto& d = delegate_map.at(this_type_view); auto m = d.HasValue(value); - replacement = m ? wis::format("`{}::{}`", GetCFullTypename(d.name, backend), m->name) + replacement = m ? std::format("`{}::{}`", GetCFullTypename(d.name, backend), m->name) : GetCFullTypename(d.name, backend); break; } @@ -1574,35 +1575,35 @@ std::string Generator::FinalizeCPPDocumentation(std::string doc, std::string_vie case TypeKind::Enum: { auto& x = enum_map.at(this_type_view); auto evalue = x.HasValue(value); - replacement = evalue ? wis::format("`{}::{}`", GetCPPFullTypename(x.name, backend), evalue->name) + replacement = evalue ? std::format("`{}::{}`", GetCPPFullTypename(x.name, backend), evalue->name) : GetCPPFullTypename(x.name, backend); break; } case TypeKind::Bitmask: { auto& b = bitmask_map.at(this_type_view); auto evalue = b.HasValue(value); - replacement = evalue ? wis::format("`{}::{}`", GetCPPFullTypename(b.name, backend), evalue->name) + replacement = evalue ? std::format("`{}::{}`", GetCPPFullTypename(b.name, backend), evalue->name) : GetCPPFullTypename(b.name, backend); break; } case TypeKind::Struct: { auto& s = struct_map.at(this_type_view); auto member = s.HasValue(value); - replacement = member ? wis::format("`{}::{}`", GetCPPFullTypename(s.name, backend), member->name) + replacement = member ? std::format("`{}::{}`", GetCPPFullTypename(s.name, backend), member->name) : GetCPPFullTypename(s.name, backend); break; } case TypeKind::Variant: { auto& v = variant_map.at(this_type_view); auto m = v.HasValue(value); - replacement = m ? wis::format("`{}::{}`", GetCPPFullTypename(v.name, backend), m->name) + replacement = m ? std::format("`{}::{}`", GetCPPFullTypename(v.name, backend), m->name) : GetCPPFullTypename(v.name, backend); break; } case TypeKind::FuncPointer: { auto& d = delegate_map.at(this_type_view); auto m = d.HasValue(value); - replacement = m ? wis::format("`{}::{}`", GetCPPFullTypename(d.name, backend), m->name) + replacement = m ? std::format("`{}::{}`", GetCPPFullTypename(d.name, backend), m->name) : GetCPPFullTypename(d.name, backend); break; } @@ -1671,10 +1672,10 @@ std::string Generator::GetSpecificationCode( { std::string template_content_c; if (!c_code.empty()) { - template_content_c = wis::format(" C Version:\n```c\n{}```\n", c_code); + template_content_c = std::format(" C Version:\n```c\n{}```\n", c_code); if (!c_impl_code.empty()) { // append a details section - template_content_c += wis::format( + template_content_c += std::format( "
\nC Implementation Specific Version:\n```c\n{}```\n
\n", c_impl_code ); @@ -1683,10 +1684,10 @@ std::string Generator::GetSpecificationCode( std::string template_content_cpp; if (!cpp_code.empty()) { - template_content_cpp = wis::format("C++ Version:\n```cpp\nnamespace wis{{\n{}}}\n```\n", cpp_code); + template_content_cpp = std::format("C++ Version:\n```cpp\nnamespace wis{{\n{}}}\n```\n", cpp_code); if (!cpp_impl_code.empty()) { // append a details section - template_content_cpp += wis::format( + template_content_cpp += std::format( "
\nC++ Implementation Specific Version:\n```cpp\nnamespace " "wis{{\n{}}}\n```\n
\n", cpp_impl_code @@ -1694,7 +1695,7 @@ std::string Generator::GetSpecificationCode( } } - std::string output = wis::format(" * {}\n{}", template_content_c, template_content_cpp); + std::string output = std::format(" * {}\n{}", template_content_c, template_content_cpp); ReplaceAll(output, "\n", "\n * "); return output; } @@ -1778,7 +1779,7 @@ InlineTypeInfo Generator::FindInlineType(std::string_view str) std::string Generator::MakeVersionString(std::string_view version, bool newline) { - return version.empty() ? "" : wis::format("Provided by Wisdom {}.{}", version, newline ? "\n" : " "); + return version.empty() ? "" : std::format("Provided by Wisdom {}.{}", version, newline ? "\n" : " "); } std::string Generator::MakeSnakeCase(std::string_view str) @@ -1927,7 +1928,54 @@ std::string Generator::GetRefs(std::string_view for_type) } if (!refs.empty()) { - refs = wis::format(" * @see {}\n", refs); + refs = std::format(" * @see {}\n", refs); } return refs; } + +std::string Generator::GetFunctionCallParameters(const WisFunction& func, Backend backend) +{ + constexpr static std::string_view arg_prefix = ",\n "; + std::string body; + for (size_t i = 0; i < func.parameters.size(); ++i) { + auto& p = func.parameters[i]; + + if (p.modifier & Modifier::Span) { + body += std::format( + "reinterpret_cast<{}>({}.data()), {}.size()", + GetMemberTypeString(p, backend), + p.name, + p.name + ); + i++; // skip next parameter (the size) + if (i < func.parameters.size() - 1) { + body += arg_prefix; + } + continue; + } + + switch (GetType(p.type)) { + case TypeKind::Enum: + case TypeKind::Bitmask: + body += std::format("static_cast<{}>({})", GetMemberTypeString(p, backend), p.name); + break; + case TypeKind::None: + case TypeKind::View: + case TypeKind::Base: + body += p.name; + break; + default: + if (p.modifier & Modifier::Reference) { + body += std::format("reinterpret_cast<{}>(&{})", GetMemberTypeString(p, backend), p.name); + break; + } + body += std::format("reinterpret_cast<{}>({})", GetMemberTypeString(p, backend), p.name); + break; + } + + if (i < func.parameters.size() - 1) { + body += arg_prefix; + } + } + return body; +} diff --git a/generator/generator.hpp b/generator/generator.hpp index 0a1e5f693..8464737cd 100644 --- a/generator/generator.hpp +++ b/generator/generator.hpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -9,7 +10,6 @@ #include #include -#include "../src/include/wisdom/bridge/format.hpp" #include "types.hpp" class Generator @@ -151,6 +151,7 @@ class Generator void TryMakeRef(std::string_view type, std::string_view from); void TryMakeRef(std::string_view type, FunctionKey from); std::string GetRefs(std::string_view for_type); + std::string GetFunctionCallParameters(const WisFunction& func, Backend backend); static Backend ParseBackend(std::string_view backend) noexcept; static ImplOs GetImplOs(std::string_view os) noexcept; @@ -214,11 +215,11 @@ class Generator if (kind == DocKind::VersionOnly) { if constexpr (requires { value.version; }) { if (value.version.empty()) { - return wis::format("{}\n", value_decl); + return std::format("{}\n", value_decl); } - return wis::format("// {}{}\n", version_info, value_decl); + return std::format("// {}{}\n", version_info, value_decl); } - return wis::format("{}\n", value_decl); + return std::format("{}\n", value_decl); } auto doc = value.doc; @@ -237,22 +238,22 @@ class Generator if (doc.find('\n') != std::string_view::npos) { pre_doc = true; - documentation = wis::format("/**\n@brief {}\n{}\n*/", version_info, doc); + documentation = std::format("/**\n@brief {}\n{}\n*/", version_info, doc); ReplaceAll(documentation, "\n", "\n * "); } else { - documentation = wis::format(" ///< {}{}", version_info, doc); + documentation = std::format(" ///< {}{}", version_info, doc); } documentation = finalize_doc(std::move(documentation)); if (!pre_doc && value_decl.length() + documentation.length() > value_comment_column_limit) { pre_doc = true; - documentation = wis::format("/**\n@brief {}{}\n*/", version_info, doc); + documentation = std::format("/**\n@brief {}{}\n*/", version_info, doc); ReplaceAll(documentation, "\n", "\n * "); documentation = finalize_doc(std::move(documentation)); } } - return pre_doc ? wis::format(" {}\n {}\n", documentation, value_decl) - : wis::format("{}{}\n", value_decl, documentation); + return pre_doc ? std::format(" {}\n {}\n", documentation, value_decl) + : std::format("{}{}\n", value_decl, documentation); } template @@ -265,7 +266,7 @@ class Generator if constexpr (lang == Lang::C) { // This arg if (!type.this_type.empty()) { - args += wis::format( + args += std::format( "@param self is a pointer to the valid {{{}::}} instance.\n", type.this_type ); @@ -273,16 +274,16 @@ class Generator // Function arguments for (auto& param : type.parameters) { - args += wis::format("@param {} {}\n", param.name, param.doc); + args += std::format("@param {} {}\n", param.name, param.doc); } if (type.return_type.IsRV()) { - args += wis::format("@param {} {}\n", type.return_type.opt_name, type.return_type.doc); - args += wis::format("@return {} {}\n", "Result", "denoting the outcome of operation."); + args += std::format("@param {} {}\n", type.return_type.opt_name, type.return_type.doc); + args += std::format("@return {} {}\n", "Result", "denoting the outcome of operation."); } else if (type.return_type.IsDirect()) { - args += wis::format("@return {} {}\n", type.return_type.type, type.return_type.doc); + args += std::format("@return {} {}\n", type.return_type.type, type.return_type.doc); } else if (type.return_type.IsResultOnly()) { - args += wis::format("@return {} {}\n", "Result", "denoting the outcome of operation."); + args += std::format("@return {} {}\n", "Result", "denoting the outcome of operation."); } } else { // Function arguments, beware of spans @@ -295,20 +296,20 @@ class Generator if (param.modifier & Modifier::Span) { last_was_span = true; } - args += wis::format("@param {} {}\n", param.name, param.doc); + args += std::format("@param {} {}\n", param.name, param.doc); } auto kind = type.return_type.GetKind(); switch (kind) { case ReturnTypeKind::Direct: - args += wis::format("@return {} {}\n", type.return_type.type, type.return_type.doc); + args += std::format("@return {} {}\n", type.return_type.type, type.return_type.doc); break; case ReturnTypeKind::ResultOnly: - args += wis::format("@return {} {}\n", "Result", "denoting the outcome of operation."); + args += std::format("@return {} {}\n", "Result", "denoting the outcome of operation."); break; case ReturnTypeKind::ResultAndValue: - args += wis::format("@param {} {}\n", "out_result", "denoting the outcome of operation."); - args += wis::format("@return {} {}\n", type.return_type.opt_name, type.return_type.doc); + args += std::format("@param {} {}\n", "out_result", "denoting the outcome of operation."); + args += std::format("@return {} {}\n", type.return_type.opt_name, type.return_type.doc); break; default: break; @@ -316,7 +317,7 @@ class Generator } } - std::string documentation = wis::format("/**\n@brief {}{}\n{}\n", version_info, type.doc, args); + std::string documentation = std::format("/**\n@brief {}{}\n{}\n", version_info, type.doc, args); if constexpr (requires { type.doc_translates; }) { documentation += type.doc_translates; } @@ -330,7 +331,7 @@ class Generator return FinalizeCDocumentation(documentation, type.name); } } - return wis::format("// {}", version_info); + return std::format("// {}", version_info); } template @@ -352,7 +353,7 @@ class Generator attributes_inter += "&"; } if (member.modifier & Modifier::Span) { - return wis::format( + return std::format( "wis::span<{}>", attributes_pre + GetCPPFullTypename(member.type, backend) + attributes_inter ); diff --git a/generator/handle.cpp b/generator/handle.cpp index d19725385..e4fb52d6d 100644 --- a/generator/handle.cpp +++ b/generator/handle.cpp @@ -87,6 +87,40 @@ void Generator::ParseHandles(tinyxml2::XMLElement* types) create.modifier = Modifier::Construct; create.version = version; create.doc = create_doc; + + if (auto* init = type->FirstChildElement("init")) { + if (auto* vers = init->FindAttribute("version")) { + create.version = vers->Value(); + } + + if (auto* doc = init->FindAttribute("doc")) { + create.doc = doc->Value(); + } + + // Parse parameters + for (auto* param = init->FirstChildElement("arg"); param; param = param->NextSiblingElement("arg")) { + auto& p = create.parameters.emplace_back(); + p.type = param->FindAttribute("type")->Value(); + + if (auto* name_attr = param->FindAttribute("name")) { + p.name = name_attr->Value(); + } else { + throw std::runtime_error(std::format("Function {} has a parameter with no name.", create_name)); + } + if (auto* def = param->FindAttribute("default")) { + p.default_value = def->Value(); + } + if (auto* mod = param->FindAttribute("mod")) { + p.modifier = GetModifiers(mod->Value()); + } + if (auto* doc = param->FindAttribute("doc")) { + p.doc = doc->Value(); + } + create.FilterBackend(GetTypeBackendSupport(p.type)); + TryMakeRef(p.type, create_key); + } + } + create.FilterBackend(ref.GetBackend()); type_map[iref] = TypeKind::Function; module_map[active_module_name].functions_in_order.emplace_back(create_key); @@ -97,6 +131,11 @@ void Generator::ParseHandles(tinyxml2::XMLElement* types) bool has_view = false; for (auto* impl = type->FirstChildElement("view"); impl; impl = impl->NextSiblingElement("view")) { has_view = true; + auto voverride = impl->FindAttribute("type"); + if (voverride) { + ref.view_override = voverride->Value(); + } + auto impl_for = impl->FindAttribute("for"); if (!impl_for) { // if "for" attribute is missing, we can assume it's for both @@ -111,9 +150,9 @@ void Generator::ParseHandles(tinyxml2::XMLElement* types) uint32_t size = impl->UnsignedAttribute("size", 0); if (backend == Backend::DX12) { - ref.sizes[0] = size; + ref.view_sizes[0] = size; } else if (backend == Backend::Vulkan) { - ref.sizes[1] = size; + ref.view_sizes[1] = size; } } @@ -132,31 +171,33 @@ std::string Generator::MakeCHandle(const WisHandle& s, Backend backend, DocKind auto extends_macro = s.extends == Extends::None ? std::string("WIS_DEFINE_HANDLE") : (s.extends == Extends::Instance - ? wis::format("WIS_DEFINE_{}_INSTANCE_EXT_HANDLE", impl_string) - : wis::format("WIS_DEFINE_{}_DEVICE_EXT_HANDLE", impl_string)); + ? std::format("WIS_DEFINE_{}_INSTANCE_EXT_HANDLE", impl_string) + : std::format("WIS_DEFINE_{}_DEVICE_EXT_HANDLE", impl_string)); auto full_name = GetCFullTypename(s.name, backend); - std::string st_decl = wis::format("{}({},{});\n", extends_macro, full_name, s.GetSize(backend)); + std::string st_decl = std::format("{}({},{});\n", extends_macro, full_name, s.GetSize(backend)); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } - if (s.GetViewSize(backend) > 0) { - std::string view_decl = wis::format("WIS_DEFINE_HANDLE_VIEW({},{});\n", full_name, s.GetViewSize(backend)); + if (s.GetViewSize(backend) > 0 && s.view_override.empty()) { + std::string view_decl = std::format("WIS_DEFINE_HANDLE_VIEW({},{});\n", full_name, s.GetViewSize(backend)); st_decl += view_decl; } - if (kind == DocKind::Full && s.GetViewSize(backend) > 0) { + if (kind == DocKind::Full && (s.GetViewSize(backend) > 0 || !s.view_override.empty())) { // Add view extraction function - st_decl += wis::format( + auto view_name = s.view_override.empty() ? full_name : GetCFullTypename(s.view_override, backend); + + st_decl += std::format( "\nstatic inline {}View wisGet{}{}View(const {}* handle){{\n", - full_name, + view_name, impl_string, s.name, full_name ); - st_decl += wis::format(" {}View v;\n", full_name); + st_decl += std::format(" {}View v;\n", view_name); st_decl += " memcpy(&v, handle, sizeof(v));\n" " return v;\n}\n"; } @@ -170,7 +211,7 @@ std::string Generator::MakeCPPHandle(const WisHandle& s, Backend backend, DocKin auto impl_string = GetBackendSuffix(backend); auto full_name = GetCFullTypename(s.name, backend); - std::string deleter = wis::format( + std::string deleter = std::format( "struct {}{}Deleter {{\n " "void operator()({}* handle) noexcept {{\n ", impl_string, @@ -178,7 +219,7 @@ std::string Generator::MakeCPPHandle(const WisHandle& s, Backend backend, DocKin full_name ); - std::string st_decl = wis::format( + std::string st_decl = std::format( "class {}{} : public wis::impl::Implements{{\npublic:\n", impl_string, s.name, @@ -191,39 +232,38 @@ std::string Generator::MakeCPPHandle(const WisHandle& s, Backend backend, DocKin if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } std::string ctor_decl; // Use constructor from base - if (s.extends != Extends::None) { - ctor_decl += wis::format("{}{}() noexcept\n:ImplType(std::in_place)\n{{\n ", impl_string, s.name); - } else { + if (s.extends == Extends::None) { ctor_decl += " using ImplType::ImplType;\n"; } std::string st_decl2 = "public:\n"; - if (s.GetViewSize(backend) > 0) { + if (s.GetViewSize(backend) > 0 || !s.view_override.empty()) { // Strict aliasing rules prevent us from doing a simple cast, so we have to memcpy the data to a new view struct - st_decl2 += wis::format( + auto view_name = s.view_override.empty() ? s.name : s.view_override; + st_decl2 += std::format( " WIS_NODISCARD {}{}View GetView() const noexcept {{\n" " {}{}View v;\n" " std::memcpy(&v, &_impl_storage, sizeof(v));\n" " return v;\n" " }}\n", impl_string, - s.name, + view_name, impl_string, - s.name + view_name ); // add conversion operator to view - st_decl2 += wis::format( + st_decl2 += std::format( " WIS_NODISCARD operator {}{}View() const noexcept {{\n" " return GetView();\n" " }}\n", impl_string, - s.name + view_name ); } @@ -231,18 +271,61 @@ std::string Generator::MakeCPPHandle(const WisHandle& s, Backend backend, DocKin for (const auto& func_name : s.functions) { FunctionKey func_key{s.name, func_name}; auto& func_ref = function_map[func_key]; - auto c_name = wis::format( + auto c_name = std::format( "wis{}{}{}", impl_string, func_ref.modifier & (Destroy | Construct) ? "" : func_ref.this_type, func_ref.name ); if (func_ref.modifier & Modifier::Destroy) { - deleter += wis::format(" ::{}(handle);\n", c_name); + deleter += std::format(" ::{}(handle);\n", c_name); continue; } if (func_ref.modifier & Modifier::Construct) { - ctor_decl += wis::format(" ::{}(GetStorage());\n }}\n", c_name); + // Build the init function parameter list for the constructor + std::string params; + std::string args = "GetStorage(), " + GetFunctionCallParameters(func_ref, backend); + if (func_ref.parameters.empty()) { + args.pop_back(); + args.pop_back(); + } + + bool last_was_span = false; + for (size_t i = 0; i < func_ref.parameters.size(); ++i) { + if (last_was_span) { + last_was_span = false; + continue; + } + + const auto& p = func_ref.parameters[i]; + if (p.modifier & Modifier::Span) { + last_was_span = true; + } + + std::string type_str = GetMemberTypeString(p, backend); + params += std::format("{} {}", type_str, p.name); + + // edge case for spans - if last argument was a span, skip the next one (the size) + // That means we need to check if i 0) { - view_decl = wis::format("using {}{}View = {}View;\n", impl_string, s.name, full_name); + view_decl = std::format("using {}{}View = {}View;\n", impl_string, s.name, full_name); } return view_decl; } @@ -289,18 +372,19 @@ void Generator::WriteHandleDocumentation(std::filesystem::path handle_output_pat // Make a folder for enums starting with this letter std::filesystem::create_directories(handle_output_path); std::filesystem::path handle_file_path = handle_output_path - / wis::format("{}_handle.h", MakeSnakeCase(handle_name)); + / std::format("{}_handle.h", MakeSnakeCase(handle_name)); auto& handle_ref = handle_map[handle_name]; + files.push_back(handle_file_path); std::string vk_code; std::string dx_code; if (has(backend, Backend::Vulkan)) { vk_code = MakeCHandle(handle_ref, Backend::Vulkan, DocKind::VersionOnly); - vk_code = wis::format(" Vulkan Version:\n```c\n{}```\n", vk_code); + vk_code = std::format(" Vulkan Version:\n```c\n{}```\n", vk_code); } if (has(backend, Backend::DX12)) { dx_code = MakeCHandle(handle_ref, Backend::DX12, DocKind::VersionOnly); - dx_code = wis::format(" DX12 Version:\n```c\n{}```\n", dx_code); + dx_code = std::format(" DX12 Version:\n```c\n{}```\n", dx_code); } std::string handle_template_content = " * " + vk_code + dx_code; diff --git a/generator/pch.hpp b/generator/pch.hpp index 555286ef7..70d48f890 100644 --- a/generator/pch.hpp +++ b/generator/pch.hpp @@ -2,10 +2,10 @@ #include #include #include +#include #include #include #include #include #include #include -#include "../src/include/wisdom/bridge/format.hpp" diff --git a/generator/struct.cpp b/generator/struct.cpp index 7f4fd75ca..8a4cbd3f1 100644 --- a/generator/struct.cpp +++ b/generator/struct.cpp @@ -48,7 +48,7 @@ void Generator::ParseStruct(tinyxml2::XMLElement* type) if (auto* size = type->FindAttribute("version")) { ref.version = size->Value(); } else { - throw std::runtime_error(wis::format("Struct {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Struct {} is missing version attribute.", name)); } if (auto* mod = type->FindAttribute("mod")) { @@ -80,6 +80,9 @@ void Generator::ParseStruct(tinyxml2::XMLElement* type) if (auto* doc = member->FindAttribute("doc")) { m.doc = doc->Value(); } + if (auto* bits = member->FindAttribute("bits")) { + m.bits = std::stoul(bits->Value()); + } } } @@ -87,14 +90,14 @@ void Generator::ParseStruct(tinyxml2::XMLElement* type) std::string Generator::MakeCStruct(const WisStruct& s, DocKind kind) { auto full_name = GetCFullTypename(s.name, Backend::Any); - std::string st_decl = wis::format( + std::string st_decl = std::format( "typedef struct {} {} {{\n", s.modifier & Modifier::Nodiscard ? "WIS_NODISCARD" : "", full_name ); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } // Calculate maximum type length for alignment @@ -107,21 +110,21 @@ std::string Generator::MakeCStruct(const WisStruct& s, DocKind kind) for (auto& m : s.members) { st_decl += MakeValueDocumentation(s, m, MakeCMemberDeclaration(m, max_type_length), kind); } - st_decl += wis::format("}} {};\n\n", full_name); + st_decl += std::format("}} {};\n\n", full_name); return st_decl; } //---------------------------------------------------------------------------------------------------------------------- std::string Generator::MakeCPPStruct(const WisStruct& s, DocKind kind) { - std::string st_decl = wis::format( + std::string st_decl = std::format( "struct {} {} {{\n", s.modifier & Modifier::Nodiscard ? "WIS_NODISCARD" : "", s.name ); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } // Calculate maximum type length for alignment @@ -157,13 +160,17 @@ std::string Generator::MakeCMemberDeclaration(const WisStructMember& member, siz std::string array_modifier; if (!member.array_size.empty()) { - array_modifier = wis::format("[{}]", member.array_size); + array_modifier = std::format("[{}]", member.array_size); } // Pad the type string to align_width size_t padding = align_width > type_string.length() ? align_width - type_string.length() : 0; std::string padded_type = type_string + std::string(padding, ' '); + if (member.bits > 0) { + return std::format(" {} {} : {}{};", padded_type, member.name, member.bits, array_modifier); + } + return std::format(" {} {}{};", padded_type, member.name, array_modifier); } @@ -173,13 +180,18 @@ std::string Generator::MakeCPPMemberDeclaration(const WisStructMember& member, s std::string type_string = GetMemberTypeString(member, backend); if (!member.array_size.empty()) { - type_string = wis::format("std::array<{}, {}>", type_string, member.array_size); + type_string = std::format("std::array<{}, {}>", type_string, member.array_size); } // Pad the type string to align_width size_t padding = align_width > type_string.length() ? align_width - type_string.length() : 0; std::string padded_type = type_string + std::string(padding, ' '); + // Bitfield + if (member.bits > 0) { + return std::format(" {} {} : {};", padded_type, member.name, member.bits); + } + return std::format(" {} {};", padded_type, member.name); } @@ -188,7 +200,7 @@ std::string Generator::MakeStructDescription(const WisStruct& s) { std::string description; for (auto& m : s.members) { - description += wis::format("- `{}` {}\n", m.name, m.doc.empty() ? "No description." : m.doc); + description += std::format("- `{}` {}\n", m.name, m.doc.empty() ? "No description." : m.doc); } return description; } @@ -201,17 +213,18 @@ void Generator::WriteStructDocumentation(std::filesystem::path struct_output_pat for (const auto& struct_name : struct_names) { // Make a folder for enums starting with this letter std::filesystem::path struct_file_path = struct_output_path - / wis::format("{}_struct.h", MakeSnakeCase(struct_name)); + / std::format("{}_struct.h", MakeSnakeCase(struct_name)); auto& struct_ref = struct_map[struct_name]; + files.push_back(struct_file_path); - std::string struct_template_content = wis::format( + std::string struct_template_content = std::format( " * C version:\n```c\n{}```\n" "C++ version:\n```cpp\nnamespace wis{{\n{}}}\n```\n", MakeCStruct(struct_ref, DocKind::VersionOnly), MakeCPPStruct(struct_ref, DocKind::VersionOnly) ); - std::string struct_description = wis::format(" * {}", MakeStructDescription(struct_ref)); + std::string struct_description = std::format(" * {}", MakeStructDescription(struct_ref)); std::string struct_refs = GetRefs(struct_name); std::string vuids = MakeValidationForType(struct_name); diff --git a/generator/types.hpp b/generator/types.hpp index 4f9d98a89..dfe6932c6 100644 --- a/generator/types.hpp +++ b/generator/types.hpp @@ -105,7 +105,7 @@ struct WisEnumValue { std::string_view doc; std::string_view version; std::array converts; - int64_t value = 0; + std::string_view value; }; struct WisEnum { std::string_view name; @@ -153,6 +153,7 @@ struct WisStructMember { std::string_view type; std::string_view array_size; Modifier modifier; + uint32_t bits; // for bitfield std::string_view default_value; std::string_view doc; }; @@ -188,6 +189,7 @@ struct WisHandle { Extends extends = Extends::None; // handle for extension std::array sizes{}; std::array view_sizes{}; + std::string_view view_override; // optional std::list functions; // must be string to hold destructors diff --git a/generator/validation.cpp b/generator/validation.cpp index 3723fffe5..33388eed5 100644 --- a/generator/validation.cpp +++ b/generator/validation.cpp @@ -24,14 +24,14 @@ void Generator::ParseValidations(tinyxml2::XMLElement* validations) if (auto* id_attr = check->FindAttribute("id")) { vcheck.id = id_attr->Value(); } else { - throw std::runtime_error(wis::format("Validation for {} is missing id attribute.", name)); + throw std::runtime_error(std::format("Validation for {} is missing id attribute.", name)); } // Message if (auto* msg = check->FindAttribute("msg")) { vcheck.message = msg->Value(); } else { - throw std::runtime_error(wis::format("Validation for {} is missing message attribute.", name)); + throw std::runtime_error(std::format("Validation for {} is missing message attribute.", name)); } ref.push_back(vcheck); @@ -43,7 +43,7 @@ void Generator::ParseValidations(tinyxml2::XMLElement* validations) std::string Generator::MakeValidationDescription(const Validation& v) { auto doc = FinalizeCDocumentation(std::string(v.message), v.type_name); - return wis::format(" * @vuid_begin{{WIS-{}-{}}} {} @vuid_end\n", GetCFullTypename(v.type_name), v.id, doc); + return std::format(" * @vuid_begin{{WIS-{}-{}}} {} @vuid_end\n", GetCFullTypename(v.type_name), v.id, doc); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/generator/variant.cpp b/generator/variant.cpp index 7b1be3d5e..2b7deb445 100644 --- a/generator/variant.cpp +++ b/generator/variant.cpp @@ -48,7 +48,7 @@ void Generator::ParseVariant(tinyxml2::XMLElement* type) if (auto* size = type->FindAttribute("version")) { ref.version = size->Value(); } else { - throw std::runtime_error(wis::format("Struct {} is missing version attribute.", name)); + throw std::runtime_error(std::format("Struct {} is missing version attribute.", name)); } if (auto* mod = type->FindAttribute("mod")) { @@ -90,14 +90,14 @@ std::string Generator::MakeCVariant(const WisStruct& s, Backend backend, DocKind { auto impl_suffix = GetBackendSuffix(backend); auto full_name = GetCFullTypename(s.name, backend); - std::string st_decl = wis::format( + std::string st_decl = std::format( "typedef struct {}{} {{\n", s.modifier & Modifier::Nodiscard ? "WIS_NODISCARD " : "", full_name ); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } // Calculate maximum type length for alignment @@ -110,7 +110,7 @@ std::string Generator::MakeCVariant(const WisStruct& s, Backend backend, DocKind for (auto& m : s.members) { st_decl += MakeValueDocumentation(s, m, MakeCMemberDeclaration(m, max_type_length, backend), kind); } - st_decl += wis::format("}} {};\n", full_name); + st_decl += std::format("}} {};\n", full_name); return st_decl; } @@ -122,7 +122,7 @@ std::string Generator::MakeCPPVariant(const WisStruct& s, Backend backend, DocKi } auto impl_suffix = GetBackendSuffix(backend); - std::string st_decl = wis::format( + std::string st_decl = std::format( "struct {}{}{} {{\n", s.modifier & Modifier::Nodiscard ? "WIS_NODISCARD " : "", impl_suffix, @@ -130,7 +130,7 @@ std::string Generator::MakeCPPVariant(const WisStruct& s, Backend backend, DocKi ); if (!s.doc.empty()) { std::string xdoc = MakeTypeDocumentation(s, kind); - st_decl = wis::format("{}\n{}", xdoc, st_decl); + st_decl = std::format("{}\n{}", xdoc, st_decl); } // Calculate maximum type length for alignment @@ -158,7 +158,7 @@ std::string Generator::MakeVariantDescription(const WisStruct& s) { std::string description; for (auto& m : s.members) { - description += wis::format("- `{}` {}\n", m.name, m.doc.empty() ? "No description." : m.doc); + description += std::format("- `{}` {}\n", m.name, m.doc.empty() ? "No description." : m.doc); } return description; } @@ -171,8 +171,9 @@ void Generator::WriteVariantDocumentation(std::filesystem::path struct_output_pa for (const auto& variant_name : variant_names) { // Make a folder for enums starting with this letter std::filesystem::path variant_file_path = struct_output_path - / wis::format("{}_struct.h", MakeSnakeCase(variant_name)); + / std::format("{}_struct.h", MakeSnakeCase(variant_name)); auto& variant_ref = variant_map[variant_name]; + files.push_back(variant_file_path); auto supports_vk = has(variant_ref.backend, Backend::Vulkan); auto supports_dx = has(variant_ref.backend, Backend::DX12); @@ -208,7 +209,7 @@ void Generator::WriteVariantDocumentation(std::filesystem::path struct_output_pa std::string variant_template_content = GetSpecificationCode(c_code, cimpl_code, cpp_code, cimpl_code_cpp); - std::string variant_description = wis::format(" * {}", MakeVariantDescription(variant_ref)); + std::string variant_description = std::format(" * {}", MakeVariantDescription(variant_ref)); std::string variant_refs = GetRefs(variant_name); std::string vuids = MakeValidationForType(variant_name); diff --git a/package.ps1 b/scripts/package.ps1 similarity index 63% rename from package.ps1 rename to scripts/package.ps1 index c8259ea37..e60a5c5fc 100644 --- a/package.ps1 +++ b/scripts/package.ps1 @@ -17,7 +17,7 @@ Skip the build step (use existing build artifacts). Default: $false .PARAMETER OutputDir - Directory for output packages. Default: './artifacts' + Directory for output packages. Default: '../artifacts' .PARAMETER Configuration Build configuration: 'both', 'debug', or 'release'. Default: 'both' @@ -31,8 +31,8 @@ Clean build and create NuGet package only. .EXAMPLE - .\package.ps1 -Format zip -SkipBuild -OutputDir "./release" - Create ZIP from existing build, output to ./release folder. + .\package.ps1 -Format zip -SkipBuild -OutputDir "../release" + Create ZIP from existing build, output to ../release folder. #> [CmdletBinding()] @@ -44,7 +44,7 @@ param( [switch]$SkipBuild, - [string]$OutputDir = './artifacts', + [string]$OutputDir = $null, [ValidateSet('both', 'debug', 'release')] [string]$Configuration = 'both' @@ -57,10 +57,24 @@ $ErrorActionPreference = "Stop" $generateNuGet = $Format -in @('nuget', 'all') $generateZip = $Format -in @('zip', 'all') +$WorkspaceRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path + # Build configurations to process $buildDebug = $Configuration -in @('both', 'debug') $buildRelease = $Configuration -in @('both', 'release') +# Package-specific build roots +$nugetDebugBuildDir = Join-Path $WorkspaceRoot 'build/msvc-debug-nuget' +$nugetReleaseBuildDir = Join-Path $WorkspaceRoot 'build/msvc-release-nuget' +$zipDebugBuildDir = Join-Path $WorkspaceRoot 'build/msvc-debug-zip' +$zipReleaseBuildDir = Join-Path $WorkspaceRoot 'build/msvc-release-zip' + +# Package-specific install roots +$nugetDebugInstallDir = Join-Path $WorkspaceRoot 'install/msvc-debug-nuget' +$nugetReleaseInstallDir = Join-Path $WorkspaceRoot 'install/msvc-release-nuget' +$zipDebugInstallDir = Join-Path $WorkspaceRoot 'install/msvc-debug-zip' +$zipReleaseInstallDir = Join-Path $WorkspaceRoot 'install/msvc-release-zip' + function Initialize-VSEnvironment { Write-Host "Initializing Visual Studio environment..." -ForegroundColor Cyan @@ -102,9 +116,13 @@ function Resolve-NuGetExecutable { } $candidatePaths = @( - 'build/msvc-release/NuGet/NuGet.exe', - 'build/msvc-debug/NuGet/NuGet.exe', - 'build/NuGet/NuGet.exe' + "$WorkspaceRoot/build/msvc-release-nuget/NuGet/NuGet.exe", + "$WorkspaceRoot/build/msvc-debug-nuget/NuGet/NuGet.exe", + "$WorkspaceRoot/build/msvc-release-zip/NuGet/NuGet.exe", + "$WorkspaceRoot/build/msvc-debug-zip/NuGet/NuGet.exe", + "$WorkspaceRoot/build/msvc-release/NuGet/NuGet.exe", + "$WorkspaceRoot/build/msvc-debug/NuGet/NuGet.exe", + "$WorkspaceRoot/build/NuGet/NuGet.exe" ) $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" @@ -151,19 +169,36 @@ function Invoke-CMake { function Build-Configuration { param( - [string]$Preset, [string]$BuildDir, - [string]$Config + [string]$Config, + [bool]$UseAgility, + [string]$InstallDir + ) + + $agilityValue = if ($UseAgility) { 'ON' } else { 'OFF' } + + Write-Host " Configuring $Config (WISDOM_USE_AGILITY_SDK=$agilityValue)..." -ForegroundColor Gray + + $configureArgs = @( + '-S', $WorkspaceRoot, + '-B', $BuildDir, + '-G', 'Ninja', + "-DCMAKE_BUILD_TYPE=$Config", + "-DCMAKE_INSTALL_PREFIX=$InstallDir", + '-DWISDOM_BUILD_EXAMPLES=OFF', + '-DWISDOM_BUILD_TESTS=OFF', + '-DCMAKE_UNITY_BUILD=ON', + "-DWISDOM_USE_AGILITY_SDK=$agilityValue", + "-DCPM_SOURCE_CACHE=$WorkspaceRoot/build/_deps_cache" ) - Write-Host " Configuring $Config..." -ForegroundColor Gray - Invoke-CMake @('--preset', $Preset) + Invoke-CMake $configureArgs Write-Host " Building $Config..." -ForegroundColor Gray - Invoke-CMake @('--build', $BuildDir, '--config', $Config) + Invoke-CMake @('--build', $BuildDir) Write-Host " Installing $Config..." -ForegroundColor Gray - Invoke-CMake @('--install', $BuildDir, '--config', $Config) + Invoke-CMake @('--install', $BuildDir) } function New-Package { @@ -172,13 +207,13 @@ function New-Package { [string]$OutputPath ) - $buildDir = "build/msvc-release" - $cpackDir = Join-Path $buildDir "_CPack_Packages" + $buildDir = switch ($Generator) { + 'NuGet' { $nugetReleaseBuildDir } + 'ZIP' { $zipReleaseBuildDir } + } - # Clean CPack staging directory to prevent cross-contamination between formats - if (Test-Path $cpackDir) { - Write-Host " Cleaning CPack staging directory..." -ForegroundColor Gray - Remove-Item -Recurse -Force $cpackDir + if (-not (Test-Path $buildDir)) { + throw "$Generator build directory not found at '$buildDir'. Run without -SkipBuild or build required artifacts first." } # Also clean any existing packages in the build directory @@ -188,8 +223,6 @@ function New-Package { } # Select the appropriate config file based on generator - # NuGet: excludes DXC (users get it from Microsoft.Direct3D.DXC package) - # ZIP: includes everything for standalone usage $configFile = switch ($Generator) { 'NuGet' { '../../cmake/install/multi-config-nuget.cmake' } 'ZIP' { '../../cmake/install/multi-config.cmake' } @@ -229,8 +262,14 @@ function New-Package { $totalSteps = 0 if (-not $SkipBuild) { - if ($buildDebug) { $totalSteps++ } - if ($buildRelease) { $totalSteps++ } + if ($generateNuGet) { + if ($buildDebug) { $totalSteps++ } + if ($buildRelease) { $totalSteps++ } + } + if ($generateZip) { + if ($buildDebug) { $totalSteps++ } + if ($buildRelease) { $totalSteps++ } + } } if ($generateNuGet) { $totalSteps++ } if ($generateZip) { $totalSteps++ } @@ -241,11 +280,15 @@ Write-Host " Wisdom Package Builder" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host " Format: $Format" Write-Host " Configuration: $Configuration" -Write-Host " Output: $OutputDir" +Write-Host " Output: $(if ($OutputDir) { $OutputDir } else { Join-Path $WorkspaceRoot 'artifacts' })" Write-Host " Clean: $Clean" Write-Host " Skip Build: $SkipBuild" Write-Host "========================================`n" -ForegroundColor Cyan +if (-not $OutputDir) { + $OutputDir = Join-Path $WorkspaceRoot "artifacts" +} + # Initialize VS environment Initialize-VSEnvironment @@ -258,23 +301,46 @@ $OutputDir = Resolve-Path $OutputDir # Clean if requested if ($Clean) { Write-Host "Cleaning build directories..." -ForegroundColor Yellow - @('build/msvc-debug', 'build/msvc-release') | ForEach-Object { + @( + $nugetDebugBuildDir, + $nugetReleaseBuildDir, + $zipDebugBuildDir, + $zipReleaseBuildDir, + "$WorkspaceRoot/build/msvc-debug", + "$WorkspaceRoot/build/msvc-release" + ) | ForEach-Object { if (Test-Path $_) { Remove-Item -Recurse -Force $_ } } } # Build if (-not $SkipBuild) { - if ($buildDebug) { - $currentStep++ - Write-Host "`n[$currentStep/$totalSteps] Building Debug configuration..." -ForegroundColor Yellow - Build-Configuration -Preset 'win-msvc-debug-lib' -BuildDir 'build/msvc-debug' -Config 'Debug' + if ($generateNuGet) { + if ($buildDebug) { + $currentStep++ + Write-Host "`n[$currentStep/$totalSteps] Building Debug configuration for NuGet (without Agility SDK)..." -ForegroundColor Yellow + Build-Configuration -BuildDir $nugetDebugBuildDir -Config 'Debug' -UseAgility $false -InstallDir $nugetDebugInstallDir + } + + if ($buildRelease) { + $currentStep++ + Write-Host "`n[$currentStep/$totalSteps] Building Release configuration for NuGet (without Agility SDK)..." -ForegroundColor Yellow + Build-Configuration -BuildDir $nugetReleaseBuildDir -Config 'Release' -UseAgility $false -InstallDir $nugetReleaseInstallDir + } } - if ($buildRelease) { - $currentStep++ - Write-Host "`n[$currentStep/$totalSteps] Building Release configuration..." -ForegroundColor Yellow - Build-Configuration -Preset 'win-msvc-lib' -BuildDir 'build/msvc-release' -Config 'Release' + if ($generateZip) { + if ($buildDebug) { + $currentStep++ + Write-Host "`n[$currentStep/$totalSteps] Building Debug configuration for ZIP (with Agility SDK)..." -ForegroundColor Yellow + Build-Configuration -BuildDir $zipDebugBuildDir -Config 'Debug' -UseAgility $true -InstallDir $zipDebugInstallDir + } + + if ($buildRelease) { + $currentStep++ + Write-Host "`n[$currentStep/$totalSteps] Building Release configuration for ZIP (with Agility SDK)..." -ForegroundColor Yellow + Build-Configuration -BuildDir $zipReleaseBuildDir -Config 'Release' -UseAgility $true -InstallDir $zipReleaseInstallDir + } } } @@ -282,14 +348,12 @@ if (-not $SkipBuild) { if ($generateNuGet) { $currentStep++ Write-Host "`n[$currentStep/$totalSteps] Generating NuGet package..." -ForegroundColor Yellow - Write-Host " (DXC excluded - use Microsoft.Direct3D.DXC NuGet package)" -ForegroundColor Gray New-Package -Generator 'NuGet' -OutputPath $OutputDir } if ($generateZip) { $currentStep++ Write-Host "`n[$currentStep/$totalSteps] Generating ZIP archive..." -ForegroundColor Yellow - Write-Host " (Includes DXC for standalone usage)" -ForegroundColor Gray New-Package -Generator 'ZIP' -OutputPath $OutputDir } diff --git a/scripts/test-all.ps1 b/scripts/test-all.ps1 new file mode 100644 index 000000000..4d52f5ce2 --- /dev/null +++ b/scripts/test-all.ps1 @@ -0,0 +1,75 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$scriptRoot = $PSScriptRoot + +$steps = @( + @{ Name = 'Build and package artifacts'; Script = Join-Path $scriptRoot 'package.ps1' }, + @{ Name = 'Build and run unit tests'; Script = Join-Path $scriptRoot 'test-unit.ps1' }, + @{ Name = 'Run ZIP (CMake) integration test'; Script = Join-Path $scriptRoot 'test-cmake.ps1' }, + @{ Name = 'Run NuGet integration test'; Script = Join-Path $scriptRoot 'test-nuget.ps1' } + @{ Name = 'Run Conan integration test'; Script = Join-Path $scriptRoot 'test-conan.ps1' } +) + +function Invoke-TestStep { + param( + [Parameter(Mandatory = $true)] + [int]$Index, + + [Parameter(Mandatory = $true)] + [int]$Total, + + [Parameter(Mandatory = $true)] + [hashtable]$Step + ) + + Write-Host ("[{0}/{1}] {2}" -f $Index, $Total, $Step.Name) -ForegroundColor Cyan + + if ($VerbosePreference -eq 'Continue') { + & $Step.Script + if ($LASTEXITCODE -ne 0) { + throw "Step failed with exit code ${LASTEXITCODE}: $($Step.Name)" + } + + Write-Host ' OK' -ForegroundColor Green + return + } + + $output = @(& $Step.Script *>&1) + $exitCode = $LASTEXITCODE + + if ($exitCode -ne 0) { + $messages = @( + $output | + ForEach-Object { $_.ToString() } | + Where-Object { $_ -match '(?i)error|failed|exception|fatal' } + ) + + Write-Host ' FAILED' -ForegroundColor Red + if ($messages.Count -gt 0) { + $messages | Select-Object -Unique | ForEach-Object { Write-Host " $_" -ForegroundColor Red } + } + else { + $output | + ForEach-Object { $_.ToString() } | + Select-Object -Last 10 | + ForEach-Object { Write-Host " $_" -ForegroundColor Red } + } + + throw "Step failed with exit code ${exitCode}: $($Step.Name). Re-run with -Verbose for full logs." + } + + Write-Host ' OK' -ForegroundColor Green +} + +Write-Host "Starting local validation..." -ForegroundColor Yellow +Write-Host "Use -Verbose to show full command output." -ForegroundColor DarkGray + +for ($i = 0; $i -lt $steps.Count; $i++) { + Invoke-TestStep -Index ($i + 1) -Total $steps.Count -Step $steps[$i] +} + +Write-Host "All steps completed successfully." -ForegroundColor Green diff --git a/scripts/test-cmake.ps1 b/scripts/test-cmake.ps1 new file mode 100644 index 000000000..f3b74a62b --- /dev/null +++ b/scripts/test-cmake.ps1 @@ -0,0 +1,64 @@ +param ( + [switch]$NoRun # Optional flag to disable running the application at the end +) + +# 0. Get the script's directory +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +# 1. Read the version +$VersionFilePath = Join-Path $ScriptDir "..\version\VERSION" +$WisdomVersion = (Get-Content $VersionFilePath).Trim() +Write-Host "Automated testing for Wisdom ZIP Package v$WisdomVersion" -ForegroundColor Cyan + +# 2. Find the generated ZIP file +$ArtifactsDir = Join-Path $ScriptDir "..\artifacts" +$ZipFile = Get-ChildItem -Path $ArtifactsDir -Filter "wisdom-*$WisdomVersion*.zip" | Select-Object -First 1 +if (-Not $ZipFile) { + Write-Error "Could not find the generated .zip package in $ArtifactsDir" + exit 1 +} + +# 3. Unzip the package +$ExtractDir = Join-Path $ScriptDir "..\tests\integration\cmake\extracted" +if (Test-Path $ExtractDir) { Remove-Item -Recurse -Force $ExtractDir } +Write-Host "Extracting $($ZipFile.Name) to $ExtractDir..." +Expand-Archive -Path $ZipFile.FullName -DestinationPath $ExtractDir + +# CPack usually puts everything inside a subfolder inside the ZIP (e.g., wisdom-0.7.0-win64) +$ExtractedRoot = Get-ChildItem -Path $ExtractDir | Select-Object -First 1 + +# 4. Configure the test project using CMake +Write-Host "Configuring Test App via CMake..." +# We pass CMAKE_PREFIX_PATH so find_package() knows exactly where to look +$CmakeInputDir = Join-Path $ScriptDir "..\tests\integration\cmake" +$CmakeBuildDir = Join-Path $ScriptDir "..\tests\integration\cmake\build" +cmake -S $CmakeInputDir -B $CmakeBuildDir -DCMAKE_PREFIX_PATH="$($ExtractedRoot.FullName)" + +# 5. Build the test project +Write-Host "Building Test App..." +cmake --build $CmakeBuildDir --config Release + +if ($LASTEXITCODE -ne 0) { + Write-Error "ZIP integration test failed to compile!" + exit 1 +} + + +if ($NoRun) { + Write-Host "Skipping execution of Test App due to -NoRun flag..." -ForegroundColor Cyan +} else { + # 6. Run the compiled executable + # NOTE: Because it's a dynamic build, Windows needs to find wisdom-shared.dll. + # We temporarily add the extracted /bin folder to the environment PATH just for this run. + $env:PATH = "$($ExtractedRoot.FullName)\bin;$env:PATH" + + Write-Host "Running Test App..." + & (Join-Path $CmakeBuildDir "Release\TestApp.exe") + Write-Host "Running Test App..." + & (Join-Path $CmakeBuildDir "Release\TestAppShared.exe") + Write-Host "Running Test App..." + & (Join-Path $CmakeBuildDir "Release\TestAppHeaders.exe") +} + + +Write-Host "ZIP packaging completely validated!" -ForegroundColor Green diff --git a/scripts/test-conan.ps1 b/scripts/test-conan.ps1 new file mode 100644 index 000000000..cea8a91aa --- /dev/null +++ b/scripts/test-conan.ps1 @@ -0,0 +1,10 @@ +# 0. Get the script's directory +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$TestDir = Join-Path $ScriptDir "..\tests\integration\conan" +$BaseDir = Join-Path $ScriptDir "\.." + +# 1. Test Static +conan create $BaseDir --build=missing + +# 2. Test Shared +conan create $BaseDir -o "wisdom/*:shared=True" diff --git a/scripts/test-nuget.ps1 b/scripts/test-nuget.ps1 new file mode 100644 index 000000000..c0dff0e0c --- /dev/null +++ b/scripts/test-nuget.ps1 @@ -0,0 +1,63 @@ +param ( + [switch]$NoRun # Optional flag to disable running the application at the end +) + +# 0. Get the script's directory +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +# 1. Read the version dynamically from your repository's VERSION file +$VersionFilePath = Join-Path $ScriptDir "..\version\VERSION" +if (-Not (Test-Path $VersionFilePath)) { + Write-Error "Could not find VERSION file at $VersionFilePath" + exit 1 +} + +$WisdomVersion = (Get-Content $VersionFilePath).Trim() +Write-Host "Automated testing for Wisdom NuGet Package v$WisdomVersion" -ForegroundColor Cyan + +# 1.5 Clear the output directory before building +$GlobalCachePath = "$env:USERPROFILE\.nuget\packages\wisdom\$WisdomVersion" +if (Test-Path $GlobalCachePath) { + Write-Host "Purging outdated v$WisdomVersion from global NuGet cache..." -ForegroundColor Yellow + Remove-Item -Path $GlobalCachePath -Recurse -Force +} + +# 2. Restore the NuGet package from your local feed, passing the version variable +Write-Host "Restoring NuGet packages..." +$VcxprojPath = Join-Path $ScriptDir "..\tests\integration\nuget\test.vcxproj" +msbuild $VcxprojPath -t:restore -p:RestorePackagesConfig=true /p:WisdomPackageVersion=$WisdomVersion + +$Linkages = @("dynamic", "static", "headers") + +foreach ($Linkage in $Linkages) { + Write-Host "`n--- Testing Linkage: $Linkage ---" -ForegroundColor Cyan + + # 3. Build the project using MSBuild + Write-Host "Building Test App ($Linkage)..." + msbuild $VcxprojPath /p:Configuration=Release /p:Platform=x64 /p:WisdomPackageVersion=$WisdomVersion /p:WisdomLinkage=$Linkage + + # 4. Verify the build succeeded + if ($LASTEXITCODE -ne 0) { + Write-Error "Integration test failed to compile for $Linkage linkage!" + exit 1 + } + + # 5. Verify your .targets file successfully copied the DLL (only for shared linkage) + if ($Linkage -eq "shared") { + $DllPath = Join-Path $ScriptDir "..\tests\integration\nuget\x64\Release\wisdom-shared.dll" + if (-Not (Test-Path $DllPath)) { + Write-Error "DLL was not copied to the output directory! Check your .targets DeploymentContent." + exit 1 + } + } + + # 6. Run the compiled executable + if ($NoRun) { + Write-Host "Skipping execution of Test App due to -NoRun flag..." -ForegroundColor Cyan + } else { + Write-Host "Running Test App ($Linkage)..." + & (Join-Path $ScriptDir "..\tests\integration\nuget\x64\Release\test.exe") + } +} + +Write-Host "`nNuGet packaging completely validated for v$WisdomVersion!" -ForegroundColor Green diff --git a/scripts/test-unit.ps1 b/scripts/test-unit.ps1 new file mode 100644 index 000000000..8d6a969c5 --- /dev/null +++ b/scripts/test-unit.ps1 @@ -0,0 +1,108 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$workspaceRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path +$buildDir = Join-Path $workspaceRoot 'build/msvc-debug-tests' + +function Initialize-VSEnvironment { + Write-Host 'Initializing Visual Studio environment...' -ForegroundColor Cyan + + $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (-not (Test-Path $vsWhere)) { + throw 'Visual Studio not found. Please install Visual Studio with C++ workload.' + } + + $vsPath = & $vsWhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + if (-not $vsPath) { + throw 'Visual Studio with C++ tools not found.' + } + + $vcvarsPath = Join-Path $vsPath 'VC\Auxiliary\Build\vcvars64.bat' + if (-not (Test-Path $vcvarsPath)) { + throw "vcvars64.bat not found at: $vcvarsPath" + } + + $env:PATH = ($env:PATH -split ';' | Where-Object { $_ -notmatch 'Strawberry' }) -join ';' + + $envBlock = cmd /c "`"$vcvarsPath`" >nul 2>&1 && set" + foreach ($line in $envBlock) { + if ($line -match '^([^=]+)=(.*)$') { + [Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process') + } + } +} + +function Invoke-ExternalCommand { + param( + [Parameter(Mandatory = $true)] + [string]$FilePath, + + [Parameter(Mandatory = $true)] + [string[]]$Arguments, + + [Parameter(Mandatory = $true)] + [string]$ActionName + ) + + if ($VerbosePreference -eq 'Continue') { + & $FilePath @Arguments + $exitCode = $LASTEXITCODE + if ($exitCode -ne 0) { + throw "$ActionName failed with exit code $exitCode" + } + + return + } + + $output = @(& $FilePath @Arguments *>&1) + $exitCode = $LASTEXITCODE + + if ($exitCode -ne 0) { + $messages = @( + $output | + ForEach-Object { $_.ToString() } | + Where-Object { $_ -match '(?i)error|failed|exception|fatal' } + ) + + if ($messages.Count -gt 0) { + $messages | Select-Object -Unique | ForEach-Object { Write-Host " $_" -ForegroundColor Red } + } + else { + $output | + ForEach-Object { $_.ToString() } | + Select-Object -Last 10 | + ForEach-Object { Write-Host " $_" -ForegroundColor Red } + } + + throw "$ActionName failed with exit code $exitCode. Re-run with -Verbose for full logs." + } +} + +Write-Host 'Starting unit tests...' -ForegroundColor Yellow +Write-Host 'Use -Verbose to show full command output.' -ForegroundColor DarkGray + +Initialize-VSEnvironment + +Write-Host '[1/3] Configure unit test build' -ForegroundColor Cyan +Invoke-ExternalCommand -FilePath 'cmake' -Arguments @( + '-S', $workspaceRoot, + '-B', $buildDir, + '-G', 'Ninja', + '-DCMAKE_BUILD_TYPE=Debug', + '-DWISDOM_BUILD_TESTS=ON', + '-DWISDOM_BUILD_EXAMPLES=OFF' +) -ActionName 'CMake configure' +Write-Host ' OK' -ForegroundColor Green + +Write-Host '[2/3] Build unit tests' -ForegroundColor Cyan +Invoke-ExternalCommand -FilePath 'cmake' -Arguments @('--build', $buildDir) -ActionName 'CMake build' +Write-Host ' OK' -ForegroundColor Green + +Write-Host '[3/3] Run unit tests' -ForegroundColor Cyan +Invoke-ExternalCommand -FilePath 'ctest' -Arguments @('--test-dir', $buildDir, '--output-on-failure') -ActionName 'CTest run' +Write-Host ' OK' -ForegroundColor Green + +Write-Host 'Unit tests completed successfully.' -ForegroundColor Green diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1248abfa..0db81f93f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,3 +4,5 @@ add_subdirectory(include) if(WISDOM_BUILD_PLATFORM) add_subdirectory(platform) endif() + +add_subdirectory(extensions) diff --git a/src/extensions/CMakeLists.txt b/src/extensions/CMakeLists.txt new file mode 100644 index 000000000..a99b6e2ae --- /dev/null +++ b/src/extensions/CMakeLists.txt @@ -0,0 +1,4 @@ +# Each extension will provide an option to build it + +# Extensions option(WISDOM_BUILD_EXTENSION "Build the X extension." ON) if +# (WISDOM_BUILD_EXTENSION) add_subdirectory(extension) endif() diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt index 208071b4f..7840f7a63 100644 --- a/src/include/CMakeLists.txt +++ b/src/include/CMakeLists.txt @@ -8,14 +8,7 @@ set(WISDOM_CORE_DEFINITIONS $:WISDOM_VULKAN=1>>) if(WISDOM_DX12) - list( - APPEND - WISDOM_CORE_LIBS - DXGI - DXGUID - d3d12 - DX12Allocator - DX12Agility) + list(APPEND WISDOM_CORE_LIBS DXGI DXGUID d3d12 GPUOpen::D3D12MemoryAllocator) list( APPEND @@ -117,7 +110,6 @@ if(WISDOM_BUILD_SHARED) wisdom-shared PROPERTIES CXX_STANDARD 20 POSITION_INDEPENDENT_CODE ON - # UNITY_BUILD ON DEBUG_POSTFIX d) include(GenerateExportHeader) diff --git a/src/include/wisdom/bridge/format.hpp b/src/include/wisdom/bridge/format.hpp deleted file mode 100644 index e68cad3a4..000000000 --- a/src/include/wisdom/bridge/format.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef WIS_BRIDGE_FORMAT_H -#define WIS_BRIDGE_FORMAT_H -#if defined(WISDOM_USE_FMT) -# include -namespace wis { -using fmt::format; // NOLINT -using fmt::format_to; // NOLINT -using fmt::make_format_args; // NOLINT -using fmt::vformat; // NOLINT -} // namespace wis -#elif __has_include() -# include -namespace wis { -using std::format; -using std::format_to; -using std::make_format_args; -using std::vformat; -} // namespace wis -#else -# error "wisdom requires fmt or std::format" -#endif -#endif // WISDOM_BRIDGE_FORMAT_H diff --git a/src/include/wisdom/dx12/detail/dx12_detail.hpp b/src/include/wisdom/dx12/detail/dx12_detail.hpp index 53db8267e..262d5ad8b 100644 --- a/src/include/wisdom/dx12/detail/dx12_detail.hpp +++ b/src/include/wisdom/dx12/detail/dx12_detail.hpp @@ -6,11 +6,10 @@ #include #include +#include #include #include -#include - #include #include @@ -242,6 +241,266 @@ inline constexpr uint32_t DX12GetCopyPlaneSlice(WisBarrierFlags flags, uint16_t return 0u; } +//---------------------------------------------------------------------------------------------------------------------- +// Barrier helper constants +constexpr static uint32_t dx12_max_barrier_size = std::max( + {sizeof(D3D12_BUFFER_BARRIER), sizeof(D3D12_TEXTURE_BARRIER), sizeof(D3D12_GLOBAL_BARRIER)} +); +constexpr static uint32_t dx12_static_size = wis::TransientMaxBarrierCount * dx12_max_barrier_size; + +template +inline uint8_t* DX12AllocateScratchSpace(const Impl& impl, uint32_t new_size) +{ + if (new_size > impl.scratch_memory_size) { + delete[] impl.scratch_memory; + impl.scratch_memory = new (std::nothrow) uint8_t[new_size]; + impl.scratch_memory_size = impl.scratch_memory ? new_size : 0; + } + return impl.scratch_memory; +} + +template +inline std::array, 3> DX12AllocateBarriers( + const Impl& impl, + uint8_t* local_scratch, + const WisDX12BarrierGroup& barriers +) +{ + std::array, 3> spans; + std::size_t needed_size = barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER) + + barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER) + + barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER); + + if (needed_size <= dx12_static_size) { + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + } + + std::size_t sizes[] = { + barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER), + barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER), + barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER), + 0, + 0, + 0 + }; + + sizes[3] = sizes[0] + sizes[1]; + sizes[4] = sizes[1] + sizes[2]; + sizes[5] = sizes[0] + sizes[2]; + + uint32_t closest_size = 0; + int index = -1; + for (int i = std::size(sizes) - 1; i >= 0; --i) { + if (sizes[i] > dx12_static_size) { + continue; + } + if (dx12_static_size - sizes[i] < dx12_static_size - closest_size) { + closest_size = sizes[i]; + index = i; + } + } + + uint32_t allocated_size = needed_size - closest_size; + auto* allocated_data = DX12AllocateScratchSpace(impl, allocated_size); + + switch (index) { + default: + case -1: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 0: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 1: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 2: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {local_scratch, barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 3: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {allocated_data, barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 4: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + case 5: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; + spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; + spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; + return spans; + } +} + +inline constexpr D3D12_BARRIER_LAYOUT DX12GetOptimalBarrierLayout( + WisCommandQueueType type, + WisTextureState state +) noexcept +{ + switch (type) { + case WisCommandQueueTypeGraphics: + switch (state) { + case WisTextureStateCommon: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON; + case WisTextureStateRead: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ; + case WisTextureStateUnorderedAccess: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS; + case WisTextureStateShaderResource: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE; + case WisTextureStateCopySrc: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE; + case WisTextureStateCopyDst: + return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST; + default: + return wis::detail::DX12Convert(state); + } + case WisCommandQueueTypeCompute: + switch (state) { + case WisTextureStateCommon: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON; + case WisTextureStateRead: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ; + case WisTextureStateUnorderedAccess: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS; + case WisTextureStateShaderResource: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE; + case WisTextureStateCopySrc: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE; + case WisTextureStateCopyDst: + return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST; + default: + return wis::detail::DX12Convert(state); + } + default: + return wis::detail::DX12Convert(state); + } +} + +template +inline void DX12InsertBarriers( + const Impl& impl, + List* list, + const WisDX12BarrierGroup* barriers, + WisCommandQueueType queue_type +) +{ + if (barriers->buffer_barrier_count + barriers->texture_barrier_count + barriers->global_barrier_count == 0) { + return; + } + + uint8_t local_scratch[dx12_static_size]{}; + + auto [buffer_span, texture_span, global_span] = DX12AllocateBarriers(impl, local_scratch, *barriers); + + wis::span buffer_barriers_span{ + reinterpret_cast(buffer_span.data()), + barriers->buffer_barrier_count + }; + uint32_t real_buffer_barrier_count = barriers->buffer_barrier_count; + + for (size_t i = 0; i < barriers->buffer_barrier_count; ++i) { + auto& src = barriers->buffer_barriers[i]; + + if (src.queue_type_after != src.queue_type_before) { + real_buffer_barrier_count--; + continue; + } + + buffer_barriers_span[i] = D3D12_BUFFER_BARRIER{ + .SyncBefore = DX12Convert(src.sync_before), + .SyncAfter = DX12Convert(src.sync_after), + .AccessBefore = DX12Convert(src.access_before), + .AccessAfter = DX12Convert(src.access_after), + .pResource = std::bit_cast(src.buffer), + .Offset = src.offset, + .Size = src.size, + }; + } + + wis::span texture_barriers_span{ + reinterpret_cast(texture_span.data()), + barriers->texture_barrier_count + }; + for (size_t i = 0; i < barriers->texture_barrier_count; ++i) { + auto& src = barriers->texture_barriers[i]; + + bool qfot_barrier = src.queue_type_after != src.queue_type_before; + bool acquire_barrier = qfot_barrier && src.queue_type_after == queue_type; + bool release_barrier = qfot_barrier && src.queue_type_before == queue_type; + + auto layout_before = DX12GetOptimalBarrierLayout( + queue_type, + acquire_barrier ? WisTextureStateCommon : src.state_before + ); + auto layout_after = DX12GetOptimalBarrierLayout( + queue_type, + release_barrier ? WisTextureStateCommon : src.state_after + ); + + texture_barriers_span[i] = D3D12_TEXTURE_BARRIER{ + .SyncBefore = DX12Convert(src.sync_before), + .SyncAfter = DX12Convert(src.sync_after), + .AccessBefore = DX12Convert(src.access_before), + .AccessAfter = DX12Convert(src.access_after), + .LayoutBefore = layout_before, + .LayoutAfter = layout_after, + .pResource = std::bit_cast(src.texture), + .Subresources = + { + .IndexOrFirstMipLevel = src.subresource_range.base_mip_level, + .NumMipLevels = src.subresource_range.mip_level_count, + .FirstArraySlice = src.subresource_range.base_array_layer, + .NumArraySlices = src.subresource_range.array_layer_count, + .FirstPlane = src.flags & WisBarrierFlagsPlanarImage ? src.subresource_range.plane_slice : 0u, + .NumPlanes = src.flags & WisBarrierFlagsPlanarImage ? src.subresource_range.plane_slice_count : 1u, + }, + .Flags = src.state_before == WisTextureStateUndefined ? D3D12_TEXTURE_BARRIER_FLAG_DISCARD + : D3D12_TEXTURE_BARRIER_FLAG_NONE, + }; + } + + wis::span global_barriers_span{ + reinterpret_cast(global_span.data()), + barriers->global_barrier_count + }; + for (size_t i = 0; i < barriers->global_barrier_count; ++i) { + auto& src = barriers->global_barriers[i]; + global_barriers_span[i] = D3D12_GLOBAL_BARRIER{ + .SyncBefore = DX12Convert(src.sync_before), + .SyncAfter = DX12Convert(src.sync_after), + .AccessBefore = DX12Convert(src.access_before), + .AccessAfter = DX12Convert(src.access_after), + }; + } + + D3D12_BARRIER_GROUP groups[]{ + {.Type = D3D12_BARRIER_TYPE_BUFFER, + .NumBarriers = real_buffer_barrier_count, + .pBufferBarriers = buffer_barriers_span.data()}, + {.Type = D3D12_BARRIER_TYPE_TEXTURE, + .NumBarriers = static_cast(barriers->texture_barrier_count), + .pTextureBarriers = texture_barriers_span.data()}, + {.Type = D3D12_BARRIER_TYPE_GLOBAL, + .NumBarriers = static_cast(barriers->global_barrier_count), + .pGlobalBarriers = global_barriers_span.data()} + }; + list->Barrier(std::size(groups), groups); +} } // namespace wis::detail #endif // WIS_DX12_DETAIL_HPP diff --git a/src/include/wisdom/dx12/dx12_command_list.cpp b/src/include/wisdom/dx12/dx12_command_list.cpp index 20838baf3..c8c1684e1 100644 --- a/src/include/wisdom/dx12/dx12_command_list.cpp +++ b/src/include/wisdom/dx12/dx12_command_list.cpp @@ -10,22 +10,9 @@ #include #include -namespace wis::detail { -constexpr static uint32_t dx12_max_barrier_size = std::max( - {sizeof(D3D12_BUFFER_BARRIER), sizeof(D3D12_TEXTURE_BARRIER), sizeof(D3D12_GLOBAL_BARRIER)} -); -constexpr static uint32_t dx12_static_size = wis::TransientMaxBarrierCount * dx12_max_barrier_size; - -inline uint8_t* DX12AllocateScratchSpace(const wis::impl::DX12CommandListImpl& impl, uint32_t new_size) -{ - if (new_size > impl.scratch_memory_size) { - delete[] impl.scratch_memory; - impl.scratch_memory = new (std::nothrow) uint8_t[new_size]; - impl.scratch_memory_size = impl.scratch_memory ? new_size : 0; - } - return impl.scratch_memory; -} +// Barrier helper functions moved to wis::detail in dx12_detail.hpp +namespace wis::detail { inline D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS* DX12AllocateRPSpace( const wis::impl::DX12CommandListImpl& impl, uint32_t new_size @@ -39,148 +26,6 @@ inline D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS* DX12Alloc } return impl.render_pass_memory; } - -inline constexpr D3D12_BARRIER_LAYOUT DX12GetOptimalBarrierLayout( - WisCommandQueueType type, - WisTextureState state -) noexcept -{ - switch (type) { - case WisCommandQueueTypeGraphics: - switch (state) { - case WisTextureStateCommon: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON; - case WisTextureStateRead: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ; - case WisTextureStateUnorderedAccess: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS; - case WisTextureStateShaderResource: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE; - case WisTextureStateCopySrc: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE; - case WisTextureStateCopyDst: - return D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST; - default: - return wis::detail::DX12Convert(state); - } - case WisCommandQueueTypeCompute: - switch (state) { - case WisTextureStateCommon: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON; - case WisTextureStateRead: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ; - case WisTextureStateUnorderedAccess: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS; - case WisTextureStateShaderResource: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE; - case WisTextureStateCopySrc: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE; - case WisTextureStateCopyDst: - return D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST; - default: - return wis::detail::DX12Convert(state); - } - default: - return wis::detail::DX12Convert(state); - } -} - -inline std::array, 3> DX12AllocateBarriers( - const wis::impl::DX12CommandListImpl& impl, - uint8_t* local_scratch, - const WisDX12BarrierGroup& barriers -) -{ - std::array, 3> spans; - std::size_t needed_size = barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER) - + barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER) - + barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER); - - if (needed_size <= dx12_static_size) { - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - } - - std::size_t sizes[] = { - barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER), - barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER), - barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER), - 0, - 0, - 0 - }; - - sizes[3] = sizes[0] + sizes[1]; - sizes[4] = sizes[1] + sizes[2]; - sizes[5] = sizes[0] + sizes[2]; - - // find closest value from below - uint32_t closest_size = 0; - int index = -1; - for (int i = std::size(sizes) - 1; i >= 0; --i) { - if (sizes[i] > dx12_static_size) { - continue; - } - - // less than or equal to static size, check if it's the closest one - if (dx12_static_size - sizes[i] < dx12_static_size - closest_size) { - closest_size = sizes[i]; - index = i; - } - } - - uint32_t allocated_size = needed_size - closest_size; - - // allocate from the command list's scratch memory if the needed size exceeds the local scratch buffer size. This is - // to avoid large stack allocations. - auto* allocated_data = wis::detail::DX12AllocateScratchSpace(impl, allocated_size); - - // set pointers to the right offsets in the allocated scratch memory - switch (index) { - default: - case -1: - // no single group can fit into the local scratch, allocate all from the command list's scratch memory - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 0: - // buffer barriers fit into local scratch, texture and global barriers allocated from command list's scratch - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 1: - // texture barriers fit into local scratch, buffer and global barriers allocated from command list's scratch - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 2: - // global barriers fit into local scratch, buffer and texture barriers allocated from command list's scratch - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {local_scratch, barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 3: - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {allocated_data, barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 4: - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - case 5: - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(D3D12_BUFFER_BARRIER)}; - spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(D3D12_TEXTURE_BARRIER)}; - spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(D3D12_GLOBAL_BARRIER)}; - return spans; - } -} } // namespace wis::detail //---------------------------------------------------------------------------------------------------------------------- @@ -373,119 +218,8 @@ WIS_EXTERN_C WISDOM_API void wisDX12CommandListInsertBarriers( const WisDX12BarrierGroup* barriers ) { - // clang-format off - if (barriers->buffer_barrier_count + - barriers->texture_barrier_count + - barriers->global_barrier_count == 0) { - return; - } - // clang-format on - auto& impl = wis::from_handle_ref(self); - - constexpr static uint32_t max_barrier_size = std::max(sizeof(D3D12_BUFFER_BARRIER), sizeof(D3D12_TEXTURE_BARRIER)); - constexpr static uint32_t static_size = static_cast(wis::TransientMaxBarrierCount * max_barrier_size); - uint8_t local_scratch[static_size]{}; - - auto [buffer_span, texture_span, global_span] = wis::detail::DX12AllocateBarriers(impl, local_scratch, *barriers); - - wis::span buffer_barriers_span{ - reinterpret_cast(buffer_span.data()), - barriers->buffer_barrier_count - }; - uint32_t real_buffer_barrier_count = barriers->buffer_barrier_count; - // convert buffer barriers - for (size_t i = 0; i < barriers->buffer_barrier_count; ++i) { - auto& src = barriers->buffer_barriers[i]; - - // skip barriers that only perform queue ownership transfer without any actual synchronization or access - // changes, as they don't require an explicit barrier in D3D12 and can be handled implicitly by the driver. - if (src.queue_type_after != src.queue_type_before) { - real_buffer_barrier_count--; - continue; - } - - buffer_barriers_span[i] = D3D12_BUFFER_BARRIER{ - .SyncBefore = wis::detail::DX12Convert(src.sync_before), - .SyncAfter = wis::detail::DX12Convert(src.sync_after), - .AccessBefore = wis::detail::DX12Convert(src.access_before), - .AccessAfter = wis::detail::DX12Convert(src.access_after), - .pResource = std::bit_cast(src.buffer), - .Offset = src.offset, - .Size = src.size, - }; - } - - // convert texture barriers - wis::span texture_barriers_span{ - reinterpret_cast(texture_span.data()), - barriers->texture_barrier_count - }; - for (size_t i = 0; i < barriers->texture_barrier_count; ++i) { - auto& src = barriers->texture_barriers[i]; - - bool qfot_barrier = src.queue_type_after != src.queue_type_before; - bool acquire_barrier = qfot_barrier && src.queue_type_after == impl.queue_type; - bool release_barrier = qfot_barrier && src.queue_type_before == impl.queue_type; - - auto layout_before = wis::detail::DX12GetOptimalBarrierLayout( - impl.queue_type, - acquire_barrier ? WisTextureStateCommon : src.state_before - ); - auto layout_after = wis::detail::DX12GetOptimalBarrierLayout( - impl.queue_type, - release_barrier ? WisTextureStateCommon : src.state_after - ); - - texture_barriers_span[i] = D3D12_TEXTURE_BARRIER{ - .SyncBefore = wis::detail::DX12Convert(src.sync_before), - .SyncAfter = wis::detail::DX12Convert(src.sync_after), - .AccessBefore = wis::detail::DX12Convert(src.access_before), - .AccessAfter = wis::detail::DX12Convert(src.access_after), - .LayoutBefore = layout_before, - .LayoutAfter = layout_after, - .pResource = std::bit_cast(src.texture), - .Subresources = - { - .IndexOrFirstMipLevel = src.subresource_range.base_mip_level, - .NumMipLevels = src.subresource_range.mip_level_count, - .FirstArraySlice = src.subresource_range.base_array_layer, - .NumArraySlices = src.subresource_range.array_layer_count, - .FirstPlane = src.flags & WisBarrierFlagsPlanarImage ? src.subresource_range.plane_slice : 0u, - .NumPlanes = src.flags & WisBarrierFlagsPlanarImage ? src.subresource_range.plane_slice_count : 1u, - }, - .Flags = src.state_before == WisTextureStateUndefined ? D3D12_TEXTURE_BARRIER_FLAG_DISCARD - : D3D12_TEXTURE_BARRIER_FLAG_NONE, - }; - } - - // convert global barriers - wis::span global_barriers_span{ - reinterpret_cast(global_span.data()), - barriers->global_barrier_count - }; - for (size_t i = 0; i < barriers->global_barrier_count; ++i) { - auto& src = barriers->global_barriers[i]; - global_barriers_span[i] = D3D12_GLOBAL_BARRIER{ - .SyncBefore = wis::detail::DX12Convert(src.sync_before), - .SyncAfter = wis::detail::DX12Convert(src.sync_after), - .AccessBefore = wis::detail::DX12Convert(src.access_before), - .AccessAfter = wis::detail::DX12Convert(src.access_after), - }; - } - - D3D12_BARRIER_GROUP groups[]{ - {.Type = D3D12_BARRIER_TYPE_BUFFER, - .NumBarriers = real_buffer_barrier_count, - .pBufferBarriers = buffer_barriers_span.data()}, - {.Type = D3D12_BARRIER_TYPE_TEXTURE, - .NumBarriers = static_cast(barriers->texture_barrier_count), - .pTextureBarriers = texture_barriers_span.data()}, - {.Type = D3D12_BARRIER_TYPE_GLOBAL, - .NumBarriers = static_cast(barriers->global_barrier_count), - .pGlobalBarriers = global_barriers_span.data()} - }; - impl.list->Barrier(std::size(groups), groups); + wis::detail::DX12InsertBarriers(impl, impl.list, barriers, impl.queue_type); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/include/wisdom/dx12/dx12_descriptor_heap.cpp b/src/include/wisdom/dx12/dx12_descriptor_heap.cpp index 14870eaae..aac4e712f 100644 --- a/src/include/wisdom/dx12/dx12_descriptor_heap.cpp +++ b/src/include/wisdom/dx12/dx12_descriptor_heap.cpp @@ -626,6 +626,28 @@ WIS_EXTERN_C WISDOM_API uint64_t wisDX12ViewHeapWriteDepthStencil( return descriptor_handle.ptr; } +//---------------------------------------------------------------------------------------------------------------------- +WIS_EXTERN_C WISDOM_API uint64_t wisDX12ViewHeapWriteVideoDecodeTarget( + const WisDX12ViewHeap* self, + const WisDX12Texture* texture, + const WisRenderTargetDesc* render_target, + uint32_t index +) +{ + auto& heap = wis::from_handle_ref(self); + auto& tex = wis::from_handle_ref(texture); + if (!heap.aux_data) { + return 0; + } + + auto& aux = heap.aux_data[index]; + aux.handle = {0}; + aux.resource = tex.resource; + aux.format = static_cast(wis::detail::DX12Convert(render_target->format)); + wis::detail::DX12FillRTVAuxData(aux, *render_target, tex.resource->GetDesc(), render_target->plane_slice, false); + return wis::detail::DX12EncodeViewAddress(&aux); +} + //---------------------------------------------------------------------------------------------------------------------- WIS_EXTERN_C WISDOM_API uint64_t wisDX12ViewHeapGetViewAddress(const WisDX12ViewHeap* self, uint32_t index) { @@ -659,6 +681,14 @@ WIS_EXTERN_C WISDOM_API void wisDX12ViewHeapCopyViews( {src_handle_ptr}, heap.type ); + + // copy aux data if present + if (heap.aux_data) { + auto* dst_aux_base = heap.aux_data + dst_index; + if (auto* src_aux_base = wis::detail::DX12DecodeViewAddress(src_ptr)) { + std::copy_n(src_aux_base + src_index, count, dst_aux_base); + } + } } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/include/wisdom/dx12/dx12_device.cpp b/src/include/wisdom/dx12/dx12_device.cpp index 9a23fc6a1..bf5eb8e72 100644 --- a/src/include/wisdom/dx12/dx12_device.cpp +++ b/src/include/wisdom/dx12/dx12_device.cpp @@ -1,7 +1,6 @@ #ifndef WIS_DX12_DEVICE_CPP #define WIS_DX12_DEVICE_CPP -#include #include #include #include @@ -10,7 +9,11 @@ #include #include -#include +#ifdef DX12SDKVER +# include +#else +# include +#endif #include #include @@ -471,9 +474,9 @@ WIS_EXTERN_C WISDOM_API void wisDX12DeviceQueryProperties(const WisDX12Device* s if (wis::detail::succeeded( device.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &options16, sizeof(options16)) )) { + props->gpu_upload_supported = options16.GPUUploadHeapSupported; props->host_image_copy_supported = options16.GPUUploadHeapSupported; - props->supported_initial_transitions = 0b0001'1111'1111'1111; // All thansitions are supported } } break; case WisQueryPropertyTypeDeviceBindingProperties: { @@ -650,7 +653,8 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12DeviceCreateComputePipeline( wis::com_ptr pipeline_state; // Calculate hash of pipeline state description for caching purposes - wchar_t name_buffer[256] = {}; + static constexpr std::size_t hash_input_size = 256; + wchar_t name_buffer[hash_input_size] = {}; if (cache) { // Get root signature hash @@ -670,7 +674,7 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12DeviceCreateComputePipeline( XXH128_hash_t pso_hash = XXH3_128bits(rehash_input, sizeof(rehash_input)); // convert hash to hex string for use as pipeline cache key - wis::format_to(name_buffer, L"CPSO_{:016x}{:016x}", pso_hash.low64, pso_hash.high64); + std::swprintf(name_buffer, hash_input_size, L"CPSO_%016llx%016llx", pso_hash.low64, pso_hash.high64); // Try to load pipeline from cache first if available HRESULT hr = cache->LoadPipeline( @@ -979,7 +983,8 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12DeviceCreateGraphicsPipeline( }; wis::com_ptr pipeline_state; - wchar_t name_buffer[128] = {}; + static constexpr std::size_t hash_input_size = 256; + wchar_t name_buffer[hash_input_size] = {}; if (cache) { uint32_t name_offset = 0; // max 7 struct RehashInput { @@ -1024,7 +1029,13 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12DeviceCreateGraphicsPipeline( XXH128_hash_t pso_hash = XXH3_128bits(&rehash_input, sizeof(rehash_input)); // convert hash to hex string for use as pipeline cache key - wis::format_to(name_buffer + name_offset, L"PSO_{:016x}{:016x}", pso_hash.low64, pso_hash.high64); + std::swprintf( + name_buffer + name_offset, + hash_input_size - name_offset, + L"PSO_%016llx%016llx", + pso_hash.low64, + pso_hash.high64 + ); // Try to load pipeline from cache first if available HRESULT hr = cache->LoadPipeline( diff --git a/src/include/wisdom/dx12/dx12_impl.cpp b/src/include/wisdom/dx12/dx12_impl.cpp index 44edcbc7d..43b6cfeca 100644 --- a/src/include/wisdom/dx12/dx12_impl.cpp +++ b/src/include/wisdom/dx12/dx12_impl.cpp @@ -6,7 +6,11 @@ #include #include -#include +#ifdef DX12SDKVER +# include +#else +# include +#endif //---------------------------------------------------------------------------------------------------------------------- WIS_EXTERN_C WISDOM_API void wisDX12DestroyRootSignature(WisDX12RootSignature* self) diff --git a/src/include/wisdom/dx12/dx12_resource_allocator.cpp b/src/include/wisdom/dx12/dx12_resource_allocator.cpp index 72e0f4b8c..07f15e736 100644 --- a/src/include/wisdom/dx12/dx12_resource_allocator.cpp +++ b/src/include/wisdom/dx12/dx12_resource_allocator.cpp @@ -1,6 +1,7 @@ #ifndef WIS_DX12_RESOURCE_ALLOCATOR_CPP #define WIS_DX12_RESOURCE_ALLOCATOR_CPP +#include #include #include #include @@ -14,6 +15,7 @@ inline WisResult DX12CreateResource( const D3D12_RESOURCE_DESC1& res_desc, D3D12_BARRIER_LAYOUT initial_layout, D3D12MA::Allocator* allocator, + wis::span cast_formats, void* buffer ) noexcept { @@ -30,8 +32,8 @@ inline WisResult DX12CreateResource( &res_desc, initial_layout, nullptr, - 0, - nullptr, + static_cast(cast_formats.size()), + cast_formats.data(), allocation.put_unchecked(), resource.iid(), resource.put_void_unchecked() @@ -150,7 +152,14 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12ResourceAllocatorCreateBuffer( .Flags = wis::detail::DX12Convert(desc->memory_flags), .HeapType = wis::detail::DX12Convert(desc->memory_type), }; - return wis::detail::DX12CreateResource(all_desc, buffer_desc, D3D12_BARRIER_LAYOUT_UNDEFINED, allocator, buffer); + return wis::detail::DX12CreateResource( + all_desc, + buffer_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + allocator, + {}, + buffer + ); } //---------------------------------------------------------------------------------------------------------------------- @@ -166,7 +175,68 @@ WIS_EXTERN_C WISDOM_API WisResult wisDX12ResourceAllocatorCreateTexture( .Flags = wis::detail::DX12Convert(desc->memory_flags), .HeapType = wis::detail::DX12Convert(desc->memory_type), }; - return wis::detail::DX12CreateResource(all_desc, tex_desc, D3D12_BARRIER_LAYOUT_UNDEFINED, impl.allocator, buffer); + + // planar formats are uncastable + if (desc->format >= WisDataFormatNV12) { + return wis::detail::DX12CreateResource( + all_desc, + tex_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + impl.allocator, + {}, + buffer + ); + } + + static constexpr uint32_t max_cast_formats = 16; + DXGI_FORMAT cast_formats[max_cast_formats]; + wis::span cast_formats_span; + std::unique_ptr cast_formats_ptr; + + bool directly_mappable = true; + uint32_t format_index = 0; + for (; format_index < desc->cast_format_count; format_index++) { + auto format = desc->cast_formats[format_index]; + if (static_cast(format) >= 256) { + directly_mappable = false; + + if (desc->cast_format_count > max_cast_formats) { + cast_formats_ptr = std::make_unique(desc->cast_format_count); + cast_formats_span = {cast_formats_ptr.get(), desc->cast_format_count}; + } else { + cast_formats_span = {cast_formats, desc->cast_format_count}; + } + + // Copy the compatible formats into the span [0->format_index) + std::memcpy(cast_formats_span.data(), desc->cast_formats, format_index); + + // Convert the rest + for (uint32_t i = format_index; i < desc->cast_format_count; i++) { + cast_formats_span[i] = wis::detail::DX12Convert(desc->cast_formats[i]); + } + + break; + } + } + + if (directly_mappable) { + return wis::detail::DX12CreateResource( + all_desc, + tex_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + impl.allocator, + {reinterpret_cast(desc->cast_formats), desc->cast_format_count}, + buffer + ); + } + return wis::detail::DX12CreateResource( + all_desc, + tex_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + impl.allocator, + cast_formats_span, + buffer + ); } #endif // WIS_DX12_RESOURCE_ALLOCATOR_CPP diff --git a/src/include/wisdom/dx12/dx12_types.hpp b/src/include/wisdom/dx12/dx12_types.hpp index aa742d984..4e3739a7b 100644 --- a/src/include/wisdom/dx12/dx12_types.hpp +++ b/src/include/wisdom/dx12/dx12_types.hpp @@ -5,8 +5,6 @@ #endif // __cplusplus #include - -#include #include #include diff --git a/src/include/wisdom/generated/c_api.h b/src/include/wisdom/generated/c_api.h index 252179e92..27a008d61 100644 --- a/src/include/wisdom/generated/c_api.h +++ b/src/include/wisdom/generated/c_api.h @@ -615,6 +615,39 @@ typedef enum WisDataFormat { * a 4-bit A component in bits 12..15. * */ WisDataFormatBGRA4Unorm = 115, + /** + * @brief Provided by Wisdom 0.7.1. + * NV12 video format. + * A two-plane format with a single 8-bit Y plane followed by an interleaved UV plane, where the U and V components + * are subsampled by a factor of 2 in both dimensions. The Y plane contains the luma (brightness) information, while + * the UV plane contains the chroma (color) information. This format is commonly used for video encoding and + * decoding applications. + * */ + WisDataFormatNV12 = 256, + /** + * @brief Provided by Wisdom 0.7.1. + * P010 video format. + * A two-plane format similar to NV12, but with 10 bits per channel instead of 8. The Y plane contains 10-bit luma + * information, and the UV plane contains interleaved 10-bit chroma information. This format is used for + * high-quality video encoding and decoding, providing improved color fidelity compared to NV12. + * */ + WisDataFormatP010 = 257, + /** + * @brief Provided by Wisdom 0.7.1. + * P012 video format. + * A two-plane format similar to P010, but with 12 bits per channel instead of 10. The Y plane contains 12-bit luma + * information, and the UV plane contains interleaved 12-bit chroma information. This format is used for + * professional video applications that require higher color fidelity and dynamic range than P010. + * */ + WisDataFormatP012 = 258, + /** + * @brief Provided by Wisdom 0.7.1. + * P016 video format. + * A two-plane format similar to P010, but with 16 bits per channel instead of 10. The Y plane contains 16-bit luma + * information, and the UV plane contains interleaved 16-bit chroma information. This format is used for + * professional video applications that require the highest color fidelity and dynamic range. + * */ + WisDataFormatP016 = 259, } WisDataFormat; /** @@ -961,6 +994,11 @@ typedef enum WisTextureState { WisTextureStateVideoDecodeWrite = 14, ///< Video Decode Write state. WisTextureStateResolveDepthStensilDst = 15, ///< Depth Stencil Resolve Destination state. WisTextureStateResolveRenderTargetDst = 16, ///< Render Target Resolve Destination state. + /** + * @brief Video Decode DPB (Decoded Picture Buffer) state. Used for reference frame storage during video decoding. + * Vulkan only, maps to the same video decode read on other APIs. + * */ + WisTextureStateVideoDecodeDPB = 17, } WisTextureState; /** @@ -1271,6 +1309,8 @@ typedef enum WisBufferUsageFlags { * */ WisBufferUsageFlagsAccelerationStructureInput = (1u << 8), WisBufferUsageFlagsShaderBindingTable = (1u << 9), ///< Buffer is used as a shader binding table buffer. + WisBufferUsageFlagsVideoDecodeDst = (1u << 10), ///< Buffer is used as an output of the video decoding operation. + WisBufferUsageFlagsVideoDecodeSrc = (1u << 11), ///< Buffer is used as an input of the video decoding operation. } WisBufferUsageFlags; /** @@ -1287,6 +1327,9 @@ typedef enum WisTextureUsageFlags { WisTextureUsageFlagsShaderResource = (1u << 4), ///< Texture is used as a shader resource. WisTextureUsageFlagsUnorderedAccess = (1u << 5), ///< Texture is used as an unordered access resource. WisTextureUsageFlagsHostCopy = (1u << 7), ///< Texture is used for host copy operations. Works with GPUUpload heap. + WisTextureUsageFlagsVideoDecodeDst = (1u << 6), ///< Texture is used as a destination for video decode operations. + WisTextureUsageFlagsVideoDecodeSrc = (1u << 8), ///< Texture is used as a source for video decode operations. + WisTextureUsageFlagsVideoDecodeDpb = (1u << 9), ///< Texture is used as a DPB storage for video decode. } WisTextureUsageFlags; /** @@ -1545,6 +1588,11 @@ typedef enum WisViewHeapFlags { * multisample-related usage. * */ WisViewHeapFlagsAllowMultisample = (1u << 0), + /** + * @brief Allows the view heap to be used with video targets. If not set, the view heap does not enable video + * target-related usage. + * */ + WisViewHeapFlagsAllowVideoTargets = (1u << 0), } WisViewHeapFlags; /** @@ -1844,6 +1892,15 @@ typedef struct WisTextureDesc { WisTextureFlags flags; ///< describes texture flags. Describe additional options for the texture. WisMemoryType memory_type; ///< specifies where the texture will be allocated. WisMemoryFlags memory_flags; ///< describes the flags of the memory to allocate for the texture. + /** + * @brief points to an array of formats that can be used to cast the texture to another format. Used for format + * casting in shaders. + * */ + const WisDataFormat* cast_formats; + /** + * @brief defines the number of the number of cast formats in the `WisTextureDesc::cast_formats` array. + * */ + size_t cast_format_count; } WisTextureDesc; /** @@ -2513,12 +2570,6 @@ typedef struct WisDeviceMemoryProperties { * Windows 10 22H2 and later with WDDM 3.0 or later. On Vulkan it requires `VK_EXT_host_image_copy` extension. * */ bool host_image_copy_supported; - /** - * @brief defines bitfield of supported initial resource state transitions for buffers and textures. If a transition - * is supported, the corresponding bit is set to `1`, otherwise `0`. Bit positions are the same as in - * WisTextureState enum. `WisTextureStateUndefined` is always supported. - * */ - uint32_t supported_initial_transitions; } WisDeviceMemoryProperties; /** @@ -2649,7 +2700,7 @@ WIS_DEFINE_HANDLE(WisDX12ViewHeap, 6); * GPU pipeline and allows to execute draw and dispatch calls with it. * * */ -WIS_DEFINE_HANDLE(WisDX12Pipeline, 1); +WIS_DEFINE_HANDLE(WisDX12Pipeline, 2); WIS_DEFINE_HANDLE_VIEW(WisDX12Pipeline, 1); static inline WisDX12PipelineView wisGetDX12PipelineView(const WisDX12Pipeline* handle) @@ -2997,126 +3048,126 @@ typedef struct WisDX12IndexBufferDesc { * @param self is a pointer to the valid WisTexture instance. * * */ -WISDOM_API void wisDX12DestroyTexture(WisDX12Texture* self); +WIS_INLINE WISDOM_API void wisDX12DestroyTexture(WisDX12Texture* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisBuffer handle. * @param self is a pointer to the valid WisBuffer instance. * * */ -WISDOM_API void wisDX12DestroyBuffer(WisDX12Buffer* self); +WIS_INLINE WISDOM_API void wisDX12DestroyBuffer(WisDX12Buffer* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisSwapchain handle. * @param self is a pointer to the valid WisSwapchain instance. * * */ -WISDOM_API void wisDX12DestroySwapchain(WisDX12Swapchain* self); +WIS_INLINE WISDOM_API void wisDX12DestroySwapchain(WisDX12Swapchain* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisSurface handle. * @param self is a pointer to the valid WisSurface instance. * * */ -WISDOM_API void wisDX12DestroySurface(WisDX12Surface* self); +WIS_INLINE WISDOM_API void wisDX12DestroySurface(WisDX12Surface* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisViewHeap handle. * @param self is a pointer to the valid WisViewHeap instance. * * */ -WISDOM_API void wisDX12DestroyViewHeap(WisDX12ViewHeap* self); +WIS_INLINE WISDOM_API void wisDX12DestroyViewHeap(WisDX12ViewHeap* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisPipeline handle. * @param self is a pointer to the valid WisPipeline instance. * * */ -WISDOM_API void wisDX12DestroyPipeline(WisDX12Pipeline* self); +WIS_INLINE WISDOM_API void wisDX12DestroyPipeline(WisDX12Pipeline* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisShader handle. * @param self is a pointer to the valid WisShader instance. * * */ -WISDOM_API void wisDX12DestroyShader(WisDX12Shader* self); +WIS_INLINE WISDOM_API void wisDX12DestroyShader(WisDX12Shader* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisPipelineCache handle. * @param self is a pointer to the valid WisPipelineCache instance. * * */ -WISDOM_API void wisDX12DestroyPipelineCache(WisDX12PipelineCache* self); +WIS_INLINE WISDOM_API void wisDX12DestroyPipelineCache(WisDX12PipelineCache* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisDescriptorHeap handle. * @param self is a pointer to the valid WisDescriptorHeap instance. * * */ -WISDOM_API void wisDX12DestroyDescriptorHeap(WisDX12DescriptorHeap* self); +WIS_INLINE WISDOM_API void wisDX12DestroyDescriptorHeap(WisDX12DescriptorHeap* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisRootSignature handle. * @param self is a pointer to the valid WisRootSignature instance. * * */ -WISDOM_API void wisDX12DestroyRootSignature(WisDX12RootSignature* self); +WIS_INLINE WISDOM_API void wisDX12DestroyRootSignature(WisDX12RootSignature* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisResourceAllocator handle. * @param self is a pointer to the valid WisResourceAllocator instance. * * */ -WISDOM_API void wisDX12DestroyResourceAllocator(WisDX12ResourceAllocator* self); +WIS_INLINE WISDOM_API void wisDX12DestroyResourceAllocator(WisDX12ResourceAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisFence handle. * @param self is a pointer to the valid WisFence instance. * * */ -WISDOM_API void wisDX12DestroyFence(WisDX12Fence* self); +WIS_INLINE WISDOM_API void wisDX12DestroyFence(WisDX12Fence* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandList handle. * @param self is a pointer to the valid WisCommandList instance. * * */ -WISDOM_API void wisDX12DestroyCommandList(WisDX12CommandList* self); +WIS_INLINE WISDOM_API void wisDX12DestroyCommandList(WisDX12CommandList* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandAllocator handle. * @param self is a pointer to the valid WisCommandAllocator instance. * * */ -WISDOM_API void wisDX12DestroyCommandAllocator(WisDX12CommandAllocator* self); +WIS_INLINE WISDOM_API void wisDX12DestroyCommandAllocator(WisDX12CommandAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandQueue handle. * @param self is a pointer to the valid WisCommandQueue instance. * * */ -WISDOM_API void wisDX12DestroyCommandQueue(WisDX12CommandQueue* self); +WIS_INLINE WISDOM_API void wisDX12DestroyCommandQueue(WisDX12CommandQueue* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisDevice handle. * @param self is a pointer to the valid WisDevice instance. * * */ -WISDOM_API void wisDX12DestroyDevice(WisDX12Device* self); +WIS_INLINE WISDOM_API void wisDX12DestroyDevice(WisDX12Device* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisAdapterQuery handle. * @param self is a pointer to the valid WisAdapterQuery instance. * * */ -WISDOM_API void wisDX12DestroyAdapterQuery(WisDX12AdapterQuery* self); +WIS_INLINE WISDOM_API void wisDX12DestroyAdapterQuery(WisDX12AdapterQuery* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisInstance handle. * @param self is a pointer to the valid WisInstance instance. * * */ -WISDOM_API void wisDX12DestroyInstance(WisDX12Instance* self); +WIS_INLINE WISDOM_API void wisDX12DestroyInstance(WisDX12Instance* self); /** * @brief Provided by Wisdom 0.7.0. Creates the WisInstance with extensions, specified in extension array. @@ -3129,7 +3180,7 @@ WISDOM_API void wisDX12DestroyInstance(WisDX12Instance* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CreateInstance( +WIS_INLINE WISDOM_API WisResult wisDX12CreateInstance( const WisDebugDesc* debug_desc, WisDX12InstanceExtensionHeader** extensions, size_t extension_count, @@ -3147,11 +3198,8 @@ WISDOM_API WisResult wisDX12CreateInstance( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12InstanceQueryAdapters( - const WisDX12Instance* self, - WisAdapterPreference preference, - WisDX12AdapterQuery* query -); +WIS_INLINE WISDOM_API WisResult +wisDX12InstanceQueryAdapters(const WisDX12Instance* self, WisAdapterPreference preference, WisDX12AdapterQuery* query); /** * @brief Provided by Wisdom 0.7.0. Returns the number of adapters present on the system at the time of the query. @@ -3159,7 +3207,7 @@ WISDOM_API WisResult wisDX12InstanceQueryAdapters( * @return size is a number of adapters present on the system. * * */ -WISDOM_API size_t wisDX12AdapterQueryGetAdapterCount(const WisDX12AdapterQuery* self); +WIS_INLINE WISDOM_API size_t wisDX12AdapterQueryGetAdapterCount(const WisDX12AdapterQuery* self); /** * @brief Provided by Wisdom 0.7.0. Returns the description of the adapter at given index. @@ -3170,11 +3218,8 @@ WISDOM_API size_t wisDX12AdapterQueryGetAdapterCount(const WisDX12AdapterQuery* * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12AdapterQueryGetAdapterDesc( - const WisDX12AdapterQuery* self, - size_t index, - WisAdapterDesc* desc -); +WIS_INLINE WISDOM_API WisResult +wisDX12AdapterQueryGetAdapterDesc(const WisDX12AdapterQuery* self, size_t index, WisAdapterDesc* desc); /** * @brief Provided by Wisdom 0.7.0. Checks if the adapter at given index supports presentation to given surface. @@ -3185,7 +3230,7 @@ WISDOM_API WisResult wisDX12AdapterQueryGetAdapterDesc( * @return bool `true` if the adapter supports presentation to the surface, `false` otherwise. * * */ -WISDOM_API bool wisDX12AdapterQueryGetSurfaceSupport( +WIS_INLINE WISDOM_API bool wisDX12AdapterQueryGetSurfaceSupport( const WisDX12AdapterQuery* self, size_t index, WisDX12SurfaceView surface @@ -3202,7 +3247,7 @@ WISDOM_API bool wisDX12AdapterQueryGetSurfaceSupport( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12AdapterQueryCreateDevice( +WIS_INLINE WISDOM_API WisResult wisDX12AdapterQueryCreateDevice( const WisDX12AdapterQuery* self, size_t index, const WisDX12DeviceRequirements* requirements, @@ -3217,11 +3262,8 @@ WISDOM_API WisResult wisDX12AdapterQueryCreateDevice( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateCommandQueue( - const WisDX12Device* self, - WisCommandQueueType type, - WisDX12CommandQueue* queue -); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceCreateCommandQueue(const WisDX12Device* self, WisCommandQueueType type, WisDX12CommandQueue* queue); /** * @brief Provided by Wisdom 0.7.0. Creates a command allocator to allocate command lists with. @@ -3231,7 +3273,7 @@ WISDOM_API WisResult wisDX12DeviceCreateCommandQueue( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateCommandAllocator( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateCommandAllocator( const WisDX12Device* self, WisCommandQueueType type, WisDX12CommandAllocator* allocator @@ -3245,7 +3287,8 @@ WISDOM_API WisResult wisDX12DeviceCreateCommandAllocator( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateFence(const WisDX12Device* self, uint64_t initial_value, WisDX12Fence* fence); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceCreateFence(const WisDX12Device* self, uint64_t initial_value, WisDX12Fence* fence); /** * @brief Provided by Wisdom 0.7.0. Creates a resource allocator for managing GPU resources. @@ -3254,7 +3297,8 @@ WISDOM_API WisResult wisDX12DeviceCreateFence(const WisDX12Device* self, uint64_ * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceGetResourceAllocator(const WisDX12Device* self, WisDX12ResourceAllocator* allocator); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceGetResourceAllocator(const WisDX12Device* self, WisDX12ResourceAllocator* allocator); /** * @brief Provided by Wisdom 0.7.0. Creates a pipeline layout with given descriptor. @@ -3264,7 +3308,7 @@ WISDOM_API WisResult wisDX12DeviceGetResourceAllocator(const WisDX12Device* self * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateRootSignature( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateRootSignature( const WisDX12Device* self, const WisRootSignatureDesc* desc, WisDX12RootSignature* layout @@ -3278,7 +3322,7 @@ WISDOM_API WisResult wisDX12DeviceCreateRootSignature( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateDescriptorHeap( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateDescriptorHeap( const WisDX12Device* self, const WisDescriptorHeapDesc* desc, WisDX12DescriptorHeap* heap @@ -3294,7 +3338,7 @@ WISDOM_API WisResult wisDX12DeviceCreateDescriptorHeap( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateViewHeap( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateViewHeap( const WisDX12Device* self, WisViewHeapType type, uint32_t capacity, @@ -3308,7 +3352,7 @@ WISDOM_API WisResult wisDX12DeviceCreateViewHeap( * @param properties describes a pointer to one of the query structs, which is filled with device properties. * * */ -WISDOM_API void wisDX12DeviceQueryProperties(const WisDX12Device* self, void* properties); +WIS_INLINE WISDOM_API void wisDX12DeviceQueryProperties(const WisDX12Device* self, void* properties); /** * @brief Provided by Wisdom 0.7.0. Waits on multiple fences simultaneously. @@ -3324,7 +3368,7 @@ WISDOM_API void wisDX12DeviceQueryProperties(const WisDX12Device* self, void* pr * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceWaitForMultipleFences( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceWaitForMultipleFences( const WisDX12Device* self, const WisDX12FenceView* fences, const uint64_t* fence_values, @@ -3342,7 +3386,7 @@ WISDOM_API WisResult wisDX12DeviceWaitForMultipleFences( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreatePipelineCache( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreatePipelineCache( const WisDX12Device* self, const uint8_t* initial_data, size_t data_size, @@ -3358,12 +3402,8 @@ WISDOM_API WisResult wisDX12DeviceCreatePipelineCache( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateShader( - const WisDX12Device* self, - const uint8_t* data, - size_t size, - WisDX12Shader* shader -); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceCreateShader(const WisDX12Device* self, const uint8_t* data, size_t size, WisDX12Shader* shader); /** * @brief Provided by Wisdom 0.7.0. Creates a compute pipeline state object with given descriptor. @@ -3373,7 +3413,7 @@ WISDOM_API WisResult wisDX12DeviceCreateShader( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateComputePipeline( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateComputePipeline( const WisDX12Device* self, const WisDX12ComputePipelineDesc* desc, WisDX12Pipeline* pipeline @@ -3387,7 +3427,7 @@ WISDOM_API WisResult wisDX12DeviceCreateComputePipeline( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateGraphicsPipeline( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateGraphicsPipeline( const WisDX12Device* self, const WisDX12GraphicsPipelineDesc* desc, WisDX12Pipeline* pipeline @@ -3402,7 +3442,7 @@ WISDOM_API WisResult wisDX12DeviceCreateGraphicsPipeline( * @return bool Result of operation. * * */ -WISDOM_API bool wisDX12DeviceGetFormatPresentationSupport( +WIS_INLINE WISDOM_API bool wisDX12DeviceGetFormatPresentationSupport( const WisDX12Device* self, WisDX12SurfaceView surface, WisDataFormat format @@ -3416,11 +3456,8 @@ WISDOM_API bool wisDX12DeviceGetFormatPresentationSupport( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceGetSurfaceParameters( - const WisDX12Device* self, - WisDX12SurfaceView surface, - WisSurfaceParameters* params -); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceGetSurfaceParameters(const WisDX12Device* self, WisDX12SurfaceView surface, WisSurfaceParameters* params); /** * @brief Provided by Wisdom 0.7.0. Creates a swapchain for given surface with given descriptor. @@ -3433,7 +3470,7 @@ WISDOM_API WisResult wisDX12DeviceGetSurfaceParameters( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceCreateSwapchain( +WIS_INLINE WISDOM_API WisResult wisDX12DeviceCreateSwapchain( const WisDX12Device* self, const WisDX12Surface* surface, const WisDX12CommandQueue* queue, @@ -3449,11 +3486,8 @@ WISDOM_API WisResult wisDX12DeviceCreateSwapchain( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DeviceGetFormatProperties( - const WisDX12Device* self, - WisDataFormat format, - WisFormatProperties* properties -); +WIS_INLINE WISDOM_API WisResult +wisDX12DeviceGetFormatProperties(const WisDX12Device* self, WisDataFormat format, WisFormatProperties* properties); /** * @brief Provided by Wisdom 0.7.0. Get the current value of the fence. @@ -3461,7 +3495,7 @@ WISDOM_API WisResult wisDX12DeviceGetFormatProperties( * @return u64 Value of the fence. * * */ -WISDOM_API uint64_t wisDX12FenceGetCompletedValue(const WisDX12Fence* self); +WIS_INLINE WISDOM_API uint64_t wisDX12FenceGetCompletedValue(const WisDX12Fence* self); /** * @brief Provided by Wisdom 0.7.0. Wait on CPU for the fence to reach a certain value. @@ -3471,7 +3505,7 @@ WISDOM_API uint64_t wisDX12FenceGetCompletedValue(const WisDX12Fence* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12FenceWait(const WisDX12Fence* self, uint64_t value, uint64_t wait_ns); +WIS_INLINE WISDOM_API WisResult wisDX12FenceWait(const WisDX12Fence* self, uint64_t value, uint64_t wait_ns); /** * @brief Provided by Wisdom 0.7.0. Signal the fence from CPU. @@ -3480,7 +3514,7 @@ WISDOM_API WisResult wisDX12FenceWait(const WisDX12Fence* self, uint64_t value, * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12FenceSignal(const WisDX12Fence* self, uint64_t value); +WIS_INLINE WISDOM_API WisResult wisDX12FenceSignal(const WisDX12Fence* self, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Executes the command lists. @@ -3490,11 +3524,8 @@ WISDOM_API WisResult wisDX12FenceSignal(const WisDX12Fence* self, uint64_t value * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandQueueSubmit( - const WisDX12CommandQueue* self, - const WisDX12CommandListView* lists, - size_t list_count -); +WIS_INLINE WISDOM_API WisResult +wisDX12CommandQueueSubmit(const WisDX12CommandQueue* self, const WisDX12CommandListView* lists, size_t list_count); /** * @brief Provided by Wisdom 0.7.0. Enqueue the signal to the queue, that gets executed after all the work has been @@ -3505,11 +3536,8 @@ WISDOM_API WisResult wisDX12CommandQueueSubmit( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandQueueSignalFence( - const WisDX12CommandQueue* self, - WisDX12FenceView fence, - uint64_t value -); +WIS_INLINE WISDOM_API WisResult +wisDX12CommandQueueSignalFence(const WisDX12CommandQueue* self, WisDX12FenceView fence, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Enqueues wait operation to the command queue. Queue then waits for the fence to be @@ -3520,11 +3548,8 @@ WISDOM_API WisResult wisDX12CommandQueueSignalFence( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandQueueWaitFence( - const WisDX12CommandQueue* self, - WisDX12FenceView fence, - uint64_t value -); +WIS_INLINE WISDOM_API WisResult +wisDX12CommandQueueWaitFence(const WisDX12CommandQueue* self, WisDX12FenceView fence, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Creates a buffer with given descriptor. @@ -3534,7 +3559,7 @@ WISDOM_API WisResult wisDX12CommandQueueWaitFence( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12ResourceAllocatorCreateBuffer( +WIS_INLINE WISDOM_API WisResult wisDX12ResourceAllocatorCreateBuffer( const WisDX12ResourceAllocator* self, const WisBufferDesc* desc, WisDX12Buffer* buffer @@ -3548,7 +3573,7 @@ WISDOM_API WisResult wisDX12ResourceAllocatorCreateBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12ResourceAllocatorCreateTexture( +WIS_INLINE WISDOM_API WisResult wisDX12ResourceAllocatorCreateTexture( const WisDX12ResourceAllocator* self, const WisTextureDesc* desc, WisDX12Texture* texture @@ -3560,7 +3585,7 @@ WISDOM_API WisResult wisDX12ResourceAllocatorCreateTexture( * @return void points to the pointer, which is filled with the address of the mapped memory on success. * * */ -WISDOM_API void* wisDX12BufferMap(const WisDX12Buffer* self); +WIS_INLINE WISDOM_API void* wisDX12BufferMap(const WisDX12Buffer* self); /** * @brief Provided by Wisdom 0.7.0. Gets the GPU virtual address of the buffer. @@ -3568,7 +3593,7 @@ WISDOM_API void* wisDX12BufferMap(const WisDX12Buffer* self); * @return u64 Address of the buffer on GPU. * * */ -WISDOM_API uint64_t wisDX12BufferGetGPUAddress(const WisDX12Buffer* self); +WIS_INLINE WISDOM_API uint64_t wisDX12BufferGetGPUAddress(const WisDX12Buffer* self); /** * @brief Provided by Wisdom 0.7.0. Writes data directly to the texture subresource. Texture @wis_must be in @@ -3580,7 +3605,7 @@ WISDOM_API uint64_t wisDX12BufferGetGPUAddress(const WisDX12Buffer* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12TextureWriteSubresource( +WIS_INLINE WISDOM_API WisResult wisDX12TextureWriteSubresource( const WisDX12Texture* self, const void* source_data, const WisTextureRegion* target_region @@ -3592,7 +3617,7 @@ WISDOM_API WisResult wisDX12TextureWriteSubresource( * @return void CPU descriptor handle for the descriptor heap. * * */ -WISDOM_API void* wisDX12DescriptorHeapGetCPUHandle(const WisDX12DescriptorHeap* self); +WIS_INLINE WISDOM_API void* wisDX12DescriptorHeapGetCPUHandle(const WisDX12DescriptorHeap* self); /** * @brief Provided by Wisdom 0.7.0. Writes `WisDescriptorTypeConstantBuffer` descriptor to the descriptor heap. @@ -3603,7 +3628,7 @@ WISDOM_API void* wisDX12DescriptorHeapGetCPUHandle(const WisDX12DescriptorHeap* * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteConstantBuffer( +WIS_INLINE WISDOM_API WisResult wisDX12DescriptorHeapWriteConstantBuffer( const WisDX12DescriptorHeap* self, const WisConstantBufferBinding* data, uint32_t index @@ -3618,7 +3643,7 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteConstantBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteStructuredBuffer( +WIS_INLINE WISDOM_API WisResult wisDX12DescriptorHeapWriteStructuredBuffer( const WisDX12DescriptorHeap* self, WisDX12BufferView buffer, const WisBufferBinding* data, @@ -3634,7 +3659,7 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteStructuredBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteRWStructuredBuffer( +WIS_INLINE WISDOM_API WisResult wisDX12DescriptorHeapWriteRWStructuredBuffer( const WisDX12DescriptorHeap* self, WisDX12BufferView buffer, const WisBufferBinding* data, @@ -3649,11 +3674,8 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteRWStructuredBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteSampler( - const WisDX12DescriptorHeap* self, - const WisSamplerDesc* sampler, - uint32_t index -); +WIS_INLINE WISDOM_API WisResult +wisDX12DescriptorHeapWriteSampler(const WisDX12DescriptorHeap* self, const WisSamplerDesc* sampler, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Writes a descriptor to the descriptor heap. @@ -3664,7 +3686,7 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteSampler( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteTexture( +WIS_INLINE WISDOM_API WisResult wisDX12DescriptorHeapWriteTexture( const WisDX12DescriptorHeap* self, WisDX12TextureView texture, const WisTextureBinding* data, @@ -3680,7 +3702,7 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteTexture( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteRWTexture( +WIS_INLINE WISDOM_API WisResult wisDX12DescriptorHeapWriteRWTexture( const WisDX12DescriptorHeap* self, WisDX12TextureView texture, const WisTextureBinding* data, @@ -3695,11 +3717,8 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteRWTexture( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12DescriptorHeapWriteAccelerationStructure( - const WisDX12DescriptorHeap* self, - uint64_t address, - uint32_t index -); +WIS_INLINE WISDOM_API WisResult +wisDX12DescriptorHeapWriteAccelerationStructure(const WisDX12DescriptorHeap* self, uint64_t address, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Copies descriptors from one heap to another. @@ -3711,7 +3730,7 @@ WISDOM_API WisResult wisDX12DescriptorHeapWriteAccelerationStructure( * @param descriptor_count indicates the number of descriptors to copy. * * */ -WISDOM_API void wisDX12DescriptorHeapCopyDescriptors( +WIS_INLINE WISDOM_API void wisDX12DescriptorHeapCopyDescriptors( const WisDX12DescriptorHeap* self, uint32_t dst_index, const void* src_ptr, @@ -3729,7 +3748,7 @@ WISDOM_API void wisDX12DescriptorHeapCopyDescriptors( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisDX12ViewHeapWriteRenderTarget( +WIS_INLINE WISDOM_API uint64_t wisDX12ViewHeapWriteRenderTarget( const WisDX12ViewHeap* self, const WisDX12Texture* texture, const WisRenderTargetDesc* render_target, @@ -3746,7 +3765,24 @@ WISDOM_API uint64_t wisDX12ViewHeapWriteRenderTarget( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisDX12ViewHeapWriteDepthStencil( +WIS_INLINE WISDOM_API uint64_t wisDX12ViewHeapWriteDepthStencil( + const WisDX12ViewHeap* self, + const WisDX12Texture* texture, + const WisRenderTargetDesc* render_target, + uint32_t index +); + +/** + * @brief Provided by Wisdom 0.7.1. Writes a texture view for video decode output and returns the texture view handle + * for it. The heap must have been created with `WisViewHeapFlagsAllowVideoTargets` + * @param self is a pointer to the valid WisViewHeap instance. + * @param texture describes a pointer to WisTexture to write the view for. + * @param render_target specifies a pointer to WisRenderTargetDesc, which describes the texture view to write. + * @param index defines the index in the view heap to write the view to. + * @return u64 CPU descriptor handle for the view heap. + * + * */ +WIS_INLINE WISDOM_API uint64_t wisDX12ViewHeapWriteVideoDecodeTarget( const WisDX12ViewHeap* self, const WisDX12Texture* texture, const WisRenderTargetDesc* render_target, @@ -3760,7 +3796,7 @@ WISDOM_API uint64_t wisDX12ViewHeapWriteDepthStencil( * @return u64 Address of a view in heap. * * */ -WISDOM_API uint64_t wisDX12ViewHeapGetViewAddress(const WisDX12ViewHeap* self, uint32_t index); +WIS_INLINE WISDOM_API uint64_t wisDX12ViewHeapGetViewAddress(const WisDX12ViewHeap* self, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Copies views from one heap to another. @@ -3771,7 +3807,7 @@ WISDOM_API uint64_t wisDX12ViewHeapGetViewAddress(const WisDX12ViewHeap* self, u * @param view_count indicates the number of views to copy. * * */ -WISDOM_API void wisDX12ViewHeapCopyViews( +WIS_INLINE WISDOM_API void wisDX12ViewHeapCopyViews( const WisDX12ViewHeap* self, uint32_t dst_index, uint64_t src_ptr, @@ -3785,7 +3821,7 @@ WISDOM_API void wisDX12ViewHeapCopyViews( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisDX12ViewHeapGetCPUHandle(const WisDX12ViewHeap* self); +WIS_INLINE WISDOM_API uint64_t wisDX12ViewHeapGetCPUHandle(const WisDX12ViewHeap* self); /** * @brief Provided by Wisdom 0.7.0. Resets the command allocator, so it can be reused for allocating new command lists. @@ -3793,7 +3829,7 @@ WISDOM_API uint64_t wisDX12ViewHeapGetCPUHandle(const WisDX12ViewHeap* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandAllocatorReset(const WisDX12CommandAllocator* self); +WIS_INLINE WISDOM_API WisResult wisDX12CommandAllocatorReset(const WisDX12CommandAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Creates a command list of given type. @@ -3802,10 +3838,8 @@ WISDOM_API WisResult wisDX12CommandAllocatorReset(const WisDX12CommandAllocator* * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandAllocatorCreateCommandList( - const WisDX12CommandAllocator* self, - WisDX12CommandList* list -); +WIS_INLINE WISDOM_API WisResult +wisDX12CommandAllocatorCreateCommandList(const WisDX12CommandAllocator* self, WisDX12CommandList* list); /** * @brief Provided by Wisdom 0.7.0. Opens the command list, so commands can be recorded to it. @@ -3813,7 +3847,7 @@ WISDOM_API WisResult wisDX12CommandAllocatorCreateCommandList( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandListBegin(const WisDX12CommandList* self); +WIS_INLINE WISDOM_API WisResult wisDX12CommandListBegin(const WisDX12CommandList* self); /** * @brief Provided by Wisdom 0.7.0. Closes the command list, so it can be executed on the command queue. @@ -3821,7 +3855,7 @@ WISDOM_API WisResult wisDX12CommandListBegin(const WisDX12CommandList* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12CommandListEnd(const WisDX12CommandList* self); +WIS_INLINE WISDOM_API WisResult wisDX12CommandListEnd(const WisDX12CommandList* self); /** * @brief Provided by Wisdom 0.7.0. Binds descriptor heaps to the command list, so they can be used for resource @@ -3832,7 +3866,7 @@ WISDOM_API WisResult wisDX12CommandListEnd(const WisDX12CommandList* self); * @param sampler_heap describes a pointer to WisDescriptorHeap with samplers. If `nullptr`, no sampler heap is bound. * * */ -WISDOM_API void wisDX12CommandListSetDescriptorHeaps( +WIS_INLINE WISDOM_API void wisDX12CommandListSetDescriptorHeaps( const WisDX12CommandList* self, const WisDX12DescriptorHeap* resource_heap, const WisDX12DescriptorHeap* sampler_heap @@ -3846,7 +3880,7 @@ WISDOM_API void wisDX12CommandListSetDescriptorHeaps( * @param pipeline specifies the pipeline type to set the root signature for. * * */ -WISDOM_API void wisDX12CommandListSetRootSignature( +WIS_INLINE WISDOM_API void wisDX12CommandListSetRootSignature( const WisDX12CommandList* self, WisDX12RootSignatureView signature, WisPipelineType pipeline @@ -3859,7 +3893,10 @@ WISDOM_API void wisDX12CommandListSetRootSignature( * @param data specifies a pointer to WisPushConstantDataDesc, which describes the push constant data to set. * * */ -WISDOM_API void wisDX12CommandListSetPushConstants(const WisDX12CommandList* self, const WisPushConstantDataDesc* data); +WIS_INLINE WISDOM_API void wisDX12CommandListSetPushConstants( + const WisDX12CommandList* self, + const WisPushConstantDataDesc* data +); /** * @brief Provided by Wisdom 0.7.0. Sets the push descriptors for the command list, so they can be used for resource @@ -3868,7 +3905,7 @@ WISDOM_API void wisDX12CommandListSetPushConstants(const WisDX12CommandList* sel * @param data specifies a pointer to WisPushDescriptorDataDesc, which describes the push descriptors to set. * * */ -WISDOM_API void wisDX12CommandListSetPushDescriptor( +WIS_INLINE WISDOM_API void wisDX12CommandListSetPushDescriptor( const WisDX12CommandList* self, const WisPushDescriptorDataDesc* data ); @@ -3880,7 +3917,7 @@ WISDOM_API void wisDX12CommandListSetPushDescriptor( * @param data specifies the root parameter index to set the descriptor table for. * * */ -WISDOM_API void wisDX12CommandListSetDescriptorTable( +WIS_INLINE WISDOM_API void wisDX12CommandListSetDescriptorTable( const WisDX12CommandList* self, const WisDescriptorTableDataDesc* data ); @@ -3891,7 +3928,10 @@ WISDOM_API void wisDX12CommandListSetDescriptorTable( * @param barriers specifies a pointer to an array of barriers to insert. * * */ -WISDOM_API void wisDX12CommandListInsertBarriers(const WisDX12CommandList* self, const WisDX12BarrierGroup* barriers); +WIS_INLINE WISDOM_API void wisDX12CommandListInsertBarriers( + const WisDX12CommandList* self, + const WisDX12BarrierGroup* barriers +); /** * @brief Provided by Wisdom 0.7.0. Sets the pipeline state object for the command list, so it can be used for draw and @@ -3901,7 +3941,7 @@ WISDOM_API void wisDX12CommandListInsertBarriers(const WisDX12CommandList* self, * @param type specifies the pipeline type to set the pipeline for. * * */ -WISDOM_API void wisDX12CommandListSetPipeline( +WIS_INLINE WISDOM_API void wisDX12CommandListSetPipeline( const WisDX12CommandList* self, WisDX12PipelineView pipeline, WisPipelineType type @@ -3914,7 +3954,7 @@ WISDOM_API void wisDX12CommandListSetPipeline( * @param viewport_count defines number of viewports to set. * * */ -WISDOM_API void wisDX12CommandListSetViewports( +WIS_INLINE WISDOM_API void wisDX12CommandListSetViewports( WisDX12CommandList* self, const WisViewport* viewports, size_t viewport_count @@ -3930,7 +3970,11 @@ WISDOM_API void wisDX12CommandListSetViewports( * @param rect_count defines number of scissor rectangles to set. * * */ -WISDOM_API void wisDX12CommandListSetScissors(WisDX12CommandList* self, const WisRect* scissor_rect, size_t rect_count); +WIS_INLINE WISDOM_API void wisDX12CommandListSetScissors( + WisDX12CommandList* self, + const WisRect* scissor_rect, + size_t rect_count +); /** * @brief Provided by Wisdom 0.7.0. Sets the primitive topology. Determines how vertices shall be processed. @@ -3938,7 +3982,10 @@ WISDOM_API void wisDX12CommandListSetScissors(WisDX12CommandList* self, const Wi * @param topology describes primitive topology to set. * * */ -WISDOM_API void wisDX12CommandListSetPrimitiveTopology(WisDX12CommandList* self, WisPrimitiveTopology topology); +WIS_INLINE WISDOM_API void wisDX12CommandListSetPrimitiveTopology( + WisDX12CommandList* self, + WisPrimitiveTopology topology +); /** * @brief Provided by Wisdom 0.7.0. Sets the depth bias. Determines how depth values are modified during rasterization. @@ -3948,7 +3995,7 @@ WISDOM_API void wisDX12CommandListSetPrimitiveTopology(WisDX12CommandList* self, * @param slope_scaled_depth_bias defines slope-scaled depth bias to set. * * */ -WISDOM_API void wisDX12CommandListSetDepthBias( +WIS_INLINE WISDOM_API void wisDX12CommandListSetDepthBias( WisDX12CommandList* self, float depth_bias, float depth_bias_clamp, @@ -3962,7 +4009,7 @@ WISDOM_API void wisDX12CommandListSetDepthBias( * @param restart_value describes primitive restart value to set. * * */ -WISDOM_API void wisDX12CommandListSetPrimitiveRestartValue( +WIS_INLINE WISDOM_API void wisDX12CommandListSetPrimitiveRestartValue( WisDX12CommandList* self, WisPrimitiveRestartValue restart_value ); @@ -3975,7 +4022,7 @@ WISDOM_API void wisDX12CommandListSetPrimitiveRestartValue( * @param group_count_z specifies number of groups to dispatch in Z dimension; default is 1. * * */ -WISDOM_API void wisDX12CommandListDispatch( +WIS_INLINE WISDOM_API void wisDX12CommandListDispatch( const WisDX12CommandList* self, uint32_t group_count_x, uint32_t group_count_y, @@ -3991,7 +4038,7 @@ WISDOM_API void wisDX12CommandListDispatch( * @param start_instance specifies index of the first instance to draw; default is 0. * * */ -WISDOM_API void wisDX12CommandListDraw( +WIS_INLINE WISDOM_API void wisDX12CommandListDraw( const WisDX12CommandList* self, uint32_t vertex_count, uint32_t instance_count, @@ -4009,7 +4056,7 @@ WISDOM_API void wisDX12CommandListDraw( * @param start_instance specifies index of the first instance to draw; default is 0. * * */ -WISDOM_API void wisDX12CommandListDrawIndexed( +WIS_INLINE WISDOM_API void wisDX12CommandListDrawIndexed( const WisDX12CommandList* self, uint32_t index_count, uint32_t instance_count, @@ -4024,14 +4071,17 @@ WISDOM_API void wisDX12CommandListDrawIndexed( * @param desc indicates a pointer to WisRenderPassDesc, which describes the render pass to begin. * * */ -WISDOM_API void wisDX12CommandListBeginRenderPass(const WisDX12CommandList* self, const WisRenderPassDesc* desc); +WIS_INLINE WISDOM_API void wisDX12CommandListBeginRenderPass( + const WisDX12CommandList* self, + const WisRenderPassDesc* desc +); /** * @brief Provided by Wisdom 0.7.0. Ends the current render pass. * @param self is a pointer to the valid WisCommandList instance. * * */ -WISDOM_API void wisDX12CommandListEndRenderPass(const WisDX12CommandList* self); +WIS_INLINE WISDOM_API void wisDX12CommandListEndRenderPass(const WisDX12CommandList* self); /** * @brief Provided by Wisdom 0.7.0. Copies regions from one buffer to another. @@ -4042,7 +4092,7 @@ WISDOM_API void wisDX12CommandListEndRenderPass(const WisDX12CommandList* self); * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisDX12CommandListCopyBuffer( +WIS_INLINE WISDOM_API void wisDX12CommandListCopyBuffer( const WisDX12CommandList* self, WisDX12BufferView dst_buffer, WisDX12BufferView src_buffer, @@ -4059,7 +4109,7 @@ WISDOM_API void wisDX12CommandListCopyBuffer( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisDX12CommandListCopyBufferToTexture( +WIS_INLINE WISDOM_API void wisDX12CommandListCopyBufferToTexture( const WisDX12CommandList* self, WisDX12TextureView dst_texture, WisDX12BufferView src_buffer, @@ -4076,7 +4126,7 @@ WISDOM_API void wisDX12CommandListCopyBufferToTexture( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisDX12CommandListCopyTextureToBuffer( +WIS_INLINE WISDOM_API void wisDX12CommandListCopyTextureToBuffer( const WisDX12CommandList* self, WisDX12BufferView dst_buffer, WisDX12TextureView src_texture, @@ -4093,7 +4143,7 @@ WISDOM_API void wisDX12CommandListCopyTextureToBuffer( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisDX12CommandListCopyTexture( +WIS_INLINE WISDOM_API void wisDX12CommandListCopyTexture( const WisDX12CommandList* self, WisDX12TextureView dst_texture, WisDX12TextureView src_texture, @@ -4109,7 +4159,7 @@ WISDOM_API void wisDX12CommandListCopyTexture( * @param start_slot The start slot to set the vertex buffers to. Default is 0. * * */ -WISDOM_API void wisDX12CommandListSetVertexBuffers( +WIS_INLINE WISDOM_API void wisDX12CommandListSetVertexBuffers( WisDX12CommandList* self, const WisDX12VertexBufferDesc* buffers, size_t buffer_count, @@ -4125,7 +4175,7 @@ WISDOM_API void wisDX12CommandListSetVertexBuffers( * @param start_slot The start slot to set the vertex buffers to. Default is 0. * * */ -WISDOM_API void wisDX12CommandListSetVertexBuffers2( +WIS_INLINE WISDOM_API void wisDX12CommandListSetVertexBuffers2( WisDX12CommandList* self, const WisVertexBufferAddressDesc* buffers, size_t buffer_count, @@ -4140,7 +4190,7 @@ WISDOM_API void wisDX12CommandListSetVertexBuffers2( * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. * * */ -WISDOM_API void wisDX12CommandListSetIndexBuffer( +WIS_INLINE WISDOM_API void wisDX12CommandListSetIndexBuffer( WisDX12CommandList* self, const WisDX12IndexBufferDesc* buffer, WisIndexType index_type @@ -4155,7 +4205,7 @@ WISDOM_API void wisDX12CommandListSetIndexBuffer( * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. * * */ -WISDOM_API void wisDX12CommandListSetIndexBuffer2( +WIS_INLINE WISDOM_API void wisDX12CommandListSetIndexBuffer2( WisDX12CommandList* self, const WisIndexBufferAddressDesc* buffer, WisIndexType index_type @@ -4171,7 +4221,7 @@ WISDOM_API void wisDX12CommandListSetIndexBuffer2( * @param blend_factor_a specifies blend factor for alpha channel to set. * * */ -WISDOM_API void wisDX12CommandListSetBlendFactors( +WIS_INLINE WISDOM_API void wisDX12CommandListSetBlendFactors( const WisDX12CommandList* self, float blend_factor_r, float blend_factor_g, @@ -4188,7 +4238,8 @@ WISDOM_API void wisDX12CommandListSetBlendFactors( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12PipelineCacheSerialize(const WisDX12PipelineCache* self, uint8_t* data, size_t data_size); +WIS_INLINE WISDOM_API WisResult +wisDX12PipelineCacheSerialize(const WisDX12PipelineCache* self, uint8_t* data, size_t data_size); /** * @brief Provided by Wisdom 0.7.0. Gets the size of the data in the pipeline cache. @@ -4196,7 +4247,7 @@ WISDOM_API WisResult wisDX12PipelineCacheSerialize(const WisDX12PipelineCache* s * @return size Size of the data in bytes. * * */ -WISDOM_API size_t wisDX12PipelineCacheGetSerializedSize(const WisDX12PipelineCache* self); +WIS_INLINE WISDOM_API size_t wisDX12PipelineCacheGetSerializedSize(const WisDX12PipelineCache* self); /** * @brief Provided by Wisdom 0.7.0. Presents the swapchain image to the screen. @@ -4207,12 +4258,8 @@ WISDOM_API size_t wisDX12PipelineCacheGetSerializedSize(const WisDX12PipelineCac * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12SwapchainPresent( - const WisDX12Swapchain* self, - WisPresentFlags flags, - const WisRect* rects, - size_t rect_count -); +WIS_INLINE WISDOM_API WisResult +wisDX12SwapchainPresent(const WisDX12Swapchain* self, WisPresentFlags flags, const WisRect* rects, size_t rect_count); /** * @brief Provided by Wisdom 0.7.0. Gets the index of the current backbuffer. In case of lazy indexing it may wait for @@ -4222,7 +4269,7 @@ WISDOM_API WisResult wisDX12SwapchainPresent( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12SwapchainGetCurrentIndex(const WisDX12Swapchain* self, uint32_t* index); +WIS_INLINE WISDOM_API WisResult wisDX12SwapchainGetCurrentIndex(const WisDX12Swapchain* self, uint32_t* index); /** * @brief Provided by Wisdom 0.7.0. Resizes the swapchain buffers. If the swapchain is currently in use, it @wis_must be @@ -4232,7 +4279,8 @@ WISDOM_API WisResult wisDX12SwapchainGetCurrentIndex(const WisDX12Swapchain* sel * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12SwapchainUpdate(const WisDX12Swapchain* self, const WisSwapchainUpdateDesc* desc); +WIS_INLINE WISDOM_API WisResult +wisDX12SwapchainUpdate(const WisDX12Swapchain* self, const WisSwapchainUpdateDesc* desc); /** * @brief Provided by Wisdom 0.7.0. Gets the swapchain buffers. The textures are in `WisTextureStateCommon`. @@ -4243,11 +4291,8 @@ WISDOM_API WisResult wisDX12SwapchainUpdate(const WisDX12Swapchain* self, const * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisDX12SwapchainGetTextures( - const WisDX12Swapchain* self, - WisDX12Texture* buffers, - size_t buffer_count -); +WIS_INLINE WISDOM_API WisResult +wisDX12SwapchainGetTextures(const WisDX12Swapchain* self, WisDX12Texture* buffers, size_t buffer_count); #endif // WISDOM_DX12 @@ -4313,7 +4358,7 @@ WIS_DEFINE_HANDLE(WisVKViewHeap, 3); * GPU pipeline and allows to execute draw and dispatch calls with it. * * */ -WIS_DEFINE_HANDLE(WisVKPipeline, 2); +WIS_DEFINE_HANDLE(WisVKPipeline, 3); WIS_DEFINE_HANDLE_VIEW(WisVKPipeline, 1); static inline WisVKPipelineView wisGetVKPipelineView(const WisVKPipeline* handle) @@ -4661,126 +4706,126 @@ typedef struct WisVKIndexBufferDesc { * @param self is a pointer to the valid WisTexture instance. * * */ -WISDOM_API void wisVKDestroyTexture(WisVKTexture* self); +WIS_INLINE WISDOM_API void wisVKDestroyTexture(WisVKTexture* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisBuffer handle. * @param self is a pointer to the valid WisBuffer instance. * * */ -WISDOM_API void wisVKDestroyBuffer(WisVKBuffer* self); +WIS_INLINE WISDOM_API void wisVKDestroyBuffer(WisVKBuffer* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisSwapchain handle. * @param self is a pointer to the valid WisSwapchain instance. * * */ -WISDOM_API void wisVKDestroySwapchain(WisVKSwapchain* self); +WIS_INLINE WISDOM_API void wisVKDestroySwapchain(WisVKSwapchain* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisSurface handle. * @param self is a pointer to the valid WisSurface instance. * * */ -WISDOM_API void wisVKDestroySurface(WisVKSurface* self); +WIS_INLINE WISDOM_API void wisVKDestroySurface(WisVKSurface* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisViewHeap handle. * @param self is a pointer to the valid WisViewHeap instance. * * */ -WISDOM_API void wisVKDestroyViewHeap(WisVKViewHeap* self); +WIS_INLINE WISDOM_API void wisVKDestroyViewHeap(WisVKViewHeap* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisPipeline handle. * @param self is a pointer to the valid WisPipeline instance. * * */ -WISDOM_API void wisVKDestroyPipeline(WisVKPipeline* self); +WIS_INLINE WISDOM_API void wisVKDestroyPipeline(WisVKPipeline* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisShader handle. * @param self is a pointer to the valid WisShader instance. * * */ -WISDOM_API void wisVKDestroyShader(WisVKShader* self); +WIS_INLINE WISDOM_API void wisVKDestroyShader(WisVKShader* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisPipelineCache handle. * @param self is a pointer to the valid WisPipelineCache instance. * * */ -WISDOM_API void wisVKDestroyPipelineCache(WisVKPipelineCache* self); +WIS_INLINE WISDOM_API void wisVKDestroyPipelineCache(WisVKPipelineCache* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisDescriptorHeap handle. * @param self is a pointer to the valid WisDescriptorHeap instance. * * */ -WISDOM_API void wisVKDestroyDescriptorHeap(WisVKDescriptorHeap* self); +WIS_INLINE WISDOM_API void wisVKDestroyDescriptorHeap(WisVKDescriptorHeap* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisRootSignature handle. * @param self is a pointer to the valid WisRootSignature instance. * * */ -WISDOM_API void wisVKDestroyRootSignature(WisVKRootSignature* self); +WIS_INLINE WISDOM_API void wisVKDestroyRootSignature(WisVKRootSignature* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisResourceAllocator handle. * @param self is a pointer to the valid WisResourceAllocator instance. * * */ -WISDOM_API void wisVKDestroyResourceAllocator(WisVKResourceAllocator* self); +WIS_INLINE WISDOM_API void wisVKDestroyResourceAllocator(WisVKResourceAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisFence handle. * @param self is a pointer to the valid WisFence instance. * * */ -WISDOM_API void wisVKDestroyFence(WisVKFence* self); +WIS_INLINE WISDOM_API void wisVKDestroyFence(WisVKFence* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandList handle. * @param self is a pointer to the valid WisCommandList instance. * * */ -WISDOM_API void wisVKDestroyCommandList(WisVKCommandList* self); +WIS_INLINE WISDOM_API void wisVKDestroyCommandList(WisVKCommandList* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandAllocator handle. * @param self is a pointer to the valid WisCommandAllocator instance. * * */ -WISDOM_API void wisVKDestroyCommandAllocator(WisVKCommandAllocator* self); +WIS_INLINE WISDOM_API void wisVKDestroyCommandAllocator(WisVKCommandAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisCommandQueue handle. * @param self is a pointer to the valid WisCommandQueue instance. * * */ -WISDOM_API void wisVKDestroyCommandQueue(WisVKCommandQueue* self); +WIS_INLINE WISDOM_API void wisVKDestroyCommandQueue(WisVKCommandQueue* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisDevice handle. * @param self is a pointer to the valid WisDevice instance. * * */ -WISDOM_API void wisVKDestroyDevice(WisVKDevice* self); +WIS_INLINE WISDOM_API void wisVKDestroyDevice(WisVKDevice* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisAdapterQuery handle. * @param self is a pointer to the valid WisAdapterQuery instance. * * */ -WISDOM_API void wisVKDestroyAdapterQuery(WisVKAdapterQuery* self); +WIS_INLINE WISDOM_API void wisVKDestroyAdapterQuery(WisVKAdapterQuery* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisInstance handle. * @param self is a pointer to the valid WisInstance instance. * * */ -WISDOM_API void wisVKDestroyInstance(WisVKInstance* self); +WIS_INLINE WISDOM_API void wisVKDestroyInstance(WisVKInstance* self); /** * @brief Provided by Wisdom 0.7.0. Creates the WisInstance with extensions, specified in extension array. @@ -4793,7 +4838,7 @@ WISDOM_API void wisVKDestroyInstance(WisVKInstance* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCreateInstance( +WIS_INLINE WISDOM_API WisResult wisVKCreateInstance( const WisDebugDesc* debug_desc, WisVKInstanceExtensionHeader** extensions, size_t extension_count, @@ -4811,11 +4856,8 @@ WISDOM_API WisResult wisVKCreateInstance( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKInstanceQueryAdapters( - const WisVKInstance* self, - WisAdapterPreference preference, - WisVKAdapterQuery* query -); +WIS_INLINE WISDOM_API WisResult +wisVKInstanceQueryAdapters(const WisVKInstance* self, WisAdapterPreference preference, WisVKAdapterQuery* query); /** * @brief Provided by Wisdom 0.7.0. Returns the number of adapters present on the system at the time of the query. @@ -4823,7 +4865,7 @@ WISDOM_API WisResult wisVKInstanceQueryAdapters( * @return size is a number of adapters present on the system. * * */ -WISDOM_API size_t wisVKAdapterQueryGetAdapterCount(const WisVKAdapterQuery* self); +WIS_INLINE WISDOM_API size_t wisVKAdapterQueryGetAdapterCount(const WisVKAdapterQuery* self); /** * @brief Provided by Wisdom 0.7.0. Returns the description of the adapter at given index. @@ -4834,7 +4876,8 @@ WISDOM_API size_t wisVKAdapterQueryGetAdapterCount(const WisVKAdapterQuery* self * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKAdapterQueryGetAdapterDesc(const WisVKAdapterQuery* self, size_t index, WisAdapterDesc* desc); +WIS_INLINE WISDOM_API WisResult +wisVKAdapterQueryGetAdapterDesc(const WisVKAdapterQuery* self, size_t index, WisAdapterDesc* desc); /** * @brief Provided by Wisdom 0.7.0. Checks if the adapter at given index supports presentation to given surface. @@ -4845,7 +4888,7 @@ WISDOM_API WisResult wisVKAdapterQueryGetAdapterDesc(const WisVKAdapterQuery* se * @return bool `true` if the adapter supports presentation to the surface, `false` otherwise. * * */ -WISDOM_API bool wisVKAdapterQueryGetSurfaceSupport( +WIS_INLINE WISDOM_API bool wisVKAdapterQueryGetSurfaceSupport( const WisVKAdapterQuery* self, size_t index, WisVKSurfaceView surface @@ -4862,7 +4905,7 @@ WISDOM_API bool wisVKAdapterQueryGetSurfaceSupport( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKAdapterQueryCreateDevice( +WIS_INLINE WISDOM_API WisResult wisVKAdapterQueryCreateDevice( const WisVKAdapterQuery* self, size_t index, const WisVKDeviceRequirements* requirements, @@ -4877,11 +4920,8 @@ WISDOM_API WisResult wisVKAdapterQueryCreateDevice( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateCommandQueue( - const WisVKDevice* self, - WisCommandQueueType type, - WisVKCommandQueue* queue -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateCommandQueue(const WisVKDevice* self, WisCommandQueueType type, WisVKCommandQueue* queue); /** * @brief Provided by Wisdom 0.7.0. Creates a command allocator to allocate command lists with. @@ -4891,11 +4931,8 @@ WISDOM_API WisResult wisVKDeviceCreateCommandQueue( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateCommandAllocator( - const WisVKDevice* self, - WisCommandQueueType type, - WisVKCommandAllocator* allocator -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateCommandAllocator(const WisVKDevice* self, WisCommandQueueType type, WisVKCommandAllocator* allocator); /** * @brief Provided by Wisdom 0.7.0. Creates a fence for GPU-CPU and GPU-GPU synchronization. @@ -4905,7 +4942,8 @@ WISDOM_API WisResult wisVKDeviceCreateCommandAllocator( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateFence(const WisVKDevice* self, uint64_t initial_value, WisVKFence* fence); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateFence(const WisVKDevice* self, uint64_t initial_value, WisVKFence* fence); /** * @brief Provided by Wisdom 0.7.0. Creates a resource allocator for managing GPU resources. @@ -4914,7 +4952,8 @@ WISDOM_API WisResult wisVKDeviceCreateFence(const WisVKDevice* self, uint64_t in * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceGetResourceAllocator(const WisVKDevice* self, WisVKResourceAllocator* allocator); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceGetResourceAllocator(const WisVKDevice* self, WisVKResourceAllocator* allocator); /** * @brief Provided by Wisdom 0.7.0. Creates a pipeline layout with given descriptor. @@ -4924,11 +4963,8 @@ WISDOM_API WisResult wisVKDeviceGetResourceAllocator(const WisVKDevice* self, Wi * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateRootSignature( - const WisVKDevice* self, - const WisRootSignatureDesc* desc, - WisVKRootSignature* layout -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateRootSignature(const WisVKDevice* self, const WisRootSignatureDesc* desc, WisVKRootSignature* layout); /** * @brief Provided by Wisdom 0.7.0. Creates a descriptor storage with given description. @@ -4938,11 +4974,8 @@ WISDOM_API WisResult wisVKDeviceCreateRootSignature( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateDescriptorHeap( - const WisVKDevice* self, - const WisDescriptorHeapDesc* desc, - WisVKDescriptorHeap* heap -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateDescriptorHeap(const WisVKDevice* self, const WisDescriptorHeapDesc* desc, WisVKDescriptorHeap* heap); /** * @brief Provided by Wisdom 0.7.0. Creates a view storage with given descriptor. @@ -4954,7 +4987,7 @@ WISDOM_API WisResult wisVKDeviceCreateDescriptorHeap( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateViewHeap( +WIS_INLINE WISDOM_API WisResult wisVKDeviceCreateViewHeap( const WisVKDevice* self, WisViewHeapType type, uint32_t capacity, @@ -4968,7 +5001,7 @@ WISDOM_API WisResult wisVKDeviceCreateViewHeap( * @param properties describes a pointer to one of the query structs, which is filled with device properties. * * */ -WISDOM_API void wisVKDeviceQueryProperties(const WisVKDevice* self, void* properties); +WIS_INLINE WISDOM_API void wisVKDeviceQueryProperties(const WisVKDevice* self, void* properties); /** * @brief Provided by Wisdom 0.7.0. Waits on multiple fences simultaneously. @@ -4984,7 +5017,7 @@ WISDOM_API void wisVKDeviceQueryProperties(const WisVKDevice* self, void* proper * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceWaitForMultipleFences( +WIS_INLINE WISDOM_API WisResult wisVKDeviceWaitForMultipleFences( const WisVKDevice* self, const WisVKFenceView* fences, const uint64_t* fence_values, @@ -5002,7 +5035,7 @@ WISDOM_API WisResult wisVKDeviceWaitForMultipleFences( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreatePipelineCache( +WIS_INLINE WISDOM_API WisResult wisVKDeviceCreatePipelineCache( const WisVKDevice* self, const uint8_t* initial_data, size_t data_size, @@ -5018,12 +5051,8 @@ WISDOM_API WisResult wisVKDeviceCreatePipelineCache( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateShader( - const WisVKDevice* self, - const uint8_t* data, - size_t size, - WisVKShader* shader -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceCreateShader(const WisVKDevice* self, const uint8_t* data, size_t size, WisVKShader* shader); /** * @brief Provided by Wisdom 0.7.0. Creates a compute pipeline state object with given descriptor. @@ -5033,7 +5062,7 @@ WISDOM_API WisResult wisVKDeviceCreateShader( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateComputePipeline( +WIS_INLINE WISDOM_API WisResult wisVKDeviceCreateComputePipeline( const WisVKDevice* self, const WisVKComputePipelineDesc* desc, WisVKPipeline* pipeline @@ -5047,7 +5076,7 @@ WISDOM_API WisResult wisVKDeviceCreateComputePipeline( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateGraphicsPipeline( +WIS_INLINE WISDOM_API WisResult wisVKDeviceCreateGraphicsPipeline( const WisVKDevice* self, const WisVKGraphicsPipelineDesc* desc, WisVKPipeline* pipeline @@ -5062,7 +5091,7 @@ WISDOM_API WisResult wisVKDeviceCreateGraphicsPipeline( * @return bool Result of operation. * * */ -WISDOM_API bool wisVKDeviceGetFormatPresentationSupport( +WIS_INLINE WISDOM_API bool wisVKDeviceGetFormatPresentationSupport( const WisVKDevice* self, WisVKSurfaceView surface, WisDataFormat format @@ -5076,11 +5105,8 @@ WISDOM_API bool wisVKDeviceGetFormatPresentationSupport( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceGetSurfaceParameters( - const WisVKDevice* self, - WisVKSurfaceView surface, - WisSurfaceParameters* params -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceGetSurfaceParameters(const WisVKDevice* self, WisVKSurfaceView surface, WisSurfaceParameters* params); /** * @brief Provided by Wisdom 0.7.0. Creates a swapchain for given surface with given descriptor. @@ -5093,7 +5119,7 @@ WISDOM_API WisResult wisVKDeviceGetSurfaceParameters( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceCreateSwapchain( +WIS_INLINE WISDOM_API WisResult wisVKDeviceCreateSwapchain( const WisVKDevice* self, const WisVKSurface* surface, const WisVKCommandQueue* queue, @@ -5109,11 +5135,8 @@ WISDOM_API WisResult wisVKDeviceCreateSwapchain( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDeviceGetFormatProperties( - const WisVKDevice* self, - WisDataFormat format, - WisFormatProperties* properties -); +WIS_INLINE WISDOM_API WisResult +wisVKDeviceGetFormatProperties(const WisVKDevice* self, WisDataFormat format, WisFormatProperties* properties); /** * @brief Provided by Wisdom 0.7.0. Get the current value of the fence. @@ -5121,7 +5144,7 @@ WISDOM_API WisResult wisVKDeviceGetFormatProperties( * @return u64 Value of the fence. * * */ -WISDOM_API uint64_t wisVKFenceGetCompletedValue(const WisVKFence* self); +WIS_INLINE WISDOM_API uint64_t wisVKFenceGetCompletedValue(const WisVKFence* self); /** * @brief Provided by Wisdom 0.7.0. Wait on CPU for the fence to reach a certain value. @@ -5131,7 +5154,7 @@ WISDOM_API uint64_t wisVKFenceGetCompletedValue(const WisVKFence* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKFenceWait(const WisVKFence* self, uint64_t value, uint64_t wait_ns); +WIS_INLINE WISDOM_API WisResult wisVKFenceWait(const WisVKFence* self, uint64_t value, uint64_t wait_ns); /** * @brief Provided by Wisdom 0.7.0. Signal the fence from CPU. @@ -5140,7 +5163,7 @@ WISDOM_API WisResult wisVKFenceWait(const WisVKFence* self, uint64_t value, uint * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKFenceSignal(const WisVKFence* self, uint64_t value); +WIS_INLINE WISDOM_API WisResult wisVKFenceSignal(const WisVKFence* self, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Executes the command lists. @@ -5150,11 +5173,8 @@ WISDOM_API WisResult wisVKFenceSignal(const WisVKFence* self, uint64_t value); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandQueueSubmit( - const WisVKCommandQueue* self, - const WisVKCommandListView* lists, - size_t list_count -); +WIS_INLINE WISDOM_API WisResult +wisVKCommandQueueSubmit(const WisVKCommandQueue* self, const WisVKCommandListView* lists, size_t list_count); /** * @brief Provided by Wisdom 0.7.0. Enqueue the signal to the queue, that gets executed after all the work has been @@ -5165,7 +5185,8 @@ WISDOM_API WisResult wisVKCommandQueueSubmit( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandQueueSignalFence(const WisVKCommandQueue* self, WisVKFenceView fence, uint64_t value); +WIS_INLINE WISDOM_API WisResult +wisVKCommandQueueSignalFence(const WisVKCommandQueue* self, WisVKFenceView fence, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Enqueues wait operation to the command queue. Queue then waits for the fence to be @@ -5176,7 +5197,8 @@ WISDOM_API WisResult wisVKCommandQueueSignalFence(const WisVKCommandQueue* self, * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandQueueWaitFence(const WisVKCommandQueue* self, WisVKFenceView fence, uint64_t value); +WIS_INLINE WISDOM_API WisResult +wisVKCommandQueueWaitFence(const WisVKCommandQueue* self, WisVKFenceView fence, uint64_t value); /** * @brief Provided by Wisdom 0.7.0. Creates a buffer with given descriptor. @@ -5186,11 +5208,8 @@ WISDOM_API WisResult wisVKCommandQueueWaitFence(const WisVKCommandQueue* self, W * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKResourceAllocatorCreateBuffer( - const WisVKResourceAllocator* self, - const WisBufferDesc* desc, - WisVKBuffer* buffer -); +WIS_INLINE WISDOM_API WisResult +wisVKResourceAllocatorCreateBuffer(const WisVKResourceAllocator* self, const WisBufferDesc* desc, WisVKBuffer* buffer); /** * @brief Provided by Wisdom 0.7.0. Creates a texture with given descriptor. @@ -5200,7 +5219,7 @@ WISDOM_API WisResult wisVKResourceAllocatorCreateBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKResourceAllocatorCreateTexture( +WIS_INLINE WISDOM_API WisResult wisVKResourceAllocatorCreateTexture( const WisVKResourceAllocator* self, const WisTextureDesc* desc, WisVKTexture* texture @@ -5212,7 +5231,7 @@ WISDOM_API WisResult wisVKResourceAllocatorCreateTexture( * @return void points to the pointer, which is filled with the address of the mapped memory on success. * * */ -WISDOM_API void* wisVKBufferMap(const WisVKBuffer* self); +WIS_INLINE WISDOM_API void* wisVKBufferMap(const WisVKBuffer* self); /** * @brief Provided by Wisdom 0.7.0. Gets the GPU virtual address of the buffer. @@ -5220,7 +5239,7 @@ WISDOM_API void* wisVKBufferMap(const WisVKBuffer* self); * @return u64 Address of the buffer on GPU. * * */ -WISDOM_API uint64_t wisVKBufferGetGPUAddress(const WisVKBuffer* self); +WIS_INLINE WISDOM_API uint64_t wisVKBufferGetGPUAddress(const WisVKBuffer* self); /** * @brief Provided by Wisdom 0.7.0. Writes data directly to the texture subresource. Texture @wis_must be in @@ -5232,11 +5251,8 @@ WISDOM_API uint64_t wisVKBufferGetGPUAddress(const WisVKBuffer* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKTextureWriteSubresource( - const WisVKTexture* self, - const void* source_data, - const WisTextureRegion* target_region -); +WIS_INLINE WISDOM_API WisResult +wisVKTextureWriteSubresource(const WisVKTexture* self, const void* source_data, const WisTextureRegion* target_region); /** * @brief Provided by Wisdom 0.7.0. Returns the CPU descriptor handle for the descriptor heap. @@ -5244,7 +5260,7 @@ WISDOM_API WisResult wisVKTextureWriteSubresource( * @return void CPU descriptor handle for the descriptor heap. * * */ -WISDOM_API void* wisVKDescriptorHeapGetCPUHandle(const WisVKDescriptorHeap* self); +WIS_INLINE WISDOM_API void* wisVKDescriptorHeapGetCPUHandle(const WisVKDescriptorHeap* self); /** * @brief Provided by Wisdom 0.7.0. Writes `WisDescriptorTypeConstantBuffer` descriptor to the descriptor heap. @@ -5255,7 +5271,7 @@ WISDOM_API void* wisVKDescriptorHeapGetCPUHandle(const WisVKDescriptorHeap* self * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteConstantBuffer( +WIS_INLINE WISDOM_API WisResult wisVKDescriptorHeapWriteConstantBuffer( const WisVKDescriptorHeap* self, const WisConstantBufferBinding* data, uint32_t index @@ -5270,7 +5286,7 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteConstantBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteStructuredBuffer( +WIS_INLINE WISDOM_API WisResult wisVKDescriptorHeapWriteStructuredBuffer( const WisVKDescriptorHeap* self, WisVKBufferView buffer, const WisBufferBinding* data, @@ -5286,7 +5302,7 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteStructuredBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteRWStructuredBuffer( +WIS_INLINE WISDOM_API WisResult wisVKDescriptorHeapWriteRWStructuredBuffer( const WisVKDescriptorHeap* self, WisVKBufferView buffer, const WisBufferBinding* data, @@ -5301,11 +5317,8 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteRWStructuredBuffer( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteSampler( - const WisVKDescriptorHeap* self, - const WisSamplerDesc* sampler, - uint32_t index -); +WIS_INLINE WISDOM_API WisResult +wisVKDescriptorHeapWriteSampler(const WisVKDescriptorHeap* self, const WisSamplerDesc* sampler, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Writes a descriptor to the descriptor heap. @@ -5316,7 +5329,7 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteSampler( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteTexture( +WIS_INLINE WISDOM_API WisResult wisVKDescriptorHeapWriteTexture( const WisVKDescriptorHeap* self, WisVKTextureView texture, const WisTextureBinding* data, @@ -5332,7 +5345,7 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteTexture( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteRWTexture( +WIS_INLINE WISDOM_API WisResult wisVKDescriptorHeapWriteRWTexture( const WisVKDescriptorHeap* self, WisVKTextureView texture, const WisTextureBinding* data, @@ -5347,11 +5360,8 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteRWTexture( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKDescriptorHeapWriteAccelerationStructure( - const WisVKDescriptorHeap* self, - uint64_t address, - uint32_t index -); +WIS_INLINE WISDOM_API WisResult +wisVKDescriptorHeapWriteAccelerationStructure(const WisVKDescriptorHeap* self, uint64_t address, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Copies descriptors from one heap to another. @@ -5363,7 +5373,7 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteAccelerationStructure( * @param descriptor_count indicates the number of descriptors to copy. * * */ -WISDOM_API void wisVKDescriptorHeapCopyDescriptors( +WIS_INLINE WISDOM_API void wisVKDescriptorHeapCopyDescriptors( const WisVKDescriptorHeap* self, uint32_t dst_index, const void* src_ptr, @@ -5381,7 +5391,7 @@ WISDOM_API void wisVKDescriptorHeapCopyDescriptors( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisVKViewHeapWriteRenderTarget( +WIS_INLINE WISDOM_API uint64_t wisVKViewHeapWriteRenderTarget( const WisVKViewHeap* self, const WisVKTexture* texture, const WisRenderTargetDesc* render_target, @@ -5398,7 +5408,24 @@ WISDOM_API uint64_t wisVKViewHeapWriteRenderTarget( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisVKViewHeapWriteDepthStencil( +WIS_INLINE WISDOM_API uint64_t wisVKViewHeapWriteDepthStencil( + const WisVKViewHeap* self, + const WisVKTexture* texture, + const WisRenderTargetDesc* render_target, + uint32_t index +); + +/** + * @brief Provided by Wisdom 0.7.1. Writes a texture view for video decode output and returns the texture view handle + * for it. The heap must have been created with `WisViewHeapFlagsAllowVideoTargets` + * @param self is a pointer to the valid WisViewHeap instance. + * @param texture describes a pointer to WisTexture to write the view for. + * @param render_target specifies a pointer to WisRenderTargetDesc, which describes the texture view to write. + * @param index defines the index in the view heap to write the view to. + * @return u64 CPU descriptor handle for the view heap. + * + * */ +WIS_INLINE WISDOM_API uint64_t wisVKViewHeapWriteVideoDecodeTarget( const WisVKViewHeap* self, const WisVKTexture* texture, const WisRenderTargetDesc* render_target, @@ -5412,7 +5439,7 @@ WISDOM_API uint64_t wisVKViewHeapWriteDepthStencil( * @return u64 Address of a view in heap. * * */ -WISDOM_API uint64_t wisVKViewHeapGetViewAddress(const WisVKViewHeap* self, uint32_t index); +WIS_INLINE WISDOM_API uint64_t wisVKViewHeapGetViewAddress(const WisVKViewHeap* self, uint32_t index); /** * @brief Provided by Wisdom 0.7.0. Copies views from one heap to another. @@ -5423,7 +5450,7 @@ WISDOM_API uint64_t wisVKViewHeapGetViewAddress(const WisVKViewHeap* self, uint3 * @param view_count indicates the number of views to copy. * * */ -WISDOM_API void wisVKViewHeapCopyViews( +WIS_INLINE WISDOM_API void wisVKViewHeapCopyViews( const WisVKViewHeap* self, uint32_t dst_index, uint64_t src_ptr, @@ -5437,7 +5464,7 @@ WISDOM_API void wisVKViewHeapCopyViews( * @return u64 CPU descriptor handle for the view heap. * * */ -WISDOM_API uint64_t wisVKViewHeapGetCPUHandle(const WisVKViewHeap* self); +WIS_INLINE WISDOM_API uint64_t wisVKViewHeapGetCPUHandle(const WisVKViewHeap* self); /** * @brief Provided by Wisdom 0.7.0. Resets the command allocator, so it can be reused for allocating new command lists. @@ -5445,7 +5472,7 @@ WISDOM_API uint64_t wisVKViewHeapGetCPUHandle(const WisVKViewHeap* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandAllocatorReset(const WisVKCommandAllocator* self); +WIS_INLINE WISDOM_API WisResult wisVKCommandAllocatorReset(const WisVKCommandAllocator* self); /** * @brief Provided by Wisdom 0.7.0. Creates a command list of given type. @@ -5454,7 +5481,8 @@ WISDOM_API WisResult wisVKCommandAllocatorReset(const WisVKCommandAllocator* sel * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandAllocatorCreateCommandList(const WisVKCommandAllocator* self, WisVKCommandList* list); +WIS_INLINE WISDOM_API WisResult +wisVKCommandAllocatorCreateCommandList(const WisVKCommandAllocator* self, WisVKCommandList* list); /** * @brief Provided by Wisdom 0.7.0. Opens the command list, so commands can be recorded to it. @@ -5462,7 +5490,7 @@ WISDOM_API WisResult wisVKCommandAllocatorCreateCommandList(const WisVKCommandAl * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandListBegin(const WisVKCommandList* self); +WIS_INLINE WISDOM_API WisResult wisVKCommandListBegin(const WisVKCommandList* self); /** * @brief Provided by Wisdom 0.7.0. Closes the command list, so it can be executed on the command queue. @@ -5470,7 +5498,7 @@ WISDOM_API WisResult wisVKCommandListBegin(const WisVKCommandList* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKCommandListEnd(const WisVKCommandList* self); +WIS_INLINE WISDOM_API WisResult wisVKCommandListEnd(const WisVKCommandList* self); /** * @brief Provided by Wisdom 0.7.0. Binds descriptor heaps to the command list, so they can be used for resource @@ -5481,7 +5509,7 @@ WISDOM_API WisResult wisVKCommandListEnd(const WisVKCommandList* self); * @param sampler_heap describes a pointer to WisDescriptorHeap with samplers. If `nullptr`, no sampler heap is bound. * * */ -WISDOM_API void wisVKCommandListSetDescriptorHeaps( +WIS_INLINE WISDOM_API void wisVKCommandListSetDescriptorHeaps( const WisVKCommandList* self, const WisVKDescriptorHeap* resource_heap, const WisVKDescriptorHeap* sampler_heap @@ -5495,7 +5523,7 @@ WISDOM_API void wisVKCommandListSetDescriptorHeaps( * @param pipeline specifies the pipeline type to set the root signature for. * * */ -WISDOM_API void wisVKCommandListSetRootSignature( +WIS_INLINE WISDOM_API void wisVKCommandListSetRootSignature( const WisVKCommandList* self, WisVKRootSignatureView signature, WisPipelineType pipeline @@ -5508,7 +5536,10 @@ WISDOM_API void wisVKCommandListSetRootSignature( * @param data specifies a pointer to WisPushConstantDataDesc, which describes the push constant data to set. * * */ -WISDOM_API void wisVKCommandListSetPushConstants(const WisVKCommandList* self, const WisPushConstantDataDesc* data); +WIS_INLINE WISDOM_API void wisVKCommandListSetPushConstants( + const WisVKCommandList* self, + const WisPushConstantDataDesc* data +); /** * @brief Provided by Wisdom 0.7.0. Sets the push descriptors for the command list, so they can be used for resource @@ -5517,7 +5548,10 @@ WISDOM_API void wisVKCommandListSetPushConstants(const WisVKCommandList* self, c * @param data specifies a pointer to WisPushDescriptorDataDesc, which describes the push descriptors to set. * * */ -WISDOM_API void wisVKCommandListSetPushDescriptor(const WisVKCommandList* self, const WisPushDescriptorDataDesc* data); +WIS_INLINE WISDOM_API void wisVKCommandListSetPushDescriptor( + const WisVKCommandList* self, + const WisPushDescriptorDataDesc* data +); /** * @brief Provided by Wisdom 0.7.0. Sets the descriptor table offset in descriptor heap for the command list, so it can @@ -5526,7 +5560,7 @@ WISDOM_API void wisVKCommandListSetPushDescriptor(const WisVKCommandList* self, * @param data specifies the root parameter index to set the descriptor table for. * * */ -WISDOM_API void wisVKCommandListSetDescriptorTable( +WIS_INLINE WISDOM_API void wisVKCommandListSetDescriptorTable( const WisVKCommandList* self, const WisDescriptorTableDataDesc* data ); @@ -5537,7 +5571,10 @@ WISDOM_API void wisVKCommandListSetDescriptorTable( * @param barriers specifies a pointer to an array of barriers to insert. * * */ -WISDOM_API void wisVKCommandListInsertBarriers(const WisVKCommandList* self, const WisVKBarrierGroup* barriers); +WIS_INLINE WISDOM_API void wisVKCommandListInsertBarriers( + const WisVKCommandList* self, + const WisVKBarrierGroup* barriers +); /** * @brief Provided by Wisdom 0.7.0. Sets the pipeline state object for the command list, so it can be used for draw and @@ -5547,7 +5584,7 @@ WISDOM_API void wisVKCommandListInsertBarriers(const WisVKCommandList* self, con * @param type specifies the pipeline type to set the pipeline for. * * */ -WISDOM_API void wisVKCommandListSetPipeline( +WIS_INLINE WISDOM_API void wisVKCommandListSetPipeline( const WisVKCommandList* self, WisVKPipelineView pipeline, WisPipelineType type @@ -5560,7 +5597,7 @@ WISDOM_API void wisVKCommandListSetPipeline( * @param viewport_count defines number of viewports to set. * * */ -WISDOM_API void wisVKCommandListSetViewports( +WIS_INLINE WISDOM_API void wisVKCommandListSetViewports( WisVKCommandList* self, const WisViewport* viewports, size_t viewport_count @@ -5576,7 +5613,11 @@ WISDOM_API void wisVKCommandListSetViewports( * @param rect_count defines number of scissor rectangles to set. * * */ -WISDOM_API void wisVKCommandListSetScissors(WisVKCommandList* self, const WisRect* scissor_rect, size_t rect_count); +WIS_INLINE WISDOM_API void wisVKCommandListSetScissors( + WisVKCommandList* self, + const WisRect* scissor_rect, + size_t rect_count +); /** * @brief Provided by Wisdom 0.7.0. Sets the primitive topology. Determines how vertices shall be processed. @@ -5584,7 +5625,7 @@ WISDOM_API void wisVKCommandListSetScissors(WisVKCommandList* self, const WisRec * @param topology describes primitive topology to set. * * */ -WISDOM_API void wisVKCommandListSetPrimitiveTopology(WisVKCommandList* self, WisPrimitiveTopology topology); +WIS_INLINE WISDOM_API void wisVKCommandListSetPrimitiveTopology(WisVKCommandList* self, WisPrimitiveTopology topology); /** * @brief Provided by Wisdom 0.7.0. Sets the depth bias. Determines how depth values are modified during rasterization. @@ -5594,7 +5635,7 @@ WISDOM_API void wisVKCommandListSetPrimitiveTopology(WisVKCommandList* self, Wis * @param slope_scaled_depth_bias defines slope-scaled depth bias to set. * * */ -WISDOM_API void wisVKCommandListSetDepthBias( +WIS_INLINE WISDOM_API void wisVKCommandListSetDepthBias( WisVKCommandList* self, float depth_bias, float depth_bias_clamp, @@ -5608,7 +5649,7 @@ WISDOM_API void wisVKCommandListSetDepthBias( * @param restart_value describes primitive restart value to set. * * */ -WISDOM_API void wisVKCommandListSetPrimitiveRestartValue( +WIS_INLINE WISDOM_API void wisVKCommandListSetPrimitiveRestartValue( WisVKCommandList* self, WisPrimitiveRestartValue restart_value ); @@ -5621,7 +5662,7 @@ WISDOM_API void wisVKCommandListSetPrimitiveRestartValue( * @param group_count_z specifies number of groups to dispatch in Z dimension; default is 1. * * */ -WISDOM_API void wisVKCommandListDispatch( +WIS_INLINE WISDOM_API void wisVKCommandListDispatch( const WisVKCommandList* self, uint32_t group_count_x, uint32_t group_count_y, @@ -5637,7 +5678,7 @@ WISDOM_API void wisVKCommandListDispatch( * @param start_instance specifies index of the first instance to draw; default is 0. * * */ -WISDOM_API void wisVKCommandListDraw( +WIS_INLINE WISDOM_API void wisVKCommandListDraw( const WisVKCommandList* self, uint32_t vertex_count, uint32_t instance_count, @@ -5655,7 +5696,7 @@ WISDOM_API void wisVKCommandListDraw( * @param start_instance specifies index of the first instance to draw; default is 0. * * */ -WISDOM_API void wisVKCommandListDrawIndexed( +WIS_INLINE WISDOM_API void wisVKCommandListDrawIndexed( const WisVKCommandList* self, uint32_t index_count, uint32_t instance_count, @@ -5670,14 +5711,14 @@ WISDOM_API void wisVKCommandListDrawIndexed( * @param desc indicates a pointer to WisRenderPassDesc, which describes the render pass to begin. * * */ -WISDOM_API void wisVKCommandListBeginRenderPass(const WisVKCommandList* self, const WisRenderPassDesc* desc); +WIS_INLINE WISDOM_API void wisVKCommandListBeginRenderPass(const WisVKCommandList* self, const WisRenderPassDesc* desc); /** * @brief Provided by Wisdom 0.7.0. Ends the current render pass. * @param self is a pointer to the valid WisCommandList instance. * * */ -WISDOM_API void wisVKCommandListEndRenderPass(const WisVKCommandList* self); +WIS_INLINE WISDOM_API void wisVKCommandListEndRenderPass(const WisVKCommandList* self); /** * @brief Provided by Wisdom 0.7.0. Copies regions from one buffer to another. @@ -5688,7 +5729,7 @@ WISDOM_API void wisVKCommandListEndRenderPass(const WisVKCommandList* self); * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisVKCommandListCopyBuffer( +WIS_INLINE WISDOM_API void wisVKCommandListCopyBuffer( const WisVKCommandList* self, WisVKBufferView dst_buffer, WisVKBufferView src_buffer, @@ -5705,7 +5746,7 @@ WISDOM_API void wisVKCommandListCopyBuffer( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisVKCommandListCopyBufferToTexture( +WIS_INLINE WISDOM_API void wisVKCommandListCopyBufferToTexture( const WisVKCommandList* self, WisVKTextureView dst_texture, WisVKBufferView src_buffer, @@ -5722,7 +5763,7 @@ WISDOM_API void wisVKCommandListCopyBufferToTexture( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisVKCommandListCopyTextureToBuffer( +WIS_INLINE WISDOM_API void wisVKCommandListCopyTextureToBuffer( const WisVKCommandList* self, WisVKBufferView dst_buffer, WisVKTextureView src_texture, @@ -5739,7 +5780,7 @@ WISDOM_API void wisVKCommandListCopyTextureToBuffer( * @param region_count defines the count of the regions. * * */ -WISDOM_API void wisVKCommandListCopyTexture( +WIS_INLINE WISDOM_API void wisVKCommandListCopyTexture( const WisVKCommandList* self, WisVKTextureView dst_texture, WisVKTextureView src_texture, @@ -5755,7 +5796,7 @@ WISDOM_API void wisVKCommandListCopyTexture( * @param start_slot The start slot to set the vertex buffers to. Default is 0. * * */ -WISDOM_API void wisVKCommandListSetVertexBuffers( +WIS_INLINE WISDOM_API void wisVKCommandListSetVertexBuffers( WisVKCommandList* self, const WisVKVertexBufferDesc* buffers, size_t buffer_count, @@ -5771,7 +5812,7 @@ WISDOM_API void wisVKCommandListSetVertexBuffers( * @param start_slot The start slot to set the vertex buffers to. Default is 0. * * */ -WISDOM_API void wisVKCommandListSetVertexBuffers2( +WIS_INLINE WISDOM_API void wisVKCommandListSetVertexBuffers2( WisVKCommandList* self, const WisVertexBufferAddressDesc* buffers, size_t buffer_count, @@ -5786,7 +5827,7 @@ WISDOM_API void wisVKCommandListSetVertexBuffers2( * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. * * */ -WISDOM_API void wisVKCommandListSetIndexBuffer( +WIS_INLINE WISDOM_API void wisVKCommandListSetIndexBuffer( WisVKCommandList* self, const WisVKIndexBufferDesc* buffer, WisIndexType index_type @@ -5801,7 +5842,7 @@ WISDOM_API void wisVKCommandListSetIndexBuffer( * `WisIndexTypeUInt16` or `WisIndexTypeUInt32`. * * */ -WISDOM_API void wisVKCommandListSetIndexBuffer2( +WIS_INLINE WISDOM_API void wisVKCommandListSetIndexBuffer2( WisVKCommandList* self, const WisIndexBufferAddressDesc* buffer, WisIndexType index_type @@ -5817,7 +5858,7 @@ WISDOM_API void wisVKCommandListSetIndexBuffer2( * @param blend_factor_a specifies blend factor for alpha channel to set. * * */ -WISDOM_API void wisVKCommandListSetBlendFactors( +WIS_INLINE WISDOM_API void wisVKCommandListSetBlendFactors( const WisVKCommandList* self, float blend_factor_r, float blend_factor_g, @@ -5834,7 +5875,8 @@ WISDOM_API void wisVKCommandListSetBlendFactors( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKPipelineCacheSerialize(const WisVKPipelineCache* self, uint8_t* data, size_t data_size); +WIS_INLINE WISDOM_API WisResult +wisVKPipelineCacheSerialize(const WisVKPipelineCache* self, uint8_t* data, size_t data_size); /** * @brief Provided by Wisdom 0.7.0. Gets the size of the data in the pipeline cache. @@ -5842,7 +5884,7 @@ WISDOM_API WisResult wisVKPipelineCacheSerialize(const WisVKPipelineCache* self, * @return size Size of the data in bytes. * * */ -WISDOM_API size_t wisVKPipelineCacheGetSerializedSize(const WisVKPipelineCache* self); +WIS_INLINE WISDOM_API size_t wisVKPipelineCacheGetSerializedSize(const WisVKPipelineCache* self); /** * @brief Provided by Wisdom 0.7.0. Presents the swapchain image to the screen. @@ -5853,12 +5895,8 @@ WISDOM_API size_t wisVKPipelineCacheGetSerializedSize(const WisVKPipelineCache* * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKSwapchainPresent( - const WisVKSwapchain* self, - WisPresentFlags flags, - const WisRect* rects, - size_t rect_count -); +WIS_INLINE WISDOM_API WisResult +wisVKSwapchainPresent(const WisVKSwapchain* self, WisPresentFlags flags, const WisRect* rects, size_t rect_count); /** * @brief Provided by Wisdom 0.7.0. Gets the index of the current backbuffer. In case of lazy indexing it may wait for @@ -5868,7 +5906,7 @@ WISDOM_API WisResult wisVKSwapchainPresent( * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKSwapchainGetCurrentIndex(const WisVKSwapchain* self, uint32_t* index); +WIS_INLINE WISDOM_API WisResult wisVKSwapchainGetCurrentIndex(const WisVKSwapchain* self, uint32_t* index); /** * @brief Provided by Wisdom 0.7.0. Resizes the swapchain buffers. If the swapchain is currently in use, it @wis_must be @@ -5878,7 +5916,7 @@ WISDOM_API WisResult wisVKSwapchainGetCurrentIndex(const WisVKSwapchain* self, u * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKSwapchainUpdate(const WisVKSwapchain* self, const WisSwapchainUpdateDesc* desc); +WIS_INLINE WISDOM_API WisResult wisVKSwapchainUpdate(const WisVKSwapchain* self, const WisSwapchainUpdateDesc* desc); /** * @brief Provided by Wisdom 0.7.0. Gets the swapchain buffers. The textures are in `WisTextureStateCommon`. @@ -5889,7 +5927,8 @@ WISDOM_API WisResult wisVKSwapchainUpdate(const WisVKSwapchain* self, const WisS * @return Result denoting the outcome of operation. * * */ -WISDOM_API WisResult wisVKSwapchainGetTextures(const WisVKSwapchain* self, WisVKTexture* buffers, size_t buffer_count); +WIS_INLINE WISDOM_API WisResult +wisVKSwapchainGetTextures(const WisVKSwapchain* self, WisVKTexture* buffers, size_t buffer_count); #endif // WISDOM_VULKAN diff --git a/src/include/wisdom/generated/cpp_api.hpp b/src/include/wisdom/generated/cpp_api.hpp index bba2d4a48..ba95d0031 100644 --- a/src/include/wisdom/generated/cpp_api.hpp +++ b/src/include/wisdom/generated/cpp_api.hpp @@ -613,6 +613,39 @@ enum class DataFormat { * a 4-bit A component in bits 12..15. * */ BGRA4Unorm = 115, + /** + * @brief Provided by Wisdom 0.7.1. + * NV12 video format. + * A two-plane format with a single 8-bit Y plane followed by an interleaved UV plane, where the U and V components + * are subsampled by a factor of 2 in both dimensions. The Y plane contains the luma (brightness) information, while + * the UV plane contains the chroma (color) information. This format is commonly used for video encoding and + * decoding applications. + * */ + NV12 = 256, + /** + * @brief Provided by Wisdom 0.7.1. + * P010 video format. + * A two-plane format similar to NV12, but with 10 bits per channel instead of 8. The Y plane contains 10-bit luma + * information, and the UV plane contains interleaved 10-bit chroma information. This format is used for + * high-quality video encoding and decoding, providing improved color fidelity compared to NV12. + * */ + P010 = 257, + /** + * @brief Provided by Wisdom 0.7.1. + * P012 video format. + * A two-plane format similar to P010, but with 12 bits per channel instead of 10. The Y plane contains 12-bit luma + * information, and the UV plane contains interleaved 12-bit chroma information. This format is used for + * professional video applications that require higher color fidelity and dynamic range than P010. + * */ + P012 = 258, + /** + * @brief Provided by Wisdom 0.7.1. + * P016 video format. + * A two-plane format similar to P010, but with 16 bits per channel instead of 10. The Y plane contains 16-bit luma + * information, and the UV plane contains interleaved 16-bit chroma information. This format is used for + * professional video applications that require the highest color fidelity and dynamic range. + * */ + P016 = 259, }; /** @@ -941,6 +974,11 @@ enum class TextureState { VideoDecodeWrite = 14, ///< Video Decode Write state. ResolveDepthStensilDst = 15, ///< Depth Stencil Resolve Destination state. ResolveRenderTargetDst = 16, ///< Render Target Resolve Destination state. + /** + * @brief Video Decode DPB (Decoded Picture Buffer) state. Used for reference frame storage during video decoding. + * Vulkan only, maps to the same video decode read on other APIs. + * */ + VideoDecodeDPB = 17, }; /** @@ -1248,6 +1286,8 @@ enum class BufferUsageFlags : uint32_t { AccelerationStructureBuffer = (1u << 7), ///< Buffer is used as an acceleration structure buffer. AccelerationStructureInput = (1u << 8), ///< Buffer is used as a read only acceleration instance input buffer. ShaderBindingTable = (1u << 9), ///< Buffer is used as a shader binding table buffer. + VideoDecodeDst = (1u << 10), ///< Buffer is used as an output of the video decoding operation. + VideoDecodeSrc = (1u << 11), ///< Buffer is used as an input of the video decoding operation. }; WISDOM_DEFINE_ENUM_OPERATORS(BufferUsageFlags) @@ -1265,6 +1305,9 @@ enum class TextureUsageFlags : uint32_t { ShaderResource = (1u << 4), ///< Texture is used as a shader resource. UnorderedAccess = (1u << 5), ///< Texture is used as an unordered access resource. HostCopy = (1u << 7), ///< Texture is used for host copy operations. Works with GPUUpload heap. + VideoDecodeDst = (1u << 6), ///< Texture is used as a destination for video decode operations. + VideoDecodeSrc = (1u << 8), ///< Texture is used as a source for video decode operations. + VideoDecodeDpb = (1u << 9), ///< Texture is used as a DPB storage for video decode. }; WISDOM_DEFINE_ENUM_OPERATORS(TextureUsageFlags) @@ -1533,6 +1576,11 @@ enum class ViewHeapFlags : uint32_t { * multisample-related usage. * */ AllowMultisample = (1u << 0), + /** + * @brief Allows the view heap to be used with video targets. If not set, the view heap does not enable video + * target-related usage. + * */ + AllowVideoTargets = (1u << 0), }; WISDOM_DEFINE_ENUM_OPERATORS(ViewHeapFlags) @@ -1822,7 +1870,10 @@ struct BufferDesc { struct TextureDesc { std::uint32_t width; ///< defines texture width in pixels. std::uint32_t height; ///< describes texture height in pixels. - std::uint16_t depth_or_array_size; ///< describes texture depth in pixels. Used only for 3D textures. + /** + * @brief describes texture depth in pixels. Used only for 3D textures. + * */ + std::uint16_t depth_or_array_size; std::uint16_t mip_levels; ///< defines number of mip levels in the texture. wis::DataFormat format; ///< describes texture format. /** @@ -1830,10 +1881,18 @@ struct TextureDesc { * */ wis::SampleCount sample_count; wis::TextureLayout layout; ///< specifies texture layout. Default is `wis::TextureLayout::Texture2D`. - wis::TextureUsageFlags usage_flags; ///< describes texture usage flags. Describe how the texture will be used. + /** + * @brief describes texture usage flags. Describe how the texture will be used. + * */ + wis::TextureUsageFlags usage_flags; wis::TextureFlags flags; ///< describes texture flags. Describe additional options for the texture. wis::MemoryType memory_type; ///< specifies where the texture will be allocated. wis::MemoryFlags memory_flags; ///< describes the flags of the memory to allocate for the texture. + /** + * @brief points to an array of formats that can be used to cast the texture to another format. Used for format + * casting in shaders. + * */ + wis::span cast_formats; }; /** @@ -2533,12 +2592,6 @@ struct DeviceMemoryProperties { * Windows 10 22H2 and later with WDDM 3.0 or later. On Vulkan it requires `VK_EXT_host_image_copy` extension. * */ bool host_image_copy_supported; - /** - * @brief defines bitfield of supported initial resource state transitions for buffers and textures. If a transition - * is supported, the corresponding bit is set to `1`, otherwise `0`. Bit positions are the same as in - * wis::TextureState enum. `wis::TextureState::Undefined` is always supported. - * */ - std::uint32_t supported_initial_transitions; }; /** @@ -2932,7 +2985,7 @@ class DX12Swapchain * */ WIS_NODISCARD inline std::uint32_t GetCurrentIndex(wis::Result& out_result) const noexcept { - std::uint32_t index; + std::uint32_t index{}; const WisResult wis_result = ::wisDX12SwapchainGetCurrentIndex( &_impl_storage, reinterpret_cast(&index) @@ -3059,6 +3112,28 @@ class DX12ViewHeap index )); } + /** + * @brief Provided by Wisdom 0.7.1. Writes a texture view for video decode output and returns the texture view + * handle for it. The heap must have been created with `wis::ViewHeapFlags::AllowVideoTargets` + * @param texture describes a pointer to wis::Texture to write the view for. + * @param render_target specifies a pointer to wis::RenderTargetDesc, which describes the texture view to write. + * @param index defines the index in the view heap to write the view to. + * @return u64 CPU descriptor handle for the view heap. + * + * */ + WIS_NODISCARD inline std::uint64_t WriteVideoDecodeTarget( + const wis::DX12Texture& texture, + const wis::RenderTargetDesc& render_target, + std::uint32_t index + ) const noexcept + { + return (::wisDX12ViewHeapWriteVideoDecodeTarget( + &_impl_storage, + reinterpret_cast(&texture), + reinterpret_cast(&render_target), + index + )); + } /** * @brief Provided by Wisdom 0.7.0. Returns the CPU descriptor handle for the view heap. * @param index defines the index in the view heap to get the descriptor from. @@ -3304,11 +3379,8 @@ class DX12DescriptorHeap * @return Result denoting the outcome of operation. * * */ - inline wis::Result WriteTexture( - wis::DX12TextureView texture, - const wis::TextureBinding& data, - std::uint32_t index - ) const noexcept + inline wis::Result WriteTexture(wis::DX12TextureView texture, const wis::TextureBinding& data, std::uint32_t index) + const noexcept { const WisResult wis_result = ::wisDX12DescriptorHeapWriteTexture( &_impl_storage, @@ -3419,12 +3491,10 @@ class DX12ResourceAllocator * @return buffer points to wis::Buffer, which is initialized on success. * * */ - WIS_NODISCARD inline wis::DX12Buffer CreateBuffer( - const wis::BufferDesc& desc, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::DX12Buffer CreateBuffer(const wis::BufferDesc& desc, wis::Result& out_result) + const noexcept { - wis::DX12Buffer buffer; + wis::DX12Buffer buffer{}; const WisResult wis_result = ::wisDX12ResourceAllocatorCreateBuffer( &_impl_storage, reinterpret_cast(&desc), @@ -3444,12 +3514,10 @@ class DX12ResourceAllocator * @return texture points to wis::Texture, which is initialized on success. * * */ - WIS_NODISCARD inline wis::DX12Texture CreateTexture( - const wis::TextureDesc& desc, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::DX12Texture CreateTexture(const wis::TextureDesc& desc, wis::Result& out_result) + const noexcept { - wis::DX12Texture texture; + wis::DX12Texture texture{}; const WisResult wis_result = ::wisDX12ResourceAllocatorCreateTexture( &_impl_storage, reinterpret_cast(&desc), @@ -3716,11 +3784,8 @@ class DX12CommandList * @param group_count_z specifies number of groups to dispatch in Z dimension; default is 1. * * */ - inline void Dispatch( - std::uint32_t group_count_x, - std::uint32_t group_count_y, - std::uint32_t group_count_z - ) const noexcept + inline void Dispatch(std::uint32_t group_count_x, std::uint32_t group_count_y, std::uint32_t group_count_z) + const noexcept { ::wisDX12CommandListDispatch(&_impl_storage, group_count_x, group_count_y, group_count_z); } @@ -3949,12 +4014,8 @@ class DX12CommandList * @param blend_factor_a specifies blend factor for alpha channel to set. * * */ - inline void SetBlendFactors( - float blend_factor_r, - float blend_factor_g, - float blend_factor_b, - float blend_factor_a - ) const noexcept + inline void SetBlendFactors(float blend_factor_r, float blend_factor_g, float blend_factor_b, float blend_factor_a) + const noexcept { ::wisDX12CommandListSetBlendFactors( &_impl_storage, @@ -4000,7 +4061,7 @@ class DX12CommandAllocator * */ WIS_NODISCARD inline wis::DX12CommandList CreateCommandList(wis::Result& out_result) const noexcept { - wis::DX12CommandList list; + wis::DX12CommandList list{}; const WisResult wis_result = ::wisDX12CommandAllocatorCreateCommandList(&_impl_storage, list.GetStorage()); out_result = wis::Result{ static_cast(wis_result.status), @@ -4088,12 +4149,10 @@ class DX12Device : public wis::impl::Implements(type), @@ -4118,7 +4177,7 @@ class DX12Device : public wis::impl::Implements(type), @@ -4140,7 +4199,7 @@ class DX12Device : public wis::impl::Implements(wis_result.status), @@ -4157,7 +4216,7 @@ class DX12Device : public wis::impl::Implements(wis_result.status), @@ -4178,7 +4237,7 @@ class DX12Device : public wis::impl::Implements(&desc), @@ -4203,7 +4262,7 @@ class DX12Device : public wis::impl::Implements(&desc), @@ -4232,7 +4291,7 @@ class DX12Device : public wis::impl::Implements(type), @@ -4299,7 +4358,7 @@ class DX12Device : public wis::impl::Implements(initial_data.data()), @@ -4320,12 +4379,10 @@ class DX12Device : public wis::impl::Implements data, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::DX12Shader CreateShader(wis::span data, wis::Result& out_result) + const noexcept { - wis::DX12Shader shader; + wis::DX12Shader shader{}; const WisResult wis_result = ::wisDX12DeviceCreateShader( &_impl_storage, reinterpret_cast(data.data()), @@ -4351,7 +4408,7 @@ class DX12Device : public wis::impl::Implements(&desc), @@ -4376,7 +4433,7 @@ class DX12Device : public wis::impl::Implements(&desc), @@ -4397,13 +4454,10 @@ class DX12Device : public wis::impl::Implements(format)) + return (::wisDX12DeviceGetFormatPresentationSupport(&_impl_storage, surface, static_cast(format)) ); } /** @@ -4418,7 +4472,7 @@ class DX12Device : public wis::impl::Implements(&surface), @@ -4470,12 +4524,10 @@ class DX12Device : public wis::impl::Implements(format), @@ -4523,7 +4575,7 @@ class DX12AdapterQuery * */ WIS_NODISCARD inline wis::AdapterDesc GetAdapterDesc(std::size_t index, wis::Result& out_result) const noexcept { - wis::AdapterDesc desc; + wis::AdapterDesc desc{}; const WisResult wis_result = ::wisDX12AdapterQueryGetAdapterDesc( &_impl_storage, index, @@ -4564,7 +4616,7 @@ class DX12AdapterQuery wis::Result& out_result ) const noexcept { - wis::DX12Device device; + wis::DX12Device device{}; const WisResult wis_result = ::wisDX12AdapterQueryCreateDevice( &_impl_storage, index, @@ -4604,12 +4656,10 @@ class DX12Instance * @return query points to wis::AdapterQuery, which is initialized on success. * * */ - WIS_NODISCARD inline wis::DX12AdapterQuery QueryAdapters( - wis::AdapterPreference preference, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::DX12AdapterQuery QueryAdapters(wis::AdapterPreference preference, wis::Result& out_result) + const noexcept { - wis::DX12AdapterQuery query; + wis::DX12AdapterQuery query{}; const WisResult wis_result = ::wisDX12InstanceQueryAdapters( &_impl_storage, static_cast(preference), @@ -4640,7 +4690,7 @@ WIS_NODISCARD inline wis::DX12Instance DX12CreateInstance( wis::Result& out_result ) noexcept { - wis::DX12Instance instance; + wis::DX12Instance instance{}; const WisResult wis_result = ::wisDX12CreateInstance( reinterpret_cast(debug_desc), reinterpret_cast(extensions.data()), @@ -4976,7 +5026,7 @@ class VKSwapchain : public wis::impl::Implements(&index) @@ -5102,6 +5152,28 @@ class VKViewHeap : public wis::impl::Implements(&texture), + reinterpret_cast(&render_target), + index + )); + } /** * @brief Provided by Wisdom 0.7.0. Returns the CPU descriptor handle for the view heap. * @param index defines the index in the view heap to get the descriptor from. @@ -5344,11 +5416,8 @@ class VKDescriptorHeap * @return Result denoting the outcome of operation. * * */ - inline wis::Result WriteTexture( - wis::VKTextureView texture, - const wis::TextureBinding& data, - std::uint32_t index - ) const noexcept + inline wis::Result WriteTexture(wis::VKTextureView texture, const wis::TextureBinding& data, std::uint32_t index) + const noexcept { const WisResult wis_result = ::wisVKDescriptorHeapWriteTexture( &_impl_storage, @@ -5366,11 +5435,8 @@ class VKDescriptorHeap * @return Result denoting the outcome of operation. * * */ - inline wis::Result WriteRWTexture( - wis::VKTextureView texture, - const wis::TextureBinding& data, - std::uint32_t index - ) const noexcept + inline wis::Result WriteRWTexture(wis::VKTextureView texture, const wis::TextureBinding& data, std::uint32_t index) + const noexcept { const WisResult wis_result = ::wisVKDescriptorHeapWriteRWTexture( &_impl_storage, @@ -5460,7 +5526,7 @@ class VKResourceAllocator * */ WIS_NODISCARD inline wis::VKBuffer CreateBuffer(const wis::BufferDesc& desc, wis::Result& out_result) const noexcept { - wis::VKBuffer buffer; + wis::VKBuffer buffer{}; const WisResult wis_result = ::wisVKResourceAllocatorCreateBuffer( &_impl_storage, reinterpret_cast(&desc), @@ -5480,12 +5546,10 @@ class VKResourceAllocator * @return texture points to wis::Texture, which is initialized on success. * * */ - WIS_NODISCARD inline wis::VKTexture CreateTexture( - const wis::TextureDesc& desc, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::VKTexture CreateTexture(const wis::TextureDesc& desc, wis::Result& out_result) + const noexcept { - wis::VKTexture texture; + wis::VKTexture texture{}; const WisResult wis_result = ::wisVKResourceAllocatorCreateTexture( &_impl_storage, reinterpret_cast(&desc), @@ -5749,11 +5813,8 @@ class VKCommandList * @param group_count_z specifies number of groups to dispatch in Z dimension; default is 1. * * */ - inline void Dispatch( - std::uint32_t group_count_x, - std::uint32_t group_count_y, - std::uint32_t group_count_z - ) const noexcept + inline void Dispatch(std::uint32_t group_count_x, std::uint32_t group_count_y, std::uint32_t group_count_z) + const noexcept { ::wisVKCommandListDispatch(&_impl_storage, group_count_x, group_count_y, group_count_z); } @@ -5982,12 +6043,8 @@ class VKCommandList * @param blend_factor_a specifies blend factor for alpha channel to set. * * */ - inline void SetBlendFactors( - float blend_factor_r, - float blend_factor_g, - float blend_factor_b, - float blend_factor_a - ) const noexcept + inline void SetBlendFactors(float blend_factor_r, float blend_factor_g, float blend_factor_b, float blend_factor_a) + const noexcept { ::wisVKCommandListSetBlendFactors( &_impl_storage, @@ -6033,7 +6090,7 @@ class VKCommandAllocator * */ WIS_NODISCARD inline wis::VKCommandList CreateCommandList(wis::Result& out_result) const noexcept { - wis::VKCommandList list; + wis::VKCommandList list{}; const WisResult wis_result = ::wisVKCommandAllocatorCreateCommandList(&_impl_storage, list.GetStorage()); out_result = wis::Result{ static_cast(wis_result.status), @@ -6121,12 +6178,10 @@ class VKDevice : public wis::impl::Implements(type), @@ -6151,7 +6206,7 @@ class VKDevice : public wis::impl::Implements(type), @@ -6173,7 +6228,7 @@ class VKDevice : public wis::impl::Implements(wis_result.status), @@ -6190,7 +6245,7 @@ class VKDevice : public wis::impl::Implements(wis_result.status), @@ -6211,7 +6266,7 @@ class VKDevice : public wis::impl::Implements(&desc), @@ -6236,7 +6291,7 @@ class VKDevice : public wis::impl::Implements(&desc), @@ -6265,7 +6320,7 @@ class VKDevice : public wis::impl::Implements(type), @@ -6332,7 +6387,7 @@ class VKDevice : public wis::impl::Implements(initial_data.data()), @@ -6353,12 +6408,10 @@ class VKDevice : public wis::impl::Implements data, - wis::Result& out_result - ) const noexcept + WIS_NODISCARD inline wis::VKShader CreateShader(wis::span data, wis::Result& out_result) + const noexcept { - wis::VKShader shader; + wis::VKShader shader{}; const WisResult wis_result = ::wisVKDeviceCreateShader( &_impl_storage, reinterpret_cast(data.data()), @@ -6384,7 +6437,7 @@ class VKDevice : public wis::impl::Implements(&desc), @@ -6409,7 +6462,7 @@ class VKDevice : public wis::impl::Implements(&desc), @@ -6430,10 +6483,8 @@ class VKDevice : public wis::impl::Implements(format))); } @@ -6449,7 +6500,7 @@ class VKDevice : public wis::impl::Implements(&surface), @@ -6501,12 +6552,10 @@ class VKDevice : public wis::impl::Implements(format), @@ -6554,7 +6603,7 @@ class VKAdapterQuery * */ WIS_NODISCARD inline wis::AdapterDesc GetAdapterDesc(std::size_t index, wis::Result& out_result) const noexcept { - wis::AdapterDesc desc; + wis::AdapterDesc desc{}; const WisResult wis_result = ::wisVKAdapterQueryGetAdapterDesc( &_impl_storage, index, @@ -6595,7 +6644,7 @@ class VKAdapterQuery wis::Result& out_result ) const noexcept { - wis::VKDevice device; + wis::VKDevice device{}; const WisResult wis_result = ::wisVKAdapterQueryCreateDevice( &_impl_storage, index, @@ -6634,12 +6683,10 @@ class VKInstance : public wis::impl::Implements(preference), @@ -6670,7 +6717,7 @@ WIS_NODISCARD inline wis::VKInstance VKCreateInstance( wis::Result& out_result ) noexcept { - wis::VKInstance instance; + wis::VKInstance instance{}; const WisResult wis_result = ::wisVKCreateInstance( reinterpret_cast(debug_desc), reinterpret_cast(extensions.data()), diff --git a/src/include/wisdom/generated/dx12_convert.hpp b/src/include/wisdom/generated/dx12_convert.hpp index 9e277dc50..4465c66ac 100644 --- a/src/include/wisdom/generated/dx12_convert.hpp +++ b/src/include/wisdom/generated/dx12_convert.hpp @@ -5,7 +5,6 @@ # error "This is a C++ only header" #endif // __cplusplus -#include #include #include #include "c_api.h" @@ -13,7 +12,153 @@ namespace wis { namespace detail { -constexpr inline DXGI_FORMAT DX12Convert(WisDataFormat value) noexcept { return static_cast(value); } +constexpr inline DXGI_FORMAT DX12Convert(WisDataFormat value) noexcept +{ + switch (value) { + case WisDataFormatRGBA32Float: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case WisDataFormatRGBA32Uint: + return DXGI_FORMAT_R32G32B32A32_UINT; + case WisDataFormatRGBA32Sint: + return DXGI_FORMAT_R32G32B32A32_SINT; + case WisDataFormatRGB32Float: + return DXGI_FORMAT_R32G32B32_FLOAT; + case WisDataFormatRGB32Uint: + return DXGI_FORMAT_R32G32B32_UINT; + case WisDataFormatRGB32Sint: + return DXGI_FORMAT_R32G32B32_SINT; + case WisDataFormatRGBA16Float: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case WisDataFormatRGBA16Unorm: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case WisDataFormatRGBA16Uint: + return DXGI_FORMAT_R16G16B16A16_UINT; + case WisDataFormatRGBA16Snorm: + return DXGI_FORMAT_R16G16B16A16_SNORM; + case WisDataFormatRGBA16Sint: + return DXGI_FORMAT_R16G16B16A16_SINT; + case WisDataFormatRG32Float: + return DXGI_FORMAT_R32G32_FLOAT; + case WisDataFormatRG32Uint: + return DXGI_FORMAT_R32G32_UINT; + case WisDataFormatRG32Sint: + return DXGI_FORMAT_R32G32_SINT; + case WisDataFormatD32FloatS8Uint: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case WisDataFormatRGB10A2Unorm: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case WisDataFormatRGB10A2Uint: + return DXGI_FORMAT_R10G10B10A2_UINT; + case WisDataFormatRG11B10Float: + return DXGI_FORMAT_R11G11B10_FLOAT; + case WisDataFormatRGBA8Unorm: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case WisDataFormatRGBA8UnormSrgb: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case WisDataFormatRGBA8Uint: + return DXGI_FORMAT_R8G8B8A8_UINT; + case WisDataFormatRGBA8Snorm: + return DXGI_FORMAT_R8G8B8A8_SNORM; + case WisDataFormatRGBA8Sint: + return DXGI_FORMAT_R8G8B8A8_SINT; + case WisDataFormatRG16Float: + return DXGI_FORMAT_R16G16_FLOAT; + case WisDataFormatRG16Unorm: + return DXGI_FORMAT_R16G16_UNORM; + case WisDataFormatRG16Uint: + return DXGI_FORMAT_R16G16_UINT; + case WisDataFormatRG16Snorm: + return DXGI_FORMAT_R16G16_SNORM; + case WisDataFormatRG16Sint: + return DXGI_FORMAT_R16G16_SINT; + case WisDataFormatD32Float: + return DXGI_FORMAT_D32_FLOAT; + case WisDataFormatR32Float: + return DXGI_FORMAT_R32_FLOAT; + case WisDataFormatR32Uint: + return DXGI_FORMAT_R32_UINT; + case WisDataFormatR32Sint: + return DXGI_FORMAT_R32_SINT; + case WisDataFormatD24UnormS8Uint: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case WisDataFormatRG8Unorm: + return DXGI_FORMAT_R8G8_UNORM; + case WisDataFormatRG8Uint: + return DXGI_FORMAT_R8G8_UINT; + case WisDataFormatRG8Snorm: + return DXGI_FORMAT_R8G8_SNORM; + case WisDataFormatRG8Sint: + return DXGI_FORMAT_R8G8_SINT; + case WisDataFormatR16Float: + return DXGI_FORMAT_R16_FLOAT; + case WisDataFormatR16Unorm: + return DXGI_FORMAT_R16_UNORM; + case WisDataFormatR16Uint: + return DXGI_FORMAT_R16_UINT; + case WisDataFormatR16Snorm: + return DXGI_FORMAT_R16_SNORM; + case WisDataFormatR16Sint: + return DXGI_FORMAT_R16_SINT; + case WisDataFormatR8Unorm: + return DXGI_FORMAT_R8_UNORM; + case WisDataFormatR8Uint: + return DXGI_FORMAT_R8_UINT; + case WisDataFormatR8Snorm: + return DXGI_FORMAT_R8_SNORM; + case WisDataFormatR8Sint: + return DXGI_FORMAT_R8_SINT; + case WisDataFormatRGB9E5UFloat: + return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + case WisDataFormatBC1RGBAUnorm: + return DXGI_FORMAT_BC1_UNORM; + case WisDataFormatBC1RGBAUnormSrgb: + return DXGI_FORMAT_BC1_UNORM_SRGB; + case WisDataFormatBC2RGBAUnorm: + return DXGI_FORMAT_BC2_UNORM; + case WisDataFormatBC2RGBAUnormSrgb: + return DXGI_FORMAT_BC2_UNORM_SRGB; + case WisDataFormatBC3RGBAUnorm: + return DXGI_FORMAT_BC3_UNORM; + case WisDataFormatBC3RGBAUnormSrgb: + return DXGI_FORMAT_BC3_UNORM_SRGB; + case WisDataFormatBC4RUnorm: + return DXGI_FORMAT_BC4_UNORM; + case WisDataFormatBC4RSnorm: + return DXGI_FORMAT_BC4_SNORM; + case WisDataFormatBC5RGUnorm: + return DXGI_FORMAT_BC5_UNORM; + case WisDataFormatBC5RGSnorm: + return DXGI_FORMAT_BC5_SNORM; + case WisDataFormatB5G6R5Unorm: + return DXGI_FORMAT_B5G6R5_UNORM; + case WisDataFormatB5G5R5A1Unorm: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case WisDataFormatBGRA8Unorm: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case WisDataFormatBGRA8UnormSrgb: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case WisDataFormatBC6HUfloat16: + return DXGI_FORMAT_BC6H_TYPELESS; + case WisDataFormatBC6HSfloat16: + return DXGI_FORMAT_BC6H_TYPELESS; + case WisDataFormatBC7RGBAUnorm: + return DXGI_FORMAT_BC7_TYPELESS; + case WisDataFormatBC7RGBAUnormSrgb: + return DXGI_FORMAT_BC7_TYPELESS; + case WisDataFormatBGRA4Unorm: + return DXGI_FORMAT_B4G4R4A4_UNORM; + case WisDataFormatNV12: + return DXGI_FORMAT_NV12; + case WisDataFormatP010: + return DXGI_FORMAT_P010; + case WisDataFormatP012: + return DXGI_FORMAT_P016; + case WisDataFormatP016: + return DXGI_FORMAT_P016; + default: + return static_cast(0); + } +} constexpr inline uint32_t DX12Convert(WisSampleCount value) noexcept { return static_cast(value); } @@ -229,6 +374,8 @@ constexpr inline D3D12_BARRIER_LAYOUT DX12Convert(WisTextureState value) noexcep return D3D12_BARRIER_LAYOUT_RESOLVE_DEST; case WisTextureStateResolveRenderTargetDst: return D3D12_BARRIER_LAYOUT_RESOLVE_DEST; + case WisTextureStateVideoDecodeDPB: + return D3D12_BARRIER_LAYOUT_VIDEO_DECODE_READ; default: return static_cast(0); } @@ -458,6 +605,15 @@ constexpr inline D3D12_RESOURCE_FLAGS DX12Convert(WisTextureUsageFlags value) no if (value & WisTextureUsageFlagsHostCopy) { result |= D3D12_RESOURCE_FLAG_NONE; } + if (value & WisTextureUsageFlagsVideoDecodeDst) { + result |= D3D12_RESOURCE_FLAG_NONE; + } + if (value & WisTextureUsageFlagsVideoDecodeSrc) { + result |= D3D12_RESOURCE_FLAG_NONE; + } + if (value & WisTextureUsageFlagsVideoDecodeDpb) { + result |= D3D12_RESOURCE_FLAG_NONE; + } return result; } @@ -485,6 +641,15 @@ constexpr inline WisTextureUsageFlags DX12Convert(D3D12_RESOURCE_FLAGS value) no if (value & D3D12_RESOURCE_FLAG_NONE) { result = static_cast(result | WisTextureUsageFlagsHostCopy); } + if (value & D3D12_RESOURCE_FLAG_NONE) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeDst); + } + if (value & D3D12_RESOURCE_FLAG_NONE) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeSrc); + } + if (value & D3D12_RESOURCE_FLAG_NONE) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeDpb); + } return result; } diff --git a/src/include/wisdom/generated/vk_convert.hpp b/src/include/wisdom/generated/vk_convert.hpp index aff8b0dc9..24abc9e40 100644 --- a/src/include/wisdom/generated/vk_convert.hpp +++ b/src/include/wisdom/generated/vk_convert.hpp @@ -5,6 +5,7 @@ # error "This is a C++ only header" #endif // __cplusplus +#include #include #include "c_api.h" @@ -148,6 +149,14 @@ constexpr inline VkFormat VKConvert(WisDataFormat value) noexcept return VK_FORMAT_BC7_SRGB_BLOCK; case WisDataFormatBGRA4Unorm: return VK_FORMAT_A4R4G4B4_UNORM_PACK16; + case WisDataFormatNV12: + return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; + case WisDataFormatP010: + return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16; + case WisDataFormatP012: + return VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16; + case WisDataFormatP016: + return VK_FORMAT_G16_B16R16_2PLANE_420_UNORM; default: return static_cast(0); } @@ -407,6 +416,8 @@ constexpr inline VkImageLayout VKConvert(WisTextureState value) noexcept return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; case WisTextureStateResolveRenderTargetDst: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case WisTextureStateVideoDecodeDPB: + return VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR; default: return static_cast(0); } @@ -743,6 +754,12 @@ constexpr inline VkBufferUsageFlags VKConvert(WisBufferUsageFlags value) noexcep if (value & WisBufferUsageFlagsShaderBindingTable) { result |= VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR; } + if (value & WisBufferUsageFlagsVideoDecodeDst) { + result |= VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR; + } + if (value & WisBufferUsageFlagsVideoDecodeSrc) { + result |= VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR; + } return result; } @@ -770,6 +787,15 @@ constexpr inline VkImageUsageFlags VKConvert(WisTextureUsageFlags value) noexcep if (value & WisTextureUsageFlagsHostCopy) { result |= VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT; } + if (value & WisTextureUsageFlagsVideoDecodeDst) { + result |= VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR; + } + if (value & WisTextureUsageFlagsVideoDecodeSrc) { + result |= VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR; + } + if (value & WisTextureUsageFlagsVideoDecodeDpb) { + result |= VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR; + } return result; } @@ -797,6 +823,15 @@ constexpr inline WisTextureUsageFlags VKConvert(VkImageUsageFlags value) noexcep if (value & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) { result = static_cast(result | WisTextureUsageFlagsHostCopy); } + if (value & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeDst); + } + if (value & VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeSrc); + } + if (value & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) { + result = static_cast(result | WisTextureUsageFlagsVideoDecodeDpb); + } return result; } diff --git a/src/include/wisdom/global/definitions.h b/src/include/wisdom/global/definitions.h index 36955fdda..b3bb1c8b5 100644 --- a/src/include/wisdom/global/definitions.h +++ b/src/include/wisdom/global/definitions.h @@ -192,4 +192,21 @@ # define WISDOM_USES_VULKAN 1 #endif // API selection +#if defined(WISDOM_DX12) +# define WISDOM_EXPORT_AGILITY_CUSTOM(SDK_VER) \ + _declspec(dllexport) const unsigned D3D12SDKVersion = SDK_VER; \ + _declspec(dllexport) const char* D3D12SDKPath = ".\\D3D12\\" + +# if defined(DX12SDKVER) +// That means we are using D3D12Agility SDK +# define WISDOM_EXPORT_AGILITY_SYMBOLS() WISDOM_EXPORT_AGILITY_CUSTOM(DX12SDKVER) +# else +# define WISDOM_EXPORT_AGILITY_SYMBOLS() +# endif + +#else // We are using regular D3D12 headers, so we don't need to export these symbols +# define WISDOM_EXPORT_AGILITY_CUSTOM(SDK_VER) +# define WISDOM_EXPORT_AGILITY_SYMBOLS() +#endif // WISDOM_DX12 && !D3D12MA_USING_DIRECTX_HEADERS + #endif // !WIS_GLOBAL_DEFINITIONS_H diff --git a/src/include/wisdom/global/internal.hpp b/src/include/wisdom/global/internal.hpp index 78167e9a2..c1ac2ff2b 100644 --- a/src/include/wisdom/global/internal.hpp +++ b/src/include/wisdom/global/internal.hpp @@ -7,6 +7,12 @@ # include namespace wis { +/// @brief Tag type for in-place construction (for C++11 and later) +struct in_place_t {}; + +/// @brief Constant for in-place construction (for C++11 and later) +static constexpr in_place_t in_place{}; + namespace impl { /// @brief Implements class for querying the internal implementation @@ -27,7 +33,7 @@ struct Implements { /// @brief Default constructor, zeros the storage template - Implements(std::in_place_t in_place, Args&&... args) noexcept + Implements(wis::in_place_t in_place, Args&&... args) noexcept { (void)in_place; // explicitly start life of Impl in our storage diff --git a/src/include/wisdom/vulkan/detail/vk_detail.hpp b/src/include/wisdom/vulkan/detail/vk_detail.hpp index 52472b846..44e833c4b 100644 --- a/src/include/wisdom/vulkan/detail/vk_detail.hpp +++ b/src/include/wisdom/vulkan/detail/vk_detail.hpp @@ -6,19 +6,53 @@ #include #include +#include #include #include +#include #include #include +#include #include +#include namespace wis::impl { struct VKSwapchainImpl; } namespace wis::detail { +template +struct VKScopeGuard { + HandleType handle; + F f; + + VKScopeGuard(HandleType handle, F&& f) noexcept + : handle(handle) + , f(std::forward(f)) + {} + ~VKScopeGuard() noexcept + { + if (handle) { + f(); + } + } + + // Prevent copying + VKScopeGuard(const VKScopeGuard&) = delete; + VKScopeGuard& operator=(const VKScopeGuard&) = delete; + + HandleType* PutUnchecked() noexcept { return &handle; } + HandleType Release() noexcept { return std::exchange(handle, nullptr); } +}; + +template +VKScopeGuard VKMakeScopeGuard(HandleType handle, F&& f) noexcept +{ + return VKScopeGuard(handle, std::forward(f)); +} + //---------------------------------------------------------------------------------------------------------------------- /** * @brief A control block structure that manages reference counting for Vulkan objects. This template struct is designed @@ -165,7 +199,7 @@ struct VKDeviceFeatures { uint16_t resource_desc_size = 0; uint16_t sampler_desc_size = 0; uint16_t max_root_space = 0; - uint16_t supported_image_layout_transitions = 0; // bitmask of supported image layout transitions, indexed by + // WisImageLayout. A bit value of 1 indicates support for the // transition. uint32_t descriptor_heap_reserved_size = 0; @@ -426,6 +460,8 @@ inline constexpr WisTextureState VKConvertToTextureState(VkImageLayout layout) n return WisTextureStateVideoDecodeRead; case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR: return WisTextureStateVideoDecodeWrite; + case VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR: + return WisTextureStateVideoDecodeDPB; } } @@ -448,6 +484,35 @@ inline constexpr VkImageAspectFlags VKAspectFlags(VkFormat format) noexcept } } +//---------------------------------------------------------------------------------------------------------------------- +inline constexpr VkImageAspectFlags VKExtractAspectFlags( + WisSubresourceRange subresource, + WisBarrierFlags flags +) noexcept +{ + VkImageAspectFlags aspect_flags = 0; + if (flags & WisBarrierFlagsDepthResource) { + aspect_flags |= VK_IMAGE_ASPECT_DEPTH_BIT; + } + if (flags & WisBarrierFlagsStencilResource) { + aspect_flags |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + if (aspect_flags != 0) { + // If depth or stencil specified, ignore plane slice and return early + // since depth/stencil views of multi-planar formats are not allowed to have a plane slice. + return aspect_flags; + } + + if ((flags & WisBarrierFlagsPlanarImage) == 0) { + return VK_IMAGE_ASPECT_COLOR_BIT; // If not a planar image, return color aspect for simplicity. + } + + for (uint16_t plane = subresource.plane_slice; plane < subresource.plane_slice_count; ++plane) { + aspect_flags |= VK_IMAGE_ASPECT_PLANE_0_BIT << plane; + } + return aspect_flags; +} + //---------------------------------------------------------------------------------------------------------------------- /** * @brief Releases a Vulkan instance, destroying it if this is the last reference. Also destroys the debug messenger if @@ -554,6 +619,245 @@ inline void VKReleaseSwapchain(VkSwapchainKHR swap, VKSwapchainControlBlock* hea } } +//---------------------------------------------------------------------------------------------------------------------- +// Barrier helper constants +constexpr static uint32_t vk_max_barrier_size = std::max( + {sizeof(VkBufferMemoryBarrier), sizeof(VkImageMemoryBarrier2), sizeof(VkMemoryBarrier2)} +); +constexpr static uint32_t vk_static_barrier_size = WIS_TRANSIENT_MAX_BARRIER_COUNT * vk_max_barrier_size; + +template +inline uint8_t* VKAllocateScratchSpace(const Impl& impl, uint32_t new_size) +{ + if (new_size > impl.scratch_memory_size) { + delete[] impl.scratch_memory; + impl.scratch_memory = new (std::nothrow) uint8_t[new_size]; + impl.scratch_memory_size = impl.scratch_memory ? new_size : 0; + } + return impl.scratch_memory; +} + +template +inline std::array, 3> VKAllocateBarriers( + const Impl& impl, + uint8_t* local_scratch, + const WisVKBarrierGroup& barriers +) +{ + std::array, 3> spans; + std::size_t needed_size = barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2) + + barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2) + + barriers.global_barrier_count * sizeof(VkMemoryBarrier2); + + if (needed_size <= vk_static_barrier_size) { + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + } + + std::size_t sizes[] = { + barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2), + barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2), + barriers.global_barrier_count * sizeof(VkMemoryBarrier2), + 0, + 0, + 0 + }; + + sizes[3] = sizes[0] + sizes[1]; + sizes[4] = sizes[1] + sizes[2]; + sizes[5] = sizes[0] + sizes[2]; + + uint32_t closest_size = 0; + int index = -1; + for (int i = std::size(sizes) - 1; i >= 0; --i) { + if (sizes[i] > vk_static_barrier_size) { + continue; + } + if (vk_static_barrier_size - sizes[i] < vk_static_barrier_size - closest_size) { + closest_size = sizes[i]; + index = i; + } + } + + uint32_t allocated_size = needed_size - closest_size; + auto* allocated_data = VKAllocateScratchSpace(impl, allocated_size); + + switch (index) { + default: + case -1: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 0: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 1: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 2: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {local_scratch, barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 3: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {allocated_data, barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 4: + spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + case 5: + spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; + spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; + spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; + return spans; + } +} + +template +inline void VKInsertBarriers(const Impl& impl, const WisVKBarrierGroup* barriers) +{ + if (barriers->buffer_barrier_count + barriers->texture_barrier_count + barriers->global_barrier_count == 0) { + return; + } + + uint8_t local_scratch[vk_static_barrier_size]{}; + + auto [buffer_span, texture_span, global_span] = VKAllocateBarriers(impl, local_scratch, *barriers); + + wis::span buffer_barriers_span{ + reinterpret_cast(buffer_span.data()), + barriers->buffer_barrier_count + }; + uint32_t real_buffer_barrier_count = barriers->buffer_barrier_count; + + for (size_t i = 0; i < barriers->buffer_barrier_count; i++) { + const auto& src = barriers->buffer_barriers[i]; + + auto q1 = VK_QUEUE_FAMILY_IGNORED; + auto q2 = VK_QUEUE_FAMILY_IGNORED; + if (src.queue_type_before != src.queue_type_after) { + if (impl.maintenance9) { + real_buffer_barrier_count--; + continue; + } + q1 = impl.queue_indices[src.queue_type_before].family_index; + q2 = impl.queue_indices[src.queue_type_after].family_index; + } + + buffer_barriers_span[i] = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, + .pNext = nullptr, + .srcStageMask = VKConvert(src.sync_before), + .srcAccessMask = VKConvert(src.access_before), + .dstStageMask = VKConvert(src.sync_after), + .dstAccessMask = VKConvert(src.access_after), + .srcQueueFamilyIndex = q1, + .dstQueueFamilyIndex = q2, + .buffer = std::bit_cast(src.buffer), + .offset = src.offset, + .size = src.size, + }; + } + + wis::span texture_barriers_span{ + reinterpret_cast(texture_span.data()), + barriers->texture_barrier_count + }; + uint32_t real_texture_barrier_count = barriers->texture_barrier_count; + + for (size_t i = 0; i < barriers->texture_barrier_count; i++) { + const auto& src = barriers->texture_barriers[i]; + auto q1 = VK_QUEUE_FAMILY_IGNORED; + auto q2 = VK_QUEUE_FAMILY_IGNORED; + + if (src.queue_type_before != src.queue_type_after) { + if (impl.maintenance9 + && (impl.queue_indices[src.queue_type_before].compatible_to_families + & (1 << impl.queue_indices[src.queue_type_after].family_index))) { + if (src.queue_type_before == impl.queue_type) { + real_texture_barrier_count--; + continue; + } + } else { + q1 = impl.queue_indices[src.queue_type_before].family_index; + q2 = impl.queue_indices[src.queue_type_after].family_index; + } + } + + texture_barriers_span[i] = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, + .pNext = nullptr, + .srcStageMask = VKConvert(src.sync_before), + .srcAccessMask = VKConvert(src.access_before), + .dstStageMask = VKConvert(src.sync_after), + .dstAccessMask = VKConvert(src.access_after), + .oldLayout = VKConvert(src.state_before), + .newLayout = VKConvert(src.state_after), + .srcQueueFamilyIndex = q1, + .dstQueueFamilyIndex = q2, + .image = std::bit_cast(src.texture) + }; + + auto aspect_flags = VKExtractAspectFlags(src.subresource_range, src.flags); + if (src.flags & WisBarrierFlagsWholeRange) { + texture_barriers_span[i].subresourceRange = { + .aspectMask = aspect_flags, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }; + } else { + texture_barriers_span[i].subresourceRange = { + .aspectMask = aspect_flags, + .baseMipLevel = src.subresource_range.base_mip_level, + .levelCount = src.subresource_range.mip_level_count, + .baseArrayLayer = src.subresource_range.base_array_layer, + .layerCount = src.subresource_range.array_layer_count, + }; + } + } + + wis::span global_barriers_span{ + reinterpret_cast(global_span.data()), + barriers->global_barrier_count + }; + + for (size_t i = 0; i < barriers->global_barrier_count; i++) { + const auto& src = barriers->global_barriers[i]; + global_barriers_span[i] = { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + .pNext = nullptr, + .srcStageMask = VKConvert(src.sync_before), + .srcAccessMask = VKConvert(src.access_before), + .dstStageMask = VKConvert(src.sync_after), + .dstAccessMask = VKConvert(src.access_after), + }; + } + + VkDependencyInfo dependency_info{ + .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + .pNext = nullptr, + .memoryBarrierCount = static_cast(barriers->global_barrier_count), + .pMemoryBarriers = global_barriers_span.data(), + .bufferMemoryBarrierCount = real_buffer_barrier_count, + .pBufferMemoryBarriers = buffer_barriers_span.data(), + .imageMemoryBarrierCount = real_texture_barrier_count, + .pImageMemoryBarriers = texture_barriers_span.data(), + }; + impl.command_list_table->vkCmdPipelineBarrier2(impl.command_buffer, &dependency_info); +} } // namespace wis::detail #endif // WIS_VK_DETAIL_HPP diff --git a/src/include/wisdom/vulkan/detail/vk_ext1.hpp b/src/include/wisdom/vulkan/detail/vk_ext1.hpp index 4c30590e6..443490af3 100644 --- a/src/include/wisdom/vulkan/detail/vk_ext1.hpp +++ b/src/include/wisdom/vulkan/detail/vk_ext1.hpp @@ -207,46 +207,6 @@ struct DeviceExtension1 : VKDeviceExtensionImpl { features.max_vertex_bindings = static_cast(device_properties.properties.limits.maxVertexInputBindings); features.multiple_viewports = device_properties.properties.limits.maxViewports > 1 ? 1 : 0; - if (features.host_image_copy) { - // Host image copy support - auto& host_image_copy_properties = *collector.GetEnabledPropertyStruct< - VkPhysicalDeviceHostImageCopyPropertiesEXT>( - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT - ); - - static constexpr std::size_t reasonable_layout_count = 32; - VkImageLayout dst_layouts[reasonable_layout_count]{}; - std::unique_ptr dynamic_dst_layouts; - wis::span dst_layout_span; - - if (host_image_copy_properties.copyDstLayoutCount > reasonable_layout_count) { - dynamic_dst_layouts = std::make_unique(host_image_copy_properties.copyDstLayoutCount); - dst_layout_span = wis::span{ - dynamic_dst_layouts.get(), - host_image_copy_properties.copyDstLayoutCount - }; - } else { - dst_layout_span = wis::span{dst_layouts, host_image_copy_properties.copyDstLayoutCount}; - } - - // We are not interested in src layouts. - host_image_copy_properties.pCopyDstLayouts = dst_layout_span.data(); - device_properties.pNext = &host_image_copy_properties; - - auto& atable = device_impl.device_header->header.shared_header->header.adapter_table; - auto adapter = device_impl.physical_device; - - atable.vkGetPhysicalDeviceProperties2(adapter, &device_properties); - - for (uint32_t i = 0; i < host_image_copy_properties.copyDstLayoutCount; ++i) { - WisTextureState dst_layout = VKConvertToTextureState(dst_layout_span[i]); - if (dst_layout == WisTextureStateUndefined) { - continue; // Unsupported layout, skip - } - features.supported_image_layout_transitions |= (1 << static_cast(dst_layout_span[i])); - } - } - // Nothing to initialize for now return wis::detail::vk_success; } diff --git a/src/include/wisdom/vulkan/vk_command_list.cpp b/src/include/wisdom/vulkan/vk_command_list.cpp index c3c754e29..149a867c3 100644 --- a/src/include/wisdom/vulkan/vk_command_list.cpp +++ b/src/include/wisdom/vulkan/vk_command_list.cpp @@ -1,152 +1,10 @@ #ifndef WIS_VK_COMMAND_LIST_CPP #define WIS_VK_COMMAND_LIST_CPP #include -#include #include +#include #include -#include - -namespace wis::detail { -constexpr static uint32_t vk_max_barrier_size = std::max( - {sizeof(VkBufferMemoryBarrier), sizeof(VkImageMemoryBarrier2), sizeof(VkMemoryBarrier2)} -); -constexpr static uint32_t vk_static_size = wis::TransientMaxBarrierCount * vk_max_barrier_size; - -inline uint8_t* VKAllocateScratchSpace(const wis::impl::VKCommandListImpl& impl, uint32_t new_size) -{ - if (new_size > impl.scratch_memory_size) { - delete[] impl.scratch_memory; - impl.scratch_memory = new (std::nothrow) uint8_t[new_size]; - } - return impl.scratch_memory; -} -inline constexpr VkImageAspectFlags VKExtractAspectFlags( - WisSubresourceRange subresource, - WisBarrierFlags flags -) noexcept -{ - VkImageAspectFlags aspect_flags = 0; - if (flags & WisBarrierFlagsDepthResource) { - aspect_flags |= VK_IMAGE_ASPECT_DEPTH_BIT; - } - if (flags & WisBarrierFlagsStencilResource) { - aspect_flags |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - if (aspect_flags != 0) { - // If depth or stencil specified, ignore plane slice and return early - // since depth/stencil views of multi-planar formats are not allowed to have a plane slice. - return aspect_flags; - } - - if ((flags & WisBarrierFlagsPlanarImage) == 0) { - return VK_IMAGE_ASPECT_COLOR_BIT; // If not a planar image, return color aspect for simplicity. - } - - for (uint16_t plane = subresource.plane_slice; plane < subresource.plane_slice_count; ++plane) { - aspect_flags |= VK_IMAGE_ASPECT_PLANE_0_BIT << plane; - } - return aspect_flags; -} - -inline std::array, 3> VKAllocateBarriers( - const wis::impl::VKCommandListImpl& impl, - uint8_t* local_scratch, - const WisVKBarrierGroup& barriers -) -{ - std::array, 3> spans; - std::size_t needed_size = barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2) - + barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2) - + barriers.global_barrier_count * sizeof(VkMemoryBarrier2); - - if (needed_size <= vk_static_size) { - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - } - - std::size_t sizes[] = { - barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2), - barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2), - barriers.global_barrier_count * sizeof(VkMemoryBarrier2), - 0, - 0, - 0 - }; - - sizes[3] = sizes[0] + sizes[1]; - sizes[4] = sizes[1] + sizes[2]; - sizes[5] = sizes[0] + sizes[2]; - - // find closest value from below - uint32_t closest_size = 0; - int index = -1; - for (int i = std::size(sizes) - 1; i >= 0; --i) { - if (sizes[i] > vk_static_size) { - continue; - } - - // less than or equal to static size, check if it's the closest one - if (vk_static_size - sizes[i] < vk_static_size - closest_size) { - closest_size = sizes[i]; - index = i; - } - } - - uint32_t allocated_size = needed_size - closest_size; - - // allocate from the command list's scratch memory if the needed size exceeds the local scratch buffer size. This is - // to avoid large stack allocations. - auto* allocated_data = wis::detail::VKAllocateScratchSpace(impl, allocated_size); - - // set pointers to the right offsets in the allocated scratch memory - switch (index) { - default: - case -1: - // no single group can fit into the local scratch, allocate all from the command list's scratch memory - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 0: - // buffer barriers fit into local scratch, texture and global barriers allocated from command list's scratch - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 1: - // texture barriers fit into local scratch, buffer and global barriers allocated from command list's scratch - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 2: - // global barriers fit into local scratch, buffer and texture barriers allocated from command list's scratch - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {local_scratch, barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 3: - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {spans[0].end(), barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {allocated_data, barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 4: - spans[0] = {allocated_data, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {local_scratch, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[1].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - case 5: - spans[0] = {local_scratch, barriers.buffer_barrier_count * sizeof(VkBufferMemoryBarrier2)}; - spans[1] = {allocated_data, barriers.texture_barrier_count * sizeof(VkImageMemoryBarrier2)}; - spans[2] = {spans[0].end(), barriers.global_barrier_count * sizeof(VkMemoryBarrier2)}; - return spans; - } -} -} // namespace wis::detail - //---------------------------------------------------------------------------------------------------------------------- WIS_EXTERN_C WISDOM_API void wisVKDestroyCommandList(WisVKCommandList* self) { @@ -307,150 +165,8 @@ WIS_EXTERN_C WISDOM_API void wisVKCommandListInsertBarriers( const WisVKBarrierGroup* barriers ) { - // clang-format off - if (barriers->buffer_barrier_count + - barriers->texture_barrier_count + - barriers->global_barrier_count == 0) { - return; - } - // clang-format on - auto& impl = wis::from_handle_ref(self); - auto& device_header = impl.command_pool_header->header; - uint8_t local_scratch[wis::detail::vk_static_size]{}; - - auto [buffer_span, texture_span, global_span] = wis::detail::VKAllocateBarriers(impl, local_scratch, *barriers); - - wis::span buffer_barriers_span{ - reinterpret_cast(buffer_span.data()), - barriers->buffer_barrier_count - }; - uint32_t real_buffer_barrier_count = barriers->buffer_barrier_count; - - for (size_t i = 0; i < barriers->buffer_barrier_count; i++) { - const auto& src = barriers->buffer_barriers[i]; - - auto q1 = VK_QUEUE_FAMILY_IGNORED; - auto q2 = VK_QUEUE_FAMILY_IGNORED; - if (src.queue_type_before != src.queue_type_after) { - // skip barriers that only perform queue ownership transfer - if (impl.maintenance9) { - real_buffer_barrier_count--; - continue; - } - q1 = impl.queue_indices[src.queue_type_before].family_index; - q2 = impl.queue_indices[src.queue_type_after].family_index; - } - - buffer_barriers_span[i] = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = wis::detail::VKConvert(src.sync_before), - .srcAccessMask = wis::detail::VKConvert(src.access_before), - .dstStageMask = wis::detail::VKConvert(src.sync_after), - .dstAccessMask = wis::detail::VKConvert(src.access_after), - .srcQueueFamilyIndex = q1, - .dstQueueFamilyIndex = q2, - .buffer = std::bit_cast(src.buffer), - .offset = src.offset, - .size = src.size, - }; - } - - // convert texture barriers - wis::span texture_barriers_span{ - reinterpret_cast(texture_span.data()), - barriers->texture_barrier_count - }; - uint32_t real_texture_barrier_count = barriers->texture_barrier_count; - - for (size_t i = 0; i < barriers->texture_barrier_count; i++) { - const auto& src = barriers->texture_barriers[i]; - auto q1 = VK_QUEUE_FAMILY_IGNORED; - auto q2 = VK_QUEUE_FAMILY_IGNORED; - - if (src.queue_type_before != src.queue_type_after) { - // skip barriers that only perform queue ownership transfer or relaxed transitions if maintenance9 is - // supported - if (impl.maintenance9 - && (impl.queue_indices[src.queue_type_before].compatible_to_families - & (1 << impl.queue_indices[src.queue_type_after].family_index))) { - // Skip only release barriers - // Acquire barriers will just perform relaxed transitions. - if (src.queue_type_before == impl.queue_type) { - real_texture_barrier_count--; - continue; - } - } else { - q1 = impl.queue_indices[src.queue_type_before].family_index; - q2 = impl.queue_indices[src.queue_type_after].family_index; - } - } - - texture_barriers_span[i] = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = wis::detail::VKConvert(src.sync_before), - .srcAccessMask = wis::detail::VKConvert(src.access_before), - .dstStageMask = wis::detail::VKConvert(src.sync_after), - .dstAccessMask = wis::detail::VKConvert(src.access_after), - .oldLayout = wis::detail::VKConvert(src.state_before), - .newLayout = wis::detail::VKConvert(src.state_after), - .srcQueueFamilyIndex = q1, - .dstQueueFamilyIndex = q2, - .image = std::bit_cast(src.texture) - }; - - auto aspect_flags = wis::detail::VKExtractAspectFlags(src.subresource_range, src.flags); - if (src.flags & WisBarrierFlagsWholeRange) { - texture_barriers_span[i].subresourceRange = { - .aspectMask = aspect_flags, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }; - } else { - texture_barriers_span[i].subresourceRange = { - .aspectMask = aspect_flags, - .baseMipLevel = src.subresource_range.base_mip_level, - .levelCount = src.subresource_range.mip_level_count, - .baseArrayLayer = src.subresource_range.base_array_layer, - .layerCount = src.subresource_range.array_layer_count, - }; - } - } - - // convert global barriers - wis::span global_barriers_span{ - reinterpret_cast(global_span.data()), - barriers->global_barrier_count - }; - - for (size_t i = 0; i < barriers->global_barrier_count; i++) { - const auto& src = barriers->global_barriers[i]; - global_barriers_span[i] = { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, - .pNext = nullptr, - .srcStageMask = wis::detail::VKConvert(src.sync_before), - .srcAccessMask = wis::detail::VKConvert(src.access_before), - .dstStageMask = wis::detail::VKConvert(src.sync_after), - .dstAccessMask = wis::detail::VKConvert(src.access_after), - }; - } - - // future work: support image barriers - VkDependencyInfo dependency_info{ - .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - .pNext = nullptr, - .memoryBarrierCount = static_cast(barriers->global_barrier_count), - .pMemoryBarriers = global_barriers_span.data(), - .bufferMemoryBarrierCount = real_buffer_barrier_count, - .pBufferMemoryBarriers = buffer_barriers_span.data(), - .imageMemoryBarrierCount = real_texture_barrier_count, - .pImageMemoryBarriers = texture_barriers_span.data(), - }; - impl.command_list_table->vkCmdPipelineBarrier2(impl.command_buffer, &dependency_info); + wis::detail::VKInsertBarriers(impl, barriers); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/include/wisdom/vulkan/vk_descriptor_heap.cpp b/src/include/wisdom/vulkan/vk_descriptor_heap.cpp index aabfbe937..ca54117a7 100644 --- a/src/include/wisdom/vulkan/vk_descriptor_heap.cpp +++ b/src/include/wisdom/vulkan/vk_descriptor_heap.cpp @@ -220,6 +220,102 @@ inline VkImageViewCreateInfo VKGetUAVDesc(const WisTextureBinding& binding) noex } return srv_desc; } + +inline uint64_t VKViewHeapWriteRenderTarget( + const WisVKViewHeap* self, + const WisVKTexture* texture, + const WisRenderTargetDesc* render_target, + uint32_t index, + void* pNext = nullptr +) +{ + auto& heap = wis::from_handle_ref(self); + auto& tex = wis::from_handle_ref(texture); + auto& header = heap.device_header->header; + + // simply create image view + auto vk_format = wis::detail::VKConvert(render_target->format); + VkImageViewCreateInfo info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = pNext, + .image = tex.image, + .format = vk_format, + }; + info.subresourceRange.aspectMask = wis::detail::VKAspectFlags(vk_format); + + switch (render_target->layout) { + case WisTextureLayoutTexture1D: + info.viewType = VK_IMAGE_VIEW_TYPE_1D; + info.subresourceRange.baseMipLevel = render_target->mip_level; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = 0, info.subresourceRange.layerCount = 1; + break; + case WisTextureLayoutTexture2D: + info.viewType = VK_IMAGE_VIEW_TYPE_2D; + info.subresourceRange.baseMipLevel = render_target->mip_level; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = 0, info.subresourceRange.layerCount = 1; + break; + case WisTextureLayoutTexture3D: + info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + info.subresourceRange.baseMipLevel = render_target->mip_level; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = render_target->base_array_layer; + info.subresourceRange.layerCount = render_target->array_layer_count; + break; + case WisTextureLayoutTexture1DArray: + info.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + info.subresourceRange.baseMipLevel = render_target->mip_level; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = render_target->base_array_layer; + info.subresourceRange.layerCount = render_target->array_layer_count; + break; + case WisTextureLayoutTexture2DArray: + info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + info.subresourceRange.baseMipLevel = render_target->mip_level; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = render_target->base_array_layer; + info.subresourceRange.layerCount = render_target->array_layer_count; + break; + case WisTextureLayoutTexture2DMS: + info.viewType = VK_IMAGE_VIEW_TYPE_2D; + info.subresourceRange.baseMipLevel = 0; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = 0; + info.subresourceRange.layerCount = 1; + break; + case WisTextureLayoutTexture2DMSArray: + info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + info.subresourceRange.baseMipLevel = 0; + info.subresourceRange.levelCount = 1; + info.subresourceRange.baseArrayLayer = render_target->base_array_layer; + info.subresourceRange.layerCount = render_target->array_layer_count; + break; + default: + break; + } + + // Get at index position in the view heap + wis::detail::VKRenderTargetView& out_render_target = heap.view_heap[index]; + if (out_render_target.view != VK_NULL_HANDLE) { + header.device_table.vkDestroyImageView(header.device, out_render_target.view, nullptr); + } + + VkImageView view = VK_NULL_HANDLE; + auto vr = header.device_table.vkCreateImageView(header.device, &info, nullptr, &view); + if (!wis::detail::succeeded(vr)) { + return 0; // Failed to create image view, return 0 as an invalid handle + } + + out_render_target = { + .view = view, + .width = tex.width, + .height = tex.height, + .array_layer_count = tex.depth_or_array_size, + }; + + return std::bit_cast(&out_render_target); +} } // namespace wis::detail //---------------------------------------------------------------------------------------------------------------------- @@ -414,8 +510,14 @@ WISDOM_API WisResult wisVKDescriptorHeapWriteTexture( .size = heap.descriptor_size, }; + VkImageViewUsageCreateInfo usage_info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, + .pNext = nullptr, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT + }; VkImageViewCreateInfo view_create_info = wis::detail::VKGetSRVDesc(*data); view_create_info.image = std::bit_cast(view); + view_create_info.pNext = &usage_info; VkImageDescriptorInfoEXT image_desc{ .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, @@ -530,92 +632,7 @@ WIS_EXTERN_C WISDOM_API uint64_t wisVKViewHeapWriteRenderTarget( uint32_t index ) { - auto& heap = wis::from_handle_ref(self); - auto& tex = wis::from_handle_ref(texture); - auto& header = heap.device_header->header; - - // simply create image view - auto vk_format = wis::detail::VKConvert(render_target->format); - VkImageViewCreateInfo info{ - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = nullptr, - .image = tex.image, - .format = vk_format, - }; - info.subresourceRange.aspectMask = wis::detail::VKAspectFlags(vk_format); - - switch (render_target->layout) { - case WisTextureLayoutTexture1D: - info.viewType = VK_IMAGE_VIEW_TYPE_1D; - info.subresourceRange.baseMipLevel = render_target->mip_level; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = 0, info.subresourceRange.layerCount = 1; - break; - case WisTextureLayoutTexture2D: - info.viewType = VK_IMAGE_VIEW_TYPE_2D; - info.subresourceRange.baseMipLevel = render_target->mip_level; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = 0, info.subresourceRange.layerCount = 1; - break; - case WisTextureLayoutTexture3D: - info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - info.subresourceRange.baseMipLevel = render_target->mip_level; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = render_target->base_array_layer; - info.subresourceRange.layerCount = render_target->array_layer_count; - break; - case WisTextureLayoutTexture1DArray: - info.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY; - info.subresourceRange.baseMipLevel = render_target->mip_level; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = render_target->base_array_layer; - info.subresourceRange.layerCount = render_target->array_layer_count; - break; - case WisTextureLayoutTexture2DArray: - info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - info.subresourceRange.baseMipLevel = render_target->mip_level; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = render_target->base_array_layer; - info.subresourceRange.layerCount = render_target->array_layer_count; - break; - case WisTextureLayoutTexture2DMS: - info.viewType = VK_IMAGE_VIEW_TYPE_2D; - info.subresourceRange.baseMipLevel = 0; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = 0; - info.subresourceRange.layerCount = 1; - break; - case WisTextureLayoutTexture2DMSArray: - info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - info.subresourceRange.baseMipLevel = 0; - info.subresourceRange.levelCount = 1; - info.subresourceRange.baseArrayLayer = render_target->base_array_layer; - info.subresourceRange.layerCount = render_target->array_layer_count; - break; - default: - break; - } - - // Get at index position in the view heap - wis::detail::VKRenderTargetView& out_render_target = heap.view_heap[index]; - if (out_render_target.view != VK_NULL_HANDLE) { - header.device_table.vkDestroyImageView(header.device, out_render_target.view, nullptr); - } - - VkImageView view = VK_NULL_HANDLE; - auto vr = header.device_table.vkCreateImageView(header.device, &info, nullptr, &view); - if (!wis::detail::succeeded(vr)) { - return 0; // Failed to create image view, return 0 as an invalid handle - } - - out_render_target = { - .view = view, - .width = tex.width, - .height = tex.height, - .array_layer_count = tex.depth_or_array_size, - }; - - return std::bit_cast(&out_render_target); + return wis::detail::VKViewHeapWriteRenderTarget(self, texture, render_target, index); } //---------------------------------------------------------------------------------------------------------------------- @@ -631,6 +648,22 @@ WIS_EXTERN_C WISDOM_API uint64_t wisVKViewHeapWriteDepthStencil( return wisVKViewHeapWriteRenderTarget(self, texture, render_target, index); } +//---------------------------------------------------------------------------------------------------------------------- +WIS_EXTERN_C WISDOM_API uint64_t wisVKViewHeapWriteVideoDecodeTarget( + const WisVKViewHeap* self, + const WisVKTexture* texture, + const WisRenderTargetDesc* render_target, + uint32_t index +) +{ + VkImageViewUsageCreateInfo usage_info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, + .pNext = nullptr, + .usage = VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR + }; + return wis::detail::VKViewHeapWriteRenderTarget(self, texture, render_target, index, &usage_info); +} + //---------------------------------------------------------------------------------------------------------------------- WIS_EXTERN_C WISDOM_API uint64_t wisVKViewHeapGetViewAddress(const WisVKViewHeap* self, uint32_t index) { diff --git a/src/include/wisdom/vulkan/vk_device.cpp b/src/include/wisdom/vulkan/vk_device.cpp index f025a44d4..b9474aced 100644 --- a/src/include/wisdom/vulkan/vk_device.cpp +++ b/src/include/wisdom/vulkan/vk_device.cpp @@ -706,12 +706,31 @@ WIS_EXTERN_C WISDOM_API void wisVKDeviceQueryProperties(const WisVKDevice* self, case WisQueryPropertyTypeDeviceMemoryProperties: { auto* props = static_cast(next); props->host_image_copy_supported = header.features.host_image_copy; - props->supported_initial_transitions = header.features.supported_image_layout_transitions; const VkPhysicalDeviceMemoryProperties* mem_props; vmaGetMemoryProperties(header.allocator, &mem_props); + // Find largest VRAM heap. + uint64_t largest_vram_heap_size = 0; + uint32_t largest_vram_heap_index = 0; + for (uint32_t i = 0; i < mem_props->memoryHeapCount; ++i) { + if (mem_props->memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) { + auto heap_size = mem_props->memoryHeaps[i].size; + if (heap_size > largest_vram_heap_size) { + largest_vram_heap_size = heap_size; + largest_vram_heap_index = i; + } + } + } + + // Scan memory types to find one that is HOST_VISIBLE, HOST_COHERENT and DEVICE_LOCAL, and belongs to the + // largest VRAM heap. + props->gpu_upload_supported = false; for (uint32_t i = 0; i < mem_props->memoryTypeCount; ++i) { + if ((mem_props->memoryTypes[i].heapIndex != largest_vram_heap_index)) { + continue; + } + const VkMemoryPropertyFlags flags = mem_props->memoryTypes[i].propertyFlags; if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) && (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { @@ -719,6 +738,7 @@ WIS_EXTERN_C WISDOM_API void wisVKDeviceQueryProperties(const WisVKDevice* self, break; } } + } break; case WisQueryPropertyTypeDeviceBindingProperties: { auto* props = static_cast(next); diff --git a/src/include/wisdom/vulkan/vk_extensions.hpp b/src/include/wisdom/vulkan/vk_extensions.hpp index 7a31aaa4c..563d29c2e 100644 --- a/src/include/wisdom/vulkan/vk_extensions.hpp +++ b/src/include/wisdom/vulkan/vk_extensions.hpp @@ -108,7 +108,7 @@ struct WISDOM_API VKInstanceExtensionCollector { constexpr static std::size_t instance_ext_initial_size = 4; public: - VKInstanceExtensionCollector(const impl::VKMainGlobal& table, WisResult& out_result) noexcept; + WIS_INLINE VKInstanceExtensionCollector(const impl::VKMainGlobal& table, WisResult& out_result) noexcept; public: void EnableExtension(const char* name) noexcept @@ -142,7 +142,7 @@ struct WISDOM_API VKInstanceExtensionCollector { std::size_t count_exts; std::size_t count_layers; }; - WIS_NODISCARD ExtReturn GetExtensionsAndLayers(WisResult& out_res) const noexcept; + WIS_NODISCARD WIS_INLINE ExtReturn GetExtensionsAndLayers(WisResult& out_res) const noexcept; private: detail::CStringSet enabled_extension_names_set; @@ -162,7 +162,7 @@ struct WISDOM_API VKDeviceExtensionCollector { }; public: - VKDeviceExtensionCollector( + WIS_INLINE VKDeviceExtensionCollector( const impl::VKMainAdapter& adapter_table, VkPhysicalDevice adapter, WisResult& res diff --git a/src/include/wisdom/vulkan/vk_impl.cpp b/src/include/wisdom/vulkan/vk_impl.cpp index 261c0533e..84bd85b66 100644 --- a/src/include/wisdom/vulkan/vk_impl.cpp +++ b/src/include/wisdom/vulkan/vk_impl.cpp @@ -10,6 +10,7 @@ WIS_EXTERN_C WISDOM_API void wisVKDestroyBuffer(WisVKBuffer* self) { auto& impl = wis::from_handle_ref(self); if (impl.buffer != VK_NULL_HANDLE) { + // get allocator VmaAllocator allocator = impl.device_header->header.allocator; diff --git a/src/include/wisdom/vulkan/vk_resource_allocator.cpp b/src/include/wisdom/vulkan/vk_resource_allocator.cpp index 615acaa20..75a2bb7b8 100644 --- a/src/include/wisdom/vulkan/vk_resource_allocator.cpp +++ b/src/include/wisdom/vulkan/vk_resource_allocator.cpp @@ -9,13 +9,18 @@ namespace wis::detail { inline VkImageCreateInfo VKFillImageDesc(const WisTextureDesc& desc) noexcept { + VkImageUsageFlags usage = wis::detail::VKConvert(desc.usage_flags); VkImageCreateInfo info{ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .pNext = nullptr, - .flags = 0, + .flags = (usage + & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR + | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR)) + ? VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR + : VkImageCreateFlags{0}, .format = wis::detail::VKConvert(desc.format), .samples = VK_SAMPLE_COUNT_1_BIT, - .usage = wis::detail::VKConvert(desc.usage_flags), + .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, }; @@ -108,6 +113,11 @@ wisVKResourceAllocatorCreateBuffer(const WisVKResourceAllocator* self, const Wis .usage = (VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | wis::detail::VKConvert(desc->usage_flags)), }; + buffer_info.flags = (buffer_info.usage + & (VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR)) + ? VK_BUFFER_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR + : 0; + VmaAllocationCreateFlags flags = wis::detail::VKConvert(desc->memory_flags); if (desc->memory_flags & WisMemoryFlagsMapped) { switch (desc->memory_type) { @@ -181,6 +191,36 @@ WIS_EXTERN_C WISDOM_API WisResult wisVKResourceAllocatorCreateTexture( VkImageCreateInfo image_info = wis::detail::VKFillImageDesc(*desc); + // Castable formats + static constexpr size_t max_cast_formats = 16; + + VkFormat cast_formats[max_cast_formats]; + std::unique_ptr cast_formats_ptr; + wis::span cast_formats_span; + VkImageFormatListCreateInfo format_list_info{ + .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, + .pNext = nullptr, + .viewFormatCount = static_cast(desc->cast_format_count) + 1, + }; + size_t fmt_count = desc->cast_format_count + 1; // +1 for the main format + + if (desc->cast_format_count > 0) { + if (desc->cast_format_count > max_cast_formats - 1) { + cast_formats_ptr = std::make_unique(fmt_count); + cast_formats_span = {cast_formats_ptr.get(), fmt_count}; + } else { + cast_formats_span = {cast_formats, fmt_count}; + } + + cast_formats_span[0] = wis::detail::VKConvert(desc->format); + for (size_t i = 1; i < fmt_count; ++i) { + cast_formats_span[i] = wis::detail::VKConvert(desc->cast_formats[i - 1]); + } + format_list_info.pViewFormats = cast_formats_span.data(); + image_info.pNext = &format_list_info; + image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + } + VmaAllocationCreateFlags flags = wis::detail::VKConvert(desc->memory_flags) & ~VMA_ALLOCATION_CREATE_MAPPED_BIT; VmaAllocationCreateInfo alloc_info{ .flags = flags, diff --git a/src/include/wisdom/vulkan/vk_swapchain.cpp b/src/include/wisdom/vulkan/vk_swapchain.cpp index c1d0816e2..bc8d2b1bb 100644 --- a/src/include/wisdom/vulkan/vk_swapchain.cpp +++ b/src/include/wisdom/vulkan/vk_swapchain.cpp @@ -335,6 +335,9 @@ wisVKSwapchainGetTextures(const WisVKSwapchain* self, WisVKTexture* buffers, siz new (&tex) wis::impl::VKTextureImpl{ .image = image, + .width = static_cast(impl.swapchain_header->header.create_info.imageExtent.width), + .height = static_cast(impl.swapchain_header->header.create_info.imageExtent.height), + .depth_or_array_size = static_cast(impl.swapchain_header->header.create_info.imageArrayLayers), .owned_by_swapchain = true, }; } diff --git a/src/include/wisdom/vulkan/vk_tables.hpp b/src/include/wisdom/vulkan/vk_tables.hpp index 2a65e6967..0fed82c81 100644 --- a/src/include/wisdom/vulkan/vk_tables.hpp +++ b/src/include/wisdom/vulkan/vk_tables.hpp @@ -193,6 +193,12 @@ struct VKMainCommandList { PFN_vkCmdBindVertexBuffers3KHR vkCmdBindVertexBuffers3KHR; PFN_vkCmdBindIndexBuffer3KHR vkCmdBindIndexBuffer3KHR; + // Video decode functions (placed here, for lesser space consumption) + PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR; + PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR; + PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR; + PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR; + public: bool Init(VkDevice device, PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr) noexcept { @@ -232,6 +238,12 @@ struct VKMainCommandList { ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdBindVertexBuffers3KHR); ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdBindIndexBuffer3KHR); + + ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdBeginVideoCodingKHR); + ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdControlVideoCodingKHR); + ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdDecodeVideoKHR); + ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkCmdEndVideoCodingKHR); + return true; } }; @@ -324,6 +336,8 @@ struct VKMainDevice { PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR; #endif //_WIN32 + PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR; + public: bool Init(VkDevice device, PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr) noexcept { @@ -408,6 +422,7 @@ struct VKMainDevice { #ifdef _WIN32 ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkGetMemoryWin32HandleKHR); #endif //_WIN32 + ASSIGN_DEVICE_PROC_ADDR_OPTIONAL(device, vkDestroyAccelerationStructureKHR); return true; } }; diff --git a/src/include/wisdom/wisdom.h b/src/include/wisdom/wisdom.h index 93e6d2a53..2821fa9d7 100644 --- a/src/include/wisdom/wisdom.h +++ b/src/include/wisdom/wisdom.h @@ -144,6 +144,7 @@ typedef struct WisDX12IndexBufferDesc WisIndexBufferDesc; # define wisDescriptorHeapCopyDescriptors wisDX12DescriptorHeapCopyDescriptors # define wisViewHeapWriteRenderTarget wisDX12ViewHeapWriteRenderTarget # define wisViewHeapWriteDepthStencil wisDX12ViewHeapWriteDepthStencil +# define wisViewHeapWriteVideoDecodeTarget wisDX12ViewHeapWriteVideoDecodeTarget # define wisViewHeapGetViewAddress wisDX12ViewHeapGetViewAddress # define wisViewHeapCopyViews wisDX12ViewHeapCopyViews # define wisViewHeapGetCPUHandle wisDX12ViewHeapGetCPUHandle @@ -312,6 +313,7 @@ typedef struct WisVKIndexBufferDesc WisIndexBufferDesc; # define wisDescriptorHeapCopyDescriptors wisVKDescriptorHeapCopyDescriptors # define wisViewHeapWriteRenderTarget wisVKViewHeapWriteRenderTarget # define wisViewHeapWriteDepthStencil wisVKViewHeapWriteDepthStencil +# define wisViewHeapWriteVideoDecodeTarget wisVKViewHeapWriteVideoDecodeTarget # define wisViewHeapGetViewAddress wisVKViewHeapGetViewAddress # define wisViewHeapCopyViews wisVKViewHeapCopyViews # define wisViewHeapGetCPUHandle wisVKViewHeapGetCPUHandle diff --git a/src/include/wisdom/wisdom.hpp b/src/include/wisdom/wisdom.hpp index 8f4ec161c..9f6d7f667 100644 --- a/src/include/wisdom/wisdom.hpp +++ b/src/include/wisdom/wisdom.hpp @@ -89,7 +89,7 @@ WIS_NODISCARD inline wis::Instance CreateInstance( wis::Result& out_result ) noexcept { - wis::DX12Instance instance; + wis::DX12Instance instance{}; const WisResult wis_result = ::wisDX12CreateInstance( reinterpret_cast(debug_desc), reinterpret_cast(extensions.data()), @@ -175,7 +175,7 @@ WIS_NODISCARD inline wis::Instance CreateInstance( wis::Result& out_result ) noexcept { - wis::VKInstance instance; + wis::VKInstance instance{}; const WisResult wis_result = ::wisVKCreateInstance( reinterpret_cast(debug_desc), reinterpret_cast(extensions.data()), diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index bee29494d..51ed2d106 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -26,8 +26,8 @@ target_include_directories( $) target_link_libraries(wisdom-platform-headers INTERFACE wis::wisdom-headers) -target_compile_definitions( - wisdom-platform-headers INTERFACE WISDOM_PLATFORM_STATIC=1) +target_compile_definitions(wisdom-platform-headers + INTERFACE WISDOM_PLATFORM_STATIC=1) install( TARGETS wisdom-platform-headers @@ -49,9 +49,8 @@ if(WISDOM_BUILD_STATIC) wisdom-platform PUBLIC $ $) - set_target_properties( - wisdom-platform PROPERTIES CXX_STANDARD 20 # UNITY_BUILD ON - DEBUG_POSTFIX d) + set_target_properties(wisdom-platform PROPERTIES CXX_STANDARD 20 DEBUG_POSTFIX + d) install( TARGETS wisdom-platform @@ -67,7 +66,7 @@ if(WISDOM_BUILD_SHARED) add_library(wisdom-platform-shared SHARED ${WISDOM_PLATFORM_SOURCES}) add_library(wis::wisdom-platform-shared ALIAS wisdom-platform-shared) - target_link_libraries(wisdom-platform-shared PRIVATE wisdom) + target_link_libraries(wisdom-platform-shared PRIVATE wisdom-shared) target_include_directories( wisdom-platform-shared PUBLIC $ @@ -80,7 +79,6 @@ if(WISDOM_BUILD_SHARED) set_target_properties( wisdom-platform-shared PROPERTIES CXX_STANDARD 20 - # UNITY_BUILD ON POSITION_INDEPENDENT_CODE ON DEBUG_POSTFIX d) diff --git a/src/platform/wisdom_platform/dx12/dx12_platform_uwp.cpp b/src/platform/wisdom_platform/dx12/dx12_platform_uwp.cpp index c8166bd96..9ebb4fc74 100644 --- a/src/platform/wisdom_platform/dx12/dx12_platform_uwp.cpp +++ b/src/platform/wisdom_platform/dx12/dx12_platform_uwp.cpp @@ -35,6 +35,7 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisDX12DestroyUWPExtension(WisDX12UWPExten impl.factory->Release(); impl.factory = nullptr; } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/platform/wisdom_platform/dx12/dx12_platform_win32.cpp b/src/platform/wisdom_platform/dx12/dx12_platform_win32.cpp index 680dab073..81b777107 100644 --- a/src/platform/wisdom_platform/dx12/dx12_platform_win32.cpp +++ b/src/platform/wisdom_platform/dx12/dx12_platform_win32.cpp @@ -35,6 +35,7 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisDX12DestroyWin32Extension(WisDX12Win32E impl.factory->Release(); impl.factory = nullptr; } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/platform/wisdom_platform/generated/c_api.h b/src/platform/wisdom_platform/generated/c_api.h index 77797c166..e1757104f 100644 --- a/src/platform/wisdom_platform/generated/c_api.h +++ b/src/platform/wisdom_platform/generated/c_api.h @@ -78,28 +78,28 @@ WIS_DEFINE_DX12_INSTANCE_EXT_HANDLE(WisDX12UWPExtension, 1); * @param self is a pointer to the valid WisWin32Extension instance. * * */ -WISDOM_PLATFORM_API void wisDX12DestroyWin32Extension(WisDX12Win32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisDX12DestroyWin32Extension(WisDX12Win32Extension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisWin32Extension handle. * @param self is a pointer to the valid WisWin32Extension instance. * * */ -WISDOM_PLATFORM_API void wisDX12InitWin32Extension(WisDX12Win32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisDX12InitWin32Extension(WisDX12Win32Extension* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisUWPExtension handle. * @param self is a pointer to the valid WisUWPExtension instance. * * */ -WISDOM_PLATFORM_API void wisDX12DestroyUWPExtension(WisDX12UWPExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisDX12DestroyUWPExtension(WisDX12UWPExtension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisUWPExtension handle. * @param self is a pointer to the valid WisUWPExtension instance. * * */ -WISDOM_PLATFORM_API void wisDX12InitUWPExtension(WisDX12UWPExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisDX12InitUWPExtension(WisDX12UWPExtension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a surface using Win32. @@ -109,7 +109,7 @@ WISDOM_PLATFORM_API void wisDX12InitUWPExtension(WisDX12UWPExtension* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisDX12Win32ExtensionCreateSurface( +WIS_INLINE WISDOM_PLATFORM_API WisResult wisDX12Win32ExtensionCreateSurface( WisDX12Win32Extension* self, const WisWin32WindowDesc* info, WisDX12Surface* surface @@ -122,7 +122,7 @@ WISDOM_PLATFORM_API WisResult wisDX12Win32ExtensionCreateSurface( * @return bool true if the extension is supported, false otherwise. * * */ -WISDOM_PLATFORM_API bool wisDX12Win32ExtensionSupported(WisDX12Win32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API bool wisDX12Win32ExtensionSupported(WisDX12Win32Extension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a surface using UWP. @@ -132,11 +132,8 @@ WISDOM_PLATFORM_API bool wisDX12Win32ExtensionSupported(WisDX12Win32Extension* s * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisDX12UWPExtensionCreateSurface( - WisDX12UWPExtension* self, - const WisUWPWindowDesc* info, - WisDX12Surface* surface -); +WIS_INLINE WISDOM_PLATFORM_API WisResult +wisDX12UWPExtensionCreateSurface(WisDX12UWPExtension* self, const WisUWPWindowDesc* info, WisDX12Surface* surface); #endif // WISDOM_DX12 @@ -170,56 +167,56 @@ WIS_DEFINE_VK_INSTANCE_EXT_HANDLE(WisVKWin32Extension, 2); * @param self is a pointer to the valid WisXlibExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKDestroyXlibExtension(WisVKXlibExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKDestroyXlibExtension(WisVKXlibExtension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisXlibExtension handle. * @param self is a pointer to the valid WisXlibExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKInitXlibExtension(WisVKXlibExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKInitXlibExtension(WisVKXlibExtension* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisXCBExtension handle. * @param self is a pointer to the valid WisXCBExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKDestroyXCBExtension(WisVKXCBExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKDestroyXCBExtension(WisVKXCBExtension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisXCBExtension handle. * @param self is a pointer to the valid WisXCBExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKInitXCBExtension(WisVKXCBExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKInitXCBExtension(WisVKXCBExtension* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisWaylandExtension handle. * @param self is a pointer to the valid WisWaylandExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKDestroyWaylandExtension(WisVKWaylandExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKDestroyWaylandExtension(WisVKWaylandExtension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisWaylandExtension handle. * @param self is a pointer to the valid WisWaylandExtension instance. * * */ -WISDOM_PLATFORM_API void wisVKInitWaylandExtension(WisVKWaylandExtension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKInitWaylandExtension(WisVKWaylandExtension* self); /** * @brief Provided by Wisdom 0.7.0. Destroys a WisWin32Extension handle. * @param self is a pointer to the valid WisWin32Extension instance. * * */ -WISDOM_PLATFORM_API void wisVKDestroyWin32Extension(WisVKWin32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKDestroyWin32Extension(WisVKWin32Extension* self); /** * @brief Provided by Wisdom 0.7.0. Initializes a WisWin32Extension handle. * @param self is a pointer to the valid WisWin32Extension instance. * * */ -WISDOM_PLATFORM_API void wisVKInitWin32Extension(WisVKWin32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API void wisVKInitWin32Extension(WisVKWin32Extension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a Vulkan surface using Xlib. @@ -229,11 +226,8 @@ WISDOM_PLATFORM_API void wisVKInitWin32Extension(WisVKWin32Extension* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisVKXlibExtensionCreateSurface( - WisVKXlibExtension* self, - const WisXlibWindowDesc* info, - WisVKSurface* surface -); +WIS_INLINE WISDOM_PLATFORM_API WisResult +wisVKXlibExtensionCreateSurface(WisVKXlibExtension* self, const WisXlibWindowDesc* info, WisVKSurface* surface); /** * @brief Provided by Wisdom 0.7.0. Checks if the Xlib surface extension is supported on the current platform. @@ -241,7 +235,7 @@ WISDOM_PLATFORM_API WisResult wisVKXlibExtensionCreateSurface( * @return bool true if the extension is supported, false otherwise. * * */ -WISDOM_PLATFORM_API bool wisVKXlibExtensionSupported(WisVKXlibExtension* self); +WIS_INLINE WISDOM_PLATFORM_API bool wisVKXlibExtensionSupported(WisVKXlibExtension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a surface using Win32. @@ -251,11 +245,8 @@ WISDOM_PLATFORM_API bool wisVKXlibExtensionSupported(WisVKXlibExtension* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisVKXCBExtensionCreateSurface( - WisVKXCBExtension* self, - const WisXCBWindowDesc* info, - WisVKSurface* surface -); +WIS_INLINE WISDOM_PLATFORM_API WisResult +wisVKXCBExtensionCreateSurface(WisVKXCBExtension* self, const WisXCBWindowDesc* info, WisVKSurface* surface); /** * @brief Provided by Wisdom 0.7.0. Checks if the XCB surface extension is supported on the current platform. @@ -263,7 +254,7 @@ WISDOM_PLATFORM_API WisResult wisVKXCBExtensionCreateSurface( * @return bool true if the extension is supported, false otherwise. * * */ -WISDOM_PLATFORM_API bool wisVKXCBExtensionSupported(WisVKXCBExtension* self); +WIS_INLINE WISDOM_PLATFORM_API bool wisVKXCBExtensionSupported(WisVKXCBExtension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a surface using Wayland. @@ -273,7 +264,7 @@ WISDOM_PLATFORM_API bool wisVKXCBExtensionSupported(WisVKXCBExtension* self); * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisVKWaylandExtensionCreateSurface( +WIS_INLINE WISDOM_PLATFORM_API WisResult wisVKWaylandExtensionCreateSurface( WisVKWaylandExtension* self, const WisWaylandWindowDesc* info, WisVKSurface* surface @@ -285,7 +276,7 @@ WISDOM_PLATFORM_API WisResult wisVKWaylandExtensionCreateSurface( * @return bool true if the extension is supported, false otherwise. * * */ -WISDOM_PLATFORM_API bool wisVKWaylandExtensionSupported(WisVKWaylandExtension* self); +WIS_INLINE WISDOM_PLATFORM_API bool wisVKWaylandExtensionSupported(WisVKWaylandExtension* self); /** * @brief Provided by Wisdom 0.7.0. Creates a surface using Win32. @@ -295,11 +286,8 @@ WISDOM_PLATFORM_API bool wisVKWaylandExtensionSupported(WisVKWaylandExtension* s * @return Result denoting the outcome of operation. * * */ -WISDOM_PLATFORM_API WisResult wisVKWin32ExtensionCreateSurface( - WisVKWin32Extension* self, - const WisWin32WindowDesc* info, - WisVKSurface* surface -); +WIS_INLINE WISDOM_PLATFORM_API WisResult +wisVKWin32ExtensionCreateSurface(WisVKWin32Extension* self, const WisWin32WindowDesc* info, WisVKSurface* surface); /** * @brief Provided by Wisdom 0.7.0. Checks if the Win32 surface extension is supported on the current platform. Always @@ -308,7 +296,7 @@ WISDOM_PLATFORM_API WisResult wisVKWin32ExtensionCreateSurface( * @return bool true if the extension is supported, false otherwise. * * */ -WISDOM_PLATFORM_API bool wisVKWin32ExtensionSupported(WisVKWin32Extension* self); +WIS_INLINE WISDOM_PLATFORM_API bool wisVKWin32ExtensionSupported(WisVKWin32Extension* self); #endif // WISDOM_VULKAN diff --git a/src/platform/wisdom_platform/generated/cpp_api.hpp b/src/platform/wisdom_platform/generated/cpp_api.hpp index 6a0b50f0a..74cc9072f 100644 --- a/src/platform/wisdom_platform/generated/cpp_api.hpp +++ b/src/platform/wisdom_platform/generated/cpp_api.hpp @@ -82,7 +82,7 @@ class DX12Win32Extension { public: DX12Win32Extension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisDX12InitWin32Extension(GetStorage()); } @@ -102,7 +102,7 @@ class DX12Win32Extension wis::Result& out_result ) noexcept { - wis::DX12Surface surface; + wis::DX12Surface surface{}; const WisResult wis_result = ::wisDX12Win32ExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), @@ -136,7 +136,7 @@ class DX12UWPExtension { public: DX12UWPExtension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisDX12InitUWPExtension(GetStorage()); } @@ -156,7 +156,7 @@ class DX12UWPExtension wis::Result& out_result ) noexcept { - wis::DX12Surface surface; + wis::DX12Surface surface{}; const WisResult wis_result = ::wisDX12UWPExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), @@ -190,7 +190,7 @@ class VKXlibExtension { public: VKXlibExtension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisVKInitXlibExtension(GetStorage()); } @@ -207,7 +207,7 @@ class VKXlibExtension * */ WIS_NODISCARD inline wis::VKSurface CreateSurface(const wis::XlibWindowDesc& info, wis::Result& out_result) noexcept { - wis::VKSurface surface; + wis::VKSurface surface{}; const WisResult wis_result = ::wisVKXlibExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), @@ -240,7 +240,7 @@ class VKXCBExtension { public: VKXCBExtension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisVKInitXCBExtension(GetStorage()); } @@ -257,7 +257,7 @@ class VKXCBExtension * */ WIS_NODISCARD inline wis::VKSurface CreateSurface(const wis::XCBWindowDesc& info, wis::Result& out_result) noexcept { - wis::VKSurface surface; + wis::VKSurface surface{}; const WisResult wis_result = ::wisVKXCBExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), @@ -291,7 +291,7 @@ class VKWaylandExtension { public: VKWaylandExtension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisVKInitWaylandExtension(GetStorage()); } @@ -311,7 +311,7 @@ class VKWaylandExtension wis::Result& out_result ) noexcept { - wis::VKSurface surface; + wis::VKSurface surface{}; const WisResult wis_result = ::wisVKWaylandExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), @@ -344,7 +344,7 @@ class VKWin32Extension { public: VKWin32Extension() noexcept - : ImplType(std::in_place) + : ImplType(wis::in_place) { ::wisVKInitWin32Extension(GetStorage()); } @@ -364,7 +364,7 @@ class VKWin32Extension wis::Result& out_result ) noexcept { - wis::VKSurface surface; + wis::VKSurface surface{}; const WisResult wis_result = ::wisVKWin32ExtensionCreateSurface( &_impl_storage, reinterpret_cast(&info), diff --git a/src/platform/wisdom_platform/vulkan/vk_platform_wayland.cpp b/src/platform/wisdom_platform/vulkan/vk_platform_wayland.cpp index 4478add10..7c88e6388 100644 --- a/src/platform/wisdom_platform/vulkan/vk_platform_wayland.cpp +++ b/src/platform/wisdom_platform/vulkan/vk_platform_wayland.cpp @@ -50,6 +50,7 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisVKDestroyWaylandExtension(WisVKWaylandE if (impl.instance_control_block) { wis::detail::VKReleaseInstance(impl.instance_control_block); } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/platform/wisdom_platform/vulkan/vk_platform_win32.cpp b/src/platform/wisdom_platform/vulkan/vk_platform_win32.cpp index 6a8467f28..d56332ed1 100644 --- a/src/platform/wisdom_platform/vulkan/vk_platform_win32.cpp +++ b/src/platform/wisdom_platform/vulkan/vk_platform_win32.cpp @@ -76,14 +76,12 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisVKDestroyWin32Extension(WisVKWin32Exten if (impl.instance_control_block) { wis::detail::VKReleaseInstance(impl.instance_control_block); } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- -WISDOM_PLATFORM_API WisResult wisVKWin32ExtensionCreateSurface( - WisVKWin32Extension* self, - const WisWin32WindowDesc* info, - WisVKSurface* surface -) +WISDOM_PLATFORM_API WisResult +wisVKWin32ExtensionCreateSurface(WisVKWin32Extension* self, const WisWin32WindowDesc* info, WisVKSurface* surface) { auto& impl = wis::from_handle_ref(self); auto vkCreateWin32SurfaceKHR = reinterpret_cast(impl.vkCreateWin32SurfaceKHR); diff --git a/src/platform/wisdom_platform/vulkan/vk_platform_xcb.cpp b/src/platform/wisdom_platform/vulkan/vk_platform_xcb.cpp index fc8db47b5..18e5a05af 100644 --- a/src/platform/wisdom_platform/vulkan/vk_platform_xcb.cpp +++ b/src/platform/wisdom_platform/vulkan/vk_platform_xcb.cpp @@ -54,14 +54,12 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisVKDestroyXCBExtension(WisVKXCBExtension if (impl.instance_control_block) { wis::detail::VKReleaseInstance(impl.instance_control_block); } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- -WISDOM_PLATFORM_API WisResult wisVKXCBExtensionCreateSurface( - WisVKXCBExtension* self, - const WisXCBWindowDesc* info, - WisVKSurface* surface -) +WISDOM_PLATFORM_API WisResult +wisVKXCBExtensionCreateSurface(WisVKXCBExtension* self, const WisXCBWindowDesc* info, WisVKSurface* surface) { auto& impl = wis::from_handle_ref(self); auto vkCreateXcbSurfaceKHR = reinterpret_cast(impl.vkCreateXcbSurfaceKHR); diff --git a/src/platform/wisdom_platform/vulkan/vk_platform_xlib.cpp b/src/platform/wisdom_platform/vulkan/vk_platform_xlib.cpp index b0e933729..9b8ebc73d 100644 --- a/src/platform/wisdom_platform/vulkan/vk_platform_xlib.cpp +++ b/src/platform/wisdom_platform/vulkan/vk_platform_xlib.cpp @@ -55,14 +55,12 @@ WIS_EXTERN_C WISDOM_PLATFORM_API void wisVKDestroyXlibExtension(WisVKXlibExtensi if (impl.instance_control_block) { wis::detail::VKReleaseInstance(impl.instance_control_block); } + impl.header.init_fptr = nullptr; } //---------------------------------------------------------------------------------------------------------------------- -WISDOM_PLATFORM_API WisResult wisVKXlibExtensionCreateSurface( - WisVKXlibExtension* self, - const WisXlibWindowDesc* info, - WisVKSurface* surface -) +WISDOM_PLATFORM_API WisResult +wisVKXlibExtensionCreateSurface(WisVKXlibExtension* self, const WisXlibWindowDesc* info, WisVKSurface* surface) { auto& impl = wis::from_handle_ref(self); auto vkCreateXlibSurfaceKHR = reinterpret_cast(impl.vkCreateXlibSurfaceKHR); diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 000000000..19ca31214 --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.22) + +project(TestApp) +find_package(Wisdom REQUIRED) + +add_executable(test_app main.cpp) +if(WISDOM_IS_SHARED) + target_link_libraries(test_app PRIVATE wis::wisdom-shared) +else() + target_link_libraries(test_app PRIVATE wis::wisdom) +endif() diff --git a/test_package/CMakeUserPresets.json b/test_package/CMakeUserPresets.json new file mode 100644 index 000000000..159166670 --- /dev/null +++ b/test_package/CMakeUserPresets.json @@ -0,0 +1,7 @@ +{ + "version": 4, + "vendor": { + "conan": {} + }, + "include": ["build/msvc-195-x86_64-20-release/generators/CMakePresets.json"] +} diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 000000000..0669a92e1 --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,43 @@ +import os + +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import CMake +from conan.tools.cmake import cmake_layout +from conan.tools.cmake import CMakeToolchain + + +class WisdomTestConan(ConanFile): + """ """ + + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps" + + def requirements(self): + """ """ + self.requires(self.tested_reference_str) + + def layout(self): + """ """ + cmake_layout(self) + + def generate(self): + """ """ + tc = CMakeToolchain(self) + # Check if the wisdom package we are testing was built as shared + is_shared = self.dependencies["wisdom"].options.shared + # Pass that info to CMake! + tc.variables["WISDOM_IS_SHARED"] = is_shared + tc.generate() + + def build(self): + """ """ + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + """ """ + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "test_app") + self.run(cmd, env="conanrun") diff --git a/test_package/main.cpp b/test_package/main.cpp new file mode 100644 index 000000000..eb58a56a3 --- /dev/null +++ b/test_package/main.cpp @@ -0,0 +1,9 @@ +#include + +int main() +{ + wis::Result result{}; + wis::DebugDesc debug_desc{true}; + wis::Instance instance = wis::CreateInstance(&debug_desc, {}, result); + return 0; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 735273d9a..f9de6d2e8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,11 +6,13 @@ function(wis_add_test TARGET SOURCES IMPL) add_executable(${TEST_TARGET} ${SOURCES}) if(WISDOM_BUILD_STATIC) # Link against static library if built - target_link_libraries(${TEST_TARGET} PUBLIC wis::wisdom wis::wisdom-platform - Catch2::Catch2WithMain) + target_link_libraries( + ${TEST_TARGET} PUBLIC wis::wisdom wis::wisdom-platform + Catch2::Catch2WithMain) else() - target_link_libraries(${TEST_TARGET} PUBLIC wis::wisdom-headers wis::wisdom-platform-headers - Catch2::Catch2WithMain) + target_link_libraries( + ${TEST_TARGET} PUBLIC wis::wisdom-headers wis::wisdom-platform-headers + Catch2::Catch2WithMain) endif() set_target_properties( diff --git a/tests/basic/CMakeLists.txt b/tests/basic/CMakeLists.txt index f3d7d49d8..28ed3dd08 100644 --- a/tests/basic/CMakeLists.txt +++ b/tests/basic/CMakeLists.txt @@ -1,5 +1,11 @@ set(TEST_SOURCES "relaxed_destruction_order.cpp") -wis_add_test_suite("test-basic" ${TEST_SOURCES}) +if(WISDOM_DX12) + wis_add_test(test-basic "${TEST_SOURCES}" "dx12") +endif() -target_sources(test-basic-vk PRIVATE "platform_check.cpp") \ No newline at end of file +if(WISDOM_VULKAN) + wis_add_test(test-basic "${TEST_SOURCES}" "vk") +endif() + +target_sources(test-basic-vk PRIVATE "platform_check.cpp") diff --git a/tests/basic/platform_check.cpp b/tests/basic/platform_check.cpp index 52d6d38f2..8e0905dc4 100644 --- a/tests/basic/platform_check.cpp +++ b/tests/basic/platform_check.cpp @@ -28,7 +28,7 @@ TEST_CASE("check_platform_support") ); // Expect partial success - REQUIRE(result.status >= 0); + REQUIRE(result.status >= 0); #ifdef WISDOM_WINDOWS printf("XCB supported: %s\n", wisXCBExtensionSupported(&xcb_extension) ? "Yes" : "No"); @@ -43,7 +43,6 @@ TEST_CASE("check_platform_support") bool wayland_supported = wisWaylandExtensionSupported(&wayland_extension); bool win32_supported = wisWin32ExtensionSupported(&win32_extension); - printf("XCB supported: %s\n", xcb_supported ? "Yes" : "No"); printf("Xlib supported: %s\n", xlib_supported ? "Yes" : "No"); printf("Wayland supported: %s\n", wayland_supported ? "Yes" : "No"); @@ -52,4 +51,17 @@ TEST_CASE("check_platform_support") // At least one of the Linux surface extensions should be supported REQUIRE(xcb_supported || xlib_supported || wayland_supported); #endif + + wisDestroyInstance(&instance); + REQUIRE(!wisHandleValid(&instance)); + + wisDestroyXCBExtension(&xcb_extension); + wisDestroyXlibExtension(&xlib_extension); + wisDestroyWaylandExtension(&wayland_extension); + wisDestroyWin32Extension(&win32_extension); + + REQUIRE(!wisHandleValid(&xcb_extension)); + REQUIRE(!wisHandleValid(&xlib_extension)); + REQUIRE(!wisHandleValid(&wayland_extension)); + REQUIRE(!wisHandleValid(&win32_extension)); } diff --git a/tests/basic/relaxed_destruction_order.cpp b/tests/basic/relaxed_destruction_order.cpp index d1a58621e..7ddc117c3 100644 --- a/tests/basic/relaxed_destruction_order.cpp +++ b/tests/basic/relaxed_destruction_order.cpp @@ -6,24 +6,15 @@ void log_callback(WisSeverity severity, const char* message, uint64_t device, vo { const char* severity_str = ""; switch (severity) { - case WisSeverityVerbose: - severity_str = "VERBOSE"; - break; - case WisSeverityInfo: - severity_str = "INFO"; - break; - case WisSeverityWarning: - severity_str = "WARNING"; - break; case WisSeverityError: severity_str = "ERROR"; break; case WisSeverityFatal: severity_str = "FATAL"; + FAIL("Fatal message in log: " << (message ? message : "")); break; default: - severity_str = "UNKNOWN"; - break; + return; } printf("[%s] %s\n", severity_str, message); } diff --git a/tests/integration/cmake/CMakeLists.txt b/tests/integration/cmake/CMakeLists.txt new file mode 100644 index 000000000..efc6b77bb --- /dev/null +++ b/tests/integration/cmake/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.20) +project(WisdomZipIntegrationTest) + +# This is what a standard user does after extracting your ZIP +find_package(wisdom REQUIRED) + +add_executable(TestAppShared entry_main.cpp) +add_executable(TestApp entry_main.cpp) +add_executable(TestAppHeaders entry_main.cpp) + +# Test dynamic linkage to ensure the DLLs load correctly +target_link_libraries(TestAppShared PRIVATE wis::wisdom-shared) +target_link_libraries(TestApp PRIVATE wis::wisdom) +target_link_libraries(TestAppHeaders PRIVATE wis::wisdom-headers) + +set_target_properties(TestAppHeaders PROPERTIES CXX_STANDARD 20) diff --git a/tests/integration/cmake/entry_main.cpp b/tests/integration/cmake/entry_main.cpp new file mode 100644 index 000000000..e9bb31ef6 --- /dev/null +++ b/tests/integration/cmake/entry_main.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + wis::Result result; + wis::Instance instance = wis::CreateInstance(nullptr, {}, result); + std::cout << "Wisdom NuGet package successfully linked!" << std::endl; + return 0; +} diff --git a/tests/integration/nuget/entry_main.cpp b/tests/integration/nuget/entry_main.cpp new file mode 100644 index 000000000..e9bb31ef6 --- /dev/null +++ b/tests/integration/nuget/entry_main.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + wis::Result result; + wis::Instance instance = wis::CreateInstance(nullptr, {}, result); + std::cout << "Wisdom NuGet package successfully linked!" << std::endl; + return 0; +} diff --git a/tests/integration/nuget/nuget.config b/tests/integration/nuget/nuget.config new file mode 100644 index 000000000..df933c331 --- /dev/null +++ b/tests/integration/nuget/nuget.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/integration/nuget/test.vcxproj b/tests/integration/nuget/test.vcxproj new file mode 100644 index 000000000..fb3958016 --- /dev/null +++ b/tests/integration/nuget/test.vcxproj @@ -0,0 +1,48 @@ + + + + + Debug + x64 + + + Release + x64 + + + + native + {12345678-ABCD-EFGH-IJKL-1234567890AB} + Win32Proj + 10.0 + + + + Application + v143 + Unicode + + + + + + + + + $(WisdomLinkage) + + + + + + stdcpp20 + + + + + + $(WisdomPackageVersion) + + + + diff --git a/xml/enums.xml b/xml/enums.xml index a809a2d0b..a9814d880 100644 --- a/xml/enums.xml +++ b/xml/enums.xml @@ -24,7 +24,7 @@ Can be used to describe: - Texture data format - Render target data format - Depth stencil data format"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -289,41 +327,49 @@ A 16-bit depth format supporting 16-bit unsigned normalized depth values."> A one-component, 16-bit unsigned normalized format that has a 16-bit R component in bytes 0..1."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -912,6 +1003,10 @@ Support of this memory must be queried."> + + + + @@ -1373,6 +1468,12 @@ Determine how the buffer can be used throughout its lifetime."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml/structs.xml b/xml/structs.xml index 349baf4d2..aa794e4fd 100644 --- a/xml/structs.xml +++ b/xml/structs.xml @@ -153,6 +153,8 @@ + + @@ -464,7 +466,6 @@ Viewport is considered from Top Left corner."> - diff --git a/xml/wis.xml b/xml/wis.xml index a1ee0248f..635cf7578 100644 --- a/xml/wis.xml +++ b/xml/wis.xml @@ -32,8 +32,8 @@ - - + + @@ -324,6 +324,12 @@ Can still be enqueued after the signal."> + + + + + +