📄 texdata.c
字号:
static IMG_VOID TranslateScaleTexture(GLESContext *gc, GLEStexture *psTex, IMG_UINT32 ui32Lod,
GLEStextureBuffer *pui8Src, IMG_UINT32 ui32Width, IMG_UINT32 ui32Height,
IMG_UINT32 ui32BytesPerPixel, IMG_UINT32 ui32Factor)
{
IMG_UINT8 *pui8Dest;
IMG_UINT8 *pui8TmpSrc, *pui8TmpDst;
IMG_UINT32 ui32LoopX, ui32LoopY, ui32Rx, ui32Ry;
IMG_UINT32 ui32ByteCount;
IMG_UINT32 ui32Stride = ui32Width*ui32BytesPerPixel;
IMG_UINT32 ui32Size;
ui32Size = (ui32Width << ui32Factor) * (ui32Height << ui32Factor) * ui32BytesPerPixel;
pui8Dest = GLESMalloc(gc, ui32Size);
pui8TmpDst = pui8Dest;
ui32Rx = (1 << ui32Factor);
ui32Ry = (1 << ui32Factor);
for (ui32LoopY = 0; ui32LoopY < ui32Height; ui32LoopY++)
{
for (ui32Ry = 0; ui32Ry < (IMG_UINT32)(1 << ui32Factor); ui32Ry++)
{
pui8TmpSrc = pui8Src + (ui32Stride * ui32LoopY);
for (ui32LoopX = 0; ui32LoopX < ui32Width; ui32LoopX++)
{
for (ui32Rx = 0; ui32Rx < (IMG_UINT32)(1 << ui32Factor); ui32Rx++)
{
for (ui32ByteCount = 0; ui32ByteCount < ui32BytesPerPixel; ui32ByteCount++)
{
pui8TmpDst[ui32ByteCount] = pui8TmpSrc[ui32ByteCount];
}
pui8TmpDst += ui32BytesPerPixel;
}
pui8TmpSrc += ui32BytesPerPixel;
}
}
}
TwiddleLoadData(psTex, ui32Width << ui32Factor, ui32Height << ui32Factor, ui32Lod, ui32Lod, pui8Dest);
GLESFree(gc, pui8Dest);
}
/***********************************************************************************
Function Name : TranslateLevel
Inputs : gc, psTex, ui32Lod
Outputs : psTex
Returns : -
Description : This is called to translate a given level of the texture object
into the final texture. It applies the scaleShift and
synthesises upper levels of the map as required.
************************************************************************************/
IMG_VOID TranslateLevel(GLESContext *gc, GLEStexture *psTex, IMG_UINT32 ui32Lod)
{
GLESmipMapLevel *psMipLevel = &psTex->asMipLevel[ui32Lod];
const GLEStextureFormat *psTexFmt = psMipLevel->psTexFormat;
IMG_UINT32 ui32Stride;
IMG_UINT32 ui32BytesPerPixel;
IMG_UINT32 ui32HeightScale, ui32WidthScale;
IMG_UINT32 ui32TmpA, ui32TmpB;
GLEStextureBuffer *pui8Buffer;
IMG_UINT32 ui32Width, ui32Height;
ui32BytesPerPixel = (psTexFmt->ui32BitsPerTexel+7) >> 3;
ui32HeightScale = psTex->ui32HeightScale;
ui32WidthScale = psTex->ui32WidthScale;
ui32Width = psMipLevel->ui32Width;
ui32Height = psMipLevel->ui32Height;
ui32Stride = ui32Width * ui32BytesPerPixel;
if (ui32WidthScale | ui32HeightScale)
{
/*Only adjust scale if previous ui32Lod has width/ui32Height 1*/
/*If it is, calculate the relevant scale factor for this ui32Lod*/
ui32TmpA = 0;
ui32TmpB = MIN(ui32HeightScale, ui32Lod);
while(ui32TmpA < ui32TmpB)
{
if (psTex->asMipLevel[ui32Lod - ui32TmpA - 1].ui32Height == 1)
ui32HeightScale--;
ui32TmpA++;
}
ui32TmpA = 0;
ui32TmpB = MIN(ui32WidthScale, ui32Lod);
while(ui32TmpA < ui32TmpB)
{
if (psTex->asMipLevel[ui32Lod - ui32TmpA - 1].ui32Width == 1)
ui32WidthScale--;
ui32TmpA++;
}
}
if(ui32HeightScale)
{
IMG_UINT32 ui32Height2;
IMG_UINT32 ui32LoopY, ui32LoopScale;
/* The each scan in the buffered texture image must be repeated 2^HeightScale times
* to fill the texture vertically
*/
ui32Height2 = 1 << ui32HeightScale;
pui8Buffer = psMipLevel->pui8Buffer;
for(ui32LoopY = 0; ui32LoopY < ui32Height; ui32LoopY++, pui8Buffer += ui32Stride)
{
for(ui32LoopScale = 0; ui32LoopScale < ui32Height2; ui32LoopScale++)
{
TwiddleLoadSubData(psTex, ui32Lod, 0, (ui32LoopY*ui32Height2)+ui32LoopScale, ui32Width, 1, pui8Buffer);
}
}
}
else if(ui32WidthScale)
{
IMG_UINT32 ui32Width2;
IMG_UINT32 ui32LoopX, ui32LoopScale;
/* The each pixel in the buffered texture image must be repeated 2^WidthScale times
* to fill the texture horizontaly
*/
ui32Width2 = 1<<ui32WidthScale;
pui8Buffer = psMipLevel->pui8Buffer;
for(ui32LoopX=0; ui32LoopX < ui32Width; ui32LoopX++, pui8Buffer += ui32BytesPerPixel)
{
for(ui32LoopScale=0; ui32LoopScale < ui32Width2; ui32LoopScale++)
{
TwiddleLoadSubData(psTex, ui32Lod, (ui32LoopX*ui32Width2)+ui32LoopScale, 0, 1, ui32Height, pui8Buffer);
}
}
}
else
{
TwiddleLoadData(psTex, ui32Width, ui32Height, ui32Lod, ui32Lod + psTex->ui32ScaleShift, psMipLevel->pui8Buffer);
/*
* If scaleShift is set, we need to synthesise the top levels
* of the map by replicating pixels (or copying data for PVRTC).
*/
if (ui32Lod == 0 && psTex->ui32ScaleShift)
{
IMG_UINT32 ui32Scale;
for (ui32Scale = 1; ui32Scale <= psTex->ui32ScaleShift; ui32Scale++)
{
if(ui32BytesPerPixel == 8)
{
TwiddleLoadData(psTex, ui32Width, ui32Height, 0,
psTex->ui32ScaleShift - ui32Scale, psMipLevel->pui8Buffer);
}
else
{
TranslateScaleTexture(gc, psTex, psTex->ui32ScaleShift - ui32Scale,
psMipLevel->pui8Buffer,
psMipLevel->ui32Width,
psMipLevel->ui32Height,
ui32BytesPerPixel, ui32Scale);
}
}
}
}
}
/***********************************************************************************
Function Name : ReadBackTextureData
Inputs : gc, ui32SrcLevel, ui32DstLevel
Outputs : pvBuffer
Returns : -
Description : Reads back texture data from a HW texture. Downcales as
appropriate
************************************************************************************/
IMG_VOID ReadBackTextureData(GLEStexture *psTex, IMG_UINT32 ui32SrcLevel, IMG_UINT32 ui32DstLevel, IMG_VOID *pvBuffer)
{
IMG_UINT32 ui32Width, ui32Height, ui32WidthLog2, ui32HeightLog2;
IMG_VOID *pvTmpBuffer;
IMG_UINT32 ui32BytesPerPixel;
IMG_VOID *pvSrcData;
IMG_UINT32 i, ui32Offset, ui32Size=0;
const GLEStextureFormat *psTexFormat = psTex->asMipLevel[ui32DstLevel].psTexFormat;
ui32BytesPerPixel = (psTexFormat->ui32BitsPerTexel+7) >> 3;
ui32Width = psTex->asMipLevel[ui32DstLevel].ui32Width;
ui32Height = psTex->asMipLevel[ui32DstLevel].ui32Height;
ui32WidthLog2 = ((psTex->ui32HWSize & ~MBX1_TSPPL1_TUSIZECLRMASK) >> MBX1_TSPPL1_TUSIZESHIFT) + GLES_MIN_TEXTURE_LEVEL;
ui32HeightLog2 = ((psTex->ui32HWSize & ~MBX1_TSPPL1_TVSIZECLRMASK) >> MBX1_TSPPL1_TVSIZESHIFT) + GLES_MIN_TEXTURE_LEVEL;
pvTmpBuffer = pvBuffer;
if(ui32BytesPerPixel == 8)
{
ui32Offset = GetCompressedMipMapOffset(ui32SrcLevel, 1 << ui32WidthLog2, 1 << ui32HeightLog2,
psTexFormat->ui32HWFormat == MBX1_TSPPL1_TPIXFORMPVRTC2 ? IMG_TRUE : IMG_FALSE);
ui32Size = GetCompressedMipMapOffset(ui32SrcLevel + 1, 1 << ui32WidthLog2, 1 << ui32HeightLog2,
psTexFormat->ui32HWFormat == MBX1_TSPPL1_TPIXFORMPVRTC2 ? IMG_TRUE : IMG_FALSE) -
ui32Offset;
pvSrcData = (IMG_UINT8 *)psTex->psMemInfo->pvLinAddr + (ui32Offset << 3);
}
else
{
pvSrcData = (IMG_UINT8 *)psTex->psMemInfo->pvLinAddr + (ui32BytesPerPixel *
GetMipMapOffset(ui32SrcLevel, 1 << ui32WidthLog2, 1 << ui32HeightLog2));
}
if(ui32SrcLevel > ui32WidthLog2)
ui32WidthLog2 = 0;
else
ui32WidthLog2 -= ui32SrcLevel;
if(ui32SrcLevel > ui32HeightLog2)
ui32HeightLog2 = 0;
else
ui32HeightLog2 -= ui32SrcLevel;
if(psTex->ui32WidthScale)
{
for(i=0; i < ui32Width; i++)
{
psTex->pfnReadBackData(pvTmpBuffer, pvSrcData, ui32WidthLog2, ui32HeightLog2,
i<<psTex->ui32WidthScale, 0, 1, ui32Height, ui32Width);
pvTmpBuffer = (IMG_UINT8 *)pvTmpBuffer + ui32BytesPerPixel;
}
}
else if(psTex->ui32HeightScale)
{
for(i=0; i < ui32Height; i++)
{
psTex->pfnReadBackData(pvTmpBuffer, pvSrcData, ui32WidthLog2, ui32HeightLog2,
0, i << psTex->ui32HeightScale, ui32Width, 1, ui32Width);
pvTmpBuffer = (IMG_UINT8 *)pvTmpBuffer + (ui32Width * ui32BytesPerPixel);
}
}
else
{
if(ui32BytesPerPixel == 8)
{
HostMemCopy(pvTmpBuffer, pvSrcData, (ui32Size << 3));
}
else
{
psTex->pfnReadBackData(pvTmpBuffer, pvSrcData, ui32WidthLog2, ui32HeightLog2,
0, 0, ui32Width, ui32Height, ui32Width);
}
}
}
/***********************************************************************************
Function Name : SetupTwiddleFns
Inputs : psTex
Outputs : psTex
Returns : -
Description : Sets up the appropriate twiddle,subtwiddle and readback
functions based on a texture's bit depth.
************************************************************************************/
IMG_VOID SetupTwiddleFns(GLEStexture *psTex)
{
switch(psTex->psFormat->ui32BitsPerTexel)
{
case 8:
psTex->pfnTextureTwiddle = DeTwiddleAddress8bpp;
psTex->pfnSubTextureTwiddle = TwiddleAddress8bpp;
psTex->pfnReadBackData = ReadBackTwiddle8bpp;
break;
case 16:
psTex->pfnTextureTwiddle = DeTwiddleAddress16bpp;
psTex->pfnSubTextureTwiddle = TwiddleAddress16bpp;
psTex->pfnReadBackData = ReadBackTwiddle16bpp;
break;
case 32:
psTex->pfnTextureTwiddle = DeTwiddleAddress32bpp;
psTex->pfnSubTextureTwiddle = TwiddleAddress32bpp;
psTex->pfnReadBackData = ReadBackTwiddle32bpp;
break;
default:
/* May get here for PVRTC - shouldn't use these fn pointers anyway */
break;
}
}
/***********************************************************************************
Function Name : CopyTextureData
Inputs : gc, psSrcInfo
Outputs : psDstInfo
Returns : -
Description : Copies texture data from one texture to another. (Could be
accelerated by HW).
************************************************************************************/
IMG_VOID CopyTextureData(GLESContext *gc, PVRSRV_MEM_INFO *psDstInfo, PVRSRV_MEM_INFO *psSrcInfo)
{
GLES_TIME_START(GLES_TIMER_TEXTURE_GHOST_LOAD_TIME);
HostMemCopy(psDstInfo->pvLinAddr, psSrcInfo->pvLinAddr, psSrcInfo->ui32AllocSize);
GLES_TIME_STOP(GLES_TIMER_TEXTURE_GHOST_LOAD_TIME);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -