[rlsw][SEGFAULT] Fix triangle and quad spans applying pixels out of bounds#5849
[rlsw][SEGFAULT] Fix triangle and quad spans applying pixels out of bounds#5849NighthowlerStudios wants to merge 5 commits intoraysan5:masterfrom
Conversation
|
Thanks for retesting on the RPi 2 + 5. Clipping interpolants by int yLoopMax = sw_clamp_int(yMax, 0, RLSW.colorBuffer->height - 1);
int xLoopMax = sw_clamp_int(xMax, 0, RLSW.colorBuffer->width - 1);
// ...
for (int y = yLoopMin; y < yLoopMax; y++) { ... }
for (int x = xLoopMin; x < xLoopMax; x++) { ... }
int yLoopMax = sw_clamp_int(yMax, 0, RLSW.colorBuffer->height); // not height-1
int xLoopMax = sw_clamp_int(xMax, 0, RLSW.colorBuffer->width); // not width-1Inclusive lower ( Second concern — the per-row interpolant compensation in for (int y = yLoopMin; y < yLoopMax; y++) {
...
float z = zRow + dZdy*dyMin;
float u = uRow + dUdy*dyMin;
float v = vRow + dVdy*dyMin;If Once those two are sorted, the structure is good. RPi 2 retest after fixing the upper clamp will tell you immediately whether the bottom row was missing. |
|
@Bigfoot71 please, could you take a look to this PR when possible? No hurries. |
Great catch! My bad. That makes sense because of the < check. After some research I can agree that a -1 on LoopStart is still safe because these raster routines are reached after culling of triangles entirely outside anyway. Our issue is only with triangles overlapping the border.
Yes, and I believe that I've discovered that those row vars don't just denote the start of the row, but actually behave as 2-dimensional "cursors" (or turtles) for the interpolation. At the end of the for loop, they get incremented by So we need bilinear interpolation offsets. Instead of just moving them across the X, we need to move them across both X and Y for the correct start position. And yes, only do it once, outside of the loop. The incrementor for X gets put into a separate variable and the for loop controls how far that will sweep to the right and bottom anyway, and the incrementor at the end of the for loop adding a Y step (just adding row) would keep the x offset, so it's safe to do this only once. This has to be in, because the for loop is just iterating, so yStart wouldn't have affected where interpolation started. Tested our changes on both RPI2 and RPI5. |
|
Yes, by fixing the off by one, a single pixel wide bar of pixels on the right hand and bottom end of the screen is now being filled by colour information correctly. The first commit in the PR had them white only, which was definitely something I should have spotted. Bunnymark shows no issues with colour information after the movement of interpolation starts on raster_quad. Maybe there's a better example I could look toward that could reliably produce artifacts if our code is wrong here? |
Fixes #5838
The code in this commit and text in this PR are entirely human written.
It has been tested on a Raspberry Pi 2, the same board the original issue was found on.
Then it was tested on a Raspberry Pi 5 to verify texture and triangle warping wasn't present, using
models_first_person_mazeFixes RLSW Rastering buffer boundary out of bounds
In the raster routine
SW_RASTER_QUAD, there was the following problem spotted by @ZX41RAdditionally, in
TRIANGLE_SPAN, the issue is much simpler. It only has anxMinthat calculates intobaseOffset, there is noyMininvolved on that method. However it is the same boundary crossing bug.This commit applies some fixes they suggested by ensuring to clamp the loop min and max to inside of
RLSW.colorBuffer.Then it moves the start of each interpolation for spans, textures, depths and vertex colours, to compensate for the new clamps so that only the correct colours are grabbed.
This fixes the segfault discovered on the issue and avoids the triangle warping that was previously discussed in the deleted fork on #5843
It should be much safer than the previous PR I self-rejected.