YUV2 Fallback Broken?
Posted: Wed Dec 30, 2020 1:45 pm
I am running a cli only linux build of snes9x 1.60 (the unix folder). I have tested on two machines and can provide screenshots if absolutely needed. Without the -xvideo argument everything is fine, with the exception that fullscreen does not scale, but I don't think it ever has. With the -xvideo argument colors are really off. When I built and tested snes9x 1.55 one machine (x11-intel-i915) looked great, but the other (x11-openchrome) looked different, than 1.60, but still bad.
The difference between 1.60 and 1.55 causing 1.55 to work on the i915 machine, is the use of rbg555 for 24 bit linux displays.
The i915 has an okay amount of x11 visuals (pixel formats) to pick from. And it finds one and does not have to fall back on the last resort Yuv2 conversion. The change to rgb565 leaves the i915 without a good match and it then fallsback to yuv2.
The openchrome machine falls back with both versions.
Before I understood the code better, I thought that the issue was the change over to rgb565, but the yuv2 conversion still being setup for rgb555. But I doubt that is the case.
I have some notes, but they may not help.
First, I have found why the broken output between 1.55 and 1.60 did not match. The shift operator for blue is reversed after 1.55.
x11.cpp line 635 -> b = (color & 0x001F) >> 3; <- if you switch it back to left shift, the outputs match again. It is my opinion that it should remain left shift. But perhaps this only looks better because something else is broken, and once fixed maybe the right shift would be correct.
As I said before, I had originally thought the issue was that the Yuv2 conversion was still working with rgb555, even though the rest of the x11 is working with rgb565. But I don't think these really interact with each other. Seems to me that the Yuv2 is isolated to its own conversion. But I did try changing it to rgb565 and the result was better, but still incorrect.
r = (color & 0xF800) >> 7;
g = (color & 0x07E0) >> 3;
b = (color & 0x001F) << 3;
The last thing I noticed, is that moving layers seem to not blend well. Game play is fine. But during intros and the like, a still frame with another frame moving across the other lookes painfully unblended. This goes away if you use the -notransparency argument. The odd thing here is that in the untouched (other than the shift operator) 1.60 code, with no transparency you just get the still layer. With the 1.60 code using the yuv2 rgb565 conversion I modified it with, you then lose the still layer and only have the moving one.
The rom I tested with is Castlevania Dracula X. It is a good one because it starts off with the "Konami" logo, which has a white background. That way you can see if your color is white balanced or not. If you let the game load and do nothing, an intro will play and show the layer issue.
It is kind of a pain to upload images, but it would be my guess that this could be reproduced on any Linux machine, if you modify x11 to force useage of the fallback Yuv2 conversion. But if this is not the case, I can provide screenshots and test patches. The issue could be between snes9x and Slackware 14.2, which is used on both machines.
The difference between 1.60 and 1.55 causing 1.55 to work on the i915 machine, is the use of rbg555 for 24 bit linux displays.
The i915 has an okay amount of x11 visuals (pixel formats) to pick from. And it finds one and does not have to fall back on the last resort Yuv2 conversion. The change to rgb565 leaves the i915 without a good match and it then fallsback to yuv2.
The openchrome machine falls back with both versions.
Before I understood the code better, I thought that the issue was the change over to rgb565, but the yuv2 conversion still being setup for rgb555. But I doubt that is the case.
I have some notes, but they may not help.
First, I have found why the broken output between 1.55 and 1.60 did not match. The shift operator for blue is reversed after 1.55.
x11.cpp line 635 -> b = (color & 0x001F) >> 3; <- if you switch it back to left shift, the outputs match again. It is my opinion that it should remain left shift. But perhaps this only looks better because something else is broken, and once fixed maybe the right shift would be correct.
As I said before, I had originally thought the issue was that the Yuv2 conversion was still working with rgb555, even though the rest of the x11 is working with rgb565. But I don't think these really interact with each other. Seems to me that the Yuv2 is isolated to its own conversion. But I did try changing it to rgb565 and the result was better, but still incorrect.
r = (color & 0xF800) >> 7;
g = (color & 0x07E0) >> 3;
b = (color & 0x001F) << 3;
The last thing I noticed, is that moving layers seem to not blend well. Game play is fine. But during intros and the like, a still frame with another frame moving across the other lookes painfully unblended. This goes away if you use the -notransparency argument. The odd thing here is that in the untouched (other than the shift operator) 1.60 code, with no transparency you just get the still layer. With the 1.60 code using the yuv2 rgb565 conversion I modified it with, you then lose the still layer and only have the moving one.
The rom I tested with is Castlevania Dracula X. It is a good one because it starts off with the "Konami" logo, which has a white background. That way you can see if your color is white balanced or not. If you let the game load and do nothing, an intro will play and show the layer issue.
It is kind of a pain to upload images, but it would be my guess that this could be reproduced on any Linux machine, if you modify x11 to force useage of the fallback Yuv2 conversion. But if this is not the case, I can provide screenshots and test patches. The issue could be between snes9x and Slackware 14.2, which is used on both machines.