/*!***************************************************************************
@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;
}
Example #2
0
/*!***********************************************************************
@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
	{
Example #3
0
/*!***********************************************************************
@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
	{