📄 tex.c
字号:
if(ui32Height == 0)
ui32Height = 1;
}
if(i != ui32NumLevels)
{
bad_value:
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXIMAGE_TIME);
return;
}
}
else
{
ui32Size = MAX(1, (ui32Width * ui32Height * ui32SrcBitsPerPixel) >> 3);
}
if(imageSize != (GLint)(ui32Size + ui32PaletteSize))
{
goto bad_value;
}
ui32Width = width;
ui32Height = height;
pvPixels = (IMG_UINT8 *)pvPixels + ui32PaletteSize;
/* Allocate memory for the level data */
for(i=0; i< ui32NumLevels; i++)
{
pui8Dest = TextureCreateLevel(gc, psTex, i, internalformat, psTexFormat, ui32Width, ui32Height);
if(data && pui8Dest)
{
IMG_VOID *pvDest = psTex->asMipLevel[level].pui8Buffer;
IMG_UINT8 *pui8Src = (IMG_UINT8 *)pvPixels;
IMG_UINT32 ui32SrcRowSize = (ui32Width * ui32SrcBitsPerPixel) >> 3;
IMG_UINT32 ui32DstRowSize = ui32Width * ((psTex->psFormat->ui32BitsPerTexel+7) >> 3);
IMG_UINT32 j;
for(j=0; j < ui32Height; j++)
{
(*pfnCopySpan)(pvDest, pui8Src, ui32Width, data);
pvDest = (IMG_UINT8 *)pvDest + ui32DstRowSize;
pui8Src += ui32SrcRowSize;
}
}
else
{
/*
* remove texture from active list. If needed, validation will reload
*/
TextureRemoveResident(gc, psTex);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXIMAGE_TIME);
return;
}
pvPixels = (IMG_UINT8 *)pvPixels + ((ui32Width * ui32Height * ui32SrcBitsPerPixel) >> 3);
ui32Width >>= 1;
ui32Height >>= 1;
if(ui32Width == 0)
ui32Width = 1;
if(ui32Height == 0)
ui32Height = 1;
}
/*
* remove texture from active list. If needed, validation will reload
*/
TextureRemoveResident(gc, psTex);
}
else /* PVRTC */
{
/* Must have at least 2x2 blocks */
ui32Height = MAX(height >> 2, 2);
/* 2Bpp encodes 8x4 blocks, 4Bpp encodes 4x4 */
if(psTexFormat->ui32HWFormat == MBX1_TSPPL1_TPIXFORMPVRTC2)
{
ui32Width = MAX(width >> 3, 2);
}
else
{
ui32Width = MAX(width >> 2, 2);
}
ui32Size = ui32Width * ui32Height << 3;
if(imageSize != (GLint)ui32Size)
{
goto bad_value;
}
pui8Dest = TextureCreateLevel(gc, psTex, level, internalformat, psTexFormat, width, height);
#if defined(DEBUG)
if(psTex->asMipLevel[level].ui32ImageSize != (IMG_UINT32)imageSize)
DPF((DBG_ERROR,"Bad level size calc"));
#endif
if(pvPixels && pui8Dest)
{
IMG_VOID *pvDest = psTex->asMipLevel[level].pui8Buffer;
IMG_UINT8 *pui8Src = (IMG_UINT8 *)pvPixels;
IMG_UINT32 ui32RowSize = (ui32Width * ui32SrcBitsPerPixel) >> 3;
for(i=0; i < ui32Height; i++)
{
(*pfnCopySpan)(pvDest, pui8Src, ui32Width, data);
pvDest = (IMG_UINT8 *)pvDest + ui32RowSize;
pui8Src += ui32RowSize;
}
}
else
{
/*
* remove texture from active list. If needed, validation will reload
*/
TextureRemoveResident(gc, psTex);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXIMAGE_TIME);
return;
}
/*
* remove texture from active list. If needed, validation will reload
*/
TextureRemoveResident(gc, psTex);
}
GLES_INC_PIXEL_COUNT(GLES_TIMER_COMPRESSTEXIMAGE_TIME, width*height);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXIMAGE_TIME);
GLES_TIME_STOP(GLES_TIMES_glCompressedTexImage2D);
}
/***********************************************************************************
Function Name : glCompressedTexSubImage2D
Inputs : target, level, xoffset, yoffset, width, height, format,
imageSize, data
Outputs : -
Returns : -
Description : ENTRYPOINT: Provides texture subdata in a pre-compressed format.
Host texture data memory is already allocated/may have already
been uploaded to HW. Subdata will need to be integrated/uploaded.
************************************************************************************/
GLAPI void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
{
GLEStexture *psTex;
PFNCopyPaletteSpan pfnCopySpan;
IMG_UINT32 ui32SrcBitsPerPixel;
const GLEStextureFormat *psTexFormat;
GLEStextureBuffer *pui8Dest;
IMG_UINT32 ui32Width = width;
IMG_UINT32 ui32Height = height;
IMG_UINT32 i, ui32Size;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME);
GLES_TIME_START(GLES_TIMES_glCompressedTexSubImage2D);
psTex = CheckTexSubImageArgs(gc, target, level, xoffset, yoffset, width, height);
if(!psTex)
{
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME);
return;
}
switch(format)
{
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
ui32SrcBitsPerPixel = 64;
pfnCopySpan = (PFNCopyPaletteSpan) Copy64Span;
psTexFormat = (GLEStextureFormat *)&TexFormatPVRTC2RGB;
break;
case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
ui32SrcBitsPerPixel = 64;
pfnCopySpan = (PFNCopyPaletteSpan) Copy64Span;
psTexFormat = (GLEStextureFormat *)&TexFormatPVRTC2RGBA;
break;
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
ui32SrcBitsPerPixel = 64;
pfnCopySpan = (PFNCopyPaletteSpan) Copy64Span;
psTexFormat = (GLEStextureFormat *)&TexFormatPVRTC4RGB;
break;
case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
ui32SrcBitsPerPixel = 64;
pfnCopySpan = (PFNCopyPaletteSpan) Copy64Span;
psTexFormat = (GLEStextureFormat *)&TexFormatPVRTC4RGBA;
break;
default:
bad_enum:
SetError(gc, GL_INVALID_ENUM);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME);
return;
}
if(psTexFormat != psTex->asMipLevel[level].psTexFormat)
{
goto bad_enum;
}
/* Must have at least 2x2 blocks */
ui32Height = MAX(height >> 2, 2);
/* 2Bpp encodes 8x4 blocks, 4Bpp encodes 4x4 */
if(psTexFormat->ui32HWFormat == MBX1_TSPPL1_TPIXFORMPVRTC2)
{
ui32Width = MAX(width >> 3, 2);
}
else
{
ui32Width = MAX(width >> 2, 2);
}
ui32Size = ui32Width * ui32Height << 3;
if(imageSize != (GLint)ui32Size)
{
SetError(gc, GL_INVALID_VALUE);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME);
return;
}
pui8Dest = psTex->asMipLevel[level].pui8Buffer;
if(data && pui8Dest)
{
IMG_VOID *pvDest = psTex->asMipLevel[level].pui8Buffer;
IMG_UINT8 *pui8Src = (IMG_UINT8 *)data;
IMG_UINT32 ui32RowSize = (ui32Width * ui32SrcBitsPerPixel) >> 3;
for(i=0; i < ui32Height; i++)
{
(*pfnCopySpan)(pvDest, pui8Src, ui32Width, data);
pvDest = (IMG_UINT8 *)pvDest + ui32RowSize;
pui8Src += ui32RowSize;
}
GLES_INC_PIXEL_COUNT(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME, width*height);
}
TextureRemoveResident(gc, psTex);
GLES_TIME_STOP(GLES_TIMER_COMPRESSTEXSUBIMAGE_TIME);
GLES_TIME_STOP(GLES_TIMES_glCompressedTexSubImage2D);
}
/***********************************************************************************
Function Name : glCopyTexImage2D
Inputs : target, level, internalformat, x, y, width, height, border
Outputs : -
Returns : -
Description : ENTRYPOINT: Copies data from frambuffer to a texture.
Host texture data memory is allocated and loaded immediately.
Will cause a render to take place.
************************************************************************************/
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
GLEStexture *psTex;
const GLEStextureFormat *psTexFormat;
PFNReadSpan pfnReadSpan;
GLenum type;
GLEStextureBuffer *pui8Dest;
GLESpixelSpanInfo sSpanInfo = {0};
IMG_VOID *pvSurfacePointer;
IMG_UINT32 i;
GLESDrawableParams sReadParams;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMER_COPYTEXIMAGE_TIME);
GLES_TIME_START(GLES_TIMES_glCopyTexImage2D);
/* Check arguments and get the right texture being changed */
psTex = CheckTexImageArgs(gc, target, level, IMG_FALSE, width, height, border);
if (!psTex)
{
GLES_TIME_STOP(GLES_TIMER_COPYTEXIMAGE_TIME);
return;
}
switch(gc->psMode->ePixelFormat)
{
case PVRSRV_PIXEL_FORMAT_ARGB8888:
switch(internalformat)
{
case GL_RGBA:
pfnReadSpan = ReadCopy8888Span;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatRGBA8888;
break;
case GL_RGB:
pfnReadSpan = ReadCopy8888to888Span;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatRGB888;
break;
case GL_LUMINANCE:
pfnReadSpan = ReadCopy8888toLuminanceSpan;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatLuminance;
break;
case GL_ALPHA:
pfnReadSpan = ReadCopy8888ToAlphaSpan; type = GL_UNSIGNED_BYTE;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatAlpha;
break;
case GL_LUMINANCE_ALPHA:
pfnReadSpan = ReadCopy8888toLuminanceAlphaSpan;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatLuminanceAlpha;
break;
default:
bad_enum:
SetError(gc, GL_INVALID_ENUM);
GLES_TIME_STOP(GLES_TIMER_COPYTEXIMAGE_TIME);
return;
}
break;
case PVRSRV_PIXEL_FORMAT_RGB565:
default:
switch(internalformat)
{
case GL_RGB:
pfnReadSpan = ReadCopy565Span;
type = GL_UNSIGNED_SHORT_5_6_5;
psTexFormat = &TexFormatRGB565;
break;
case GL_LUMINANCE:
pfnReadSpan = ReadCopy565toLuminanceSpan;
type = GL_UNSIGNED_BYTE;
psTexFormat = &TexFormatLuminance;
break;
default:
goto bad_enum;
}
break;
}
/* Allocate memory for the level data */
pui8Dest = TextureCreateLevel(gc, psTex, (IMG_UINT32)level, internalformat,
psTexFormat, (IMG_UINT32)width, (IMG_UINT32)height);
/* Copy image data */
if (pui8Dest)
{
GLESGetDrawableParameters(gc->hReadDrawable, &sReadParams);
if(!SetupReadPixelsSpanInfo(gc, &sSpanInfo, x, y, (IMG_UINT32)width, (IMG_UINT32)height,
internalformat, type, IMG_FALSE, &sReadParams))
{
GLES_TIME_STOP(GLES_TIMER_COPYTEXIMAGE_TIME);
return;
}
/* Make sure to flush the read render surface, not the write one */
if(FlushHW(gc, (GLESRenderSurface *)sReadParams.hRenderSurface, IMG_TRUE) != IMG_GLES_NO_ERROR)
{
DPF((DBG_ERROR,"Can't flush HW"));
GLES_TIME_STOP(GLES_TIMER_COPYTEXIMAGE_TIME);
return;
}
pvSurfacePointer = sReadParams.pvLinSurfaceAddress;
sSpanInfo.pvOutData = (IMG_VOID *) ((psTex->asMipLevel[level].pui8Buffer) +
sSpanInfo.ui32DstSkipLines * sSpanInfo.i32DstRowIncrement +
sSpanInfo.ui32DstSkipPixels * sSpanInfo.i32DstGroupIncrement);
sSpanInfo.pvInData = (IMG_VOID *) ((IMG_UINT8 *)pvSurfacePointer +
sSpanInfo.i32ReadY * sSpanInfo.i32SrcRowIncrement +
sSpanInfo.i32ReadX * sSpanInfo.i32SrcGroupIncrement);
for (i=0; i<sSpanInfo.ui32Height; i++)
{
(*pfnReadSpan)(gc, &sSpanInfo);
sSpanInfo.pvInData = (IMG_UINT8 *)sSpanInfo.pvInData + sSpanInfo.i32SrcRowIncrement;
sSpanInfo.pvOutData = (IMG_UINT8 *)sSpanInfo.pvOutData + sSpanInfo.i32DstRowIncrement;
}
}
/*
* remove texture from active list. If needed, validation will reload
*/
TextureRemoveResident(gc, psTex);
GLES_INC_PIXEL_COUNT(GLES_TIMER_COPYTEXIMAGE_TIME, width*height);
GLES_TIME_STOP(GLES_TIMER_COPYTEXIMAGE_TIME);
GLES_TIME_STOP(GLES_TIMES_glCopyTexImage2D);
}
/***********************************************************************************
Function Name : glCopyTexSubImage2D
Inputs : target, level, xoffset, yoffset, x, y, width, height
Outputs : -
Return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -