diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index 6709032b5..62459aac2 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -338,17 +338,17 @@ static const PvrTexInfo *pvrTexInfo = opengl::pvrTexInfo; extern const u32 VQMipPoint[11] = { - 0x00000,//1 - 0x00001,//2 - 0x00002,//4 - 0x00006,//8 - 0x00016,//16 - 0x00056,//32 - 0x00156,//64 - 0x00556,//128 - 0x01556,//256 - 0x05556,//512 - 0x15556//1024 + VQ_CODEBOOK_SIZE + 0x00000, // 1 + VQ_CODEBOOK_SIZE + 0x00001, // 2 + VQ_CODEBOOK_SIZE + 0x00002, // 4 + VQ_CODEBOOK_SIZE + 0x00006, // 8 + VQ_CODEBOOK_SIZE + 0x00016, // 16 + VQ_CODEBOOK_SIZE + 0x00056, // 32 + VQ_CODEBOOK_SIZE + 0x00156, // 64 + VQ_CODEBOOK_SIZE + 0x00556, // 128 + VQ_CODEBOOK_SIZE + 0x01556, // 256 + VQ_CODEBOOK_SIZE + 0x05556, // 512 + VQ_CODEBOOK_SIZE + 0x15556 // 1024 }; extern const u32 OtherMipPoint[11] = { @@ -410,22 +410,22 @@ bool BaseTextureCacheData::NeedsUpdate() { void BaseTextureCacheData::protectVRam() { - u32 end = sa + size - 1; + u32 end = mmStartAddress + size - 1; if (end >= VRAM_SIZE) { WARN_LOG(PVR, "protectVRam: end >= VRAM_SIZE. Tried to lock area out of vram"); end = VRAM_SIZE - 1; } - if (sa_tex > end) + if (startAddress > end) { - WARN_LOG(PVR, "vramlock_Lock: sa_tex > end. Tried to lock negative block"); + WARN_LOG(PVR, "vramlock_Lock: startAddress > end. Tried to lock negative block"); return; } vram_block *block = new vram_block(); block->end = end; - block->start = sa_tex; + block->start = startAddress; block->texture = this; { @@ -482,8 +482,8 @@ BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw) //decode info from tsp/tcw into the texture struct tex = &pvrTexInfo[tcw.PixelFmt == PixelReserved ? Pixel1555 : tcw.PixelFmt]; //texture format table entry - sa_tex = (tcw.TexAddr << 3) & VRAM_MASK; //texture start address - sa = sa_tex; //data texture start address (modified for MIPs, as needed) + startAddress = (tcw.TexAddr << 3) & VRAM_MASK; // texture start address + mmStartAddress = startAddress; // data texture start address (modified for MIPs, as needed) width = 8 << tsp.TexU; //tex width height = 8 << tsp.TexV; //tex height @@ -534,16 +534,18 @@ BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw) { verify(tex->VQ != NULL || tex->VQ32 != NULL); if (tcw.MipMapped) - sa += VQMipPoint[tsp.TexU + 3]; + mmStartAddress += VQMipPoint[tsp.TexU + 3]; + else + mmStartAddress += VQ_CODEBOOK_SIZE; texconv = tex->VQ; texconv32 = tex->VQ32; - size = width * height / 8 + 256 * 8; + size = width * height / 4; } else { verify(tex->TW != NULL || tex->TW32 != NULL); if (tcw.MipMapped) - sa += OtherMipPoint[tsp.TexU + 3] * tex->bpp / 8; + mmStartAddress += OtherMipPoint[tsp.TexU + 3] * tex->bpp / 8; texconv = tex->TW; texconv32 = tex->TW32; size = width * height * tex->bpp / 8; @@ -556,14 +558,13 @@ void BaseTextureCacheData::ComputeHash() { // Include everything but texaddr, reserved and stride. Palette textures don't have ScanOrder const u32 tcwMask = IsPaletted() ? 0xF8000000 : 0xFC000000; - u32 hashSize = size; if (tcw.VQ_Comp) { // The size for VQ textures wasn't correctly calculated. // We use the old size to compute the hash for backward-compatibility // with existing custom texture packs. - hashSize = size - 256 * 8; - old_vqtexture_hash = XXH32(&vram[sa], hashSize, 7); + int oldSize = width * height / 8; + old_vqtexture_hash = XXH32(&vram[mmStartAddress - VQ_CODEBOOK_SIZE], oldSize, 7); if (IsPaletted()) old_vqtexture_hash ^= palette_hash; old_texture_hash = old_vqtexture_hash; @@ -572,9 +573,9 @@ void BaseTextureCacheData::ComputeHash() XXH32_state_t *state = XXH32_createState(); XXH32_reset(state, 7); // hash vq codebook - XXH32_update(state, &vram[sa_tex], 256 * 8); + XXH32_update(state, &vram[startAddress], VQ_CODEBOOK_SIZE); // hash texture - XXH32_update(state, &vram[sa + 256 * 8], hashSize); + XXH32_update(state, &vram[mmStartAddress], size); texture_hash = XXH32_digest(state); XXH32_freeState(state); if (IsPaletted()) @@ -584,7 +585,7 @@ void BaseTextureCacheData::ComputeHash() else { old_vqtexture_hash = 0; - texture_hash = XXH32(&vram[sa], hashSize, 7); + texture_hash = XXH32(&vram[mmStartAddress], size, 7); if (IsPaletted()) texture_hash ^= palette_hash; old_texture_hash = texture_hash; @@ -630,7 +631,7 @@ bool BaseTextureCacheData::Update() } if (tcw.VQ_Comp) - ::vq_codebook = &vram[sa_tex]; // might be used if VQ tex + ::vq_codebook = &vram[startAddress]; //texture conversion work u32 stride = width; @@ -643,19 +644,19 @@ bool BaseTextureCacheData::Update() } const u32 original_h = height; - if (sa_tex > VRAM_SIZE || sa + size > VRAM_SIZE) + if (startAddress > VRAM_SIZE || mmStartAddress + size > VRAM_SIZE) { height = 0; - if (sa < VRAM_SIZE && sa + size > VRAM_SIZE && tcw.ScanOrder) + if (mmStartAddress < VRAM_SIZE && mmStartAddress + size > VRAM_SIZE && tcw.ScanOrder) { // Shenmue Space Harrier mini-arcade loads a texture that goes beyond the end of VRAM // but only uses the top portion of it - height = (VRAM_SIZE - sa) * 8 / stride / tex->bpp; + height = (VRAM_SIZE - mmStartAddress) * 8 / stride / tex->bpp; size = stride * height * tex->bpp/8; } if (height == 0) { - WARN_LOG(RENDERER, "Warning: invalid texture. Address %08X %08X size %d", sa_tex, sa, size); + WARN_LOG(RENDERER, "Warning: invalid texture. Address %08X %08X size %d", startAddress, mmStartAddress, size); dirty = 1; height = original_h; unprotectVRam(); @@ -706,7 +707,7 @@ bool BaseTextureCacheData::Update() u32 vram_addr; if (tcw.VQ_Comp) { - vram_addr = sa_tex + VQMipPoint[i]; + vram_addr = startAddress + VQMipPoint[i]; if (i == 0) { PixelBuffer pb0; @@ -717,7 +718,7 @@ bool BaseTextureCacheData::Update() } } else - vram_addr = sa_tex + OtherMipPoint[i] * tex->bpp / 8; + vram_addr = startAddress + OtherMipPoint[i] * tex->bpp / 8; if (tcw.PixelFmt == PixelYUV && i == 0) // Special case for YUV at 1x1 LoD pvrTexInfo[Pixel565].TW32(&pb32, &vram[vram_addr], 1, 1); @@ -729,7 +730,7 @@ bool BaseTextureCacheData::Update() else { pb32.init(width, height); - texconv32(&pb32, (u8*)&vram[sa], stride, height); + texconv32(&pb32, (u8*)&vram[mmStartAddress], stride, height); // xBRZ scaling if (textureUpscaling) @@ -757,7 +758,7 @@ bool BaseTextureCacheData::Update() for (u32 i = 0; i <= tsp.TexU + 3u; i++) { pb8.set_mipmap(i); - u32 vram_addr = sa_tex + OtherMipPoint[i] * tex->bpp / 8; + u32 vram_addr = startAddress + OtherMipPoint[i] * tex->bpp / 8; texconv8(&pb8, &vram[vram_addr], 1 << i, 1 << i); } pb8.set_mipmap(0); @@ -765,7 +766,7 @@ bool BaseTextureCacheData::Update() else { pb8.init(width, height); - texconv8(&pb8, &vram[sa], stride, height); + texconv8(&pb8, &vram[mmStartAddress], stride, height); } temp_tex_buffer = pb8.data(); } @@ -780,7 +781,7 @@ bool BaseTextureCacheData::Update() u32 vram_addr; if (tcw.VQ_Comp) { - vram_addr = sa_tex + VQMipPoint[i]; + vram_addr = startAddress + VQMipPoint[i]; if (i == 0) { PixelBuffer pb0; @@ -791,7 +792,7 @@ bool BaseTextureCacheData::Update() } } else - vram_addr = sa_tex + OtherMipPoint[i] * tex->bpp / 8; + vram_addr = startAddress + OtherMipPoint[i] * tex->bpp / 8; texconv(&pb16, (u8*)&vram[vram_addr], 1 << i, 1 << i); } pb16.set_mipmap(0); @@ -799,7 +800,7 @@ bool BaseTextureCacheData::Update() else { pb16.init(width, height); - texconv(&pb16,(u8*)&vram[sa],stride,height); + texconv(&pb16,(u8*)&vram[mmStartAddress],stride,height); } temp_tex_buffer = pb16.data(); } diff --git a/core/rend/TexCache.h b/core/rend/TexCache.h index 62ebb8f10..f25ace56b 100644 --- a/core/rend/TexCache.h +++ b/core/rend/TexCache.h @@ -12,6 +12,7 @@ #include extern const u8 *vq_codebook; +constexpr int VQ_CODEBOOK_SIZE = 256 * 8; extern u32 palette_index; extern u32 palette16_ram[1024]; extern u32 palette32_ram[1024]; @@ -446,7 +447,6 @@ void texture_TW(PixelBuffer* pb, const u template void texture_VQ(PixelBuffer* pb, const u8* p_in, u32 Width, u32 Height) { - p_in += 256 * 4 * 2; // Skip VQ codebook pb->amove(0, 0); const u32 divider = PixelConvertor::xpp * PixelConvertor::ypp; @@ -578,10 +578,10 @@ public: tsp = other.tsp; tcw = other.tcw; tex_type = other.tex_type; - sa_tex = other.sa_tex; + startAddress = other.startAddress; dirty = other.dirty; std::swap(lock_block, other.lock_block); - sa = other.sa; + mmStartAddress = other.mmStartAddress; width = other.width; height = other.height; size = other.size; @@ -605,12 +605,12 @@ public: // Decoded/filtered texture format TextureType tex_type; - u32 sa_tex; // texture data start address in vram + u32 startAddress; // texture data start address in vram u32 dirty; // frame number at which texture was overwritten vram_block* lock_block; - u32 sa; // pixel data start address of max level mipmap + u32 mmStartAddress; // pixel data start address of max level mipmap u16 width, height; // width & height of the texture u32 size; // size in bytes of max level mipmap in vram diff --git a/core/rend/boxart/pvrparser.h b/core/rend/boxart/pvrparser.h index 04590a6fd..3cf699553 100644 --- a/core/rend/boxart/pvrparser.h +++ b/core/rend/boxart/pvrparser.h @@ -141,12 +141,12 @@ static bool pvrParse(const u8 *data, u32 len, u32& width, u32& height, std::vect p += (OtherMipPoint[texU] - 2) * 2; else if (imgType == PvrVQMipmaps) p += VQMipPoint[texU]; + else if (imgType == PvrVQ) + p += VQ_CODEBOOK_SIZE; u32 expectedSize = width * height; - if (imgType == PvrVQ || imgType == PvrVQMipmaps) { - expectedSize /= 4; // 4 pixels per byte - expectedSize += 256 * 4 * 2; // VQ codebook size - } + if (imgType == PvrVQ || imgType == PvrVQMipmaps) + expectedSize /= 4; // 4 pixels per byte else expectedSize *= 2; // 2 bytes per pixel if (end - p < expectedSize)