In the below code, a PVRTC_RGBA2 texture is created and set with data. But viewing this on device only shows whatever mip count is set, minus 4 mips. So putting in 7 for the mip count will result in 3 actual mips on device.
bool linear = false;
Texture2D brokenTexture = new Texture2D(256, 256, TextureFormat.PVRTC_RGBA2, mipCount, linear);
NativeArray<byte> rawTexData = brokenTexture.GetRawTextureData<byte>();
for (int i = 0; i < rawTexData.Length; i++)
{
rawTexData[i] = (byte)Random.Range(0, 255);
}
brokenTexture.Apply();
this is expected and is the artefact of the pvrtc spec (we might need to revisit this with metal, but bear with me)
if you look into the spec you would see that pvrtc is block format, with block size depending on the bitness. So, for example, pvrtc 2bpp has 8x4 blocks. But you need 4 blocks to decode texel (again, by spec), so essentially you can say that you need 16x8 texels to decode anything. And this is your answer: 1x1, 2x2, 4x4, 8x8 texel data does not make sense for pvrtc - it cannot unpack anything.
Obviously this is not the whole story: you might argue that somehow dxt goes all the way down to 1x1 mip. And you will be right - this is kinda the artefact of (apple impl of) GLES + pvrtc, as in - on OpenGL ES it was explicitly forbidden by GL to create smaller mips with pvrtc. So i guess we should revisit this with metal (maybe it is possible now). On the other hand - kinda “meh whatever”, as there is no actual issue with dropping lower mip levels
I can certainly understand that, and I had counted on that already (although forgot about the decoding, was planning on having lowest as 8x8 block, but yes I see now), but the main issue for me is the unexpected handling of mips. I would expect that it would discard mips lower than some texture size, but instead it discards just the lowest 4. Which doesn’t make any sense to me. It leads to having to make special cases in code for things like this, whereas instead it could just decide to give an error when creating the texture that there are too many mips, or even just create the texture with less mips.
Instead it gives no error, says it is using the number of mips it was told it to, then the GPU doesn’t line up with what the texture is saying.
I would expect that it would discard mips lower than some texture size, but instead it discards just the lowest 4
Ah i see what you mean. Indeed in your case i see mips stopping at 64x64, which indeed sounds weird. Will check, no worries