-
-
Notifications
You must be signed in to change notification settings - Fork 37
Description
It seems that addresses passed to TEXUNIT0_ADDRX require some kind of ordering, otherwise certain faces do not get rendered correctly and become all glitchy:
Lowest to highest address seems to fix the problem. One could test this by manually setting each texunit address; however I tried to come up with a testcase that could trigger the bug "in the wild". The testcase is based on the cubemap example:
static bool loadTextureFromFile(C3D_Tex* tex, C3D_TexCube* cube, const char* path) {
FILE* f = fopen(path, "rb");
if (!f)
return false;
//
void* mema = vramAllocAt(256 * 256, VRAM_ALLOC_A);
if (!mema)
svcBreak(USERBREAK_PANIC);
if (!vramAllocAt(2 * 1024 * 1024 + 1024 * 512, VRAM_ALLOC_A))
svcBreak(USERBREAK_PANIC);
vramFree(mema);
if (!vramAllocAt(2 * 1024 * 1024 + 1024 * 512 - 256 * 128, VRAM_ALLOC_B))
svcBreak(USERBREAK_PANIC);
//
Tex3DS_Texture t3x = Tex3DS_TextureImportStdio(f, tex, cube, true /* false */);
fclose(f);
if (!t3x)
return false;
// Delete the t3x object since we don't need it
Tex3DS_TextureFree(t3x);
return true;
}The allocator stuff attempts to shape vram such that face 0 of the cubemap gets allocated near the end of bank B, while face 1 gets allocated near the start of bank A, thus causing a huge leap between addresses. I was able to trigger the bug on all my consoles with the testcase but I cannot guarantee it always work due to this being reliant on allocator behaviour.