Skip to content

Add CpuSurfaceUploadFilter test to ImageBlit suite to explicitly test linear filter pipeline#306

Open
stianeklund wants to merge 1 commit into
abaire:mainfrom
stianeklund:add-cpu-surface-upload-filter-test
Open

Add CpuSurfaceUploadFilter test to ImageBlit suite to explicitly test linear filter pipeline#306
stianeklund wants to merge 1 commit into
abaire:mainfrom
stianeklund:add-cpu-surface-upload-filter-test

Conversation

@stianeklund

@stianeklund stianeklund commented May 24, 2026

Copy link
Copy Markdown

Add CpuSurfaceUploadFilter test to ImageBlit suite

Tests the round-trip fidelity of CPU-written surface data through xemu's internal scale path.

Specifically this targets the bug which is fixed in xemu-project/xemu#2874, where pgraph_vk_upload_surface_data used the linear filter instead of nearest causing blurred visuals when upscaling CPU-written surfaces to the internal GPU resolution.

The test writes 1-pixel-wide alternating red/blue vertical stripes directly to the framebuffer via CPU, then issues a minimal GPU draw to trigger the surface upload. Reading the framebuffer back via CPU then triggers the download path. With Vulkan as the renderer and 1x (no upscale) the round-trip should be pixel-exact.

This test will fail with current xemu 0.8.135 with the Vulkan renderer with an upscale >= 2x (but passes with the fixes mentioned above).

Resulting pass for PR branch mentioned earlier:
xemu-2026-05-24-18-37-44

Current xemu 0.8.135:

xemu-2026-05-24-18-38-25

Just for posterity, I ran this on real hardware, too (it should pass), this is through a HDMI converter -> HDMI capture device so it's already upscaling a bit:
Screenshot 2026-05-24 19-10-33

Please let me know if you want any changes, I am really over my head with this already so I do want to emphasize that I actually know very little about this stuff, but I'm willing to learn.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new test case, CpuSurfaceUploadFilter, to the image blit test suite. The test verifies that CPU-written data uploaded to the GPU and then read back maintains pixel purity (using NEAREST filtering) rather than being blended (LINEAR filtering), specifically targeting issues with internal surface upload scaling. I have no feedback to provide.

Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
static constexpr char kOverlapFIFOTest[] = "OverlapFIFO";
#endif
static constexpr char kBlitPastWidthTest[] = "BlitBeyondWidth";
static constexpr char kCpuSurfaceUploadFilterTest[] = "CpuSurfaceUploadFilter";

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename this to XemuScaledSurfaceUploadFilter since the test is specific to xemu's extension of Xbox behavior and requires render scaling to be enabled. We'll also need to make some changes to the test harness to facilitate this; currently we only run tests at 1x.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good input, done. I'm curious what would be necessary to achieve this though? Is there any guest side control of render scale in xemu? I guess you could in theory use two separate configs or separate CI jobs..? (assuming the config exposes the render scale setting). I do think that's a bit outside of scope of this PR though but I do see the value in having perhaps a xemu-specific test harness for sure.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, it's entirely outside of the scope of this change.

https://github.com/abaire/nxdk-pgraph-test-runner and the CI scripts for https://github.com/abaire/xemu-nxdk_pgraph_tests_results and https://github.com/abaire/xemu-dev_pgraph_test_results will need to be updated to produce a config with >1x render scale, likely along with a test set filtered to contain just this test initially.

We may want to update this repo to make it easier to enumerate all tests along with some metadata so we can tag tests that have xemu-specific requirements alongside the test; it'd be difficult to discover this cross-repo requirement otherwise.

Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
Comment thread src/tests/image_blit_tests.cpp Outdated
@abaire

abaire commented May 25, 2026

Copy link
Copy Markdown
Owner

Thanks!

FYI - the tests already save the framebuffer to the HDD for you, so you should be able to run this on HW and retrieve results without going through any HDMI/etc... encoding.

@stianeklund stianeklund force-pushed the add-cpu-surface-upload-filter-test branch from 86475d2 to b23553e Compare May 25, 2026 14:55
@stianeklund

Copy link
Copy Markdown
Author

@abaire thanks for the review. I've addressed your comments. I checked the HDD but I can't actually see any saved output, does it save attempt to save to D:\ if run from that partition?

@stianeklund stianeklund requested a review from abaire May 25, 2026 15:11
@abaire

abaire commented May 26, 2026

Copy link
Copy Markdown
Owner

@abaire thanks for the review. I've addressed your comments. I checked the HDD but I can't actually see any saved output, does it save attempt to save to D:\ if run from that partition?

DEFAULT_OUTPUT_DIRECTORY_PATH
if you haven't overridden it, E:\nxdk_pgraph_tests\

@abaire

abaire commented May 26, 2026

Copy link
Copy Markdown
Owner

Looks like clang-format needs to be run; you can also set up the pre-commit hook in githooks to do this automatically on commit.

If you've already run it and it's still different, let me know. Unfortunately clang-format isn't versioned so it's possible that your local version and the CI version are out of sync.

Writes 1-pixel-wide alternating R/B vertical stripes to the framebuffer
via CPU, then issues a GPU draw to trigger xemu's internal surface upload
(pgraph_vk_upload_surface_data). The framebuffer is then read back via
CPU, which triggers xemu's download path.

At scale > 1x, NEAREST+NEAREST round-trips to exact per-channel values,
while any other filtering produces blended intermediate values detectable
with a channel-purity check. At scale == 1x no upscale path is exercised
and the test passes trivially.
@stianeklund stianeklund force-pushed the add-cpu-surface-upload-filter-test branch from b23553e to 8562c2c Compare May 26, 2026 06:41
@stianeklund

Copy link
Copy Markdown
Author

Please do not merge this until the respective PR in xemu is merged I think (if it will be) otherwise I'm not sure I see the value in it, unless you're OK with it explicitly failing.

@abaire

abaire commented May 26, 2026

Copy link
Copy Markdown
Owner

Sounds good, I'll keep an eye on your xemu PR; I agree with your perspective that it doesn't make sense to add a xemu-specific test for something that may be considered by-design behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants