u64 TextureCacheBase::TCacheEntryBase::CalculateHash() const { u8* ptr = Memory::GetPointer(addr); if (memory_stride == BytesPerRow()) { return GetHash64(ptr, size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples); } else { u32 blocks = NumBlocksY(); u64 temp_hash = size_in_bytes; u32 samples_per_row = 0; if (g_ActiveConfig.iSafeTextureCache_ColorSamples != 0) { // Hash at least 4 samples per row to avoid hashing in a bad pattern, like just on the left side of the efb copy samples_per_row = std::max(g_ActiveConfig.iSafeTextureCache_ColorSamples / blocks, 4u); } for (u32 i = 0; i < blocks; i++) { // Multiply by a prime number to mix the hash up a bit. This prevents identical blocks from canceling each other out temp_hash = (temp_hash * 397) ^ GetHash64(ptr, BytesPerRow(), samples_per_row); ptr += memory_stride; } return temp_hash; } }
void TextureCacheBase::TCacheEntryBase::SetEfbCopy(u32 stride) { is_efb_copy = true; memory_stride = stride; _assert_msg_(VIDEO, memory_stride >= BytesPerRow(), "Memory stride is too small"); size_in_bytes = memory_stride * NumBlocksY(); }
/// Downsampler::Downsample void Downsampler::Downsample(UBYTE **&data,class ImageLayout *src) { UWORD i; // Delete the old image components. Does not release the // memory we hold. delete[] m_pComponent; m_pComponent = NULL; ReleaseComponents(data); // if (m_bChromaOnly) { m_ulWidth = src->WidthOf(); m_ulHeight = src->HeightOf(); } else { m_ulWidth = (src->WidthOf() + m_ucScaleX - 1) / m_ucScaleX; m_ulHeight = (src->HeightOf() + m_ucScaleY - 1) / m_ucScaleY; } // m_usDepth = src->DepthOf(); m_pComponent = new struct ComponentLayout[m_usDepth]; // // Initialize component dimensions. for(i = 0; i < m_usDepth; i++) { if (m_bChromaOnly == false || i > 0) { m_pComponent[i].m_ulWidth = (src->WidthOf(i) + m_ucScaleX - 1) / m_ucScaleX; m_pComponent[i].m_ulHeight = (src->HeightOf(i) + m_ucScaleY - 1) / m_ucScaleY; } else { m_pComponent[i].m_ulWidth = src->WidthOf(i); m_pComponent[i].m_ulHeight = src->HeightOf(i); } m_pComponent[i].m_ucBits = src->BitsOf(i); m_pComponent[i].m_bSigned = src->isSigned(i); m_pComponent[i].m_bFloat = src->isFloat(i); if (m_bChromaOnly && i > 0) { m_pComponent[i].m_ucSubX = src->SubXOf(i) * m_ucScaleX; m_pComponent[i].m_ucSubY = src->SubYOf(i) * m_ucScaleY; } else { m_pComponent[i].m_ucSubX = src->SubXOf(i); m_pComponent[i].m_ucSubY = src->SubYOf(i); } } // data = new UBYTE *[m_usDepth]; memset(data,0,sizeof(UBYTE *) * m_usDepth); // for(i = 0;i < m_usDepth;i++) { UBYTE bps = (m_pComponent[i].m_ucBits + 7) >> 3; if (m_pComponent[i].m_bFloat && m_pComponent[i].m_ucBits == 16) bps = sizeof(FLOAT); // stored as float // data[i] = new UBYTE[m_pComponent[i].m_ulWidth * m_pComponent[i].m_ulHeight * bps]; m_pComponent[i].m_ulBytesPerPixel = bps; m_pComponent[i].m_ulBytesPerRow = bps * m_pComponent[i].m_ulWidth; m_pComponent[i].m_pPtr = data[i]; } // for(i = 0;i < m_usDepth;i++) { UBYTE sx,sy; // if (m_bChromaOnly == false || i > 0) { sx = m_ucScaleX; sy = m_ucScaleY; } else { sx = 1; sy = 1; } // if (isSigned(i)) { if (BitsOf(i) <= 8) { BoxFilter<BYTE>((BYTE *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (BYTE *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), BYTE(-1UL << (BitsOf(i) - 1)),BYTE((1UL << (BitsOf(i) - 1)) - 1), sx,sy); } else if (!isFloat(i) && BitsOf(i) <= 16) { BoxFilter<WORD>((WORD *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (WORD *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), WORD(-1UL << (BitsOf(i) - 1)),WORD((1UL << (BitsOf(i) - 1)) - 1), sx,sy); } else if (!isFloat(i) && BitsOf(i) <= 32) { BoxFilter<LONG>((LONG *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (LONG *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), LONG(-1UL << (BitsOf(i) - 1)),LONG((1UL << (BitsOf(i) - 1)) - 1), sx,sy); } else if (isFloat(i) && BitsOf(i) <= 32) { BoxFilter<FLOAT>((FLOAT *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (FLOAT *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), -HUGE_VAL,HUGE_VAL, sx,sy); } else if (isFloat(i) && BitsOf(i) == 64) { BoxFilter<DOUBLE>((DOUBLE *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (DOUBLE *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), -HUGE_VAL,HUGE_VAL, sx,sy); } else { throw "unsupported data type"; } } else { if (BitsOf(i) <= 8) { BoxFilter<UBYTE>((UBYTE *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (UBYTE *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), 0,UBYTE((1UL << BitsOf(i)) - 1), sx,sy); } else if (!isFloat(i) && BitsOf(i) <= 16) { BoxFilter<UWORD>((UWORD *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (UWORD *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), 0,UWORD((1UL << BitsOf(i)) - 1), sx,sy); } else if (!isFloat(i) && BitsOf(i) <= 32) { BoxFilter<ULONG>((ULONG *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (ULONG *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), 0,LONG((1UL << BitsOf(i)) - 1), sx,sy); } else if (isFloat(i) && BitsOf(i) <= 32) { BoxFilter<FLOAT>((FLOAT *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (FLOAT *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), 0.0,HUGE_VAL, sx,sy); } else if (isFloat(i) && BitsOf(i) == 64) { BoxFilter<DOUBLE>((DOUBLE *)src->DataOf(i),src->BytesPerPixel(i),src->BytesPerRow(i), (DOUBLE *)DataOf(i),BytesPerPixel(i),BytesPerRow(i), src->WidthOf(i),src->HeightOf(i), 0.0,HUGE_VAL, sx,sy); } else { throw "unsupported data type"; } } } // Swap(*src); }