2012-05-06 03:46:55 +02:00
# include <string.h>
# include <stdlib.h>
# include <limits.h>
# include <math.h>
# include <float.h>
# include <cell/gcm.h>
# include <sys/sys_time.h>
# include "rgl.h"
# include "private.h"
# include <ppu_intrinsics.h>
# include "cg.h"
# include <Cg/cgc.h>
# include <Cg/cgGL.h>
# include "readelf.h"
# include "cgnv2rt.h"
# include <cell/sysmodule.h>
2012-05-22 18:51:06 +02:00
# include "../../../compat/strl.h"
2012-05-06 03:46:55 +02:00
# define RGL_ALIGN_FAST_TRANSFER 128
# define ENDIAN_32(X, F) ((F) ? endianSwapWord(X) : (X))
# define SWAP_IF_BIG_ENDIAN(arg) endianSwapWordByHalf(arg)
# define ROW_MAJOR 0
# define COL_MAJOR 1
# define pad(x, pad) (((x) + (pad) - 1 ) / (pad) * (pad))
# define gmmAddressToOffset(address, isMain) ((isMain) ? (address)-pGmmMainAllocator->memoryBase : (address)-pGmmLocalAllocator->memoryBase)
# define GL_UNSIGNED_SHORT_8_8 GL_UNSIGNED_SHORT_8_8_SCE
# define GL_UNSIGNED_SHORT_8_8_REV GL_UNSIGNED_SHORT_8_8_REV_SCE
# define GL_UNSIGNED_INT_16_16 GL_UNSIGNED_INT_16_16_SCE
# define GL_UNSIGNED_INT_16_16_REV GL_UNSIGNED_INT_16_16_REV_SCE
# define DECLARE_C_TYPES \
DECLARE_TYPE ( GL_BYTE , GLbyte , 127.f ) \
DECLARE_TYPE ( GL_UNSIGNED_BYTE , GLubyte , 255.f ) \
DECLARE_TYPE ( GL_SHORT , GLshort , 32767.f ) \
DECLARE_TYPE ( GL_UNSIGNED_SHORT , GLushort , 65535.f ) \
DECLARE_TYPE ( GL_INT , GLint , 2147483647.f ) \
DECLARE_TYPE ( GL_UNSIGNED_INT , GLuint , 4294967295.0 ) \
DECLARE_TYPE ( GL_FIXED , GLfixed , 65535.f )
# define DECLARE_UNPACKED_TYPES \
DECLARE_UNPACKED_TYPE ( GL_BYTE ) \
DECLARE_UNPACKED_TYPE ( GL_UNSIGNED_BYTE ) \
DECLARE_UNPACKED_TYPE ( GL_SHORT ) \
DECLARE_UNPACKED_TYPE ( GL_UNSIGNED_SHORT ) \
DECLARE_UNPACKED_TYPE ( GL_INT ) \
DECLARE_UNPACKED_TYPE ( GL_UNSIGNED_INT ) \
DECLARE_UNPACKED_TYPE ( GL_HALF_FLOAT_ARB ) \
DECLARE_UNPACKED_TYPE ( GL_FLOAT ) \
DECLARE_UNPACKED_TYPE ( GL_FIXED )
# define DECLARE_PACKED_TYPES \
DECLARE_PACKED_TYPE_AND_REV_2 ( UNSIGNED_BYTE , 4 , 4 ) \
DECLARE_PACKED_TYPE_AND_REV_2 ( UNSIGNED_BYTE , 6 , 2 ) \
DECLARE_PACKED_TYPE_AND_REV_3 ( UNSIGNED_BYTE , 3 , 3 , 2 ) \
DECLARE_PACKED_TYPE_AND_REV_4 ( UNSIGNED_BYTE , 2 , 2 , 2 , 2 ) \
DECLARE_PACKED_TYPE_AND_REV_2 ( UNSIGNED_SHORT , 12 , 4 ) \
DECLARE_PACKED_TYPE_AND_REV_2 ( UNSIGNED_SHORT , 8 , 8 ) \
DECLARE_PACKED_TYPE_AND_REV_3 ( UNSIGNED_SHORT , 5 , 6 , 5 ) \
DECLARE_PACKED_TYPE_AND_REV_4 ( UNSIGNED_SHORT , 4 , 4 , 4 , 4 ) \
DECLARE_PACKED_TYPE_AND_REV_4 ( UNSIGNED_SHORT , 5 , 5 , 5 , 1 ) \
DECLARE_PACKED_TYPE_AND_REV_2 ( UNSIGNED_INT , 16 , 16 ) \
DECLARE_PACKED_TYPE_AND_REV_4 ( UNSIGNED_INT , 8 , 8 , 8 , 8 ) \
DECLARE_PACKED_TYPE_AND_REV_4 ( UNSIGNED_INT , 10 , 10 , 10 , 2 )
# define DECLARE_FORMATS \
DECLARE_FORMAT ( GL_RGB , 3 ) \
DECLARE_FORMAT ( GL_BGR , 3 ) \
DECLARE_FORMAT ( GL_RGBA , 4 ) \
DECLARE_FORMAT ( GL_BGRA , 4 ) \
DECLARE_FORMAT ( GL_ABGR , 4 ) \
DECLARE_FORMAT ( GL_ARGB_SCE , 4 ) \
DECLARE_FORMAT ( GL_RED , 1 ) \
DECLARE_FORMAT ( GL_GREEN , 1 ) \
DECLARE_FORMAT ( GL_BLUE , 1 ) \
DECLARE_FORMAT ( GL_ALPHA , 1 )
# define jsMATRIX_SIZEf (sizeof(GLfloat)*ELEMENTS_IN_MATRIX)
enum
{
M10 = 1 , M20 , M30 ,
M01 , M11 , M21 , M31 ,
M02 , M12 , M22 , M32 ,
M03 , M13 , M23 , M33
} ;
static int _RGLInitCompleted = 0 ;
static char * _RGLVendorString = " Retro Arch " ;
static char * _RGLRendererString = " RGL " ;
static char * _RGLExtensionsString = " " ;
static char * _RGLVersionNumber = " 1.0 " ;
PSGLcontext * _CurrentContext = NULL ;
RGLcontextHookFunction _RGLContextCreateHook = NULL ;
RGLcontextHookFunction _RGLContextDestroyHook = NULL ;
GmmAllocator * pGmmLocalAllocator = NULL ;
GmmAllocator * pGmmMainAllocator = NULL ;
static volatile uint32_t * pLock = NULL ;
static uint32_t cachedLockValue = 0 ;
static GmmFixedAllocData * pGmmFixedAllocData = NULL ;
GLuint nvFenceCounter = 0 ;
static const unsigned int capacityIncr = 16 ;
static const int NAME_INCREMENT = 4 ;
# define DECLARE_TYPE(TYPE,CTYPE,MAXVAL) \
typedef CTYPE type_ # # TYPE ; \
static inline type_ # # TYPE _RGLFloatTo_ # # TYPE ( float v ) { return ( type_ # # TYPE ) ( _RGLClampf ( v ) * MAXVAL ) ; } \
static inline float _RGLFloatFrom_ # # TYPE ( type_ # # TYPE v ) { return ( ( float ) v ) / MAXVAL ; }
DECLARE_C_TYPES
# undef DECLARE_TYPE
typedef GLfloat type_GL_FLOAT ;
static inline type_GL_FLOAT _RGLFloatTo_GL_FLOAT ( float v ) { return v ; }
static inline float _RGLFloatFrom_GL_FLOAT ( type_GL_FLOAT v ) { return v ; }
typedef GLhalfARB type_GL_HALF_FLOAT_ARB ;
static const char * _getStringTable ( const Elf32_Ehdr * ehdr )
{
const char * sectionHeaderStart = ( const char * ) ehdr + ehdr - > e_shoff ;
const Elf32_Shdr * shstrtabHeader = ( const Elf32_Shdr * ) sectionHeaderStart + ehdr - > e_shstrndx ;
return ( const char * ) ehdr + shstrtabHeader - > sh_offset ;
}
const char * findSectionInPlace ( const char * memory , unsigned int /*size*/ , const char * name , size_t * sectionSize )
{
const Elf32_Ehdr * ehdr = ( const Elf32_Ehdr * ) memory ;
const char * shstrtab = _getStringTable ( ehdr ) ;
size_t sectionCount = ehdr - > e_shnum ;
const char * sectionHeaderStart = ( const char * ) ehdr + ehdr - > e_shoff ;
for ( size_t i = 0 ; i < sectionCount ; i + + )
{
const Elf32_Shdr * sectionHeader = ( const Elf32_Shdr * ) sectionHeaderStart + i ;
const char * sectionName = shstrtab + sectionHeader - > sh_name ;
if ( ! strcmp ( name , sectionName ) )
{
* sectionSize = sectionHeader - > sh_size ;
return ( const char * ) ehdr + sectionHeader - > sh_offset ;
}
}
return NULL ;
}
const char * findSymbolSectionInPlace ( const char * memory , unsigned int /*size*/ , size_t * symbolSize , size_t * symbolCount , const char * * symbolstrtab )
{
const Elf32_Ehdr * ehdr = ( const Elf32_Ehdr * ) memory ;
size_t sectionCount = ehdr - > e_shnum ;
const char * sectionHeaderStart = ( const char * ) ehdr + ehdr - > e_shoff ;
for ( size_t i = 0 ; i < sectionCount ; i + + )
{
const Elf32_Shdr * sectionHeader = ( const Elf32_Shdr * ) sectionHeaderStart + i ;
if ( sectionHeader - > sh_type = = SHT_SYMTAB )
{
* symbolSize = sectionHeader - > sh_entsize ;
* symbolCount = sectionHeader - > sh_size / sectionHeader - > sh_entsize ;
const Elf32_Shdr * symbolStrHeader = ( const Elf32_Shdr * ) sectionHeaderStart + sectionHeader - > sh_link ;
* symbolstrtab = ( const char * ) ehdr + symbolStrHeader - > sh_offset ;
return ( const char * ) ehdr + sectionHeader - > sh_offset ;
}
}
return NULL ;
}
int lookupSymbolValueInPlace ( const char * symbolSection , size_t symbolSize , size_t symbolCount , const char * symbolstrtab , const char * name )
{
for ( size_t i = 0 ; i < symbolCount ; i + + )
{
Elf32_Sym * elf_sym = ( Elf32_Sym * ) symbolSection ;
if ( ! strcmp ( symbolstrtab + elf_sym - > st_name , name ) )
{
return elf_sym - > st_value ;
}
symbolSection + = symbolSize ;
}
return - 1 ;
}
const char * getSymbolByIndexInPlace ( const char * symbolSection , size_t symbolSize , size_t symbolCount , const char * symbolstrtab , int index )
{
Elf32_Sym * elf_sym = ( Elf32_Sym * ) symbolSection + index ;
return symbolstrtab + elf_sym - > st_name ;
}
static inline type_GL_HALF_FLOAT_ARB _RGLFloatTo_GL_HALF_FLOAT_ARB ( float x )
{
jsIntAndFloat V = { f : x } ;
unsigned int S = ( V . i > > 31 ) & 1 ;
int E = ( ( V . i > > 23 ) & 0xff ) - 0x7f ;
unsigned int M = V . i & 0x007fffff ;
if ( ( E = = 0x80 ) & & ( M ) ) return 0x7fff ;
else if ( E > = 15 ) return ( S < < 15 ) | 0x7c00 ;
else if ( E < = - 14 ) return ( S < < 15 ) | ( ( 0x800000 + M ) > > ( - 14 - E ) ) ;
else return ( S < < 15 ) | ( ( ( E + 15 ) & 0x1f ) < < 10 ) | ( M > > 13 ) ;
}
static inline float _RGLFloatFrom_GL_HALF_FLOAT_ARB ( type_GL_HALF_FLOAT_ARB x )
{
unsigned int S = x > > 15 ;
unsigned int E = ( x & 0x7C00 ) > > 10 ;
unsigned int M = x & 0x03ff ;
float f ;
if ( E = = 31 )
{
if ( M = = 0 ) f = _RGLInfinity . f ;
else f = _RGLNan . f ;
}
else if ( E = = 0 )
{
if ( M = = 0 ) f = 0.f ;
else f = M * 1.f / ( 1 < < 24 ) ;
}
else f = ( 0x400 + M ) * 1.f / ( 1 < < 25 ) * ( 1 < < E ) ;
return S ? - f : f ;
}
# define DECLARE_PACKED_TYPE_AND_REV_2(REALTYPE,S1,S2) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S1 # # _ # # S2 , 2 , S1 , S2 , 0 , 0 , ) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S2 # # _ # # S1 # # _REV , 2 , S2 , S1 , 0 , 0 , _REV )
# define DECLARE_PACKED_TYPE_AND_REV_3(REALTYPE,S1,S2,S3) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S1 # # _ # # S2 # # _ # # S3 , 3 , S1 , S2 , S3 , 0 , ) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S3 # # _ # # S2 # # _ # # S1 # # _REV , 3 , S3 , S2 , S1 , 0 , _REV )
# define DECLARE_PACKED_TYPE_AND_REV_4(REALTYPE,S1,S2,S3,S4) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S1 # # _ # # S2 # # _ # # S3 # # _ # # S4 , 4 , S1 , S2 , S3 , S4 , ) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , GL_ # # REALTYPE # # _ # # S4 # # _ # # S3 # # _ # # S2 # # _ # # S1 # # _REV , 4 , S4 , S3 , S2 , S1 , _REV )
# define DECLARE_PACKED_TYPE_AND_REALTYPE(REALTYPE,N,S1,S2,S3,S4,REV) \
DECLARE_PACKED_TYPE ( GL_ # # REALTYPE , PACKED_TYPE ( REALTYPE , N , S1 , S2 , S3 , S4 , REV ) , N , S1 , S2 , S3 , S4 , REV )
# define INDEX(N,X) (X)
# define INDEX_REV(N,X) (N-1-X)
# define GET_BITS(to,from,first,count) if ((count)>0) to=((GLfloat)(((from)>>(first))&((1<<(count))-1))) / (GLfloat)((1<<((count==0)?1:count))-1)
# define PUT_BITS(from,to,first,count) if ((count)>0) to|=((unsigned int)((from)*((GLfloat)((1<<((count==0)?1:count))-1))))<<(first);
static inline void _RGLFifoGlVertexAttribPointer
(
GLuint index ,
GLint size ,
RGLEnum type ,
GLboolean normalized ,
GLsizei stride ,
GLushort frequency ,
GLboolean isMain ,
GLuint offset
)
{
switch ( size )
{
case 0 :
stride = 0 ;
normalized = 0 ;
type = RGL_FLOAT ;
offset = 0 ;
break ;
case 1 :
case 2 :
case 3 :
case 4 :
break ;
default :
break ;
}
uint8_t gcmType = 0 ;
switch ( type )
{
case RGL_UNSIGNED_BYTE :
if ( normalized )
gcmType = CELL_GCM_VERTEX_UB ;
else
gcmType = CELL_GCM_VERTEX_UB256 ;
break ;
case RGL_SHORT :
gcmType = normalized ? CELL_GCM_VERTEX_S1 : CELL_GCM_VERTEX_S32K ;
break ;
case RGL_FLOAT :
gcmType = CELL_GCM_VERTEX_F ;
break ;
case RGL_HALF_FLOAT :
gcmType = CELL_GCM_VERTEX_SF ;
break ;
case RGL_CMP :
size = 1 ;
gcmType = CELL_GCM_VERTEX_CMP ;
break ;
default :
break ;
}
uint8_t location = CELL_GCM_LOCATION_LOCAL ;
if ( isMain )
location = CELL_GCM_LOCATION_MAIN ;
cellGcmSetVertexDataArrayInline ( & _RGLState . fifo , index , frequency , stride , size , gcmType , location , offset ) ;
}
static void _RGLResetAttributeState ( jsAttributeState * as )
{
for ( int i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
as - > attrib [ i ] . clientSize = 4 ;
as - > attrib [ i ] . clientType = GL_FLOAT ;
as - > attrib [ i ] . clientStride = 16 ;
as - > attrib [ i ] . clientData = NULL ;
as - > attrib [ i ] . value [ 0 ] = 0.0f ;
as - > attrib [ i ] . value [ 1 ] = 0.0f ;
as - > attrib [ i ] . value [ 2 ] = 0.0f ;
as - > attrib [ i ] . value [ 3 ] = 1.0f ;
as - > attrib [ i ] . normalized = GL_FALSE ;
as - > attrib [ i ] . frequency = 1 ;
as - > attrib [ i ] . arrayBuffer = 0 ;
}
as - > attrib [ _RGL_ATTRIB_PRIMARY_COLOR_INDEX ] . value [ 0 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_PRIMARY_COLOR_INDEX ] . value [ 1 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_PRIMARY_COLOR_INDEX ] . value [ 2 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_PRIMARY_COLOR_INDEX ] . value [ 3 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_SECONDARY_COLOR_INDEX ] . value [ 0 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_SECONDARY_COLOR_INDEX ] . value [ 1 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_SECONDARY_COLOR_INDEX ] . value [ 2 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_SECONDARY_COLOR_INDEX ] . value [ 3 ] = 1.0f ;
as - > attrib [ _RGL_ATTRIB_NORMAL_INDEX ] . value [ 0 ] = 0.f ;
as - > attrib [ _RGL_ATTRIB_NORMAL_INDEX ] . value [ 1 ] = 0.f ;
as - > attrib [ _RGL_ATTRIB_NORMAL_INDEX ] . value [ 2 ] = 1.f ;
as - > DirtyMask = ( 1 < < _RGL_MAX_VERTEX_ATTRIBS ) - 1 ;
as - > EnabledMask = 0 ;
as - > NeedsConversionMask = 0 ;
as - > HasVBOMask = 0 ;
as - > ModuloMask = 0 ;
}
static jsAttribSet * _RGLCreateAttribSet ( void )
{
jsAttribSet * attribSet = ( jsAttribSet * ) memalign ( 16 , sizeof ( jsAttribSet ) ) ;
_RGLResetAttributeState ( & attribSet - > attribs ) ;
attribSet - > dirty = GL_TRUE ;
attribSet - > beenUpdatedMask = 0 ;
attribSet - > cmdBuffer = NULL ;
attribSet - > cmdNumWords = 0 ;
return attribSet ;
}
static void _RGLDestroyAttribSet ( jsAttribSet * attribSet )
{
if ( attribSet - > cmdBuffer )
free ( attribSet - > cmdBuffer ) ;
free ( attribSet ) ;
}
static inline jsBufferObject * _RGLGetBufferObject ( PSGLcontext * LContext , GLuint name )
{
return ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ name ] ;
}
static void _RGLAttribSetDeleteBuffer ( PSGLcontext * LContext , GLuint buffName )
{
jsBufferObject * bufferObject = _RGLGetBufferObject ( LContext , buffName ) ;
GLuint attrSetCount = bufferObject - > attribSets . getCount ( ) ;
if ( attrSetCount = = 0 ) return ;
for ( unsigned int i = 0 ; i < attrSetCount ; + + i )
{
jsAttribSet * attribSet = bufferObject - > attribSets [ i ] ;
for ( GLuint j = 0 ; j < _RGL_MAX_VERTEX_ATTRIBS ; + + j )
if ( attribSet - > attribs . attrib [ j ] . arrayBuffer = = buffName )
attribSet - > attribs . attrib [ j ] . arrayBuffer = 0 ;
attribSet - > dirty = GL_TRUE ;
}
LContext - > attribSetDirty = GL_TRUE ;
bufferObject - > attribSets . clear ( ) ;
}
static inline jsAttribSet * _RGLGetAttribSet ( GLuint name )
{
PSGLcontext * LContext = _CurrentContext ;
return ( jsAttribSet * ) LContext - > attribSetNameSpace . data [ name ] ;
}
static void _RGLAttribSetMarkDirty ( void )
{
PSGLcontext * LContext = _CurrentContext ;
jsAttribSet * attribSet = _RGLGetAttribSet ( LContext - > attribSetName ) ;
attribSet - > dirty = GL_TRUE ;
LContext - > attribSetDirty = GL_TRUE ;
}
static jsBufferObject * _RGLCreateBufferObject ( void )
{
GLuint size = sizeof ( jsBufferObject ) + sizeof ( RGLBufferObject ) ;
jsBufferObject * buffer = ( jsBufferObject * ) malloc ( size ) ;
if ( ! buffer )
return NULL ;
memset ( buffer , 0 , size ) ;
buffer - > refCount = 1 ;
new ( & buffer - > textureReferences ) RGL : : Vector < jsTexture * > ( ) ;
new ( & buffer - > attribSets ) RGL : : Vector < jsAttribSet * > ( ) ;
return buffer ;
}
static void _RGLPlatformDestroyBufferObject ( jsBufferObject * bufferObject )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
switch ( jsBuffer - > pool )
{
case _RGL_SURFACE_POOL_SYSTEM :
case _RGL_SURFACE_POOL_LINEAR :
gmmFree ( jsBuffer - > bufferId ) ;
break ;
case _RGL_SURFACE_POOL_NONE :
break ;
default :
break ;
}
jsBuffer - > pool = _RGL_SURFACE_POOL_NONE ;
jsBuffer - > bufferId = GMM_ERROR ;
}
static void _RGLFreeBufferObject ( jsBufferObject * buffer )
{
if ( - - buffer - > refCount = = 0 )
{
_RGLPlatformDestroyBufferObject ( buffer ) ;
buffer - > textureReferences . ~ Vector < jsTexture * > ( ) ;
buffer - > attribSets . ~ Vector < jsAttribSet * > ( ) ;
if ( buffer ! = NULL )
free ( buffer ) ;
}
}
static void _RGLUnbindBufferObject ( PSGLcontext * LContext , GLuint name )
{
if ( LContext - > ArrayBuffer = = name ) LContext - > ArrayBuffer = 0 ;
if ( LContext - > PixelUnpackBuffer = = name ) LContext - > PixelUnpackBuffer = 0 ;
for ( int i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
if ( LContext - > attribs - > attrib [ i ] . arrayBuffer = = name )
{
LContext - > attribs - > attrib [ i ] . arrayBuffer = 0 ;
LContext - > attribs - > HasVBOMask & = ~ ( 1 < < i ) ;
}
}
_RGLAttribSetDeleteBuffer ( LContext , name ) ;
}
GLAPI void APIENTRY glBindBuffer ( GLenum target , GLuint name )
{
PSGLcontext * LContext = _CurrentContext ;
if ( name ) _RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
switch ( target )
{
case GL_ARRAY_BUFFER : LContext - > ArrayBuffer = name ;
break ;
case GL_ELEMENT_ARRAY_BUFFER :
break ;
case GL_PIXEL_PACK_BUFFER_ARB :
break ;
case GL_PIXEL_UNPACK_BUFFER_ARB :
LContext - > PixelUnpackBuffer = name ;
break ;
case GL_TEXTURE_REFERENCE_BUFFER_SCE :
LContext - > TextureBuffer = name ;
break ;
default :
break ;
}
}
GLAPI void APIENTRY glDeleteBuffers ( GLsizei n , const GLuint * buffers )
{
PSGLcontext * LContext = _CurrentContext ;
for ( int i = 0 ; i < n ; + + i )
{
if ( ! _RGLTexNameSpaceIsName ( & LContext - > bufferObjectNameSpace , buffers [ i ] ) )
continue ;
if ( buffers [ i ] )
_RGLUnbindBufferObject ( LContext , buffers [ i ] ) ;
}
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , n , buffers ) ;
}
GLAPI void APIENTRY glGenBuffers ( GLsizei n , GLuint * buffers )
{
PSGLcontext * LContext = _CurrentContext ;
_RGLTexNameSpaceGenNames ( & LContext - > bufferObjectNameSpace , n , buffers ) ;
}
static inline jsFramebuffer * _RGLGetFramebuffer ( PSGLcontext * LContext , GLuint name )
{
return ( jsFramebuffer * ) LContext - > framebufferNameSpace . data [ name ] ;
}
static inline void _RGLTextureTouchFBOs ( jsTexture * texture )
{
PSGLcontext * LContext = _CurrentContext ;
if ( ! LContext ) return ;
GLuint fbCount = texture - > framebuffers . getCount ( ) ;
if ( fbCount > 0 )
{
jsFramebuffer * contextFramebuffer = LContext - > framebuffer ? _RGLGetFramebuffer ( LContext , LContext - > framebuffer ) : NULL ;
for ( GLuint i = 0 ; i < fbCount ; + + i )
{
jsFramebuffer * framebuffer = texture - > framebuffers [ i ] ;
framebuffer - > needValidate = GL_TRUE ;
if ( RGL_UNLIKELY ( framebuffer = = contextFramebuffer ) ) LContext - > needValidate | = PSGL_VALIDATE_FRAMEBUFFER ;
}
}
}
static void _RGLAllocateBuffer ( jsBufferObject * bufferObject )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
_RGLPlatformDestroyBufferObject ( bufferObject ) ;
jsBuffer - > pool = _RGL_SURFACE_POOL_LINEAR ;
jsBuffer - > bufferId = gmmAlloc ( 0 , jsBuffer - > bufferSize ) ;
jsBuffer - > pitch = 0 ;
if ( jsBuffer - > bufferId = = GMM_ERROR )
jsBuffer - > pool = _RGL_SURFACE_POOL_NONE ;
GLuint referenceCount = bufferObject - > textureReferences . getCount ( ) ;
if ( referenceCount > 0 )
{
for ( GLuint i = 0 ; i < referenceCount ; + + i )
{
jsTexture * texture = bufferObject - > textureReferences [ i ] ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
gcmTexture - > gpuAddressId = jsBuffer - > bufferId ;
gcmTexture - > gpuAddressIdOffset = texture - > offset ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_PARAMETERS ;
_RGLTextureTouchFBOs ( texture ) ;
}
_CurrentContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
}
static void _RGLMemcpy ( const GLuint dstId , unsigned dstOffset , unsigned int pitch , const GLuint srcId , unsigned int size )
{
pitch = pitch ? : 64 ;
const GLuint dstOffsetAlign = dstOffset % pitch ;
GLuint srcOffset = 0 ;
if ( dstOffsetAlign )
{
const GLuint firstBytes = MIN ( pitch - dstOffsetAlign , size ) ;
_RGLTransferDataVidToVid (
dstId ,
0 ,
pitch ,
dstOffsetAlign / 2 , dstOffset / pitch ,
srcId ,
srcOffset ,
pitch ,
0 , 0 ,
firstBytes / 2 , 1 ,
2 ) ;
dstOffset + = firstBytes ;
srcOffset + = firstBytes ;
size - = firstBytes ;
}
const GLuint fullLines = size / pitch ;
const GLuint extraBytes = size % pitch ;
if ( fullLines )
_RGLTransferDataVidToVid (
dstId ,
0 ,
pitch ,
0 , dstOffset / pitch ,
srcId ,
srcOffset ,
pitch ,
0 , 0 ,
pitch / 2 , fullLines ,
2 ) ;
if ( extraBytes )
_RGLTransferDataVidToVid (
dstId ,
0 ,
pitch ,
0 , fullLines + dstOffset / pitch ,
srcId ,
srcOffset ,
pitch ,
0 , fullLines ,
extraBytes / 2 , 1 ,
2 ) ;
}
static void _RGLPlatformBufferObjectSetData ( jsBufferObject * bufferObject , GLintptr offset , GLsizeiptr size , const GLvoid * data , GLboolean tryImmediateCopy )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
if ( size = = bufferObject - > size & & tryImmediateCopy )
memcpy ( gmmIdToAddress ( jsBuffer - > bufferId ) + offset , data , size ) ;
else
if ( size > = bufferObject - > size )
{
jsBuffer - > bufferSize = _RGLPad ( size , _RGL_BUFFER_OBJECT_BLOCK_SIZE ) ;
_RGLAllocateBuffer ( bufferObject ) ;
switch ( jsBuffer - > pool )
{
case _RGL_SURFACE_POOL_NONE :
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
return ;
default :
memcpy ( gmmIdToAddress ( jsBuffer - > bufferId ) , data , size ) ;
break ;
}
}
else
{
if ( tryImmediateCopy )
memcpy ( gmmIdToAddress ( jsBuffer - > bufferId ) + offset , data , size ) ;
else
{
unsigned int dstId = jsBuffer - > bufferId ;
unsigned int pitch = jsBuffer - > pitch ;
const char * src = ( const char * ) data ;
switch ( bufferObject - > usage )
{
case GL_STREAM_DRAW :
case GL_STREAM_READ :
case GL_STREAM_COPY :
case GL_DYNAMIC_DRAW :
case GL_DYNAMIC_READ :
case GL_DYNAMIC_COPY :
{
GLuint id = gmmAlloc ( 0 , size ) ;
memcpy ( gmmIdToAddress ( id ) , src , size ) ;
_RGLMemcpy ( dstId , offset , pitch , id , size ) ;
gmmFree ( id ) ;
}
break ;
default :
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
memcpy ( gmmIdToAddress ( dstId ) + offset , src , size ) ;
break ;
} ;
}
}
( ( RGLDriver * ) _CurrentDevice - > rasterDriver ) - > invalidateVertexCache = GL_TRUE ;
}
static GLboolean _RGLPlatformCreateBufferObject ( jsBufferObject * bufferObject )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
jsBuffer - > pool = _RGL_SURFACE_POOL_NONE ;
jsBuffer - > bufferId = GMM_ERROR ;
jsBuffer - > mapCount = 0 ;
jsBuffer - > mapAccess = GL_NONE ;
jsBuffer - > bufferSize = _RGLPad ( bufferObject - > size , _RGL_BUFFER_OBJECT_BLOCK_SIZE ) ;
_RGLAllocateBuffer ( bufferObject ) ;
return jsBuffer - > bufferId ! = GMM_ERROR ;
}
GLAPI void APIENTRY glBufferData ( GLenum target , GLsizeiptr size , const GLvoid * data , GLenum usage )
{
PSGLcontext * LContext = _CurrentContext ;
GLuint name = 0 ;
switch ( target )
{
case GL_ARRAY_BUFFER :
name = LContext - > ArrayBuffer ;
break ;
case GL_ELEMENT_ARRAY_BUFFER :
break ;
case GL_PIXEL_PACK_BUFFER_ARB :
break ;
case GL_PIXEL_UNPACK_BUFFER_ARB :
name = LContext - > PixelUnpackBuffer ;
break ;
case GL_TEXTURE_REFERENCE_BUFFER_SCE :
name = LContext - > TextureBuffer ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
jsBufferObject * bufferObject = _RGLGetBufferObject ( LContext , name ) ;
if ( bufferObject - > refCount > 1 )
{
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , 1 , & name ) ;
_RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
bufferObject = _RGLGetBufferObject ( LContext , name ) ;
}
if ( bufferObject - > size > 0 ) _RGLPlatformDestroyBufferObject ( bufferObject ) ;
bufferObject - > usage = usage ;
bufferObject - > size = size ;
bufferObject - > width = 0 ;
bufferObject - > height = 0 ;
bufferObject - > internalFormat = GL_NONE ;
if ( size > 0 )
{
GLboolean created = _RGLPlatformCreateBufferObject ( bufferObject ) ;
if ( ! created )
{
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
return ;
}
if ( data )
_RGLPlatformBufferObjectSetData ( bufferObject , 0 , size , data , GL_TRUE ) ;
}
GLuint attrSetCount = bufferObject - > attribSets . getCount ( ) ;
if ( attrSetCount = = 0 )
return ;
for ( unsigned int i = 0 ; i < attrSetCount ; + + i )
{
jsAttribSet * attribSet = bufferObject - > attribSets [ i ] ;
attribSet - > dirty = GL_TRUE ;
}
LContext - > attribSetDirty = GL_TRUE ;
}
static GLvoid _RGLPlatformBufferObjectCopyData ( jsBufferObject * bufferObjectDst ,
jsBufferObject * bufferObjectSrc )
{
RGLBufferObject * dst = ( RGLBufferObject * ) bufferObjectDst - > platformBufferObject ;
RGLBufferObject * src = ( RGLBufferObject * ) bufferObjectSrc - > platformBufferObject ;
switch ( dst - > pool )
{
case _RGL_SURFACE_POOL_LINEAR :
_RGLMemcpy ( dst - > bufferId , 0 , dst - > pitch , src - > bufferId , src - > bufferSize ) ;
break ;
case _RGL_SURFACE_POOL_SYSTEM :
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
memcpy ( gmmIdToAddress ( dst - > bufferId ) , gmmIdToAddress ( src - > bufferId ) ,
src - > bufferSize ) ;
break ;
}
( ( RGLDriver * ) _CurrentDevice - > rasterDriver ) - > invalidateVertexCache = GL_TRUE ;
}
GLAPI void APIENTRY glBufferSubData ( GLenum target , GLintptr offset , GLsizeiptr size , const GLvoid * data )
{
PSGLcontext * LContext = _CurrentContext ;
GLuint name = 0 ;
switch ( target )
{
case GL_ARRAY_BUFFER :
name = LContext - > ArrayBuffer ;
break ;
case GL_ELEMENT_ARRAY_BUFFER :
break ;
case GL_PIXEL_PACK_BUFFER_ARB :
break ;
case GL_PIXEL_UNPACK_BUFFER_ARB :
name = LContext - > PixelUnpackBuffer ;
break ;
case GL_TEXTURE_REFERENCE_BUFFER_SCE :
name = LContext - > TextureBuffer ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
jsBufferObject * bufferObject = _RGLGetBufferObject ( LContext , name ) ;
if ( bufferObject - > refCount > 1 )
{
jsBufferObject * oldBufferObject = bufferObject ;
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , 1 , & name ) ;
_RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
bufferObject = _RGLGetBufferObject ( LContext , name ) ;
bufferObject - > size = oldBufferObject - > size ;
bufferObject - > usage = oldBufferObject - > usage ;
GLboolean created = _RGLPlatformCreateBufferObject ( bufferObject ) ;
if ( ! created )
{
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
return ;
}
_RGLPlatformBufferObjectCopyData ( bufferObject , oldBufferObject ) ;
}
_RGLPlatformBufferObjectSetData ( bufferObject , offset , size , data , GL_FALSE ) ;
}
static inline jsTexture * _RGLGetTexture ( PSGLcontext * LContext , GLuint name )
{
return ( jsTexture * ) LContext - > textureNameSpace . data [ name ] ;
}
static inline jsTexture * _RGLGetTextureSafe ( PSGLcontext * LContext , GLuint name )
{
return _RGLTexNameSpaceIsName ( & LContext - > textureNameSpace , name ) ? ( jsTexture * ) LContext - > textureNameSpace . data [ name ] : NULL ;
}
static void _RGLFramebufferGetAttachmentTexture (
const jsFramebufferAttachment * attachment ,
jsTexture * * texture ,
GLuint * face )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( attachment - > type )
{
case _RGL_FRAMEBUFFER_ATTACHMENT_NONE :
* texture = NULL ;
* face = 0 ;
break ;
case _RGL_FRAMEBUFFER_ATTACHMENT_RENDERBUFFER :
break ;
case _RGL_FRAMEBUFFER_ATTACHMENT_TEXTURE :
* texture = _RGLGetTextureSafe ( LContext , attachment - > name ) ;
* face = 0 ;
break ;
default :
* face = 0 ;
* texture = NULL ;
break ;
}
}
static GLboolean _RGLTextureIsValid ( const jsTexture * texture )
{
if ( texture - > imageCount < 1 )
return GL_FALSE ;
if ( ! texture - > image )
return GL_FALSE ;
const jsImage * image = texture - > image ;
int width = image - > width ;
int height = image - > height ;
GLenum format = image - > format ;
GLenum type = image - > type ;
GLenum internalFormat = image - > internalFormat ;
if ( ( internalFormat = = 0 ) | | ( format = = 0 ) | | ( type = = 0 ) )
return GL_FALSE ;
if ( ! image - > isSet )
return GL_FALSE ;
if ( width ! = image - > width )
return GL_FALSE ;
if ( height ! = image - > height )
return GL_FALSE ;
if ( format ! = image - > format )
return GL_FALSE ;
if ( type ! = image - > type )
return GL_FALSE ;
if ( internalFormat ! = image - > internalFormat )
return GL_FALSE ;
return GL_TRUE ;
}
static GLenum _RGLPlatformFramebufferCheckStatus ( jsFramebuffer * framebuffer )
{
GLuint nBuffers = 0 ;
jsImage * image [ _RGL_MAX_COLOR_ATTACHMENTS + 2 ] = { 0 } ;
GLuint colorFormat = 0 ;
for ( int i = 0 ; i < _RGL_MAX_COLOR_ATTACHMENTS ; + + i )
{
jsTexture * colorTexture = NULL ;
GLuint colorFace = 0 ;
_RGLFramebufferGetAttachmentTexture ( & framebuffer - > color [ i ] , & colorTexture , & colorFace ) ;
if ( colorTexture ! = NULL )
{
if ( ! _RGLTextureIsValid ( colorTexture ) )
{
printf ( " RGL ERR: Framebuffer color attachment texture is not complete. \n " ) ;
return GL_FRAMEBUFFER_UNSUPPORTED_OES ;
}
image [ nBuffers ] = colorTexture - > image ;
if ( colorFormat & & colorFormat ! = image [ nBuffers ] - > internalFormat )
{
printf ( " RGL ERR: Framebuffer attachments have inconsistent color formats. \n " ) ;
return GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES ;
}
colorFormat = image [ nBuffers ] - > internalFormat ;
+ + nBuffers ;
}
}
if ( nBuffers & & colorFormat ! = RGL_ARGB8 )
{
printf ( " RGL: Color attachment to framebuffer must be a supported drawable format (GL_ARGB_SCE) \n " ) ;
return GL_FRAMEBUFFER_UNSUPPORTED_OES ;
}
if ( nBuffers = = 0 )
return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES ;
for ( GLuint i = 0 ; i < nBuffers ; + + i )
for ( GLuint j = i + 1 ; j < nBuffers ; + + j )
if ( image [ i ] = = image [ j ] )
return GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_OES ;
return GL_FRAMEBUFFER_COMPLETE_OES ;
}
enum _RGLTextureStrategy {
_RGL_TEXTURE_STRATEGY_END ,
_RGL_TEXTURE_STRATEGY_UNTILED_ALLOC ,
_RGL_TEXTURE_STRATEGY_UNTILED_CLEAR ,
} ;
static enum _RGLTextureStrategy linearGPUStrategy [ ] =
{
_RGL_TEXTURE_STRATEGY_UNTILED_ALLOC ,
_RGL_TEXTURE_STRATEGY_UNTILED_CLEAR ,
_RGL_TEXTURE_STRATEGY_UNTILED_ALLOC ,
_RGL_TEXTURE_STRATEGY_END ,
} ;
static void _RGLImageAllocCPUStorage ( jsImage * image )
{
if ( ( image - > storageSize > image - > mallocStorageSize ) | | ( ! image - > mallocData ) )
{
if ( image - > mallocData ) free ( image - > mallocData ) ;
image - > mallocData = ( char * ) malloc ( image - > storageSize + 128 ) ;
image - > mallocStorageSize = image - > storageSize ;
}
image - > data = _RGLPadPtr ( image - > mallocData , 128 ) ;
}
static inline int _RGLGetComponentCount ( GLenum format )
{
switch ( format )
{
# define DECLARE_FORMAT(FORMAT,COUNT) \
case FORMAT : \
return COUNT ;
DECLARE_FORMATS
# undef DECLARE_FORMAT
default :
return 0 ;
}
}
typedef void ( GetComponentsFunction_t ) ( const unsigned char * bytes , GLfloat * values , int count ) ;
typedef void ( PutComponentsFunction_t ) ( unsigned char * bytes , GLfloat * values , int count ) ;
typedef void ( ColorConvertFunction_t ) ( jsColorRGBAf * color , GLfloat * values ) ;
# define DECLARE_UNPACKED_TYPE(TYPE) \
static void _RGLGetComponents_ # # TYPE ( const unsigned char * bytes , GLfloat * values , int count ) \
{ \
int i ; \
for ( i = 0 ; i < count ; + + i ) \
{ \
const type_ # # TYPE data = * ( const type_ # # TYPE * ) bytes ; \
values [ i ] = _RGLFloatFrom_ # # TYPE ( data ) ; \
bytes + = sizeof ( type_ # # TYPE ) ; \
} \
}
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
static void _RGLGetComponents_ # # TYPE ( const unsigned char * bytes , GLfloat * values , int count ) \
{ \
const type_ # # REALTYPE data = * ( const type_ # # REALTYPE * ) bytes ; \
GET_BITS ( values [ INDEX # # REV ( N , 0 ) ] , data , S2 + S3 + S4 , S1 ) ; \
GET_BITS ( values [ INDEX # # REV ( N , 1 ) ] , data , S3 + S4 , S2 ) ; \
GET_BITS ( values [ INDEX # # REV ( N , 2 ) ] , data , S4 , S3 ) ; \
GET_BITS ( values [ INDEX # # REV ( N , 3 ) ] , data , 0 , S4 ) ; \
}
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
# define DECLARE_UNPACKED_TYPE(TYPE) \
static void _RGLPutComponents_ # # TYPE ( unsigned char * bytes , GLfloat * values , int count ) \
{ \
int i ; \
for ( i = 0 ; i < count ; + + i ) \
{ \
type_ # # TYPE * data = ( type_ # # TYPE * ) bytes ; \
* data = _RGLFloatTo_ # # TYPE ( values [ i ] ) ; \
bytes + = sizeof ( type_ # # TYPE ) ; \
} \
}
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
static void _RGLPutComponents_ # # TYPE ( unsigned char * bytes , GLfloat * values , int count ) \
{ \
type_ # # REALTYPE * data = ( type_ # # REALTYPE * ) bytes ; \
* data = 0 ; \
PUT_BITS ( values [ INDEX # # REV ( N , 0 ) ] , * data , S2 + S3 + S4 , S1 ) ; \
PUT_BITS ( values [ INDEX # # REV ( N , 1 ) ] , * data , S3 + S4 , S2 ) ; \
PUT_BITS ( values [ INDEX # # REV ( N , 2 ) ] , * data , S4 , S3 ) ; \
PUT_BITS ( values [ INDEX # # REV ( N , 3 ) ] , * data , 0 , S4 ) ; \
}
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
static inline GetComponentsFunction_t * _RGLFindGetComponentsFunction ( GLenum type )
{
switch ( type )
{
# define DECLARE_UNPACKED_TYPE(TYPE) \
case TYPE : \
return & _RGLGetComponents_ # # TYPE ;
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
case TYPE : \
return & _RGLGetComponents_ # # TYPE ;
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
default :
return NULL ;
}
}
static inline PutComponentsFunction_t * _RGLFindPutComponentsFunction ( GLenum type )
{
switch ( type )
{
# define DECLARE_UNPACKED_TYPE(TYPE) \
case TYPE : \
return & _RGLPutComponents_ # # TYPE ;
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
case TYPE : \
return & _RGLPutComponents_ # # TYPE ;
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
default :
return NULL ;
}
}
static void _RGLValuesToColor_GL_RGB ( jsColorRGBAf * c , GLfloat * v ) { c - > R = v [ 0 ] ; c - > G = v [ 1 ] ; c - > B = v [ 2 ] ; c - > A = 1.f ; }
static void _RGLValuesToColor_GL_BGR ( jsColorRGBAf * c , GLfloat * v ) { c - > B = v [ 0 ] ; c - > G = v [ 1 ] ; c - > R = v [ 2 ] ; c - > A = 1.f ; }
static void _RGLValuesToColor_GL_RGBA ( jsColorRGBAf * c , GLfloat * v ) { c - > R = v [ 0 ] ; c - > G = v [ 1 ] ; c - > B = v [ 2 ] ; c - > A = v [ 3 ] ; }
static void _RGLValuesToColor_GL_BGRA ( jsColorRGBAf * c , GLfloat * v ) { c - > B = v [ 0 ] ; c - > G = v [ 1 ] ; c - > R = v [ 2 ] ; c - > A = v [ 3 ] ; }
static void _RGLValuesToColor_GL_ABGR ( jsColorRGBAf * c , GLfloat * v ) { c - > A = v [ 0 ] ; c - > B = v [ 1 ] ; c - > G = v [ 2 ] ; c - > R = v [ 3 ] ; }
static void _RGLValuesToColor_GL_ARGB_SCE ( jsColorRGBAf * c , GLfloat * v ) { c - > A = v [ 0 ] ; c - > R = v [ 1 ] ; c - > G = v [ 2 ] ; c - > B = v [ 3 ] ; }
static void _RGLValuesToColor_GL_RED ( jsColorRGBAf * c , GLfloat * v ) { c - > R = v [ 0 ] ; c - > G = 0.f ; c - > B = 0.f ; c - > A = 1.f ; }
static void _RGLValuesToColor_GL_GREEN ( jsColorRGBAf * c , GLfloat * v ) { c - > R = 0.f ; c - > G = v [ 0 ] ; c - > B = 0.f ; c - > A = 1.f ; }
static void _RGLValuesToColor_GL_BLUE ( jsColorRGBAf * c , GLfloat * v ) { c - > R = 0.f ; c - > G = 0.f ; c - > B = v [ 0 ] ; c - > A = 1.f ; }
static void _RGLValuesToColor_GL_ALPHA ( jsColorRGBAf * c , GLfloat * v ) { c - > R = 0.f ; c - > G = 0.f ; c - > B = 0.f ; c - > A = v [ 0 ] ; }
static void _RGLColorToValues_GL_RGB ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > R ; v [ 1 ] = c - > G ; v [ 2 ] = c - > B ; }
static void _RGLColorToValues_GL_BGR ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > B ; v [ 1 ] = c - > G ; v [ 2 ] = c - > R ; }
static void _RGLColorToValues_GL_RGBA ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > R ; v [ 1 ] = c - > G ; v [ 2 ] = c - > B ; v [ 3 ] = c - > A ; }
static void _RGLColorToValues_GL_BGRA ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > B ; v [ 1 ] = c - > G ; v [ 2 ] = c - > R ; v [ 3 ] = c - > A ; }
static void _RGLColorToValues_GL_ABGR ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > A ; v [ 1 ] = c - > B ; v [ 2 ] = c - > G ; v [ 3 ] = c - > R ; }
static void _RGLColorToValues_GL_ARGB_SCE ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > A ; v [ 1 ] = c - > R ; v [ 2 ] = c - > G ; v [ 3 ] = c - > B ; }
static void _RGLColorToValues_GL_RED ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > R ; }
static void _RGLColorToValues_GL_GREEN ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > G ; }
static void _RGLColorToValues_GL_BLUE ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > B ; }
static void _RGLColorToValues_GL_ALPHA ( jsColorRGBAf * c , GLfloat * v ) { v [ 0 ] = c - > A ; }
static inline ColorConvertFunction_t * _RGLFindValuesToColorFunction ( GLenum format )
{
switch ( format )
{
# define DECLARE_FORMAT(FORMAT,COUNT) \
case FORMAT : \
return & _RGLValuesToColor_ # # FORMAT ;
DECLARE_FORMATS
# undef DECLARE_FORMAT
default :
return NULL ;
}
}
static inline ColorConvertFunction_t * _RGLFindColorToValuesFunction ( GLenum format )
{
switch ( format )
{
# define DECLARE_FORMAT(FORMAT,COUNT) \
case FORMAT : \
return & _RGLColorToValues_ # # FORMAT ;
DECLARE_FORMATS
# undef DECLARE_FORMAT
default :
return NULL ;
}
}
static void _RGLRasterToImage ( const jsRaster * raster , jsImage * image )
{
const int srcComponents = _RGLGetComponentCount ( raster - > format ) ;
const int dstComponents = _RGLGetComponentCount ( image - > format ) ;
GetComponentsFunction_t * getComponents = _RGLFindGetComponentsFunction ( raster - > type ) ;
PutComponentsFunction_t * putComponents = _RGLFindPutComponentsFunction ( image - > type ) ;
ColorConvertFunction_t * valuesToColor = _RGLFindValuesToColorFunction ( raster - > format ) ;
ColorConvertFunction_t * colorToValues = _RGLFindColorToValuesFunction ( image - > format ) ;
for ( int j = 0 ; j < raster - > height ; + + j )
{
const unsigned char * src = ( const unsigned char * ) raster - > data +
j * raster - > ystride ;
unsigned char * dst = ( unsigned char * ) image - > data +
( j ) * image - > ystride +
0 * image - > xstride ;
for ( int k = 0 ; k < raster - > width ; + + k )
{
GLfloat values [ 4 ] ;
jsColorRGBAf color ;
getComponents ( src , values , srcComponents ) ;
valuesToColor ( & color , values ) ;
colorToValues ( & color , values ) ;
if ( image - > type ! = GL_FLOAT & & image - > type ! = GL_HALF_FLOAT_ARB )
{
values [ 0 ] = MAX ( MIN ( values [ 0 ] , 1.f ) , 0.f ) ;
values [ 1 ] = MAX ( MIN ( values [ 1 ] , 1.f ) , 0.f ) ;
values [ 2 ] = MAX ( MIN ( values [ 2 ] , 1.f ) , 0.f ) ;
values [ 3 ] = MAX ( MIN ( values [ 3 ] , 1.f ) , 0.f ) ;
}
putComponents ( dst , values , dstComponents ) ;
src + = raster - > xstride ;
dst + = image - > xstride ;
}
}
}
static void _RGLPlatformCopyGPUTexture ( jsTexture * texture )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
if ( gcmTexture - > gpuAddressId = = GMM_ERROR )
return ;
RGLTextureLayout * layout = & gcmTexture - > gpuLayout ;
jsImage * image = texture - > image ;
if ( image - > dataState = = _RGL_IMAGE_DATASTATE_GPU )
{
_RGLImageAllocCPUStorage ( image ) ;
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
char * gpuData = gmmIdToAddress ( gcmTexture - > gpuAddressId ) + gcmTexture - > gpuAddressIdOffset ;
jsRaster raster =
{
format : image - > format ,
type : image - > type ,
width : image - > width ,
height : image - > height ,
xstride : image - > xstride ,
ystride : layout - > pitch ,
data : gpuData
} ;
_RGLRasterToImage ( & raster , image ) ;
image - > dataState = _RGL_IMAGE_DATASTATE_HOST ;
}
}
static void _RGLPlatformFreeGcmTexture ( jsTexture * texture )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
switch ( gcmTexture - > pool )
{
case _RGL_SURFACE_POOL_LINEAR :
case _RGL_SURFACE_POOL_SYSTEM :
gmmFree ( gcmTexture - > gpuAddressId ) ;
case _RGL_SURFACE_POOL_NONE :
break ;
default :
break ;
}
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
}
void _RGLPlatformDropTexture ( jsTexture * texture )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
if ( gcmTexture - > pbo ! = NULL )
{
_RGLPlatformCopyGPUTexture ( texture ) ;
_RGLFreeBufferObject ( gcmTexture - > pbo ) ;
gcmTexture - > pbo = NULL ;
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > pool = _RGL_SURFACE_POOL_NONE ;
gcmTexture - > gpuSize = 0 ;
}
if ( gcmTexture - > pool ! = _RGL_SURFACE_POOL_NONE )
{
_RGLPlatformCopyGPUTexture ( texture ) ;
_RGLPlatformFreeGcmTexture ( texture ) ;
}
gcmTexture - > pool = _RGL_SURFACE_POOL_NONE ;
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_IMAGES ;
_RGLTextureTouchFBOs ( texture ) ;
}
int _RGLGetPixelSize ( GLenum format , GLenum type )
{
int componentSize ;
switch ( type )
{
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
case TYPE : \
return sizeof ( type_ # # REALTYPE ) ;
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
# define DECLARE_UNPACKED_TYPE(TYPE) \
case TYPE : \
componentSize = sizeof ( type_ # # TYPE ) ; \
break ;
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
default :
return 0 ;
}
return _RGLGetComponentCount ( format ) * componentSize ;
}
static inline int _RGLGetStorageSize ( GLenum format , GLenum type , GLsizei width , GLsizei height , GLsizei depth )
{
return _RGLGetPixelSize ( format , type ) * width * height * depth ;
}
static void _RGLPlatformChooseGPUFormatAndLayout (
const jsTexture * texture ,
GLboolean forceLinear ,
GLuint pitch ,
RGLTextureLayout * newLayout )
{
jsImage * image = texture - > image ;
newLayout - > baseWidth = image - > width ;
newLayout - > baseHeight = image - > height ;
newLayout - > internalFormat = ( RGLEnum ) image - > internalFormat ;
newLayout - > pixelBits = _RGLPlatformGetBitsPerPixel ( newLayout - > internalFormat ) ;
newLayout - > pitch = pitch ? pitch : _RGLPad ( _RGLGetStorageSize ( texture - > image - > format , texture - > image - > type , texture - > image - > width , 1 , 1 ) , 64 ) ;
}
void _RGLPlatformDropUnboundTextures ( GLenum pool )
{
PSGLcontext * LContext = _CurrentContext ;
GLuint i , j ;
for ( i = 0 ; i < LContext - > textureNameSpace . capacity ; + + i )
{
GLboolean bound = GL_FALSE ;
jsTexture * texture = ( jsTexture * ) LContext - > textureNameSpace . data [ i ] ;
if ( ! texture | | ( texture - > referenceBuffer ! = 0 ) ) continue ;
for ( j = 0 ; j < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + j )
{
if ( LContext - > VertexTextureImages [ j ] = = texture )
{
bound = GL_TRUE ;
break ;
}
}
for ( j = 0 ; j < _RGL_MAX_TEXTURE_IMAGE_UNITS ; + + j )
{
jsTextureImageUnit * tu = LContext - > TextureImageUnits + j ;
if ( tu - > bound2D = = i )
{
bound = GL_TRUE ;
break ;
}
}
if ( bound )
continue ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
if ( gcmTexture - > pbo ! = NULL & & gcmTexture - > pbo - > refCount > 1 )
continue ;
if ( pool ! = _RGL_SURFACE_POOL_NONE & &
pool ! = gcmTexture - > pool )
continue ;
_RGLPlatformDropTexture ( texture ) ;
}
}
static void _RGLPlatformReallocateGcmTexture ( jsTexture * texture )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
enum _RGLTextureStrategy * step = linearGPUStrategy ;
GLuint size = 0 ;
GLuint id = GMM_ERROR ;
const RGLTextureLayout currentLayout = gcmTexture - > gpuLayout ;
const GLuint currentSize = gcmTexture - > gpuSize ;
// process strategy
GLboolean done = GL_FALSE ;
while ( ! done )
{
RGLTextureLayout newLayout ;
switch ( * step + + )
{
case _RGL_TEXTURE_STRATEGY_UNTILED_ALLOC :
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , 0 , & newLayout ) ;
size = _RGLPad ( newLayout . baseHeight * newLayout . pitch , 1 ) ;
if ( gcmTexture - > pool = = _RGL_SURFACE_POOL_LINEAR )
{
if ( currentSize > = size & & newLayout . pitch = = currentLayout . pitch )
{
gcmTexture - > gpuLayout = newLayout ;
done = GL_TRUE ;
}
else
_RGLPlatformDropTexture ( texture ) ;
}
if ( ! done )
{
id = gmmAlloc ( 0 , size ) ;
if ( id ! = GMM_ERROR )
{
if ( gcmTexture - > pool ! = _RGL_SURFACE_POOL_NONE )
_RGLPlatformDropTexture ( texture ) ;
gcmTexture - > pool = _RGL_SURFACE_POOL_LINEAR ;
gcmTexture - > gpuAddressId = id ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = size ;
gcmTexture - > gpuLayout = newLayout ;
done = GL_TRUE ;
}
}
break ;
case _RGL_TEXTURE_STRATEGY_UNTILED_CLEAR :
_RGLPlatformDropUnboundTextures ( _RGL_SURFACE_POOL_LINEAR ) ;
break ;
case _RGL_TEXTURE_STRATEGY_END :
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
done = GL_TRUE ;
break ;
default :
break ;
}
}
_RGLTextureTouchFBOs ( texture ) ;
}
static void _RGLImageFreeCPUStorage ( jsImage * image )
{
if ( ! image - > mallocData ) return ;
if ( image - > mallocData ! = NULL )
free ( image - > mallocData ) ;
image - > mallocStorageSize = 0 ;
image - > data = NULL ;
image - > mallocData = NULL ;
image - > dataState & = ~ _RGL_IMAGE_DATASTATE_HOST ;
}
static void _RGLPlatformValidateTextureResources ( jsTexture * texture )
{
if ( RGL_UNLIKELY ( ! _RGLTextureIsValid ( texture ) ) )
{
texture - > isComplete = GL_FALSE ;
return ;
}
texture - > isComplete = GL_TRUE ;
if ( texture - > revalidate & _RGL_TEXTURE_REVALIDATE_IMAGES | | texture - > revalidate & _RGL_TEXTURE_REVALIDATE_LAYOUT )
{
_RGLPlatformReallocateGcmTexture ( texture ) ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
RGLTextureLayout * layout = & gcmTexture - > gpuLayout ;
const GLuint pixelBytes = layout - > pixelBits / 8 ;
RGLSurface src = {
source : _RGL_SURFACE_SOURCE_TEMPORARY ,
width : 0 ,
height : 0 ,
bpp : pixelBytes ,
pitch : 0 ,
format : layout - > internalFormat ,
pool : _RGL_SURFACE_POOL_LINEAR ,
ppuData : NULL ,
dataId : GMM_ERROR ,
dataIdOffset : 0 ,
} ;
RGLSurface dst = {
source : _RGL_SURFACE_SOURCE_TEXTURE ,
width : 0 ,
height : 0 ,
bpp : pixelBytes ,
pitch : layout - > pitch ,
format : layout - > internalFormat ,
pool : _RGL_SURFACE_POOL_SYSTEM ,
ppuData : NULL ,
dataId : GMM_ERROR ,
dataIdOffset : 0 ,
} ;
GLuint bounceBufferId = GMM_ERROR ;
jsImage * image = texture - > image ;
if ( image - > dataState = = _RGL_IMAGE_DATASTATE_HOST )
{
src . ppuData = image - > data ;
if ( bounceBufferId = = GMM_ERROR )
bounceBufferId = gmmAlloc ( 0 , gcmTexture - > gpuSize ) ;
if ( bounceBufferId ! = GMM_ERROR )
{
src . dataId = bounceBufferId ;
src . dataIdOffset = 0 ;
memcpy ( gmmIdToAddress ( src . dataId ) , image - > data ,
image - > storageSize ) ;
}
src . width = image - > width ;
src . height = image - > height ;
src . pitch = pixelBytes * src . width ;
dst . width = src . width ;
dst . height = image - > height ;
dst . dataId = gcmTexture - > gpuAddressId ;
dst . dataIdOffset = gcmTexture - > gpuAddressIdOffset ;
_RGLTransferDataVidToVid ( dst . dataId , dst . dataIdOffset , dst . pitch ? dst . pitch : ( dst . bpp * dst . width ) , 0 , 0 , src . dataId , src . dataIdOffset , src . pitch ? src . pitch : ( src . bpp * src . width ) , 0 , 0 , src . width , src . height , src . bpp ) ;
_RGLImageFreeCPUStorage ( image ) ;
image - > dataState | = _RGL_IMAGE_DATASTATE_GPU ;
}
if ( bounceBufferId ! = GMM_ERROR )
gmmFree ( bounceBufferId ) ;
cellGcmSetInvalidateTextureCacheInline ( & _RGLState . fifo , CELL_GCM_INVALIDATE_TEXTURE ) ;
}
RGLTexture * platformTexture = ( RGLTexture * ) texture - > platformTexture ;
RGLTextureLayout * layout = & platformTexture - > gpuLayout ;
GLuint minFilter = texture - > minFilter ;
GLuint magFilter = texture - > magFilter ;
platformTexture - > gcmMethods . filter . min = _RGLMapMinTextureFilter ( minFilter ) ;
platformTexture - > gcmMethods . filter . mag = _RGLMapMagTextureFilter ( magFilter ) ;
platformTexture - > gcmMethods . filter . bias = ( GLint ) ( ( - .26f ) * 256.0f ) ;
GLuint gamma = 0 ;
GLuint remap = texture - > gammaRemap ;
gamma | = ( remap & RGL_GAMMA_REMAP_RED_BIT ) ? CELL_GCM_TEXTURE_GAMMA_R : 0 ;
gamma | = ( remap & RGL_GAMMA_REMAP_GREEN_BIT ) ? CELL_GCM_TEXTURE_GAMMA_G : 0 ;
gamma | = ( remap & RGL_GAMMA_REMAP_BLUE_BIT ) ? CELL_GCM_TEXTURE_GAMMA_B : 0 ;
gamma | = ( remap & RGL_GAMMA_REMAP_ALPHA_BIT ) ? CELL_GCM_TEXTURE_GAMMA_A : 0 ;
platformTexture - > gcmMethods . address . gamma = gamma ;
GLuint internalFormat = layout - > internalFormat ;
_RGLMapTextureFormat ( internalFormat ,
platformTexture - > gcmTexture . format , platformTexture - > gcmTexture . remap ) ;
if ( layout - > pitch )
platformTexture - > gcmTexture . format + = 0x20 ;
platformTexture - > gcmTexture . width = layout - > baseWidth ;
platformTexture - > gcmTexture . height = layout - > baseHeight ;
platformTexture - > gcmTexture . depth = 1 ;
platformTexture - > gcmTexture . pitch = layout - > pitch ;
platformTexture - > gcmTexture . mipmap = 1 ;
platformTexture - > gcmTexture . cubemap = CELL_GCM_FALSE ;
platformTexture - > gcmTexture . dimension = CELL_GCM_TEXTURE_DIMENSION_2 ;
if ( gmmIdIsMain ( platformTexture - > gpuAddressId ) )
platformTexture - > gcmTexture . location = CELL_GCM_LOCATION_MAIN ;
else
platformTexture - > gcmTexture . location = CELL_GCM_LOCATION_LOCAL ;
texture - > revalidate = 0 ;
}
static void jsPlatformFramebuffer_validate ( jsPlatformFramebuffer * fb , PSGLcontext * LContext )
{
fb - > complete = ( _RGLPlatformFramebufferCheckStatus ( fb ) = = GL_FRAMEBUFFER_COMPLETE_OES ) ;
if ( ! fb - > complete ) return ;
GLuint width = CELL_GCM_MAX_RT_DIMENSION ;
GLuint height = CELL_GCM_MAX_RT_DIMENSION ;
fb - > rt . colorBufferCount = 0 ;
fb - > rt . colorFormat = RGL_NONE ;
fb - > colorBufferMask = 0x0 ;
GLuint defaultPitch = 0 ;
GLuint defaultId = GMM_ERROR ;
GLuint defaultIdOffset = 0 ;
for ( int i = 0 ; i < RGL_SETRENDERTARGET_MAXCOUNT ; + + i )
{
jsTexture * colorTexture = NULL ;
GLuint face = 0 ;
_RGLFramebufferGetAttachmentTexture ( & fb - > color [ i ] , & colorTexture , & face ) ;
if ( colorTexture = = NULL ) continue ;
RGLTexture * nvTexture = ( RGLTexture * ) colorTexture - > platformTexture ;
if ( ! colorTexture - > isRenderTarget )
{
colorTexture - > isRenderTarget = GL_TRUE ;
colorTexture - > revalidate | = _RGL_TEXTURE_REVALIDATE_LAYOUT ;
}
_RGLPlatformValidateTextureResources ( colorTexture ) ;
colorTexture - > image - > dataState = _RGL_IMAGE_DATASTATE_GPU ;
fb - > rt . colorId [ i ] = nvTexture - > gpuAddressId ;
fb - > rt . colorIdOffset [ i ] = nvTexture - > gpuAddressIdOffset ;
fb - > rt . colorPitch [ i ] = nvTexture - > gpuLayout . pitch ? nvTexture - > gpuLayout . pitch : nvTexture - > gpuLayout . pixelBits * nvTexture - > gpuLayout . baseWidth / 8 ;
fb - > colorBufferMask | = 1 < < i ;
width = MIN ( width , nvTexture - > gpuLayout . baseWidth ) ;
height = MIN ( height , nvTexture - > gpuLayout . baseHeight ) ;
fb - > rt . colorFormat = nvTexture - > gpuLayout . internalFormat ;
fb - > rt . colorBufferCount = i + 1 ;
defaultId = fb - > rt . colorId [ i ] ;
defaultIdOffset = fb - > rt . colorIdOffset [ i ] ;
defaultPitch = fb - > rt . colorPitch [ i ] ;
if ( ! ( fb - > colorBufferMask & ( 1 < < i ) ) )
{
fb - > rt . colorId [ i ] = defaultId ;
fb - > rt . colorIdOffset [ i ] = defaultIdOffset ;
fb - > rt . colorPitch [ i ] = defaultPitch ;
}
}
fb - > rt . width = width ;
fb - > rt . height = height ;
fb - > rt . yInverted = CELL_GCM_FALSE ;
fb - > rt . xOffset = 0 ;
fb - > rt . yOffset = 0 ;
fb - > needValidate = GL_FALSE ;
}
static void _RGLValidateFramebuffer ( void )
{
PSGLdevice * LDevice = _CurrentDevice ;
RGLDevice * gcmDevice = ( RGLDevice * ) LDevice - > platformDevice ;
PSGLcontext * LContext = _CurrentContext ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
driver - > rtValid = GL_FALSE ;
if ( LContext - > framebuffer )
{
jsPlatformFramebuffer * framebuffer = static_cast < jsPlatformFramebuffer * > ( _RGLGetFramebuffer ( LContext , LContext - > framebuffer ) ) ;
if ( framebuffer - > needValidate )
jsPlatformFramebuffer_validate ( framebuffer , LContext ) ;
driver - > rt = framebuffer - > rt ;
driver - > colorBufferMask = framebuffer - > colorBufferMask ;
}
else
{
driver - > rt = gcmDevice - > rt ;
driver - > colorBufferMask = 0x1 ;
}
driver - > rtValid = GL_TRUE ;
_RGLFifoGlSetRenderTarget ( & driver - > rt ) ;
LContext - > needValidate & = ~ PSGL_VALIDATE_FRAMEBUFFER ;
_RGLFifoGlViewport ( LContext - > ViewPort . X , LContext - > ViewPort . Y ,
LContext - > ViewPort . XSize , LContext - > ViewPort . YSize , 0.0f , 1.0f ) ;
}
GLAPI void APIENTRY glClear ( GLbitfield mask )
{
PSGLcontext * LContext = _CurrentContext ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
RGLFifo * fifo = & _RGLState . fifo ;
if ( LContext - > needValidate & PSGL_VALIDATE_FRAMEBUFFER )
_RGLValidateFramebuffer ( ) ;
if ( ! driver - > rtValid )
return ;
GLbitfield newmask = 0 ;
if ( driver - > rt . colorBufferCount ) newmask | = RGL_COLOR_BUFFER_BIT ;
if ( ! newmask )
return ;
GLbitfield clearMask = newmask ;
if ( driver - > rt . colorBufferCount > 1 )
clearMask & = ~ RGL_COLOR_BUFFER_BIT ;
if ( clearMask )
{
GLuint hwColor ;
RGL_CALC_COLOR_LE_ARGB8 ( & hwColor , RGL_CLAMPF_01 ( LContext - > ClearColor . R ) , RGL_CLAMPF_01 ( LContext - > ClearColor . G ) , RGL_CLAMPF_01 ( LContext - > ClearColor . B ) , RGL_CLAMPF_01 ( LContext - > ClearColor . A ) ) ;
cellGcmSetClearColorInline ( & _RGLState . fifo , hwColor ) ;
cellGcmSetClearSurfaceInline ( & _RGLState . fifo , CELL_GCM_CLEAR_R | CELL_GCM_CLEAR_G | CELL_GCM_CLEAR_B | CELL_GCM_CLEAR_A ) ;
newmask & = ~ clearMask ;
}
if ( newmask )
{
cellGcmSetScissorInline ( & _RGLState . fifo , 0 , 0 , 4095 , 4095 ) ;
cellGcmSetDepthTestEnableInline ( & _RGLState . fifo , CELL_GCM_FALSE ) ;
cellGcmSetStencilTestEnableInline ( & _RGLState . fifo , CELL_GCM_FALSE ) ;
static float _RGLClearVertexBuffer [ 12 ] __attribute__ ( ( aligned ( RGL_ALIGN_FAST_TRANSFER ) ) ) =
{
- 1.f , - 1.f , 0.f ,
- 1.f , 1.f , 0.f ,
1.f , - 1.f , 0.f ,
1.f , 1.f , 0.f ,
} ;
_RGLClearVertexBuffer [ 2 ] = 2.f - 1.f ;
_RGLClearVertexBuffer [ 5 ] = 2.f - 1.f ;
_RGLClearVertexBuffer [ 8 ] = 2.f - 1.f ;
_RGLClearVertexBuffer [ 11 ] = 2.f - 1.f ;
GLuint bufferId = gmmAlloc ( 0 , sizeof ( _RGLClearVertexBuffer ) ) ;
memcpy ( gmmIdToAddress ( bufferId ) , _RGLClearVertexBuffer , sizeof ( _RGLClearVertexBuffer ) ) ;
_RGLFifoGlVertexAttribPointer ( 0 , 3 , RGL_FLOAT , CELL_GCM_FALSE , 3 * sizeof ( GLfloat ) , 1 , 0 , gmmIdToOffset ( bufferId ) ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , 0 ) ;
for ( int i = 1 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
_RGLFifoGlVertexAttribPointer ( i , 0 , RGL_FLOAT , 0 , 0 , 0 , 0 , 0 ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , i ) ;
}
cellGcmSetVertexData4fInline ( & _RGLState . fifo , _RGL_ATTRIB_PRIMARY_COLOR_INDEX , ( GLfloat * ) & LContext - > ClearColor ) ;
LContext - > needValidate | = PSGL_VALIDATE_FRAGMENT_PROGRAM ;
gmmFree ( bufferId ) ;
}
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFlush ( fifo ) ;
}
GLAPI void APIENTRY glClearColor ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > ClearColor . R = _RGLClampf ( red ) ;
LContext - > ClearColor . G = _RGLClampf ( green ) ;
LContext - > ClearColor . B = _RGLClampf ( blue ) ;
LContext - > ClearColor . A = _RGLClampf ( alpha ) ;
}
GLAPI void APIENTRY glBlendEquation ( GLenum mode )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > BlendEquationRGB = LContext - > BlendEquationAlpha = mode ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
}
GLAPI void APIENTRY glBlendColor ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > BlendColor . R = _RGLClampf ( red ) ;
LContext - > BlendColor . G = _RGLClampf ( green ) ;
LContext - > BlendColor . B = _RGLClampf ( blue ) ;
LContext - > BlendColor . A = _RGLClampf ( alpha ) ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
}
GLAPI void APIENTRY glBlendFunc ( GLenum sfactor , GLenum dfactor )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > BlendFactorSrcRGB = sfactor ;
LContext - > BlendFactorSrcAlpha = sfactor ;
LContext - > BlendFactorDestRGB = dfactor ;
LContext - > BlendFactorDestAlpha = dfactor ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
}
jsFramebufferAttachment * _RGLFramebufferGetAttachment ( jsFramebuffer * framebuffer , GLenum attachment )
{
switch ( attachment )
{
case GL_COLOR_ATTACHMENT0_EXT :
case GL_COLOR_ATTACHMENT1_EXT :
case GL_COLOR_ATTACHMENT2_EXT :
case GL_COLOR_ATTACHMENT3_EXT :
return & framebuffer - > color [ attachment - GL_COLOR_ATTACHMENT0_EXT ] ;
case GL_DEPTH_ATTACHMENT_OES :
case GL_STENCIL_ATTACHMENT_OES :
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return NULL ;
}
}
GLAPI void APIENTRY glBindFramebufferOES ( GLenum target , GLuint framebuffer )
{
PSGLcontext * LContext = _CurrentContext ;
if ( framebuffer )
_RGLTexNameSpaceCreateNameLazy ( & LContext - > framebufferNameSpace , framebuffer ) ;
LContext - > framebuffer = framebuffer ;
LContext - > needValidate | = PSGL_VALIDATE_FRAMEBUFFER ;
}
GLAPI void APIENTRY glDeleteFramebuffersOES ( GLsizei n , const GLuint * framebuffers )
{
PSGLcontext * LContext = _CurrentContext ;
for ( int i = 0 ; i < n ; + + i )
{
if ( framebuffers [ i ] & & framebuffers [ i ] = = LContext - > framebuffer )
glBindFramebufferOES ( GL_FRAMEBUFFER_OES , 0 ) ;
}
_RGLTexNameSpaceDeleteNames ( & LContext - > framebufferNameSpace , n , framebuffers ) ;
}
GLAPI void APIENTRY glGenFramebuffersOES ( GLsizei n , GLuint * framebuffers )
{
PSGLcontext * LContext = _CurrentContext ;
_RGLTexNameSpaceGenNames ( & LContext - > framebufferNameSpace , n , framebuffers ) ;
}
GLAPI GLenum APIENTRY glCheckFramebufferStatusOES ( GLenum target )
{
PSGLcontext * LContext = _CurrentContext ;
if ( LContext - > framebuffer )
{
jsFramebuffer * framebuffer = _RGLGetFramebuffer ( LContext , LContext - > framebuffer ) ;
return _RGLPlatformFramebufferCheckStatus ( framebuffer ) ;
}
return GL_FRAMEBUFFER_COMPLETE_OES ;
}
GLAPI void APIENTRY glFramebufferTexture2DOES ( GLenum target , GLenum attachment , GLenum textarget , GLuint texture , GLint level )
{
PSGLcontext * LContext = _CurrentContext ;
jsFramebuffer * framebuffer = _RGLGetFramebuffer ( LContext , LContext - > framebuffer ) ;
jsFramebufferAttachment * attach = _RGLFramebufferGetAttachment ( framebuffer , GL_COLOR_ATTACHMENT0_EXT ) ;
if ( ! attach )
return ;
jsTexture * textureObject = NULL ;
GLuint face ;
_RGLFramebufferGetAttachmentTexture ( attach , & textureObject , & face ) ;
if ( textureObject )
textureObject - > framebuffers . removeElement ( framebuffer ) ;
if ( texture )
{
attach - > type = _RGL_FRAMEBUFFER_ATTACHMENT_TEXTURE ;
textureObject = _RGLGetTexture ( LContext , texture ) ;
textureObject - > framebuffers . pushBack ( framebuffer ) ;
}
else
attach - > type = _RGL_FRAMEBUFFER_ATTACHMENT_NONE ;
attach - > name = texture ;
attach - > textureTarget = GL_TEXTURE_2D ;
framebuffer - > needValidate = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_FRAMEBUFFER ;
}
void cgRTCgcInit ( void )
{
_cgRTCgcCompileProgramHook = & compile_program_from_string ;
_cgRTCgcFreeCompiledProgramHook = & free_compiled_program ;
}
void cgRTCgcFree ( void )
{
_cgRTCgcCompileProgramHook = 0 ;
_cgRTCgcFreeCompiledProgramHook = 0 ;
}
void _RGLInitNameSpace ( jsNameSpace * name )
{
name - > data = NULL ;
name - > firstFree = NULL ;
name - > capacity = 0 ;
}
void _RGLFreeNameSpace ( jsNameSpace * ns )
{
if ( ns - > data )
free ( ns - > data ) ;
ns - > data = NULL ;
ns - > capacity = 0 ;
ns - > firstFree = NULL ;
}
jsName _RGLCreateName ( jsNameSpace * ns , void * object )
{
if ( NULL = = ns - > firstFree )
{
int newCapacity = ns - > capacity + NAME_INCREMENT ;
void * * newData = ( void * * ) malloc ( newCapacity * sizeof ( void * ) ) ;
if ( newData = = NULL )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return 0 ;
}
memcpy ( newData , ns - > data , ns - > capacity * sizeof ( void * ) ) ;
if ( ns - > data ! = NULL )
free ( ns - > data ) ;
ns - > data = newData ;
for ( int index = ns - > capacity ; index < newCapacity - 1 ; + + index )
ns - > data [ index ] = ns - > data + index + 1 ;
ns - > data [ newCapacity - 1 ] = NULL ;
ns - > firstFree = ns - > data + ns - > capacity ;
ns - > capacity = newCapacity ;
}
jsName result = ns - > firstFree - ns - > data ;
ns - > firstFree = ( void * * ) * ns - > firstFree ;
ns - > data [ result ] = object ;
return result + 1 ;
}
unsigned int _RGLIsName ( jsNameSpace * ns , jsName name )
{
if ( RGL_UNLIKELY ( 0 = = name ) )
return 0 ;
- - name ;
if ( RGL_UNLIKELY ( name > = ns - > capacity ) )
return 0 ;
void * * value = ( void * * ) ns - > data [ name ] ;
if ( RGL_UNLIKELY ( NULL = = value | |
( value > = ns - > data & & value < ns - > data + ns - > capacity ) ) )
return 0 ;
return 1 ;
}
void _RGLEraseName ( jsNameSpace * ns , jsName name )
{
if ( _RGLIsName ( ns , name ) )
{
- - name ;
ns - > data [ name ] = ns - > firstFree ;
ns - > firstFree = ns - > data + name ;
}
}
void _RGLTexNameSpaceInit ( jsTexNameSpace * ns , jsTexNameSpaceCreateFunction create , jsTexNameSpaceDestroyFunction destroy )
{
ns - > capacity = capacityIncr ;
ns - > data = ( void * * ) malloc ( ns - > capacity * sizeof ( void * ) ) ;
memset ( ns - > data , 0 , ns - > capacity * sizeof ( void * ) ) ;
ns - > create = create ;
ns - > destroy = destroy ;
}
void _RGLTexNameSpaceFree ( jsTexNameSpace * ns )
{
for ( GLuint i = 1 ; i < ns - > capacity ; + + i )
if ( ns - > data [ i ] ) ns - > destroy ( ns - > data [ i ] ) ;
if ( ns - > data ! = NULL )
free ( ns - > data ) ;
ns - > data = NULL ;
}
void _RGLTexNameSpaceResetNames ( jsTexNameSpace * ns )
{
for ( GLuint i = 1 ; i < ns - > capacity ; + + i )
{
if ( ns - > data [ i ] )
{
ns - > destroy ( ns - > data [ i ] ) ;
ns - > data [ i ] = NULL ;
}
}
}
GLuint _RGLTexNameSpaceGetFree ( jsTexNameSpace * ns )
{
GLuint i ;
for ( i = 1 ; i < ns - > capacity ; + + i )
if ( ! ns - > data [ i ] ) break ;
return i ;
}
GLboolean _RGLTexNameSpaceCreateNameLazy ( jsTexNameSpace * ns , GLuint name )
{
if ( name > = ns - > capacity )
{
int newCapacity = name > = ns - > capacity + capacityIncr ? name + 1 : ns - > capacity + capacityIncr ;
void * * newData = ( void * * ) realloc ( ns - > data , newCapacity * sizeof ( void * ) ) ;
memset ( newData + ns - > capacity , 0 , ( newCapacity - ns - > capacity ) * sizeof ( void * ) ) ;
ns - > data = newData ;
ns - > capacity = newCapacity ;
}
if ( ! ns - > data [ name ] )
{
ns - > data [ name ] = ns - > create ( ) ;
if ( ns - > data [ name ] ) return GL_TRUE ;
}
return GL_FALSE ;
}
GLboolean _RGLTexNameSpaceIsName ( jsTexNameSpace * ns , GLuint name )
{
if ( ( name > 0 ) & & ( name < ns - > capacity ) ) return ( ns - > data [ name ] ! = 0 ) ;
else return GL_FALSE ;
}
void _RGLTexNameSpaceGenNames ( jsTexNameSpace * ns , GLsizei n , GLuint * names )
{
for ( int i = 0 ; i < n ; + + i )
{
GLuint name = _RGLTexNameSpaceGetFree ( ns ) ;
names [ i ] = name ;
if ( name ) _RGLTexNameSpaceCreateNameLazy ( ns , name ) ;
}
}
void _RGLTexNameSpaceDeleteNames ( jsTexNameSpace * ns , GLsizei n , const GLuint * names )
{
for ( int i = 0 ; i < n ; + + i )
{
GLuint name = names [ i ] ;
if ( ! _RGLTexNameSpaceIsName ( ns , name ) ) continue ;
ns - > destroy ( ns - > data [ name ] ) ;
ns - > data [ name ] = NULL ;
}
}
static inline unsigned int endianSwapWordByHalf ( unsigned int v )
{
return ( v & 0xffff ) < < 16 | v > > 16 ;
}
static uint32_t gmmInitFixedAllocator ( void )
{
pGmmFixedAllocData = ( GmmFixedAllocData * ) malloc ( sizeof ( GmmFixedAllocData ) ) ;
if ( pGmmFixedAllocData = = NULL )
return GMM_ERROR ;
memset ( pGmmFixedAllocData , 0 , sizeof ( GmmFixedAllocData ) ) ;
for ( int i = 0 ; i < 2 ; i + + )
{
int blockCount = ( i = = 0 ) ? GMM_BLOCK_COUNT : GMM_TILE_BLOCK_COUNT ;
int blockSize = ( i = = 0 ) ? sizeof ( GmmBlock ) : sizeof ( GmmTileBlock ) ;
pGmmFixedAllocData - > ppBlockList [ i ] = ( char * * ) malloc ( sizeof ( char * ) ) ;
if ( pGmmFixedAllocData - > ppBlockList [ i ] = = NULL )
return GMM_ERROR ;
pGmmFixedAllocData - > ppBlockList [ i ] [ 0 ] = ( char * ) malloc ( blockSize * blockCount ) ;
if ( pGmmFixedAllocData - > ppBlockList [ i ] [ 0 ] = = NULL )
return GMM_ERROR ;
pGmmFixedAllocData - > ppFreeBlockList [ i ] = ( uint16_t * * ) malloc ( sizeof ( uint16_t * ) ) ;
if ( pGmmFixedAllocData - > ppFreeBlockList [ i ] = = NULL )
return GMM_ERROR ;
pGmmFixedAllocData - > ppFreeBlockList [ i ] [ 0 ] = ( uint16_t * ) malloc ( sizeof ( uint16_t ) * blockCount ) ;
if ( pGmmFixedAllocData - > ppFreeBlockList [ i ] [ 0 ] = = NULL )
return GMM_ERROR ;
pGmmFixedAllocData - > pBlocksUsed [ i ] = ( uint16_t * ) malloc ( sizeof ( uint16_t ) ) ;
if ( pGmmFixedAllocData - > pBlocksUsed [ i ] = = NULL )
return GMM_ERROR ;
for ( int j = 0 ; j < blockCount ; j + + )
{
pGmmFixedAllocData - > ppFreeBlockList [ i ] [ 0 ] [ j ] = j ;
}
pGmmFixedAllocData - > pBlocksUsed [ i ] [ 0 ] = 0 ;
pGmmFixedAllocData - > BlockListCount [ i ] = 1 ;
}
return CELL_OK ;
}
static void gmmRemovePendingFree (
GmmAllocator * pAllocator ,
GmmBlock * pBlock
)
{
if ( pBlock = = pAllocator - > pPendingFreeHead )
pAllocator - > pPendingFreeHead = pBlock - > pNextFree ;
if ( pBlock = = pAllocator - > pPendingFreeTail )
pAllocator - > pPendingFreeTail = pBlock - > pPrevFree ;
if ( pBlock - > pNextFree )
pBlock - > pNextFree - > pPrevFree = pBlock - > pPrevFree ;
if ( pBlock - > pPrevFree )
pBlock - > pPrevFree - > pNextFree = pBlock - > pNextFree ;
}
static uint8_t gmmSizeToFreeIndex (
uint32_t size
)
{
if ( size > = GMM_FREE_BIN_0 & & size < GMM_FREE_BIN_1 )
{
return 0 ;
}
else if ( size > = GMM_FREE_BIN_1 & & size < GMM_FREE_BIN_2 )
{
return 1 ;
}
else if ( size > = GMM_FREE_BIN_2 & & size < GMM_FREE_BIN_3 )
{
return 2 ;
}
else if ( size > = GMM_FREE_BIN_3 & & size < GMM_FREE_BIN_4 )
{
return 3 ;
}
else if ( size > = GMM_FREE_BIN_4 & & size < GMM_FREE_BIN_5 )
{
return 4 ;
}
else if ( size > = GMM_FREE_BIN_5 & & size < GMM_FREE_BIN_6 )
{
return 5 ;
}
else if ( size > = GMM_FREE_BIN_6 & & size < GMM_FREE_BIN_7 )
{
return 6 ;
}
else if ( size > = GMM_FREE_BIN_7 & & size < GMM_FREE_BIN_8 )
{
return 7 ;
}
else if ( size > = GMM_FREE_BIN_8 & & size < GMM_FREE_BIN_9 )
{
return 8 ;
}
else if ( size > = GMM_FREE_BIN_9 & & size < GMM_FREE_BIN_10 )
{
return 9 ;
}
else if ( size > = GMM_FREE_BIN_10 & & size < GMM_FREE_BIN_11 )
{
return 10 ;
}
else if ( size > = GMM_FREE_BIN_11 & & size < GMM_FREE_BIN_12 )
{
return 11 ;
}
else if ( size > = GMM_FREE_BIN_12 & & size < GMM_FREE_BIN_13 )
{
return 12 ;
}
else if ( size > = GMM_FREE_BIN_13 & & size < GMM_FREE_BIN_14 )
{
return 13 ;
}
else if ( size > = GMM_FREE_BIN_14 & & size < GMM_FREE_BIN_15 )
{
return 14 ;
}
else if ( size > = GMM_FREE_BIN_15 & & size < GMM_FREE_BIN_16 )
{
return 15 ;
}
else if ( size > = GMM_FREE_BIN_16 & & size < GMM_FREE_BIN_17 )
{
return 16 ;
}
else if ( size > = GMM_FREE_BIN_17 & & size < GMM_FREE_BIN_18 )
{
return 17 ;
}
else if ( size > = GMM_FREE_BIN_18 & & size < GMM_FREE_BIN_19 )
{
return 18 ;
}
else if ( size > = GMM_FREE_BIN_19 & & size < GMM_FREE_BIN_20 )
{
return 19 ;
}
else if ( size > = GMM_FREE_BIN_20 & & size < GMM_FREE_BIN_21 )
{
return 20 ;
}
else
return 21 ;
}
static void gmmAddFree (
GmmAllocator * pAllocator ,
GmmBlock * pBlock
)
{
uint8_t freeIndex = gmmSizeToFreeIndex ( pBlock - > base . size ) ;
if ( pAllocator - > pFreeHead [ freeIndex ] )
{
GmmBlock * pInsertBefore = pAllocator - > pFreeHead [ freeIndex ] ;
while ( pInsertBefore & & pInsertBefore - > base . size < pBlock - > base . size )
{
pInsertBefore = pInsertBefore - > pNextFree ;
}
if ( pInsertBefore = = NULL )
{
pBlock - > pNextFree = NULL ;
pBlock - > pPrevFree = pAllocator - > pFreeTail [ freeIndex ] ;
pAllocator - > pFreeTail [ freeIndex ] - > pNextFree = pBlock ;
pAllocator - > pFreeTail [ freeIndex ] = pBlock ;
}
else if ( pInsertBefore = = pAllocator - > pFreeHead [ freeIndex ] )
{
pBlock - > pNextFree = pInsertBefore ;
pBlock - > pPrevFree = pInsertBefore - > pPrevFree ;
pInsertBefore - > pPrevFree = pBlock ;
pAllocator - > pFreeHead [ freeIndex ] = pBlock ;
}
else
{
pBlock - > pNextFree = pInsertBefore ;
pBlock - > pPrevFree = pInsertBefore - > pPrevFree ;
pInsertBefore - > pPrevFree - > pNextFree = pBlock ;
pInsertBefore - > pPrevFree = pBlock ;
}
}
else
{
pBlock - > pNextFree = NULL ;
pBlock - > pPrevFree = NULL ;
pAllocator - > pFreeHead [ freeIndex ] = pBlock ;
pAllocator - > pFreeTail [ freeIndex ] = pBlock ;
}
}
void gmmUpdateFreeList ( const uint8_t location )
{
GmmAllocator * pAllocator ;
const uint32_t fence = _RGLState . semaphores - > userSemaphores [ _RGL_SEMA_FENCE ] . val ;
GmmBlock * pBlock = NULL ;
GmmBlock * pTemp = NULL ;
pAllocator = ( location = = CELL_GCM_LOCATION_LOCAL ) ?
pGmmLocalAllocator :
pGmmMainAllocator ;
pBlock = pAllocator - > pPendingFreeHead ;
while ( pBlock )
{
pTemp = pBlock - > pNextFree ;
if ( ! ( ( fence - pBlock - > fence ) & 0x80000000 ) )
{
gmmRemovePendingFree ( pAllocator , pBlock ) ;
gmmAddFree ( pAllocator , pBlock ) ;
}
pBlock = pTemp ;
}
}
static void * gmmAllocFixed ( uint8_t isTile )
{
int blockCount = isTile ? GMM_TILE_BLOCK_COUNT : GMM_BLOCK_COUNT ;
int blockSize = isTile ? sizeof ( GmmTileBlock ) : sizeof ( GmmBlock ) ;
int listCount = pGmmFixedAllocData - > BlockListCount [ isTile ] ;
for ( int i = 0 ; i < listCount ; i + + )
{
if ( pGmmFixedAllocData - > pBlocksUsed [ isTile ] [ i ] < blockCount )
{
return pGmmFixedAllocData - > ppBlockList [ isTile ] [ i ] +
( pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ i ] [ pGmmFixedAllocData - > pBlocksUsed [ isTile ] [ i ] + + ] *
blockSize ) ;
}
}
char * * ppBlockList =
( char * * ) realloc ( pGmmFixedAllocData - > ppBlockList [ isTile ] ,
( listCount + 1 ) * sizeof ( char * ) ) ;
if ( ppBlockList = = NULL )
return NULL ;
pGmmFixedAllocData - > ppBlockList [ isTile ] = ppBlockList ;
pGmmFixedAllocData - > ppBlockList [ isTile ] [ listCount ] =
( char * ) malloc ( blockSize * blockCount ) ;
if ( pGmmFixedAllocData - > ppBlockList [ isTile ] [ listCount ] = = NULL )
return NULL ;
uint16_t * * ppFreeBlockList =
( uint16_t * * ) realloc ( pGmmFixedAllocData - > ppFreeBlockList [ isTile ] ,
( listCount + 1 ) * sizeof ( uint16_t * ) ) ;
if ( ppFreeBlockList = = NULL )
return NULL ;
pGmmFixedAllocData - > ppFreeBlockList [ isTile ] = ppFreeBlockList ;
pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ listCount ] =
( uint16_t * ) malloc ( sizeof ( uint16_t ) * blockCount ) ;
if ( pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ listCount ] = = NULL )
return NULL ;
uint16_t * pBlocksUsed =
( uint16_t * ) realloc ( pGmmFixedAllocData - > pBlocksUsed [ isTile ] ,
( listCount + 1 ) * sizeof ( uint16_t ) ) ;
if ( pBlocksUsed = = NULL )
return NULL ;
pGmmFixedAllocData - > pBlocksUsed [ isTile ] = pBlocksUsed ;
for ( int i = 0 ; i < blockCount ; i + + )
{
pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ listCount ] [ i ] = i ;
}
pGmmFixedAllocData - > pBlocksUsed [ isTile ] [ listCount ] = 0 ;
pGmmFixedAllocData - > BlockListCount [ isTile ] + + ;
return pGmmFixedAllocData - > ppBlockList [ isTile ] [ listCount ] +
( pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ listCount ] [ pGmmFixedAllocData - > pBlocksUsed [ isTile ] [ listCount ] + + ] *
blockSize ) ;
}
static void gmmFreeFixed ( uint8_t isTile , void * pBlock )
{
int blockCount = isTile ? GMM_TILE_BLOCK_COUNT : GMM_BLOCK_COUNT ;
int blockSize = isTile ? sizeof ( GmmTileBlock ) : sizeof ( GmmBlock ) ;
for ( int i = 0 ; i < pGmmFixedAllocData - > BlockListCount [ isTile ] ; i + + )
{
if ( pBlock > = pGmmFixedAllocData - > ppBlockList [ isTile ] [ i ] & &
pBlock < ( pGmmFixedAllocData - > ppBlockList [ isTile ] [ i ] + blockSize * blockCount ) )
{
int index = ( ( char * ) pBlock - pGmmFixedAllocData - > ppBlockList [ isTile ] [ i ] ) / blockSize ;
pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ i ] [ - - pGmmFixedAllocData - > pBlocksUsed [ isTile ] [ i ] ] = index ;
}
}
}
uint32_t gmmInit (
const void * localMemoryBase ,
const void * localStartAddress ,
const uint32_t localSize ,
const void * mainMemoryBase ,
const void * mainStartAddress ,
const uint32_t mainSize
)
{
GmmAllocator * pAllocator [ 2 ] ;
uint32_t alignedLocalSize , alignedMainSize ;
uint32_t localEndAddress = ( uint32_t ) localStartAddress + localSize ;
uint32_t mainEndAddress = ( uint32_t ) mainStartAddress + mainSize ;
localEndAddress = ( localEndAddress / GMM_TILE_ALIGNMENT ) * GMM_TILE_ALIGNMENT ;
mainEndAddress = ( mainEndAddress / GMM_TILE_ALIGNMENT ) * GMM_TILE_ALIGNMENT ;
alignedLocalSize = localEndAddress - ( uint32_t ) localStartAddress ;
alignedMainSize = mainEndAddress - ( uint32_t ) mainStartAddress ;
pAllocator [ 0 ] = ( GmmAllocator * ) malloc ( 2 * sizeof ( GmmAllocator ) ) ;
pAllocator [ 1 ] = pAllocator [ 0 ] + 1 ;
if ( pAllocator [ 0 ] = = NULL )
return GMM_ERROR ;
memset ( pAllocator [ 0 ] , 0 , 2 * sizeof ( GmmAllocator ) ) ;
if ( pAllocator [ 0 ] )
{
pAllocator [ 0 ] - > memoryBase = ( uint32_t ) localMemoryBase ;
pAllocator [ 1 ] - > memoryBase = ( uint32_t ) mainMemoryBase ;
pAllocator [ 0 ] - > startAddress = ( uint32_t ) localStartAddress ;
pAllocator [ 1 ] - > startAddress = ( uint32_t ) mainStartAddress ;
pAllocator [ 0 ] - > size = alignedLocalSize ;
pAllocator [ 1 ] - > size = alignedMainSize ;
pAllocator [ 0 ] - > freeAddress = pAllocator [ 0 ] - > startAddress ;
pAllocator [ 1 ] - > freeAddress = pAllocator [ 1 ] - > startAddress ;
pAllocator [ 0 ] - > tileStartAddress = ( ( uint32_t ) localStartAddress ) + alignedLocalSize ;
pAllocator [ 1 ] - > tileStartAddress = ( ( uint32_t ) mainStartAddress ) + alignedMainSize ;
pAllocator [ 0 ] - > totalSize = alignedLocalSize ;
pAllocator [ 1 ] - > totalSize = alignedMainSize ;
pGmmLocalAllocator = pAllocator [ 0 ] ;
pGmmMainAllocator = pAllocator [ 1 ] ;
}
else
return GMM_ERROR ;
pLock = cellGcmGetLabelAddress ( GMM_PPU_WAIT_INDEX ) ;
* pLock = 0 ;
cachedLockValue = 0 ;
return gmmInitFixedAllocator ( ) ;
}
void gmmSetTileAttrib (
const uint32_t id ,
const uint32_t tag ,
void * pData
)
{
GmmTileBlock * pTileBlock = ( GmmTileBlock * ) id ;
pTileBlock - > tileTag = tag ;
pTileBlock - > pData = pData ;
}
uint32_t gmmIdToOffset ( const uint32_t id )
{
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) id ;
return gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) ;
}
char * gmmIdToAddress ( const uint32_t id )
{
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) id ;
do
{
if ( cachedLockValue = = 0 )
break ;
cachedLockValue = * pLock ;
if ( cachedLockValue = = 0 )
break ;
sys_timer_usleep ( 30 ) ;
} while ( 1 ) ;
return ( char * ) pBaseBlock - > address ;
}
static GmmBlock * gmmAllocBlock ( GmmAllocator * pAllocator , uint32_t size )
{
uint32_t address ;
GmmBlock * pNewBlock = NULL ;
GmmBlock * pBlock = pAllocator - > pTail ;
address = pAllocator - > freeAddress ;
if ( UINT_MAX - address > = size & &
address + size < = pAllocator - > startAddress + pAllocator - > size )
{
pNewBlock = ( GmmBlock * ) gmmAllocFixed ( 0 ) ;
if ( pNewBlock = = NULL )
return NULL ;
memset ( pNewBlock , 0 , sizeof ( GmmBlock ) ) ;
pNewBlock - > base . address = address ;
pNewBlock - > base . isMain = ( pAllocator = = pGmmMainAllocator ) ;
pNewBlock - > base . size = size ;
pAllocator - > freeAddress = address + size ;
if ( pBlock )
{
pNewBlock - > pPrev = pBlock ;
pBlock - > pNext = pNewBlock ;
pAllocator - > pTail = pNewBlock ;
}
else
{
pAllocator - > pHead = pNewBlock ;
pAllocator - > pTail = pNewBlock ;
}
}
return pNewBlock ;
}
static GmmTileBlock * gmmFindFreeTileBlock (
GmmAllocator * pAllocator ,
const uint32_t size
)
{
GmmTileBlock * pBlock = pAllocator - > pTileHead ;
GmmTileBlock * pBestAfterBlock = NULL ;
GmmTileBlock * pNewBlock = NULL ;
uint32_t bestSize = 0 ;
uint32_t freeSize = 0 ;
while ( pBlock & & pBlock - > pNext )
{
freeSize = pBlock - > pNext - > base . address - pBlock - > base . address - pBlock - > base . size ;
if ( freeSize > = size & &
( pBestAfterBlock = = NULL | | freeSize < bestSize ) & &
( pBlock - > pNext = = NULL | |
pBlock - > pData ! = pBlock - > pNext - > pData ) )
{
pBestAfterBlock = pBlock ;
bestSize = freeSize ;
}
pBlock = pBlock - > pNext ;
}
if ( pBestAfterBlock )
{
pNewBlock = ( GmmTileBlock * ) gmmAllocFixed ( 1 ) ;
if ( pNewBlock = = NULL )
return NULL ;
memset ( pNewBlock , 0 , sizeof ( GmmTileBlock ) ) ;
pNewBlock - > base . address = pBestAfterBlock - > base . address + pBestAfterBlock - > base . size ;
pNewBlock - > base . isMain = ( pAllocator = = pGmmMainAllocator ) ;
pNewBlock - > base . isTile = 1 ;
pNewBlock - > base . size = size ;
pNewBlock - > pNext = pBestAfterBlock - > pNext ;
pNewBlock - > pPrev = pBestAfterBlock ;
pNewBlock - > pPrev - > pNext = pNewBlock ;
pNewBlock - > pNext - > pPrev = pNewBlock ;
return pNewBlock ;
}
else
{
return NULL ;
}
}
static GmmTileBlock * gmmCreateTileBlock (
GmmAllocator * pAllocator ,
const uint32_t size
)
{
GmmTileBlock * pNewBlock ;
uint32_t address ;
address = pAllocator - > tileStartAddress - size ;
if ( address > pAllocator - > startAddress + pAllocator - > size )
return NULL ;
if ( pAllocator - > pTail & &
pAllocator - > pTail - > base . address + pAllocator - > pTail - > base . size > address )
{
return NULL ;
}
pAllocator - > size = address - pAllocator - > startAddress ;
pAllocator - > tileSize = pAllocator - > tileStartAddress + pAllocator - > tileSize - address ;
pAllocator - > tileStartAddress = address ;
pNewBlock = ( GmmTileBlock * ) gmmAllocFixed ( 1 ) ;
if ( pNewBlock = = NULL )
{
return NULL ;
}
memset ( pNewBlock , 0 , sizeof ( GmmTileBlock ) ) ;
pNewBlock - > base . address = address ;
pNewBlock - > base . isMain = ( pAllocator = = pGmmMainAllocator ) ;
pNewBlock - > base . isTile = 1 ;
pNewBlock - > base . size = size ;
pNewBlock - > pNext = pAllocator - > pTileHead ;
if ( pAllocator - > pTileHead )
{
pAllocator - > pTileHead - > pPrev = pNewBlock ;
pAllocator - > pTileHead = pNewBlock ;
}
else
{
pAllocator - > pTileHead = pNewBlock ;
pAllocator - > pTileTail = pNewBlock ;
}
return pNewBlock ;
}
static void gmmFreeTileBlock (
GmmTileBlock * pTileBlock
)
{
GmmAllocator * pAllocator ;
if ( pTileBlock - > pPrev )
pTileBlock - > pPrev - > pNext = pTileBlock - > pNext ;
if ( pTileBlock - > pNext )
pTileBlock - > pNext - > pPrev = pTileBlock - > pPrev ;
if ( pTileBlock - > base . isMain )
pAllocator = pGmmMainAllocator ;
else
pAllocator = pGmmLocalAllocator ;
if ( pAllocator - > pTileHead = = pTileBlock )
{
pAllocator - > pTileHead = pTileBlock - > pNext ;
if ( pAllocator - > pTileHead )
{
pAllocator - > pTileHead - > pPrev = NULL ;
}
pAllocator - > size = pAllocator - > pTileHead ?
pAllocator - > pTileHead - > base . address - pAllocator - > startAddress :
pAllocator - > totalSize ;
pAllocator - > tileSize = pAllocator - > totalSize - pAllocator - > size ;
pAllocator - > tileStartAddress = pAllocator - > pTileHead ?
pAllocator - > pTileHead - > base . address :
pAllocator - > startAddress + pAllocator - > size ;
}
if ( pAllocator - > pTileTail = = pTileBlock )
{
pAllocator - > pTileTail = pTileBlock - > pPrev ;
if ( pAllocator - > pTileTail )
{
pAllocator - > pTileTail - > pNext = NULL ;
}
}
gmmFreeFixed ( 1 , pTileBlock ) ;
}
uint32_t gmmAllocExtendedTileBlock ( const uint32_t size , const uint32_t tag )
{
GmmAllocator * pAllocator = pGmmLocalAllocator ;
uint32_t retId = 0 ;
uint32_t newSize ;
uint8_t resizeSucceed = 1 ;
newSize = pad ( size , GMM_TILE_ALIGNMENT ) ;
GmmTileBlock * pBlock = pAllocator - > pTileTail ;
while ( pBlock )
{
if ( pBlock - > tileTag = = tag )
{
GLuint address , tileSize ;
_RGLGetTileRegionInfo ( pBlock - > pData , & address , & tileSize ) ;
if ( ( pBlock - > pNext & & pBlock - > pNext - > base . address - pBlock - > base . address - pBlock - > base . size > = newSize ) | |
( pBlock - > pPrev & & pBlock - > base . address - pBlock - > pPrev - > base . address - pBlock - > pPrev - > base . size > = newSize ) )
{
GmmTileBlock * pNewBlock = ( GmmTileBlock * ) gmmAllocFixed ( 1 ) ;
if ( pNewBlock = = NULL )
break ;
retId = ( uint32_t ) pNewBlock ;
memset ( pNewBlock , 0 , sizeof ( GmmTileBlock ) ) ;
pNewBlock - > base . isMain = ( pAllocator = = pGmmMainAllocator ) ;
pNewBlock - > base . isTile = 1 ;
pNewBlock - > base . size = newSize ;
if ( pBlock - > pNext & & pBlock - > pNext - > base . address - pBlock - > base . address - pBlock - > base . size > = newSize )
{
pNewBlock - > base . address = pBlock - > base . address + pBlock - > base . size ;
pNewBlock - > pNext = pBlock - > pNext ;
pNewBlock - > pPrev = pBlock ;
pBlock - > pNext - > pPrev = pNewBlock ;
pBlock - > pNext = pNewBlock ;
if ( pNewBlock - > pPrev - > pData ! = pNewBlock - > pNext - > pData )
{
resizeSucceed = _RGLTryResizeTileRegion ( address , tileSize + newSize , pBlock - > pData ) ;
}
}
else
{
pNewBlock - > base . address = pBlock - > base . address - newSize ;
pNewBlock - > pNext = pBlock ;
pNewBlock - > pPrev = pBlock - > pPrev ;
pBlock - > pPrev - > pNext = pNewBlock ;
pBlock - > pPrev = pNewBlock ;
if ( pNewBlock - > pPrev - > pData ! = pNewBlock - > pNext - > pData )
{
resizeSucceed = _RGLTryResizeTileRegion ( ( GLuint ) gmmIdToOffset ( ( uint32_t ) pNewBlock ) , tileSize + newSize , pBlock - > pData ) ;
}
}
gmmSetTileAttrib ( retId , tag , pBlock - > pData ) ;
break ;
}
if ( pBlock = = pAllocator - > pTileHead )
{
retId = ( uint32_t ) gmmCreateTileBlock ( pAllocator , newSize ) ;
if ( retId = = 0 )
break ;
resizeSucceed = _RGLTryResizeTileRegion ( ( GLuint ) gmmIdToOffset ( retId ) , tileSize + newSize , pBlock - > pData ) ;
gmmSetTileAttrib ( retId , tag , pBlock - > pData ) ;
break ;
}
}
pBlock = pBlock - > pPrev ;
}
if ( retId = = 0 )
return GMM_ERROR ;
if ( ! resizeSucceed )
{
gmmFreeTileBlock ( ( GmmTileBlock * ) retId ) ;
return GMM_ERROR ;
}
return retId ;
}
static GmmTileBlock * gmmAllocTileBlock (
GmmAllocator * pAllocator ,
const uint32_t size
)
{
GmmTileBlock * pBlock = gmmFindFreeTileBlock ( pAllocator , size ) ;
if ( pBlock = = NULL )
pBlock = gmmCreateTileBlock ( pAllocator , size ) ;
return pBlock ;
}
static void gmmFreeBlock (
GmmBlock * pBlock
)
{
GmmAllocator * pAllocator ;
if ( pBlock - > pPrev )
pBlock - > pPrev - > pNext = pBlock - > pNext ;
if ( pBlock - > pNext )
pBlock - > pNext - > pPrev = pBlock - > pPrev ;
if ( pBlock - > base . isMain )
pAllocator = pGmmMainAllocator ;
else
pAllocator = pGmmLocalAllocator ;
if ( pAllocator - > pHead = = pBlock )
{
pAllocator - > pHead = pBlock - > pNext ;
if ( pAllocator - > pHead )
pAllocator - > pHead - > pPrev = NULL ;
}
if ( pAllocator - > pTail = = pBlock )
{
pAllocator - > pTail = pBlock - > pPrev ;
if ( pAllocator - > pTail )
pAllocator - > pTail - > pNext = NULL ;
}
if ( pBlock - > pPrev = = NULL )
pAllocator - > pSweepHead = pAllocator - > pHead ;
else if ( pBlock - > pPrev & &
( pAllocator - > pSweepHead = = NULL | |
( pAllocator - > pSweepHead & &
pAllocator - > pSweepHead - > base . address > pBlock - > pPrev - > base . address ) ) )
{
pAllocator - > pSweepHead = pBlock - > pPrev ;
}
pAllocator - > freedSinceSweep + = pBlock - > base . size ;
gmmFreeFixed ( 0 , pBlock ) ;
}
static void gmmAddPendingFree (
GmmBlock * pBlock
)
{
GmmAllocator * pAllocator ;
if ( pBlock - > base . isMain )
pAllocator = pGmmMainAllocator ;
else
pAllocator = pGmmLocalAllocator ;
if ( pAllocator - > pPendingFreeTail )
{
pBlock - > pNextFree = NULL ;
pBlock - > pPrevFree = pAllocator - > pPendingFreeTail ;
pAllocator - > pPendingFreeTail - > pNextFree = pBlock ;
pAllocator - > pPendingFreeTail = pBlock ;
}
else
{
pBlock - > pNextFree = NULL ;
pBlock - > pPrevFree = NULL ;
pAllocator - > pPendingFreeHead = pBlock ;
pAllocator - > pPendingFreeTail = pBlock ;
}
pBlock - > isPinned = 0 ;
GLuint * ref = & pBlock - > fence ;
+ + nvFenceCounter ;
cellGcmSetWriteBackEndLabelInline ( & _RGLState . fifo , _RGL_SEMA_FENCE , nvFenceCounter ) ;
* ref = nvFenceCounter ;
}
uint32_t gmmFree ( const uint32_t freeId )
{
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) freeId ;
if ( pBaseBlock - > isTile )
{
GmmTileBlock * pTileBlock = ( GmmTileBlock * ) pBaseBlock ;
if ( pTileBlock - > pPrev & &
pTileBlock - > pNext & &
pTileBlock - > pPrev - > pData = = pTileBlock - > pNext - > pData )
{
}
else if ( pTileBlock - > pPrev & & pTileBlock - > pPrev - > pData = = pTileBlock - > pData )
{
GLuint address , size ;
_RGLGetTileRegionInfo ( pTileBlock - > pData , & address , & size ) ;
if ( ! _RGLTryResizeTileRegion ( address , ( size - pTileBlock - > base . size ) , pTileBlock - > pData ) )
{
_RGLTryResizeTileRegion ( address , 0 , pTileBlock - > pData ) ;
if ( ! _RGLTryResizeTileRegion ( address , ( size - pTileBlock - > base . size ) , pTileBlock - > pData ) )
{
}
}
}
else if ( pTileBlock - > pNext & & pTileBlock - > pNext - > pData = = pTileBlock - > pData )
{
GLuint address , size ;
_RGLGetTileRegionInfo ( pTileBlock - > pData , & address , & size ) ;
if ( ! _RGLTryResizeTileRegion ( ( address + pTileBlock - > base . size ) , ( size - pTileBlock - > base . size ) , pTileBlock - > pData ) )
{
_RGLTryResizeTileRegion ( address , 0 , pTileBlock - > pData ) ;
if ( ! _RGLTryResizeTileRegion ( ( address + pTileBlock - > base . size ) , ( size - pTileBlock - > base . size ) , pTileBlock - > pData ) )
{
}
}
}
else
{
if ( ! _RGLTryResizeTileRegion ( ( GLuint ) gmmIdToOffset ( freeId ) , 0 , ( ( GmmTileBlock * ) freeId ) - > pData ) )
{
}
}
gmmFreeTileBlock ( pTileBlock ) ;
}
else
{
GmmBlock * pBlock = ( GmmBlock * ) pBaseBlock ;
gmmAddPendingFree ( pBlock ) ;
}
return CELL_OK ;
}
static inline void gmmLocalMemcpy (
const uint32_t dstOffset ,
const uint32_t srcOffset ,
const uint32_t moveSize
)
{
CellGcmContextData * thisContext = & _RGLState . fifo ;
int32_t offset = 0 ;
int32_t sizeLeft = moveSize ;
int32_t dimension = 4096 ;
while ( sizeLeft )
{
while ( sizeLeft > = dimension * dimension * 4 )
{
cellGcmSetTransferImage ( thisContext ,
CELL_GCM_TRANSFER_LOCAL_TO_LOCAL ,
dstOffset + offset ,
dimension * 4 ,
0 ,
0 ,
srcOffset + offset ,
dimension * 4 ,
0 ,
0 ,
dimension ,
dimension ,
4 ) ;
offset = offset + dimension * dimension * 4 ;
sizeLeft = sizeLeft - ( dimension * dimension * 4 ) ;
}
dimension = dimension > > 1 ;
if ( dimension = = 32 )
break ;
}
if ( sizeLeft )
{
cellGcmSetTransferImage ( thisContext ,
CELL_GCM_TRANSFER_LOCAL_TO_LOCAL ,
dstOffset + offset ,
sizeLeft ,
0 ,
0 ,
srcOffset + offset ,
sizeLeft ,
0 ,
0 ,
sizeLeft / 4 ,
1 ,
4 ) ;
}
}
static inline void gmmMemcpy ( const uint32_t dstOffset , const uint32_t srcOffset , const uint32_t moveSize )
{
if ( dstOffset + moveSize < = srcOffset )
{
gmmLocalMemcpy ( dstOffset , srcOffset , moveSize ) ;
}
else
{
uint32_t moveBlockSize = srcOffset - dstOffset ;
uint32_t iterations = ( moveSize + moveBlockSize - 1 ) / moveBlockSize ;
for ( uint32_t i = 0 ; i < iterations ; i + + )
2012-05-27 23:57:16 +02:00
gmmLocalMemcpy ( dstOffset + ( i * moveBlockSize ) , srcOffset + ( i * moveBlockSize ) , moveBlockSize ) ;
2012-05-06 03:46:55 +02:00
}
}
static uint8_t gmmInternalSweep ( void )
{
GmmAllocator * pAllocator = pGmmLocalAllocator ;
GmmBlock * pBlock ;
GmmBlock * pSrcBlock ;
GmmBlock * pTempBlock ;
GmmBlock * pTempBlockNext ;
uint32_t dstAddress , srcAddress ;
uint32_t srcOffset , dstOffset ;
uint32_t prevEndAddress ;
uint32_t moveSize , moveDistance ;
uint8_t ret = 0 ;
uint32_t totalMoveSize = 0 ;
pBlock = pAllocator - > pSweepHead ;
srcAddress = 0 ;
dstAddress = 0 ;
prevEndAddress = 0 ;
pSrcBlock = pBlock ;
while ( pBlock ! = NULL )
{
if ( pBlock - > isPinned = = 0 )
{
if ( pBlock - > pPrev )
prevEndAddress = pBlock - > pPrev - > base . address + pBlock - > pPrev - > base . size ;
else
prevEndAddress = pAllocator - > startAddress ;
if ( pBlock - > base . address > prevEndAddress )
{
dstAddress = prevEndAddress ;
srcAddress = pBlock - > base . address ;
pSrcBlock = pBlock ;
}
moveSize = pBlock - > base . address + pBlock - > base . size - srcAddress ;
if ( srcAddress > dstAddress & &
( pBlock - > pNext = = NULL | |
pBlock - > pNext - > base . address > pBlock - > base . address + pBlock - > base . size | |
pBlock - > pNext - > isPinned ) )
{
dstOffset = gmmAddressToOffset ( dstAddress , 0 ) ;
srcOffset = gmmAddressToOffset ( srcAddress , 0 ) ;
totalMoveSize + = moveSize ;
gmmMemcpy ( dstOffset , srcOffset , moveSize ) ;
pTempBlock = pSrcBlock ;
moveDistance = srcOffset - dstOffset ;
while ( pTempBlock ! = pBlock - > pNext )
{
pTempBlock - > base . address - = moveDistance ;
pTempBlock = pTempBlock - > pNext ;
}
}
}
else
{
uint32_t availableSize ;
srcAddress = 0 ;
dstAddress = 0 ;
if ( pBlock - > pPrev = = NULL )
availableSize = pBlock - > base . address - pAllocator - > startAddress ;
else
availableSize = pBlock - > base . address - ( pBlock - > pPrev - > base . address + pBlock - > pPrev - > base . size ) ;
pTempBlock = pBlock - > pNext ;
while ( availableSize > = GMM_ALIGNMENT & & pTempBlock )
{
pTempBlockNext = pTempBlock - > pNext ;
if ( pTempBlock - > isPinned = = 0 & & pTempBlock - > base . size < = availableSize )
{
uint32_t pinDstAddress = ( pBlock - > pPrev = = NULL ) ?
pAllocator - > startAddress :
pBlock - > pPrev - > base . address + pBlock - > pPrev - > base . size ;
uint32_t pinSrcAddress = pTempBlock - > base . address ;
dstOffset = gmmAddressToOffset ( pinDstAddress , 0 ) ;
srcOffset = gmmAddressToOffset ( pinSrcAddress , 0 ) ;
totalMoveSize + = pTempBlock - > base . size ;
gmmMemcpy ( dstOffset , srcOffset , pTempBlock - > base . size ) ;
pTempBlock - > base . address = pinDstAddress ;
if ( pTempBlock = = pAllocator - > pTail )
{
if ( pTempBlock - > pNext )
pAllocator - > pTail = pTempBlock - > pNext ;
else
pAllocator - > pTail = pTempBlock - > pPrev ;
}
if ( pTempBlock - > pNext )
pTempBlock - > pNext - > pPrev = pTempBlock - > pPrev ;
if ( pTempBlock - > pPrev )
pTempBlock - > pPrev - > pNext = pTempBlock - > pNext ;
if ( pBlock - > pPrev )
pBlock - > pPrev - > pNext = pTempBlock ;
else
pAllocator - > pHead = pTempBlock ;
pTempBlock - > pPrev = pBlock - > pPrev ;
pTempBlock - > pNext = pBlock ;
pBlock - > pPrev = pTempBlock ;
}
if ( pBlock - > pPrev )
availableSize = pBlock - > base . address - ( pBlock - > pPrev - > base . address + pBlock - > pPrev - > base . size ) ;
pTempBlock = pTempBlockNext ;
}
if ( availableSize )
{
GmmBlock * pNewBlock = ( GmmBlock * ) gmmAllocFixed ( 0 ) ;
if ( pNewBlock )
{
memset ( pNewBlock , 0 , sizeof ( GmmBlock ) ) ;
pNewBlock - > base . address = pBlock - > base . address - availableSize ;
pNewBlock - > base . isMain = pBlock - > base . isMain ;
pNewBlock - > base . size = availableSize ;
pNewBlock - > pNext = pBlock ;
pNewBlock - > pPrev = pBlock - > pPrev ;
if ( pBlock - > pPrev )
pBlock - > pPrev - > pNext = pNewBlock ;
pBlock - > pPrev = pNewBlock ;
if ( pBlock = = pAllocator - > pHead )
pAllocator - > pHead = pNewBlock ;
gmmAddFree ( pAllocator , pNewBlock ) ;
ret = 1 ;
}
}
}
pBlock = pBlock - > pNext ;
}
uint32_t newFreeAddress = pAllocator - > pTail ?
pAllocator - > pTail - > base . address + pAllocator - > pTail - > base . size :
pAllocator - > startAddress ;
if ( pAllocator - > freeAddress ! = newFreeAddress )
{
pAllocator - > freeAddress = newFreeAddress ;
ret = 1 ;
}
pAllocator - > freedSinceSweep = 0 ;
pAllocator - > pSweepHead = NULL ;
return ret ;
}
static void gmmFreeAll ( void )
{
GmmAllocator * pAllocator = pGmmLocalAllocator ;
GmmBlock * pBlock ;
GmmBlock * pTemp ;
pBlock = pAllocator - > pPendingFreeHead ;
while ( pBlock )
{
pTemp = pBlock - > pNextFree ;
gmmFreeBlock ( pBlock ) ;
pBlock = pTemp ;
}
pAllocator - > pPendingFreeHead = NULL ;
pAllocator - > pPendingFreeTail = NULL ;
for ( int i = 0 ; i < GMM_NUM_FREE_BINS ; i + + )
{
pBlock = pAllocator - > pFreeHead [ i ] ;
while ( pBlock )
{
pTemp = pBlock - > pNextFree ;
gmmFreeBlock ( pBlock ) ;
pBlock = pTemp ;
}
pAllocator - > pFreeHead [ i ] = NULL ;
pAllocator - > pFreeTail [ i ] = NULL ;
}
}
static void gmmRemoveFree (
GmmAllocator * pAllocator ,
GmmBlock * pBlock ,
uint8_t freeIndex
)
{
if ( pBlock = = pAllocator - > pFreeHead [ freeIndex ] )
pAllocator - > pFreeHead [ freeIndex ] = pBlock - > pNextFree ;
if ( pBlock = = pAllocator - > pFreeTail [ freeIndex ] )
pAllocator - > pFreeTail [ freeIndex ] = pBlock - > pPrevFree ;
if ( pBlock - > pNextFree )
pBlock - > pNextFree - > pPrevFree = pBlock - > pPrevFree ;
if ( pBlock - > pPrevFree )
pBlock - > pPrevFree - > pNextFree = pBlock - > pNextFree ;
}
static uint32_t gmmFindFreeBlock (
GmmAllocator * pAllocator ,
uint32_t size
)
{
uint32_t retId = GMM_ERROR ;
GmmBlock * pBlock ;
uint8_t found = 0 ;
uint8_t freeIndex = gmmSizeToFreeIndex ( size ) ;
pBlock = pAllocator - > pFreeHead [ freeIndex ] ;
while ( freeIndex < GMM_NUM_FREE_BINS )
{
if ( pBlock )
{
if ( pBlock - > base . size > = size )
{
found = 1 ;
break ;
}
pBlock = pBlock - > pNextFree ;
}
else if ( + + freeIndex < GMM_NUM_FREE_BINS )
{
pBlock = pAllocator - > pFreeHead [ freeIndex ] ;
}
}
if ( found )
{
if ( pBlock - > base . size ! = size )
{
// create a new block here
GmmBlock * pNewBlock = ( GmmBlock * ) gmmAllocFixed ( 0 ) ;
if ( pNewBlock = = NULL )
return GMM_ERROR ;
memset ( pNewBlock , 0 , sizeof ( GmmBlock ) ) ;
pNewBlock - > base . address = pBlock - > base . address + size ;
pNewBlock - > base . isMain = pBlock - > base . isMain ;
pNewBlock - > base . size = pBlock - > base . size - size ;
pNewBlock - > pNext = pBlock - > pNext ;
pNewBlock - > pPrev = pBlock ;
if ( pBlock - > pNext )
{
pBlock - > pNext - > pPrev = pNewBlock ;
}
pBlock - > pNext = pNewBlock ;
if ( pBlock = = pAllocator - > pTail )
pAllocator - > pTail = pNewBlock ;
gmmAddFree ( pAllocator , pNewBlock ) ;
}
pBlock - > base . size = size ;
gmmRemoveFree ( pAllocator , pBlock , freeIndex ) ;
retId = ( uint32_t ) pBlock ;
}
return retId ;
}
uint32_t gmmAlloc ( const uint8_t isTile , const uint32_t size )
{
CellGcmContextData * thisContext = ( CellGcmContextData * ) & _RGLState . fifo ;
GmmAllocator * pAllocator ;
uint32_t retId ;
uint32_t newSize ;
if ( __builtin_expect ( ( size = = 0 ) , 0 ) )
return GMM_ERROR ;
pAllocator = pGmmLocalAllocator ;
if ( ! isTile )
{
newSize = pad ( size , GMM_ALIGNMENT ) ;
retId = gmmFindFreeBlock ( pAllocator , newSize ) ;
}
else
{
newSize = pad ( size , GMM_TILE_ALIGNMENT ) ;
retId = GMM_ERROR ;
}
if ( retId = = GMM_ERROR )
{
if ( isTile )
retId = ( uint32_t ) gmmAllocTileBlock ( pAllocator , newSize ) ;
else
retId = ( uint32_t ) gmmAllocBlock ( pAllocator , newSize ) ;
if ( retId = = RGL_MEMORY_ALLOC_ERROR )
{
gmmFreeAll ( ) ;
if ( gmmInternalSweep ( ) )
{
* pLock = 1 ;
cachedLockValue = 1 ;
cellGcmSetWriteBackEndLabel ( thisContext , GMM_PPU_WAIT_INDEX , 0 ) ;
cellGcmFlush ( thisContext ) ;
}
if ( isTile )
retId = ( uint32_t ) gmmAllocTileBlock ( pAllocator , newSize ) ;
else
retId = ( uint32_t ) gmmAllocBlock ( pAllocator , newSize ) ;
if ( ! isTile & & retId = = RGL_MEMORY_ALLOC_ERROR )
retId = gmmFindFreeBlock ( pAllocator , newSize ) ;
}
}
return retId ;
}
static int _RGLLoadFPShader ( _CGprogram * program )
{
unsigned int ucodeSize = program - > header . instructionCount * 16 ;
if ( program - > loadProgramId = = GMM_ERROR )
{
program - > loadProgramId = gmmAlloc ( 0 , ucodeSize ) ;
program - > loadProgramOffset = 0 ;
}
unsigned int dstId = program - > loadProgramId ;
unsigned dstOffset = program - > loadProgramOffset ;
const char * src = ( char * ) program - > ucode ;
GLuint id = gmmAlloc ( 0 , ucodeSize ) ;
memcpy ( gmmIdToAddress ( id ) , src , ucodeSize ) ;
_RGLMemcpy ( dstId , dstOffset , 0 , id , ucodeSize ) ;
gmmFree ( id ) ;
return GL_TRUE ;
}
static void _RGLUnloadFPShader ( _CGprogram * program )
{
if ( program - > loadProgramId ! = GMM_ERROR )
{
gmmFree ( program - > loadProgramId ) ;
program - > loadProgramId = GMM_ERROR ;
program - > loadProgramOffset = 0 ;
}
}
typedef struct RGLparamUIDRec
{
char * string ;
GLboolean global ;
} RGLparamUID ;
typedef struct RGLparamUIDTableRec
{
int count ;
RGLparamUID * uids ;
} RGLparamUIDTable ;
RGLparamUID getParamUIDByIndex ( const RGLparamUIDTable * st , int index )
{
return st - > uids [ index ] ;
}
void _RGLPlatformSetVertexRegister4fv ( unsigned int reg , const float * __restrict v )
{
}
void _RGLPlatformSetVertexRegisterBlock ( unsigned int reg , unsigned int count , const float * __restrict v )
{
}
void _RGLPlatformSetFragmentRegister4fv ( unsigned int reg , const float * __restrict v )
{
}
void _RGLPlatformSetFragmentRegisterBlock ( unsigned int reg , unsigned int count , const float * __restrict v )
{
}
template < int SIZE > inline static void swapandsetfp ( int ucodeSize , unsigned int loadProgramId , unsigned int loadProgramOffset , unsigned short * ec , const unsigned int * __restrict v )
{
cellGcmSetTransferLocationInline ( & _RGLState . fifo , CELL_GCM_LOCATION_LOCAL ) ;
unsigned short count = * ( ec + + ) ;
for ( unsigned long offsetIndex = 0 ; offsetIndex < count ; + + offsetIndex )
{
void * pointer = NULL ;
const int paddedSIZE = ( SIZE + 1 ) & ~ 1 ;
cellGcmSetInlineTransferPointerInline ( & _RGLState . fifo , gmmIdToOffset ( loadProgramId ) + loadProgramOffset + * ( ec + + ) , paddedSIZE , & pointer ) ;
float * fp = ( float * ) pointer ;
float * src = ( float * ) v ;
for ( uint32_t j = 0 ; j < SIZE ; j + + )
{
* fp = cellGcmSwap16Float32 ( * src ) ;
fp + + ; src + + ;
}
}
}
template < int SIZE > static void setVectorTypefp ( CgRuntimeParameter * __restrict ptr , const void * __restrict v )
{
float * __restrict f = ( float * ) v ;
float * __restrict data = ( float * ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
data [ i ] = f [ i ] ;
_CGprogram * program = ptr - > program ;
CgParameterResource * parameterResource = _RGLGetParameterResource ( ptr - > program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
unsigned short * ec = ( unsigned short * ) ( ptr - > program - > resources ) + resource + 1 ;
if ( RGL_LIKELY ( * ec ) )
{
swapandsetfp < SIZE > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) data ) ;
}
}
template < int SIZE > static void setVectorTypeSharedfpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int )
{
}
template < int SIZE > static void setVectorTypeSharedfpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
}
template < int SIZE > static void setVectorTypeSharedvpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int )
{
const float * __restrict f = ( const float * __restrict ) v ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( ptr - > program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
float * __restrict dst = ( float * __restrict ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
dst [ i ] = f [ i ] ;
_RGLPlatformSetVertexRegister4fv ( resource , dst ) ;
}
template < int SIZE > static void setVectorTypeSharedvpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
const float * __restrict f = ( const float * __restrict ) v ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( ptr - > program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource + index ;
float * __restrict dst = ( float * __restrict ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
dst [ i ] = f [ i ] ;
_RGLPlatformSetVertexRegister4fv ( resource , dst ) ;
}
template < int SIZE > static void setVectorTypevpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int )
{
PSGLcontext * LContext = _CurrentContext ;
const float * __restrict f = ( const float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
dst [ i ] = f [ i ] ;
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_CONSTANTS ;
}
template < int SIZE > static void setVectorTypevpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
PSGLcontext * LContext = _CurrentContext ;
const float * __restrict f = ( const float * ) v ;
float * __restrict dst = ( float * ) ( * ( ( unsigned int * * ) ptr - > pushBufferPointer + index ) ) ;
for ( long i = 0 ; i < SIZE ; + + i )
dst [ i ] = f [ i ] ;
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_CONSTANTS ;
}
template < int SIZE > static void setVectorTypefpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int )
{
float * __restrict f = ( float * ) v ;
float * __restrict data = ( float * ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
data [ i ] = f [ i ] ;
_CGprogram * program = ptr - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
unsigned short * ec = ( unsigned short * ) ( ptr - > program - > resources ) + resource + 1 ;
if ( RGL_LIKELY ( * ec ) )
{
swapandsetfp < SIZE > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) data ) ;
}
}
template < int SIZE > static void setVectorTypefpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
float * __restrict f = ( float * ) v ;
float * __restrict data = ( float * ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
data [ i ] = f [ i ] ;
_CGprogram * program = ptr - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
unsigned short * ec = ( unsigned short * ) ( program - > resources ) + resource + 1 ;
int arrayIndex = index ;
while ( arrayIndex )
{
ec + = ( ( * ec ) + 2 ) ;
arrayIndex - - ;
}
if ( RGL_LIKELY ( * ec ) )
{
swapandsetfp < SIZE > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) data ) ;
}
}
template < int ROWS , int COLS , int ORDER > static void setMatrixvpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
PSGLcontext * LContext = _CurrentContext ;
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
}
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_CONSTANTS ;
}
template < int ROWS , int COLS , int ORDER > static void setMatrixSharedvpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int /*index*/ )
{
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( ptr - > program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
float tmp [ ROWS * 4 ] ;
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
{
tmp [ row * 4 + col ] = dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
}
for ( long col = COLS ; col < 4 ; + + col ) tmp [ row * 4 + col ] = dst [ row * 4 + col ] ;
}
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , resource , ROWS , ( const float * ) tmp ) ;
}
template < int ROWS , int COLS , int ORDER > static void setMatrixSharedvpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( ptr - > program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource + index * ROWS ;
float tmp [ ROWS * 4 ] ;
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
{
tmp [ row * 4 + col ] = dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
}
for ( long col = COLS ; col < 4 ; + + col ) tmp [ row * 4 + col ] = dst [ row * 4 + col ] ;
}
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , resource , ROWS , ( const float * ) tmp ) ;
}
template < int ROWS , int COLS , int ORDER > static void setMatrixSharedfpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int /*index*/ )
{
}
template < int ROWS , int COLS , int ORDER > static void setMatrixSharedfpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
}
template < int ROWS , int COLS , int ORDER > static void setMatrixvpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
PSGLcontext * LContext = _CurrentContext ;
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ( * ( ( unsigned int * * ) ptr - > pushBufferPointer + index ) ) ;
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
}
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_CONSTANTS ;
}
template < int ROWS , int COLS , int ORDER > static void setMatrixfpIndex ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int /*index*/ )
{
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
_CGprogram * program = ( ( CgRuntimeParameter * ) ptr ) - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
unsigned short * ec = ( unsigned short * ) program - > resources + resource + 1 ;
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
int count = * ec ;
if ( RGL_LIKELY ( count ) )
{
swapandsetfp < COLS > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) dst + row * 4 ) ;
}
ec + = count + 2 ;
}
}
template < int ROWS , int COLS , int ORDER > static void setMatrixfpIndexArray ( CgRuntimeParameter * __restrict ptr , const void * __restrict v , const int index )
{
float * __restrict f = ( float * ) v ;
float * __restrict dst = ( float * ) ptr - > pushBufferPointer ;
_CGprogram * program = ptr - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ptr - > parameterEntry ) ;
unsigned short resource = parameterResource - > resource ;
unsigned short * ec = ( unsigned short * ) program - > resources + resource + 1 ;
int arrayIndex = index * ROWS ;
while ( arrayIndex )
{
unsigned short count = ( * ec ) ;
ec + = ( count + 2 ) ;
arrayIndex - - ;
}
for ( long row = 0 ; row < ROWS ; + + row )
{
for ( long col = 0 ; col < COLS ; + + col )
dst [ row * 4 + col ] = ( ORDER = = ROW_MAJOR ) ? f [ row * COLS + col ] : f [ col * ROWS + row ] ;
int count = * ec ;
if ( RGL_LIKELY ( count ) )
{
swapandsetfp < COLS > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) dst + row * 4 ) ;
}
ec + = count + 2 ;
}
}
static _cgSetArrayIndexFunction setVectorTypeIndex [ 2 ] [ 2 ] [ 2 ] [ 4 ] =
{
{
{
{ & setVectorTypevpIndex < 1 > , & setVectorTypevpIndex < 2 > , & setVectorTypevpIndex < 3 > , & setVectorTypevpIndex < 4 > , } ,
{ & setVectorTypefpIndex < 1 > , & setVectorTypefpIndex < 2 > , & setVectorTypefpIndex < 3 > , & setVectorTypefpIndex < 4 > , }
} ,
{
{ & setVectorTypeSharedvpIndex < 1 > , & setVectorTypeSharedvpIndex < 2 > , & setVectorTypeSharedvpIndex < 3 > , & setVectorTypeSharedvpIndex < 4 > , } ,
{ & setVectorTypeSharedfpIndex < 1 > , & setVectorTypeSharedfpIndex < 2 > , & setVectorTypeSharedfpIndex < 3 > , & setVectorTypeSharedfpIndex < 4 > , }
} ,
} ,
{
{
{ & setVectorTypevpIndexArray < 1 > , & setVectorTypevpIndexArray < 2 > , & setVectorTypevpIndexArray < 3 > , & setVectorTypevpIndexArray < 4 > , } ,
{ & setVectorTypefpIndexArray < 1 > , & setVectorTypefpIndexArray < 2 > , & setVectorTypefpIndexArray < 3 > , & setVectorTypefpIndexArray < 4 > , }
} ,
{
{ & setVectorTypeSharedvpIndexArray < 1 > , & setVectorTypeSharedvpIndexArray < 2 > , & setVectorTypeSharedvpIndexArray < 3 > , & setVectorTypeSharedvpIndexArray < 4 > , } , //should be the shared
{ & setVectorTypeSharedfpIndexArray < 1 > , & setVectorTypeSharedfpIndexArray < 2 > , & setVectorTypeSharedfpIndexArray < 3 > , & setVectorTypeSharedfpIndexArray < 4 > , } //should be the shared
} ,
} ,
} ;
static _cgSetArrayIndexFunction setMatrixTypeIndex [ 2 ] [ 2 ] [ 2 ] [ 4 ] [ 4 ] [ 2 ] =
{
{
{
{
{ { & setMatrixvpIndex < 1 , 1 , 0 > , & setMatrixvpIndex < 1 , 1 , 1 > } , { & setMatrixvpIndex < 1 , 2 , 0 > , & setMatrixvpIndex < 1 , 2 , 1 > } , { & setMatrixvpIndex < 1 , 3 , 0 > , & setMatrixvpIndex < 1 , 3 , 1 > } , { & setMatrixvpIndex < 1 , 4 , 0 > , & setMatrixvpIndex < 1 , 4 , 1 > } } ,
{ { & setMatrixvpIndex < 2 , 1 , 0 > , & setMatrixvpIndex < 2 , 1 , 1 > } , { & setMatrixvpIndex < 2 , 2 , 0 > , & setMatrixvpIndex < 2 , 2 , 1 > } , { & setMatrixvpIndex < 2 , 3 , 0 > , & setMatrixvpIndex < 2 , 3 , 1 > } , { & setMatrixvpIndex < 2 , 4 , 0 > , & setMatrixvpIndex < 2 , 4 , 1 > } } ,
{ { & setMatrixvpIndex < 3 , 1 , 0 > , & setMatrixvpIndex < 3 , 1 , 1 > } , { & setMatrixvpIndex < 3 , 2 , 0 > , & setMatrixvpIndex < 3 , 2 , 1 > } , { & setMatrixvpIndex < 3 , 3 , 0 > , & setMatrixvpIndex < 3 , 3 , 1 > } , { & setMatrixvpIndex < 3 , 4 , 0 > , & setMatrixvpIndex < 3 , 4 , 1 > } } ,
{ { & setMatrixvpIndex < 4 , 1 , 0 > , & setMatrixvpIndex < 4 , 1 , 1 > } , { & setMatrixvpIndex < 4 , 2 , 0 > , & setMatrixvpIndex < 4 , 2 , 1 > } , { & setMatrixvpIndex < 4 , 3 , 0 > , & setMatrixvpIndex < 4 , 3 , 1 > } , { & setMatrixvpIndex < 4 , 4 , 0 > , & setMatrixvpIndex < 4 , 4 , 1 > } } ,
} ,
{
{ { & setMatrixfpIndex < 1 , 1 , 0 > , & setMatrixfpIndex < 1 , 1 , 1 > } , { & setMatrixfpIndex < 1 , 2 , 0 > , & setMatrixfpIndex < 1 , 2 , 1 > } , { & setMatrixfpIndex < 1 , 3 , 0 > , & setMatrixfpIndex < 1 , 3 , 1 > } , { & setMatrixfpIndex < 1 , 4 , 0 > , & setMatrixfpIndex < 1 , 4 , 1 > } } ,
{ { & setMatrixfpIndex < 2 , 1 , 0 > , & setMatrixfpIndex < 2 , 1 , 1 > } , { & setMatrixfpIndex < 2 , 2 , 0 > , & setMatrixfpIndex < 2 , 2 , 1 > } , { & setMatrixfpIndex < 2 , 3 , 0 > , & setMatrixfpIndex < 2 , 3 , 1 > } , { & setMatrixfpIndex < 2 , 4 , 0 > , & setMatrixfpIndex < 2 , 4 , 1 > } } ,
{ { & setMatrixfpIndex < 3 , 1 , 0 > , & setMatrixfpIndex < 3 , 1 , 1 > } , { & setMatrixfpIndex < 3 , 2 , 0 > , & setMatrixfpIndex < 3 , 2 , 1 > } , { & setMatrixfpIndex < 3 , 3 , 0 > , & setMatrixfpIndex < 3 , 3 , 1 > } , { & setMatrixfpIndex < 3 , 4 , 0 > , & setMatrixfpIndex < 3 , 4 , 1 > } } ,
{ { & setMatrixfpIndex < 4 , 1 , 0 > , & setMatrixfpIndex < 4 , 1 , 1 > } , { & setMatrixfpIndex < 4 , 2 , 0 > , & setMatrixfpIndex < 4 , 2 , 1 > } , { & setMatrixfpIndex < 4 , 3 , 0 > , & setMatrixfpIndex < 4 , 3 , 1 > } , { & setMatrixfpIndex < 4 , 4 , 0 > , & setMatrixfpIndex < 4 , 4 , 1 > } } ,
} ,
} ,
{ //should be shared
{
{ { & setMatrixSharedvpIndex < 1 , 1 , 0 > , & setMatrixSharedvpIndex < 1 , 1 , 1 > } , { & setMatrixSharedvpIndex < 1 , 2 , 0 > , & setMatrixSharedvpIndex < 1 , 2 , 1 > } , { & setMatrixSharedvpIndex < 1 , 3 , 0 > , & setMatrixSharedvpIndex < 1 , 3 , 1 > } , { & setMatrixSharedvpIndex < 1 , 4 , 0 > , & setMatrixSharedvpIndex < 1 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndex < 2 , 1 , 0 > , & setMatrixSharedvpIndex < 2 , 1 , 1 > } , { & setMatrixSharedvpIndex < 2 , 2 , 0 > , & setMatrixSharedvpIndex < 2 , 2 , 1 > } , { & setMatrixSharedvpIndex < 2 , 3 , 0 > , & setMatrixSharedvpIndex < 2 , 3 , 1 > } , { & setMatrixSharedvpIndex < 2 , 4 , 0 > , & setMatrixSharedvpIndex < 2 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndex < 3 , 1 , 0 > , & setMatrixSharedvpIndex < 3 , 1 , 1 > } , { & setMatrixSharedvpIndex < 3 , 2 , 0 > , & setMatrixSharedvpIndex < 3 , 2 , 1 > } , { & setMatrixSharedvpIndex < 3 , 3 , 0 > , & setMatrixSharedvpIndex < 3 , 3 , 1 > } , { & setMatrixSharedvpIndex < 3 , 4 , 0 > , & setMatrixSharedvpIndex < 3 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndex < 4 , 1 , 0 > , & setMatrixSharedvpIndex < 4 , 1 , 1 > } , { & setMatrixSharedvpIndex < 4 , 2 , 0 > , & setMatrixSharedvpIndex < 4 , 2 , 1 > } , { & setMatrixSharedvpIndex < 4 , 3 , 0 > , & setMatrixSharedvpIndex < 4 , 3 , 1 > } , { & setMatrixSharedvpIndex < 4 , 4 , 0 > , & setMatrixSharedvpIndex < 4 , 4 , 1 > } } ,
} ,
{
{ { & setMatrixSharedfpIndex < 1 , 1 , 0 > , & setMatrixSharedfpIndex < 1 , 1 , 1 > } , { & setMatrixSharedfpIndex < 1 , 2 , 0 > , & setMatrixSharedfpIndex < 1 , 2 , 1 > } , { & setMatrixSharedfpIndex < 1 , 3 , 0 > , & setMatrixSharedfpIndex < 1 , 3 , 1 > } , { & setMatrixSharedfpIndex < 1 , 4 , 0 > , & setMatrixSharedfpIndex < 1 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndex < 2 , 1 , 0 > , & setMatrixSharedfpIndex < 2 , 1 , 1 > } , { & setMatrixSharedfpIndex < 2 , 2 , 0 > , & setMatrixSharedfpIndex < 2 , 2 , 1 > } , { & setMatrixSharedfpIndex < 2 , 3 , 0 > , & setMatrixSharedfpIndex < 2 , 3 , 1 > } , { & setMatrixSharedfpIndex < 2 , 4 , 0 > , & setMatrixSharedfpIndex < 2 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndex < 3 , 1 , 0 > , & setMatrixSharedfpIndex < 3 , 1 , 1 > } , { & setMatrixSharedfpIndex < 3 , 2 , 0 > , & setMatrixSharedfpIndex < 3 , 2 , 1 > } , { & setMatrixSharedfpIndex < 3 , 3 , 0 > , & setMatrixSharedfpIndex < 3 , 3 , 1 > } , { & setMatrixSharedfpIndex < 3 , 4 , 0 > , & setMatrixSharedfpIndex < 3 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndex < 4 , 1 , 0 > , & setMatrixSharedfpIndex < 4 , 1 , 1 > } , { & setMatrixSharedfpIndex < 4 , 2 , 0 > , & setMatrixSharedfpIndex < 4 , 2 , 1 > } , { & setMatrixSharedfpIndex < 4 , 3 , 0 > , & setMatrixSharedfpIndex < 4 , 3 , 1 > } , { & setMatrixSharedfpIndex < 4 , 4 , 0 > , & setMatrixSharedfpIndex < 4 , 4 , 1 > } } ,
} ,
} ,
} ,
{
{
{
{ { & setMatrixvpIndexArray < 1 , 1 , 0 > , & setMatrixvpIndexArray < 1 , 1 , 1 > } , { & setMatrixvpIndexArray < 1 , 2 , 0 > , & setMatrixvpIndexArray < 1 , 2 , 1 > } , { & setMatrixvpIndexArray < 1 , 3 , 0 > , & setMatrixvpIndexArray < 1 , 3 , 1 > } , { & setMatrixvpIndexArray < 1 , 4 , 0 > , & setMatrixvpIndexArray < 1 , 4 , 1 > } } ,
{ { & setMatrixvpIndexArray < 2 , 1 , 0 > , & setMatrixvpIndexArray < 2 , 1 , 1 > } , { & setMatrixvpIndexArray < 2 , 2 , 0 > , & setMatrixvpIndexArray < 2 , 2 , 1 > } , { & setMatrixvpIndexArray < 2 , 3 , 0 > , & setMatrixvpIndexArray < 2 , 3 , 1 > } , { & setMatrixvpIndexArray < 2 , 4 , 0 > , & setMatrixvpIndexArray < 2 , 4 , 1 > } } ,
{ { & setMatrixvpIndexArray < 3 , 1 , 0 > , & setMatrixvpIndexArray < 3 , 1 , 1 > } , { & setMatrixvpIndexArray < 3 , 2 , 0 > , & setMatrixvpIndexArray < 3 , 2 , 1 > } , { & setMatrixvpIndexArray < 3 , 3 , 0 > , & setMatrixvpIndexArray < 3 , 3 , 1 > } , { & setMatrixvpIndexArray < 3 , 4 , 0 > , & setMatrixvpIndexArray < 3 , 4 , 1 > } } ,
{ { & setMatrixvpIndexArray < 4 , 1 , 0 > , & setMatrixvpIndexArray < 4 , 1 , 1 > } , { & setMatrixvpIndexArray < 4 , 2 , 0 > , & setMatrixvpIndexArray < 4 , 2 , 1 > } , { & setMatrixvpIndexArray < 4 , 3 , 0 > , & setMatrixvpIndexArray < 4 , 3 , 1 > } , { & setMatrixvpIndexArray < 4 , 4 , 0 > , & setMatrixvpIndexArray < 4 , 4 , 1 > } } ,
} ,
{
{ { & setMatrixfpIndexArray < 1 , 1 , 0 > , & setMatrixfpIndexArray < 1 , 1 , 1 > } , { & setMatrixfpIndexArray < 1 , 2 , 0 > , & setMatrixfpIndexArray < 1 , 2 , 1 > } , { & setMatrixfpIndexArray < 1 , 3 , 0 > , & setMatrixfpIndexArray < 1 , 3 , 1 > } , { & setMatrixfpIndexArray < 1 , 4 , 0 > , & setMatrixfpIndexArray < 1 , 4 , 1 > } } ,
{ { & setMatrixfpIndexArray < 2 , 1 , 0 > , & setMatrixfpIndexArray < 2 , 1 , 1 > } , { & setMatrixfpIndexArray < 2 , 2 , 0 > , & setMatrixfpIndexArray < 2 , 2 , 1 > } , { & setMatrixfpIndexArray < 2 , 3 , 0 > , & setMatrixfpIndexArray < 2 , 3 , 1 > } , { & setMatrixfpIndexArray < 2 , 4 , 0 > , & setMatrixfpIndexArray < 2 , 4 , 1 > } } ,
{ { & setMatrixfpIndexArray < 3 , 1 , 0 > , & setMatrixfpIndexArray < 3 , 1 , 1 > } , { & setMatrixfpIndexArray < 3 , 2 , 0 > , & setMatrixfpIndexArray < 3 , 2 , 1 > } , { & setMatrixfpIndexArray < 3 , 3 , 0 > , & setMatrixfpIndexArray < 3 , 3 , 1 > } , { & setMatrixfpIndexArray < 3 , 4 , 0 > , & setMatrixfpIndexArray < 3 , 4 , 1 > } } ,
{ { & setMatrixfpIndexArray < 4 , 1 , 0 > , & setMatrixfpIndexArray < 4 , 1 , 1 > } , { & setMatrixfpIndexArray < 4 , 2 , 0 > , & setMatrixfpIndexArray < 4 , 2 , 1 > } , { & setMatrixfpIndexArray < 4 , 3 , 0 > , & setMatrixfpIndexArray < 4 , 3 , 1 > } , { & setMatrixfpIndexArray < 4 , 4 , 0 > , & setMatrixfpIndexArray < 4 , 4 , 1 > } } ,
} ,
} ,
{ //should be shared
{
{ { & setMatrixSharedvpIndexArray < 1 , 1 , 0 > , & setMatrixSharedvpIndexArray < 1 , 1 , 1 > } , { & setMatrixSharedvpIndexArray < 1 , 2 , 0 > , & setMatrixSharedvpIndexArray < 1 , 2 , 1 > } , { & setMatrixSharedvpIndexArray < 1 , 3 , 0 > , & setMatrixSharedvpIndexArray < 1 , 3 , 1 > } , { & setMatrixSharedvpIndexArray < 1 , 4 , 0 > , & setMatrixSharedvpIndexArray < 1 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndexArray < 2 , 1 , 0 > , & setMatrixSharedvpIndexArray < 2 , 1 , 1 > } , { & setMatrixSharedvpIndexArray < 2 , 2 , 0 > , & setMatrixSharedvpIndexArray < 2 , 2 , 1 > } , { & setMatrixSharedvpIndexArray < 2 , 3 , 0 > , & setMatrixSharedvpIndexArray < 2 , 3 , 1 > } , { & setMatrixSharedvpIndexArray < 2 , 4 , 0 > , & setMatrixSharedvpIndexArray < 2 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndexArray < 3 , 1 , 0 > , & setMatrixSharedvpIndexArray < 3 , 1 , 1 > } , { & setMatrixSharedvpIndexArray < 3 , 2 , 0 > , & setMatrixSharedvpIndexArray < 3 , 2 , 1 > } , { & setMatrixSharedvpIndexArray < 3 , 3 , 0 > , & setMatrixSharedvpIndexArray < 3 , 3 , 1 > } , { & setMatrixSharedvpIndexArray < 3 , 4 , 0 > , & setMatrixSharedvpIndexArray < 3 , 4 , 1 > } } ,
{ { & setMatrixSharedvpIndexArray < 4 , 1 , 0 > , & setMatrixSharedvpIndexArray < 4 , 1 , 1 > } , { & setMatrixSharedvpIndexArray < 4 , 2 , 0 > , & setMatrixSharedvpIndexArray < 4 , 2 , 1 > } , { & setMatrixSharedvpIndexArray < 4 , 3 , 0 > , & setMatrixSharedvpIndexArray < 4 , 3 , 1 > } , { & setMatrixSharedvpIndexArray < 4 , 4 , 0 > , & setMatrixSharedvpIndexArray < 4 , 4 , 1 > } } ,
} ,
{
{ { & setMatrixSharedfpIndexArray < 1 , 1 , 0 > , & setMatrixSharedfpIndexArray < 1 , 1 , 1 > } , { & setMatrixSharedfpIndexArray < 1 , 2 , 0 > , & setMatrixSharedfpIndexArray < 1 , 2 , 1 > } , { & setMatrixSharedfpIndexArray < 1 , 3 , 0 > , & setMatrixSharedfpIndexArray < 1 , 3 , 1 > } , { & setMatrixSharedfpIndexArray < 1 , 4 , 0 > , & setMatrixSharedfpIndexArray < 1 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndexArray < 2 , 1 , 0 > , & setMatrixSharedfpIndexArray < 2 , 1 , 1 > } , { & setMatrixSharedfpIndexArray < 2 , 2 , 0 > , & setMatrixSharedfpIndexArray < 2 , 2 , 1 > } , { & setMatrixSharedfpIndexArray < 2 , 3 , 0 > , & setMatrixSharedfpIndexArray < 2 , 3 , 1 > } , { & setMatrixSharedfpIndexArray < 2 , 4 , 0 > , & setMatrixSharedfpIndexArray < 2 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndexArray < 3 , 1 , 0 > , & setMatrixSharedfpIndexArray < 3 , 1 , 1 > } , { & setMatrixSharedfpIndexArray < 3 , 2 , 0 > , & setMatrixSharedfpIndexArray < 3 , 2 , 1 > } , { & setMatrixSharedfpIndexArray < 3 , 3 , 0 > , & setMatrixSharedfpIndexArray < 3 , 3 , 1 > } , { & setMatrixSharedfpIndexArray < 3 , 4 , 0 > , & setMatrixSharedfpIndexArray < 3 , 4 , 1 > } } ,
{ { & setMatrixSharedfpIndexArray < 4 , 1 , 0 > , & setMatrixSharedfpIndexArray < 4 , 1 , 1 > } , { & setMatrixSharedfpIndexArray < 4 , 2 , 0 > , & setMatrixSharedfpIndexArray < 4 , 2 , 1 > } , { & setMatrixSharedfpIndexArray < 4 , 3 , 0 > , & setMatrixSharedfpIndexArray < 4 , 3 , 1 > } , { & setMatrixSharedfpIndexArray < 4 , 4 , 0 > , & setMatrixSharedfpIndexArray < 4 , 4 , 1 > } } ,
} ,
} ,
}
} ;
_cgSetArrayIndexFunction getVectorTypeIndexSetterFunction ( unsigned short a , unsigned short b , unsigned short c , unsigned short d )
{
return setVectorTypeIndex [ a ] [ b ] [ c ] [ d ] ;
}
_cgSetArrayIndexFunction getMatrixTypeIndexSetterFunction ( unsigned short a , unsigned short b , unsigned short c , unsigned short d , unsigned short e , unsigned short f )
{
return setMatrixTypeIndex [ a ] [ b ] [ c ] [ d ] [ e ] [ f ] ;
}
static void _RGLBindTextureInternal ( jsTextureImageUnit * unit , GLuint name )
{
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture = NULL ;
if ( name )
{
_RGLTexNameSpaceCreateNameLazy ( & LContext - > textureNameSpace , name ) ;
texture = ( jsTexture * ) LContext - > textureNameSpace . data [ name ] ;
texture - > target = GL_TEXTURE_2D ;
}
unit - > bound2D = name ;
unit - > currentTexture = _RGLGetCurrentTexture ( unit , GL_TEXTURE_2D ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED ;
}
static void setSamplerfp ( CgRuntimeParameter * ptr , const void * v , int )
{
_CGprogram * program = ( ( CgRuntimeParameter * ) ptr ) - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ( ( CgRuntimeParameter * ) ptr ) - > parameterEntry ) ;
if ( v )
{
* ( GLuint * ) ptr - > pushBufferPointer = * ( GLuint * ) v ;
}
else
{
jsTextureImageUnit * unit = _CurrentContext - > TextureImageUnits + ( parameterResource - > resource - CG_TEXUNIT0 ) ;
_RGLBindTextureInternal ( unit , * ( GLuint * ) ptr - > pushBufferPointer ) ;
}
}
static void setSamplervp ( CgRuntimeParameter * ptr , const void * v , int )
{
_CGprogram * program = ( ( CgRuntimeParameter * ) ptr ) - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ( ( CgRuntimeParameter * ) ptr ) - > parameterEntry ) ;
if ( v )
{
* ( GLuint * ) ptr - > pushBufferPointer = * ( GLuint * ) v ;
}
else
{
GLuint unit = parameterResource - > resource - CG_TEXUNIT0 ;
GLuint name = * ( GLuint * ) ptr - > pushBufferPointer ;
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture = NULL ;
if ( name & & ( name < LContext - > textureNameSpace . capacity ) )
texture = ( jsTexture * ) LContext - > textureNameSpace . data [ name ] ;
LContext - > VertexTextureImages [ unit ] = texture ;
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
}
static void _RGLCreatePushBuffer ( _CGprogram * program )
{
int bufferSize = 0 ;
int programPushBufferPointersSize = 0 ;
int extraStorageInWords = 0 ;
int offsetCount = 0 ;
int samplerCount = 0 ;
int profileIndex = ( program - > header . profile = = CG_PROFILE_SCE_FP_TYPEB | |
program - > header . profile = = CG_PROFILE_SCE_FP_RSX ) ? FRAGMENT_PROFILE_INDEX : VERTEX_PROFILE_INDEX ;
bool hasSharedParams = false ;
int arrayCount = 1 ;
for ( int i = 0 ; i < program - > rtParametersCount ; i + + )
{
const CgParameterEntry * parameterEntry = program - > parametersEntries + i ;
if ( ( parameterEntry - > flags & CGP_STRUCTURE ) | | ( parameterEntry - > flags & CGP_UNROLLED ) )
{
arrayCount = 1 ;
continue ;
}
if ( ( parameterEntry - > flags & CGPF_REFERENCED ) )
{
if ( parameterEntry - > flags & CGP_ARRAY )
{
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , parameterEntry ) ;
arrayCount = _RGLGetSizeofSubArray ( parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
continue ;
}
if ( ( parameterEntry - > flags & CGPV_MASK ) = = CGPV_UNIFORM )
{
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
if ( parameterResource - > type > = CG_SAMPLER1D & & parameterResource - > type < = CG_SAMPLERCUBE )
{
offsetCount + = arrayCount ;
samplerCount + = arrayCount ;
}
else if ( profileIndex = = VERTEX_PROFILE_INDEX )
{
if ( parameterResource - > type = = CGP_SCF_BOOL )
{
}
else if ( ! ( parameterEntry - > flags & CGPF_SHARED ) )
{
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
if ( parameterEntry - > flags & CGP_CONTIGUOUS )
bufferSize + = 3 + 4 * arrayCount * registerStride ;
else
{
programPushBufferPointersSize + = arrayCount ;
int resourceIndex = parameterResource - > resource ;
int referencedSize = 3 + 4 * registerStride ;
int notReferencedSize = 4 * registerStride ;
for ( int j = 0 ; j < arrayCount ; j + + , resourceIndex + = registerStride )
{
if ( program - > resources [ resourceIndex ] ! = 0xffff )
bufferSize + = referencedSize ;
else
extraStorageInWords + = notReferencedSize ;
}
}
}
else
{
hasSharedParams = true ;
if ( ! ( parameterEntry - > flags & CGP_CONTIGUOUS ) )
{
programPushBufferPointersSize + = arrayCount ;
}
}
}
else
{
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
if ( ! ( parameterEntry - > flags & CGPF_SHARED ) )
{
extraStorageInWords + = 4 * arrayCount * registerStride ;
}
else
{
hasSharedParams = true ;
unsigned short * resource = program - > resources + parameterResource - > resource ;
for ( int j = 0 ; j < arrayCount * registerStride ; j + + )
{
resource + + ;
unsigned short count = * resource + + ;
bufferSize + = 24 * count ;
resource + = count ;
}
}
}
}
}
arrayCount = 1 ;
}
if ( ( profileIndex = = FRAGMENT_PROFILE_INDEX ) & & ( hasSharedParams ) )
{
bufferSize + = 8 + 3 + 2 ;
}
bufferSize = _RGLPad ( bufferSize , 4 ) ;
unsigned int storageSizeInWords = bufferSize + extraStorageInWords ;
if ( storageSizeInWords )
program - > memoryBlock = ( unsigned int * ) memalign ( 16 , storageSizeInWords * 4 ) ;
else
program - > memoryBlock = NULL ;
program - > samplerCount = samplerCount ;
if ( samplerCount )
{
program - > samplerValuesLocation = ( GLuint * ) malloc ( samplerCount * sizeof ( GLuint ) ) ;
program - > samplerIndices = ( GLuint * ) malloc ( samplerCount * sizeof ( GLuint ) ) ;
program - > samplerUnits = ( GLuint * ) malloc ( samplerCount * sizeof ( GLuint ) ) ;
}
else
{
program - > samplerValuesLocation = NULL ;
program - > samplerIndices = NULL ;
program - > samplerUnits = NULL ;
}
GLuint * samplerValuesLocation = program - > samplerValuesLocation ;
GLuint * samplerIndices = program - > samplerIndices ;
GLuint * samplerUnits = program - > samplerUnits ;
if ( programPushBufferPointersSize )
program - > constantPushBufferPointers = ( unsigned int * * ) malloc ( programPushBufferPointersSize * 4 ) ;
else
program - > constantPushBufferPointers = NULL ;
uint32_t * RGLCurrent = ( uint32_t * ) program - > memoryBlock ;
program - > constantPushBuffer = ( bufferSize > 0 ) ? ( unsigned int * ) RGLCurrent : NULL ;
unsigned int * * programPushBuffer = program - > constantPushBufferPointers ;
program - > constantPushBufferWordSize = bufferSize ;
GLuint * currentStorage = ( GLuint * ) ( RGLCurrent + bufferSize ) ;
arrayCount = 1 ;
const CgParameterEntry * containerEntry = NULL ;
for ( int i = 0 ; i < program - > rtParametersCount ; i + + )
{
CgRuntimeParameter * rtParameter = program - > runtimeParameters + i ;
const CgParameterEntry * parameterEntry = program - > parametersEntries + i ;
if ( containerEntry = = NULL )
containerEntry = parameterEntry ;
rtParameter - > samplerSetter = _cgRaiseInvalidParamIndex ;
rtParameter - > setterIndex = _cgRaiseInvalidParamIndex ;
rtParameter - > setterrIndex = _cgRaiseNotMatrixParamIndex ;
rtParameter - > settercIndex = _cgRaiseNotMatrixParamIndex ;
CGparameter id = ( CGparameter ) _RGLCreateName ( & _CurrentContext - > cgParameterNameSpace , ( void * ) rtParameter ) ;
if ( ! id )
break ;
rtParameter - > id = id ;
rtParameter - > parameterEntry = parameterEntry ;
rtParameter - > program = program ;
if ( ( parameterEntry - > flags & CGP_STRUCTURE ) | | ( parameterEntry - > flags & CGP_UNROLLED ) )
{
arrayCount = 1 ;
containerEntry = NULL ;
continue ;
}
if ( parameterEntry - > flags & CGPF_REFERENCED )
{
if ( parameterEntry - > flags & CGP_ARRAY )
{
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , parameterEntry ) ;
arrayCount = _RGLGetSizeofSubArray ( parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
continue ;
}
if ( ( parameterEntry - > flags & CGPV_MASK ) = = CGPV_UNIFORM )
{
rtParameter - > glType = GL_NONE ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
if ( parameterResource - > type > = CG_SAMPLER1D & & parameterResource - > type < = CG_SAMPLERCUBE )
{
rtParameter - > pushBufferPointer = samplerValuesLocation ;
* samplerValuesLocation = 0 ;
samplerValuesLocation + + ;
* samplerIndices = i ;
samplerIndices + + ;
* samplerUnits = parameterResource - > resource - CG_TEXUNIT0 ;
samplerUnits + + ;
if ( profileIndex = = VERTEX_PROFILE_INDEX )
{
rtParameter - > setterIndex = _cgIgnoreSetParamIndex ;
rtParameter - > samplerSetter = setSamplervp ;
}
else
{
rtParameter - > samplerSetter = setSamplerfp ;
}
rtParameter - > glType = _RGLCgGetSamplerGLTypeFromCgType ( ( CGtype ) ( parameterResource - > type ) ) ;
}
else
{
if ( profileIndex = = VERTEX_PROFILE_INDEX )
{
if ( parameterResource - > type = = CGP_SCF_BOOL )
{
}
else if ( ! ( parameterEntry - > flags & CGPF_SHARED ) )
{
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
int registerCount = arrayCount * registerStride ;
if ( parameterEntry - > flags & CGP_CONTIGUOUS )
{
memset ( RGLCurrent , 0 , 4 * ( 4 * registerCount + 3 ) ) ;
GCM_FUNC_BUFFERED ( cellGcmSetVertexProgramParameterBlock , RGLCurrent , parameterResource - > resource , registerCount , ( float * ) RGLCurrent ) ;
rtParameter - > pushBufferPointer = RGLCurrent - 4 * registerCount ;
}
else
{
rtParameter - > pushBufferPointer = programPushBuffer ;
int resourceIndex = parameterResource - > resource ;
for ( int j = 0 ; j < arrayCount ; j + + , resourceIndex + = registerStride )
{
if ( program - > resources [ resourceIndex ] ! = 0xffff )
{
memset ( RGLCurrent , 0 , 4 * ( 4 * registerStride + 3 ) ) ;
GCM_FUNC_BUFFERED ( cellGcmSetVertexProgramParameterBlock , RGLCurrent , program - > resources [ resourceIndex ] , registerStride , ( float * ) RGLCurrent ) ;
* ( programPushBuffer + + ) = ( unsigned int * ) ( RGLCurrent - 4 * registerStride ) ;
}
else
{
* ( programPushBuffer + + ) = ( unsigned int * ) currentStorage ;
currentStorage + = 4 * registerStride ;
}
}
}
}
}
else
{
if ( parameterEntry - > flags & CGPF_SHARED )
{
rtParameter - > pushBufferPointer = NULL ;
}
else
{
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
int registerCount = arrayCount * registerStride ;
rtParameter - > pushBufferPointer = currentStorage ;
currentStorage + = 4 * registerCount ;
}
}
switch ( parameterResource - > type )
{
case CG_FLOAT :
case CG_FLOAT1 : case CG_FLOAT2 : case CG_FLOAT3 : case CG_FLOAT4 :
{
unsigned int floatCount = _RGLCountFloatsInCgType ( ( CGtype ) parameterResource - > type ) ;
rtParameter - > setterIndex = setVectorTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ floatCount - 1 ] ;
}
break ;
case CG_FLOAT1x1 : case CG_FLOAT1x2 : case CG_FLOAT1x3 : case CG_FLOAT1x4 :
case CG_FLOAT2x1 : case CG_FLOAT2x2 : case CG_FLOAT2x3 : case CG_FLOAT2x4 :
case CG_FLOAT3x1 : case CG_FLOAT3x2 : case CG_FLOAT3x3 : case CG_FLOAT3x4 :
case CG_FLOAT4x1 : case CG_FLOAT4x2 : case CG_FLOAT4x3 : case CG_FLOAT4x4 :
rtParameter - > setterrIndex = setMatrixTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ _RGLGetTypeColCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ ROW_MAJOR ] ;
rtParameter - > settercIndex = setMatrixTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ _RGLGetTypeColCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ COL_MAJOR ] ;
break ;
case CG_SAMPLER1D : case CG_SAMPLER2D : case CG_SAMPLER3D : case CG_SAMPLERRECT : case CG_SAMPLERCUBE :
break ;
case CGP_SCF_BOOL :
break ;
case CG_HALF :
case CG_HALF1 : case CG_HALF2 : case CG_HALF3 : case CG_HALF4 :
case CG_INT :
case CG_INT1 : case CG_INT2 : case CG_INT3 : case CG_INT4 :
case CG_BOOL :
case CG_BOOL1 : case CG_BOOL2 : case CG_BOOL3 : case CG_BOOL4 :
case CG_FIXED :
case CG_FIXED1 : case CG_FIXED2 : case CG_FIXED3 : case CG_FIXED4 :
{
unsigned int floatCount = _RGLCountFloatsInCgType ( ( CGtype ) parameterResource - > type ) ;
rtParameter - > setterIndex = setVectorTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ floatCount - 1 ] ;
}
break ;
case CG_HALF1x1 : case CG_HALF1x2 : case CG_HALF1x3 : case CG_HALF1x4 :
case CG_HALF2x1 : case CG_HALF2x2 : case CG_HALF2x3 : case CG_HALF2x4 :
case CG_HALF3x1 : case CG_HALF3x2 : case CG_HALF3x3 : case CG_HALF3x4 :
case CG_HALF4x1 : case CG_HALF4x2 : case CG_HALF4x3 : case CG_HALF4x4 :
case CG_INT1x1 : case CG_INT1x2 : case CG_INT1x3 : case CG_INT1x4 :
case CG_INT2x1 : case CG_INT2x2 : case CG_INT2x3 : case CG_INT2x4 :
case CG_INT3x1 : case CG_INT3x2 : case CG_INT3x3 : case CG_INT3x4 :
case CG_INT4x1 : case CG_INT4x2 : case CG_INT4x3 : case CG_INT4x4 :
case CG_BOOL1x1 : case CG_BOOL1x2 : case CG_BOOL1x3 : case CG_BOOL1x4 :
case CG_BOOL2x1 : case CG_BOOL2x2 : case CG_BOOL2x3 : case CG_BOOL2x4 :
case CG_BOOL3x1 : case CG_BOOL3x2 : case CG_BOOL3x3 : case CG_BOOL3x4 :
case CG_BOOL4x1 : case CG_BOOL4x2 : case CG_BOOL4x3 : case CG_BOOL4x4 :
case CG_FIXED1x1 : case CG_FIXED1x2 : case CG_FIXED1x3 : case CG_FIXED1x4 :
case CG_FIXED2x1 : case CG_FIXED2x2 : case CG_FIXED2x3 : case CG_FIXED2x4 :
case CG_FIXED3x1 : case CG_FIXED3x2 : case CG_FIXED3x3 : case CG_FIXED3x4 :
case CG_FIXED4x1 : case CG_FIXED4x2 : case CG_FIXED4x3 : case CG_FIXED4x4 :
rtParameter - > setterrIndex = setMatrixTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ _RGLGetTypeColCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ ROW_MAJOR ] ;
rtParameter - > settercIndex = setMatrixTypeIndex [ ( containerEntry - > flags & CGP_ARRAY ) ? 1 : 0 ] [ ( containerEntry - > flags & CGPF_SHARED ) ? 1 : 0 ] [ profileIndex ] [ _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ _RGLGetTypeColCount ( ( CGtype ) parameterResource - > type ) - 1 ] [ COL_MAJOR ] ;
break ;
case CG_STRING :
break ;
default :
break ;
}
}
}
}
else
{
if ( ( parameterEntry - > flags & CGPV_MASK ) = = CGPV_UNIFORM )
{
if ( parameterEntry - > flags & CGP_ARRAY )
continue ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
switch ( parameterResource - > type )
{
case CG_FLOAT :
case CG_FLOAT1 : case CG_FLOAT2 : case CG_FLOAT3 : case CG_FLOAT4 :
rtParameter - > setterIndex = _cgIgnoreSetParamIndex ;
break ;
case CG_FLOAT1x1 : case CG_FLOAT1x2 : case CG_FLOAT1x3 : case CG_FLOAT1x4 :
case CG_FLOAT2x1 : case CG_FLOAT2x2 : case CG_FLOAT2x3 : case CG_FLOAT2x4 :
case CG_FLOAT3x1 : case CG_FLOAT3x2 : case CG_FLOAT3x3 : case CG_FLOAT3x4 :
case CG_FLOAT4x1 : case CG_FLOAT4x2 : case CG_FLOAT4x3 : case CG_FLOAT4x4 :
rtParameter - > setterrIndex = _cgIgnoreSetParamIndex ;
rtParameter - > settercIndex = _cgIgnoreSetParamIndex ;
break ;
case CG_SAMPLER1D : case CG_SAMPLER2D : case CG_SAMPLER3D : case CG_SAMPLERRECT : case CG_SAMPLERCUBE :
rtParameter - > samplerSetter = _cgIgnoreSetParamIndex ;
break ;
case CGP_SCF_BOOL :
break ;
case CG_HALF :
case CG_HALF1 : case CG_HALF2 : case CG_HALF3 : case CG_HALF4 :
case CG_INT :
case CG_INT1 : case CG_INT2 : case CG_INT3 : case CG_INT4 :
case CG_BOOL :
case CG_BOOL1 : case CG_BOOL2 : case CG_BOOL3 : case CG_BOOL4 :
case CG_FIXED :
case CG_FIXED1 : case CG_FIXED2 : case CG_FIXED3 : case CG_FIXED4 :
rtParameter - > setterIndex = _cgIgnoreSetParamIndex ;
break ;
case CG_HALF1x1 : case CG_HALF1x2 : case CG_HALF1x3 : case CG_HALF1x4 :
case CG_HALF2x1 : case CG_HALF2x2 : case CG_HALF2x3 : case CG_HALF2x4 :
case CG_HALF3x1 : case CG_HALF3x2 : case CG_HALF3x3 : case CG_HALF3x4 :
case CG_HALF4x1 : case CG_HALF4x2 : case CG_HALF4x3 : case CG_HALF4x4 :
case CG_INT1x1 : case CG_INT1x2 : case CG_INT1x3 : case CG_INT1x4 :
case CG_INT2x1 : case CG_INT2x2 : case CG_INT2x3 : case CG_INT2x4 :
case CG_INT3x1 : case CG_INT3x2 : case CG_INT3x3 : case CG_INT3x4 :
case CG_INT4x1 : case CG_INT4x2 : case CG_INT4x3 : case CG_INT4x4 :
case CG_BOOL1x1 : case CG_BOOL1x2 : case CG_BOOL1x3 : case CG_BOOL1x4 :
case CG_BOOL2x1 : case CG_BOOL2x2 : case CG_BOOL2x3 : case CG_BOOL2x4 :
case CG_BOOL3x1 : case CG_BOOL3x2 : case CG_BOOL3x3 : case CG_BOOL3x4 :
case CG_BOOL4x1 : case CG_BOOL4x2 : case CG_BOOL4x3 : case CG_BOOL4x4 :
case CG_FIXED1x1 : case CG_FIXED1x2 : case CG_FIXED1x3 : case CG_FIXED1x4 :
case CG_FIXED2x1 : case CG_FIXED2x2 : case CG_FIXED2x3 : case CG_FIXED2x4 :
case CG_FIXED3x1 : case CG_FIXED3x2 : case CG_FIXED3x3 : case CG_FIXED3x4 :
case CG_FIXED4x1 : case CG_FIXED4x2 : case CG_FIXED4x3 : case CG_FIXED4x4 :
rtParameter - > setterrIndex = _cgIgnoreSetParamIndex ;
rtParameter - > settercIndex = _cgIgnoreSetParamIndex ;
break ;
case CG_STRING :
break ;
default :
break ;
}
}
}
arrayCount = 1 ;
containerEntry = NULL ;
}
if ( bufferSize > 0 )
{
int nopCount = ( program - > constantPushBuffer + bufferSize ) - ( unsigned int * ) RGLCurrent ;
GCM_FUNC_BUFFERED ( cellGcmSetNopCommand , RGLCurrent , nopCount ) ;
}
}
static int _RGLGenerateProgram ( _CGprogram * program , int profileIndex , const CgProgramHeader * programHeader , const void * ucode , const CgParameterTableHeader * parameterHeader ,
const CgParameterEntry * parameterEntries , const char * stringTable , const float * defaultValues )
{
CGprofile profile = ( CGprofile ) programHeader - > profile ;
int need_swapping = 0 ;
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
if ( ( profile ! = CG_PROFILE_SCE_FP_TYPEB ) & & ( profile ! = CG_PROFILE_SCE_VP_TYPEB ) & &
( profile ! = CG_PROFILE_SCE_FP_RSX ) & & ( profile ! = CG_PROFILE_SCE_VP_RSX ) )
{
need_swapping = 1 ;
}
int invalidProfile = 0 ;
switch ( ENDIAN_32 ( profile , need_swapping ) )
{
case CG_PROFILE_SCE_VP_TYPEB :
if ( profileIndex ! = VERTEX_PROFILE_INDEX ) invalidProfile = 1 ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
if ( profileIndex ! = FRAGMENT_PROFILE_INDEX ) invalidProfile = 1 ;
break ;
case CG_PROFILE_SCE_VP_RSX :
if ( profileIndex ! = VERTEX_PROFILE_INDEX ) invalidProfile = 1 ;
break ;
case CG_PROFILE_SCE_FP_RSX :
if ( profileIndex ! = FRAGMENT_PROFILE_INDEX ) invalidProfile = 1 ;
break ;
default :
invalidProfile = 1 ;
break ;
}
if ( invalidProfile )
{
_RGLCgRaiseError ( CG_UNKNOWN_PROFILE_ERROR ) ;
return 0 ;
}
memcpy ( & program - > header , programHeader , sizeof ( program - > header ) ) ;
program - > ucode = ucode ;
program - > loadProgramId = GMM_ERROR ;
program - > loadProgramOffset = 0 ;
size_t parameterSize = parameterHeader - > entryCount * sizeof ( CgRuntimeParameter ) ;
void * memoryBlock ;
if ( parameterSize )
memoryBlock = memalign ( 16 , parameterSize ) ;
else
memoryBlock = NULL ;
program - > rtParametersCount = parameterHeader - > entryCount ;
program - > runtimeParameters = ( CgRuntimeParameter * ) memoryBlock ;
if ( parameterEntries = = NULL )
parameterEntries = ( CgParameterEntry * ) ( parameterHeader + 1 ) ;
program - > parametersEntries = parameterEntries ;
program - > parameterResources = ( char * ) ( program - > parametersEntries + program - > rtParametersCount ) ;
program - > resources = ( unsigned short * ) ( ( char * ) program - > parametersEntries + ( parameterHeader - > resourceTableOffset - sizeof ( CgParameterTableHeader ) ) ) ;
program - > defaultValuesIndexCount = parameterHeader - > defaultValueIndexCount ;
program - > defaultValuesIndices = ( CgParameterDefaultValue * ) ( ( char * ) program - > parametersEntries + ( parameterHeader - > defaultValueIndexTableOffset - sizeof ( CgParameterTableHeader ) ) ) ;
program - > defaultValues = NULL ;
memset ( program - > runtimeParameters , 0 , parameterHeader - > entryCount * sizeof ( CgRuntimeParameter ) ) ;
program - > stringTable = stringTable ;
program - > defaultValues = defaultValues ;
_RGLCreatePushBuffer ( program ) ;
int count = program - > defaultValuesIndexCount ;
if ( profileIndex = = FRAGMENT_PROFILE_INDEX )
{
for ( int i = 0 ; i < count ; i + + )
{
const void * __restrict pItemDefaultValues = program - > defaultValues + program - > defaultValuesIndices [ i ] . defaultValueIndex ;
const unsigned int * itemDefaultValues = ( const unsigned int * ) pItemDefaultValues ;
int index = ( int ) program - > defaultValuesIndices [ i ] . entryIndex ;
CgRuntimeParameter * rtParameter = program - > runtimeParameters + index ;
float * hostMemoryCopy = ( float * ) rtParameter - > pushBufferPointer ;
if ( hostMemoryCopy )
{
const CgParameterEntry * parameterEntry = rtParameter - > parameterEntry ;
int arrayCount = 1 ;
if ( parameterEntry - > flags & CGP_ARRAY )
{
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , parameterEntry ) ;
arrayCount = _RGLGetSizeofSubArray ( parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
i + + ;
parameterEntry + + ;
}
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
unsigned short * resource = program - > resources + parameterResource - > resource + 1 ;
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
int registerCount = arrayCount * registerStride ;
int j ;
for ( j = 0 ; j < registerCount ; j + + )
{
unsigned short embeddedConstCount = * ( resource + + ) ;
int k ;
for ( k = 0 ; k < embeddedConstCount ; k + + )
{
unsigned short ucodePatchOffset = * ( resource ) + + ;
unsigned int * dst = ( unsigned int * ) ( ( char * ) program - > ucode + ucodePatchOffset ) ;
dst [ 0 ] = SWAP_IF_BIG_ENDIAN ( itemDefaultValues [ 0 ] ) ;
dst [ 1 ] = SWAP_IF_BIG_ENDIAN ( itemDefaultValues [ 1 ] ) ;
dst [ 2 ] = SWAP_IF_BIG_ENDIAN ( itemDefaultValues [ 2 ] ) ;
dst [ 3 ] = SWAP_IF_BIG_ENDIAN ( itemDefaultValues [ 3 ] ) ;
}
memcpy ( ( void * ) hostMemoryCopy , ( void * ) itemDefaultValues , sizeof ( float ) * 4 ) ;
hostMemoryCopy + = 4 ;
itemDefaultValues + = 4 ;
resource + + ;
}
}
}
}
else
{
for ( int i = 0 ; i < count ; i + + )
{
int index = ( int ) program - > defaultValuesIndices [ i ] . entryIndex ;
CgRuntimeParameter * rtParameter = program - > runtimeParameters + index ;
int arrayCount = 1 ;
const CgParameterEntry * parameterEntry = rtParameter - > parameterEntry ;
bool isArray = false ;
if ( parameterEntry - > flags & CGP_ARRAY )
{
isArray = true ;
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , parameterEntry ) ;
arrayCount = _RGLGetSizeofSubArray ( parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
parameterEntry + + ;
rtParameter + + ;
}
if ( rtParameter - > pushBufferPointer )
{
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
const float * itemDefaultValues = program - > defaultValues + program - > defaultValuesIndices [ i ] . defaultValueIndex ;
int registerStride = isMatrix ( ( CGtype ) parameterResource - > type ) ? _RGLGetTypeRowCount ( ( CGtype ) parameterResource - > type ) : 1 ;
if ( parameterEntry - > flags & CGP_CONTIGUOUS )
memcpy ( rtParameter - > pushBufferPointer , itemDefaultValues , arrayCount * registerStride * 4 * sizeof ( float ) ) ;
else
{
unsigned int * pushBufferPointer = ( ( unsigned int * ) rtParameter - > pushBufferPointer ) ;
for ( int j = 0 ; j < arrayCount ; j + + )
{
unsigned int * pushBufferAddress = isArray ? ( * ( unsigned int * * ) pushBufferPointer ) : pushBufferPointer ;
memcpy ( pushBufferAddress , itemDefaultValues , registerStride * 4 * sizeof ( float ) ) ;
pushBufferPointer + = isArray ? 1 : 3 + registerStride * 4 ;
itemDefaultValues + = 4 * registerStride ;
}
}
}
}
}
program - > loadProgramId = GMM_ERROR ;
program - > loadProgramOffset = 0 ;
if ( profileIndex = = FRAGMENT_PROFILE_INDEX )
{
int loaded = _RGLLoadFPShader ( program ) ;
if ( ! loaded )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return 0 ;
}
}
program - > programGroup = NULL ;
program - > programIndexInGroup = - 1 ;
return 1 ;
}
int _RGLPlatformGenerateFragmentProgram ( _CGprogram * program , const CgProgramHeader * programHeader , const void * ucode ,
const CgParameterTableHeader * parameterHeader , const char * stringTable , const float * defaultValues )
{
return _RGLGenerateProgram ( program , FRAGMENT_PROFILE_INDEX , programHeader , ucode , parameterHeader , NULL , stringTable , defaultValues ) ;
}
void _RGLPlatformVertexProgramErase ( void * platformProgram )
{
_CGprogram * program = ( _CGprogram * ) platformProgram ;
if ( program - > runtimeParameters )
free ( program - > runtimeParameters ) ;
if ( program - > memoryBlock )
free ( program - > memoryBlock ) ;
if ( program - > samplerIndices )
{
free ( program - > samplerValuesLocation ) ;
free ( program - > samplerIndices ) ;
free ( program - > samplerUnits ) ;
}
if ( program - > constantPushBufferPointers )
free ( program - > constantPushBufferPointers ) ;
}
void _RGLPlatformProgramErase ( void * platformProgram )
{
_CGprogram * program = ( _CGprogram * ) platformProgram ;
if ( program - > loadProgramId ! = GMM_ERROR )
_RGLUnloadFPShader ( program ) ;
if ( program - > runtimeParameters )
{
int i ;
int count = ( int ) program - > rtParametersCount ;
for ( i = 0 ; i < count ; i + + )
{
_RGLEraseName ( & _CurrentContext - > cgParameterNameSpace , ( jsName ) program - > runtimeParameters [ i ] . id ) ;
}
free ( program - > runtimeParameters ) ;
}
if ( program - > memoryBlock )
free ( program - > memoryBlock ) ;
if ( program - > samplerIndices )
{
free ( program - > samplerValuesLocation ) ;
free ( program - > samplerIndices ) ;
free ( program - > samplerUnits ) ;
}
if ( program - > constantPushBufferPointers )
free ( program - > constantPushBufferPointers ) ;
}
CGbool _RGLPlatformSupportsFragmentProgram ( CGprofile p )
{
if ( p = = CG_PROFILE_SCE_FP_TYPEB )
return CG_TRUE ;
if ( CG_PROFILE_SCE_FP_RSX = = p )
return CG_TRUE ;
return CG_FALSE ;
}
CGprofile _RGLPlatformGetLatestProfile ( CGGLenum profile_type )
{
switch ( profile_type )
{
case CG_GL_VERTEX :
return CG_PROFILE_SCE_VP_RSX ;
case CG_GL_FRAGMENT :
return CG_PROFILE_SCE_FP_RSX ;
default :
break ;
}
return CG_PROFILE_UNKNOWN ;
}
int _RGLPlatformCopyProgram ( _CGprogram * source , _CGprogram * destination )
{
CgParameterTableHeader parameterHeader ;
parameterHeader . entryCount = source - > rtParametersCount ;
parameterHeader . resourceTableOffset = ( uintptr_t ) ( ( char * ) source - > resources - ( char * ) source - > parametersEntries + sizeof ( CgParameterTableHeader ) ) ;
parameterHeader . defaultValueIndexCount = source - > defaultValuesIndexCount ;
parameterHeader . defaultValueIndexTableOffset = ( uintptr_t ) ( ( char * ) source - > defaultValuesIndices - ( char * ) source - > parametersEntries + sizeof ( CgParameterTableHeader ) ) ;
int profileIndex ;
switch ( source - > header . profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
profileIndex = VERTEX_PROFILE_INDEX ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
profileIndex = FRAGMENT_PROFILE_INDEX ;
break ;
default :
return 0 ;
}
return _RGLGenerateProgram ( destination , profileIndex , & source - > header , source - > ucode , & parameterHeader , source - > parametersEntries , source - > stringTable , source - > defaultValues ) ;
}
static char * _RGLPlatformBufferObjectMap ( jsBufferObject * bufferObject , GLenum access )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
if ( jsBuffer - > mapCount + + = = 0 )
{
if ( access = = GL_WRITE_ONLY )
{
_RGLAllocateBuffer ( bufferObject ) ;
if ( jsBuffer - > pool = = _RGL_SURFACE_POOL_NONE )
{
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
return NULL ;
}
}
else
{
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
}
jsBuffer - > mapAccess = access ;
if ( jsBuffer - > mapAccess ! = GL_READ_ONLY )
{
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
+ + driver - > flushBufferCount ;
}
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) jsBuffer - > bufferId ;
if ( ! pBaseBlock - > isTile )
{
GmmBlock * pBlock = ( GmmBlock * ) jsBuffer - > bufferId ;
pBlock - > isPinned = 1 ;
}
}
return gmmIdToAddress ( jsBuffer - > bufferId ) ;
}
static jsFramebuffer * _RGLCreateFramebuffer ( void )
{
jsFramebuffer * framebuffer = new jsPlatformFramebuffer ( ) ;
return framebuffer ;
}
static void _RGLDestroyFramebuffer ( jsFramebuffer * framebuffer )
{
delete framebuffer ;
}
static void _RGLPlatformDestroyTexture ( jsTexture * texture )
{
if ( ! texture - > referenceBuffer )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
if ( gcmTexture - > pbo ! = NULL )
{
_RGLFreeBufferObject ( gcmTexture - > pbo ) ;
gcmTexture - > pbo = NULL ;
gcmTexture - > pool = _RGL_SURFACE_POOL_NONE ;
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
}
_RGLPlatformFreeGcmTexture ( texture ) ;
}
_RGLTextureTouchFBOs ( texture ) ;
}
// Get size of texture in GPU layout
static inline GLuint _RGLPlatformTextureGetGPUSize ( const jsTexture * texture )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
return _RGLPad ( gcmTexture - > gpuLayout . baseHeight * gcmTexture - > gpuLayout . pitch , 1 ) ;
}
# include <cell/gcm/gcm_method_data.h>
static void _RGLPlatformValidateTextureStage ( int unit , jsTexture * texture )
{
if ( RGL_UNLIKELY ( texture - > revalidate ) )
{
_RGLPlatformValidateTextureResources ( texture ) ;
}
GLboolean isCompleteCache = texture - > isComplete ;
if ( RGL_LIKELY ( isCompleteCache ) )
{
RGLTexture * platformTexture = ( RGLTexture * ) texture - > platformTexture ;
const GLuint imageOffset = gmmIdToOffset ( platformTexture - > gpuAddressId ) + platformTexture - > gpuAddressIdOffset ;
platformTexture - > gcmTexture . offset = imageOffset ;
cellGcmSetTexture ( & _RGLState . fifo , unit , & platformTexture - > gcmTexture ) ;
CellGcmContextData * gcm_context = ( CellGcmContextData * ) & _RGLState . fifo ;
cellGcmReserveMethodSizeInline ( gcm_context , 11 ) ;
uint32_t * current = gcm_context - > current ;
current [ 0 ] = CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET ( unit , 8 ) ;
current [ 1 ] = CELL_GCM_METHOD_DATA_TEXTURE_OFFSET ( platformTexture - > gcmTexture . offset ) ;
current [ 2 ] = CELL_GCM_METHOD_DATA_TEXTURE_FORMAT ( platformTexture - > gcmTexture . location ,
CELL_GCM_FALSE ,
CELL_GCM_TEXTURE_DIMENSION_2 ,
platformTexture - > gcmTexture . format ,
1 ) ;
current [ 3 ] = CELL_GCM_METHOD_DATA_TEXTURE_ADDRESS (
CELL_GCM_TEXTURE_BORDER , /* wrapS */
CELL_GCM_TEXTURE_BORDER , /* wrapT */
CELL_GCM_TEXTURE_BORDER , /* wrapR */
CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL , /* unsignedRemap */
CELL_GCM_TEXTURE_ZFUNC_NEVER ,
platformTexture - > gcmMethods . address . gamma ,
0 ) ;
current [ 4 ] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL0 ( CELL_GCM_TRUE ,
0 , /* minLOD */
256000 , /* maxLOD */
CELL_GCM_TEXTURE_MAX_ANISO_1 ) ;
current [ 5 ] = platformTexture - > gcmTexture . remap ;
current [ 6 ] = CELL_GCM_METHOD_DATA_TEXTURE_FILTER (
( platformTexture - > gcmMethods . filter . bias & 0x1fff ) ,
platformTexture - > gcmMethods . filter . min ,
platformTexture - > gcmMethods . filter . mag ,
CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX ) ; /* filter */
current [ 7 ] = CELL_GCM_METHOD_DATA_TEXTURE_IMAGE_RECT (
platformTexture - > gcmTexture . height ,
platformTexture - > gcmTexture . width ) ;
current [ 8 ] = CELL_GCM_METHOD_DATA_TEXTURE_BORDER_COLOR ( 0 ) ;
current [ 9 ] = CELL_GCM_METHOD_HEADER_TEXTURE_CONTROL3 ( unit , 1 ) ;
current [ 10 ] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3 (
platformTexture - > gcmTexture . pitch ,
1 ) ; /* depth */
gcm_context - > current = & current [ 11 ] ;
}
else
{
//printf("RGL WARN: Texture bound to unit %d is incomplete.\n", unit);
GLuint remap = CELL_GCM_REMAP_MODE (
CELL_GCM_TEXTURE_REMAP_ORDER_XYXY ,
CELL_GCM_TEXTURE_REMAP_FROM_A ,
CELL_GCM_TEXTURE_REMAP_FROM_R ,
CELL_GCM_TEXTURE_REMAP_FROM_G ,
CELL_GCM_TEXTURE_REMAP_FROM_B ,
CELL_GCM_TEXTURE_REMAP_ONE ,
CELL_GCM_TEXTURE_REMAP_ZERO ,
CELL_GCM_TEXTURE_REMAP_ZERO ,
CELL_GCM_TEXTURE_REMAP_ZERO ) ;
cellGcmSetTextureControlInline ( & _RGLState . fifo , unit , CELL_GCM_FALSE , 0 , 0 , 0 ) ;
cellGcmSetTextureRemapInline ( & _RGLState . fifo , unit , remap ) ;
}
}
static GLenum _RGLPlatformChooseInternalFormat ( GLenum internalFormat )
{
switch ( internalFormat )
{
case GL_ALPHA :
case GL_ALPHA4 :
case GL_ALPHA8 :
return RGL_ALPHA8 ;
case GL_RGB10 :
case GL_RGB10_A2 :
case GL_RGB12 :
case GL_RGB16 :
return RGL_FLOAT_RGBX32 ;
case GL_RGBA12 :
case GL_RGBA16 :
return RGL_FLOAT_RGBA32 ;
case 3 :
case GL_R3_G3_B2 :
case GL_RGB4 :
case GL_RGB :
case GL_RGB8 :
case RGL_RGBX8 :
return RGL_RGBX8 ;
case 4 :
case GL_RGBA2 :
case GL_RGBA4 :
case GL_RGBA8 :
case GL_RGBA :
return RGL_RGBA8 ;
case GL_RGB5_A1 :
return RGL_RGB5_A1_SCE ;
case GL_RGB5 :
return RGL_RGB565_SCE ;
case GL_BGRA :
case RGL_BGRA8 :
return RGL_BGRA8 ;
case GL_ARGB_SCE :
return RGL_ARGB8 ;
default :
return GL_INVALID_ENUM ;
}
return GL_INVALID_ENUM ;
}
static void _RGLPlatformExpandInternalFormat ( GLenum internalFormat , GLenum * format , GLenum * type )
{
switch ( internalFormat )
{
case RGL_ALPHA8 :
* format = GL_ALPHA ;
* type = GL_UNSIGNED_BYTE ;
break ;
case RGL_ARGB8 :
* format = GL_BGRA ;
* type = GL_UNSIGNED_INT_8_8_8_8_REV ;
break ;
case RGL_RGB5_A1_SCE :
* format = GL_RGBA ;
* type = GL_UNSIGNED_SHORT_1_5_5_5_REV ;
break ;
case RGL_RGB565_SCE :
* format = GL_RGB ;
* type = GL_UNSIGNED_SHORT_5_6_5_REV ;
break ;
default :
return ;
}
}
static GLenum _RGLPlatformChooseInternalStorage ( jsImage * image , GLenum internalFormat )
{
image - > storageSize = 0 ;
GLenum platformInternalFormat = _RGLPlatformChooseInternalFormat ( internalFormat ) ;
if ( platformInternalFormat = = GL_INVALID_ENUM )
return GL_INVALID_ENUM ;
image - > internalFormat = platformInternalFormat ;
_RGLPlatformExpandInternalFormat ( platformInternalFormat , & image - > format , & image - > type ) ;
image - > storageSize = _RGLGetStorageSize (
image - > format , image - > type ,
image - > width , image - > height , 1 ) ;
return GL_NO_ERROR ;
}
static inline GLuint _RGLGetBufferObjectOrigin ( GLuint buffer )
{
jsBufferObject * bufferObject = _RGLGetBufferObject ( _CurrentContext , buffer ) ;
RGLBufferObject * gcmBuffer = ( RGLBufferObject * ) & bufferObject - > platformBufferObject ;
return gcmBuffer - > bufferId ;
}
static void _RGLSetImage ( jsImage * image , GLint internalFormat , GLsizei width , GLsizei height , GLsizei depth , GLsizei alignment , GLenum format , GLenum type , const GLvoid * pixels )
{
image - > width = width ;
image - > height = height ;
image - > alignment = alignment ;
image - > xblk = 0 ;
image - > yblk = 0 ;
image - > xstride = 0 ;
image - > ystride = 0 ;
image - > format = 0 ;
image - > type = 0 ;
image - > internalFormat = 0 ;
const GLenum status = _RGLPlatformChooseInternalStorage ( image , internalFormat ) ;
( ( void ) status ) ;
image - > data = NULL ;
image - > mallocData = NULL ;
image - > mallocStorageSize = 0 ;
image - > isSet = GL_TRUE ;
if ( image - > xstride = = 0 )
image - > xstride = _RGLGetPixelSize ( image - > format , image - > type ) ;
if ( image - > ystride = = 0 )
image - > ystride = image - > width * image - > xstride ;
if ( pixels )
{
_RGLImageAllocCPUStorage ( image ) ;
if ( ! image - > data )
return ;
jsRaster raster ;
raster . format = format ;
raster . type = type ;
raster . width = width ;
raster . height = height ;
raster . data = ( void * ) pixels ;
raster . xstride = _RGLGetPixelSize ( raster . format , raster . type ) ;
raster . ystride = ( raster . width * raster . xstride + alignment - 1 ) / alignment * alignment ;
_RGLRasterToImage ( & raster , image ) ;
image - > dataState = _RGL_IMAGE_DATASTATE_HOST ;
}
else
image - > dataState = _RGL_IMAGE_DATASTATE_UNSET ;
}
static GLboolean _RGLPlatformTexturePBOImage (
jsTexture * texture ,
jsImage * image ,
GLint internalFormat ,
GLsizei width , GLsizei height ,
GLenum format , GLenum type ,
const GLvoid * offset )
{
PSGLcontext * LContext = _CurrentContext ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
image - > dataState = _RGL_IMAGE_DATASTATE_UNSET ;
if ( gcmTexture - > pbo ! = NULL )
_RGLPlatformDropTexture ( texture ) ;
_RGLSetImage ( image , internalFormat , width , height , 1 /* depth */ , LContext - > unpackAlignment , format , type , NULL ) ;
if ( LContext - > PixelUnpackBuffer = = 0 )
return GL_FALSE ;
const GLuint pboPitch = _RGLPad (
_RGLGetStorageSize ( format , type , width , 1 , 1 ) ,
LContext - > unpackAlignment ) ;
if ( ( pboPitch & 3 ) ! = 0 )
{
printf ( " RGL WARN: PBO image pitch not a multiple of 4, using slow path. \n " ) ;
return GL_FALSE ;
}
GLuint gpuId = _RGLGetBufferObjectOrigin ( LContext - > PixelUnpackBuffer ) ;
GLuint gpuIdOffset = ( ( GLubyte * ) offset - ( GLubyte * ) NULL ) ;
if ( gmmIdToOffset ( gpuId ) + gpuIdOffset & 63 )
{
printf ( " RGL: PBO offset not 64-byte aligned, using slow path. \n " ) ;
return GL_FALSE ;
}
GLboolean formatOK = GL_FALSE ;
switch ( internalFormat )
{
case 4 :
case GL_RGBA :
case GL_RGBA8 :
if ( format = = GL_RGBA & & type = = GL_UNSIGNED_INT_8_8_8_8 )
formatOK = GL_TRUE ;
break ;
case GL_ALPHA :
case GL_ALPHA8 :
if ( format = = GL_ALPHA & & type = = GL_UNSIGNED_BYTE )
formatOK = GL_TRUE ;
break ;
case GL_ARGB_SCE :
if ( format = = GL_BGRA & & type = = GL_UNSIGNED_INT_8_8_8_8_REV )
formatOK = GL_TRUE ;
break ;
default :
formatOK = GL_FALSE ;
}
if ( ! formatOK )
{
printf ( " RGL: PBO format/type requires conversion to texture internal format, using slow path. \n " ) ;
return GL_FALSE ;
}
if ( ! _RGLTextureIsValid ( texture ) )
{
printf ( " RGL: PBO transfering to incomplete texture, using slow path. \n " ) ;
return GL_FALSE ;
}
RGLTextureLayout newLayout ;
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , pboPitch , & newLayout ) ;
jsBufferObject * bufferObject = _RGLGetBufferObject ( LContext , LContext - > PixelUnpackBuffer ) ;
if ( newLayout . pitch ! = 0 & & ! bufferObject - > mapped )
{
gcmTexture - > gpuLayout = newLayout ;
if ( gcmTexture - > gpuAddressId ! = GMM_ERROR & & gcmTexture - > pbo = = NULL )
{
_RGLPlatformFreeGcmTexture ( texture ) ;
}
gcmTexture - > pbo = bufferObject ;
gcmTexture - > gpuAddressId = gpuId ;
gcmTexture - > gpuAddressIdOffset = gpuIdOffset ;
gcmTexture - > pool = _RGL_SURFACE_POOL_LINEAR ;
gcmTexture - > gpuSize = _RGLPlatformTextureGetGPUSize ( texture ) ;
+ + bufferObject - > refCount ;
}
else
{
const GLuint bytesPerPixel = newLayout . pixelBits / 8 ;
RGLSurface src =
{
source : _RGL_SURFACE_SOURCE_PBO ,
width : image - > width ,
height : image - > height ,
bpp : bytesPerPixel ,
pitch : pboPitch ,
format : newLayout . internalFormat ,
pool : _RGL_SURFACE_POOL_LINEAR ,
ppuData : NULL ,
dataId : gpuId ,
dataIdOffset : gpuIdOffset ,
} ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_LAYOUT ;
_RGLPlatformValidateTextureResources ( texture ) ;
RGLSurface dst =
{
source : _RGL_SURFACE_SOURCE_TEXTURE ,
width : image - > width ,
height : image - > height ,
bpp : bytesPerPixel ,
pitch : gcmTexture - > gpuLayout . pitch ,
format : gcmTexture - > gpuLayout . internalFormat ,
pool : gcmTexture - > pool ,
ppuData : NULL ,
dataId : gcmTexture - > gpuAddressId ,
dataIdOffset : gcmTexture - > gpuAddressIdOffset ,
} ;
_RGLTransferDataVidToVid ( dst . dataId , dst . dataIdOffset , dst . pitch ? dst . pitch : ( dst . bpp * dst . width ) , 0 , 0 , src . dataId , src . dataIdOffset , src . pitch ? src . pitch : ( src . bpp * src . width ) , 0 , 0 , width , height , src . bpp ) ;
}
_RGLImageFreeCPUStorage ( image ) ;
image - > dataState = _RGL_IMAGE_DATASTATE_GPU ;
texture - > revalidate & = ~ ( _RGL_TEXTURE_REVALIDATE_LAYOUT | _RGL_TEXTURE_REVALIDATE_IMAGES ) ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_PARAMETERS ;
_RGLTextureTouchFBOs ( texture ) ;
return GL_TRUE ;
}
static GLboolean _RGLPlatformTextureReference ( jsTexture * texture , GLuint pitch , jsBufferObject * bufferObject , GLintptr offset )
{
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
RGLTextureLayout newLayout ;
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , pitch , & newLayout ) ;
texture - > isRenderTarget = GL_TRUE ;
if ( gcmTexture - > gpuAddressId ! = GMM_ERROR )
_RGLPlatformDestroyTexture ( texture ) ;
RGLBufferObject * gcmBuffer = ( RGLBufferObject * ) & bufferObject - > platformBufferObject ;
gcmTexture - > gpuLayout = newLayout ;
gcmTexture - > pool = gcmBuffer - > pool ;
gcmTexture - > gpuAddressId = gcmBuffer - > bufferId ;
gcmTexture - > gpuAddressIdOffset = offset ;
gcmTexture - > gpuSize = _RGLPad ( newLayout . baseHeight * newLayout . pitch , 1 ) ;
texture - > revalidate & = ~ ( _RGL_TEXTURE_REVALIDATE_LAYOUT | _RGL_TEXTURE_REVALIDATE_IMAGES ) ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_PARAMETERS ;
_RGLTextureTouchFBOs ( texture ) ;
return GL_TRUE ;
}
static inline void _RGLSetColorDepthBuffers ( RGLRenderTarget * rt , RGLRenderTargetEx const * const args )
{
CellGcmSurface * grt = & rt - > gcmRenderTarget ;
rt - > colorBufferCount = args - > colorBufferCount ;
GLuint oldHeight ;
GLuint oldyInverted ;
oldyInverted = rt - > yInverted ;
oldHeight = rt - > gcmRenderTarget . height ;
GLuint i ;
for ( i = 0 ; i < args - > colorBufferCount ; i + + )
{
if ( args - > colorPitch [ i ] = = 0 )
{
grt - > colorOffset [ i ] = 0 ;
grt - > colorPitch [ i ] = 0x200 ;
grt - > colorLocation [ i ] = CELL_GCM_LOCATION_LOCAL ;
}
else
{
if ( args - > colorId [ i ] ! = GMM_ERROR )
{
if ( gmmIdIsMain ( args - > colorId [ i ] ) )
grt - > colorLocation [ i ] = CELL_GCM_LOCATION_MAIN ;
else
grt - > colorLocation [ i ] = CELL_GCM_LOCATION_LOCAL ;
grt - > colorOffset [ i ] = gmmIdToOffset ( args - > colorId [ i ] ) + args - > colorIdOffset [ i ] ;
grt - > colorPitch [ i ] = args - > colorPitch [ i ] ;
}
}
}
for ( ; i < RGL_SETRENDERTARGET_MAXCOUNT ; i + + )
{
grt - > colorOffset [ i ] = grt - > colorOffset [ 0 ] ;
grt - > colorPitch [ i ] = grt - > colorPitch [ 0 ] ;
grt - > colorLocation [ i ] = grt - > colorLocation [ 0 ] ;
}
rt - > yInverted = args - > yInverted ;
grt - > x = args - > xOffset ;
grt - > y = args - > yOffset ;
grt - > width = args - > width ;
grt - > height = args - > height ;
if ( ( grt - > height ! = oldHeight ) | ( rt - > yInverted ! = oldyInverted ) )
{
RGLViewportState * v = & _RGLState . state . viewport ;
_RGLFifoGlViewport ( v - > x , v - > y , v - > w , v - > h ) ;
}
}
static inline void _RGLSetColorDepthFormats ( RGLRenderTarget * rt , RGLRenderTargetEx const * const args )
{
CellGcmSurface * grt = & rt - > gcmRenderTarget ;
grt - > colorFormat = CELL_GCM_SURFACE_A8R8G8B8 ;
grt - > depthFormat = CELL_GCM_SURFACE_Z24S8 ;
grt - > depthLocation = CELL_GCM_LOCATION_LOCAL ;
grt - > depthOffset = 0 ;
grt - > depthPitch = 64 ;
}
static inline void _RGLSetTarget ( RGLRenderTarget * rt , RGLRenderTargetEx const * const args )
{
CellGcmSurface * grt = & rt - > gcmRenderTarget ;
switch ( rt - > colorBufferCount )
{
case 0 :
grt - > colorTarget = CELL_GCM_SURFACE_TARGET_NONE ;
break ;
case 1 :
grt - > colorTarget = CELL_GCM_SURFACE_TARGET_1 ;
break ;
case 2 :
grt - > colorTarget = CELL_GCM_SURFACE_TARGET_MRT1 ;
break ;
case 3 :
grt - > colorTarget = CELL_GCM_SURFACE_TARGET_MRT2 ;
break ;
case 4 :
grt - > colorTarget = CELL_GCM_SURFACE_TARGET_MRT3 ;
break ;
default :
break ;
}
}
void _RGLFifoGlSetRenderTarget ( RGLRenderTargetEx const * const args )
{
RGLRenderTarget * rt = & _RGLState . renderTarget ;
CellGcmSurface * grt = & _RGLState . renderTarget . gcmRenderTarget ;
_RGLSetColorDepthBuffers ( rt , args ) ;
_RGLSetColorDepthFormats ( rt , args ) ;
grt - > antialias = CELL_GCM_SURFACE_CENTER_1 ;
cellGcmSetAntiAliasingControlInline ( & _RGLState . fifo , CELL_GCM_FALSE , CELL_GCM_FALSE , CELL_GCM_FALSE , 0xFFFF ) ;
grt - > type = CELL_GCM_SURFACE_PITCH ;
_RGLSetTarget ( rt , args ) ;
cellGcmSetSurfaceInline ( & _RGLState . fifo , grt ) ;
cellGcmSetDepthTestEnableInline ( & _RGLState . fifo , CELL_GCM_FALSE ) ;
}
void _RGLSetError ( GLenum error )
{
}
GLAPI GLenum APIENTRY glGetError ( )
{
if ( ! _CurrentContext )
return GL_INVALID_OPERATION ;
else
{
GLenum error = _CurrentContext - > error ;
_CurrentContext - > error = GL_NO_ERROR ;
return error ;
}
}
static uint32_t * _RGLFifoWaitForFreeSpace ( RGLFifo * fifo , GLuint spaceInWords )
{
if ( fifo - > current + spaceInWords + 1024 > fifo - > end )
_RGLOutOfSpaceCallback ( fifo , spaceInWords ) ;
return _RGLState . fifo . current ;
}
static inline void _RGLPushProgramPushBuffer ( _CGprogram * cgprog )
{
_RGLFifoWaitForFreeSpace ( & _RGLState . fifo , cgprog - > constantPushBufferWordSize + 4 + 32 ) ;
uint32_t padding_in_word = ( ( 0x10 - ( ( ( uint32_t ) _RGLState . fifo . current ) & 0xf ) ) & 0xf ) > > 2 ;
uint32_t padded_size = ( ( ( cgprog - > constantPushBufferWordSize ) < < 2 ) + 0xf ) & ~ 0xf ;
cellGcmSetNopCommandUnsafeInline ( & _RGLState . fifo , padding_in_word ) ;
memcpy16 ( _RGLState . fifo . current , cgprog - > constantPushBuffer , padded_size ) ;
_RGLState . fifo . current + = cgprog - > constantPushBufferWordSize ;
}
static GLuint _RGLValidateStates ( void )
{
PSGLcontext * LContext = _CurrentContext ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
LContext - > needValidate & = PSGL_VALIDATE_ALL ;
GLuint dirty = LContext - > needValidate ;
GLuint needValidate = LContext - > needValidate ;
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_FRAMEBUFFER ) )
{
_RGLValidateFramebuffer ( ) ;
needValidate = LContext - > needValidate ;
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_TEXTURES_USED ) )
{
long unitInUseCount = LContext - > BoundFragmentProgram - > samplerCount ;
const GLuint * unitsInUse = LContext - > BoundFragmentProgram - > samplerUnits ;
for ( long i = 0 ; i < unitInUseCount ; + + i )
{
long unit = unitsInUse [ i ] ;
jsTexture * texture = LContext - > TextureImageUnits [ unit ] . currentTexture ;
_RGLPlatformValidateTextureStage ( unit , texture ) ;
}
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_VERTEX_PROGRAM ) )
{
const void * header = LContext - > BoundVertexProgram ;
const _CGprogram * vs = ( const _CGprogram * ) header ;
__dcbt ( vs - > ucode ) ;
__dcbt ( ( ( uint8_t * ) vs - > ucode ) + 128 ) ;
__dcbt ( ( ( uint8_t * ) vs - > ucode ) + 256 ) ;
__dcbt ( ( ( uint8_t * ) vs - > ucode ) + 384 ) ;
CellCgbVertexProgramConfiguration conf ;
conf . instructionSlot = vs - > header . vertexProgram . instructionSlot ;
conf . instructionCount = vs - > header . instructionCount ;
conf . registerCount = vs - > header . vertexProgram . registerCount ;
conf . attributeInputMask = vs - > header . attributeInputMask ;
_RGLFifoWaitForFreeSpace ( & _RGLState . fifo , 7 + 5 * conf . instructionCount ) ;
cellGcmSetVertexProgramLoadInline ( & _RGLState . fifo , & conf , vs - > ucode ) ;
cellGcmSetUserClipPlaneControlInline ( & _RGLState . fifo , 0 , 0 , 0 , 0 , 0 , 0 ) ;
RGLInterpolantState * s = & _RGLState . state . interpolant ;
s - > vertexProgramAttribMask = vs - > header . vertexProgram . attributeOutputMask ;
cellGcmSetVertexAttribOutputMaskInline ( & _RGLState . fifo , s - > vertexProgramAttribMask & s - > fragmentProgramAttribMask ) ;
_CGprogram * program = ( _CGprogram * ) vs ;
int count = program - > defaultValuesIndexCount ;
for ( int i = 0 ; i < count ; i + + )
{
const CgParameterEntry * parameterEntry = program - > parametersEntries + program - > defaultValuesIndices [ i ] . entryIndex ;
if ( ( parameterEntry - > flags & CGPF_REFERENCED ) & & ( parameterEntry - > flags & CGPV_MASK ) = = CGPV_CONSTANT )
{
const float * itemDefaultValues = program - > defaultValues + program - > defaultValuesIndices [ i ] . defaultValueIndex ;
const GLfloat * value = itemDefaultValues ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , parameterEntry ) ;
if ( parameterResource - > resource ! = ( unsigned short ) - 1 )
{
switch ( parameterResource - > type )
{
case CG_FLOAT :
case CG_FLOAT1 :
case CG_FLOAT2 :
case CG_FLOAT3 :
case CG_FLOAT4 :
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 1 , value ) ;
break ;
case CG_FLOAT4x4 :
{
GLfloat v2 [ 16 ] ;
v2 [ 0 ] = value [ 0 ] ; v2 [ 1 ] = value [ 4 ] ; v2 [ 2 ] = value [ 8 ] ; v2 [ 3 ] = value [ 12 ] ;
v2 [ 4 ] = value [ 1 ] ; v2 [ 5 ] = value [ 5 ] ; v2 [ 6 ] = value [ 9 ] ; v2 [ 7 ] = value [ 13 ] ;
v2 [ 8 ] = value [ 2 ] ; v2 [ 9 ] = value [ 6 ] ; v2 [ 10 ] = value [ 10 ] ; v2 [ 11 ] = value [ 14 ] ;
v2 [ 12 ] = value [ 3 ] ; v2 [ 13 ] = value [ 7 ] ; v2 [ 14 ] = value [ 11 ] ; v2 [ 15 ] = value [ 15 ] ;
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 4 , v2 ) ;
}
break ;
case CG_FLOAT3x3 :
{
GLfloat v2 [ 12 ] ;
v2 [ 0 ] = value [ 0 ] ; v2 [ 1 ] = value [ 3 ] ; v2 [ 2 ] = value [ 6 ] ; v2 [ 3 ] = 0 ;
v2 [ 4 ] = value [ 1 ] ; v2 [ 5 ] = value [ 4 ] ; v2 [ 6 ] = value [ 7 ] ; v2 [ 7 ] = 0 ;
v2 [ 8 ] = value [ 2 ] ; v2 [ 9 ] = value [ 5 ] ; v2 [ 10 ] = value [ 8 ] ; v2 [ 11 ] = 0 ;
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 3 , v2 ) ;
}
break ;
case CG_HALF :
case CG_HALF1 :
case CG_HALF2 :
case CG_HALF3 :
case CG_HALF4 :
case CG_INT :
case CG_INT1 :
case CG_INT2 :
case CG_INT3 :
case CG_INT4 :
case CG_BOOL :
case CG_BOOL1 :
case CG_BOOL2 :
case CG_BOOL3 :
case CG_BOOL4 :
case CG_FIXED :
case CG_FIXED1 :
case CG_FIXED2 :
case CG_FIXED3 :
case CG_FIXED4 :
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 1 , value ) ;
break ;
case CG_HALF4x4 :
case CG_INT4x4 :
case CG_BOOL4x4 :
case CG_FIXED4x4 :
{
GLfloat v2 [ 16 ] ;
v2 [ 0 ] = value [ 0 ] ; v2 [ 1 ] = value [ 4 ] ; v2 [ 2 ] = value [ 8 ] ; v2 [ 3 ] = value [ 12 ] ;
v2 [ 4 ] = value [ 1 ] ; v2 [ 5 ] = value [ 5 ] ; v2 [ 6 ] = value [ 9 ] ; v2 [ 7 ] = value [ 13 ] ;
v2 [ 8 ] = value [ 2 ] ; v2 [ 9 ] = value [ 6 ] ; v2 [ 10 ] = value [ 10 ] ; v2 [ 11 ] = value [ 14 ] ;
v2 [ 12 ] = value [ 3 ] ; v2 [ 13 ] = value [ 7 ] ; v2 [ 14 ] = value [ 11 ] ; v2 [ 15 ] = value [ 15 ] ;
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 4 , v2 ) ;
}
break ;
case CG_HALF3x3 :
case CG_INT3x3 :
case CG_BOOL3x3 :
case CG_FIXED3x3 :
{
GLfloat v2 [ 12 ] ;
v2 [ 0 ] = value [ 0 ] ; v2 [ 1 ] = value [ 3 ] ; v2 [ 2 ] = value [ 6 ] ; v2 [ 3 ] = 0 ;
v2 [ 4 ] = value [ 1 ] ; v2 [ 5 ] = value [ 4 ] ; v2 [ 6 ] = value [ 7 ] ; v2 [ 7 ] = 0 ;
v2 [ 8 ] = value [ 2 ] ; v2 [ 9 ] = value [ 5 ] ; v2 [ 10 ] = value [ 8 ] ; v2 [ 11 ] = 0 ;
cellGcmSetVertexProgramParameterBlockInline ( & _RGLState . fifo , parameterResource - > resource , 3 , v2 ) ;
}
break ;
default :
break ;
}
}
}
}
if ( ! ( LContext - > needValidate & PSGL_VALIDATE_VERTEX_CONSTANTS ) & & LContext - > BoundVertexProgram - > parentContext )
{
cellGcmSetTransformBranchBitsInline ( & _RGLState . fifo , LContext - > BoundVertexProgram - > controlFlowBools | LContext - > BoundVertexProgram - > parentContext - > controlFlowBoolsShared ) ;
_RGLPushProgramPushBuffer ( LContext - > BoundVertexProgram ) ;
}
}
if ( RGL_LIKELY ( needValidate & PSGL_VALIDATE_VERTEX_CONSTANTS ) & & LContext - > BoundVertexProgram - > parentContext )
{
cellGcmSetTransformBranchBitsInline ( & _RGLState . fifo , LContext - > BoundVertexProgram - > controlFlowBools | LContext - > BoundVertexProgram - > parentContext - > controlFlowBoolsShared ) ;
_RGLPushProgramPushBuffer ( LContext - > BoundVertexProgram ) ;
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_VERTEX_TEXTURES_USED ) )
{
for ( int unit = 0 ; unit < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + unit )
{
jsTexture * texture = LContext - > VertexTextureImages [ unit ] ;
if ( texture )
if ( RGL_UNLIKELY ( texture - > revalidate ) )
_RGLPlatformValidateTextureResources ( texture ) ;
cellGcmSetVertexTextureAddressInline ( & _RGLState . fifo , unit , CELL_GCM_TEXTURE_WRAP , CELL_GCM_TEXTURE_WRAP ) ;
cellGcmSetVertexTextureControlInline ( & _RGLState . fifo , unit , GL_FALSE , 0 , 256 ) ;
cellGcmSetVertexTextureFilterInline ( & _RGLState . fifo , unit , 0 ) ;
}
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_FRAGMENT_PROGRAM ) )
{
_CGprogram * program = LContext - > BoundFragmentProgram ;
const GLvoid * header = program ;
const _CGprogram * ps = ( const _CGprogram * ) header ;
CellCgbFragmentProgramConfiguration conf ;
conf . offset = gmmIdToOffset ( ps - > loadProgramId ) + ps - > loadProgramOffset ;
RGLInterpolantState * s = & _RGLState . state . interpolant ;
s - > fragmentProgramAttribMask | = ps - > header . attributeInputMask | CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE ;
conf . attributeInputMask = s - > vertexProgramAttribMask & s - > fragmentProgramAttribMask ;
conf . texCoordsInputMask = ps - > header . fragmentProgram . texcoordInputMask ;
conf . texCoords2D = ps - > header . fragmentProgram . texcoord2d ;
conf . texCoordsCentroid = ps - > header . fragmentProgram . texcoordCentroid ;
int fragmentControl = ( 1 < < 15 ) | ( 1 < < 10 ) ;
fragmentControl | = ps - > header . fragmentProgram . flags & CGF_DEPTHREPLACE ? 0xE : 0x0 ;
fragmentControl | = ps - > header . fragmentProgram . flags & CGF_OUTPUTFROMH0 ? 0x00 : 0x40 ;
fragmentControl | = ps - > header . fragmentProgram . flags & CGF_PIXELKILL ? 0x80 : 0x00 ;
conf . fragmentControl = fragmentControl ;
conf . registerCount = ps - > header . fragmentProgram . registerCount < 2 ? 2 : ps - > header . fragmentProgram . registerCount ;
uint32_t controlTxp = _CurrentContext - > AllowTXPDemotion ;
conf . fragmentControl & = ~ CELL_GCM_MASK_SET_SHADER_CONTROL_CONTROL_TXP ;
conf . fragmentControl | = controlTxp < < CELL_GCM_SHIFT_SET_SHADER_CONTROL_CONTROL_TXP ;
cellGcmSetFragmentProgramLoadInline ( & _RGLState . fifo , & conf ) ;
cellGcmSetZMinMaxControlInline ( & _RGLState . fifo , ( ps - > header . fragmentProgram . flags & CGF_DEPTHREPLACE ) ? CELL_GCM_FALSE : CELL_GCM_TRUE , CELL_GCM_FALSE , CELL_GCM_FALSE ) ;
driver - > fpLoadProgramId = program - > loadProgramId ;
driver - > fpLoadProgramOffset = program - > loadProgramOffset ;
}
if ( RGL_LIKELY ( ( needValidate & ~ ( PSGL_VALIDATE_TEXTURES_USED |
PSGL_VALIDATE_VERTEX_PROGRAM |
PSGL_VALIDATE_VERTEX_CONSTANTS |
PSGL_VALIDATE_VERTEX_TEXTURES_USED |
PSGL_VALIDATE_FRAGMENT_PROGRAM ) ) = = 0 ) )
{
LContext - > needValidate = 0 ;
return dirty ;
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_BLENDING ) )
{
if ( ( LContext - > Blending | | LContext - > BlendingMrt [ 0 ] | | LContext - > BlendingMrt [ 1 ] | | LContext - > BlendingMrt [ 2 ] ) )
{
GLuint hwColor ;
cellGcmSetBlendEnableInline ( & _RGLState . fifo , LContext - > Blending ) ;
cellGcmSetBlendEnableMrtInline ( & _RGLState . fifo , LContext - > BlendingMrt [ 0 ] , LContext - > BlendingMrt [ 1 ] , LContext - > BlendingMrt [ 2 ] ) ;
RGL_CALC_COLOR_LE_ARGB8 ( & hwColor , RGL_CLAMPF_01 ( LContext - > BlendColor . R ) , RGL_CLAMPF_01 ( LContext - > BlendColor . G ) , RGL_CLAMPF_01 ( LContext - > BlendColor . B ) , RGL_CLAMPF_01 ( LContext - > BlendColor . A ) ) ;
cellGcmSetBlendColorInline ( & _RGLState . fifo , hwColor , hwColor ) ;
cellGcmSetBlendEquationInline ( & _RGLState . fifo , ( RGLEnum ) LContext - > BlendEquationRGB , ( RGLEnum ) LContext - > BlendEquationAlpha ) ;
cellGcmSetBlendFuncInline ( & _RGLState . fifo , ( RGLEnum ) LContext - > BlendFactorSrcRGB , ( RGLEnum ) LContext - > BlendFactorDestRGB , ( RGLEnum ) LContext - > BlendFactorSrcAlpha , ( RGLEnum ) LContext - > BlendFactorDestAlpha ) ;
}
else
{
cellGcmSetBlendEnableInline ( & _RGLState . fifo , CELL_GCM_FALSE ) ;
cellGcmSetBlendEnableMrtInline ( & _RGLState . fifo , CELL_GCM_FALSE , CELL_GCM_FALSE , CELL_GCM_FALSE ) ;
}
}
if ( RGL_UNLIKELY ( needValidate & PSGL_VALIDATE_SHADER_SRGB_REMAP ) )
{
cellGcmSetFragmentProgramGammaEnableInline ( & _RGLState . fifo , LContext - > ShaderSRGBRemap ? CELL_GCM_TRUE : CELL_GCM_FALSE ) ;
LContext - > needValidate & = ~ PSGL_VALIDATE_SHADER_SRGB_REMAP ;
}
LContext - > needValidate = 0 ;
return dirty ;
}
PSGLcontext * psglGetCurrentContext ( )
{
return _CurrentContext ;
}
const GLfloat _RGLIdentityMatrixf [ ELEMENTS_IN_MATRIX ] =
{
1.f , 0.f , 0.f , 0.f ,
0.f , 1.f , 0.f , 0.f ,
0.f , 0.f , 1.f , 0.f ,
0.f , 0.f , 0.f , 1.f
} ;
static void _RGLMatrixStackReset ( jsMatrixStack * LMatrixStack )
{
LMatrixStack - > MatrixStackPtr = 0 ;
memcpy ( LMatrixStack - > MatrixStackf , _RGLIdentityMatrixf , jsMATRIX_SIZEf ) ;
LMatrixStack - > dirty = GL_TRUE ;
}
static void _RGLResetContext ( PSGLcontext * LContext )
{
_RGLMatrixStackReset ( & ( LContext - > ModelViewMatrixStack ) ) ;
_RGLMatrixStackReset ( & ( LContext - > ProjectionMatrixStack ) ) ;
_RGLTexNameSpaceResetNames ( & LContext - > textureNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > bufferObjectNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > framebufferNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > attribSetNameSpace ) ;
LContext - > InverseModelViewValid = GL_FALSE ;
LContext - > ScalingFactor = 1.f ;
LContext - > ViewPort . X = 0 ;
LContext - > ViewPort . Y = 0 ;
LContext - > ViewPort . XSize = 0 ;
LContext - > ViewPort . YSize = 0 ;
LContext - > ClearColor . R = 0.f ;
LContext - > ClearColor . G = 0.f ;
LContext - > ClearColor . B = 0.f ;
LContext - > ClearColor . A = 0.f ;
LContext - > AccumClearColor . R = 0.f ;
LContext - > AccumClearColor . G = 0.f ;
LContext - > AccumClearColor . B = 0.f ;
LContext - > AccumClearColor . A = 0.f ;
LContext - > ShaderSRGBRemap = GL_FALSE ;
LContext - > Blending = GL_FALSE ;
LContext - > BlendingMrt [ 0 ] = GL_FALSE ;
LContext - > BlendingMrt [ 1 ] = GL_FALSE ;
LContext - > BlendingMrt [ 2 ] = GL_FALSE ;
LContext - > BlendColor . R = 0.0f ;
LContext - > BlendColor . G = 0.0f ;
LContext - > BlendColor . B = 0.0f ;
LContext - > BlendColor . A = 0.0f ;
LContext - > BlendEquationRGB = GL_FUNC_ADD ;
LContext - > BlendEquationAlpha = GL_FUNC_ADD ;
LContext - > BlendFactorSrcRGB = GL_ONE ;
LContext - > BlendFactorDestRGB = GL_ZERO ;
LContext - > BlendFactorSrcAlpha = GL_ONE ;
LContext - > BlendFactorDestAlpha = GL_ZERO ;
LContext - > Dithering = GL_TRUE ;
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_COORDS ; + + i )
{
jsTextureCoordsUnit * tu = LContext - > TextureCoordsUnits + i ;
tu - > revalidate = 0 ;
_RGLMatrixStackReset ( & ( tu - > TextureMatrixStack ) ) ;
}
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_IMAGE_UNITS ; + + i )
{
jsTextureImageUnit * tu = LContext - > TextureImageUnits + i ;
tu - > bound2D = 0 ;
tu - > fragmentTarget = 0 ;
tu - > envMode = GL_MODULATE ;
tu - > envColor . R = 0.f ;
tu - > envColor . G = 0.f ;
tu - > envColor . B = 0.f ;
tu - > envColor . A = 0.f ;
tu - > currentTexture = NULL ;
}
for ( int i = 0 ; i < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + i )
{
LContext - > VertexTextureImages [ i ] = NULL ;
}
LContext - > ActiveTexture = 0 ;
LContext - > CurrentImageUnit = LContext - > TextureImageUnits ;
LContext - > CurrentCoordsUnit = LContext - > TextureCoordsUnits ;
LContext - > packAlignment = 4 ;
LContext - > unpackAlignment = 4 ;
LContext - > CS_ActiveTexture = 0 ;
_RGLResetAttributeState ( & LContext - > defaultAttribs0 ) ;
LContext - > attribs = & LContext - > defaultAttribs0 ;
LContext - > attribSetName = 0 ;
LContext - > attribSetDirty = GL_FALSE ;
LContext - > framebuffer = 0 ;
LContext - > VertexProgram = GL_FALSE ;
LContext - > BoundVertexProgram = 0 ;
LContext - > FragmentProgram = GL_FALSE ;
LContext - > BoundFragmentProgram = 0 ;
LContext - > ArrayBuffer = 0 ;
LContext - > PixelUnpackBuffer = 0 ;
LContext - > TextureBuffer = 0 ;
LContext - > VSync = GL_FALSE ;
LContext - > AllowTXPDemotion = GL_FALSE ;
}
static void _RGLMatrixStackInit ( jsMatrixStack * LMatrixStack , GLuint depth )
{
LMatrixStack - > MatrixStackf = ( GLfloat * ) malloc ( jsMATRIX_SIZEf * depth ) ;
if ( ! LMatrixStack - > MatrixStackf ) return ;
_RGLMatrixStackReset ( LMatrixStack ) ;
}
static jsTexture * _RGLAllocateTexture ( void )
{
GLuint size = sizeof ( jsTexture ) + sizeof ( RGLTexture ) ;
jsTexture * texture = ( jsTexture * ) malloc ( size ) ;
memset ( texture , 0 , size ) ;
texture - > target = 0 ;
texture - > minFilter = GL_NEAREST_MIPMAP_LINEAR ;
texture - > magFilter = GL_LINEAR ;
texture - > gammaRemap = 0 ;
texture - > usage = 0 ;
texture - > isRenderTarget = GL_FALSE ;
texture - > image = NULL ;
texture - > isComplete = GL_FALSE ;
texture - > imageCount = 0 ;
texture - > revalidate = 0 ;
texture - > referenceBuffer = NULL ;
new ( & texture - > framebuffers ) RGL : : Vector < jsFramebuffer * > ( ) ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
memset ( gcmTexture , 0 , sizeof ( RGLTexture ) ) ;
gcmTexture - > gpuAddressId = GMM_ERROR ;
return texture ;
}
static void _RGLFreeTexture ( jsTexture * texture )
{
_RGLTextureTouchFBOs ( texture ) ;
texture - > framebuffers . ~ Vector < jsFramebuffer * > ( ) ;
if ( texture - > image )
{
for ( GLuint i = 0 ; i < texture - > imageCount ; + + i )
{
jsImage * image = texture - > image + i ;
_RGLImageFreeCPUStorage ( image ) ;
}
if ( texture - > image ! = NULL )
free ( texture - > image ) ;
}
if ( texture - > referenceBuffer )
{
texture - > referenceBuffer - > textureReferences . removeElement ( texture ) ;
}
_RGLPlatformDestroyTexture ( texture ) ;
if ( texture ! = NULL )
free ( texture ) ;
}
PSGLcontext * psglCreateContext ( void )
{
PSGLcontext * LContext = ( PSGLcontext * ) malloc ( sizeof ( PSGLcontext ) ) ;
if ( ! LContext ) return NULL ;
memset ( LContext , 0 , sizeof ( PSGLcontext ) ) ;
LContext - > error = GL_NO_ERROR ;
LContext - > MatrixMode = GL_MODELVIEW ;
_RGLMatrixStackInit ( & ( LContext - > ModelViewMatrixStack ) , _RGL_MAX_MODELVIEW_STACK_DEPTH ) ;
if ( ! LContext - > ModelViewMatrixStack . MatrixStackf )
{
psglDestroyContext ( LContext ) ;
return NULL ;
}
_RGLMatrixStackInit ( & ( LContext - > ProjectionMatrixStack ) , _RGL_MAX_PROJECTION_STACK_DEPTH ) ;
if ( ! LContext - > ProjectionMatrixStack . MatrixStackf )
{
psglDestroyContext ( LContext ) ;
return NULL ;
}
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_COORDS ; i + + )
{
_RGLMatrixStackInit ( & ( LContext - > TextureCoordsUnits [ i ] . TextureMatrixStack ) , _RGL_MAX_TEXTURE_STACK_DEPTH ) ;
if ( ! LContext - > TextureCoordsUnits [ i ] . TextureMatrixStack . MatrixStackf )
{
psglDestroyContext ( LContext ) ;
return NULL ;
}
}
_RGLTexNameSpaceInit ( & LContext - > textureNameSpace , ( jsTexNameSpaceCreateFunction ) _RGLAllocateTexture , ( jsTexNameSpaceDestroyFunction ) _RGLFreeTexture ) ;
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_IMAGE_UNITS ; + + i )
{
jsTextureImageUnit * tu = LContext - > TextureImageUnits + i ;
tu - > default2D = _RGLAllocateTexture ( ) ;
if ( ! tu - > default2D )
{
psglDestroyContext ( LContext ) ;
return NULL ;
}
tu - > default2D - > target = GL_TEXTURE_2D ;
}
_RGLTexNameSpaceInit ( & LContext - > bufferObjectNameSpace , ( jsTexNameSpaceCreateFunction ) _RGLCreateBufferObject , ( jsTexNameSpaceDestroyFunction ) _RGLFreeBufferObject ) ;
_RGLTexNameSpaceInit ( & LContext - > framebufferNameSpace , ( jsTexNameSpaceCreateFunction ) _RGLCreateFramebuffer , ( jsTexNameSpaceDestroyFunction ) _RGLDestroyFramebuffer ) ;
_RGLTexNameSpaceInit ( & LContext - > attribSetNameSpace , ( jsTexNameSpaceCreateFunction ) _RGLCreateAttribSet , ( jsTexNameSpaceDestroyFunction ) _RGLDestroyAttribSet ) ;
LContext - > needValidate = 0 ;
LContext - > everAttached = 0 ;
LContext - > RGLcgLastError = CG_NO_ERROR ;
LContext - > RGLcgErrorCallbackFunction = NULL ;
LContext - > RGLcgContextHead = ( CGcontext ) NULL ;
_RGLInitNameSpace ( & LContext - > cgProgramNameSpace ) ;
_RGLInitNameSpace ( & LContext - > cgParameterNameSpace ) ;
_RGLInitNameSpace ( & LContext - > cgContextNameSpace ) ;
_RGLResetContext ( LContext ) ;
if ( _RGLContextCreateHook ) _RGLContextCreateHook ( LContext ) ;
return ( LContext ) ;
}
void psglResetCurrentContext ( void )
{
PSGLcontext * context = _CurrentContext ;
_RGLResetContext ( context ) ;
context - > needValidate | = PSGL_VALIDATE_ALL ;
}
static void _RGLMatrixStackClear ( jsMatrixStack * LMatrixStack )
{
if ( LMatrixStack - > MatrixStackf ) free ( LMatrixStack - > MatrixStackf ) ;
LMatrixStack - > MatrixStackf = NULL ;
LMatrixStack - > MatrixStackPtr = 0 ;
LMatrixStack - > dirty = GL_FALSE ;
}
void psglDestroyContext ( PSGLcontext * LContext )
{
if ( _CurrentContext = = LContext )
{
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
}
while ( LContext - > RGLcgContextHead ! = ( CGcontext ) NULL )
{
PSGLcontext * current = _CurrentContext ;
_CurrentContext = LContext ;
cgDestroyContext ( LContext - > RGLcgContextHead ) ;
_CurrentContext = current ;
}
_RGLFreeNameSpace ( & LContext - > cgProgramNameSpace ) ;
_RGLFreeNameSpace ( & LContext - > cgParameterNameSpace ) ;
_RGLFreeNameSpace ( & LContext - > cgContextNameSpace ) ;
if ( _RGLContextDestroyHook ) _RGLContextDestroyHook ( LContext ) ;
_RGLMatrixStackClear ( & ( LContext - > ModelViewMatrixStack ) ) ;
_RGLMatrixStackClear ( & ( LContext - > ProjectionMatrixStack ) ) ;
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_COORDS ; i + + )
_RGLMatrixStackClear ( & ( LContext - > TextureCoordsUnits [ i ] . TextureMatrixStack ) ) ;
for ( int i = 0 ; i < _RGL_MAX_TEXTURE_IMAGE_UNITS ; + + i )
{
jsTextureImageUnit * tu = LContext - > TextureImageUnits + i ;
if ( tu - > default2D ) _RGLFreeTexture ( tu - > default2D ) ;
}
_RGLTexNameSpaceFree ( & LContext - > textureNameSpace ) ;
_RGLTexNameSpaceFree ( & LContext - > bufferObjectNameSpace ) ;
_RGLTexNameSpaceFree ( & LContext - > framebufferNameSpace ) ;
_RGLTexNameSpaceFree ( & LContext - > attribSetNameSpace ) ;
if ( _CurrentContext = = LContext )
{
psglMakeCurrent ( NULL , NULL ) ;
}
if ( LContext ! = NULL )
free ( LContext ) ;
}
void _RGLAttachContext ( PSGLdevice * device , PSGLcontext * context )
{
if ( ! context - > everAttached )
{
context - > ViewPort . XSize = device - > deviceParameters . width ;
context - > ViewPort . YSize = device - > deviceParameters . height ;
context - > everAttached = GL_TRUE ;
_RGLFifoGlViewport ( context - > ViewPort . X , context - > ViewPort . Y ,
context - > ViewPort . XSize , context - > ViewPort . YSize , 0.0f , 1.0f ) ;
}
context - > needValidate = PSGL_VALIDATE_ALL ;
for ( int unit = 0 ; unit < _RGL_MAX_TEXTURE_UNITS ; unit + + )
context - > TextureCoordsUnits [ unit ] . TextureMatrixStack . dirty = GL_TRUE ;
context - > ModelViewMatrixStack . dirty = GL_TRUE ;
context - > ProjectionMatrixStack . dirty = GL_TRUE ;
context - > attribs - > DirtyMask = ( 1 < < _RGL_MAX_VERTEX_ATTRIBS ) - 1 ;
}
GLAPI void APIENTRY glGetFloatv ( GLenum pname , GLfloat * params )
{
PSGLcontext * LContext = _CurrentContext ;
jsMatrixStack * LMatrixStack = NULL ;
GLfloat * LMatrix = NULL ;
switch ( pname )
{
case GL_MODELVIEW_MATRIX :
jsContextGetMatrixf ( LContext , GL_MODELVIEW , LMatrixStack , LMatrix ) ;
break ;
case GL_PROJECTION_MATRIX :
jsContextGetMatrixf ( LContext , GL_PROJECTION , LMatrixStack , LMatrix ) ;
break ;
case GL_TEXTURE_MATRIX :
jsContextGetMatrixf ( LContext , GL_TEXTURE , LMatrixStack , LMatrix ) ;
break ;
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT :
return ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
memcpy ( params , LMatrixStack - > MatrixStackf + LMatrixStack - > MatrixStackPtr * ELEMENTS_IN_MATRIX , jsMATRIX_SIZEf ) ;
}
GLAPI void APIENTRY glEnable ( GLenum cap )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( cap )
{
case GL_SHADER_SRGB_REMAP_SCE :
LContext - > ShaderSRGBRemap = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_SHADER_SRGB_REMAP ;
break ;
case GL_BLEND :
LContext - > Blending = GL_TRUE ;
LContext - > BlendingMrt [ 0 ] = GL_TRUE ;
LContext - > BlendingMrt [ 1 ] = GL_TRUE ;
LContext - > BlendingMrt [ 2 ] = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT0_SCE :
LContext - > Blending = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT1_SCE :
LContext - > BlendingMrt [ 0 ] = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT2_SCE :
LContext - > BlendingMrt [ 1 ] = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT3_SCE :
LContext - > BlendingMrt [ 2 ] = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_POINT_SMOOTH :
break ;
case GL_DITHER :
LContext - > Dithering = GL_TRUE ;
break ;
case GL_POINT_SPRITE_OES :
case GL_VERTEX_PROGRAM_POINT_SIZE_ARB :
break ;
case GL_VSYNC_SCE :
LContext - > VSync = GL_TRUE ;
break ;
case GL_FRAGMENT_PROGRAM_CONTROL_CONTROLTXP_SCE :
LContext - > AllowTXPDemotion = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_FRAGMENT_PROGRAM ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
}
GLAPI void APIENTRY glDisable ( GLenum cap )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( cap )
{
case GL_SHADER_SRGB_REMAP_SCE :
LContext - > ShaderSRGBRemap = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_SHADER_SRGB_REMAP ;
break ;
case GL_BLEND :
LContext - > Blending = GL_FALSE ;
LContext - > BlendingMrt [ 0 ] = GL_FALSE ;
LContext - > BlendingMrt [ 1 ] = GL_FALSE ;
LContext - > BlendingMrt [ 2 ] = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT0_SCE :
LContext - > Blending = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT1_SCE :
LContext - > BlendingMrt [ 0 ] = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT2_SCE :
LContext - > BlendingMrt [ 1 ] = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_BLEND_MRT3_SCE :
LContext - > BlendingMrt [ 2 ] = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
break ;
case GL_POINT_SMOOTH :
case GL_LINE_SMOOTH :
break ;
case GL_DITHER :
LContext - > Dithering = GL_FALSE ;
break ;
case GL_POINT_SPRITE_OES :
case GL_VERTEX_PROGRAM_POINT_SIZE_ARB :
break ;
case GL_VSYNC_SCE :
LContext - > VSync = GL_FALSE ;
break ;
case GL_FRAGMENT_PROGRAM_CONTROL_CONTROLTXP_SCE :
LContext - > AllowTXPDemotion = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_FRAGMENT_PROGRAM ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
}
GLAPI void APIENTRY glEnableClientState ( GLenum array )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( array )
{
case GL_VERTEX_ARRAY :
_RGLEnableVertexAttribArrayNV ( _RGL_ATTRIB_POSITION_INDEX ) ;
break ;
case GL_COLOR_ARRAY :
_RGLEnableVertexAttribArrayNV ( _RGL_ATTRIB_PRIMARY_COLOR_INDEX ) ;
break ;
case GL_NORMAL_ARRAY :
_RGLEnableVertexAttribArrayNV ( _RGL_ATTRIB_NORMAL_INDEX ) ;
break ;
case GL_TEXTURE_COORD_ARRAY :
_RGLEnableVertexAttribArrayNV ( _RGL_ATTRIB_TEX_COORD0_INDEX + LContext - > CS_ActiveTexture ) ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
}
GLAPI void APIENTRY glDisableClientState ( GLenum array )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( array )
{
case GL_VERTEX_ARRAY :
_RGLDisableVertexAttribArrayNV ( _RGL_ATTRIB_POSITION_INDEX ) ;
break ;
case GL_COLOR_ARRAY :
_RGLDisableVertexAttribArrayNV ( _RGL_ATTRIB_PRIMARY_COLOR_INDEX ) ;
break ;
case GL_NORMAL_ARRAY :
_RGLDisableVertexAttribArrayNV ( _RGL_ATTRIB_NORMAL_INDEX ) ;
break ;
case GL_TEXTURE_COORD_ARRAY :
_RGLDisableVertexAttribArrayNV ( _RGL_ATTRIB_TEX_COORD0_INDEX + LContext - > CS_ActiveTexture ) ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
}
GLAPI void APIENTRY glFlush ( )
{
PSGLcontext * LContext = _CurrentContext ;
RGLFifo * fifo = & _RGLState . fifo ;
if ( RGL_UNLIKELY ( LContext - > needValidate ) )
_RGLValidateStates ( ) ;
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFlush ( fifo ) ;
}
GLAPI void APIENTRY glFinish ( void )
{
glFlush ( ) ;
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
}
GLAPI const GLubyte * APIENTRY glGetString ( GLenum name )
{
switch ( name )
{
case GL_VENDOR :
return ( ( GLubyte * ) _RGLVendorString ) ;
case GL_RENDERER :
return ( ( GLubyte * ) _RGLRendererString ) ;
case GL_VERSION :
return ( ( GLubyte * ) _RGLVersionNumber ) ;
case GL_EXTENSIONS :
return ( ( GLubyte * ) _RGLExtensionsString ) ;
default :
{
_RGLSetError ( GL_INVALID_ENUM ) ;
return ( ( GLubyte * ) NULL ) ;
}
}
}
void psglInit ( PSGLinitOptions * options )
{
if ( ! _RGLInitCompleted )
{
int ret = cellSysmoduleLoadModule ( CELL_SYSMODULE_GCM_SYS ) ;
ret = cellSysmoduleLoadModule ( CELL_SYSMODULE_RESC ) ;
_RGLDeviceInit ( options ) ;
_CurrentContext = NULL ;
_CurrentDevice = NULL ;
}
_RGLInitCompleted = 1 ;
}
void psglExit ( void )
{
PSGLcontext * LContext = _CurrentContext ;
if ( LContext )
{
glFlush ( ) ;
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
_RGLFifoFinish ( & _RGLState . fifo ) ;
psglMakeCurrent ( NULL , NULL ) ;
_RGLDeviceExit ( ) ;
_CurrentContext = NULL ;
_RGLInitCompleted = 0 ;
}
}
# undef __STRICT_ANSI__
GLAPI void APIENTRY glLoadIdentity ( )
{
PSGLcontext * LContext = _CurrentContext ;
jsMatrixStack * LMatrixStack = NULL ;
jsContextGetMatrixStack ( LContext , LContext - > MatrixMode , LMatrixStack ) ;
memcpy ( LMatrixStack - > MatrixStackf + LMatrixStack - > MatrixStackPtr * ELEMENTS_IN_MATRIX , _RGLIdentityMatrixf , jsMATRIX_SIZEf ) ;
LMatrixStack - > dirty = GL_TRUE ;
}
GLAPI void APIENTRY glMatrixMode ( GLenum mode )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > MatrixMode = mode ;
}
GLAPI void APIENTRY glOrthof ( GLfloat left , GLfloat right , GLfloat bottom , GLfloat top , GLfloat zNear , GLfloat zFar )
{
PSGLcontext * LContext = _CurrentContext ;
jsMatrixStack * LMatrixStack = NULL ;
GLfloat * LMatrix = NULL ;
jsContextGetMatrixStack ( LContext , LContext - > MatrixMode , LMatrixStack ) ;
if ( LMatrixStack )
LMatrix = LMatrixStack - > MatrixStackf + LMatrixStack - > MatrixStackPtr * ELEMENTS_IN_MATRIX ;
GLfloat L00 , L01 , L02 , L03 , L10 , L11 , L12 , L13 , L20 , L21 , L22 , L23 , L30 , L31 , L32 , L33 ;
GLfloat m00 = 2.f / ( right - left ) ;
GLfloat m03 = - ( right + left ) / ( right - left ) ;
GLfloat m11 = 2.f / ( top - bottom ) ;
GLfloat m13 = - ( top + bottom ) / ( top - bottom ) ;
GLfloat m22 = - 2.f / ( zFar - zNear ) ;
GLfloat m23 = - ( zFar + zNear ) / ( zFar - zNear ) ;
L00 = LMatrix [ 0 ] ;
L01 = LMatrix [ M01 ] ;
L02 = LMatrix [ M02 ] ;
L03 = LMatrix [ M03 ] ;
L10 = LMatrix [ M10 ] ;
L11 = LMatrix [ M11 ] ;
L12 = LMatrix [ M12 ] ;
L13 = LMatrix [ M13 ] ;
L20 = LMatrix [ M20 ] ;
L21 = LMatrix [ M21 ] ;
L22 = LMatrix [ M22 ] ;
L23 = LMatrix [ M23 ] ;
L30 = LMatrix [ M30 ] ;
L31 = LMatrix [ M31 ] ;
L32 = LMatrix [ M32 ] ;
L33 = LMatrix [ M33 ] ;
LMatrix [ 0 ] = L00 * m00 ;
LMatrix [ M01 ] = L01 * m11 ;
LMatrix [ M02 ] = L02 * m22 ;
LMatrix [ M03 ] = L00 * m03 + L01 * m13 + L02 * m23 + L03 ;
LMatrix [ M10 ] = L10 * m00 ;
LMatrix [ M11 ] = L11 * m11 ;
LMatrix [ M12 ] = L12 * m22 ;
LMatrix [ M13 ] = L10 * m03 + L11 * m13 + L12 * m23 + L13 ;
LMatrix [ M20 ] = L20 * m00 ;
LMatrix [ M21 ] = L21 * m11 ;
LMatrix [ M22 ] = L22 * m22 ;
LMatrix [ M23 ] = L20 * m03 + L21 * m13 + L22 * m23 + L23 ;
LMatrix [ M30 ] = L30 * m00 ;
LMatrix [ M31 ] = L31 * m11 ;
LMatrix [ M32 ] = L32 * m22 ;
LMatrix [ M33 ] = L30 * m03 + L31 * m13 + L32 * m23 + L33 ;
LMatrixStack - > dirty = GL_TRUE ;
if ( LContext - > MatrixMode = = GL_MODELVIEW )
LContext - > InverseModelViewValid = GL_FALSE ;
}
const uint32_t c_rounded_size_of_RGLDrawParams = ( sizeof ( jsDrawParams ) + 0x7f ) & ~ 0x7f ;
static uint8_t s_dparams_buff [ c_rounded_size_of_RGLDrawParams ] __attribute__ ( ( aligned ( 128 ) ) ) ;
int _psglCheckDrawElementsVBOBounds = 0 ;
GLAPI void APIENTRY glVertexPointer ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer )
{
_RGLVertexAttribPointerNV ( _RGL_ATTRIB_POSITION_INDEX , size , type , GL_FALSE , stride , pointer ) ;
}
GLAPI void APIENTRY glTexCoordPointer ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer )
{
PSGLcontext * LContext = _CurrentContext ;
_RGLVertexAttribPointerNV (
_RGL_ATTRIB_TEX_COORD0_INDEX + LContext - > CS_ActiveTexture ,
size ,
type ,
GL_FALSE ,
stride ,
pointer ) ;
}
GLAPI void APIENTRY glColorPointer ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer )
{
_RGLVertexAttribPointerNV ( _RGL_ATTRIB_PRIMARY_COLOR_INDEX , size , type , GL_TRUE , stride , pointer ) ;
}
static GLboolean _RGLPlatformNeedsConversion ( const jsAttributeState * as , GLuint index )
{
const jsAttribute * attrib = as - > attrib + index ;
switch ( attrib - > clientType )
{
case GL_SHORT :
case GL_HALF_FLOAT_ARB :
case GL_FLOAT :
case GL_FIXED_11_11_10_SCE :
return GL_FALSE ;
case GL_UNSIGNED_BYTE :
if ( attrib - > normalized | |
attrib - > clientSize = = 4 )
return GL_FALSE ;
break ;
default :
break ;
}
printf ( " RGL WARN: Attribute %d needs conversion. Slow path ahead. \n " , index ) ;
return GL_TRUE ;
}
static int _RGLGetTypeSize ( GLenum type )
{
switch ( type )
{
# define DECLARE_PACKED_TYPE(REALTYPE,TYPE,N,S1,S2,S3,S4,REV) \
case TYPE : \
return sizeof ( type_ # # REALTYPE ) ;
DECLARE_PACKED_TYPES
# undef DECLARE_PACKED_TYPE
# define DECLARE_UNPACKED_TYPE(TYPE) \
case TYPE : \
return sizeof ( type_ # # TYPE ) ;
DECLARE_UNPACKED_TYPES
# undef DECLARE_UNPACKED_TYPE
default :
return 0 ;
}
}
void _RGLVertexAttribPointerNV (
GLuint index ,
GLint fsize ,
GLenum type ,
GLboolean normalized ,
GLsizei stride ,
const GLvoid * pointer )
{
PSGLcontext * LContext = _CurrentContext ;
GLsizei defaultStride = 0 ;
switch ( type )
{
case GL_FLOAT :
case GL_HALF_FLOAT_ARB :
case GL_BYTE :
case GL_UNSIGNED_BYTE :
case GL_SHORT :
case GL_FIXED :
defaultStride = fsize * _RGLGetTypeSize ( type ) ;
break ;
case GL_FIXED_11_11_10_SCE :
defaultStride = 4 ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
jsAttributeState * as = LContext - > attribs ;
jsAttribute * attrib = as - > attrib + index ;
attrib - > clientSize = fsize ;
attrib - > clientType = type ;
attrib - > clientStride = stride ? stride : defaultStride ;
attrib - > clientData = ( void * ) pointer ;
GLuint oldArrayBuffer = attrib - > arrayBuffer ;
attrib - > arrayBuffer = LContext - > ArrayBuffer ;
attrib - > normalized = normalized ;
RGLBIT_ASSIGN ( as - > HasVBOMask , index , attrib - > arrayBuffer ! = 0 ) ;
GLboolean needConvert = _RGLPlatformNeedsConversion ( as , index ) ;
RGLBIT_ASSIGN ( as - > NeedsConversionMask , index , needConvert ) ;
RGLBIT_TRUE ( as - > DirtyMask , index ) ;
if ( LContext - > attribSetName )
{
jsAttribSet * attribSet = _RGLGetAttribSet ( LContext - > attribSetName ) ;
if ( oldArrayBuffer )
{
int refcount = 0 ;
for ( unsigned int i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
if ( attribSet - > attribs . attrib [ i ] . arrayBuffer = = oldArrayBuffer ) + + refcount ;
}
if ( refcount = = 1 ) _RGLGetBufferObject ( LContext , oldArrayBuffer ) - > attribSets . removeElement ( attribSet ) ;
}
if ( attrib - > arrayBuffer )
{
_RGLGetBufferObject ( LContext , attrib - > arrayBuffer ) - > attribSets . appendUnique ( attribSet ) ;
}
_RGLAttribSetMarkDirty ( ) ;
}
}
void _RGLEnableVertexAttribArrayNV ( GLuint index )
{
PSGLcontext * LContext = _CurrentContext ;
RGLBIT_TRUE ( LContext - > attribs - > EnabledMask , index ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , index ) ;
if ( LContext - > attribSetName )
_RGLAttribSetMarkDirty ( ) ;
}
void _RGLDisableVertexAttribArrayNV ( GLuint index )
{
PSGLcontext * LContext = _CurrentContext ;
RGLBIT_FALSE ( LContext - > attribs - > EnabledMask , index ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , index ) ;
if ( LContext - > attribSetName )
_RGLAttribSetMarkDirty ( ) ;
}
static GLuint _RGLValidateAttributesSlow ( jsDrawParams * dparams , GLboolean * isMain )
{
PSGLcontext * LContext = _CurrentContext ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
jsAttributeState * as = LContext - > attribs ;
void * xferBuffer = NULL ;
GLuint xferId = GMM_ERROR ;
GLuint VBOId = GMM_ERROR ;
GLuint gpuOffset ;
if ( RGL_UNLIKELY ( dparams - > xferTotalSize ) )
{
xferId = gmmAlloc ( 0 , dparams - > xferTotalSize ) ;
xferBuffer = gmmIdToAddress ( xferId ) ;
}
unsigned int needsUpdateMask = ( as - > DirtyMask | ( as - > EnabledMask & ~ as - > HasVBOMask ) ) ;
LContext - > attribSetDirty = GL_FALSE ;
if ( needsUpdateMask )
{
for ( GLuint i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
if ( ! RGLBIT_GET ( needsUpdateMask , i ) )
continue ;
jsAttribute * attrib = as - > attrib + i ;
if ( RGLBIT_GET ( as - > EnabledMask , i ) )
{
const GLsizei stride = attrib - > clientStride ;
const GLuint freq = attrib - > frequency ;
if ( RGL_UNLIKELY ( dparams - > attribXferSize [ i ] ) )
{
GLuint maxElements = dparams - > firstVertex + dparams - > vertexCount ;
GLuint offset ;
if ( RGLBIT_GET ( as - > ModuloMask , i ) )
offset = ( maxElements > freq ) ? 0 : dparams - > firstVertex * stride ;
else
offset = ( dparams - > firstVertex / freq ) * stride ;
char * b = ( char * ) xferBuffer + dparams - > attribXferOffset [ i ] ;
memcpy ( b + offset ,
( char * ) attrib - > clientData + offset ,
dparams - > attribXferSize [ i ] - offset ) ;
* isMain = gmmIdIsMain ( xferId ) ;
gpuOffset = gmmIdToOffset ( xferId ) + ( b - ( char * ) xferBuffer ) ;
}
else
{
VBOId = _RGLGetBufferObjectOrigin ( attrib - > arrayBuffer ) ;
* isMain = gmmIdIsMain ( VBOId ) ;
gpuOffset = gmmIdToOffset ( VBOId )
+ ( ( const GLubyte * ) attrib - > clientData - ( const GLubyte * ) NULL ) ;
}
_RGLFifoGlVertexAttribPointer ( i , attrib - > clientSize ,
( RGLEnum ) attrib - > clientType , attrib - > normalized ,
stride , freq , * isMain , gpuOffset ) ;
}
else
{
_RGLFifoGlVertexAttribPointer ( i , 0 , RGL_FLOAT , 0 , 0 , 0 , 0 , 0 ) ;
cellGcmSetVertexData4fInline ( & _RGLState . fifo , i , attrib - > value ) ;
}
}
cellGcmSetFrequencyDividerOperationInline ( & _RGLState . fifo , as - > ModuloMask ) ;
driver - > invalidateVertexCache = GL_TRUE ;
}
as - > DirtyMask = 0 ;
if ( xferId ! = GMM_ERROR )
gmmFree ( xferId ) ;
return 0 ;
}
GLAPI void APIENTRY glDrawArrays ( GLenum mode , GLint first , GLsizei count )
{
PSGLcontext * LContext = _CurrentContext ;
jsAttributeState * as = LContext - > attribs ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
const GLuint clientSideMask = as - > EnabledMask & ~ as - > HasVBOMask ;
if ( RGL_UNLIKELY ( ! RGLBIT_GET ( LContext - > attribs - > EnabledMask , _RGL_ATTRIB_POSITION_INDEX ) ) ) return ;
uint32_t _tmp_clear_loop = c_rounded_size_of_RGLDrawParams > > 7 ;
do {
- - _tmp_clear_loop ;
__dcbz ( s_dparams_buff + ( _tmp_clear_loop < < 7 ) ) ;
} while ( _tmp_clear_loop ) ;
jsDrawParams * dparams = ( jsDrawParams * ) s_dparams_buff ;
dparams - > mode = mode ;
dparams - > firstVertex = first ;
dparams - > vertexCount = count ;
GLuint maxElements = dparams - > firstVertex + dparams - > vertexCount ;
if ( LContext - > needValidate )
_RGLValidateStates ( ) ;
if ( RGL_UNLIKELY ( clientSideMask ) )
{
for ( int i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
{
if ( clientSideMask & ( 1 < < i ) )
{
jsAttribute * attrib = as - > attrib + i ;
const GLuint freq = attrib - > frequency ;
GLuint count ;
if ( RGLBIT_GET ( as - > ModuloMask , i ) )
count = maxElements > freq ? freq : maxElements ; else
count = ( maxElements + freq - 1 ) / freq ;
const GLuint numBytes = attrib - > clientStride * count ;
dparams - > attribXferOffset [ i ] = dparams - > xferTotalSize ;
dparams - > attribXferSize [ i ] = numBytes ;
const GLuint numBytesPadded = _RGLPad ( numBytes , 128 ) ;
dparams - > xferTotalSize + = numBytesPadded ;
dparams - > attribXferTotalSize + = numBytesPadded ;
}
else
{
dparams - > attribXferOffset [ i ] = 0 ;
dparams - > attribXferSize [ i ] = 0 ;
}
}
}
if ( driver - > flushBufferCount ! = 0 )
driver - > invalidateVertexCache = GL_TRUE ;
GLboolean isMain = 0 ;
if ( LContext - > attribSetDirty & & LContext - > attribSetName )
{
jsAttribSet * attribSet = _RGLGetAttribSet ( LContext - > attribSetName ) ;
}
uint32_t totalXfer = 0 ;
for ( GLuint i = 0 ; i < _RGL_MAX_VERTEX_ATTRIBS ; + + i )
totalXfer + = dparams - > attribXferSize [ i ] ;
GLuint gpuOffset = _RGLValidateAttributesSlow ( dparams , & isMain ) ;
( void ) gpuOffset ;
if ( driver - > invalidateVertexCache )
{
driver - > invalidateVertexCache = GL_FALSE ;
cellGcmSetInvalidateVertexCacheInline ( & _RGLState . fifo ) ;
}
cellGcmSetUpdateFragmentProgramParameterInline ( & _RGLState . fifo , gmmIdToOffset ( driver - > fpLoadProgramId ) + driver - > fpLoadProgramOffset ) ;
cellGcmSetDrawArraysInline ( & _RGLState . fifo , CELL_GCM_PRIMITIVE_QUADS , dparams - > firstVertex , dparams - > vertexCount ) ;
}
GLAPI void APIENTRY glGenTextures ( GLsizei n , GLuint * textures )
{
PSGLcontext * LContext = _CurrentContext ;
_RGLTexNameSpaceGenNames ( & LContext - > textureNameSpace , n , textures ) ;
}
static void _RGLTextureUnbind ( PSGLcontext * context , GLuint name )
{
int unit ;
for ( unit = 0 ; unit < _RGL_MAX_TEXTURE_IMAGE_UNITS ; + + unit )
{
jsTextureImageUnit * tu = context - > TextureImageUnits + unit ;
GLboolean dirty = GL_FALSE ;
if ( tu - > bound2D = = name )
{
tu - > bound2D = 0 ;
dirty = GL_TRUE ;
}
if ( dirty )
{
tu - > currentTexture = _RGLGetCurrentTexture ( tu , GL_TEXTURE_2D ) ;
context - > needValidate | = PSGL_VALIDATE_TEXTURES_USED ;
}
}
if ( _RGLTexNameSpaceIsName ( & context - > textureNameSpace , name ) )
{
jsTexture * texture = ( jsTexture * ) context - > textureNameSpace . data [ name ] ;
for ( unit = 0 ; unit < _RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + unit )
{
if ( context - > VertexTextureImages [ unit ] = = texture )
{
context - > VertexTextureImages [ unit ] = NULL ;
context - > needValidate | = PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
}
}
}
GLAPI void APIENTRY glDeleteTextures ( GLsizei n , const GLuint * textures )
{
PSGLcontext * LContext = _CurrentContext ;
for ( int i = 0 ; i < n ; + + i )
if ( textures [ i ] )
_RGLTextureUnbind ( LContext , textures [ i ] ) ;
_RGLTexNameSpaceDeleteNames ( & LContext - > textureNameSpace , n , textures ) ;
}
GLAPI void APIENTRY glTexParameteri ( GLenum target , GLenum pname , GLint param )
{
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture = _RGLGetCurrentTexture ( LContext - > CurrentImageUnit , target ) ;
switch ( pname )
{
case GL_TEXTURE_MIN_FILTER :
texture - > minFilter = param ;
if ( texture - > referenceBuffer = = 0 )
{
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_LAYOUT ; }
break ;
case GL_TEXTURE_MAG_FILTER :
texture - > magFilter = param ;
break ;
case GL_TEXTURE_MAX_LEVEL :
case GL_TEXTURE_WRAP_S :
case GL_TEXTURE_WRAP_T :
case GL_TEXTURE_WRAP_R :
case GL_TEXTURE_FROM_VERTEX_PROGRAM_SCE :
break ;
case GL_TEXTURE_ALLOCATION_HINT_SCE :
texture - > usage = param ;
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_LAYOUT ;
break ;
case GL_TEXTURE_MIN_LOD :
case GL_TEXTURE_MAX_LOD :
case GL_TEXTURE_LOD_BIAS :
case GL_TEXTURE_MAX_ANISOTROPY_EXT :
case GL_DEPTH_TEXTURE_MODE_ARB :
case GL_TEXTURE_COMPARE_MODE_ARB :
case GL_TEXTURE_COMPARE_FUNC_ARB :
break ;
case GL_TEXTURE_GAMMA_REMAP_R_SCE :
case GL_TEXTURE_GAMMA_REMAP_G_SCE :
case GL_TEXTURE_GAMMA_REMAP_B_SCE :
case GL_TEXTURE_GAMMA_REMAP_A_SCE :
{
GLuint bit = 1 < < ( pname - GL_TEXTURE_GAMMA_REMAP_R_SCE ) ;
if ( param ) texture - > gammaRemap | = bit ;
else texture - > gammaRemap & = ~ bit ;
}
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_PARAMETERS ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
GLAPI void APIENTRY glBindTexture ( GLenum target , GLuint name )
{
PSGLcontext * LContext = _CurrentContext ;
jsTextureImageUnit * unit = LContext - > CurrentImageUnit ;
_RGLBindTextureInternal ( unit , name ) ;
}
static void _RGLReallocateImages ( jsTexture * texture , GLsizei dimension )
{
GLuint oldCount = texture - > imageCount ;
if ( dimension < = 0 ) dimension = 1 ;
GLuint n = 1 + _RGLLog2 ( dimension ) ;
n = MAX ( n , oldCount ) ;
jsImage * images = ( jsImage * ) realloc ( texture - > image , n * sizeof ( jsImage ) ) ;
memset ( images + oldCount , 0 , ( n - oldCount ) * sizeof ( jsImage ) ) ;
texture - > image = images ;
texture - > imageCount = n ;
}
static int _RGLGetImage ( GLenum target , GLint level , jsTexture * * texture , jsImage * * image , GLsizei reallocateSize )
{
PSGLcontext * LContext = _CurrentContext ;
jsTextureImageUnit * unit = LContext - > CurrentImageUnit ;
jsTexture * tex = _RGLGetCurrentTexture ( unit , GL_TEXTURE_2D ) ;
if ( level > = ( int ) tex - > imageCount )
_RGLReallocateImages ( tex , reallocateSize ) ;
* image = tex - > image ;
* texture = tex ;
return 0 ;
}
GLAPI void APIENTRY glTexImage2D ( GLenum target , GLint level , GLint internalFormat ,
GLsizei width , GLsizei height , GLint border , GLenum format ,
GLenum type , const GLvoid * pixels )
{
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture ;
jsImage * image ;
_RGLGetImage ( GL_TEXTURE_2D , 0 , & texture , & image , MAX ( width , height ) ) ;
image - > dataState = _RGL_IMAGE_DATASTATE_UNSET ;
GLboolean directPBO = GL_FALSE ;
if ( LContext - > PixelUnpackBuffer ! = 0 )
{
directPBO = _RGLPlatformTexturePBOImage (
texture ,
image ,
internalFormat ,
width , height ,
format , type ,
pixels ) ;
}
if ( ! directPBO )
{
jsBufferObject * bufferObject = NULL ;
if ( LContext - > PixelUnpackBuffer ! = 0 )
{
bufferObject = _RGLGetBufferObject ( LContext , LContext - > PixelUnpackBuffer ) ;
pixels = _RGLPlatformBufferObjectMap ( bufferObject , GL_READ_ONLY ) +
( ( const GLubyte * ) pixels - ( const GLubyte * ) NULL ) ;
}
_RGLSetImage (
image ,
internalFormat ,
width , height , 1 ,
LContext - > unpackAlignment ,
format , type ,
pixels ) ;
if ( LContext - > PixelUnpackBuffer ! = 0 )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
if ( - - jsBuffer - > mapCount = = 0 )
{
if ( jsBuffer - > mapAccess ! = GL_READ_ONLY )
{
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
- - driver - > flushBufferCount ;
driver - > invalidateVertexCache = GL_TRUE ;
}
jsBuffer - > mapAccess = GL_NONE ;
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) jsBuffer - > bufferId ;
if ( ! pBaseBlock - > isTile )
{
GmmBlock * pBlock = ( GmmBlock * ) jsBuffer - > bufferId ;
pBlock - > isPinned = 0 ;
}
}
}
texture - > revalidate | = _RGL_TEXTURE_REVALIDATE_IMAGES ;
}
_RGLTextureTouchFBOs ( texture ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
GLAPI void APIENTRY glActiveTexture ( GLenum texture )
{
PSGLcontext * LContext = _CurrentContext ;
int unit = texture - GL_TEXTURE0 ;
LContext - > ActiveTexture = unit ;
LContext - > CurrentImageUnit = unit < _RGL_MAX_TEXTURE_IMAGE_UNITS ? LContext - > TextureImageUnits + unit : NULL ;
LContext - > CurrentCoordsUnit = unit < _RGL_MAX_TEXTURE_COORDS ? LContext - > TextureCoordsUnits + unit : NULL ;
}
GLAPI void APIENTRY glClientActiveTexture ( GLenum texture )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > CS_ActiveTexture = texture - GL_TEXTURE0 ;
}
GLAPI void APIENTRY glPixelStorei ( GLenum pname , GLint param )
{
PSGLcontext * LContext = _CurrentContext ;
switch ( pname )
{
case GL_PACK_ALIGNMENT :
LContext - > packAlignment = param ;
break ;
case GL_UNPACK_ALIGNMENT :
LContext - > unpackAlignment = param ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
}
GLAPI void APIENTRY glTextureReferenceSCE ( GLenum target , GLuint levels , GLuint baseWidth , GLuint baseHeight , GLuint baseDepth , GLenum internalFormat , GLuint pitch , GLintptr offset )
{
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture = _RGLGetCurrentTexture ( LContext - > CurrentImageUnit , GL_TEXTURE_2D ) ;
jsBufferObject * bufferObject = _RGLGetBufferObject ( LContext , LContext - > TextureBuffer ) ;
_RGLReallocateImages ( texture , MAX ( baseWidth , MAX ( baseHeight , baseDepth ) ) ) ;
GLuint width = baseWidth ;
GLuint height = baseHeight ;
_RGLSetImage ( texture - > image , GL_RGB5_A1 , width , height , 0 , LContext - > unpackAlignment ,
0 , 0 , NULL ) ;
width = MAX ( 1U , width / 2 ) ;
height = MAX ( 1U , height / 2 ) ;
texture - > usage = GL_TEXTURE_LINEAR_GPU_SCE ;
GLboolean r = _RGLPlatformTextureReference ( texture , pitch , bufferObject , offset ) ;
if ( ! r )
return ;
bufferObject - > textureReferences . pushBack ( texture ) ;
texture - > referenceBuffer = bufferObject ;
texture - > offset = offset ;
_RGLTextureTouchFBOs ( texture ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
GLAPI void APIENTRY glViewport ( GLint x , GLint y , GLsizei width , GLsizei height )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > ViewPort . X = x ;
LContext - > ViewPort . Y = y ;
LContext - > ViewPort . XSize = width ;
LContext - > ViewPort . YSize = height ;
_RGLFifoGlViewport ( LContext - > ViewPort . X , LContext - > ViewPort . Y ,
LContext - > ViewPort . XSize , LContext - > ViewPort . YSize , 0.0f , 1.0f ) ;
}
jsTexture * _RGLGetCurrentTexture ( const jsTextureImageUnit * unit , GLenum target )
{
PSGLcontext * LContext = _CurrentContext ;
GLuint name = unit - > bound2D ;
jsTexture * defaultTexture = unit - > default2D ;
if ( name )
return ( jsTexture * ) LContext - > textureNameSpace . data [ name ] ;
else
return defaultTexture ;
}
CgprogramHookFunction _cgProgramCreateHook = NULL ;
CgprogramHookFunction _cgProgramDestroyHook = NULL ;
CgprogramCopyHookFunction _cgProgramCopyHook = NULL ;
cgRTCgcCompileHookFunction _cgRTCgcCompileProgramHook = NULL ;
cgRTCgcFreeHookFunction _cgRTCgcFreeCompiledProgramHook ;
CgcontextHookFunction _cgContextCreateHook = NULL ;
CgcontextHookFunction _cgContextDestroyHook = NULL ;
CgparameterHookFunction _cgParameterCreateHook = NULL ;
CgparameterHookFunction _cgParameterDestroyHook = NULL ;
typedef struct RGLcgProfileMapType
{
CGprofile id ;
char * string ;
int is_vertex_program ;
}
RGLcgProfileMapType ;
static void _RGLCgProgramPushFront ( _CGcontext * ctx , _CGprogram * prog )
{
prog - > next = ctx - > programList ;
ctx - > programList = prog ;
prog - > parentContext = ctx ;
ctx - > programCount + + ;
}
static _CGprogram * _RGLCgProgramFindPrev ( _CGcontext * ctx , _CGprogram * prog )
{
_CGprogram * ptr = ctx - > programList ;
while ( NULL ! = ptr & & prog ! = ptr - > next )
{
ptr = ptr - > next ;
}
return ptr ;
}
void _RGLCgProgramErase ( _CGprogram * prog )
{
if ( _cgProgramDestroyHook ) _cgProgramDestroyHook ( prog ) ;
switch ( prog - > header . profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
_RGLPlatformProgramErase ( prog ) ;
break ;
default :
break ;
}
if ( prog - > id ) _RGLEraseName ( & _CurrentContext - > cgProgramNameSpace , ( jsName ) prog - > id ) ;
if ( prog - > runtimeElf )
free ( prog - > runtimeElf ) ;
memset ( prog , 0 , sizeof ( _CGprogram ) ) ;
}
bool _RGLCgCreateProgramChecks ( CGcontext ctx , CGprofile profile , CGenum program_type )
{
if ( ! CG_IS_CONTEXT ( ctx ) )
{
_RGLCgRaiseError ( CG_INVALID_CONTEXT_HANDLE_ERROR ) ;
return false ;
}
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
case CG_PROFILE_SCE_FP_RSX :
break ;
default :
_RGLCgRaiseError ( CG_UNKNOWN_PROFILE_ERROR ) ;
return false ;
}
switch ( program_type )
{
case CG_BINARY :
case CG_SOURCE :
break ;
default :
_RGLCgRaiseError ( CG_INVALID_ENUMERANT_ERROR ) ;
return false ;
}
return true ;
}
typedef struct
{
const char * elfFile ;
size_t elfFileSize ;
const char * symtab ;
size_t symbolSize ;
size_t symbolCount ;
const char * symbolstrtab ;
const char * shadertab ;
size_t shadertabSize ;
const char * strtab ;
size_t strtabSize ;
const char * consttab ;
size_t consttabSize ;
}
CGELFBinary ;
typedef struct
{
const char * texttab ;
size_t texttabSize ;
const char * paramtab ;
size_t paramtabSize ;
int index ;
}
CGELFProgram ;
static bool cgOpenElf ( const void * ptr , size_t size , CGELFBinary * elfBinary )
{
while ( 1 )
{
size_t symbolSize ;
size_t symbolCount ;
const char * symbolstrtab ;
const char * symtab = findSymbolSectionInPlace ( ( const char * ) ptr , size , & symbolSize , & symbolCount , & symbolstrtab ) ;
if ( ! symtab )
break ;
size_t shadertabSize ;
const char * shadertab = findSectionInPlace ( ( const char * ) ptr , size , " .shadertab " , & shadertabSize ) ;
if ( ! shadertab )
break ;
size_t strtabSize ;
const char * strtab = findSectionInPlace ( ( const char * ) ptr , size , " .strtab " , & strtabSize ) ;
if ( ! strtab )
break ;
size_t consttabSize ;
const char * consttab = findSectionInPlace ( ( const char * ) ptr , size , " .const " , & consttabSize ) ;
if ( ! consttab )
break ;
elfBinary - > elfFile = ( const char * ) ptr ;
elfBinary - > elfFileSize = size ;
elfBinary - > symtab = symtab ;
elfBinary - > symbolSize = symbolSize ;
elfBinary - > symbolCount = symbolCount ;
elfBinary - > symbolstrtab = symbolstrtab ;
elfBinary - > shadertab = shadertab ;
elfBinary - > shadertabSize = shadertabSize ;
elfBinary - > strtab = strtab ;
elfBinary - > strtabSize = strtabSize ;
elfBinary - > consttab = consttab ;
elfBinary - > consttabSize = consttabSize ;
return true ;
}
return false ;
}
static bool cgGetElfProgramByIndex ( CGELFBinary * elfBinary , int index , CGELFProgram * elfProgram )
{
while ( true )
{
char sectionName [ 64 ] ;
2012-05-22 18:32:08 +02:00
snprintf ( sectionName , sizeof ( sectionName ) , " .text%04i " , index ) ;
2012-05-06 03:46:55 +02:00
size_t texttabSize ;
const char * texttab = findSectionInPlace ( elfBinary - > elfFile , elfBinary - > elfFileSize , sectionName , & texttabSize ) ;
if ( ! texttab )
break ;
2012-05-22 18:32:08 +02:00
snprintf ( sectionName , sizeof ( sectionName ) , " .paramtab%04i " , index ) ;
2012-05-06 03:46:55 +02:00
size_t paramtabSize ;
const char * paramtab = findSectionInPlace ( elfBinary - > elfFile , elfBinary - > elfFileSize , sectionName , & paramtabSize ) ;
if ( ! paramtab )
break ;
elfProgram - > texttab = texttab ;
elfProgram - > texttabSize = texttabSize ;
elfProgram - > paramtab = paramtab ;
elfProgram - > paramtabSize = paramtabSize ;
elfProgram - > index = index ;
return true ;
}
return false ;
}
static bool cgGetElfProgramByName ( CGELFBinary * elfBinary , const char * name , CGELFProgram * elfProgram )
{
//if no name try to return the first program
int res ;
if ( name = = NULL | | name [ 0 ] = = ' \0 ' )
res = 0 ;
else
res = lookupSymbolValueInPlace ( elfBinary - > symtab , elfBinary - > symbolSize , elfBinary - > symbolCount , elfBinary - > symbolstrtab , name ) ;
if ( res ! = - 1 )
return cgGetElfProgramByIndex ( elfBinary , res , elfProgram ) ;
else
return false ;
}
static CGprogram _RGLCgCreateProgram ( CGcontext ctx , CGprofile profile , const CgProgramHeader * programHeader , const void * ucode , const CgParameterTableHeader * parameterHeader , const char * stringTable , const float * defaultValues )
{
// Create the program structure.
// all the structural data is filled in here,
// as well as the profile.
// The parameters and the actual program are generated from the ABI specific calls.
_CGprogram * prog = ( _CGprogram * ) malloc ( sizeof ( _CGprogram ) ) ;
if ( NULL = = prog )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return NULL ;
}
// zero out the fields
memset ( prog , 0 , sizeof ( _CGprogram ) ) ;
// fill in the fields we know
prog - > parentContext = _cgGetContextPtr ( ctx ) ;
prog - > header . profile = profile ;
int success = 0 ;
// create a name for the program and record it in the object
CGprogram id = ( CGprogram ) _RGLCreateName ( & _CurrentContext - > cgProgramNameSpace , prog ) ;
if ( ! id )
{
free ( prog ) ;
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return NULL ;
}
prog - > id = id ;
//hack to counter removal of TypeC during beta
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
// load the binary into the program object
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
//case CG_PROFILE_SCE_VP_TYPEC:
case CG_PROFILE_SCE_VP_RSX :
// TODO ************** need to include the entry symbol too
success = _RGLGenerateProgram ( prog , VERTEX_PROFILE_INDEX , programHeader ,
ucode , parameterHeader , NULL , stringTable , defaultValues ) ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
//case CG_PROFILE_SCE_FP_TYPEC:
case CG_PROFILE_SCE_FP_RSX :
success = _RGLPlatformGenerateFragmentProgram ( prog , programHeader , ucode , parameterHeader , stringTable , defaultValues ) ;
break ;
default :
// should never reach here
break ;
}
// if the creation failed, free all resources.
// the error was raised when the error was encoutered.
if ( 0 = = success )
{
// free the program object
free ( prog ) ;
// release the id too
_RGLEraseName ( & _CurrentContext - > cgProgramNameSpace , ( jsName ) id ) ;
return NULL ;
}
// success! add the program to the program list in the context.
_RGLCgProgramPushFront ( prog - > parentContext , prog ) ;
if ( _cgProgramCreateHook ) _cgProgramCreateHook ( prog ) ;
// everything worked.
return id ;
}
static CGprogram _RGLCgUpdateProgramAtIndex ( CGprogramGroup group , int index , int refcount ) ;
CG_API CGprogram cgCreateProgram ( CGcontext ctx ,
CGenum program_type ,
const char * program ,
CGprofile profile ,
const char * entry ,
const char * * args )
{
// Load a program from a memory pointer.
// NOTE: in our API all programs are pre-compiled binaries
// so entry point and compiler arguments are ignored.
//hack to counter removal of TypeC during beta
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
//hack to counter change of defines for program_type at r5294
// previously CG_BINARY was defined the same as CG_ROW_MAJOR
// if those values are passed in here, move them to the new values and remove this hack after we have
// an sdk that incorporates these changes so that prebuild libs (aka debugfont) can be used meanwhile
if ( program_type = = CG_ROW_MAJOR )
program_type = CG_BINARY ;
if ( ! _RGLCgCreateProgramChecks ( ctx , profile , program_type ) )
return NULL ;
//data to extract from the buffer passed:
CgProgramHeader * programHeader = NULL ;
const void * ucode = NULL ;
CgParameterTableHeader * parameterHeader = NULL ;
const char * stringTable = NULL ;
const float * defaultValues = NULL ;
//first step, compile any source file
const char * binaryBuffer = NULL ;
char * compiled_program = NULL ;
if ( program_type = = CG_SOURCE )
{
if ( _cgRTCgcCompileProgramHook )
{
_cgRTCgcCompileProgramHook ( program , cgGetProfileString ( profile ) , entry , args , & compiled_program ) ;
if ( ! compiled_program )
{
_RGLCgRaiseError ( CG_COMPILER_ERROR ) ;
return NULL ;
}
binaryBuffer = compiled_program ;
}
else
{
printf ( " RGL ERR: The CG runtime compiler hasn't been setup. cgRTCgcInit() should be called prior to this function. \n " ) ;
_RGLCgRaiseError ( CG_INVALID_ENUMERANT_ERROR ) ;
return NULL ;
}
}
else
{
binaryBuffer = program ;
}
bool bConvertedToElf = false ;
//At that point we have a binary file which is either any ELF or an NV format file
const unsigned int ElfTag = 0x7F454C46 ; // == MAKEFOURCC(0x7F,'E','L','F');
if ( ! ( * ( unsigned int * ) binaryBuffer = = ElfTag ) )
{
//we have an NV file, convert it to the runtime format
// if it was initially binary, throw warning about old format and recommend conversion to new with cgnv2elf
// don't throw the warning if it was source, cause clearly that would have been on purpose.
if ( program_type = = CG_BINARY )
{
printf ( " RGL WARN: A binary shader is being loaded using a deprecated binary format. Please use the cgnv2elf tool to convert to the new, memory-saving, faster-loading format. \n " ) ;
}
//convert from NV format to the runtime format
int compiled_program_size = 0 ;
STL_NAMESPACE vector < char > stringTableArray ;
STL_NAMESPACE vector < float > defaultValuesArray ;
CgBinaryProgram * nvProgram = ( CgBinaryProgram * ) binaryBuffer ;
char * runtimeElfShader = NULL ;
//check the endianness
int totalSize ;
if ( ( nvProgram - > profile ! = CG_PROFILE_SCE_FP_TYPEB ) & & ( nvProgram - > profile ! = CG_PROFILE_SCE_VP_TYPEB ) & &
( nvProgram - > profile ! = ( CGprofile ) 7006 ) & & ( nvProgram - > profile ! = ( CGprofile ) 7005 ) & &
( nvProgram - > profile ! = CG_PROFILE_SCE_FP_RSX ) & & ( nvProgram - > profile ! = CG_PROFILE_SCE_VP_RSX ) )
{
totalSize = endianSwapWord ( nvProgram - > totalSize ) ;
}
else
totalSize = nvProgram - > totalSize ;
int res = convertNvToElfFromMemory ( binaryBuffer , totalSize , 2 , 0 , ( void * * ) & runtimeElfShader , & compiled_program_size , stringTableArray , defaultValuesArray ) ;
if ( res ! = 0 )
{
printf ( " RGL ERR: invalid CG binary program. \n " ) ;
_RGLCgRaiseError ( CG_COMPILER_ERROR ) ;
if ( compiled_program )
_cgRTCgcFreeCompiledProgramHook ( compiled_program ) ;
return NULL ;
}
if ( compiled_program )
_cgRTCgcFreeCompiledProgramHook ( compiled_program ) ;
size_t stringTableSize = stringTableArray . size ( ) * sizeof ( stringTable [ 0 ] ) ;
size_t defaultTableSize = defaultValuesArray . size ( ) * sizeof ( defaultValues [ 0 ] ) ;
int paddedSize = _RGLPad ( compiled_program_size , 4 ) ;
char * runtimeElf = ( char * ) memalign ( 16 , paddedSize + stringTableSize + defaultTableSize ) ;
if ( ! runtimeElf )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return NULL ;
}
bConvertedToElf = true ;
memcpy ( runtimeElf , runtimeElfShader , compiled_program_size ) ;
convertNvToElfFreeBinaryShader ( runtimeElfShader ) ;
float * pDefaultValues = ( float * ) ( ( char * ) runtimeElf + paddedSize ) ;
defaultValues = pDefaultValues ;
if ( defaultTableSize )
memcpy ( pDefaultValues , & defaultValuesArray [ 0 ] , defaultTableSize ) ;
char * pStringTable = ( char * ) runtimeElf + paddedSize + defaultTableSize ;
stringTable = pStringTable ;
if ( stringTableSize )
memcpy ( pStringTable , & stringTableArray [ 0 ] , stringTableSize ) ;
programHeader = ( CgProgramHeader * ) runtimeElf ;
size_t elfUcodeSize = programHeader - > instructionCount * 16 ;
size_t ucodeOffset = _RGLPad ( sizeof ( CgProgramHeader ) , 16 ) ;
size_t parameterOffset = _RGLPad ( ucodeOffset + elfUcodeSize , 16 ) ;
ucode = ( char * ) runtimeElf + ucodeOffset ;
parameterHeader = ( CgParameterTableHeader * ) ( ( char * ) runtimeElf + parameterOffset ) ;
}
else
{
CGELFBinary elfBinary ;
CGELFProgram elfProgram ;
if ( ( ( intptr_t ) binaryBuffer ) & 15 )
{
printf ( " RGL ERR: CG Binary not aligned on 16 bytes, needed for ucode section. \n " ) ;
_RGLCgRaiseError ( CG_PROGRAM_LOAD_ERROR ) ;
return NULL ;
}
bool res = cgOpenElf ( binaryBuffer , 0 , & elfBinary ) ;
if ( ! res )
{
printf ( " RGL ERR: not a valid ELF. \n " ) ;
_RGLCgRaiseError ( CG_PROGRAM_LOAD_ERROR ) ;
return NULL ;
}
if ( ! cgGetElfProgramByName ( & elfBinary , entry , & elfProgram ) )
{
printf ( " RGL ERR: couldn't find the shader entry in the CG binary. \n " ) ;
return NULL ;
}
programHeader = ( CgProgramHeader * ) elfBinary . shadertab + elfProgram . index ;
ucode = ( char * ) elfProgram . texttab ;
parameterHeader = ( CgParameterTableHeader * ) elfProgram . paramtab ;
stringTable = elfBinary . strtab ;
defaultValues = ( float * ) elfBinary . consttab ;
}
CGprogram prog = _RGLCgCreateProgram ( ctx , profile , programHeader , ucode , parameterHeader , stringTable , defaultValues ) ;
if ( bConvertedToElf )
{
_CGprogram * ptr = _cgGetProgPtr ( prog ) ;
ptr - > runtimeElf = programHeader ;
}
return prog ;
}
CG_API CGprogram cgCreateProgramFromFile ( CGcontext ctx ,
CGenum program_type ,
const char * program_file ,
CGprofile profile ,
const char * entry ,
const char * * args )
{
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
if ( program_type = = CG_ROW_MAJOR )
program_type = CG_BINARY ;
if ( ! _RGLCgCreateProgramChecks ( ctx , profile , program_type ) )
return NULL ;
FILE * fp = NULL ;
if ( RGL_LIKELY ( program_type = = CG_BINARY ) )
{
CGprogram ret = NULL ;
_CGcontext * context = _cgGetContextPtr ( ctx ) ;
CGprogramGroup group = NULL ;
group = context - > groupList ;
while ( group )
{
const char * groupName = _RGLCgGetProgramGroupName ( group ) ;
if ( groupName & & ! strcmp ( groupName , program_file ) )
{
int index ;
if ( entry = = NULL )
index = 0 ;
else
index = _RGLCgGetProgramIndex ( group , entry ) ;
if ( index > = 0 )
{
ret = _RGLCgUpdateProgramAtIndex ( group , index , 1 ) ;
break ;
}
else
{
return ( CGprogram ) NULL ;
}
}
group = group - > next ;
}
if ( ret )
return ret ;
else
{
fp = fopen ( program_file , " rb " ) ;
if ( NULL = = fp )
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogram ) NULL ;
}
unsigned int filetag = 0 ;
int res = fread ( & filetag , sizeof ( filetag ) , 1 , fp ) ;
if ( ! res )
{
fclose ( fp ) ;
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogram ) NULL ;
}
const unsigned int ElfTag = 0x7F454C46 ;
if ( filetag = = ElfTag )
{
fclose ( fp ) ;
group = _RGLCgCreateProgramGroupFromFile ( ctx , program_file ) ;
if ( group )
{
_CGprogramGroup * _group = ( _CGprogramGroup * ) group ;
_group - > userCreated = false ;
if ( entry = = NULL )
{
if ( group - > programCount = = 1 )
{
ret = _RGLCgUpdateProgramAtIndex ( group , 0 , 1 ) ;
}
}
else
{
int index = _RGLCgGetProgramIndex ( group , entry ) ;
if ( index = = - 1 )
{
printf ( " RGL ERR: couldn't find the shader entry in the CG binary. \n " ) ;
}
else
{
ret = _RGLCgUpdateProgramAtIndex ( group , index , 1 ) ;
}
}
}
return ret ;
}
}
}
if ( ! fp )
{
fp = fopen ( program_file , " rb " ) ;
if ( NULL = = fp )
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogram ) NULL ;
}
}
size_t file_size = 0 ;
fseek ( fp , 0 , SEEK_END ) ;
file_size = ftell ( fp ) ;
rewind ( fp ) ;
char * ptr = ( char * ) malloc ( file_size + 1 ) ;
if ( NULL = = ptr )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
fclose ( fp ) ;
return ( CGprogram ) NULL ;
}
fread ( ptr , file_size , 1 , fp ) ;
fclose ( fp ) ;
if ( program_type = = CG_SOURCE )
{
ptr [ file_size ] = ' \0 ' ;
}
CGprogram ret = cgCreateProgram ( ctx , program_type , ptr , profile , entry , args ) ;
free ( ptr ) ;
return ret ;
}
CG_API CGprogram cgCopyProgram ( CGprogram program )
{
if ( ! CG_IS_PROGRAM ( program ) )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return NULL ;
}
_CGprogram * prog = _cgGetProgPtr ( program ) ;
if ( NULL = = prog )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ( CGprogram ) NULL ;
}
_CGprogram * newprog ;
size_t paddedProgramSize = 0 ;
size_t ucodeSize = 0 ;
if ( prog - > header . profile = = CG_PROFILE_SCE_FP_TYPEB | | prog - > header . profile = = CG_PROFILE_SCE_FP_RSX )
{
paddedProgramSize = _RGLPad ( sizeof ( _CGprogram ) , 16 ) ;
ucodeSize = prog - > header . instructionCount * 16 ;
newprog = ( _CGprogram * ) malloc ( paddedProgramSize + ucodeSize ) ;
}
else
{
newprog = ( _CGprogram * ) malloc ( sizeof ( _CGprogram ) ) ;
}
if ( NULL = = newprog )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return ( CGprogram ) NULL ;
}
memset ( newprog , 0 , sizeof ( _CGprogram ) ) ;
newprog - > header . profile = prog - > header . profile ;
newprog - > parentContext = prog - > parentContext ;
newprog - > id = ( CGprogram ) _RGLCreateName ( & _CurrentContext - > cgProgramNameSpace , newprog ) ;
int success = 0 ;
switch ( prog - > header . profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
success = _RGLPlatformCopyProgram ( prog , newprog ) ;
break ;
default :
_RGLCgRaiseError ( CG_UNKNOWN_PROFILE_ERROR ) ;
success = 0 ;
break ;
}
if ( success = = 0 )
{
free ( newprog ) ;
_RGLEraseName ( & _CurrentContext - > cgProgramNameSpace , ( jsName ) newprog - > id ) ;
return ( CGprogram ) NULL ;
}
if ( prog - > header . profile = = CG_PROFILE_SCE_FP_TYPEB | | prog - > header . profile = = CG_PROFILE_SCE_FP_RSX )
{
newprog - > ucode = ( char * ) newprog + paddedProgramSize ;
memcpy ( ( char * ) newprog - > ucode , ( char * ) prog - > ucode , ucodeSize ) ;
}
if ( prog - > programGroup )
{
newprog - > programGroup = prog - > programGroup ;
newprog - > programIndexInGroup = - 1 ;
_RGLCgUpdateProgramAtIndex ( newprog - > programGroup , - 1 , 1 ) ;
}
_RGLCgProgramPushFront ( newprog - > parentContext , newprog ) ;
if ( _cgProgramCopyHook ) _cgProgramCopyHook ( newprog , prog ) ;
return newprog - > id ;
}
CG_API void cgDestroyProgram ( CGprogram program )
{
if ( ! CG_IS_PROGRAM ( program ) )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ;
}
_CGprogram * ptr = _cgGetProgPtr ( program ) ;
if ( NULL = = ptr )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ;
}
if ( ptr - > programGroup )
{
if ( ! ptr - > programGroup - > userCreated )
{
if ( ptr - > programIndexInGroup ! = - 1 & & ptr - > programGroup - > programs [ ptr - > programIndexInGroup ] . refCount = = 0 )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ;
}
else
{
bool isGroupMember = ( ptr - > programIndexInGroup ! = - 1 ) ;
_RGLCgUpdateProgramAtIndex ( ptr - > programGroup , ptr - > programIndexInGroup , - 1 ) ;
if ( isGroupMember )
return ;
}
}
}
_CGcontext * ctx = ptr - > parentContext ;
if ( ptr = = ctx - > programList )
{
_CGprogram * p = ctx - > programList ;
ctx - > programList = p - > next ;
_RGLCgProgramErase ( p ) ;
if ( p ! = NULL )
free ( p ) ;
}
else
{
_CGprogram * p = _RGLCgProgramFindPrev ( ctx , ptr ) ;
_CGprogram * next = p - > next ;
if ( next )
{
p - > next = next - > next ;
_RGLCgProgramErase ( next ) ;
if ( next ! = NULL )
free ( next ) ;
}
}
return ;
}
static CGprogram _RGLCgUpdateProgramAtIndex ( CGprogramGroup group , int index , int refcount )
{
if ( index < ( int ) group - > programCount )
{
if ( index > = 0 )
{
if ( refcount = = 1 & & group - > programs [ index ] . refCount = = 1 )
{
CGprogram res = cgCopyProgram ( group - > programs [ index ] . program ) ;
return res ;
}
group - > programs [ index ] . refCount + = refcount ;
}
group - > refCount + = refcount ;
if ( refcount < 0 )
{
if ( group - > refCount = = 0 & & ! group - > userCreated )
{
_RGLCgDestroyProgramGroup ( group ) ;
}
return NULL ;
}
else
return group - > programs [ index ] . program ;
}
else
return NULL ;
}
static void _RGLCgAddGroup ( CGcontext ctx , CGprogramGroup group )
{
_CGcontext * context = _cgGetContextPtr ( ctx ) ;
if ( ! context - > groupList )
context - > groupList = group ;
else
{
_CGprogramGroup * current = context - > groupList ;
while ( current - > next )
current = current - > next ;
current - > next = group ;
}
}
static void _RGLCgRemoveGroup ( CGcontext ctx , CGprogramGroup group )
{
_CGcontext * context = _cgGetContextPtr ( ctx ) ;
_CGprogramGroup * current = context - > groupList ;
_CGprogramGroup * previous = NULL ;
while ( current & & current ! = group )
{
previous = current ;
current = current - > next ;
}
if ( current )
{
if ( ! previous )
context - > groupList = current - > next ;
else
previous - > next = current - > next ;
}
}
CGprogramGroup _RGLCgCreateProgramGroupFromFile ( CGcontext ctx , const char * group_file )
{
FILE * fp = fopen ( group_file , " rb " ) ;
if ( NULL = = fp )
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogramGroup ) NULL ;
}
size_t file_size = 0 ;
fseek ( fp , 0 , SEEK_END ) ;
file_size = ftell ( fp ) ;
rewind ( fp ) ;
char * ptr = ( char * ) malloc ( file_size + 1 ) ;
if ( NULL = = ptr )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return ( CGprogramGroup ) NULL ;
}
fread ( ptr , file_size , 1 , fp ) ;
fclose ( fp ) ;
CGprogramGroup group = _RGLCgCreateProgramGroup ( ctx , group_file , ptr , file_size ) ;
if ( ! group )
free ( ptr ) ;
return group ;
}
CGprogramGroup _RGLCgCreateProgramGroup ( CGcontext ctx , const char * name , void * ptr , int size )
{
_CGprogramGroup * group = NULL ;
CGELFBinary elfBinary ;
elfBinary . elfFile = NULL ;
while ( 1 )
{
bool res = cgOpenElf ( ptr , size , & elfBinary ) ;
if ( ! res )
break ;
size_t elfConstTableSize = ( size_t ) elfBinary . consttabSize ;
size_t elfStringTableSize = ( size_t ) elfBinary . strtabSize ;
int programCount = elfBinary . shadertabSize / sizeof ( CgProgramHeader ) ;
int i ;
size_t nvProgramNamesOffset = _RGLPad ( sizeof ( _CGprogramGroup ) , sizeof ( _CGnamedProgram ) ) ;
size_t nvDefaultValuesTableOffset = _RGLPad ( nvProgramNamesOffset + programCount * sizeof ( _CGnamedProgram ) , 16 ) ;
size_t nvStringTableOffset = nvDefaultValuesTableOffset + elfConstTableSize ;
size_t structureSize = nvStringTableOffset + elfStringTableSize ;
group = ( CGprogramGroup ) malloc ( structureSize ) ;
if ( ! group )
break ;
group - > ctx = ctx ;
group - > next = NULL ;
group - > programCount = ( unsigned int ) programCount ;
group - > constantTable = ( unsigned int * ) ( ( char * ) group + nvDefaultValuesTableOffset ) ;
group - > stringTable = ( unsigned int * ) ( ( char * ) group + nvStringTableOffset ) ;
group - > programs = ( _CGnamedProgram * ) ( ( char * ) group + nvProgramNamesOffset ) ;
group - > userCreated = true ;
group - > refCount = 0 ;
group - > filedata = ( char * ) ptr ;
if ( name )
{
int len = strlen ( name ) ;
group - > name = ( char * ) malloc ( len + 1 ) ;
if ( ! group - > name )
break ;
2012-05-22 18:51:06 +02:00
strlcpy ( group - > name , name , sizeof ( group - > name ) ) ;
2012-05-06 03:46:55 +02:00
}
else
group - > name = NULL ;
if ( elfConstTableSize )
memcpy ( ( char * ) group + nvDefaultValuesTableOffset , elfBinary . consttab , elfConstTableSize ) ;
if ( elfStringTableSize )
memcpy ( ( char * ) group + nvStringTableOffset , elfBinary . strtab , elfStringTableSize ) ;
_RGLCgAddGroup ( ctx , group ) ;
for ( i = 0 ; i < ( int ) group - > programCount ; i + + )
{
CgProgramHeader * cgShader = ( CgProgramHeader * ) elfBinary . shadertab + i ;
if ( cgShader - > profile = = ( CGprofile ) 7005 )
cgShader - > profile = CG_PROFILE_SCE_VP_RSX ;
if ( cgShader - > profile = = ( CGprofile ) 7006 )
cgShader - > profile = CG_PROFILE_SCE_FP_RSX ;
CGELFProgram elfProgram ;
bool res = cgGetElfProgramByIndex ( & elfBinary , i , & elfProgram ) ;
if ( ! res )
return false ;
CgProgramHeader * programHeader = cgShader ;
char * ucode = ( char * ) elfProgram . texttab ;
CgParameterTableHeader * parameterHeader = ( CgParameterTableHeader * ) elfProgram . paramtab ;
const char * programName = getSymbolByIndexInPlace ( elfBinary . symtab , elfBinary . symbolSize , elfBinary . symbolCount , elfBinary . symbolstrtab , i + 1 ) ;
group - > programs [ i ] . name = programName ;
group - > programs [ i ] . program = _RGLCgCreateProgram ( ctx , ( CGprofile ) cgShader - > profile , programHeader , ucode , parameterHeader , ( const char * ) group - > stringTable , ( const float * ) group - > constantTable ) ;
_CGprogram * cgProgram = _cgGetProgPtr ( group - > programs [ i ] . program ) ;
cgProgram - > programGroup = group ;
cgProgram - > programIndexInGroup = i ;
group - > programs [ i ] . refCount = 0 ;
}
break ;
}
return group ;
}
void _RGLCgDestroyProgramGroup ( CGprogramGroup group )
{
_CGprogramGroup * _group = ( _CGprogramGroup * ) group ;
for ( int i = 0 ; i < ( int ) _group - > programCount ; i + + )
{
_CGprogram * cgProgram = _cgGetProgPtr ( group - > programs [ i ] . program ) ;
cgProgram - > programGroup = NULL ;
cgDestroyProgram ( _group - > programs [ i ] . program ) ;
}
if ( _group - > filedata ! = NULL )
free ( _group - > filedata ) ;
if ( _group - > name )
free ( _group - > name ) ;
_RGLCgRemoveGroup ( group - > ctx , group ) ;
if ( _group ! = NULL )
free ( _group ) ;
}
const char * _RGLCgGetProgramGroupName ( CGprogramGroup group )
{
_CGprogramGroup * _group = ( _CGprogramGroup * ) group ;
return _group - > name ;
}
int _RGLCgGetProgramIndex ( CGprogramGroup group , const char * name )
{
int i ;
for ( i = 0 ; i < ( int ) group - > programCount ; i + + )
{
if ( ! strcmp ( name , group - > programs [ i ] . name ) )
return i ;
}
return - 1 ;
}
CGprogram _RGLCgGetProgramAtIndex ( CGprogramGroup group , unsigned int index )
{
return _RGLCgUpdateProgramAtIndex ( group , index , 0 ) ;
}
int _RGLCgGetProgramCount ( CGprogramGroup group )
{
return group - > programCount ;
}
static const RGLcgProfileMapType RGLcgProfileMap [ ] =
{
{ ( CGprofile ) 6144 , " CG_PROFILE_START " , 1 } ,
{ ( CGprofile ) 6145 , " unknown " , 1 } ,
# define CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile) \
{ CG_PROFILE_ # # compiler_id_caps , compiler_opt , vertex_profile } ,
# include <Cg/cg_profiles.h>
{ ( CGprofile ) 0 , " " , 0 }
} ;
CG_API const char * cgGetProfileString ( CGprofile profile )
{
const size_t arraysize = sizeof ( RGLcgProfileMap ) / sizeof ( RGLcgProfileMapType ) ;
unsigned int i = 0 ;
while ( i < arraysize )
{
if ( profile = = RGLcgProfileMap [ i ] . id )
{
return RGLcgProfileMap [ i ] . string ;
}
+ + i ;
}
return " " ;
}
CG_API CGprofile cgGetProfile ( const char * profile_string )
{
size_t arraysize = sizeof ( RGLcgProfileMap ) / sizeof ( RGLcgProfileMapType ) ;
unsigned int i = 0 ;
while ( i < arraysize )
{
if ( 0 = = strcmp ( RGLcgProfileMap [ i ] . string , profile_string ) )
{
return RGLcgProfileMap [ i ] . id ;
}
+ + i ;
}
return CG_PROFILE_UNKNOWN ;
}
CG_API CGerror cgGetError ( void )
{
CGerror err = _CurrentContext - > RGLcgLastError ;
_CurrentContext - > RGLcgLastError = CG_NO_ERROR ;
return err ;
}
CG_API const char * cgGetErrorString ( CGerror error )
{
return " cgGetErrorString: N/A \n " ;
}
CG_API const char * cgGetLastErrorString ( CGerror * error )
{
return " cgGetErrorString: N/A \n " ;
}
CG_API void cgSetErrorCallback ( CGerrorCallbackFunc func )
{
_CurrentContext - > RGLcgErrorCallbackFunction = func ;
}
CG_API CGerrorCallbackFunc cgGetErrorCallback ( void )
{
return _CurrentContext - > RGLcgErrorCallbackFunction ;
}
void _RGLCgDestroyContextParam ( CgRuntimeParameter * ptr )
{
if ( _cgParameterDestroyHook ) _cgParameterDestroyHook ( ptr ) ;
_RGLEraseName ( & _CurrentContext - > cgParameterNameSpace , ( jsName ) ( ptr - > id ) ) ;
free ( ptr ) ;
}
static int _RGLGetSizeofSubArray ( const short * dimensions , int count )
{
int res = 1 ;
for ( int i = 0 ; i < count ; i + + )
res * = ( int ) ( * ( dimensions + + ) ) ;
return res ;
}
static _CGparameter * _cgGetNamedParameter ( _CGprogram * progPtr , const char * name , CGenum name_space , int * arrayIndex , const CgParameterEntry * _startEntry = NULL , int _entryCount = - 1 )
{
if ( name = = NULL )
return NULL ;
* arrayIndex = - 1 ;
int done = 0 ;
const char * structureEnd ;
const char * structureStart = name ;
int itemIndex = - 1 ;
_CGprogram * program = progPtr ;
const CgParameterEntry * currentEntry ;
const CgParameterEntry * lastEntry ;
int containerCount = - 2 ;
if ( _startEntry & & _entryCount ! = - 1 )
{
currentEntry = _startEntry ;
containerCount = _entryCount ;
}
else
{
currentEntry = program - > parametersEntries ;
}
lastEntry = program - > parametersEntries + program - > rtParametersCount ;
bool bWasUnrolled = false ;
const char * prevStructureStart = structureStart ;
while ( ( ! done ) & & ( * structureStart ) & & ( containerCount ! = - 1 ) )
{
structureEnd = strpbrk ( structureStart , " .[ " ) ;
if ( structureEnd = = NULL )
{
structureEnd = structureStart + strlen ( structureStart ) ;
done = 1 ;
}
if ( bWasUnrolled )
{
bWasUnrolled = false ;
structureStart = prevStructureStart ;
}
char structName [ 256 ] ;
int length = ( int ) ( structureEnd - structureStart ) ;
strncpy ( structName , structureStart , length ) ;
structName [ length ] = ' \0 ' ;
prevStructureStart = structureStart ;
structureStart = structureEnd + 1 ;
bool found = false ;
while ( ! found & & currentEntry < lastEntry & & ( containerCount = = - 2 | | containerCount > 0 ) )
{
if ( ! strncmp ( structName , program - > stringTable + currentEntry - > nameOffset , length )
& & ( name_space = = 0 | | ( name_space = = CG_GLOBAL & & ( currentEntry - > flags & CGPF_GLOBAL ) )
| | ( name_space = = CG_PROGRAM & & ! ( currentEntry - > flags & CGPF_GLOBAL ) ) ) )
{
if ( ( int ) strlen ( program - > stringTable + currentEntry - > nameOffset ) ! = length )
{
if ( ! strcmp ( name , program - > stringTable + currentEntry - > nameOffset ) )
{
found = true ;
done = 1 ;
}
if ( ! strncmp ( name , program - > stringTable + currentEntry - > nameOffset , length ) & &
! strcmp ( " [0] " , program - > stringTable + currentEntry - > nameOffset + length ) )
{
found = true ;
done = 1 ;
}
}
else
found = true ;
}
if ( ! found )
{
int skipCount = 1 ;
while ( skipCount & & currentEntry < lastEntry )
{
if ( currentEntry - > flags & CGP_STRUCTURE )
{
const CgParameterStructure * parameterStructure = _RGLGetParameterStructure ( program , currentEntry ) ;
skipCount + = parameterStructure - > memberCount ;
}
else if ( currentEntry - > flags & CGP_ARRAY )
{
if ( currentEntry - > flags & CGP_UNROLLED )
{
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , currentEntry ) ;
skipCount + = _RGLGetSizeofSubArray ( ( short * ) parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
}
else
skipCount + + ;
}
currentEntry + + ;
skipCount - - ;
}
}
if ( containerCount ! = - 2 )
containerCount - - ;
}
if ( found )
{
switch ( currentEntry - > flags & CGP_TYPE_MASK )
{
case 0 :
itemIndex = ( int ) ( currentEntry - program - > parametersEntries ) ;
break ;
case CGP_ARRAY :
{
const CgParameterEntry * arrayEntry = currentEntry ;
const CgParameterArray * parameterArray = _RGLGetParameterArray ( program , arrayEntry ) ;
if ( * structureEnd = = ' \0 ' )
{
itemIndex = ( int ) ( currentEntry - program - > parametersEntries ) ;
break ;
}
currentEntry + + ;
if ( currentEntry - > flags & CGP_STRUCTURE )
{
bWasUnrolled = true ;
containerCount = _RGLGetSizeofSubArray ( ( short * ) parameterArray - > dimensions , parameterArray - > dimensionCount ) ;
break ;
}
else
{
const char * arrayStart = structureEnd ;
const char * arrayEnd = structureEnd ;
int dimensionCount = 0 ;
int arrayCellIndex = 0 ;
while ( * arrayStart = = ' [ ' & & dimensionCount < parameterArray - > dimensionCount )
{
arrayEnd = strchr ( arrayStart + 1 , ' ] ' ) ;
int length = ( int ) ( arrayEnd - arrayStart - 1 ) ;
char indexString [ 16 ] ;
strncpy ( indexString , arrayStart + 1 , length ) ;
indexString [ length ] = ' \0 ' ;
int index = atoi ( indexString ) ;
int rowSize = parameterArray - > dimensions [ dimensionCount ] ;
if ( index > = rowSize )
{
return NULL ;
}
arrayCellIndex + = index * _RGLGetSizeofSubArray ( ( short * ) parameterArray - > dimensions + dimensionCount , parameterArray - > dimensionCount - dimensionCount - 1 ) ;
arrayStart = arrayEnd + 1 ;
dimensionCount + + ;
}
structureEnd = arrayStart ;
if ( * structureEnd = = ' \0 ' )
done = 1 ;
if ( done )
{
( * arrayIndex ) = arrayCellIndex ;
itemIndex = ( int ) ( currentEntry - program - > parametersEntries ) ;
}
}
}
break ;
case CGP_STRUCTURE :
if ( done )
{
itemIndex = ( int ) ( currentEntry - program - > parametersEntries ) ;
}
else
{
const CgParameterStructure * parameterStructure = _RGLGetParameterStructure ( program , currentEntry ) ;
containerCount = parameterStructure - > memberCount ;
}
break ;
default :
break ;
}
}
if ( found )
{
if ( ! bWasUnrolled )
currentEntry + + ;
}
else
break ;
}
if ( itemIndex ! = - 1 )
return ( _CGparameter * ) ( program - > runtimeParameters + itemIndex ) ;
else
return NULL ;
}
CG_API CGparameter cgGetNamedParameter ( CGprogram prog , const char * name )
{
if ( ! CG_IS_PROGRAM ( prog ) )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ( CGparameter ) NULL ;
}
_CGprogram * progPtr = _cgGetProgPtr ( prog ) ;
int arrayIndex = - 1 ;
CgRuntimeParameter * param = ( CgRuntimeParameter * ) _cgGetNamedParameter ( progPtr , name , ( CGenum ) 0 , & arrayIndex ) ;
if ( param )
{
int ret = ( int ) param - > id ;
if ( arrayIndex ! = - 1 )
ret | = ( arrayIndex < < CG_PARAMETERSIZE ) ;
return ( CGparameter ) ret ;
}
else
return ( CGparameter ) NULL ;
}
static CGbool _RGLPlatformSupportsVertexProgram ( CGprofile p )
{
if ( p = = CG_PROFILE_SCE_VP_TYPEB )
return CG_TRUE ;
if ( p = = CG_PROFILE_SCE_VP_TYPEC )
return CG_TRUE ;
if ( p = = CG_PROFILE_SCE_VP_RSX )
return CG_TRUE ;
return CG_FALSE ;
}
CGGL_API CGbool cgGLIsProfileSupported ( CGprofile profile )
{
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
return ( CGbool ) _RGLPlatformSupportsVertexProgram ( profile ) ;
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
return ( CGbool ) _RGLPlatformSupportsFragmentProgram ( profile ) ;
default :
return CG_FALSE ;
}
}
CGGL_API void cgGLEnableProfile ( CGprofile profile )
{
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
PSGLcontext * LContext = _CurrentContext ;
struct _CGprogram * current = LContext - > BoundFragmentProgram ;
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
LContext - > VertexProgram = GL_TRUE ;
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_PROGRAM | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
LContext - > FragmentProgram = GL_TRUE ;
if ( current )
{
for ( GLuint i = 0 ; i < current - > samplerCount ; + + i )
{
int unit = current - > samplerUnits [ i ] ;
_CurrentContext - > TextureImageUnits [ unit ] . currentTexture = _RGLGetCurrentTexture ( & _CurrentContext - > TextureImageUnits [ unit ] , GL_TEXTURE_2D ) ;
}
}
LContext - > needValidate | = PSGL_VALIDATE_FRAGMENT_PROGRAM | PSGL_VALIDATE_TEXTURES_USED ;
break ;
default :
_RGLCgRaiseError ( CG_INVALID_PROFILE_ERROR ) ;
break ;
}
}
CGGL_API void cgGLDisableProfile ( CGprofile profile )
{
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
PSGLcontext * LContext = _CurrentContext ;
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
LContext - > VertexProgram = GL_FALSE ;
LContext - > needValidate | = PSGL_VALIDATE_VERTEX_PROGRAM ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
LContext - > FragmentProgram = GL_FALSE ;
for ( GLuint unit = 0 ; unit < _RGL_MAX_TEXTURE_UNITS ; + + unit )
LContext - > TextureImageUnits [ unit ] . currentTexture = _RGLGetCurrentTexture ( & LContext - > TextureImageUnits [ unit ] , GL_TEXTURE_2D ) ;
LContext - > needValidate | = PSGL_VALIDATE_FFX_FRAGMENT_PROGRAM | PSGL_VALIDATE_TEXTURES_USED ;
break ;
default :
_RGLCgRaiseError ( CG_INVALID_PROFILE_ERROR ) ;
break ;
}
}
CGGL_API CGprofile cgGLGetLatestProfile ( CGGLenum profile_type )
{
switch ( profile_type )
{
case CG_GL_VERTEX :
case CG_GL_FRAGMENT :
return _RGLPlatformGetLatestProfile ( profile_type ) ;
default :
_RGLCgRaiseError ( CG_INVALID_ENUMERANT_ERROR ) ;
return CG_PROFILE_UNKNOWN ;
}
}
CGGL_API void cgGLSetOptimalOptions ( CGprofile profile )
{
}
CGGL_API void cgGLLoadProgram ( CGprogram program )
{
}
CGGL_API CGbool cgGLIsProgramLoaded ( CGprogram program )
{
return CG_TRUE ;
}
CGGL_API void cgGLBindProgram ( CGprogram program )
{
_CGprogram * ptr = _cgGetProgPtr ( program ) ;
switch ( ptr - > header . profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case 7005 :
case CG_PROFILE_SCE_VP_RSX :
_CurrentContext - > BoundVertexProgram = ptr ;
_CurrentContext - > needValidate | = PSGL_VALIDATE_VERTEX_PROGRAM | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
case 7006 :
case CG_PROFILE_SCE_FP_RSX :
_CurrentContext - > BoundFragmentProgram = ptr ;
_CurrentContext - > needValidate | = PSGL_VALIDATE_FRAGMENT_PROGRAM | PSGL_VALIDATE_TEXTURES_USED ;
for ( GLuint index = 0 ; index < ptr - > samplerCount ; + + index )
{
CgRuntimeParameter * rtParameter = ptr - > runtimeParameters + ptr - > samplerIndices [ index ] ;
CgParameterResource * parameter = ( CgParameterResource * ) ( ptr - > parameterResources + rtParameter - > parameterEntry - > typeIndex ) ;
unsigned int unit = parameter - > resource - CG_TEXUNIT0 ;
_CurrentContext - > TextureImageUnits [ unit ] . fragmentTarget = rtParameter - > glType ;
_CurrentContext - > TextureImageUnits [ unit ] . currentTexture = _RGLGetCurrentTexture ( & _CurrentContext - > TextureImageUnits [ unit ] , GL_TEXTURE_2D ) ;
}
break ;
default :
_RGLCgRaiseError ( CG_INVALID_PROFILE_ERROR ) ;
return ;
}
}
CGGL_API void cgGLUnbindProgram ( CGprofile profile )
{
switch ( profile )
{
case CG_PROFILE_SCE_VP_TYPEB :
case CG_PROFILE_SCE_VP_RSX :
case 7005 :
_CurrentContext - > BoundVertexProgram = NULL ;
_CurrentContext - > needValidate | = PSGL_VALIDATE_VERTEX_PROGRAM ;
break ;
case CG_PROFILE_SCE_FP_TYPEB :
case CG_PROFILE_SCE_FP_RSX :
case 7006 :
_CurrentContext - > BoundFragmentProgram = NULL ;
for ( GLuint unit = 0 ; unit < _RGL_MAX_TEXTURE_UNITS ; + + unit )
_CurrentContext - > TextureImageUnits [ unit ] . currentTexture = _RGLGetCurrentTexture ( & _CurrentContext - > TextureImageUnits [ unit ] , GL_TEXTURE_2D ) ;
_CurrentContext - > needValidate | = PSGL_VALIDATE_FFX_FRAGMENT_PROGRAM | PSGL_VALIDATE_TEXTURES_USED ;
break ;
default :
_RGLCgRaiseError ( CG_INVALID_PROFILE_ERROR ) ;
return ;
}
}
CGGL_API GLuint cgGLGetProgramID ( CGprogram program )
{
return 0 ;
}
CGGL_API void cgGLEnableProgramProfiles ( CGprogram program )
{
return ;
}
CGGL_API void cgGLDisableProgramProfiles ( CGprogram program )
{
return ;
}
CGGL_API void cgGLSetParameter1f ( CGparameter param , float x )
{
CgRuntimeParameter * ptr = _RGLCgGLTestParameter ( param ) ;
float v [ 4 ] = { x , x , x , x } ;
ptr - > setterIndex ( ptr , v , CG_GETINDEX ( param ) ) ;
}
CGGL_API void cgGLSetParameter2f ( CGparameter param , float x , float y )
{
CgRuntimeParameter * ptr = _RGLCgGLTestParameter ( param ) ;
float v [ 4 ] = { x , y , y , y } ;
ptr - > setterIndex ( ptr , v , CG_GETINDEX ( param ) ) ;
}
CGGL_API void cgGLSetParameterPointer ( CGparameter param ,
GLint fsize ,
GLenum type ,
GLsizei stride ,
const GLvoid * pointer )
{
CgRuntimeParameter * _ptr = _RGLCgGLTestParameter ( param ) ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
_RGLVertexAttribPointerNV (
index ,
fsize ,
type ,
( _ptr - > parameterEntry - > flags & CGP_NORMALIZE ) ? 1 : 0 ,
stride ,
pointer ) ;
}
CGGL_API void cgGLEnableClientState ( CGparameter param )
{
CgRuntimeParameter * _ptr = _RGLCgGLTestParameter ( param ) ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
_RGLEnableVertexAttribArrayNV ( index ) ;
}
CGGL_API void cgGLDisableClientState ( CGparameter param )
{
CgRuntimeParameter * _ptr = _RGLCgGLTestParameter ( param ) ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
_RGLDisableVertexAttribArrayNV ( index ) ;
}
CGGL_API void cgGLSetStateMatrixParameter ( CGparameter param ,
CGGLenum matrix ,
CGGLenum transform )
{
float m [ 4 ] [ 4 ] ;
switch ( matrix )
{
case CG_GL_MODELVIEW_MATRIX :
glGetFloatv ( GL_MODELVIEW_MATRIX , ( float * ) m ) ;
break ;
case CG_GL_PROJECTION_MATRIX :
glGetFloatv ( GL_PROJECTION_MATRIX , ( float * ) m ) ;
break ;
case CG_GL_TEXTURE_MATRIX :
glGetFloatv ( GL_TEXTURE_MATRIX , ( float * ) m ) ;
break ;
case CG_GL_MODELVIEW_PROJECTION_MATRIX :
{
float mv [ 4 ] [ 4 ] , p [ 4 ] [ 4 ] ;
glGetFloatv ( GL_MODELVIEW_MATRIX , ( float * ) mv ) ;
glGetFloatv ( GL_PROJECTION_MATRIX , ( float * ) p ) ;
# define M(I,J) \
m [ I ] [ J ] = mv [ I ] [ 0 ] * p [ 0 ] [ J ] + mv [ I ] [ 1 ] * p [ 1 ] [ J ] + mv [ I ] [ 2 ] * p [ 2 ] [ J ] + mv [ I ] [ 3 ] * p [ 3 ] [ J ]
M ( 0 , 0 ) ; M ( 0 , 1 ) ; M ( 0 , 2 ) ; M ( 0 , 3 ) ;
M ( 1 , 0 ) ; M ( 1 , 1 ) ; M ( 1 , 2 ) ; M ( 1 , 3 ) ;
M ( 2 , 0 ) ; M ( 2 , 1 ) ; M ( 2 , 2 ) ; M ( 2 , 3 ) ;
M ( 3 , 0 ) ; M ( 3 , 1 ) ; M ( 3 , 2 ) ; M ( 3 , 3 ) ;
# undef M
}
break ;
default :
_RGLCgRaiseError ( CG_INVALID_ENUMERANT_ERROR ) ;
return ;
}
CgRuntimeParameter * ptr = _RGLCgGLTestParameter ( param ) ;
CGtype parameterType = _RGLGetParameterCGtype ( ptr - > program , ptr - > parameterEntry ) ;
if ( RGL_LIKELY ( parameterType = = CG_FLOAT4x4 ) )
{
ptr - > settercIndex ( ptr , m , CG_GETINDEX ( param ) ) ;
}
else
{
float packedmatrix [ 16 ] ;
unsigned int rows = _RGLGetTypeRowCount ( parameterType ) ;
unsigned int cols = _RGLGetTypeColCount ( parameterType ) ;
for ( GLuint row = 0 ; row < rows ; + + row )
for ( GLuint j = 0 ; j < cols ; + + j )
packedmatrix [ row * cols + j ] = m [ j ] [ row ] ;
ptr - > setterrIndex ( ptr , packedmatrix , CG_GETINDEX ( param ) ) ;
}
}
CGGL_API void cgGLSetTextureParameter ( CGparameter param , GLuint texobj )
{
CgRuntimeParameter * ptr = _cgGLTestTextureParameter ( param ) ;
ptr - > samplerSetter ( ptr , & texobj , 0 ) ;
}
CGGL_API void cgGLEnableTextureParameter ( CGparameter param )
{
CgRuntimeParameter * ptr = _cgGLTestTextureParameter ( param ) ;
ptr - > samplerSetter ( ptr , NULL , 0 ) ;
}
2012-05-27 23:57:16 +02:00
static void _RGLCgContextZero ( _CGcontext * p )
2012-05-06 03:46:55 +02:00
{
memset ( p , 0 , sizeof ( * p ) ) ;
p - > compileType = CG_UNKNOWN ;
}
2012-05-27 23:57:16 +02:00
static void _RGLCgContextPushFront ( _CGcontext * ctx )
2012-05-06 03:46:55 +02:00
{
if ( _CurrentContext - > RGLcgContextHead )
{
_CGcontext * head = _cgGetContextPtr ( _CurrentContext - > RGLcgContextHead ) ;
ctx - > next = head ;
}
_CurrentContext - > RGLcgContextHead = ctx - > id ;
}
static void destroy_context ( _CGcontext * ctx )
{
if ( _cgContextDestroyHook ) _cgContextDestroyHook ( ctx ) ;
_RGLEraseName ( & _CurrentContext - > cgContextNameSpace , ( jsName ) ctx - > id ) ;
_RGLCgContextZero ( ctx ) ;
free ( ctx ) ;
}
CG_API CGcontext cgCreateContext ( void )
{
_CGcontext * ptr = NULL ;
ptr = ( _CGcontext * ) malloc ( sizeof ( _CGcontext ) ) ;
if ( NULL = = ptr )
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return ( CGcontext ) NULL ;
}
_RGLCgContextZero ( ptr ) ;
CGcontext result = ( CGcontext ) _RGLCreateName ( & _CurrentContext - > cgContextNameSpace , ptr ) ;
if ( ! result ) { free ( ptr ) ; return NULL ; }
ptr - > id = result ;
ptr - > defaultProgram . parentContext = ptr ;
_RGLCgContextPushFront ( ptr ) ;
if ( _cgContextCreateHook ) _cgContextCreateHook ( ptr ) ;
return result ;
}
CG_API void cgDestroyContext ( CGcontext c )
{
if ( ! CG_IS_CONTEXT ( c ) )
{
_RGLCgRaiseError ( CG_INVALID_CONTEXT_HANDLE_ERROR ) ;
return ;
}
_CGcontext * ctx = _cgGetContextPtr ( c ) ;
_RGLCgProgramErase ( & ctx - > defaultProgram ) ;
while ( ctx - > programList )
{
_CGprogram * p = ctx - > programList ;
ctx - > programList = p - > next ;
_RGLCgProgramErase ( p ) ;
if ( p ! = NULL )
free ( p ) ;
}
_CGcontext * const head = _cgGetContextPtr ( _CurrentContext - > RGLcgContextHead ) ;
if ( head ! = ctx )
{
_CGcontext * ptr = head ;
while ( ptr - > next ! = ctx ) ptr = ptr - > next ;
ptr - > next = ctx - > next ;
destroy_context ( ctx ) ;
}
else
{
_CGcontext * second = head - > next ;
destroy_context ( head ) ;
if ( second )
{
_CurrentContext - > RGLcgContextHead = second - > id ;
}
else
{
_CurrentContext - > RGLcgContextHead = 0 ;
}
}
}
CG_API const char * cgGetLastListing ( CGcontext c )
{
if ( ! CG_IS_CONTEXT ( c ) )
{
_RGLCgRaiseError ( CG_INVALID_CONTEXT_HANDLE_ERROR ) ;
return NULL ;
}
return NULL ;
}
void _RGLCgRaiseError ( CGerror error )
{
_CurrentContext - > RGLcgLastError = error ;
printf ( " RGL: Cg error:%s. \n " , cgGetErrorString ( error ) ) ;
if ( _CurrentContext - > RGLcgErrorCallbackFunction )
_CurrentContext - > RGLcgErrorCallbackFunction ( ) ;
}
unsigned int _RGLCountFloatsInCgType ( CGtype type )
{
int size = 0 ;
switch ( type )
{
case CG_FLOAT :
case CG_FLOAT1 :
case CG_FLOAT1x1 :
size = 1 ;
break ;
case CG_FLOAT2 :
case CG_FLOAT2x1 :
case CG_FLOAT1x2 :
size = 2 ;
break ;
case CG_FLOAT3 :
case CG_FLOAT3x1 :
case CG_FLOAT1x3 :
size = 3 ;
break ;
case CG_FLOAT4 :
case CG_FLOAT4x1 :
case CG_FLOAT1x4 :
case CG_FLOAT2x2 :
size = 4 ;
break ;
case CG_FLOAT2x3 :
case CG_FLOAT3x2 :
size = 6 ;
break ;
case CG_FLOAT2x4 :
case CG_FLOAT4x2 :
size = 8 ;
break ;
case CG_FLOAT3x3 :
size = 9 ;
break ;
case CG_FLOAT3x4 :
case CG_FLOAT4x3 :
size = 12 ;
break ;
case CG_FLOAT4x4 :
size = 16 ;
break ;
case CG_SAMPLER1D :
case CG_SAMPLER2D :
case CG_SAMPLER3D :
case CG_SAMPLERRECT :
case CG_SAMPLERCUBE :
case CG_BOOL :
case CG_HALF :
case CG_HALF1 :
case CG_HALF1x1 :
size = 1 ;
break ;
case CG_HALF2 :
case CG_HALF2x1 :
case CG_HALF1x2 :
size = 2 ;
break ;
case CG_HALF3 :
case CG_HALF3x1 :
case CG_HALF1x3 :
size = 3 ;
break ;
case CG_HALF4 :
case CG_HALF4x1 :
case CG_HALF1x4 :
case CG_HALF2x2 :
size = 4 ;
break ;
case CG_HALF2x3 :
case CG_HALF3x2 :
size = 6 ;
break ;
case CG_HALF2x4 :
case CG_HALF4x2 :
size = 8 ;
break ;
case CG_HALF3x3 :
size = 9 ;
break ;
case CG_HALF3x4 :
case CG_HALF4x3 :
size = 12 ;
break ;
case CG_HALF4x4 :
size = 16 ;
break ;
case CG_INT :
case CG_INT1 :
case CG_INT1x1 :
size = 1 ;
break ;
case CG_INT2 :
case CG_INT2x1 :
case CG_INT1x2 :
size = 2 ;
break ;
case CG_INT3 :
case CG_INT3x1 :
case CG_INT1x3 :
size = 3 ;
break ;
case CG_INT4 :
case CG_INT4x1 :
case CG_INT1x4 :
case CG_INT2x2 :
size = 4 ;
break ;
case CG_INT2x3 :
case CG_INT3x2 :
size = 6 ;
break ;
case CG_INT2x4 :
case CG_INT4x2 :
size = 8 ;
break ;
case CG_INT3x3 :
size = 9 ;
break ;
case CG_INT3x4 :
case CG_INT4x3 :
size = 12 ;
break ;
case CG_INT4x4 :
size = 16 ;
break ;
case CG_BOOL1 :
case CG_BOOL1x1 :
size = 1 ;
break ;
case CG_BOOL2 :
case CG_BOOL2x1 :
case CG_BOOL1x2 :
size = 2 ;
break ;
case CG_BOOL3 :
case CG_BOOL3x1 :
case CG_BOOL1x3 :
size = 3 ;
break ;
case CG_BOOL4 :
case CG_BOOL4x1 :
case CG_BOOL1x4 :
case CG_BOOL2x2 :
size = 4 ;
break ;
case CG_BOOL2x3 :
case CG_BOOL3x2 :
size = 6 ;
break ;
case CG_BOOL2x4 :
case CG_BOOL4x2 :
size = 8 ;
break ;
case CG_BOOL3x3 :
size = 9 ;
break ;
case CG_BOOL3x4 :
case CG_BOOL4x3 :
size = 12 ;
break ;
case CG_BOOL4x4 :
size = 16 ;
break ;
case CG_FIXED :
case CG_FIXED1 :
case CG_FIXED1x1 :
size = 1 ;
break ;
case CG_FIXED2 :
case CG_FIXED2x1 :
case CG_FIXED1x2 :
size = 2 ;
break ;
case CG_FIXED3 :
case CG_FIXED3x1 :
case CG_FIXED1x3 :
size = 3 ;
break ;
case CG_FIXED4 :
case CG_FIXED4x1 :
case CG_FIXED1x4 :
case CG_FIXED2x2 :
size = 4 ;
break ;
case CG_FIXED2x3 :
case CG_FIXED3x2 :
size = 6 ;
break ;
case CG_FIXED2x4 :
case CG_FIXED4x2 :
size = 8 ;
break ;
case CG_FIXED3x3 :
size = 9 ;
break ;
case CG_FIXED3x4 :
case CG_FIXED4x3 :
size = 12 ;
break ;
case CG_FIXED4x4 :
size = 16 ;
break ;
default :
size = 0 ;
break ;
}
return size ;
}
void _cgRaiseInvalidParam ( CgRuntimeParameter * p , const void * v )
{
_RGLCgRaiseError ( CG_INVALID_PARAMETER_ERROR ) ;
}
void _cgRaiseInvalidParamIndex ( CgRuntimeParameter * p , const void * v , const int index )
{
_RGLCgRaiseError ( CG_INVALID_PARAMETER_ERROR ) ;
}
void _cgRaiseNotMatrixParam ( CgRuntimeParameter * p , const void * v )
{
_RGLCgRaiseError ( CG_NOT_MATRIX_PARAM_ERROR ) ;
}
void _cgRaiseNotMatrixParamIndex ( CgRuntimeParameter * p , const void * v , const int index )
{
_RGLCgRaiseError ( CG_NOT_MATRIX_PARAM_ERROR ) ;
}
void _cgIgnoreSetParam ( CgRuntimeParameter * p , const void * v )
{
}
void _cgIgnoreSetParamIndex ( CgRuntimeParameter * p , const void * v , const int index )
{
}
CgRuntimeParameter * _cgGLTestTextureParameter ( CGparameter param )
{
CgRuntimeParameter * ptr = _RGLCgGLTestParameter ( param ) ;
return ptr ;
}
# define CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_enum, nrows, ncols,classname) \
nrows ,
static int _typesRowCount [ ] =
{
# include "Cg/cg_datatypes.h"
} ;
# define CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_enum, nrows, ncols,classname) \
ncols ,
static int _typesColCount [ ] =
{
# include "Cg/cg_datatypes.h"
} ;
unsigned int _RGLGetTypeRowCount ( CGtype parameterType )
{
int typeIndex = parameterType - 1 - CG_TYPE_START_ENUM ;
return _typesRowCount [ typeIndex ] ;
}
unsigned int _RGLGetTypeColCount ( CGtype parameterType )
{
int typeIndex = parameterType - 1 - CG_TYPE_START_ENUM ;
return _typesColCount [ typeIndex ] ;
}