Skip to content

Conversation

@CyCle1024
Copy link

Motivation

deko3d/source/dk_device.h

Lines 100 to 102 in 8cb7b4c

// Rasterizer expects clip space +Y to point down. In UpperLeft mode with Y pointing up
// (or LowerLeft mode with Y pointing down) we need to flip the incoming Y coordinate.
bool viewportFlipY() const noexcept { return !isYAxisPointsDown() ^ !isOriginLowerLeft(); }

The implementation is not consistent with the comment. We intend to flip Y when UpperLeft mode with Y pointing up. But in this case, !isYAxisPointsDown() = true and !isOriginLowerLeft() = true, true ^ true = false. Same as LowerLeft mode with Y pointing down.

Key Change

The fix is simple, I think the comment is the correct logic, so just add a ! before return.

@fincs
Copy link
Member

fincs commented Jan 27, 2026

Thank you for identifying and providing a fix. I only have two concerns:

  • Have you tested all combinations of DkDeviceFlags_Origin{Upper/Lower}Left/YAxisPoints{Up/Down} to make sure they work as intended?
  • Can you simplify the expression using logic laws? For example, NOT (a XOR b) == a XOR NOT b == NOT a XOR b.

@CyCle1024
Copy link
Author

CyCle1024 commented Jan 27, 2026

  • Have you tested all combinations of DkDeviceFlags_Origin{Upper/Lower}Left/YAxisPoints{Up/Down} to make sure they work as intended?

Sorry, I don't have much test that cover all the case, I only test on the case of OriginUpperLeft and YAxisPointsDown which is the default case, with a project called Melonds on switch. I fix the rendering problem with source code compiled deko3d.

  • Can you simplify the expression using logic laws? For example, NOT (a XOR b) == a XOR NOT b == NOT a XOR b.

I can simplify it, but the reason I fix it in this way is for readability, since isYAxisPointsDown()=true and isOriginLowerLeft()=true is a pair of case that we should flip. Since it confuses you, I think I should change it.

@CyCle1024
Copy link
Author

Here is logic table:

isYAxisPointsDown isOriginLowerLeft !isOriginLowerLeft XOR Result viewportFlipY() Description
false (0) true (1) false (0) 0 ^ 0 = 0 false Y-axis up, origin at lower-left
false (0) false (0) true (1) 0 ^ 1 = 1 true Y-axis up, origin at upper-left
true (1) true (1) false (0) 1 ^ 0 = 1 true Y-axis down, origin at lower-left
true (1) false (0) true (1) 1 ^ 1 = 0 false Y-axis down, origin at upper-left

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