📄 tex.c
字号:
/**************************************************************************
* Name : tex.c
* Author : BCB
* Created : 01/05/2003
*
* Copyright : 2003 by Imagination Technologies Limited. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8, HomePark
* : Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Platform : ANSI
*
* $Date: 2004/10/29 09:31:30 $ $Revision: 1.41.1.9 $
* $Log: tex.c $
*
**************************************************************************/
#define MODULE_ID MODID_TEX
#include "context.h"
#include "slaveport.h"
#if (DEBUG || TIMING) && !defined (__SYMBIAN32__)
static IMG_UINT32 ui32TextureMemCurrent = 0;
IMG_UINT32 ui32TextureMemHWM = 0;
#endif
/* This is a marker to show a mip level has already been loaded to FB */
const static IMG_UINT32 ui32LevelLoadedTag = 0;
#define GLES_LOADED_LEVEL ((IMG_VOID *)&ui32LevelLoadedTag)
static IMG_VOID TextureRemoveResident(GLESContext *gc, GLEStexture *psTex);
static GLEStexture *CreateTexture(GLESContext *gc, IMG_UINT32 ui32Name);
static IMG_BOOL UnloadInconsistentTexture(GLESContext *gc, GLEStexture *psTex, IMG_UINT32 ui32LevelsToSkip);
static GLEStextureBuffer *TextureCreateLevel(GLESContext *gc, GLEStexture *psTex, IMG_UINT32 ui32Lod,
GLenum internalFormat, const GLEStextureFormat *psTexFormat,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height);
/***********************************************************************************
Function Name : ConvertFactorColor
Inputs : pfColor
Outputs : -
Returns : HW format factor colour
Description : Converts a floating point factor color to the HW format
************************************************************************************/
static IMG_UINT32 ConvertFactorColor(const IMG_FLOAT *pfColor)
{
IMG_FLOAT fR,fG,fB,fA;
IMG_UINT32 ui32Color;
fR = Clampf(pfColor[0], GLES_Zero, GLES_One);
fG = Clampf(pfColor[1], GLES_Zero, GLES_One);
fB = Clampf(pfColor[2], GLES_Zero, GLES_One);
fA = Clampf(pfColor[3], GLES_Zero, GLES_One);
ui32Color = ((GLuint)(fA * 63) << MBX1_TSPOBJ_FACTORASHIFT) |
((GLuint)(fR * 31) << MBX1_TSPOBJ_FACTORRSHIFT) |
((GLuint)(fG * 31) << MBX1_TSPOBJ_FACTORGSHIFT) |
(GLuint)(fB * 31) << MBX1_TSPOBJ_FACTORBSHIFT;
return ui32Color;
}
/***********************************************************************************
Function Name : glActiveTexture
Inputs : texture
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets active texture unit.
We need to store this for the state machine, although HW makes
no use of it.
************************************************************************************/
GLAPI void APIENTRY glActiveTexture(GLenum texture)
{
IMG_UINT32 ui32Unit = texture - GL_TEXTURE0;
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glActiveTexture);
if (ui32Unit >= GLES_MAX_TEXTURE_UNITS)
{
SetError(gc, GL_INVALID_ENUM);
return;
}
gc->sState.sTexture.ui32ActiveTexture = ui32Unit;
gc->sState.sTexture.psActive = &gc->sState.sTexture.asUnit[ui32Unit];
GLES_TIME_STOP(GLES_TIMES_glActiveTexture);
}
/***********************************************************************************
Function Name : BindTexture
Inputs : gc, ui32Unit, ui32Texture
Outputs : -
Returns : -
Description : Sets current texture for subsequent calls.
Will create an internal psTex structure, but no texture data
memory is allocated yet. Uses name table.
************************************************************************************/
static IMG_VOID BindTexture(GLESContext *gc, IMG_UINT32 ui32Unit, IMG_UINT32 ui32Texture)
{
GLEStexture *psTex;
GLEStexture *psBoundTexture;
GLES_ASSERT(NULL != gc->sTexture.psNamesArray);
/*
** Retrieve the texture object from the psNamesArray structure.
*/
if (ui32Texture == 0)
{
psTex = gc->sTexture.psDefaultTexture;
GLES_ASSERT(NULL != psTex);
GLES_ASSERT(0 == psTex->sState.ui32Name);
}
else
{
LOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
psTex = (GLEStexture *) LockNamedItem(gc, gc->sTexture.psNamesArray, ui32Texture);
UNLOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
}
/*
** Is this the first time this ui32Name has been bound?
** If so, create a new texture object and initialize it.
*/
if (NULL == psTex)
{
psTex = CreateTexture(gc, ui32Texture);
GLES_ASSERT(NULL != psTex);
GLES_ASSERT(ui32Texture == psTex->sState.ui32Name);
LOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
NewNamedItem(gc, gc->sTexture.psNamesArray, ui32Texture, psTex);
UNLOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
/*
** Shortcut way to lock without doing another lookup.
*/
psTex->ui32Refcount++;
}
else
{
/*
** Retrieved an existing texture object. Do some
** sanity checks.
*/
GLES_ASSERT(ui32Texture == psTex->sState.ui32Name);
}
/*
** Release texture that is being unbound.
*/
psBoundTexture = gc->sTexture.apsBoundTexture[ui32Unit];
if (psBoundTexture && (psBoundTexture->sState.ui32Name != 0))
{
LOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
UnlockDataItem(gc, psBoundTexture);
UNLOCK_NAMES_ARRAY(gc->sTexture.psNamesArray);
}
/*
** Install the new texture into the correct target in this context.
*/
gc->sState.sTexture.asUnit[ui32Unit].psTexture = &psTex->sState;
gc->sTexture.apsBoundTexture[ui32Unit] = psTex;
gc->ui32DirtyMask |= GLES_DIRTY_SW_TEXTURE_UNIT | GLES_DIRTY_SW_TEXTURE_STATE;
}
/***********************************************************************************
Function Name : glBindTexture
Inputs : target, texture
Outputs : -
Returns : -
Description : ENTRYPOINT: Sets current texture for subsequent calls.
************************************************************************************/
GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture)
{
__GL_GET_CONTEXT();
GLES_TIME_START(GLES_TIMES_glBindTexture);
if(target != GL_TEXTURE_2D)
{
SetError(gc, GL_INVALID_ENUM);
return;
}
BindTexture(gc, gc->sState.sTexture.ui32ActiveTexture, texture);
GLES_TIME_STOP(GLES_TIMES_glBindTexture);
}
/***********************************************************************************
Function Name : IsLegalRange
Inputs : gc, w, h, border, level, bIsPalette
Outputs : -
Returns : Whether the parameters are legal
Description : UTILITY: Checks some texture parameters for legality.
************************************************************************************/
static IMG_BOOL IsLegalRangeTex(GLESContext *gc, GLsizei w, GLsizei h, GLint border, GLint level, IMG_BOOL bIsPalette)
{
if(border)
{
bad_value:
SetError(gc, GL_INVALID_VALUE);
return IMG_FALSE;
}
if ((w < 0) || (w & (w - 1)))
goto bad_value;
if ((h < 0) || (h & (h - 1)))
goto bad_value;
if(bIsPalette)
{
if ((level > 0) || (GLES_ABS(level) >= GLES_MAX_TEXTURE_MIPMAP_LEVELS))
goto bad_value;
}
else
{
if ((level < 0) || (level >= GLES_MAX_TEXTURE_MIPMAP_LEVELS))
goto bad_value;
}
return IMG_TRUE;
}
/***********************************************************************************
Function Name : IsLegalRangeSubTex
Inputs : gc, psTex, x, y, w, h, level
Outputs : -
Returns : Whether the parameters are legal
Description : UTILITY: Checks some texture parameters for legality.
************************************************************************************/
static IMG_BOOL IsLegalRangeSubTex(GLESContext *gc, GLEStexture *psTex, GLint x, GLint y,
GLsizei w, GLsizei h, GLint level)
{
if ((x < 0) || (y < 0) || (w < 0) || (h < 0))
{
bad_value:
SetError(gc, GL_INVALID_VALUE);
return IMG_FALSE;
}
if ((level < 0) || (level >= GLES_MAX_TEXTURE_MIPMAP_LEVELS))
goto bad_value;
/* PVRTC */
if(psTex->psFormat->ui32BitsPerTexel == 64)
{
if((x > 0) || (y > 0))
goto bad_value;
if((w != (IMG_INT32)psTex->asMipLevel[level].ui32Width) ||
(h != (IMG_INT32)psTex->asMipLevel[level].ui32Height))
goto bad_value;
}
else
{
if(x + w > (IMG_INT32)psTex->asMipLevel[level].ui32Width)
goto bad_value;
if(y + h > (IMG_INT32)psTex->asMipLevel[level].ui32Height)
goto bad_value;
}
return IMG_TRUE;
}
/***********************************************************************************
Function Name : CheckTexImageArgs
Inputs : gc, target, level, bIsPalette, width, height, border
Outputs : -
Returns : texture pointer
Description : UTILITY: Checks [copy]teximage params for validity.
************************************************************************************/
static GLEStexture *CheckTexImageArgs(GLESContext *gc, GLenum target, GLint level, IMG_BOOL bIsPalette,
GLsizei width, GLsizei height, GLint border)
{
GLEStexture *psTex;
if(target != GL_TEXTURE_2D)
{
bad_enum:
SetError(gc, GL_INVALID_ENUM);
return NULL;
}
if(!IsLegalRangeTex(gc, width, height, border, level, bIsPalette))
return NULL;
psTex = gc->sTexture.apsBoundTexture[gc->sState.sTexture.ui32ActiveTexture];
if(!psTex)
goto bad_enum;
return psTex;
}
/***********************************************************************************
Function Name : CheckTexSubImageArgs
Inputs : gc, target, level, x, y, width, height
Outputs : -
Returns : texture pointer
Description : UTILITY: Checks [copy]texsubimage params for validity.
************************************************************************************/
static GLEStexture *CheckTexSubImageArgs(GLESContext *gc, GLenum target, GLint level, GLint x, GLint y,
GLsizei width, GLsizei height)
{
GLEStexture *psTex;
if(target != GL_TEXTURE_2D)
{
bad_enum:
SetError(gc, GL_INVALID_ENUM);
return NULL;
}
psTex = gc->sTexture.apsBoundTexture[gc->sState.sTexture.ui32ActiveTexture];
if(!psTex)
goto bad_enum;
if(!IsLegalRangeSubTex(gc, psTex, x, y, width, height, level))
return NULL;
return psTex;
}
/***********************************************************************************
Function Name : Copy8888Span
Inputs : pui32Src, ui32Width
Outputs : pui32Dest
Returns : -
Description : Copies texture data from RGBA UB to RGBA UB HW format
************************************************************************************/
static IMG_VOID Copy8888Span(IMG_UINT32 *pui32Dest, IMG_UINT32 *pui32Src, IMG_UINT32 ui32Width)
{
IMG_UINT32 i, ui32Temp;
for (i=0; i<ui32Width; i++)
{
ui32Temp = *pui32Src++;
*pui32Dest++ = (ui32Temp & 0xff00ff00) | ((ui32Temp & 0xff) << 16) | ((ui32Temp & 0xff0000) >> 16);
}
}
/***********************************************************************************
Function Name : Copy5551Span
Inputs : pui16Src, ui32Width
Outputs : pui16Dest
Returns : -
Description : Copies texture data from RGBA 5551 to RGBA 1555 HW format
************************************************************************************/
static IMG_VOID Copy5551Span(IMG_UINT16 *pui16Dest, IMG_UINT16 *pui16Src, IMG_UINT32 ui32Width)
{
IMG_UINT32 i;
IMG_UINT16 ui16Temp;
for (i=0; i<ui32Width; i++)
{
ui16Temp = *pui16Src++;
*pui16Dest++ = (ui16Temp << 15) | (ui16Temp >> 1);
}
}
/***********************************************************************************
Function Name : Copy4444Span
Inputs : pui16Src, ui32Width
Outputs : pui16Dest
Returns : -
Description : Copies texture data from RGBA 4444 to RGBA 4444 HW format
************************************************************************************/
static IMG_VOID Copy4444Span(IMG_UINT16 *pui16Dest, IMG_UINT16 *pui16Src, IMG_UINT32 ui32Width)
{
IMG_UINT32 i;
IMG_UINT16 ui16Temp;
for (i=0; i<ui32Width; i++)
{
ui16Temp = *pui16Src++;
*pui16Dest++ = (ui16Temp << 12) | (ui16Temp >> 4);
}
}
/***********************************************************************************
Function Name : Copy888XSpan
Inputs : pui8Src, ui32Width
Outputs : pui32Dest
Returns : -
Description : Copies texture data from RGB UB to RGBA8888 HW format
************************************************************************************/
static IMG_VOID Copy888XSpan(IMG_UINT32 *pui32Dest, IMG_UINT8 *pui8Src, IMG_UINT32 ui32Width)
{
IMG_UINT32 i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -