Skip to content
Closed
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 .github/workflows/linux-docker-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ on:

jobs:
build-and-test-linux:
if: false # TODO: Re-enable later
runs-on: ubuntu-latest
timeout-minutes: 6

Expand Down
39 changes: 35 additions & 4 deletions .github/workflows/linux-smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
timeout-minutes: 6
env:
# Force CPU Vulkan ICD (lavapipe) so the smoke test runs without a GPU
VK_ICD_FILENAMES: /usr/share/vulkan/icd.d/lvp_icd.x86_64.json
VK_ICD_FILENAMES: /usr/share/vulkan/icd.d/lvp_icd.json
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -41,18 +41,21 @@ jobs:
libglfw3 libglfw3-dev libvulkan-dev \
glslang-tools glslang-dev libglm-dev \
mesa-vulkan-drivers xvfb pkg-config \
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \
weston

- name: Configure
run: cmake -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -G Ninja .
run: cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZERS=ON -DBUILD_TESTS=ON -G Ninja .

- name: Build
run: cmake --build build

- name: GTEST (Includes Validating Frame Dumps)
run: |
echo "VK_ICD_FILENAMES=$VK_ICD_FILENAMES"
ls -l /usr/share/vulkan/icd.d/
xvfb-run -s "-screen 0 1024x768x24" \
env VSDF_SMOKE_TESTS=1 build/tests/vsdf_tests
env VK_LOADER_DEBUG=all VSDF_SMOKE_TESTS=1 build/tests/vsdf_tests

- name: Vulkan single frame smoke test (CPU driver via lavapipe + fake display)
run: |
Expand All @@ -64,3 +67,31 @@ jobs:
run: |
xvfb-run -s "-screen 0 1024x768x24" \
./build/vsdf --toy shaders/testtoyshader.frag --frames 100 --headless --log-level info

- name: Start Weston (Wayland headless)
run: |
export XDG_RUNTIME_DIR=/tmp/xdg-runtime
mkdir -p "$XDG_RUNTIME_DIR"
chmod 700 "$XDG_RUNTIME_DIR"
weston --backend=headless-backend.so --socket=wayland-0 --idle-time=0 --log=weston.log &
for i in {1..20}; do
if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
break
fi
sleep 0.2
done
if [ ! -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
echo "Wayland socket not found; dumping weston.log"
cat weston.log || true
exit 1
fi

- name: Wayland headless smoke test
env:
GLFW_PLATFORM: wayland
XDG_SESSION_TYPE: wayland
XDG_RUNTIME_DIR: /tmp/xdg-runtime
WAYLAND_DISPLAY: wayland-0
run: |
env -u DISPLAY \
./build/vsdf --toy shaders/testtoyshader.frag --frames 1 --headless --log-level debug
1 change: 1 addition & 0 deletions .github/workflows/macos-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ on:

jobs:
build-and-test-macos:
if: false # TODO: Re-enable later
name: Build and Test on macOS
runs-on: macos-latest
timeout-minutes: 6
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/nix-flake-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:

jobs:
nix-flake-test:
if: false # TODO: Re-enable later
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/windows-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ on:

jobs:
build-and-test-windows:
if: false # TODO: Re-enable later
name: Build and Test on Windows
runs-on: windows-latest

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ else()
endif()

if (ENABLE_SANITIZERS)
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer -g)
add_compile_options(-fsanitize=address,undefined -fno-sanitize=vptr -fno-omit-frame-pointer -g)
add_link_options(-fsanitize=address,undefined)
endif()

Expand Down
6 changes: 5 additions & 1 deletion include/vkutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
#define VK_CHECK(x) \
do { \
VkResult err = x; \
if (err) \
if (err) { \
spdlog::error("Vulkan error: {} (0x{:x})", \
static_cast<int>(err), \
static_cast<uint32_t>(err)); \
throw std::logic_error("Got a runtime_error"); \
} \
} while (0);

inline constexpr size_t MAX_FRAME_SLOTS = 10;
Expand Down
15 changes: 12 additions & 3 deletions tests/test_offline_ffmpeg_encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,29 @@ TEST(OfflineFFmpegEncode, RendersAndEncodesMp4) {

const auto outPath =
std::filesystem::current_path() / "offline_ffmpeg_test.mp4";
const auto logPath =
std::filesystem::current_path() / "offline_ffmpeg_test.log";
std::error_code ec;
std::filesystem::remove(outPath, ec);
std::filesystem::remove(logPath, ec);

const uint32_t framesToRender = 10;
const std::string cmd = fmt::format(
"\"{}\" \"{}\" --toy --frames {} "
"--ffmpeg-output \"{}\" --ffmpeg-codec {} --ffmpeg-fps 30 "
"--ffmpeg-crf 23 --ffmpeg-preset veryfast",
"--ffmpeg-crf 23 --ffmpeg-preset veryfast --log-level debug "
"> \"{}\" 2>&1",
VSDF_BINARY_PATH, shaderPath.string(), framesToRender,
outPath.string(), encoderName);
outPath.string(), encoderName, logPath.string());

const int rc = std::system(cmd.c_str());
std::filesystem::current_path(oldCwd);
ASSERT_EQ(rc, 0);
if (rc != 0) {
const std::string log = readLogFileToString(logPath);
FAIL() << "Command failed (" << rc << "): " << cmd
<< "\n--- vsdf log ---\n"
<< log;
}

ASSERT_TRUE(std::filesystem::exists(outPath));
ASSERT_GT(std::filesystem::file_size(outPath), 0u);
Expand Down
29 changes: 23 additions & 6 deletions tests/test_offline_ppm_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,25 @@ TEST(OfflinePPMDump, DebugQuadrants) {
std::filesystem::current_path(VSDF_SOURCE_DIR);

const auto outVideoPath = outDir / "offline_ppm_dump.mp4";
const auto logPath = outDir / "offline_ppm_dump.log";
std::error_code ec;
std::filesystem::remove(outVideoPath, ec);
std::filesystem::remove(logPath, ec);
const std::string cmd =
fmt::format("\"{}\" \"{}\" --toy --frames {} "
"--debug-dump-ppm \"{}\" --ffmpeg-output \"{}\" "
"--ffmpeg-codec {}",
"--ffmpeg-codec {} --log-level debug > \"{}\" 2>&1",
VSDF_BINARY_PATH, shaderPath.string(), framesToRender,
outDir.string(), outVideoPath.string(), encoderName);
outDir.string(), outVideoPath.string(), encoderName,
logPath.string());
const int rc = std::system(cmd.c_str());
std::filesystem::current_path(oldCwd);
ASSERT_EQ(rc, 0);
if (rc != 0) {
const std::string log = readLogFileToString(logPath);
FAIL() << "Command failed (" << rc << "): " << cmd
<< "\n--- vsdf log ---\n"
<< log;
}

const std::filesystem::path ppmPath = outDir / "frame_0000.ppm";
ASSERT_TRUE(std::filesystem::exists(ppmPath));
Expand Down Expand Up @@ -118,16 +126,25 @@ TEST(OfflinePPMDump, RingBufferMultipleFrames) {
const uint32_t framesToRender = 10;
const uint32_t ringSize = 3;
const auto outVideoPath = outDir / "offline_ppm_ring_dump.mp4";
const auto logPath = outDir / "offline_ppm_ring_dump.log";
std::error_code ec;
std::filesystem::remove(outVideoPath, ec);
std::filesystem::remove(logPath, ec);
const std::string cmd = fmt::format(
"\"{}\" \"{}\" --toy --frames {} --ffmpeg-ring-buffer-size {} "
"--debug-dump-ppm \"{}\" --ffmpeg-output \"{}\" --ffmpeg-codec {}",
"--debug-dump-ppm \"{}\" --ffmpeg-output \"{}\" --ffmpeg-codec {} "
"--log-level debug > \"{}\" 2>&1",
VSDF_BINARY_PATH, shaderPath.string(), framesToRender, ringSize,
outDir.string(), outVideoPath.string(), encoderName);
outDir.string(), outVideoPath.string(), encoderName,
logPath.string());
const int rc = std::system(cmd.c_str());
std::filesystem::current_path(oldCwd);
ASSERT_EQ(rc, 0);
if (rc != 0) {
const std::string log = readLogFileToString(logPath);
FAIL() << "Command failed (" << rc << "): " << cmd
<< "\n--- vsdf log ---\n"
<< log;
}

const std::filesystem::path ppmPathFirst = outDir / "frame_0000.ppm";
ASSERT_TRUE(std::filesystem::exists(ppmPathFirst));
Expand Down
18 changes: 14 additions & 4 deletions tests/test_online_ppm_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,22 @@ TEST(OnlinePPMDump, DebugQuadrants) {
// Move to the current dir to resolve shaders correctly
std::filesystem::current_path(VSDF_SOURCE_DIR);

const std::string cmd =
fmt::format("\"{}\" \"{}\" --toy --headless --frames 1 --debug-dump-ppm \"{}\"",
VSDF_BINARY_PATH, shaderPath.string(), outDir.string());
const auto logPath = outDir / "online_ppm_dump.log";
std::error_code ec;
std::filesystem::remove(logPath, ec);
const std::string cmd = fmt::format(
"\"{}\" \"{}\" --toy --headless --frames 1 --debug-dump-ppm \"{}\" "
"--log-level debug > \"{}\" 2>&1",
VSDF_BINARY_PATH, shaderPath.string(), outDir.string(),
logPath.string());
const int rc = std::system(cmd.c_str());
std::filesystem::current_path(oldCwd);
ASSERT_EQ(rc, 0);
if (rc != 0) {
const std::string log = readLogFileToString(logPath);
FAIL() << "Command failed (" << rc << "): " << cmd
<< "\n--- vsdf log ---\n"
<< log;
}

const std::filesystem::path ppmPath = outDir / "frame_0000.ppm";
ASSERT_TRUE(std::filesystem::exists(ppmPath));
Expand Down
18 changes: 18 additions & 0 deletions tests/test_utils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef TEST_UTILS_H
#define TEST_UTILS_H
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <string>

Expand Down Expand Up @@ -28,4 +29,21 @@ inline bool shouldSkipSmokeTests() {
const bool smokeEnabled = smokeEnv && std::string(smokeEnv) == "1";
return inCi && !smokeEnabled;
}

// Non-throwing log helper: if the log is missing/unreadable, return empty
// so the test failure still reports the original command error.
[[nodiscard]] inline std::string readLogFileToString(const std::filesystem::path &path) {
std::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
return {};
}
const std::ifstream::pos_type size = file.tellg();
if (size <= 0) {
return {};
}
std::string out(static_cast<size_t>(size), '\0');
file.seekg(0, std::ios::beg);
file.read(out.data(), out.size());
return out;
}
#endif // TEST_UTILS_H
Loading