From 11c52e184001096b9b0df359fed56a97a5f29c79 Mon Sep 17 00:00:00 2001 From: swinston Date: Wed, 3 Dec 2025 00:24:09 -0800 Subject: [PATCH 1/5] Add C++20 module support option with Vulkan integration and improve static vector handling in model loader. --- attachments/simple_engine/CMakeLists.txt | 91 ++++++++++++++++------ attachments/simple_engine/model_loader.cpp | 4 +- 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/attachments/simple_engine/CMakeLists.txt b/attachments/simple_engine/CMakeLists.txt index 4489b87e..76d5d119 100644 --- a/attachments/simple_engine/CMakeLists.txt +++ b/attachments/simple_engine/CMakeLists.txt @@ -5,6 +5,14 @@ set(CMAKE_CXX_SCAN_FOR_MODULES ON) project(SimpleEngine VERSION 1.0.0 LANGUAGES CXX C) +# Option to enable/disable Vulkan C++20 module support for this standalone project +option(ENABLE_CPP20_MODULE "Enable C++ 20 module support for Vulkan in SimpleEngine" OFF) + +# Enable C++ module dependency scanning only when modules are enabled +if(ENABLE_CPP20_MODULE) + set(CMAKE_CXX_SCAN_FOR_MODULES ON) +endif() + # Add CMake module path for custom find modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../CMake") @@ -16,32 +24,52 @@ find_package (tinygltf REQUIRED) find_package (KTX REQUIRED) find_package (OpenAL REQUIRED) -# set up Vulkan C++ module -add_library(VulkanCppModule) -add_library(Vulkan::cppm ALIAS VulkanCppModule) +if(ENABLE_CPP20_MODULE) + # Set up Vulkan C++ module for this standalone project + add_library(VulkanCppModule) + add_library(Vulkan::cppm ALIAS VulkanCppModule) -target_compile_definitions(VulkanCppModule - PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1 -) -target_include_directories(VulkanCppModule - PRIVATE - "${Vulkan_INCLUDE_DIR}" -) -target_link_libraries(VulkanCppModule - PUBLIC - Vulkan::Vulkan -) + target_compile_definitions(VulkanCppModule + PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1 + ) + target_include_directories(VulkanCppModule + PUBLIC + "${Vulkan_INCLUDE_DIR}" + ) + target_link_libraries(VulkanCppModule + PUBLIC + Vulkan::Vulkan + ) -set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20) + set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20) -target_sources(VulkanCppModule - PUBLIC - FILE_SET cxx_modules TYPE CXX_MODULES - BASE_DIRS - "${Vulkan_INCLUDE_DIR}" - FILES - "${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm" -) + target_sources(VulkanCppModule + PUBLIC + FILE_SET cxx_modules TYPE CXX_MODULES + BASE_DIRS + "${Vulkan_INCLUDE_DIR}" + FILES + "${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm" + ) + + # MSVC-specific options to improve module support + if(MSVC) + target_compile_options(VulkanCppModule PRIVATE + /std:c++latest + /permissive- + /Zc:__cplusplus + /EHsc + /Zc:preprocessor + ) + endif() +else() + add_library(VulkanCppModule INTERFACE) + add_library(Vulkan::cppm ALIAS VulkanCppModule) + target_link_libraries(VulkanCppModule INTERFACE Vulkan::Vulkan) + target_compile_definitions(VulkanCppModule + INTERFACE VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1 + ) +endif() @@ -122,9 +150,24 @@ add_executable(SimpleEngine ${SOURCES}) add_dependencies(SimpleEngine shaders) set_target_properties (SimpleEngine PROPERTIES CXX_STANDARD 20) +# Enable required defines for GLM experimental extensions and MSVC math constants +target_compile_definitions(SimpleEngine PRIVATE + GLM_ENABLE_EXPERIMENTAL + _USE_MATH_DEFINES + VULKAN_HPP_NO_STRUCT_CONSTRUCTORS + VULKAN_HPP_DISPATCH_LOADER_DYNAMIC +) + # Link libraries +# Prefer the Vulkan C++ module target when available (configured at the parent level), +# but fall back to the standard Vulkan library otherwise. +if(TARGET Vulkan::cppm) + target_link_libraries(SimpleEngine PRIVATE Vulkan::cppm) +else() + target_link_libraries(SimpleEngine PRIVATE Vulkan::Vulkan) +endif() + target_link_libraries(SimpleEngine PRIVATE - Vulkan::cppm glm::glm tinygltf::tinygltf KTX::ktx diff --git a/attachments/simple_engine/model_loader.cpp b/attachments/simple_engine/model_loader.cpp index 9cf9ec1f..1603bad4 100644 --- a/attachments/simple_engine/model_loader.cpp +++ b/attachments/simple_engine/model_loader.cpp @@ -1554,8 +1554,8 @@ const std::vector& ModelLoader::GetMaterialMeshes(const std::strin if (it != materialMeshes.end()) { return it->second; } - // Return a static empty vector to avoid creating temporary objects - static constexpr std::vector emptyVector; + // Return a static empty vector to avoid creating temporary objects. + static const std::vector emptyVector; return emptyVector; } From a2ae4a6ee4e723acbf0d98ddc3b6734d1e61e9b4 Mon Sep 17 00:00:00 2001 From: swinston Date: Wed, 3 Dec 2025 01:05:34 -0800 Subject: [PATCH 2/5] Set up CI workflow for SimpleEngine - Add GitHub Actions CI targeting `main` branch for SimpleEngine with matrix builds on Ubuntu and Windows. - Install Vulkan SDK, dependencies, and project-specific requirements for both platforms. - Configure, build, and package SimpleEngine, supporting Debug/Release builds and optional C++20 modules. --- .github/workflows/simple_engine.yml | 136 ++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 .github/workflows/simple_engine.yml diff --git a/.github/workflows/simple_engine.yml b/.github/workflows/simple_engine.yml new file mode 100644 index 00000000..b8e647bb --- /dev/null +++ b/.github/workflows/simple_engine.yml @@ -0,0 +1,136 @@ +name: SimpleEngine CI + +on: + workflow_dispatch: + pull_request: + branches: [ main ] + paths: + - 'attachments/simple_engine/**' + - '.github/workflows/simple_engine.yml' + push: + branches: [ main ] + paths: + - 'attachments/simple_engine/**' + - '.github/workflows/simple_engine.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + build-simple-engine: + name: SimpleEngine (${{ matrix.os }} • ${{ matrix.build_type }} • module=${{ matrix.enable_module }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + build_type: [Debug, Release] + enable_module: [OFF, ON] + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + + # ----------------------- + # Linux: set up Vulkan SDK similar to workflow.yml + # ----------------------- + - name: Install Vulkan SDK (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + VULKAN_VERSION=$(curl -s https://vulkan.lunarg.com/sdk/latest/linux.txt) + echo "Using Vulkan SDK version: $VULKAN_VERSION" + mkdir -p vulkan-sdk + cd vulkan-sdk + curl -sSLO "https://sdk.lunarg.com/sdk/download/$VULKAN_VERSION/linux/vulkansdk-linux-x86_64-$VULKAN_VERSION.tar.xz" + tar -xJf vulkansdk-linux-x86_64-$VULKAN_VERSION.tar.xz + echo "VULKAN_SDK=$PWD/$VULKAN_VERSION/x86_64" >> $GITHUB_ENV + echo "PATH=$PWD/$VULKAN_VERSION/x86_64/bin:$PATH" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$PWD/$VULKAN_VERSION/x86_64/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + echo "VK_LAYER_PATH=$PWD/$VULKAN_VERSION/x86_64/etc/vulkan/explicit_layer.d" >> $GITHUB_ENV + cd .. + + - name: Install Dependencies (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + libglfw3-dev \ + libglm-dev \ + libxrandr-dev \ + libxinerama-dev \ + libxcursor-dev \ + libxi-dev \ + libopenal-dev \ + libktx-dev + + - name: Install project deps via script (Ubuntu) + if: matrix.os == 'ubuntu-latest' + working-directory: attachments/simple_engine + run: | + if [ -x ./install_dependencies_linux.sh ]; then + ./install_dependencies_linux.sh || true + fi + + # ----------------------- + # Windows dependencies + # ----------------------- + - name: Install vcpkg and dependencies (Windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + git clone https://github.com/microsoft/vcpkg.git $env:USERPROFILE\vcpkg + & $env:USERPROFILE\vcpkg\bootstrap-vcpkg.bat + $triplet = 'x64-windows' + & $env:USERPROFILE\vcpkg\vcpkg.exe install ` + vulkan:${triplet} ` + glfw3:${triplet} ` + glm:${triplet} ` + tinygltf:${triplet} ` + ktx:${triplet} ` + openal-soft:${triplet} + echo "CMAKE_TOOLCHAIN_FILE=$env:USERPROFILE\vcpkg\scripts\buildsystems\vcpkg.cmake" >> $env:GITHUB_ENV + echo "VCPKG_TARGET_TRIPLET=$triplet" >> $env:GITHUB_ENV + + - name: Install project deps via script (Windows) + if: matrix.os == 'windows-latest' + shell: cmd + working-directory: attachments/simple_engine + run: | + if exist install_dependencies_windows.bat call install_dependencies_windows.bat + + # ----------------------- + # Configure & Build + # ----------------------- + - name: Configure (Unix) + if: matrix.os == 'ubuntu-latest' + run: | + cmake -S attachments/simple_engine \ + -B build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} + + - name: Configure (Windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + cmake -S attachments/simple_engine ` + -B build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} ` + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ` + -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} ` + -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` + -DVCPKG_TARGET_TRIPLET="$env:VCPKG_TARGET_TRIPLET" + + - name: Build + run: | + cmake --build build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} --config ${{ matrix.build_type }} + + - name: Package (Release only) + if: matrix.build_type == 'Release' + run: | + cmake --build build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} --target package --config ${{ matrix.build_type }} From 84400ff7eeedeaae2c78294d7333633343712376 Mon Sep 17 00:00:00 2001 From: swinston Date: Wed, 3 Dec 2025 10:32:02 -0800 Subject: [PATCH 3/5] Add OpenAL and Vulkan dependencies and streamline CI dependency installation --- .github/workflows/simple_engine.yml | 14 ++++---------- vcpkg.json | 4 +++- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/simple_engine.yml b/.github/workflows/simple_engine.yml index b8e647bb..a0bc5ac5 100644 --- a/.github/workflows/simple_engine.yml +++ b/.github/workflows/simple_engine.yml @@ -66,8 +66,7 @@ jobs: libxinerama-dev \ libxcursor-dev \ libxi-dev \ - libopenal-dev \ - libktx-dev + libopenal-dev - name: Install project deps via script (Ubuntu) if: matrix.os == 'ubuntu-latest' @@ -87,13 +86,8 @@ jobs: git clone https://github.com/microsoft/vcpkg.git $env:USERPROFILE\vcpkg & $env:USERPROFILE\vcpkg\bootstrap-vcpkg.bat $triplet = 'x64-windows' - & $env:USERPROFILE\vcpkg\vcpkg.exe install ` - vulkan:${triplet} ` - glfw3:${triplet} ` - glm:${triplet} ` - tinygltf:${triplet} ` - ktx:${triplet} ` - openal-soft:${triplet} + # Use manifest mode; vcpkg.json at repo root defines dependencies + & $env:USERPROFILE\vcpkg\vcpkg.exe install --triplet $triplet echo "CMAKE_TOOLCHAIN_FILE=$env:USERPROFILE\vcpkg\scripts\buildsystems\vcpkg.cmake" >> $env:GITHUB_ENV echo "VCPKG_TARGET_TRIPLET=$triplet" >> $env:GITHUB_ENV @@ -102,7 +96,7 @@ jobs: shell: cmd working-directory: attachments/simple_engine run: | - if exist install_dependencies_windows.bat call install_dependencies_windows.bat + if exist install_dependencies_windows.bat call install_dependencies_windows.bat || exit /b 0 # ----------------------- # Configure & Build diff --git a/vcpkg.json b/vcpkg.json index 0a90e24d..298c6729 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -8,6 +8,8 @@ "stb", "tinygltf", "nlohmann-json", - "ktx" + "ktx", + "openal-soft", + "vulkan" ] } From e1c31d7e36cc2e0d8022c33f73031c626b1c71c1 Mon Sep 17 00:00:00 2001 From: swinston Date: Wed, 3 Dec 2025 11:15:54 -0800 Subject: [PATCH 4/5] Remove Vulkan dependency, adjust CI workflow for optional module builds, and streamline dependency installation - Removed Vulkan as a dependency from `vcpkg.json`. - Updated CI to support conditional builds with and without C++20 modules. - Introduced Clang and Ninja for module-enabled builds on Ubuntu. - Added Vulkan SDK installation for Windows CI. --- .github/workflows/simple_engine.yml | 31 ++++++++++++++++++++++-- attachments/simple_engine/CMakeLists.txt | 3 --- vcpkg.json | 3 +-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.github/workflows/simple_engine.yml b/.github/workflows/simple_engine.yml index a0bc5ac5..a1ac7b36 100644 --- a/.github/workflows/simple_engine.yml +++ b/.github/workflows/simple_engine.yml @@ -60,6 +60,8 @@ jobs: sudo apt-get install -y \ build-essential \ cmake \ + ninja-build \ + clang \ libglfw3-dev \ libglm-dev \ libxrandr-dev \ @@ -98,14 +100,39 @@ jobs: run: | if exist install_dependencies_windows.bat call install_dependencies_windows.bat || exit /b 0 + # Install LunarG Vulkan SDK on Windows and export environment variables for our FindVulkan.cmake + - name: Install Vulkan SDK (Windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + choco install vulkan-sdk -y --no-progress + $sdkDir = Get-ChildItem -Path 'C:\VulkanSDK' -ErrorAction SilentlyContinue | Sort-Object Name -Descending | Select-Object -First 1 + if (-not $sdkDir) { throw "Vulkan SDK was not installed to C:\VulkanSDK" } + echo "Using Vulkan SDK: $($sdkDir.FullName)" + echo "VULKAN_SDK=$($sdkDir.FullName)" >> $env:GITHUB_ENV + echo "PATH=$($sdkDir.FullName)\Bin;$env:PATH" >> $env:GITHUB_ENV + # ----------------------- # Configure & Build # ----------------------- - - name: Configure (Unix) - if: matrix.os == 'ubuntu-latest' + # Configure on Ubuntu without modules: GCC + Unix Makefiles + - name: "Configure (Ubuntu • non-module: GCC + Makefiles)" + if: matrix.os == 'ubuntu-latest' && matrix.enable_module == 'OFF' + run: | + cmake -S attachments/simple_engine \ + -B build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} + + # Configure on Ubuntu with modules enabled: use Clang + Ninja (required for C++ modules) + - name: "Configure (Ubuntu • module: Clang + Ninja)" + if: matrix.os == 'ubuntu-latest' && matrix.enable_module == 'ON' run: | cmake -S attachments/simple_engine \ -B build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} \ + -G Ninja \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} diff --git a/attachments/simple_engine/CMakeLists.txt b/attachments/simple_engine/CMakeLists.txt index 76d5d119..ee3e2636 100644 --- a/attachments/simple_engine/CMakeLists.txt +++ b/attachments/simple_engine/CMakeLists.txt @@ -1,8 +1,5 @@ cmake_minimum_required(VERSION 3.29) -# Enable C++ module dependency scanning -set(CMAKE_CXX_SCAN_FOR_MODULES ON) - project(SimpleEngine VERSION 1.0.0 LANGUAGES CXX C) # Option to enable/disable Vulkan C++20 module support for this standalone project diff --git a/vcpkg.json b/vcpkg.json index 298c6729..905deba4 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -9,7 +9,6 @@ "tinygltf", "nlohmann-json", "ktx", - "openal-soft", - "vulkan" + "openal-soft" ] } From cb16fd1811586b17353f15d42f779b7f998dbe62 Mon Sep 17 00:00:00 2001 From: swinston Date: Wed, 3 Dec 2025 12:06:31 -0800 Subject: [PATCH 5/5] Refactor entity resource loops to remove use of `std::views`, replacing with explicit iteration for improved clarity and maintainability. Enhance CI workflows with caching for Vulkan SDK, dependencies, and build artifacts on both Windows and Ubuntu. Add ccache and sccache integration to improve build performance. --- .github/workflows/simple_engine.yml | 210 ++++++++++++++++-- attachments/simple_engine/model_loader.cpp | 7 +- attachments/simple_engine/renderer_core.cpp | 3 +- .../simple_engine/renderer_rendering.cpp | 6 +- .../simple_engine/renderer_resources.cpp | 3 +- .../simple_engine/resource_manager.cpp | 6 +- 6 files changed, 208 insertions(+), 27 deletions(-) diff --git a/.github/workflows/simple_engine.yml b/.github/workflows/simple_engine.yml index a1ac7b36..7efa8b14 100644 --- a/.github/workflows/simple_engine.yml +++ b/.github/workflows/simple_engine.yml @@ -35,6 +35,74 @@ jobs: fetch-depth: 0 submodules: recursive + # Cache Vulkan SDK on Windows like in workflow.yml + - name: Cache Vulkan SDK (Windows) + if: runner.os == 'Windows' + uses: actions/cache@v3 + with: + path: C:\VulkanSDK + key: ${{ runner.os }}-vulkan-sdk-${{ hashFiles('**/CMakeLists.txt', '**/*.cpp', '**/*.h') }} + restore-keys: | + ${{ runner.os }}-vulkan-sdk-${{ hashFiles('**/CMakeLists.txt') }}- + ${{ runner.os }}-vulkan-sdk- + + # Cache vcpkg packages (Windows) like in workflow.yml + - name: Cache vcpkg packages (Windows) + if: runner.os == 'Windows' + uses: actions/cache@v3 + with: + path: | + ${{ env.VCPKG_INSTALLATION_ROOT }}/installed + ${{ env.VCPKG_INSTALLATION_ROOT }}/packages + ${{ env.VCPKG_INSTALLATION_ROOT }}/buildtrees + ${{ env.VCPKG_INSTALLATION_ROOT }}/downloads + ${{ runner.temp }}/vcpkg-cache + key: ${{ runner.os }}-vcpkg-${{ hashFiles('scripts/install_dependencies_windows.bat', '**/CMakeLists.txt') }} + restore-keys: | + ${{ runner.os }}-vcpkg-${{ hashFiles('scripts/install_dependencies_windows.bat') }}- + ${{ runner.os }}-vcpkg- + + # Cache apt packages (Ubuntu) + - name: Cache apt packages (Ubuntu) + if: runner.os == 'Linux' + uses: actions/cache@v3 + with: + path: /var/cache/apt/archives + key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/simple_engine.yml') }} + restore-keys: | + ${{ runner.os }}-apt- + + # Cache ccache (Ubuntu) + - name: Cache ccache files (Ubuntu) + if: runner.os == 'Linux' + uses: actions/cache@v3 + with: + path: | + ~/.ccache + key: ${{ runner.os }}-ccache-${{ hashFiles('attachments/simple_engine/**', '**/CMakeLists.txt') }} + restore-keys: | + ${{ runner.os }}-ccache- + + # Cache Vulkan SDK directory (Ubuntu) + - name: Cache Vulkan SDK (Ubuntu) + if: runner.os == 'Linux' + uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/vulkan-sdk + key: ${{ runner.os }}-vulkan-sdk-${{ hashFiles('**/CMakeLists.txt') }}-${{ hashFiles('attachments/simple_engine/**') }} + restore-keys: | + ${{ runner.os }}-vulkan-sdk-${{ hashFiles('**/CMakeLists.txt') }}- + ${{ runner.os }}-vulkan-sdk- + + # Cache sccache binary (Windows) + - name: Cache sccache binary (Windows) + if: runner.os == 'Windows' + id: cache-sccache + uses: actions/cache@v3 + with: + path: ${{ runner.temp }}/sccache + key: ${{ runner.os }}-sccache-0.5.4 + # ----------------------- # Linux: set up Vulkan SDK similar to workflow.yml # ----------------------- @@ -70,6 +138,15 @@ jobs: libxi-dev \ libopenal-dev + - name: Install and configure ccache (Ubuntu) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install -y ccache + ccache --max-size=2G + ccache -z + echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Install project deps via script (Ubuntu) if: matrix.os == 'ubuntu-latest' working-directory: attachments/simple_engine @@ -85,14 +162,43 @@ jobs: if: matrix.os == 'windows-latest' shell: pwsh run: | - git clone https://github.com/microsoft/vcpkg.git $env:USERPROFILE\vcpkg - & $env:USERPROFILE\vcpkg\bootstrap-vcpkg.bat + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT + if (-not $vcpkgRoot) { $vcpkgRoot = "C:\vcpkg" } + if (-not (Test-Path $vcpkgRoot)) { + git clone https://github.com/microsoft/vcpkg.git $vcpkgRoot + & "$vcpkgRoot\bootstrap-vcpkg.bat" + } $triplet = 'x64-windows' # Use manifest mode; vcpkg.json at repo root defines dependencies - & $env:USERPROFILE\vcpkg\vcpkg.exe install --triplet $triplet - echo "CMAKE_TOOLCHAIN_FILE=$env:USERPROFILE\vcpkg\scripts\buildsystems\vcpkg.cmake" >> $env:GITHUB_ENV + & "$vcpkgRoot\vcpkg.exe" install --triplet $triplet + echo "VCPKG_INSTALLATION_ROOT=$vcpkgRoot" >> $env:GITHUB_ENV + echo "CMAKE_TOOLCHAIN_FILE=$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" >> $env:GITHUB_ENV echo "VCPKG_TARGET_TRIPLET=$triplet" >> $env:GITHUB_ENV + - name: Install sccache (Windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + if (Test-Path "$env:RUNNER_TEMP\sccache\sccache.exe") { + Write-Host "Using cached sccache binary" + $sccachePath = "$env:RUNNER_TEMP\sccache" + } else { + Write-Host "Downloading and installing sccache..." + New-Item -ItemType Directory -Force -Path "$env:RUNNER_TEMP\sccache" | Out-Null + choco install -y aria2 --no-progress + aria2c --split=8 --max-connection-per-server=8 --min-split-size=1M --dir="$env:RUNNER_TEMP" --out="sccache.tar.gz" "https://github.com/mozilla/sccache/releases/download/v0.5.4/sccache-v0.5.4-x86_64-pc-windows-msvc.tar.gz" + tar -xzf "$env:RUNNER_TEMP\sccache.tar.gz" --strip-components=1 -C "$env:RUNNER_TEMP\sccache" "sccache-v0.5.4-x86_64-pc-windows-msvc/sccache.exe" + $sccachePath = "$env:RUNNER_TEMP\sccache" + } + echo "$sccachePath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "SCCACHE_DIR=$HOME/.cache/sccache" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "SCCACHE_CACHE_SIZE=4G" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "SCCACHE_ERROR_LOG=$HOME/.cache/sccache/sccache.log" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "SCCACHE_LOG=info" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "RUST_LOG=sccache=info" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + New-Item -ItemType Directory -Force -Path "$HOME/.cache/sccache" | Out-Null + & "$sccachePath\sccache.exe" --version + - name: Install project deps via script (Windows) if: matrix.os == 'windows-latest' shell: cmd @@ -100,17 +206,51 @@ jobs: run: | if exist install_dependencies_windows.bat call install_dependencies_windows.bat || exit /b 0 - # Install LunarG Vulkan SDK on Windows and export environment variables for our FindVulkan.cmake + # Install LunarG Vulkan SDK on Windows and export environment variables (mirror workflow.yml) - name: Install Vulkan SDK (Windows) if: matrix.os == 'windows-latest' shell: pwsh run: | - choco install vulkan-sdk -y --no-progress - $sdkDir = Get-ChildItem -Path 'C:\VulkanSDK' -ErrorAction SilentlyContinue | Sort-Object Name -Descending | Select-Object -First 1 - if (-not $sdkDir) { throw "Vulkan SDK was not installed to C:\VulkanSDK" } - echo "Using Vulkan SDK: $($sdkDir.FullName)" - echo "VULKAN_SDK=$($sdkDir.FullName)" >> $env:GITHUB_ENV - echo "PATH=$($sdkDir.FullName)\Bin;$env:PATH" >> $env:GITHUB_ENV + if (Test-Path "C:\VulkanSDK") { + Write-Host "Using cached Vulkan SDK" + } else { + Write-Host "Downloading Vulkan SDK installer from LunarG..." + choco install -y aria2 --no-progress + aria2c --split=16 --max-connection-per-server=16 --min-split-size=1M --dir="$env:TEMP" --out="vulkan-sdk.exe" "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-sdk.exe" + + Write-Host "Installing Vulkan SDK silently..." + try { + Start-Process -FilePath "$env:TEMP\vulkan-sdk.exe" -ArgumentList "--accept-licenses --default-answer --confirm-command install --components VulkanRT,VulkanSDK64,VulkanDXC,VulkanTools" -Wait -NoNewWindow + if (-not (Test-Path "C:\VulkanSDK")) { + Write-Host "Vulkan SDK installation with components failed; retrying full install..." + Start-Process -FilePath "$env:TEMP\vulkan-sdk.exe" -ArgumentList "--accept-licenses --default-answer --confirm-command install" -Wait -NoNewWindow + } + } catch { + Write-Host "Error installing Vulkan SDK: $_" + Write-Host "Retrying full install without component selection..." + Start-Process -FilePath "$env:TEMP\vulkan-sdk.exe" -ArgumentList "--accept-licenses --default-answer --confirm-command install" -Wait -NoNewWindow + } + } + + # Resolve installed Vulkan SDK path (latest) + $vulkanPath = "" + if (Test-Path "C:\VulkanSDK") { + $vulkanPath = Get-ChildItem "C:\VulkanSDK" | Sort-Object -Property Name -Descending | Select-Object -First 1 -ExpandProperty FullName + } + if (-not $vulkanPath) { + if (Test-Path "C:\VulkanSDK\latest") { + $vulkanPath = "C:\VulkanSDK\latest" + } else { + throw "Vulkan SDK not found after installation." + } + } + + Write-Host "Using Vulkan SDK: $vulkanPath" + echo "VULKAN_SDK=$vulkanPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "$vulkanPath\Bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "CMAKE_PREFIX_PATH=$vulkanPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "Vulkan_INCLUDE_DIR=$vulkanPath\Include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "Vulkan_LIBRARY=$vulkanPath\Lib\vulkan-1.lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append # ----------------------- # Configure & Build @@ -122,7 +262,9 @@ jobs: cmake -S attachments/simple_engine \ -B build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} + -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache # Configure on Ubuntu with modules enabled: use Clang + Ninja (required for C++ modules) - name: "Configure (Ubuntu • module: Clang + Ninja)" @@ -134,7 +276,9 @@ jobs: -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} + -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Configure (Windows) if: matrix.os == 'windows-latest' @@ -145,13 +289,43 @@ jobs: -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ` -DENABLE_CPP20_MODULE=${{ matrix.enable_module }} ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` - -DVCPKG_TARGET_TRIPLET="$env:VCPKG_TARGET_TRIPLET" + -DVCPKG_TARGET_TRIPLET="$env:VCPKG_TARGET_TRIPLET" ` + -DCMAKE_C_COMPILER_LAUNCHER=sccache ` + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + + # Cache build artifacts (Windows) + - name: Cache build artifacts (Windows) + if: runner.os == 'Windows' + uses: actions/cache@v3 + with: + path: | + build-simple_engine-windows-latest-* + key: ${{ runner.os }}-build-msvc-${{ hashFiles('attachments/simple_engine/**', '**/CMakeLists.txt') }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} + restore-keys: | + ${{ runner.os }}-build-msvc-${{ hashFiles('attachments/simple_engine/**') }}- + ${{ runner.os }}-build-msvc- + + # Cache build artifacts (Ubuntu) + - name: Cache build artifacts (Ubuntu) + if: runner.os == 'Linux' + uses: actions/cache@v3 + with: + path: | + build-simple_engine-ubuntu-latest-* + key: ${{ runner.os }}-build-${{ hashFiles('attachments/simple_engine/**', '**/CMakeLists.txt') }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} + restore-keys: | + ${{ runner.os }}-build-${{ hashFiles('attachments/simple_engine/**') }}- + ${{ runner.os }}-build- - name: Build run: | cmake --build build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} --config ${{ matrix.build_type }} - - name: Package (Release only) - if: matrix.build_type == 'Release' - run: | - cmake --build build-simple_engine-${{ matrix.os }}-${{ matrix.build_type }}-m${{ matrix.enable_module }} --target package --config ${{ matrix.build_type }} + - name: ccache statistics + if: runner.os == 'Linux' + run: ccache -s + + - name: sccache statistics + if: runner.os == 'Windows' + shell: pwsh + run: sccache -s diff --git a/attachments/simple_engine/model_loader.cpp b/attachments/simple_engine/model_loader.cpp index 1603bad4..f07a0bab 100644 --- a/attachments/simple_engine/model_loader.cpp +++ b/attachments/simple_engine/model_loader.cpp @@ -680,7 +680,8 @@ bool ModelLoader::ParseGLTF(const std::string& filename, Model* model) { // Heuristic pass: fill missing baseColor (albedo) by deriving from normal map filenames // Many Bistro materials have no baseColorTexture index. When that happens, try inferring // the base color from the normal map by replacing common suffixes like _ddna -> _d/_c/_diffuse/_basecolor/_albedo. - for (auto& material : materials | std::views::values) { + for (auto& kv : materials) { + auto& material = kv.second; Material* mat = material.get(); if (!mat) continue; if (!mat->albedoTexturePath.empty()) continue; // already set @@ -1136,8 +1137,8 @@ if (materialMesh.vertices.empty()) { // Convert geometry-based material mesh map to vector std::vector modelMaterialMeshes; - for (auto& val : geometryMaterialMeshMap | std::views::values) { - modelMaterialMeshes.push_back(val); + for (auto& kv : geometryMaterialMeshMap) { + modelMaterialMeshes.push_back(kv.second); } // Process texture loading for each MaterialMesh diff --git a/attachments/simple_engine/renderer_core.cpp b/attachments/simple_engine/renderer_core.cpp index b6252161..eef25e26 100644 --- a/attachments/simple_engine/renderer_core.cpp +++ b/attachments/simple_engine/renderer_core.cpp @@ -235,7 +235,8 @@ void Renderer::Cleanup() { // Wait for the device to be idle before cleaning up device.waitIdle(); - for (auto& resources : entityResources | std::views::values) { + for (auto& kv : entityResources) { + auto& resources = kv.second; // Memory pool handles unmapping automatically, no need to manually unmap resources.basicDescriptorSets.clear(); resources.pbrDescriptorSets.clear(); diff --git a/attachments/simple_engine/renderer_rendering.cpp b/attachments/simple_engine/renderer_rendering.cpp index 451ae34c..9af2c4d5 100644 --- a/attachments/simple_engine/renderer_rendering.cpp +++ b/attachments/simple_engine/renderer_rendering.cpp @@ -316,7 +316,8 @@ void Renderer::recreateSwapChain() { } // Clear all entity descriptor sets since they're now invalid (allocated from the old pool) - for (auto& resources : entityResources | std::views::values) { + for (auto& kv : entityResources) { + auto& resources = kv.second; resources.basicDescriptorSets.clear(); resources.pbrDescriptorSets.clear(); } @@ -331,7 +332,8 @@ void Renderer::recreateSwapChain() { currentFrame = 0; // Recreate descriptor sets for all entities after swapchain/pipeline rebuild - for (const auto& entity : entityResources | std::views::keys) { + for (const auto& kv : entityResources) { + const auto& entity = kv.first; if (!entity) continue; auto meshComponent = entity->GetComponent(); if (!meshComponent) continue; diff --git a/attachments/simple_engine/renderer_resources.cpp b/attachments/simple_engine/renderer_resources.cpp index cc9fadf7..339e5913 100644 --- a/attachments/simple_engine/renderer_resources.cpp +++ b/attachments/simple_engine/renderer_resources.cpp @@ -1893,7 +1893,8 @@ bool Renderer::createOrResizeLightStorageBuffers(size_t lightCount) { void Renderer::updateAllDescriptorSetsWithNewLightBuffers() { try { // Iterate through all entity resources and update their PBR descriptor sets - for (auto& resources : entityResources | std::views::values) { + for (auto& kv : entityResources) { + auto& resources = kv.second; // Only update PBR descriptor sets (they have light buffer bindings) if (!resources.pbrDescriptorSets.empty()) { for (size_t i = 0; i < resources.pbrDescriptorSets.size() && i < lightStorageBuffers.size(); ++i) { diff --git a/attachments/simple_engine/resource_manager.cpp b/attachments/simple_engine/resource_manager.cpp index 5102539c..8ce4cf58 100644 --- a/attachments/simple_engine/resource_manager.cpp +++ b/attachments/simple_engine/resource_manager.cpp @@ -18,8 +18,10 @@ void Resource::Unload() { } void ResourceManager::UnloadAllResources() { - for (auto& val : resources | std::views::values) { - for (auto& loadedResource : val | std::views::values) { + for (auto& kv : resources) { + auto& val = kv.second; + for (auto& innerKv : val) { + auto& loadedResource = innerKv.second; loadedResource->Unload(); } val.clear();