Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ scripts/lint-cpp.sh --fix # rewrite the formatting and apply the fixes clang-

Both tools come from the NDK the project pins, so a machine that builds the library can lint it; `.clang-format` and `.clang-tidy` at the root hold the rules.
The script configures `splat-core`, `splatkit-engine` and `splatkit-android` for the Android target and lints tests and tools too.
It also links the Android native tests, so a wrong source path or an undefined reference fails CI; [running them on a device](packages/splatkit-android/README.md#native-tests-on-a-device) stays manual.
`git config core.hooksPath .githooks` installs a pre-push hook that runs `scripts/lint-cpp.sh --format-only`, the seconds-long formatting half of that check.
VS Code's C/C++ extension reads the compile databases it leaves in `build/lint`, as [.vscode/settings.json](.vscode/settings.json) sets up.
clang-tidy holds every function to its default cognitive complexity of 25, counting the source as written, so test assertion macros add nothing.
Expand Down
19 changes: 19 additions & 0 deletions packages/splatkit-android/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ cd apps/android-dev
./gradlew :splatkit:assembleRelease :splatkit:testDebugUnitTest
```

## Native tests on a device

The `splatkit_vulkan_*_test` executables need a real Vulkan device and run without a surface.
`scripts/lint-cpp.sh` links all of them in CI; running them is a manual device step.
Build them outside the checkout with the NDK toolchain flags from that script plus `-DSPLATKIT_ANDROID_BUILD_TESTS=ON`.

```sh
cmake -S packages/splatkit-android/src/main/cpp -B "$BUILD" \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29 -DANDROID_STL=c++_static \
-DSPLATKIT_ANDROID_BUILD_TESTS=ON
cmake --build "$BUILD" --target splatkit_android_tests
for t in "$BUILD"/tests/splatkit_vulkan_*_test; do
adb push "$t" /data/local/tmp/ && adb shell "/data/local/tmp/$(basename "$t")"
done
```

Each test exits 0 on success; `splatkit_vulkan_buffer_test` and `splatkit_vulkan_upload_pressure_test` accept `--small` for a device with little memory, which skips their large cases.

Tests and emulator evidence do not replace physical Adreno/Mali validation or reference-image acceptance.
Source builds enable 16 KB ELF alignment; CI checks every packaged shared library and APK ZIP alignment with `scripts/check_android_alignment.py`.
Artifact alignment checks do not replace execution on a 16 KB device.
39 changes: 25 additions & 14 deletions packages/splatkit-android/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,38 @@ target_compile_options(splatkit_vulkan_test_support PRIVATE
target_link_libraries(splatkit_vulkan_test_support PUBLIC
splatkit_engine vk-bootstrap::vk-bootstrap GPUOpen::VulkanMemoryAllocator vulkan android log)

add_executable(splatkit_gpu_buffer_test rendering/vulkan/device/VulkanBufferTest.cpp)
target_link_libraries(splatkit_gpu_buffer_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_gpu_upload_pressure_test rendering/vulkan/device/VulkanUploadPressureTest.cpp)
target_link_libraries(splatkit_gpu_upload_pressure_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_world_test rendering/vulkan/world/VulkanWorldTest.cpp
add_executable(splatkit_vulkan_buffer_test rendering/vulkan/device/VulkanBufferTest.cpp)
target_link_libraries(splatkit_vulkan_buffer_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_vulkan_upload_pressure_test rendering/vulkan/device/VulkanUploadPressureTest.cpp)
target_link_libraries(splatkit_vulkan_upload_pressure_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_vulkan_world_test rendering/vulkan/world/VulkanWorldTest.cpp
${vulkan_source_dir}/world/VulkanWorld.cpp)
target_link_libraries(splatkit_world_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_lod_selection_test rendering/vulkan/selection/VulkanLodSelectionTest.cpp
target_link_libraries(splatkit_vulkan_world_test PRIVATE splatkit_vulkan_test_support)
add_executable(splatkit_vulkan_lod_selection_test rendering/vulkan/selection/VulkanLodSelectionTest.cpp
${vulkan_source_dir}/selection/VulkanLodSelection.cpp)
target_link_libraries(splatkit_lod_selection_test PRIVATE
target_link_libraries(splatkit_vulkan_lod_selection_test PRIVATE
splatkit_vulkan_test_support splatkit_shaders)
add_executable(splatkit_visibility_test rendering/vulkan/cull/VulkanVisibilityPassTest.cpp
add_executable(splatkit_vulkan_visibility_pass_test rendering/vulkan/cull/VulkanVisibilityPassTest.cpp
${vulkan_source_dir}/cull/VulkanVisibilityPass.cpp)
target_link_libraries(splatkit_visibility_test PRIVATE
target_link_libraries(splatkit_vulkan_visibility_pass_test PRIVATE
splatkit_vulkan_test_support splatkit_shaders)
add_executable(splatkit_vulkan_frame_test rendering/vulkan/frame/VulkanFrameComputeTest.cpp
add_executable(splatkit_vulkan_frame_compute_test rendering/vulkan/frame/VulkanFrameComputeTest.cpp
${vulkan_source_dir}/frame/VulkanFrameCompute.cpp ${vulkan_source_dir}/selection/VulkanLodSelection.cpp
${vulkan_source_dir}/cull/VulkanVisibilityPass.cpp ${vulkan_source_dir}/sort/VulkanRadixSort.cpp)
target_link_libraries(splatkit_vulkan_frame_test PRIVATE
target_link_libraries(splatkit_vulkan_frame_compute_test PRIVATE
splatkit_vulkan_test_support splatkit_shaders)
add_executable(splatkit_radix_sort_test rendering/vulkan/sort/VulkanRadixSortTest.cpp
add_executable(splatkit_vulkan_radix_sort_test rendering/vulkan/sort/VulkanRadixSortTest.cpp
${vulkan_source_dir}/sort/VulkanRadixSort.cpp)
target_link_libraries(splatkit_radix_sort_test PRIVATE
target_link_libraries(splatkit_vulkan_radix_sort_test PRIVATE
splatkit_vulkan_test_support splatkit_shaders)

# Building this target links every device test; scripts/lint-cpp.sh does so in CI.
add_custom_target(splatkit_android_tests DEPENDS
splatkit_vulkan_buffer_test
splatkit_vulkan_upload_pressure_test
splatkit_vulkan_world_test
splatkit_vulkan_lod_selection_test
splatkit_vulkan_visibility_pass_test
splatkit_vulkan_frame_compute_test
splatkit_vulkan_radix_sort_test
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main(int argc, char** argv) {
using test::require;
try {
const bool small = argc == 2 && std::strcmp(argv[1], "--small") == 0;
require(argc == 1 || small, "usage: splatkit_gpu_buffer_test [--small]");
require(argc == 1 || small, "usage: splatkit_vulkan_buffer_test [--small]");
test::VulkanTestContext gpu;
std::printf("GPU: %s\n", gpu.context->deviceDescription().c_str());
std::vector<uint8_t> expected(small ? 4096 : 16000000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int main(int argc, char** argv) {
std::setvbuf(stdout, nullptr, _IONBF, 0);
try {
const bool small = argc == 2 && std::strcmp(argv[1], "--small") == 0;
require(argc == 1 || small, "usage: splatkit_gpu_upload_pressure_test [--small]");
require(argc == 1 || small, "usage: splatkit_vulkan_upload_pressure_test [--small]");
splatkit::test::VulkanTestContext gpu;
const uint32_t capacity = small ? 262145 : 3000000;
std::printf("upload-pressure GPU=%s capacity=%u validation=%s\n",
Expand Down
10 changes: 9 additions & 1 deletion scripts/lint-cpp.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# Formats and lints every C++ source of the repository with the clang tools the NDK
# ships, so the machine that builds the library is the machine that lints it.
# ships, so the machine that builds the library is the machine that lints it. It also
# links the Android device tests, which nothing else builds in CI.
#
# scripts/lint-cpp.sh check: exit 1 on a formatting or clang-tidy finding
# scripts/lint-cpp.sh --fix rewrite the formatting and apply clang-tidy's fixes
Expand Down Expand Up @@ -90,6 +91,13 @@ cmake -S "$android" -B "$build/android" "${toolchain[@]}" \
-DSPLATKIT_ANDROID_BUILD_TESTS=ON > /dev/null
# The splat pipeline includes the generated shader headers.
cmake --build "$build/android" --target splatkit_shaders_generate > /dev/null
# Linking the device tests catches a wrong source path or an undefined reference that
# clang-tidy, which only parses, would let through to a phone.
echo "link splatkit-android tests"
if ! tests_log="$(cmake --build "$build/android" --target splatkit_android_tests 2>&1)"; then
printf '%s\n' "$tests_log" >&2
exit 1
fi

failed=0
tidy() { # <compile database dir> <sources...>
Expand Down
Loading