GLdc/tests/README.md
2026-06-22 09:05:44 +01:00

128 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GLdc test suite
The tests are plain C++ headers under `tests/`. Every class deriving from
`test::TestCase` (or `GLTestCase`) is auto-discovered (see
`tools/test_generator.py`) and each `void test_*()` method becomes a test case.
They build into the `gldc_tests` binary.
The same tests run on two backends:
* **desktop / software** backend — fast iteration in CI;
* **Dreamcast / kospvr** backend — the real target, run under an emulator.
Suites that drive the GL API derive from **`GLTestCase`** (`tools/gl_test.h`),
which initialises the GPU exactly once and resets GL state before each test
(see "Running once on the Dreamcast" below). Pure non-GL suites (e.g. the
standalone allocator tests) derive from `test::TestCase` directly.
## Desktop
```sh
# configure + build (32-bit desktop build)
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make gldc_tests
# run everything (headless)
SDL_VIDEODRIVER=dummy ./tests/gldc_tests
# run a single suite (prefix match on "Suite::test")
SDL_VIDEODRIVER=dummy ./tests/gldc_tests TextureFormatTests
```
## Dreamcast
Build with the KallistiOS toolchain inside the `kazade/dreamcast-sdk`
container, then run the resulting `.elf` under the
[nitrocast](https://gitlab.com/simulant/nitrocast) emulator:
```sh
# build (from the repo root; KOS_BASE is set inside the container)
podman run --rm -v "$PWD":"$PWD":Z -w "$PWD" localhost/kazade/dreamcast-sdk \
/bin/sh -c "source /etc/bash.bashrc; \
mkdir -p dcbuild && cd dcbuild && \
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/Dreamcast.cmake \
-DCMAKE_BUILD_TYPE=Release -DBUILD_SAMPLES=OFF .. && \
make gldc_tests"
# run on the emulator. -u enables dcload host-file syscalls and -C mounts the
# given directory as the dcload filesystem (KOS sees it as /pc), which is where
# the golden references are read from. The build copies goldens/ next to the
# .elf, so run from there:
cd dcbuild/tests
nitrocast -b -e gldc_tests.elf -u -C . -r 32
```
The allocator unit tests are desktop-only (they assert exact host heap
addresses); they are automatically excluded from the Dreamcast build.
### Running once on the Dreamcast
`InitGPU()`/`ShutdownGPU()` map to `pvr_init()`/`pvr_shutdown()`, which must not
be torn down and brought back up between tests. `GLTestCase` therefore opens the
PVR (and the display) lazily on the first test, registers an `atexit()` handler
to shut it down once at program exit, and only *resets* GL state between tests.
New GL-driving suites should derive from `GLTestCase`; if they need extra setup
they should override `set_up()` and call `GLTestCase::set_up()` first.
## What's covered
| File | Focus |
|------|-------|
| `test_glcolor.h` | `glColor*` / `glColorPointer` state |
| `test_glteximage2d.h` | basic internal-format selection |
| `test_pvr_vertex_submission.h`| TA poly-list structure & headers |
| `test_vertex_formats.h` | `glVertexPointer` types/sizes/strides, immediate mode, `glDrawElements` |
| `test_texcoord_formats.h` | `glTexCoordPointer` type scaling, immediate `glTexCoord` |
| `test_texture_formats.h` | byte-exact texture conversion (RGB565 / ARGB4444 / ARGB1555 / RGBA8 / RED / ALPHA / paletted), `glTexSubImage2D`, errors |
| `test_golden_rendering.h` | end-to-end rendered-output comparison |
The format/submission tests work by inspecting the internal state the driver
produces — the converted texture bytes (`TextureObject::data`) and the submitted
vertices in `OP_LIST` / `PT_LIST` / `TR_LIST` — so they are exact and
deterministic, and they pin down the per-type readers and pixel conversions
without needing a framebuffer.
## Golden-image tests
`tools/golden.h` contains a small, self-contained, deterministic CPU rasteriser.
It consumes the **same** TA poly-lists the real backend submits and reproduces
the backend's triangle-strip walk and perspective divide, then fills triangles
with Gouraud vertex colour (optionally modulated by a decoded texture). Output is
compared against committed PPM references in `tests/goldens/`.
Because the rasteriser lives in the test harness (not the library) it doesn't
move when the library changes, so a diff in the rendered output reliably points
at a regression in GLdc's transform / colour / clipping / submission pipeline.
The poly-lists are produced by the real (SH4-compiled) library, so the same
references are validated against actual Dreamcast output too — on the Dreamcast
the textured cases even sample the decoded texture straight out of PVR VRAM.
Comparison is tolerant (per-channel + mismatch-fraction thresholds) so sub-LSB
rounding never causes flakiness.
The references live in `tests/goldens/`. On the desktop they are read straight
from the source tree; on the Dreamcast they are read through the dcload mount at
`/pc/goldens` (the build copies them next to the `.elf`, so `-C .` from the
build directory exposes them).
### Adding or updating a golden
1. Write a test that draws something and calls
`golden::rasterize_all_lists(img)` then
`assert_true(golden::check(img, "my_scene"))`.
2. Generate (or refresh) the reference image (desktop):
```sh
GLDC_UPDATE_GOLDENS=1 SDL_VIDEODRIVER=dummy ./tests/gldc_tests GoldenRenderingTests
```
3. **Eyeball the new `tests/goldens/my_scene.ppm`** before committing it
(any image viewer / `convert ... png` works) and commit it alongside the test.
On a mismatch the harness writes `my_scene.actual.ppm` and `my_scene.diff.ppm`
(differing pixels highlighted red) next to the golden for inspection.
> Note: the video mode is 640×480 and the viewport y-flip is relative to that
> height, so golden scenes place the viewport at `(0, 480 - H)` to capture a
> W×H image at the top-left of the framebuffer.