-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for BC1 encode errors with random colors in constant blocks #3
Comments
Note, this doesn't quite satisfy me as the solution, since the blocks shift around the image, and the blocks were on a grayscale image, so that bottom channel is never zero. I still think the selectors are reversed, but I don't quite understand the logic above on a constant block for why min16 and max aren't always the same color. There's a mask in there of 0xAA interpolation b10 x4, then 0x55 and 0x00 are the min/max. Might be better for RDO to always use the 0 selector, and munge the max16 value. |
Hi, Example: J:\dev\bc7enc-master\Release>bc7enc -c -1 J:\dev\test_images\Toof-a.png -o |
This was compiled with VS 2019, x64 build. |
I have only seen it out of kram on macOS-Intel. I haven't tried with the bc7enc command line tool. Just see if the logic above seems better I guess for now. Again, I have "3 color mode" disabled, but your output indicates it's enabled. |
I disabled 3 color mode in that test, using -c: I tried with and without -c. AMD Compressonator also decompresses the generated .DDS file OK. I also single stepped through the code, and it appears to be working as designed. This is a tricky code path though, so perhaps there is a bug - how are you decompressing the block's data to 32-bit RGBA texels? When min16==max16:
The check for "if (max16 < min16)" should never occur, so the mask will always be either 0 or 0x55. |
Here are the generated files, including the .DDS file: |
I decompress with BC7enc's decoder as well. So they should both line up. For some reason, with and without the change, I'm not seeing the artifacts right now, or I'd send you them. But I though selector b00 was min, and b01 was max, and those values looked flipped. Sorry, not trying to waste your time, but this was more obvious in my earlier tests. Ugh, okay I assumed color0 was min, and color1 was max. That makes sense then. I don't actually decode BC format on macOS-Intel, since it's a supported format. So in this case, it would have all been in the encode/mip logic of kram, but I didn't see the incorrect blocks with my other BC encoders and same mip logic (squish and ate). These were purple and green blocks that appeared in random spots on that mostly grayscale image. I should have screen captured it at the time. And they continued in long horizontal stripes, so the next block over would be less pink, until it went back to the grayscale like a gradient ramp. |
Just to be sure, I compiled & ran under ubuntu 18 using clang, and the generated file is OK. If you can repo the bug with the bc7enc tool, then I can reproduce it here. (Don't worry about the report, even if it's a false alarm - I appreciate it!) |
Also don't use that PVRTexToolGUI version, it doesn't display or import srgb and colors correctly. Even the new one doesn't, but it has a nicer UI. The one on macOS doesn't decode BC4-7, so it's not as useful to me. |
So now I'm seeing this with the bc7 encode. I have that same image that is all opaque, but many of the blocks are turned into mode 6 blocks. These blocks are wasting 2x7 bits encoding alpha, since my version of bc7enc doesn't support mode 3 or rgb-only blocks I guess. When this occurs, the blocks decode as 254 alpha in my compute sampler that just point samples from the bc7 texture. I decoded the A0/A1 chunks and they're 127, but not sure how bc7 converts that to a 255 alpha or 254 alpha. I know all the incoming source data is 255 since I can see it in the debugger. It's the same image as above (Toof-a.png). I just got KTX2 into kram (no UASTC yet), and the debug modes are flagging all blocks as transparent (a = 254) on opaque images. My shaders take slower paths on non-opaques, so I want to make sure the images stay fully opaque. astc-enc and etc2comp are preserving the alpha, but I need to look into a gray -> color change in etc2comp blocks. It's block 8,1 in the image (counting from 0). These are the gray values for the 4x4 block. The alpha are all 255. I see it take the opaque block encode path in the bc7 path. Just sharing this, in case you have time to track it down faster than I. I don't have any bc7 block printing calls, so I'll have to build those up. This might also be a good test case for the BC1 issue above, but I'll need to test that again. 251, 251, 251, 252, This is in bc7decomp I get correct bc7 alpha from ATE (apple tex encoder), but it may use the mode 3 blocks. |
If it's at all helpful, here are the ATE version and the bc7enc encoded version. I can't see the block modes across the blocks in my tools yet. The ATE bc7 is fully opaque across all mips. The bc7enc version is non-opaque when I look at all mip levels and it gets worse even one mip level down, with alpha going to 248 and lower. |
So even when I run bc7decomp on that block immediately afterwards, the Alpha is FE (254). So there's seems to be something amiss with using Alpha blocks in BC7 to encode opaque pixels. [0] = FEFBFBFB FEFBFBFB FEFBFBFB FEFCFCFC I could see where alpha = 255 if the p0 and p1 bit was set, but they are both 0, but I assume that's limiting. It looks like ATE is also using a mode6 block, but setting both p0/p1 to 1, so then the reconstruct generates 255. |
Just to follow up, I was able to fix the alpha pulldown across the mips. It was a problem in my non-pow2 mipgen where weights needed to be renormalized and I needed some rounding/snapping to 8-bits. So now it's just constant blocks across the mip chain that are 254 when those pbits are 0 on the mode 6 blocks, but that's at the encode level. |
This is one hacky fix inside find_optimal_solution() for this specific case. This always picks pbits of 1 if no alpha. May need to be specific to mode6 if rgb modes added later.
|
Ok- I don't view this as a bug exactly, but I understand why you do. The encoder is trying to optimize for lowest overall error, and it chooses the p-bits that do this, independent of alpha. (Because to the encoder, alpha is just another channel - I can't assume it means transparency.) However, I can add a mode or feature that does what you want, because it's clearly important. Thanks for bringing this up! Also the latest version of the encoder lives here: |
In bc7enc a flag to distinguish whether the mode supports alpha, and the existing one for whether the block does might help here. RGB1 style mode 3 would have full p-bits choice. But mode 6 using a transparent mode for a fully opaque texture would limit the p-bits choice to 11 And yeah, I'm a bit far back on bc7enc and astcencoder. Will make an update when I get a chance. |
This is the maintained codebase. Still has bug with all alpha = 255 mapped to 254. Will put in patch for that next. richgel999/bc7enc#3
This is the maintained codebase. Still has bug with all alpha = 255 mapped to 254. Will put in patch for that next. richgel999/bc7enc#3
In kramv, I kept seeing BC1 errors with a texture that I've linked to. It's a color texture with mostly grayscale in it. And green, yellow, and purple blocks would appear in the image where there were none originally. With the block view, I could tell these were erroneous constant blocks.
I think I might have found the issue. By decrementing the min16--, if the last color value is 0, then the entire color rolls over and can set high red or blue colors to high values. That's fine provided that color isn't the one picked from the selectors, but the selectors look like they're reversed and picking the modified color (or the non-zero color). I also added some 'else' statements, and consolidated the flow is a little clearer.
I didn't yet check the other encoders to see if this same logic was repeated.
https://github.com/alecazam/kram/blob/main/tests/src/Toof-a.png
kram encode -v -f bc1 -srgb -i ~/kram/tests/src/Toof-a.png -o ~/kram/tests/out/mac/Toof-fixbc1-a.ktx
The text was updated successfully, but these errors were encountered: