/*!*************************************************************************** @Function PVRTTextureTile @Modified pOut The tiled texture in system memory @Input pIn The source texture @Input nRepeatCnt Number of times to repeat the source texture @Description Allocates and fills, in system memory, a texture large enough to repeat the source texture specified number of times. *****************************************************************************/ void PVRTTextureTile( PVRTextureHeaderV3 **pOut, const PVRTextureHeaderV3 * const pIn, const int nRepeatCnt) { unsigned int nFormat = 0, nType = 0, nBPP, nSize, nElW = 0, nElH = 0, nElD = 0; PVRTuint8 *pMmSrc, *pMmDst; unsigned int nLevel; PVRTextureHeaderV3 *psTexHeaderNew; _ASSERT(pIn->u32Width); _ASSERT(pIn->u32Width == pIn->u32Height); _ASSERT(nRepeatCnt > 1); PVRTGetOGLES3TextureFormat(*pIn,nFormat,nFormat,nType); PVRTGetFormatMinDims(pIn->u64PixelFormat,nElW,nElH,nElD); nBPP = PVRTGetBitsPerPixel(pIn->u64PixelFormat); nSize = pIn->u32Width * nRepeatCnt; psTexHeaderNew = PVRTTextureCreate(nSize, nSize, nElW, nElH, nBPP, true); *psTexHeaderNew = *pIn; pMmDst = (PVRTuint8*)psTexHeaderNew + sizeof(*psTexHeaderNew); pMmSrc = (PVRTuint8*)pIn + sizeof(*pIn); for(nLevel = 0; ((unsigned int)1 << nLevel) < nSize; ++nLevel) { int nBlocksDstW = PVRT_MAX((unsigned int)1, (nSize >> nLevel) / nElW); int nBlocksDstH = PVRT_MAX((unsigned int)1, (nSize >> nLevel) / nElH); int nBlocksSrcW = PVRT_MAX((unsigned int)1, (pIn->u32Width >> nLevel) / nElW); int nBlocksSrcH = PVRT_MAX((unsigned int)1, (pIn->u32Height >> nLevel) / nElH); int nBlocksS = nBPP * nElW * nElH / 8; PVRTTextureLoadTiled( pMmDst, nBlocksDstW, nBlocksDstH, pMmSrc, nBlocksSrcW, nBlocksSrcH, nBlocksS, (pIn->u64PixelFormat>=ePVRTPF_PVRTCI_2bpp_RGB && pIn->u64PixelFormat<=ePVRTPF_PVRTCI_4bpp_RGBA) ? true : false); pMmDst += nBlocksDstW * nBlocksDstH * nBlocksS; pMmSrc += nBlocksSrcW * nBlocksSrcH * nBlocksS; } psTexHeaderNew->u32Width = nSize; psTexHeaderNew->u32Height = nSize; psTexHeaderNew->u32MIPMapCount = nLevel+1; *pOut = psTexHeaderNew; }
/*!*********************************************************************** @Function PVRTGetTextureDataSize @Input iMipLevel Specifies a mip level to check, 'PVRTEX_ALLMIPLEVELS' can be passed to get the size of all MIP levels. @Input bAllSurfs Size of all surfaces is calculated if true, only a single surface if false. @Input bAllFaces Size of all faces is calculated if true, only a single face if false. @Return PVRTuint32 Size in BYTES of the specified texture area. @Description Gets the size in BYTES of the texture, given various input parameters. User can retrieve the size of either all surfaces or a single surface, all faces or a single face and all MIP-Maps or a single specified MIP level. *************************************************************************/ PVRTuint32 PVRTGetTextureDataSize(PVRTextureHeaderV3 sTextureHeader, PVRTint32 iMipLevel, bool bAllSurfaces, bool bAllFaces) { //The smallest divisible sizes for a pixel format PVRTuint32 uiSmallestWidth=1; PVRTuint32 uiSmallestHeight=1; PVRTuint32 uiSmallestDepth=1; PVRTuint64 PixelFormatPartHigh = sTextureHeader.u64PixelFormat&PVRTEX_PFHIGHMASK; //If the pixel format is compressed, get the pixel format's minimum dimensions. if (PixelFormatPartHigh==0) { PVRTGetFormatMinDims((EPVRTPixelFormat)sTextureHeader.u64PixelFormat, uiSmallestWidth, uiSmallestHeight, uiSmallestDepth); } //Needs to be 64-bit integer to support 16kx16k and higher sizes. PVRTuint64 uiDataSize = 0; if (iMipLevel==-1) { for (PVRTuint8 uiCurrentMIP = 0; uiCurrentMIP<sTextureHeader.u32MIPMapCount; ++uiCurrentMIP) { //Get the dimensions of the current MIP Map level. PVRTuint32 uiWidth = PVRT_MAX(1,sTextureHeader.u32Width>>uiCurrentMIP); PVRTuint32 uiHeight = PVRT_MAX(1,sTextureHeader.u32Height>>uiCurrentMIP); PVRTuint32 uiDepth = PVRT_MAX(1,sTextureHeader.u32Depth>>uiCurrentMIP); //If pixel format is compressed, the dimensions need to be padded. if (PixelFormatPartHigh==0) { uiWidth = ((uiWidth + uiSmallestWidth - 1) / uiSmallestWidth) * uiSmallestWidth; uiHeight = ((uiHeight + uiSmallestHeight - 1) / uiSmallestHeight) * uiSmallestHeight; uiDepth = ((uiDepth + uiSmallestDepth - 1) / uiSmallestDepth) * uiSmallestDepth; } //Add the current MIP Map's data size to the total. if (sTextureHeader.u64PixelFormat >= ePVRTPF_ASTC_4x4 && sTextureHeader.u64PixelFormat <= ePVRTPF_ASTC_6x6x6) { uiDataSize += (uiWidth / uiSmallestWidth) * (uiHeight / uiSmallestHeight) * (uiDepth / uiSmallestDepth) * 128; } else { uiDataSize += (PVRTuint64)PVRTGetBitsPerPixel(sTextureHeader.u64PixelFormat)*(PVRTuint64)uiWidth*(PVRTuint64)uiHeight*(PVRTuint64)uiDepth; } } } else {
/*!*********************************************************************** @Function PVRTGetTextureDataSize @Input iMipLevel Specifies a mip level to check, 'PVRTEX_ALLMIPLEVELS' can be passed to get the size of all MIP levels. @Input bAllSurfs Size of all surfaces is calculated if true, only a single surface if false. @Input bAllFaces Size of all faces is calculated if true, only a single face if false. @Return PVRTuint32 Size in BYTES of the specified texture area. @Description Gets the size in BYTES of the texture, given various input parameters. User can retrieve the size of either all surfaces or a single surface, all faces or a single face and all MIP-Maps or a single specified MIP level. *************************************************************************/ PVRTuint32 PVRTGetTextureDataSize(PVRTextureHeaderV3 sTextureHeader, PVRTint32 iMipLevel, bool bAllSurfaces, bool bAllFaces) { //The smallest divisible sizes for a pixel format PVRTuint32 uiSmallestWidth=1; PVRTuint32 uiSmallestHeight=1; PVRTuint32 uiSmallestDepth=1; PVRTuint64 PixelFormatPartHigh = sTextureHeader.u64PixelFormat&PVRTEX_PFHIGHMASK; //If the pixel format is compressed, get the pixel format's minimum dimensions. if (PixelFormatPartHigh==0) { PVRTGetFormatMinDims((EPVRTPixelFormat)sTextureHeader.u64PixelFormat, uiSmallestWidth, uiSmallestHeight, uiSmallestDepth); } PVRTuint32 uiDataSize = 0; if (iMipLevel==-1) { for (PVRTuint8 uiCurrentMIP = 0; uiCurrentMIP<sTextureHeader.u32MIPMapCount; ++uiCurrentMIP) { //Get the dimensions of the current MIP Map level. PVRTuint32 uiWidth = PVRT_MAX(1,sTextureHeader.u32Width>>uiCurrentMIP); PVRTuint32 uiHeight = PVRT_MAX(1,sTextureHeader.u32Height>>uiCurrentMIP); PVRTuint32 uiDepth = PVRT_MAX(1,sTextureHeader.u32Depth>>uiCurrentMIP); //If pixel format is compressed, the dimensions need to be padded. if (PixelFormatPartHigh==0) { uiWidth=uiWidth+( (-1*uiWidth)%uiSmallestWidth); uiHeight=uiHeight+( (-1*uiHeight)%uiSmallestHeight); uiDepth=uiDepth+( (-1*uiDepth)%uiSmallestDepth); } //Add the current MIP Map's data size to the total. uiDataSize+=PVRTGetBitsPerPixel(sTextureHeader.u64PixelFormat)*uiWidth*uiHeight*uiDepth; } } else {