2012-05-06 01:46:55 +00: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 16:51:06 +00:00
# include "../../../compat/strl.h"
2012-07-23 09:09:36 +00:00
# include "../../../general.h"
2012-05-22 16:51:06 +00:00
2012-05-06 01:46:55 +00:00
# define ENDIAN_32(X, F) ((F) ? endianSwapWord(X) : (X))
# define SWAP_IF_BIG_ENDIAN(arg) endianSwapWordByHalf(arg)
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
# define ROW_MAJOR 0
# define COL_MAJOR 1
# define pad(x, pad) (((x) + (pad) - 1 ) / (pad) * (pad))
# 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 )
static int _RGLInitCompleted = 0 ;
2012-07-28 23:10:15 +00:00
static char * _RGLVendorString = " Retro Arch " ;
static char * _RGLRendererString = " RGL " ;
static char * _RGLExtensionsString = " " ;
static char * _RGLVersionNumber = " 1.0 " ;
2012-05-06 01:46:55 +00:00
PSGLcontext * _CurrentContext = NULL ;
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
GLuint nvFenceCounter = 0 ;
2012-07-28 23:10:15 +00:00
# define CAPACITY_INCR 16
# define NAME_INCREMENT 4
2012-05-06 01:46:55 +00:00
# define DECLARE_TYPE(TYPE,CTYPE,MAXVAL) \
typedef CTYPE type_ # # TYPE ; \
2012-08-06 03:05:16 +00:00
static inline type_ # # TYPE _RGLFloatTo_ # # TYPE ( float v ) { return ( type_ # # TYPE ) ( ( MAX ( MIN ( v , 1.f ) , 0.f ) ) * MAXVAL ) ; } \
2012-05-06 01:46:55 +00:00
static inline float _RGLFloatFrom_ # # TYPE ( type_ # # TYPE v ) { return ( ( float ) v ) / MAXVAL ; }
DECLARE_C_TYPES
# undef DECLARE_TYPE
typedef GLfloat type_GL_FLOAT ;
2012-07-28 23:10:15 +00:00
static inline type_GL_FLOAT _RGLFloatTo_GL_FLOAT ( float v )
{
return v ;
}
static inline float _RGLFloatFrom_GL_FLOAT ( type_GL_FLOAT v )
{
return v ;
}
2012-05-06 01:46:55 +00:00
typedef GLhalfARB type_GL_HALF_FLOAT_ARB ;
2012-08-15 08:49:39 +00:00
static const char * findSectionInPlace ( const char * memory , unsigned int /*size*/ , const char * name , size_t * sectionSize )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
const Elf32_Ehdr * ehdr = ( const Elf32_Ehdr * ) memory ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
const char * sectionHeaderStart = ( const char * ) ehdr + ehdr - > e_shoff ;
const Elf32_Shdr * shstrtabHeader = ( const Elf32_Shdr * ) sectionHeaderStart + ehdr - > e_shstrndx ;
const char * shstrtab = ( const char * ) ehdr + shstrtabHeader - > sh_offset ;
2012-07-28 23:10:15 +00:00
size_t sectionCount = ehdr - > e_shnum ;
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 ;
2012-05-06 01:46:55 +00:00
}
2012-08-15 08:49:39 +00:00
static const char * findSymbolSectionInPlace ( const char * memory , unsigned int /*size*/ , size_t * symbolSize , size_t * symbolCount , const char * * symbolstrtab )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
const Elf32_Ehdr * ehdr = ( const Elf32_Ehdr * ) memory ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
size_t sectionCount = ehdr - > e_shnum ;
const char * sectionHeaderStart = ( const char * ) ehdr + ehdr - > e_shoff ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
}
2012-08-15 08:49:39 +00:00
static int lookupSymbolValueInPlace ( const char * symbolSection , size_t symbolSize , size_t symbolCount , const char * symbolstrtab , const char * name )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
for ( size_t i = 0 ; i < symbolCount ; i + + )
{
Elf32_Sym * elf_sym = ( Elf32_Sym * ) symbolSection ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( ! strcmp ( symbolstrtab + elf_sym - > st_name , name ) )
return elf_sym - > st_value ;
symbolSection + = symbolSize ;
}
return - 1 ;
2012-05-06 01:46:55 +00:00
}
2012-08-15 08:49:39 +00:00
static const char * getSymbolByIndexInPlace ( const char * symbolSection , size_t symbolSize , size_t symbolCount , const char * symbolstrtab , int index )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
Elf32_Sym * elf_sym = ( Elf32_Sym * ) symbolSection + index ;
return symbolstrtab + elf_sym - > st_name ;
2012-05-06 01:46:55 +00:00
}
static inline type_GL_HALF_FLOAT_ARB _RGLFloatTo_GL_HALF_FLOAT_ARB ( float x )
{
2012-07-23 12:14:38 +00:00
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 ) ;
2012-05-06 01:46:55 +00:00
}
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 void _RGLResetAttributeState ( jsAttributeState * as )
{
2012-08-02 01:24:14 +00:00
for ( int i = 0 ; i < MAX_VERTEX_ATTRIBS ; + + i )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-08-02 01:24:14 +00:00
as - > DirtyMask = ( 1 < < MAX_VERTEX_ATTRIBS ) - 1 ;
2012-05-06 01:46:55 +00:00
as - > EnabledMask = 0 ;
as - > NeedsConversionMask = 0 ;
as - > HasVBOMask = 0 ;
as - > ModuloMask = 0 ;
}
static jsAttribSet * _RGLCreateAttribSet ( void )
{
2012-08-06 03:05:16 +00:00
jsAttribSet * attribSet = ( jsAttribSet * ) memalign ( 16 , sizeof ( jsAttribSet ) ) ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
_RGLResetAttributeState ( & attribSet - > attribs ) ;
2012-05-06 01:46:55 +00:00
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 void _RGLAttribSetDeleteBuffer ( PSGLcontext * LContext , GLuint buffName )
{
2012-07-30 02:01:54 +00:00
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ buffName ] ;
2012-07-28 23:10:15 +00:00
GLuint attrSetCount = bufferObject - > attribSets . getCount ( ) ;
if ( attrSetCount = = 0 ) return ;
for ( unsigned int i = 0 ; i < attrSetCount ; + + i )
{
jsAttribSet * attribSet = bufferObject - > attribSets [ i ] ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
for ( GLuint j = 0 ; j < MAX_VERTEX_ATTRIBS ; + + j )
2012-08-06 03:05:16 +00:00
{
if ( attribSet - > attribs . attrib [ j ] . arrayBuffer = = buffName )
2012-07-28 23:10:15 +00:00
attribSet - > attribs . attrib [ j ] . arrayBuffer = 0 ;
2012-08-06 03:05:16 +00:00
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
attribSet - > dirty = GL_TRUE ;
}
LContext - > attribSetDirty = GL_TRUE ;
bufferObject - > attribSets . clear ( ) ;
2012-05-06 01:46:55 +00:00
}
static jsBufferObject * _RGLCreateBufferObject ( void )
{
2012-08-06 03:05:16 +00:00
GLuint size = sizeof ( jsBufferObject ) + sizeof ( RGLBufferObject ) ;
jsBufferObject * buffer = ( jsBufferObject * ) malloc ( size ) ;
2012-05-06 01:46:55 +00:00
if ( ! buffer )
return NULL ;
2012-07-30 02:01:54 +00:00
memset ( buffer , 0 , size ) ;
2012-05-06 01:46:55 +00:00
buffer - > refCount = 1 ;
new ( & buffer - > textureReferences ) RGL : : Vector < jsTexture * > ( ) ;
new ( & buffer - > attribSets ) RGL : : Vector < jsAttribSet * > ( ) ;
return buffer ;
}
static void _RGLPlatformDestroyBufferObject ( jsBufferObject * bufferObject )
{
2012-08-06 03:05:16 +00:00
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
switch ( jsBuffer - > pool )
2012-05-06 01:46:55 +00:00
{
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_SYSTEM :
case SURFACE_POOL_LINEAR :
2012-05-06 01:46:55 +00:00
gmmFree ( jsBuffer - > bufferId ) ;
break ;
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_NONE :
2012-05-06 01:46:55 +00:00
break ;
default :
break ;
}
2012-08-02 01:24:14 +00:00
jsBuffer - > pool = SURFACE_POOL_NONE ;
2012-05-06 01:46:55 +00:00
jsBuffer - > bufferId = GMM_ERROR ;
}
static void _RGLFreeBufferObject ( jsBufferObject * buffer )
{
2012-08-06 03:05:16 +00:00
if ( - - buffer - > refCount = = 0 )
2012-07-28 23:10:15 +00:00
{
_RGLPlatformDestroyBufferObject ( buffer ) ;
buffer - > textureReferences . ~ Vector < jsTexture * > ( ) ;
buffer - > attribSets . ~ Vector < jsAttribSet * > ( ) ;
2012-08-06 03:05:16 +00:00
2012-07-28 23:10:15 +00:00
if ( buffer ! = NULL )
free ( buffer ) ;
}
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glBindBuffer ( GLenum target , GLuint name )
{
PSGLcontext * LContext = _CurrentContext ;
2012-07-28 23:10:15 +00:00
if ( name )
_RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
switch ( target )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
case GL_ARRAY_BUFFER :
LContext - > ArrayBuffer = name ;
2012-05-06 01:46:55 +00:00
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 ;
}
}
2012-07-28 23:10:15 +00:00
GLAPI void APIENTRY glDeleteBuffers ( GLsizei n , const GLuint * buffers )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
for ( int i = 0 ; i < n ; + + i )
{
2012-07-30 02:01:54 +00:00
if ( ! _RGLTexNameSpaceIsName ( & LContext - > bufferObjectNameSpace , buffers [ i ] ) )
2012-07-28 23:10:15 +00:00
continue ;
2012-07-30 02:01:54 +00:00
if ( buffers [ i ] )
2012-08-02 01:24:14 +00:00
{
GLuint name = buffers [ i ] ;
2012-08-06 03:05:16 +00:00
2012-08-02 01:24:14 +00:00
if ( LContext - > ArrayBuffer = = name )
LContext - > ArrayBuffer = 0 ;
2012-08-06 03:05:16 +00:00
2012-08-02 01:24:14 +00:00
if ( LContext - > PixelUnpackBuffer = = name )
LContext - > PixelUnpackBuffer = 0 ;
for ( int i = 0 ; i < 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 ) ;
}
2012-07-28 23:10:15 +00:00
}
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , n , buffers ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-28 23:10:15 +00:00
GLAPI void APIENTRY glGenBuffers ( GLsizei n , GLuint * buffers )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
_RGLTexNameSpaceGenNames ( & LContext - > bufferObjectNameSpace , n , buffers ) ;
2012-05-06 01:46:55 +00:00
}
2012-08-02 01:24:14 +00:00
static inline void _RGLTextureTouchFBOs ( jsTexture * texture )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
if ( ! LContext )
return ;
GLuint fbCount = texture - > framebuffers . getCount ( ) ;
2012-08-06 03:05:16 +00:00
2012-07-28 23:10:15 +00:00
if ( fbCount > 0 )
{
2012-08-06 03:05:16 +00:00
jsFramebuffer * contextFramebuffer = LContext - > framebuffer ? ( jsFramebuffer * ) LContext - > framebufferNameSpace . data [ LContext - > framebuffer ] : NULL ;
2012-08-02 01:24:14 +00:00
for ( GLuint i = 0 ; i < fbCount ; + + i )
2012-07-28 23:10:15 +00:00
{
jsFramebuffer * framebuffer = texture - > framebuffers [ i ] ;
framebuffer - > needValidate = GL_TRUE ;
2012-08-02 01:24:14 +00:00
if ( RGL_UNLIKELY ( framebuffer = = contextFramebuffer ) )
LContext - > needValidate | = PSGL_VALIDATE_FRAMEBUFFER ;
2012-07-28 23:10:15 +00:00
}
}
2012-05-06 01:46:55 +00:00
}
2012-08-06 03:05:16 +00:00
static void _RGLAllocateBuffer ( jsBufferObject * bufferObject )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
_RGLPlatformDestroyBufferObject ( bufferObject ) ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
jsBuffer - > pool = SURFACE_POOL_LINEAR ;
2012-05-06 01:46:55 +00:00
jsBuffer - > bufferId = gmmAlloc ( 0 , jsBuffer - > bufferSize ) ;
jsBuffer - > pitch = 0 ;
2012-08-06 03:05:16 +00:00
if ( jsBuffer - > bufferId = = GMM_ERROR )
2012-08-02 01:24:14 +00:00
jsBuffer - > pool = SURFACE_POOL_NONE ;
2012-05-06 01:46:55 +00:00
GLuint referenceCount = bufferObject - > textureReferences . getCount ( ) ;
2012-08-06 03:05:16 +00:00
if ( referenceCount > 0 )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
for ( GLuint i = 0 ; i < referenceCount ; + + i )
2012-05-06 01:46:55 +00:00
{
jsTexture * texture = bufferObject - > textureReferences [ i ] ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
gcmTexture - > gpuAddressId = jsBuffer - > bufferId ;
gcmTexture - > gpuAddressIdOffset = texture - > offset ;
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_PARAMETERS ;
2012-05-06 01:46:55 +00:00
_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 ) ;
2012-08-15 08:49:39 +00:00
transfer_params_t transfer_params ;
transfer_params . dst_id = dstId ;
transfer_params . dst_id_offset = 0 ;
transfer_params . dst_pitch = pitch ;
transfer_params . dst_x = dstOffsetAlign / 2 ;
transfer_params . dst_y = dstOffset / pitch ;
transfer_params . src_id = srcId ;
transfer_params . src_id_offset = srcOffset ;
transfer_params . src_pitch = pitch ;
transfer_params . src_x = 0 ;
transfer_params . src_y = 0 ;
transfer_params . width = firstBytes / 2 ;
transfer_params . height = 1 ;
transfer_params . bpp = 2 ;
transfer_params . fifo_ptr = & _RGLState . fifo ;
TransferDataVidToVid ( & transfer_params ) ;
2012-05-06 01:46:55 +00:00
dstOffset + = firstBytes ;
srcOffset + = firstBytes ;
size - = firstBytes ;
}
const GLuint fullLines = size / pitch ;
const GLuint extraBytes = size % pitch ;
2012-08-15 08:49:39 +00:00
2012-05-06 01:46:55 +00:00
if ( fullLines )
2012-08-15 08:49:39 +00:00
{
transfer_params_t transfer_params ;
transfer_params . dst_id = dstId ;
transfer_params . dst_id_offset = 0 ;
transfer_params . dst_pitch = pitch ;
transfer_params . dst_x = 0 ;
transfer_params . dst_y = dstOffset / pitch ;
transfer_params . src_id = srcId ;
transfer_params . src_id_offset = srcOffset ;
transfer_params . src_pitch = pitch ;
transfer_params . src_x = 0 ;
transfer_params . src_y = 0 ;
transfer_params . width = pitch / 2 ;
transfer_params . height = fullLines ;
transfer_params . bpp = 2 ;
transfer_params . fifo_ptr = & _RGLState . fifo ;
TransferDataVidToVid ( & transfer_params ) ;
}
2012-05-06 01:46:55 +00:00
if ( extraBytes )
2012-08-15 08:49:39 +00:00
{
transfer_params_t transfer_params ;
transfer_params . dst_id = dstId ;
transfer_params . dst_id_offset = 0 ;
transfer_params . dst_pitch = pitch ;
transfer_params . dst_x = 0 ;
transfer_params . dst_y = fullLines + dstOffset / pitch ;
transfer_params . src_id = srcId ;
transfer_params . src_id_offset = srcOffset ;
transfer_params . src_pitch = pitch ;
transfer_params . src_x = 0 ;
transfer_params . src_y = fullLines ;
transfer_params . width = extraBytes / 2 ;
transfer_params . height = 1 ;
transfer_params . bpp = 2 ;
transfer_params . fifo_ptr = & _RGLState . fifo ;
TransferDataVidToVid ( & transfer_params ) ;
}
2012-05-06 01:46:55 +00:00
}
static void _RGLPlatformBufferObjectSetData ( jsBufferObject * bufferObject , GLintptr offset , GLsizeiptr size , const GLvoid * data , GLboolean tryImmediateCopy )
{
2012-07-28 23:10:15 +00:00
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_NONE :
2012-05-06 01:46:55 +00:00
_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
{
2012-08-06 03:05:16 +00:00
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 :
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-08-06 03:05:16 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
memcpy ( gmmIdToAddress ( dstId ) + offset , src , size ) ;
break ;
} ;
2012-05-06 01:46:55 +00:00
}
}
2012-08-06 03:05:16 +00:00
( ( RGLDriver * ) _CurrentDevice - > rasterDriver ) - > invalidateVertexCache = GL_TRUE ;
2012-05-06 01:46:55 +00:00
}
static GLboolean _RGLPlatformCreateBufferObject ( jsBufferObject * bufferObject )
{
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
2012-08-02 01:24:14 +00:00
jsBuffer - > pool = SURFACE_POOL_NONE ;
2012-05-06 01:46:55 +00:00
jsBuffer - > bufferId = GMM_ERROR ;
jsBuffer - > mapCount = 0 ;
jsBuffer - > mapAccess = GL_NONE ;
jsBuffer - > bufferSize = _RGLPad ( bufferObject - > size , _RGL_BUFFER_OBJECT_BLOCK_SIZE ) ;
2012-08-06 03:05:16 +00:00
_RGLAllocateBuffer ( bufferObject ) ;
2012-05-06 01:46:55 +00:00
return jsBuffer - > bufferId ! = GMM_ERROR ;
}
GLAPI void APIENTRY glBufferData ( GLenum target , GLsizeiptr size , const GLvoid * data , GLenum usage )
{
PSGLcontext * LContext = _CurrentContext ;
GLuint name = 0 ;
2012-07-28 23:10:15 +00:00
switch ( target )
2012-05-06 01:46:55 +00:00
{
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 :
2012-07-28 23:10:15 +00:00
_RGLSetError ( GL_INVALID_ENUM ) ;
2012-05-06 01:46:55 +00:00
return ;
}
2012-07-30 02:01:54 +00:00
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ name ] ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( bufferObject - > refCount > 1 )
2012-05-06 01:46:55 +00:00
{
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , 1 , & name ) ;
_RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
2012-07-30 02:01:54 +00:00
bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ name ] ;
2012-05-06 01:46:55 +00:00
}
2012-07-28 23:10:15 +00:00
if ( bufferObject - > size > 0 )
_RGLPlatformDestroyBufferObject ( bufferObject ) ;
2012-05-06 01:46:55 +00:00
bufferObject - > usage = usage ;
bufferObject - > size = size ;
bufferObject - > width = 0 ;
bufferObject - > height = 0 ;
bufferObject - > internalFormat = GL_NONE ;
2012-07-28 23:10:15 +00:00
if ( size > 0 )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-07-28 23:10:15 +00:00
for ( unsigned int i = 0 ; i < attrSetCount ; + + i )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
jsAttribSet * attribSet = bufferObject - > attribSets [ i ] ;
attribSet - > dirty = GL_TRUE ;
2012-05-06 01:46:55 +00:00
}
LContext - > attribSetDirty = GL_TRUE ;
}
static GLvoid _RGLPlatformBufferObjectCopyData ( jsBufferObject * bufferObjectDst ,
jsBufferObject * bufferObjectSrc )
{
RGLBufferObject * dst = ( RGLBufferObject * ) bufferObjectDst - > platformBufferObject ;
RGLBufferObject * src = ( RGLBufferObject * ) bufferObjectSrc - > platformBufferObject ;
switch ( dst - > pool )
{
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_LINEAR :
2012-05-06 01:46:55 +00:00
_RGLMemcpy ( dst - > bufferId , 0 , dst - > pitch , src - > bufferId , src - > bufferSize ) ;
break ;
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_SYSTEM :
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
memcpy ( gmmIdToAddress ( dst - > bufferId ) , gmmIdToAddress ( src - > bufferId ) ,
2012-07-28 23:10:15 +00:00
src - > bufferSize ) ;
2012-05-06 01:46:55 +00:00
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 ;
}
2012-07-30 02:01:54 +00:00
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ name ] ;
2012-05-06 01:46:55 +00:00
if ( bufferObject - > refCount > 1 )
{
jsBufferObject * oldBufferObject = bufferObject ;
_RGLTexNameSpaceDeleteNames ( & LContext - > bufferObjectNameSpace , 1 , & name ) ;
_RGLTexNameSpaceCreateNameLazy ( & LContext - > bufferObjectNameSpace , name ) ;
2012-07-30 02:01:54 +00:00
bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ name ] ;
2012-05-06 01:46:55 +00:00
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 void _RGLFramebufferGetAttachmentTexture (
const jsFramebufferAttachment * attachment ,
2012-07-30 02:01:54 +00:00
jsTexture * * texture )
2012-05-06 01:46:55 +00:00
{
PSGLcontext * LContext = _CurrentContext ;
2012-08-06 03:05:16 +00:00
switch ( attachment - > type )
{
case FRAMEBUFFER_ATTACHMENT_NONE :
* texture = NULL ;
break ;
case FRAMEBUFFER_ATTACHMENT_RENDERBUFFER :
break ;
case FRAMEBUFFER_ATTACHMENT_TEXTURE :
* texture = _RGLTexNameSpaceIsName ( & LContext - > textureNameSpace , attachment - > name ) ? ( jsTexture * ) LContext - > textureNameSpace . data [ attachment - > name ] : NULL ;
break ;
default :
* texture = NULL ;
break ;
}
2012-05-06 01:46:55 +00:00
}
2012-08-06 03:05:16 +00:00
static GLboolean _RGLTextureIsValid ( const jsTexture * texture )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
if ( texture - > imageCount < 1 )
return GL_FALSE ;
if ( ! texture - > image )
return GL_FALSE ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
const jsImage * image = texture - > image ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
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 ;
2012-05-06 01:46:55 +00:00
}
2012-08-02 01:24:14 +00:00
static GLenum _RGLPlatformFramebufferCheckStatus ( jsFramebuffer * framebuffer )
2012-05-06 01:46:55 +00:00
{
GLuint nBuffers = 0 ;
2012-08-02 01:24:14 +00:00
jsImage * image [ MAX_COLOR_ATTACHMENTS + 2 ] = { 0 } ;
2012-05-06 01:46:55 +00:00
GLuint colorFormat = 0 ;
2012-08-02 01:24:14 +00:00
for ( int i = 0 ; i < MAX_COLOR_ATTACHMENTS ; + + i )
2012-05-06 01:46:55 +00:00
{
jsTexture * colorTexture = NULL ;
2012-07-30 02:01:54 +00:00
_RGLFramebufferGetAttachmentTexture ( & framebuffer - > color [ i ] , & colorTexture ) ;
2012-05-06 01:46:55 +00:00
if ( colorTexture ! = NULL )
{
if ( ! _RGLTextureIsValid ( colorTexture ) )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Framebuffer color attachment texture is not complete. \n " ) ;
2012-05-06 01:46:55 +00:00
return GL_FRAMEBUFFER_UNSUPPORTED_OES ;
}
image [ nBuffers ] = colorTexture - > image ;
if ( colorFormat & & colorFormat ! = image [ nBuffers ] - > internalFormat )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Framebuffer attachments have inconsistent color formats. \n " ) ;
2012-05-06 01:46:55 +00:00
return GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES ;
}
colorFormat = image [ nBuffers ] - > internalFormat ;
+ + nBuffers ;
}
}
if ( nBuffers & & colorFormat ! = RGL_ARGB8 )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Color attachment to framebuffer must be a supported drawable format (GL_ARGB_SCE) \n " ) ;
2012-05-06 01:46:55 +00:00
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 ;
}
2012-08-06 03:05:16 +00:00
enum _RGLTextureStrategy
{
TEXTURE_STRATEGY_END ,
TEXTURE_STRATEGY_UNTILED_ALLOC ,
TEXTURE_STRATEGY_UNTILED_CLEAR ,
2012-05-06 01:46:55 +00:00
} ;
static enum _RGLTextureStrategy linearGPUStrategy [ ] =
2012-07-28 23:10:15 +00:00
{
2012-08-06 03:05:16 +00:00
TEXTURE_STRATEGY_UNTILED_ALLOC ,
TEXTURE_STRATEGY_UNTILED_CLEAR ,
TEXTURE_STRATEGY_UNTILED_ALLOC ,
TEXTURE_STRATEGY_END ,
2012-07-28 23:10:15 +00:00
} ;
2012-05-06 01:46:55 +00:00
static void _RGLImageAllocCPUStorage ( jsImage * image )
{
2012-08-06 03:05:16 +00:00
if ( ( image - > storageSize > image - > mallocStorageSize ) | | ( ! image - > mallocData ) )
{
if ( image - > mallocData )
free ( image - > mallocData ) ;
image - > mallocData = ( char * ) malloc ( image - > storageSize + 128 ) ;
image - > mallocStorageSize = image - > storageSize ;
}
intptr_t x = ( intptr_t ) image - > mallocData ;
x = ( x + 128 - 1 ) / 128 * 128 ;
image - > data = ( char * ) x ;
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-28 23:10:15 +00:00
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 ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
for ( int k = 0 ; k < raster - > width ; + + k )
{
GLfloat values [ 4 ] ;
jsColorRGBAf color ;
getComponents ( src , values , srcComponents ) ;
valuesToColor ( & color , values ) ;
colorToValues ( & color , values ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ) ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
putComponents ( dst , values , dstComponents ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
src + = raster - > xstride ;
dst + = image - > xstride ;
}
}
2012-05-06 01:46:55 +00:00
}
static void _RGLPlatformCopyGPUTexture ( jsTexture * texture )
{
2012-07-28 23:10:15 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( gcmTexture - > gpuAddressId = = GMM_ERROR )
return ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
RGLTextureLayout * layout = & gcmTexture - > gpuLayout ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
jsImage * image = texture - > image ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( image - > dataState = = IMAGE_DATASTATE_GPU )
2012-07-28 23:10:15 +00:00
{
_RGLImageAllocCPUStorage ( image ) ;
2012-05-06 01:46:55 +00:00
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-07-28 23:10:15 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
char * gpuData = gmmIdToAddress ( gcmTexture - > gpuAddressId ) + gcmTexture - > gpuAddressIdOffset ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ) ;
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_HOST ;
2012-07-28 23:10:15 +00:00
}
2012-05-06 01:46:55 +00:00
}
2012-08-06 16:24:35 +00:00
static void _RGLPlatformFreeGcmTexture ( jsTexture * texture )
2012-05-06 01:46:55 +00:00
{
2012-08-06 16:24:35 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
switch ( gcmTexture - > pool )
2012-05-06 01:46:55 +00:00
{
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_LINEAR :
case SURFACE_POOL_SYSTEM :
2012-08-06 16:24:35 +00:00
gmmFree ( gcmTexture - > gpuAddressId ) ;
2012-08-02 01:24:14 +00:00
case SURFACE_POOL_NONE :
2012-05-06 01:46:55 +00:00
break ;
default :
2012-08-02 01:24:14 +00:00
break ;
2012-05-06 01:46:55 +00:00
}
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
}
void _RGLPlatformDropTexture ( jsTexture * texture )
{
2012-07-28 23:10:15 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
2012-08-06 16:24:35 +00:00
2012-07-28 23:10:15 +00:00
if ( gcmTexture - > pbo ! = NULL )
{
_RGLPlatformCopyGPUTexture ( texture ) ;
_RGLFreeBufferObject ( gcmTexture - > pbo ) ;
gcmTexture - > pbo = NULL ;
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
2012-08-02 01:24:14 +00:00
gcmTexture - > pool = SURFACE_POOL_NONE ;
2012-07-28 23:10:15 +00:00
gcmTexture - > gpuSize = 0 ;
}
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( gcmTexture - > pool ! = SURFACE_POOL_NONE )
2012-07-28 23:10:15 +00:00
{
_RGLPlatformCopyGPUTexture ( texture ) ;
_RGLPlatformFreeGcmTexture ( texture ) ;
}
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
gcmTexture - > pool = SURFACE_POOL_NONE ;
2012-07-28 23:10:15 +00:00
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_IMAGES ;
2012-07-28 23:10:15 +00:00
_RGLTextureTouchFBOs ( texture ) ;
2012-05-06 01:46:55 +00:00
}
int _RGLGetPixelSize ( GLenum format , GLenum type )
{
int componentSize ;
2012-07-28 23:10:15 +00:00
2012-07-30 02:01:54 +00:00
switch ( type )
2012-05-06 01:46:55 +00:00
{
# 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 ;
2012-07-28 23:10:15 +00:00
}
return _RGLGetComponentCount ( format ) * componentSize ;
2012-05-06 01:46:55 +00:00
}
static void _RGLPlatformChooseGPUFormatAndLayout (
const jsTexture * texture ,
GLboolean forceLinear ,
GLuint pitch ,
RGLTextureLayout * newLayout )
{
2012-07-28 23:10:15 +00:00
jsImage * image = texture - > image ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
newLayout - > baseWidth = image - > width ;
newLayout - > baseHeight = image - > height ;
2012-08-06 16:24:35 +00:00
newLayout - > internalFormat = ( RGLEnum ) image - > internalFormat ;
2012-07-28 23:10:15 +00:00
newLayout - > pixelBits = _RGLPlatformGetBitsPerPixel ( newLayout - > internalFormat ) ;
2012-08-06 03:05:16 +00:00
newLayout - > pitch = pitch ? pitch : _RGLPad ( _RGLGetPixelSize ( texture - > image - > format , texture - > image - > type ) * texture - > image - > width , 64 ) ;
2012-05-06 01:46:55 +00:00
}
2012-08-06 03:05:16 +00:00
void _RGLPlatformDropUnboundTextures ( GLenum pool )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
GLuint i , j ;
2012-08-06 03:05:16 +00:00
2012-07-28 23:10:15 +00:00
for ( i = 0 ; i < LContext - > textureNameSpace . capacity ; + + i )
{
GLboolean bound = GL_FALSE ;
jsTexture * texture = ( jsTexture * ) LContext - > textureNameSpace . data [ i ] ;
2012-08-06 03:05:16 +00:00
if ( ! texture | | ( texture - > referenceBuffer ! = 0 ) )
continue ;
2012-05-06 01:46:55 +00:00
2012-08-06 16:24:35 +00:00
for ( j = 0 ; j < MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + j )
2012-07-28 23:10:15 +00:00
{
if ( LContext - > VertexTextureImages [ j ] = = texture )
{
bound = GL_TRUE ;
break ;
}
}
2012-05-06 01:46:55 +00:00
2012-08-06 16:24:35 +00:00
for ( j = 0 ; j < MAX_TEXTURE_IMAGE_UNITS ; + + j )
2012-07-28 23:10:15 +00:00
{
jsTextureImageUnit * tu = LContext - > TextureImageUnits + j ;
if ( tu - > bound2D = = i )
{
bound = GL_TRUE ;
break ;
}
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( bound )
continue ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
if ( gcmTexture - > pbo ! = NULL & & gcmTexture - > pbo - > refCount > 1 )
continue ;
2012-08-02 01:24:14 +00:00
if ( pool ! = SURFACE_POOL_NONE & & pool ! = gcmTexture - > pool )
2012-07-28 23:10:15 +00:00
continue ;
_RGLPlatformDropTexture ( texture ) ;
}
2012-05-06 01:46:55 +00:00
}
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 + + )
{
2012-08-06 03:05:16 +00:00
case TEXTURE_STRATEGY_UNTILED_ALLOC :
2012-05-06 01:46:55 +00:00
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , 0 , & newLayout ) ;
size = _RGLPad ( newLayout . baseHeight * newLayout . pitch , 1 ) ;
2012-08-02 01:24:14 +00:00
if ( gcmTexture - > pool = = SURFACE_POOL_LINEAR )
2012-05-06 01:46:55 +00:00
{
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 )
{
2012-08-02 01:24:14 +00:00
if ( gcmTexture - > pool ! = SURFACE_POOL_NONE )
2012-05-06 01:46:55 +00:00
_RGLPlatformDropTexture ( texture ) ;
2012-08-02 01:24:14 +00:00
gcmTexture - > pool = SURFACE_POOL_LINEAR ;
2012-05-06 01:46:55 +00:00
gcmTexture - > gpuAddressId = id ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = size ;
gcmTexture - > gpuLayout = newLayout ;
done = GL_TRUE ;
}
}
break ;
2012-08-06 03:05:16 +00:00
case TEXTURE_STRATEGY_UNTILED_CLEAR :
2012-08-02 01:24:14 +00:00
_RGLPlatformDropUnboundTextures ( SURFACE_POOL_LINEAR ) ;
2012-05-06 01:46:55 +00:00
break ;
2012-08-06 03:05:16 +00:00
case TEXTURE_STRATEGY_END :
2012-05-06 01:46:55 +00:00
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
done = GL_TRUE ;
break ;
default :
break ;
}
}
_RGLTextureTouchFBOs ( texture ) ;
}
static void _RGLImageFreeCPUStorage ( jsImage * image )
{
2012-07-28 23:10:15 +00:00
if ( ! image - > mallocData )
return ;
if ( image - > mallocData ! = NULL )
free ( image - > mallocData ) ;
image - > mallocStorageSize = 0 ;
image - > data = NULL ;
image - > mallocData = NULL ;
2012-08-02 01:24:14 +00:00
image - > dataState & = ~ IMAGE_DATASTATE_HOST ;
2012-05-06 01:46:55 +00:00
}
static void _RGLPlatformValidateTextureResources ( jsTexture * texture )
{
if ( RGL_UNLIKELY ( ! _RGLTextureIsValid ( texture ) ) )
{
texture - > isComplete = GL_FALSE ;
return ;
}
texture - > isComplete = GL_TRUE ;
2012-08-02 01:24:14 +00:00
if ( texture - > revalidate & TEXTURE_REVALIDATE_IMAGES | |
texture - > revalidate & TEXTURE_REVALIDATE_LAYOUT )
2012-05-06 01:46:55 +00:00
{
_RGLPlatformReallocateGcmTexture ( texture ) ;
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
RGLTextureLayout * layout = & gcmTexture - > gpuLayout ;
const GLuint pixelBytes = layout - > pixelBits / 8 ;
2012-08-15 09:01:09 +00:00
RGLSurface src ;
src . source = SURFACE_SOURCE_TEMPORARY ;
src . width = 0 ;
src . height = 0 ;
src . bpp = pixelBytes ;
src . pitch = 0 ;
src . format = layout - > internalFormat ;
src . pool = SURFACE_POOL_LINEAR ;
src . ppuData = NULL ;
src . dataId = GMM_ERROR ;
src . dataIdOffset = 0 ;
RGLSurface dst ;
dst . source = SURFACE_SOURCE_TEXTURE ;
dst . width = 0 ;
dst . height = 0 ;
dst . bpp = pixelBytes ;
dst . pitch = layout - > pitch ;
dst . format = layout - > internalFormat ;
dst . pool = SURFACE_POOL_SYSTEM ;
dst . ppuData = NULL ;
dst . dataId = GMM_ERROR ;
dst . dataIdOffset = 0 ;
2012-05-06 01:46:55 +00:00
GLuint bounceBufferId = GMM_ERROR ;
2012-08-15 09:01:09 +00:00
2012-05-06 01:46:55 +00:00
jsImage * image = texture - > image ;
2012-08-15 09:01:09 +00:00
2012-08-02 01:24:14 +00:00
if ( image - > dataState = = IMAGE_DATASTATE_HOST )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-08-15 08:49:39 +00:00
transfer_params_t transfer_params ;
transfer_params . dst_id = dst . dataId ;
transfer_params . dst_id_offset = dst . dataIdOffset ;
transfer_params . dst_pitch = dst . pitch ? dst . pitch : ( dst . bpp * dst . width ) ;
transfer_params . dst_x = 0 ;
transfer_params . dst_y = 0 ;
transfer_params . src_id = src . dataId ;
transfer_params . src_id_offset = src . dataIdOffset ;
transfer_params . src_pitch = src . pitch ? src . pitch : ( src . bpp * src . width ) ;
transfer_params . src_x = 0 ;
transfer_params . src_y = 0 ;
transfer_params . width = src . width ;
transfer_params . height = src . height ;
transfer_params . bpp = src . bpp ;
transfer_params . fifo_ptr = & _RGLState . fifo ;
TransferDataVidToVid ( & transfer_params ) ;
2012-05-06 01:46:55 +00:00
_RGLImageFreeCPUStorage ( image ) ;
2012-08-02 01:24:14 +00:00
image - > dataState | = IMAGE_DATASTATE_GPU ;
2012-05-06 01:46:55 +00:00
}
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 ;
2012-08-06 03:05:16 +00:00
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 ;
2012-05-06 01:46:55 +00:00
platformTexture - > gcmMethods . address . gamma = gamma ;
GLuint internalFormat = layout - > internalFormat ;
_RGLMapTextureFormat ( internalFormat ,
2012-07-28 23:10:15 +00:00
platformTexture - > gcmTexture . format , platformTexture - > gcmTexture . remap ) ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-06 03:05:16 +00:00
if ( gmmIdIsMain ( platformTexture - > gpuAddressId ) )
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
fb - > complete = ( _RGLPlatformFramebufferCheckStatus ( fb ) = = GL_FRAMEBUFFER_COMPLETE_OES ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( ! fb - > complete )
return ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
GLuint width = CELL_GCM_MAX_RT_DIMENSION ;
GLuint height = CELL_GCM_MAX_RT_DIMENSION ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
fb - > rt . colorBufferCount = 0 ;
fb - > rt . colorFormat = RGL_NONE ;
fb - > colorBufferMask = 0x0 ;
GLuint defaultPitch = 0 ;
GLuint defaultId = GMM_ERROR ;
GLuint defaultIdOffset = 0 ;
2012-08-06 03:05:16 +00:00
for ( int i = 0 ; i < RGL_SETRENDERTARGET_MAXCOUNT ; + + i )
2012-07-28 23:10:15 +00:00
{
jsTexture * colorTexture = NULL ;
2012-07-30 02:01:54 +00:00
_RGLFramebufferGetAttachmentTexture ( & fb - > color [ i ] , & colorTexture ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( colorTexture = = NULL )
continue ;
RGLTexture * nvTexture = ( RGLTexture * ) colorTexture - > platformTexture ;
if ( ! colorTexture - > isRenderTarget )
{
colorTexture - > isRenderTarget = GL_TRUE ;
2012-08-02 01:24:14 +00:00
colorTexture - > revalidate | = TEXTURE_REVALIDATE_LAYOUT ;
2012-07-28 23:10:15 +00:00
}
_RGLPlatformValidateTextureResources ( colorTexture ) ;
2012-08-02 01:24:14 +00:00
colorTexture - > image - > dataState = IMAGE_DATASTATE_GPU ;
2012-07-28 23:10:15 +00:00
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 ;
}
}
2012-05-06 01:46:55 +00:00
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 ;
2012-07-28 23:10:15 +00:00
if ( LContext - > framebuffer )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
jsPlatformFramebuffer * framebuffer = static_cast < jsPlatformFramebuffer * > ( ( jsFramebuffer * ) LContext - > framebufferNameSpace . data [ LContext - > framebuffer ] ) ;
2012-05-06 01:46:55 +00:00
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 ;
2012-07-30 02:01:54 +00:00
if ( driver - > rt . colorBufferCount )
newmask | = RGL_COLOR_BUFFER_BIT ;
if ( ! newmask )
2012-05-06 01:46:55 +00:00
return ;
GLbitfield clearMask = newmask ;
2012-07-30 02:01:54 +00:00
if ( driver - > rt . colorBufferCount > 1 )
clearMask & = ~ RGL_COLOR_BUFFER_BIT ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
if ( clearMask )
2012-05-06 01:46:55 +00:00
{
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 )
{
2012-07-30 02:01:54 +00:00
static float _RGLClearVertexBuffer [ 12 ] __attribute__ ( ( aligned ( 128 ) ) ) =
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
- 1.f , - 1.f , 0.f ,
- 1.f , 1.f , 0.f ,
1.f , - 1.f , 0.f ,
1.f , 1.f , 0.f ,
2012-05-06 01:46:55 +00:00
} ;
_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 ) ) ;
2012-08-02 01:24:14 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) bufferId ;
2012-08-15 09:41:04 +00:00
cellGcmSetVertexDataArrayInline ( & _RGLState . fifo , 0 /* index */ , 1 /* frequency */ , 3 * sizeof ( GLfloat ) /*stride */ , 3 /* size */ , CELL_GCM_VERTEX_F /* gcmType */ , CELL_GCM_LOCATION_LOCAL , gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) /* offset */ ) ;
2012-05-06 01:46:55 +00:00
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , 0 ) ;
2012-08-02 01:24:14 +00:00
for ( int i = 1 ; i < MAX_VERTEX_ATTRIBS ; + + i )
2012-05-06 01:46:55 +00:00
{
2012-08-15 09:41:04 +00:00
cellGcmSetVertexDataArrayInline ( & _RGLState . fifo , i /* index */ , 0 /* frequency */ , 0 /*stride */ , 0 /* size */ , CELL_GCM_VERTEX_F /*gcmType */ , CELL_GCM_LOCATION_LOCAL , 0 /* offset */ ) ;
2012-05-06 01:46:55 +00:00
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 ) ;
}
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
_RGLFifoFlush ( fifo ) ;
}
GLAPI void APIENTRY glClearColor ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha )
{
PSGLcontext * LContext = _CurrentContext ;
2012-08-06 03:05:16 +00:00
LContext - > ClearColor . R = MAX ( MIN ( red , 1.f ) , 0.f ) ;
LContext - > ClearColor . G = MAX ( MIN ( green , 1.f ) , 0.f ) ;
LContext - > ClearColor . B = MAX ( MIN ( blue , 1.f ) , 0.f ) ;
LContext - > ClearColor . A = MAX ( MIN ( alpha , 1.f ) , 0.f ) ;
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glBlendEquation ( GLenum mode )
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > BlendEquationRGB = LContext - > BlendEquationAlpha = mode ;
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
}
2012-08-06 03:05:16 +00:00
GLAPI void APIENTRY glBlendColor ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha )
2012-05-06 01:46:55 +00:00
{
PSGLcontext * LContext = _CurrentContext ;
2012-08-06 03:05:16 +00:00
LContext - > BlendColor . R = MAX ( MIN ( red , 1.f ) , 0.f ) ;
LContext - > BlendColor . G = MAX ( MIN ( green , 1.f ) , 0.f ) ;
LContext - > BlendColor . B = MAX ( MIN ( blue , 1.f ) , 0.f ) ;
LContext - > BlendColor . A = MAX ( MIN ( alpha , 1.f ) , 0.f ) ;
2012-05-06 01:46:55 +00:00
LContext - > needValidate | = PSGL_VALIDATE_BLENDING ;
}
2012-08-06 03:05:16 +00:00
GLAPI void APIENTRY glBlendFunc ( GLenum sfactor , GLenum dfactor )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-07-28 23:10:15 +00:00
for ( int i = 0 ; i < n ; + + i )
2012-05-06 01:46:55 +00:00
{
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 )
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
_RGLTexNameSpaceGenNames ( & LContext - > framebufferNameSpace , n , framebuffers ) ;
2012-05-06 01:46:55 +00:00
}
GLAPI GLenum APIENTRY glCheckFramebufferStatusOES ( GLenum target )
{
PSGLcontext * LContext = _CurrentContext ;
if ( LContext - > framebuffer )
{
2012-08-06 03:05:16 +00:00
jsFramebuffer * framebuffer = ( jsFramebuffer * ) LContext - > framebufferNameSpace . data [ LContext - > framebuffer ] ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-06 03:05:16 +00:00
jsFramebuffer * framebuffer = ( jsFramebuffer * ) LContext - > framebufferNameSpace . data [ LContext - > framebuffer ] ;
2012-05-06 01:46:55 +00:00
jsFramebufferAttachment * attach = _RGLFramebufferGetAttachment ( framebuffer , GL_COLOR_ATTACHMENT0_EXT ) ;
if ( ! attach )
return ;
jsTexture * textureObject = NULL ;
2012-07-30 02:01:54 +00:00
_RGLFramebufferGetAttachmentTexture ( attach , & textureObject ) ;
2012-05-06 01:46:55 +00:00
if ( textureObject )
textureObject - > framebuffers . removeElement ( framebuffer ) ;
if ( texture )
{
2012-08-02 01:24:14 +00:00
attach - > type = FRAMEBUFFER_ATTACHMENT_TEXTURE ;
2012-07-30 02:01:54 +00:00
textureObject = ( jsTexture * ) LContext - > textureNameSpace . data [ texture ] ;
2012-05-06 01:46:55 +00:00
textureObject - > framebuffers . pushBack ( framebuffer ) ;
}
else
2012-08-02 01:24:14 +00:00
attach - > type = FRAMEBUFFER_ATTACHMENT_NONE ;
2012-05-06 01:46:55 +00:00
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 ;
}
2012-08-06 16:24:35 +00:00
jsName _RGLCreateName ( jsNameSpace * ns , void * object )
2012-05-06 01:46:55 +00:00
{
2012-07-23 12:14:38 +00:00
if ( ns - > firstFree = = NULL )
2012-05-06 01:46:55 +00:00
{
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 ;
}
2012-08-06 16:24:35 +00:00
unsigned int _RGLIsName ( jsNameSpace * ns , jsName name )
2012-05-06 01:46:55 +00:00
{
2012-07-23 12:14:38 +00:00
if ( RGL_UNLIKELY ( name = = 0 ) )
2012-05-06 01:46:55 +00:00
return 0 ;
- - name ;
if ( RGL_UNLIKELY ( name > = ns - > capacity ) )
return 0 ;
void * * value = ( void * * ) ns - > data [ name ] ;
2012-07-23 12:14:38 +00:00
if ( RGL_UNLIKELY ( value = = NULL | |
2012-08-06 16:24:35 +00:00
( value > = ns - > data & & value < ns - > data + ns - > capacity ) ) )
2012-05-06 01:46:55 +00:00
return 0 ;
return 1 ;
}
2012-08-06 16:24:35 +00:00
void _RGLEraseName ( jsNameSpace * ns , jsName name )
2012-05-06 01:46:55 +00:00
{
2012-08-06 16:24:35 +00:00
if ( _RGLIsName ( ns , name ) )
2012-05-06 01:46:55 +00:00
{
- - name ;
ns - > data [ name ] = ns - > firstFree ;
ns - > firstFree = ns - > data + name ;
}
}
void _RGLTexNameSpaceInit ( jsTexNameSpace * ns , jsTexNameSpaceCreateFunction create , jsTexNameSpaceDestroyFunction destroy )
{
2012-07-28 23:10:15 +00:00
ns - > capacity = CAPACITY_INCR ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-08-06 16:24:35 +00:00
for ( GLuint i = 1 ; i < ns - > capacity ; + + i )
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
GLuint i ;
for ( i = 1 ; i < ns - > capacity ; + + i )
if ( ! ns - > data [ i ] )
break ;
return i ;
2012-05-06 01:46:55 +00:00
}
GLboolean _RGLTexNameSpaceCreateNameLazy ( jsTexNameSpace * ns , GLuint name )
{
if ( name > = ns - > capacity )
{
2012-07-28 23:10:15 +00:00
int newCapacity = name > = ns - > capacity + CAPACITY_INCR ? name + 1 : ns - > capacity + CAPACITY_INCR ;
2012-08-06 16:24:35 +00:00
void * * newData = ( void * * ) realloc ( ns - > data , newCapacity * sizeof ( void * ) ) ;
memset ( newData + ns - > capacity , 0 , ( newCapacity - ns - > capacity ) * sizeof ( void * ) ) ;
2012-05-06 01:46:55 +00:00
ns - > data = newData ;
ns - > capacity = newCapacity ;
}
2012-08-06 16:24:35 +00:00
if ( ! ns - > data [ name ] )
2012-05-06 01:46:55 +00:00
{
ns - > data [ name ] = ns - > create ( ) ;
2012-08-06 16:24:35 +00:00
if ( ns - > data [ name ] )
return GL_TRUE ;
2012-05-06 01:46:55 +00:00
}
return GL_FALSE ;
}
GLboolean _RGLTexNameSpaceIsName ( jsTexNameSpace * ns , GLuint name )
{
2012-07-28 23:10:15 +00:00
if ( ( name > 0 ) & & ( name < ns - > capacity ) )
return ( ns - > data [ name ] ! = 0 ) ;
else
return GL_FALSE ;
2012-05-06 01:46:55 +00:00
}
void _RGLTexNameSpaceGenNames ( jsTexNameSpace * ns , GLsizei n , GLuint * names )
{
2012-07-28 23:10:15 +00:00
for ( int i = 0 ; i < n ; + + i )
2012-05-06 01:46:55 +00:00
{
GLuint name = _RGLTexNameSpaceGetFree ( ns ) ;
names [ i ] = name ;
2012-07-28 23:10:15 +00:00
if ( name )
_RGLTexNameSpaceCreateNameLazy ( ns , name ) ;
2012-05-06 01:46:55 +00:00
}
}
void _RGLTexNameSpaceDeleteNames ( jsTexNameSpace * ns , GLsizei n , const GLuint * names )
{
2012-07-28 23:10:15 +00:00
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 ;
}
2012-05-06 01:46:55 +00:00
}
static inline unsigned int endianSwapWordByHalf ( unsigned int v )
{
2012-07-28 23:10:15 +00:00
return ( v & 0xffff ) < < 16 | v > > 16 ;
2012-05-06 01:46:55 +00:00
}
static uint32_t gmmInitFixedAllocator ( void )
{
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData = ( GmmFixedAllocData * ) malloc ( sizeof ( GmmFixedAllocData ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( pGmmFixedAllocData = = NULL )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
memset ( pGmmFixedAllocData , 0 , sizeof ( GmmFixedAllocData ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData - > ppBlockList [ i ] = ( char * * ) malloc ( sizeof ( char * ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( pGmmFixedAllocData - > ppBlockList [ i ] = = NULL )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData - > ppBlockList [ i ] [ 0 ] = ( char * ) malloc ( blockSize * blockCount ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( pGmmFixedAllocData - > ppBlockList [ i ] [ 0 ] = = NULL )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData - > ppFreeBlockList [ i ] = ( uint16_t * * ) malloc ( sizeof ( uint16_t * ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( pGmmFixedAllocData - > ppFreeBlockList [ i ] = = NULL )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData - > ppFreeBlockList [ i ] [ 0 ] = ( uint16_t * ) malloc ( sizeof ( uint16_t ) * blockCount ) ;
if ( pGmmFixedAllocData - > ppFreeBlockList [ i ] [ 0 ] = = NULL )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
}
2012-07-28 23:10:15 +00:00
static uint8_t gmmSizeToFreeIndex ( uint32_t size )
2012-05-06 01:46:55 +00:00
{
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 ;
}
2012-08-10 00:31:39 +00:00
void gmmAddFree ( GmmAllocator * pAllocator , GmmBlock * pBlock )
2012-05-06 01:46:55 +00:00
{
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 ;
}
}
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 + + )
2012-07-28 23:10:15 +00:00
pGmmFixedAllocData - > ppFreeBlockList [ isTile ] [ listCount ] [ i ] = i ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
int blockCount = isTile ? GMM_TILE_BLOCK_COUNT : GMM_BLOCK_COUNT ;
int blockSize = isTile ? sizeof ( GmmTileBlock ) : sizeof ( GmmBlock ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
}
}
2012-05-06 01:46:55 +00:00
}
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 ( ) ;
}
2012-07-23 12:14:38 +00:00
void gmmSetTileAttrib ( const uint32_t id , const uint32_t tag , void * pData )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
GmmTileBlock * pTileBlock = ( GmmTileBlock * ) id ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
pTileBlock - > tileTag = tag ;
pTileBlock - > pData = pData ;
2012-05-06 01:46:55 +00:00
}
uint32_t gmmIdToOffset ( const uint32_t id )
{
2012-07-28 23:10:15 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) id ;
2012-07-23 12:14:38 +00:00
return gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) ;
2012-05-06 01:46:55 +00:00
}
char * gmmIdToAddress ( const uint32_t id )
{
2012-07-28 23:10:15 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) id ;
2012-05-06 01:46:55 +00:00
do
{
2012-07-28 23:10:15 +00:00
if ( cachedLockValue = = 0 )
break ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
cachedLockValue = * pLock ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( cachedLockValue = = 0 )
break ;
2012-05-06 01:46:55 +00:00
} while ( 1 ) ;
return ( char * ) pBaseBlock - > address ;
}
2012-08-10 00:31:39 +00:00
static void _RGLGetTileRegionInfo ( void * data , GLuint * address , GLuint * size )
{
jsTiledRegion * region = ( jsTiledRegion * ) data ;
* address = region - > offset ;
* size = region - > size ;
}
2012-05-06 01:46:55 +00:00
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 ;
}
2012-07-28 23:10:15 +00:00
static GmmTileBlock * gmmFindFreeTileBlock ( GmmAllocator * pAllocator , const uint32_t size )
2012-05-06 01:46:55 +00:00
{
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 ;
}
2012-07-28 23:10:15 +00:00
static GmmTileBlock * gmmCreateTileBlock ( GmmAllocator * pAllocator , const uint32_t size )
2012-05-06 01:46:55 +00:00
{
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 ;
else
pAllocator - > pTileTail = pNewBlock ;
2012-07-23 12:14:38 +00:00
pAllocator - > pTileHead = pNewBlock ;
2012-05-06 01:46:55 +00:00
return pNewBlock ;
}
2012-07-28 23:10:15 +00:00
static void gmmFreeTileBlock ( GmmTileBlock * pTileBlock )
2012-05-06 01:46:55 +00:00
{
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 )
{
2012-08-02 01:24:14 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) ( uint32_t ) ( pNewBlock ) ;
resizeSucceed = _RGLTryResizeTileRegion ( ( GLuint ) gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) , tileSize + newSize , pBlock - > pData ) ;
2012-05-06 01:46:55 +00:00
}
}
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 ;
}
2012-07-28 23:10:15 +00:00
static void gmmFreeBlock ( GmmBlock * pBlock )
2012-05-06 01:46:55 +00:00
{
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 ) ;
}
2012-07-28 23:10:15 +00:00
static void gmmAddPendingFree ( GmmBlock * pBlock )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-08-02 01:24:14 +00:00
cellGcmSetWriteBackEndLabelInline ( & _RGLState . fifo , SEMA_FENCE , nvFenceCounter ) ;
2012-05-06 01:46:55 +00:00
* 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
)
{
2012-08-09 16:58:08 +00:00
CellGcmContextData * thisContext = & _RGLState . fifo ;
int32_t offset = 0 ;
int32_t sizeLeft = moveSize ;
int32_t dimension = 4096 ;
2012-05-06 01:46:55 +00:00
2012-08-09 16:58:08 +00:00
while ( sizeLeft )
2012-07-23 12:14:38 +00:00
{
2012-08-09 16:58:08 +00:00
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 ) ;
}
2012-05-06 01:46:55 +00:00
2012-08-09 16:58:08 +00:00
dimension = dimension > > 1 ;
if ( dimension = = 32 )
break ;
2012-07-23 12:14:38 +00:00
}
2012-08-09 16:58:08 +00:00
if ( sizeLeft )
cellGcmSetTransferImage ( thisContext ,
CELL_GCM_TRANSFER_LOCAL_TO_LOCAL ,
dstOffset + offset ,
sizeLeft ,
0 ,
0 ,
srcOffset + offset ,
sizeLeft ,
0 ,
0 ,
sizeLeft / 4 ,
1 ,
4 ) ;
2012-05-06 01:46:55 +00: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 ;
2012-08-09 16:58:08 +00:00
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 + + )
gmmLocalMemcpy ( dstOffset + ( i * moveBlockSize ) , srcOffset + ( i * moveBlockSize ) , moveBlockSize ) ;
}
2012-05-06 01:46:55 +00:00
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 ;
2012-08-09 16:58:08 +00:00
uint32_t moveSize = pTempBlock - > base . size ;
2012-05-06 01:46:55 +00:00
dstOffset = gmmAddressToOffset ( pinDstAddress , 0 ) ;
srcOffset = gmmAddressToOffset ( pinSrcAddress , 0 ) ;
2012-08-09 16:58:08 +00:00
totalMoveSize + = moveSize ;
2012-05-06 01:46:55 +00:00
2012-08-09 16:58:08 +00:00
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 + + )
gmmLocalMemcpy ( dstOffset + ( i * moveBlockSize ) , srcOffset + ( i * moveBlockSize ) , moveBlockSize ) ;
}
2012-05-06 01:46:55 +00:00
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 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 ;
2012-07-23 12:14:38 +00:00
2012-05-06 01:46:55 +00:00
if ( pBlock - > pNext )
pBlock - > pNext - > pPrev = pNewBlock ;
2012-07-23 12:14:38 +00:00
2012-05-06 01:46:55 +00:00
pBlock - > pNext = pNewBlock ;
if ( pBlock = = pAllocator - > pTail )
pAllocator - > pTail = pNewBlock ;
gmmAddFree ( pAllocator , pNewBlock ) ;
}
pBlock - > base . size = size ;
2012-08-09 16:58:08 +00:00
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 ;
2012-05-06 01:46:55 +00:00
retId = ( uint32_t ) pBlock ;
}
return retId ;
}
uint32_t gmmAlloc ( const uint8_t isTile , const uint32_t size )
{
2012-07-28 23:10:15 +00:00
CellGcmContextData * thisContext = ( CellGcmContextData * ) & _RGLState . fifo ;
GmmAllocator * pAllocator ;
uint32_t retId ;
uint32_t newSize ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( __builtin_expect ( ( size = = 0 ) , 0 ) )
return GMM_ERROR ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
pAllocator = pGmmLocalAllocator ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( ! isTile )
{
newSize = pad ( size , GMM_ALIGNMENT ) ;
retId = gmmFindFreeBlock ( pAllocator , newSize ) ;
}
else
{
newSize = pad ( size , GMM_TILE_ALIGNMENT ) ;
retId = GMM_ERROR ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( retId = = GMM_ERROR )
{
if ( isTile )
retId = ( uint32_t ) gmmAllocTileBlock ( pAllocator , newSize ) ;
else
retId = ( uint32_t ) gmmAllocBlock ( pAllocator , newSize ) ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( retId = = MEMORY_ALLOC_ERROR )
2012-07-28 23:10:15 +00:00
{
gmmFreeAll ( ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( gmmInternalSweep ( ) )
{
* pLock = 1 ;
cachedLockValue = 1 ;
cellGcmSetWriteBackEndLabel ( thisContext , GMM_PPU_WAIT_INDEX , 0 ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
cellGcmFlush ( thisContext ) ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( isTile )
retId = ( uint32_t ) gmmAllocTileBlock ( pAllocator , newSize ) ;
else
retId = ( uint32_t ) gmmAllocBlock ( pAllocator , newSize ) ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( ! isTile & & retId = = MEMORY_ALLOC_ERROR )
2012-07-28 23:10:15 +00:00
retId = gmmFindFreeBlock ( pAllocator , newSize ) ;
}
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
return retId ;
2012-05-06 01:46:55 +00:00
}
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 ;
}
2012-07-23 12:14:38 +00:00
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 ) { }
2012-05-06 01:46:55 +00:00
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 )
{
2012-08-06 03:05:16 +00:00
void * ptr = NULL ;
2012-05-06 01:46:55 +00:00
const int paddedSIZE = ( SIZE + 1 ) & ~ 1 ;
2012-08-06 03:05:16 +00:00
cellGcmSetInlineTransferPointerInline ( & _RGLState . fifo , gmmIdToOffset ( loadProgramId ) + loadProgramOffset + * ( ec + + ) , paddedSIZE , & ptr ) ;
float * fp = ( float * ) ptr ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-06 03:05:16 +00:00
2012-05-06 01:46:55 +00:00
if ( RGL_LIKELY ( * ec ) )
{
2012-08-06 03:05:16 +00:00
swapandsetfp < SIZE > ( program - > header . instructionCount * 16 , program - > loadProgramId , program - > loadProgramOffset , ec , ( unsigned int * ) data ) ;
2012-05-06 01:46:55 +00:00
}
}
2012-07-23 12:14:38 +00:00
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 ) { }
2012-05-06 01:46:55 +00:00
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 ;
2012-08-06 03:05:16 +00:00
float * __restrict dst = ( float * __restrict ) ptr - > pushBufferPointer ;
for ( long i = 0 ; i < SIZE ; + + i )
2012-05-06 01:46:55 +00:00
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 )
{
2012-08-06 03:05:16 +00:00
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 ] ;
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
jsTexture * texture = NULL ;
if ( name )
{
_RGLTexNameSpaceCreateNameLazy ( & LContext - > textureNameSpace , name ) ;
texture = ( jsTexture * ) LContext - > textureNameSpace . data [ name ] ;
texture - > target = GL_TEXTURE_2D ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
unit - > bound2D = name ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
unit - > currentTexture = _RGLGetCurrentTexture ( unit , GL_TEXTURE_2D ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED ;
2012-05-06 01:46:55 +00:00
}
static void setSamplerfp ( CgRuntimeParameter * ptr , const void * v , int )
{
2012-07-28 23:10:15 +00:00
_CGprogram * program = ( ( CgRuntimeParameter * ) ptr ) - > program ;
const CgParameterResource * parameterResource = _RGLGetParameterResource ( program , ( ( CgRuntimeParameter * ) ptr ) - > parameterEntry ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( v )
* ( GLuint * ) ptr - > pushBufferPointer = * ( GLuint * ) v ;
else
{
jsTextureImageUnit * unit = _CurrentContext - > TextureImageUnits + ( parameterResource - > resource - CG_TEXUNIT0 ) ;
_RGLBindTextureInternal ( unit , * ( GLuint * ) ptr - > pushBufferPointer ) ;
}
2012-05-06 01:46:55 +00:00
}
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
{
2012-07-28 23:10:15 +00:00
for ( int i = 0 ; i < count ; i + + )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
if ( parameterEntry - > flags & CGP_CONTIGUOUS )
2012-07-28 23:10:15 +00:00
memcpy ( rtParameter - > pushBufferPointer , itemDefaultValues , arrayCount * registerStride * 4 * sizeof ( float ) ) ;
2012-05-06 01:46:55 +00:00
else
{
unsigned int * pushBufferPointer = ( ( unsigned int * ) rtParameter - > pushBufferPointer ) ;
for ( int j = 0 ; j < arrayCount ; j + + )
{
2012-07-28 23:10:15 +00:00
unsigned int * pushBufferAddress = isArray ? ( * ( unsigned int * * ) pushBufferPointer ) : pushBufferPointer ;
memcpy ( pushBufferAddress , itemDefaultValues , registerStride * 4 * sizeof ( float ) ) ;
pushBufferPointer + = isArray ? 1 : 3 + registerStride * 4 ;
itemDefaultValues + = 4 * registerStride ;
2012-05-06 01:46:55 +00:00
}
}
}
}
}
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 ;
}
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 )
2012-08-09 16:58:08 +00:00
{
if ( program - > loadProgramId ! = GMM_ERROR )
{
gmmFree ( program - > loadProgramId ) ;
program - > loadProgramId = GMM_ERROR ;
program - > loadProgramOffset = 0 ;
}
}
2012-05-06 01:46:55 +00:00
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 ) ;
2012-08-02 01:24:14 +00:00
if ( jsBuffer - > pool = = SURFACE_POOL_NONE )
2012-05-06 01:46:55 +00:00
{
_RGLSetError ( GL_OUT_OF_MEMORY ) ;
return NULL ;
}
}
else
{
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
_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 ;
2012-08-02 01:24:14 +00:00
gcmTexture - > pool = SURFACE_POOL_NONE ;
2012-05-06 01:46:55 +00:00
gcmTexture - > gpuAddressId = GMM_ERROR ;
gcmTexture - > gpuAddressIdOffset = 0 ;
gcmTexture - > gpuSize = 0 ;
}
_RGLPlatformFreeGcmTexture ( texture ) ;
}
_RGLTextureTouchFBOs ( texture ) ;
}
2012-08-15 10:30:08 +00:00
# ifndef __PSL1GHT__
2012-05-06 01:46:55 +00:00
# include <cell/gcm/gcm_method_data.h>
2012-08-15 10:06:04 +00:00
# endif
2012-05-06 01:46:55 +00:00
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 ;
2012-08-02 01:24:14 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) platformTexture - > gpuAddressId ;
const GLuint imageOffset = gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) + platformTexture - > gpuAddressIdOffset ;
2012-05-06 01:46:55 +00:00
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 ) ;
2012-08-15 10:06:04 +00:00
current [ 8 ] = 0 ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
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 ;
}
2012-05-06 01:46:55 +00:00
}
static GLenum _RGLPlatformChooseInternalStorage ( jsImage * image , GLenum internalFormat )
{
2012-07-23 12:14:38 +00:00
image - > storageSize = 0 ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
GLenum platformInternalFormat = _RGLPlatformChooseInternalFormat ( internalFormat ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
if ( platformInternalFormat = = GL_INVALID_ENUM )
return GL_INVALID_ENUM ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
image - > internalFormat = platformInternalFormat ;
_RGLPlatformExpandInternalFormat ( platformInternalFormat , & image - > format , & image - > type ) ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
image - > storageSize = _RGLGetPixelSize ( image - > format , image - > type ) * image - > width * image - > height ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
return GL_NO_ERROR ;
2012-05-06 01:46:55 +00:00
}
2012-07-30 02:01:54 +00:00
static inline GLuint _RGLGetBufferObjectOrigin ( GLuint buffer )
2012-05-06 01:46:55 +00:00
{
2012-07-30 02:01:54 +00:00
PSGLcontext * LContext = _CurrentContext ;
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ buffer ] ;
2012-05-06 01:46:55 +00:00
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 ) ;
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_HOST ;
2012-05-06 01:46:55 +00:00
}
else
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_UNSET ;
2012-05-06 01:46:55 +00:00
}
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 ;
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_UNSET ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-06 03:05:16 +00:00
const GLuint pboPitch = _RGLPad ( _RGLGetPixelSize ( format , type ) * width , LContext - > unpackAlignment ) ;
2012-05-06 01:46:55 +00:00
if ( ( pboPitch & 3 ) ! = 0 )
{
2012-07-23 09:09:36 +00:00
RARCH_WARN ( " PBO image pitch not a multiple of 4, using slow path. \n " ) ;
2012-05-06 01:46:55 +00:00
return GL_FALSE ;
}
GLuint gpuId = _RGLGetBufferObjectOrigin ( LContext - > PixelUnpackBuffer ) ;
GLuint gpuIdOffset = ( ( GLubyte * ) offset - ( GLubyte * ) NULL ) ;
if ( gmmIdToOffset ( gpuId ) + gpuIdOffset & 63 )
{
2012-07-23 09:09:36 +00:00
RARCH_WARN ( " PBO offset not 64-byte aligned, using slow path. \n " ) ;
2012-05-06 01:46:55 +00:00
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 ;
}
2012-07-30 02:01:54 +00:00
if ( ! formatOK )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
RARCH_WARN ( " PBO format/type requires conversion to texture internal format, using slow path. \n " ) ;
2012-05-06 01:46:55 +00:00
return GL_FALSE ;
}
2012-07-30 02:01:54 +00:00
if ( ! _RGLTextureIsValid ( texture ) )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
RARCH_WARN ( " PBO transfering to incomplete texture, using slow path. \n " ) ;
2012-05-06 01:46:55 +00:00
return GL_FALSE ;
}
RGLTextureLayout newLayout ;
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , pboPitch , & newLayout ) ;
2012-07-30 02:01:54 +00:00
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ LContext - > PixelUnpackBuffer ] ;
2012-05-06 01:46:55 +00:00
if ( newLayout . pitch ! = 0 & & ! bufferObject - > mapped )
{
gcmTexture - > gpuLayout = newLayout ;
if ( gcmTexture - > gpuAddressId ! = GMM_ERROR & & gcmTexture - > pbo = = NULL )
2012-08-06 03:05:16 +00:00
_RGLPlatformFreeGcmTexture ( texture ) ;
2012-05-06 01:46:55 +00:00
gcmTexture - > pbo = bufferObject ;
gcmTexture - > gpuAddressId = gpuId ;
gcmTexture - > gpuAddressIdOffset = gpuIdOffset ;
2012-08-02 01:24:14 +00:00
gcmTexture - > pool = SURFACE_POOL_LINEAR ;
2012-08-06 03:05:16 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
// Get size of texture in GPU layout
gcmTexture - > gpuSize = _RGLPad ( gcmTexture - > gpuLayout . baseHeight * gcmTexture - > gpuLayout . pitch , 1 ) ;
2012-05-06 01:46:55 +00:00
+ + bufferObject - > refCount ;
}
else
{
const GLuint bytesPerPixel = newLayout . pixelBits / 8 ;
2012-08-15 09:01:09 +00:00
RGLSurface src ;
src . source = SURFACE_SOURCE_PBO ;
src . width = image - > width ;
src . height = image - > height ;
src . bpp = bytesPerPixel ;
src . pitch = pboPitch ;
src . format = newLayout . internalFormat ;
src . pool = SURFACE_POOL_LINEAR ;
src . ppuData = NULL ;
src . dataId = gpuId ;
src . dataIdOffset = gpuIdOffset ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_LAYOUT ;
2012-05-06 01:46:55 +00:00
_RGLPlatformValidateTextureResources ( texture ) ;
2012-08-15 09:01:09 +00:00
RGLSurface dst ;
dst . source = SURFACE_SOURCE_TEXTURE ;
dst . width = image - > width ;
dst . height = image - > height ;
dst . bpp = bytesPerPixel ;
dst . pitch = gcmTexture - > gpuLayout . pitch ;
dst . format = gcmTexture - > gpuLayout . internalFormat ;
dst . pool = gcmTexture - > pool ;
dst . ppuData = NULL ;
dst . dataId = gcmTexture - > gpuAddressId ;
dst . dataIdOffset = gcmTexture - > gpuAddressIdOffset ;
2012-05-06 01:46:55 +00:00
2012-08-15 08:49:39 +00:00
transfer_params_t transfer_params ;
transfer_params . dst_id = dst . dataId ;
transfer_params . dst_id_offset = dst . dataIdOffset ;
transfer_params . dst_pitch = dst . pitch ? dst . pitch : ( dst . bpp * dst . width ) ;
transfer_params . dst_x = 0 ;
transfer_params . dst_y = 0 ;
transfer_params . src_id = src . dataId ;
transfer_params . src_id_offset = src . dataIdOffset ;
transfer_params . src_pitch = src . pitch ? src . pitch : ( src . bpp * src . width ) ;
transfer_params . src_x = 0 ;
transfer_params . src_y = 0 ;
transfer_params . width = width ;
transfer_params . height = height ;
transfer_params . bpp = src . bpp ;
transfer_params . fifo_ptr = & _RGLState . fifo ;
TransferDataVidToVid ( & transfer_params ) ;
2012-05-06 01:46:55 +00:00
}
_RGLImageFreeCPUStorage ( image ) ;
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_GPU ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
texture - > revalidate & = ~ ( TEXTURE_REVALIDATE_LAYOUT | TEXTURE_REVALIDATE_IMAGES ) ;
texture - > revalidate | = TEXTURE_REVALIDATE_PARAMETERS ;
2012-05-06 01:46:55 +00:00
_RGLTextureTouchFBOs ( texture ) ;
return GL_TRUE ;
}
static GLboolean _RGLPlatformTextureReference ( jsTexture * texture , GLuint pitch , jsBufferObject * bufferObject , GLintptr offset )
{
2012-08-06 16:24:35 +00:00
RGLTexture * gcmTexture = ( RGLTexture * ) texture - > platformTexture ;
2012-05-06 01:46:55 +00:00
RGLTextureLayout newLayout ;
2012-08-06 16:24:35 +00:00
_RGLPlatformChooseGPUFormatAndLayout ( texture , GL_TRUE , pitch , & newLayout ) ;
2012-05-06 01:46:55 +00:00
texture - > isRenderTarget = GL_TRUE ;
2012-08-06 16:24:35 +00:00
if ( gcmTexture - > gpuAddressId ! = GMM_ERROR )
2012-05-06 01:46:55 +00:00
_RGLPlatformDestroyTexture ( texture ) ;
2012-08-06 16:24:35 +00:00
RGLBufferObject * gcmBuffer = ( RGLBufferObject * ) & bufferObject - > platformBufferObject ;
2012-05-06 01:46:55 +00:00
gcmTexture - > gpuLayout = newLayout ;
gcmTexture - > pool = gcmBuffer - > pool ;
gcmTexture - > gpuAddressId = gcmBuffer - > bufferId ;
gcmTexture - > gpuAddressIdOffset = offset ;
gcmTexture - > gpuSize = _RGLPad ( newLayout . baseHeight * newLayout . pitch , 1 ) ;
2012-08-06 16:24:35 +00:00
texture - > revalidate & = ~ ( TEXTURE_REVALIDATE_LAYOUT | TEXTURE_REVALIDATE_IMAGES ) ;
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_PARAMETERS ;
2012-08-06 16:24:35 +00:00
_RGLTextureTouchFBOs ( texture ) ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-02 01:24:14 +00:00
2012-05-06 01:46:55 +00:00
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 ) )
{
2012-07-30 02:01:54 +00:00
RGLViewportState * v = & _RGLState . state . viewport ;
_RGLFifoGlViewport ( v - > x , v - > y , v - > w , v - > h ) ;
2012-05-06 01:46:55 +00:00
}
}
void _RGLFifoGlSetRenderTarget ( RGLRenderTargetEx const * const args )
{
2012-07-30 02:01:54 +00:00
RGLRenderTarget * rt = & _RGLState . renderTarget ;
CellGcmSurface * grt = & _RGLState . renderTarget . gcmRenderTarget ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
_RGLSetColorDepthBuffers ( rt , args ) ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
//set color depth formats
grt - > colorFormat = CELL_GCM_SURFACE_A8R8G8B8 ;
grt - > depthFormat = CELL_GCM_SURFACE_Z24S8 ;
grt - > depthLocation = CELL_GCM_LOCATION_LOCAL ;
grt - > depthOffset = 0 ;
grt - > depthPitch = 64 ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
grt - > antialias = CELL_GCM_SURFACE_CENTER_1 ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
grt - > type = CELL_GCM_SURFACE_PITCH ;
2012-08-09 16:58:08 +00:00
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 ;
}
2012-07-30 02:01:54 +00:00
cellGcmSetSurfaceInline ( & _RGLState . fifo , grt ) ;
2012-05-06 01:46:55 +00:00
}
2012-08-09 16:58:08 +00:00
void _RGLSetError ( GLenum error )
{
RARCH_ERR ( " Error code: %d \n " , error ) ;
}
2012-05-06 01:46:55 +00:00
2012-08-09 16:58:08 +00:00
GLAPI GLenum APIENTRY glGetError ( void )
2012-05-06 01:46:55 +00:00
{
if ( ! _CurrentContext )
return GL_INVALID_OPERATION ;
else
{
GLenum error = _CurrentContext - > error ;
_CurrentContext - > error = GL_NO_ERROR ;
return error ;
}
}
2012-08-09 16:58:08 +00:00
static inline void _RGLPushProgramPushBuffer ( _CGprogram * cgprog )
2012-05-06 01:46:55 +00:00
{
2012-08-09 16:58:08 +00:00
RGLFifo * fifo = & _RGLState . fifo ;
GLuint spaceInWords = cgprog - > constantPushBufferWordSize + 4 + 32 ;
2012-05-06 01:46:55 +00:00
if ( fifo - > current + spaceInWords + 1024 > fifo - > end )
_RGLOutOfSpaceCallback ( fifo , spaceInWords ) ;
2012-07-30 02:01:54 +00:00
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 ) ;
memcpy ( _RGLState . fifo . current , cgprog - > constantPushBuffer , padded_size ) ;
_RGLState . fifo . current + = cgprog - > constantPushBufferWordSize ;
2012-05-06 01:46:55 +00:00
}
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 ;
2012-08-09 16:58:08 +00:00
RGLFifo * fifo = & _RGLState . fifo ;
GLuint spaceInWords = 7 + 5 * conf . instructionCount ;
if ( fifo - > current + spaceInWords + 1024 > fifo - > end )
_RGLOutOfSpaceCallback ( fifo , spaceInWords ) ;
2012-05-06 01:46:55 +00:00
cellGcmSetVertexProgramLoadInline ( & _RGLState . fifo , & conf , vs - > ucode ) ;
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 ) )
{
2012-08-06 16:24:35 +00:00
for ( int unit = 0 ; unit < MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + unit )
2012-05-06 01:46:55 +00:00
{
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 ( )
{
2012-07-28 23:10:15 +00:00
return _CurrentContext ;
2012-05-06 01:46:55 +00:00
}
static void _RGLResetContext ( PSGLcontext * LContext )
{
_RGLTexNameSpaceResetNames ( & LContext - > textureNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > bufferObjectNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > framebufferNameSpace ) ;
_RGLTexNameSpaceResetNames ( & LContext - > attribSetNameSpace ) ;
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 - > 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 ;
2012-08-06 16:24:35 +00:00
for ( int i = 0 ; i < MAX_TEXTURE_IMAGE_UNITS ; + + i )
2012-05-06 01:46:55 +00:00
{
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 ;
}
2012-08-06 16:24:35 +00:00
for ( int i = 0 ; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + i )
2012-05-06 01:46:55 +00:00
LContext - > VertexTextureImages [ i ] = NULL ;
LContext - > ActiveTexture = 0 ;
LContext - > CurrentImageUnit = LContext - > TextureImageUnits ;
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 jsTexture * _RGLAllocateTexture ( void )
{
GLuint size = sizeof ( jsTexture ) + sizeof ( RGLTexture ) ;
jsTexture * texture = ( jsTexture * ) malloc ( size ) ;
memset ( texture , 0 , size ) ;
2012-08-02 01:24:14 +00:00
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-30 02:01:54 +00:00
_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 ) ;
2012-05-06 01:46:55 +00:00
}
PSGLcontext * psglCreateContext ( void )
{
PSGLcontext * LContext = ( PSGLcontext * ) malloc ( sizeof ( PSGLcontext ) ) ;
if ( ! LContext ) return NULL ;
memset ( LContext , 0 , sizeof ( PSGLcontext ) ) ;
LContext - > error = GL_NO_ERROR ;
_RGLTexNameSpaceInit ( & LContext - > textureNameSpace , ( jsTexNameSpaceCreateFunction ) _RGLAllocateTexture , ( jsTexNameSpaceDestroyFunction ) _RGLFreeTexture ) ;
2012-08-06 16:24:35 +00:00
for ( int i = 0 ; i < MAX_TEXTURE_IMAGE_UNITS ; + + i )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-08-06 16:24:35 +00:00
LContext - > cgProgramNameSpace . data = NULL ;
LContext - > cgProgramNameSpace . firstFree = NULL ;
LContext - > cgProgramNameSpace . capacity = 0 ;
LContext - > cgParameterNameSpace . data = NULL ;
LContext - > cgParameterNameSpace . firstFree = NULL ;
LContext - > cgParameterNameSpace . capacity = 0 ;
LContext - > cgContextNameSpace . data = NULL ;
LContext - > cgContextNameSpace . firstFree = NULL ;
LContext - > cgContextNameSpace . capacity = 0 ;
2012-05-06 01:46:55 +00:00
_RGLResetContext ( LContext ) ;
2012-07-23 12:14:38 +00:00
if ( _RGLContextCreateHook )
_RGLContextCreateHook ( LContext ) ;
2012-05-06 01:46:55 +00:00
return ( LContext ) ;
}
void psglResetCurrentContext ( void )
{
PSGLcontext * context = _CurrentContext ;
_RGLResetContext ( context ) ;
context - > needValidate | = PSGL_VALIDATE_ALL ;
}
2012-07-30 03:32:04 +00:00
static bool context_shutdown = false ;
2012-05-06 01:46:55 +00:00
void psglDestroyContext ( PSGLcontext * LContext )
{
2012-07-30 03:32:04 +00:00
context_shutdown = true ;
2012-05-06 01:46:55 +00:00
if ( _CurrentContext = = LContext )
{
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
}
while ( LContext - > RGLcgContextHead ! = ( CGcontext ) NULL )
{
PSGLcontext * current = _CurrentContext ;
_CurrentContext = LContext ;
cgDestroyContext ( LContext - > RGLcgContextHead ) ;
_CurrentContext = current ;
}
2012-08-06 16:24:35 +00:00
if ( LContext - > cgProgramNameSpace . data )
free ( LContext - > cgProgramNameSpace . data ) ;
LContext - > cgProgramNameSpace . data = NULL ;
LContext - > cgProgramNameSpace . capacity = 0 ;
LContext - > cgProgramNameSpace . firstFree = NULL ;
if ( LContext - > cgParameterNameSpace . data )
free ( LContext - > cgParameterNameSpace . data ) ;
LContext - > cgParameterNameSpace . data = NULL ;
LContext - > cgParameterNameSpace . capacity = 0 ;
LContext - > cgParameterNameSpace . firstFree = NULL ;
if ( LContext - > cgContextNameSpace . data )
free ( LContext - > cgContextNameSpace . data ) ;
LContext - > cgContextNameSpace . data = NULL ;
LContext - > cgContextNameSpace . capacity = 0 ;
LContext - > cgContextNameSpace . firstFree = NULL ;
2012-05-06 01:46:55 +00:00
if ( _RGLContextDestroyHook ) _RGLContextDestroyHook ( LContext ) ;
2012-08-06 16:24:35 +00:00
for ( int i = 0 ; i < MAX_TEXTURE_IMAGE_UNITS ; + + i )
2012-05-06 01:46:55 +00:00
{
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 )
2012-07-28 23:10:15 +00:00
free ( LContext ) ;
2012-05-06 01:46:55 +00:00
}
void _RGLAttachContext ( PSGLdevice * device , PSGLcontext * context )
{
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
context - > attribs - > DirtyMask = ( 1 < < MAX_VERTEX_ATTRIBS ) - 1 ;
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glEnable ( GLenum cap )
{
PSGLcontext * LContext = _CurrentContext ;
2012-07-28 23:10:15 +00:00
switch ( cap )
2012-05-06 01:46:55 +00:00
{
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 :
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 ;
}
}
2012-08-02 01:24:14 +00:00
GLAPI void APIENTRY glDisable ( GLenum cap )
2012-05-06 01:46:55 +00:00
{
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 :
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 ;
}
}
2012-08-02 01:24:14 +00:00
GLAPI void APIENTRY glEnableClientState ( GLenum array )
2012-05-06 01:46:55 +00:00
{
PSGLcontext * LContext = _CurrentContext ;
2012-07-28 23:10:15 +00:00
switch ( array )
2012-05-06 01:46:55 +00:00
{
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 ;
}
}
2012-08-02 01:24:14 +00:00
GLAPI void APIENTRY glDisableClientState ( GLenum array )
2012-05-06 01:46:55 +00:00
{
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 ;
}
}
2012-08-02 01:24:14 +00:00
GLAPI void APIENTRY glFlush ( void )
2012-05-06 01:46:55 +00:00
{
2012-07-30 02:01:54 +00:00
PSGLcontext * LContext = _CurrentContext ;
RGLFifo * fifo = & _RGLState . fifo ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
if ( RGL_UNLIKELY ( LContext - > needValidate ) )
_RGLValidateStates ( ) ;
2012-05-06 01:46:55 +00:00
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
_RGLFifoFlush ( fifo ) ;
2012-05-06 01:46:55 +00:00
}
2012-08-02 01:24:14 +00:00
GLAPI void APIENTRY glFinish ( void )
2012-05-06 01:46:55 +00:00
{
2012-07-30 02:01:54 +00:00
glFlush ( ) ;
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-07-30 02:01:54 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-28 23:10:15 +00:00
if ( ! _RGLInitCompleted )
{
int ret = cellSysmoduleLoadModule ( CELL_SYSMODULE_GCM_SYS ) ;
ret = cellSysmoduleLoadModule ( CELL_SYSMODULE_RESC ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
_RGLDeviceInit ( options ) ;
_CurrentContext = NULL ;
_CurrentDevice = NULL ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
_RGLInitCompleted = 1 ;
2012-05-06 01:46:55 +00:00
}
void psglExit ( void )
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
if ( LContext )
{
glFlush ( ) ;
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-07-28 23:10:15 +00:00
_RGLFifoFinish ( & _RGLState . fifo ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
psglMakeCurrent ( NULL , NULL ) ;
_RGLDeviceExit ( ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
_CurrentContext = NULL ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
_RGLInitCompleted = 0 ;
}
2012-05-06 01:46:55 +00:00
}
# undef __STRICT_ANSI__
GLAPI void APIENTRY glVertexPointer ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer )
{
2012-07-30 12:28:36 +00:00
_RGLVertexAttribPointerNV ( _RGL_ATTRIB_POSITION_INDEX , size , type , GL_FALSE , stride , pointer ) ;
2012-05-06 01:46:55 +00:00
}
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 ;
}
2012-07-23 09:09:36 +00:00
RARCH_WARN ( " Attribute %d needs conversion. Slow path ahead. \n " , index ) ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-30 02:01:54 +00:00
jsAttribSet * attribSet = ( jsAttribSet * ) LContext - > attribSetNameSpace . data [ LContext - > attribSetName ] ;
2012-05-06 01:46:55 +00:00
if ( oldArrayBuffer )
{
int refcount = 0 ;
2012-08-02 01:24:14 +00:00
for ( unsigned int i = 0 ; i < MAX_VERTEX_ATTRIBS ; + + i )
2012-05-06 01:46:55 +00:00
{
if ( attribSet - > attribs . attrib [ i ] . arrayBuffer = = oldArrayBuffer ) + + refcount ;
}
2012-07-30 02:01:54 +00:00
if ( refcount = = 1 )
{
jsBufferObject * buffer = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ oldArrayBuffer ] ;
buffer - > attribSets . removeElement ( attribSet ) ;
}
2012-05-06 01:46:55 +00:00
}
if ( attrib - > arrayBuffer )
{
2012-07-30 02:01:54 +00:00
jsBufferObject * buffer = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ attrib - > arrayBuffer ] ;
buffer - > attribSets . appendUnique ( attribSet ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-30 02:01:54 +00:00
attribSet - > dirty = GL_TRUE ;
LContext - > attribSetDirty = GL_TRUE ;
2012-05-06 01:46:55 +00:00
}
}
void _RGLEnableVertexAttribArrayNV ( GLuint index )
{
2012-07-30 02:01:54 +00:00
PSGLcontext * LContext = _CurrentContext ;
jsAttribSet * attribSet = ( jsAttribSet * ) LContext - > attribSetNameSpace . data [ LContext - > attribSetName ] ;
2012-05-06 01:46:55 +00:00
RGLBIT_TRUE ( LContext - > attribs - > EnabledMask , index ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , index ) ;
if ( LContext - > attribSetName )
2012-07-30 02:01:54 +00:00
{
attribSet - > dirty = GL_TRUE ;
LContext - > attribSetDirty = GL_TRUE ;
}
2012-05-06 01:46:55 +00:00
}
void _RGLDisableVertexAttribArrayNV ( GLuint index )
{
PSGLcontext * LContext = _CurrentContext ;
2012-07-30 02:01:54 +00:00
jsAttribSet * attribSet = ( jsAttribSet * ) LContext - > attribSetNameSpace . data [ LContext - > attribSetName ] ;
2012-05-06 01:46:55 +00:00
RGLBIT_FALSE ( LContext - > attribs - > EnabledMask , index ) ;
RGLBIT_TRUE ( LContext - > attribs - > DirtyMask , index ) ;
if ( LContext - > attribSetName )
2012-07-30 02:01:54 +00:00
{
attribSet - > dirty = GL_TRUE ;
LContext - > attribSetDirty = GL_TRUE ;
}
2012-05-06 01:46:55 +00:00
}
2012-07-30 02:01:54 +00:00
static GLuint _RGLValidateAttributesSlow ( jsDrawParams * dparams )
2012-05-06 01:46:55 +00:00
{
2012-08-02 01:24:14 +00:00
PSGLcontext * LContext = _CurrentContext ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
jsAttributeState * as = LContext - > attribs ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
void * xferBuffer = NULL ;
GLuint xferId = GMM_ERROR ;
GLuint VBOId = GMM_ERROR ;
GLuint gpuOffset ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( RGL_UNLIKELY ( dparams - > xferTotalSize ) )
{
xferId = gmmAlloc ( 0 , dparams - > xferTotalSize ) ;
xferBuffer = gmmIdToAddress ( xferId ) ;
}
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
unsigned int needsUpdateMask = ( as - > DirtyMask | ( as - > EnabledMask & ~ as - > HasVBOMask ) ) ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
LContext - > attribSetDirty = GL_FALSE ;
if ( needsUpdateMask )
{
for ( GLuint i = 0 ; i < MAX_VERTEX_ATTRIBS ; + + i )
{
if ( ! RGLBIT_GET ( needsUpdateMask , i ) )
continue ;
jsAttribute * attrib = as - > attrib + i ;
2012-08-15 09:41:04 +00:00
2012-08-02 01:24:14 +00:00
if ( RGLBIT_GET ( as - > EnabledMask , i ) )
{
2012-08-15 09:41:04 +00:00
GLsizei stride = attrib - > clientStride ;
2012-08-02 01:24:14 +00:00
const GLuint freq = attrib - > frequency ;
if ( RGL_UNLIKELY ( dparams - > attribXferSize [ i ] ) )
{
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) xferId ;
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 ) ;
gpuOffset = gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) + ( b - ( char * ) xferBuffer ) ;
}
else
{
VBOId = _RGLGetBufferObjectOrigin ( attrib - > arrayBuffer ) ;
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) VBOId ;
gpuOffset = gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) + ( ( const GLubyte * ) attrib - > clientData - ( const GLubyte * ) NULL ) ;
}
2012-08-15 09:41:04 +00:00
if ( attrib - > clientSize = = 0 )
{
stride = 0 ;
attrib - > normalized = 0 ;
attrib - > clientType = RGL_FLOAT ;
gpuOffset = 0 ;
}
uint8_t gcmType = 0 ;
switch ( ( RGLEnum ) attrib - > clientType )
{
case RGL_UNSIGNED_BYTE :
gcmType = attrib - > normalized ? CELL_GCM_VERTEX_UB : CELL_GCM_VERTEX_UB256 ;
break ;
case RGL_SHORT :
gcmType = attrib - > 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 :
attrib - > clientSize = 1 ;
gcmType = CELL_GCM_VERTEX_CMP ;
break ;
default :
break ;
}
cellGcmSetVertexDataArrayInline ( & _RGLState . fifo , i , freq , stride , attrib - > clientSize , gcmType , CELL_GCM_LOCATION_LOCAL , gpuOffset ) ;
2012-08-02 01:24:14 +00:00
}
else
{
2012-08-15 09:41:04 +00:00
cellGcmSetVertexDataArrayInline ( & _RGLState . fifo , i , 0 , 0 , 0 , CELL_GCM_VERTEX_F , CELL_GCM_LOCATION_LOCAL , 0 ) ;
2012-08-02 01:24:14 +00:00
cellGcmSetVertexData4fInline ( & _RGLState . fifo , i , attrib - > value ) ;
}
}
cellGcmSetFrequencyDividerOperationInline ( & _RGLState . fifo , as - > ModuloMask ) ;
driver - > invalidateVertexCache = GL_TRUE ;
}
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
as - > DirtyMask = 0 ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
if ( xferId ! = GMM_ERROR )
gmmFree ( xferId ) ;
return 0 ;
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glDrawArrays ( GLenum mode , GLint first , GLsizei count )
{
2012-07-28 23:10:15 +00:00
static uint8_t s_dparams_buff [ ( sizeof ( jsDrawParams ) + 0x7f ) & ~ 0x7f ] __attribute__ ( ( aligned ( 128 ) ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
jsAttributeState * as = LContext - > attribs ;
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
const GLuint clientSideMask = as - > EnabledMask & ~ as - > HasVBOMask ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( RGL_UNLIKELY ( ! RGLBIT_GET ( LContext - > attribs - > EnabledMask , _RGL_ATTRIB_POSITION_INDEX ) ) ) return ;
2012-07-23 12:14:38 +00:00
2012-07-28 23:10:15 +00:00
uint32_t _tmp_clear_loop = ( ( sizeof ( jsDrawParams ) + 0x7f ) & ~ 0x7f ) > > 7 ;
2012-07-23 12:14:38 +00:00
2012-07-28 23:10:15 +00:00
do {
- - _tmp_clear_loop ;
__dcbz ( s_dparams_buff + ( _tmp_clear_loop < < 7 ) ) ;
} while ( _tmp_clear_loop ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
jsDrawParams * dparams = ( jsDrawParams * ) s_dparams_buff ;
dparams - > mode = mode ;
dparams - > firstVertex = first ;
dparams - > vertexCount = count ;
GLuint maxElements = dparams - > firstVertex + dparams - > vertexCount ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( LContext - > needValidate )
2012-08-02 01:24:14 +00:00
_RGLValidateStates ( ) ;
2012-07-23 12:14:38 +00:00
2012-07-28 23:10:15 +00:00
if ( RGL_UNLIKELY ( clientSideMask ) )
{
2012-08-02 01:24:14 +00:00
for ( int i = 0 ; i < MAX_VERTEX_ATTRIBS ; + + i )
2012-07-28 23:10:15 +00:00
{
dparams - > attribXferOffset [ i ] = 0 ;
dparams - > attribXferSize [ i ] = 0 ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
}
}
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( driver - > flushBufferCount ! = 0 )
driver - > invalidateVertexCache = GL_TRUE ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
uint32_t totalXfer = 0 ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
for ( GLuint i = 0 ; i < MAX_VERTEX_ATTRIBS ; + + i )
2012-07-28 23:10:15 +00:00
totalXfer + = dparams - > attribXferSize [ i ] ;
2012-07-30 02:01:54 +00:00
GLuint gpuOffset = _RGLValidateAttributesSlow ( dparams ) ;
2012-07-28 23:10:15 +00:00
( void ) gpuOffset ;
if ( driver - > invalidateVertexCache )
{
driver - > invalidateVertexCache = GL_FALSE ;
2012-08-15 11:15:12 +00:00
cellGcmSetInvalidateVertexCache ( & _RGLState . fifo ) ;
2012-07-28 23:10:15 +00:00
}
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) driver - > fpLoadProgramId ;
cellGcmSetUpdateFragmentProgramParameterInline ( & _RGLState . fifo , gmmAddressToOffset ( pBaseBlock - > address , pBaseBlock - > isMain ) + driver - > fpLoadProgramOffset ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
cellGcmSetDrawArraysInline ( & _RGLState . fifo , CELL_GCM_PRIMITIVE_QUADS , dparams - > firstVertex , dparams - > vertexCount ) ;
2012-05-06 01:46:55 +00:00
}
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 ;
2012-08-06 16:24:35 +00:00
for ( unit = 0 ; unit < MAX_TEXTURE_IMAGE_UNITS ; + + unit )
2012-05-06 01:46:55 +00:00
{
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 ;
}
}
2012-07-30 02:01:54 +00:00
if ( _RGLTexNameSpaceIsName ( & context - > textureNameSpace , name ) )
2012-05-06 01:46:55 +00:00
{
jsTexture * texture = ( jsTexture * ) context - > textureNameSpace . data [ name ] ;
2012-08-06 16:24:35 +00:00
for ( unit = 0 ; unit < MAX_VERTEX_TEXTURE_IMAGE_UNITS ; + + unit )
2012-05-06 01:46:55 +00:00
{
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 ;
2012-08-06 16:24:35 +00:00
for ( int i = 0 ; i < n ; + + i )
if ( textures [ i ] )
_RGLTextureUnbind ( LContext , textures [ i ] ) ;
2012-05-06 01:46:55 +00:00
_RGLTexNameSpaceDeleteNames ( & LContext - > textureNameSpace , n , textures ) ;
}
2012-08-06 16:24:35 +00:00
2012-05-06 01:46:55 +00:00
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 )
2012-08-06 16:24:35 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_LAYOUT ;
2012-05-06 01:46:55 +00:00
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 ;
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_LAYOUT ;
2012-05-06 01:46:55 +00:00
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 ) ;
2012-08-06 16:24:35 +00:00
if ( param )
texture - > gammaRemap | = bit ;
else
texture - > gammaRemap & = ~ bit ;
2012-05-06 01:46:55 +00:00
}
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_PARAMETERS ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-28 23:10:15 +00:00
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 ;
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glTexImage2D ( GLenum target , GLint level , GLint internalFormat ,
2012-07-28 23:10:15 +00:00
GLsizei width , GLsizei height , GLint border , GLenum format , GLenum type , const GLvoid * pixels )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
jsTexture * texture ;
jsImage * image ;
2012-08-06 16:24:35 +00:00
jsTextureImageUnit * unit = LContext - > CurrentImageUnit ;
jsTexture * tex = _RGLGetCurrentTexture ( unit , GL_TEXTURE_2D ) ;
if ( 0 > = ( int ) tex - > imageCount )
_RGLReallocateImages ( tex , MAX ( width , height ) ) ;
image = tex - > image ;
texture = tex ;
2012-05-06 01:46:55 +00:00
2012-08-02 01:24:14 +00:00
image - > dataState = IMAGE_DATASTATE_UNSET ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-30 02:01:54 +00:00
bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ LContext - > PixelUnpackBuffer ] ;
2012-05-06 01:46:55 +00:00
pixels = _RGLPlatformBufferObjectMap ( bufferObject , GL_READ_ONLY ) +
( ( const GLubyte * ) pixels - ( const GLubyte * ) NULL ) ;
}
2012-07-28 23:10:15 +00:00
_RGLSetImage ( image , internalFormat , width , height , 1 , LContext - > unpackAlignment ,
format , type , pixels ) ;
2012-05-06 01:46:55 +00:00
if ( LContext - > PixelUnpackBuffer ! = 0 )
{
2012-07-28 23:10:15 +00:00
RGLBufferObject * jsBuffer = ( RGLBufferObject * ) bufferObject - > platformBufferObject ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( - - jsBuffer - > mapCount = = 0 )
{
if ( jsBuffer - > mapAccess ! = GL_READ_ONLY )
{
RGLDriver * driver = ( RGLDriver * ) _CurrentDevice - > rasterDriver ;
- - driver - > flushBufferCount ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
driver - > invalidateVertexCache = GL_TRUE ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
jsBuffer - > mapAccess = GL_NONE ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
GmmBaseBlock * pBaseBlock = ( GmmBaseBlock * ) jsBuffer - > bufferId ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( ! pBaseBlock - > isTile )
{
GmmBlock * pBlock = ( GmmBlock * ) jsBuffer - > bufferId ;
pBlock - > isPinned = 0 ;
}
}
2012-05-06 01:46:55 +00:00
}
2012-08-02 01:24:14 +00:00
texture - > revalidate | = TEXTURE_REVALIDATE_IMAGES ;
2012-05-06 01:46:55 +00:00
}
_RGLTextureTouchFBOs ( texture ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
}
2012-08-06 03:05:16 +00:00
GLAPI void APIENTRY glActiveTexture ( GLenum texture )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
int unit = texture - GL_TEXTURE0 ;
LContext - > ActiveTexture = unit ;
2012-08-06 16:24:35 +00:00
LContext - > CurrentImageUnit = unit < MAX_TEXTURE_IMAGE_UNITS ? LContext - > TextureImageUnits + unit : NULL ;
2012-05-06 01:46:55 +00:00
}
2012-08-06 03:05:16 +00:00
GLAPI void APIENTRY glClientActiveTexture ( GLenum texture )
2012-05-06 01:46:55 +00:00
{
PSGLcontext * LContext = _CurrentContext ;
LContext - > CS_ActiveTexture = texture - GL_TEXTURE0 ;
}
2012-08-06 03:05:16 +00:00
GLAPI void APIENTRY glPixelStorei ( GLenum pname , GLint param )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
switch ( pname )
{
case GL_PACK_ALIGNMENT :
LContext - > packAlignment = param ;
break ;
case GL_UNPACK_ALIGNMENT :
LContext - > unpackAlignment = param ;
break ;
default :
_RGLSetError ( GL_INVALID_ENUM ) ;
return ;
}
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glTextureReferenceSCE ( GLenum target , GLuint levels , GLuint baseWidth , GLuint baseHeight , GLuint baseDepth , GLenum internalFormat , GLuint pitch , GLintptr offset )
{
2012-07-23 12:14:38 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
jsTexture * texture = _RGLGetCurrentTexture ( LContext - > CurrentImageUnit , GL_TEXTURE_2D ) ;
2012-07-30 02:01:54 +00:00
jsBufferObject * bufferObject = ( jsBufferObject * ) LContext - > bufferObjectNameSpace . data [ LContext - > TextureBuffer ] ;
2012-07-23 12:14:38 +00:00
_RGLReallocateImages ( texture , MAX ( baseWidth , MAX ( baseHeight , baseDepth ) ) ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
GLuint width = baseWidth ;
GLuint height = baseHeight ;
_RGLSetImage ( texture - > image , GL_RGB5_A1 , width , height , 0 , LContext - > unpackAlignment ,
2012-07-28 23:10:15 +00:00
0 , 0 , NULL ) ;
2012-07-23 12:14:38 +00:00
width = MAX ( 1U , width / 2 ) ;
height = MAX ( 1U , height / 2 ) ;
texture - > usage = GL_TEXTURE_LINEAR_GPU_SCE ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
GLboolean r = _RGLPlatformTextureReference ( texture , pitch , bufferObject , offset ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
if ( ! r )
return ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
bufferObject - > textureReferences . pushBack ( texture ) ;
texture - > referenceBuffer = bufferObject ;
texture - > offset = offset ;
_RGLTextureTouchFBOs ( texture ) ;
LContext - > needValidate | = PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ;
2012-05-06 01:46:55 +00:00
}
GLAPI void APIENTRY glViewport ( GLint x , GLint y , GLsizei width , GLsizei height )
{
2012-07-23 12:14:38 +00:00
PSGLcontext * LContext = _CurrentContext ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
LContext - > ViewPort . X = x ;
LContext - > ViewPort . Y = y ;
LContext - > ViewPort . XSize = width ;
LContext - > ViewPort . YSize = height ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
_RGLFifoGlViewport ( LContext - > ViewPort . X , LContext - > ViewPort . Y ,
LContext - > ViewPort . XSize , LContext - > ViewPort . YSize , 0.0f , 1.0f ) ;
2012-05-06 01:46:55 +00:00
}
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
{
2012-07-23 12:14:38 +00:00
CGprofile id ;
char * string ;
int is_vertex_program ;
} RGLcgProfileMapType ;
2012-05-06 01:46:55 +00:00
static void _RGLCgProgramPushFront ( _CGcontext * ctx , _CGprogram * prog )
{
2012-07-23 12:14:38 +00:00
prog - > next = ctx - > programList ;
ctx - > programList = prog ;
prog - > parentContext = ctx ;
ctx - > programCount + + ;
2012-05-06 01:46:55 +00:00
}
static _CGprogram * _RGLCgProgramFindPrev ( _CGcontext * ctx , _CGprogram * prog )
{
2012-07-23 12:14:38 +00:00
_CGprogram * ptr = ctx - > programList ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
while ( ptr ! = NULL & & prog ! = ptr - > next )
2012-07-23 12:14:38 +00:00
ptr = ptr - > next ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
return ptr ;
2012-05-06 01:46:55 +00:00
}
void _RGLCgProgramErase ( _CGprogram * prog )
{
2012-07-28 23:10:15 +00:00
if ( _cgProgramDestroyHook ) _cgProgramDestroyHook ( prog ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
}
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( prog - > id )
_RGLEraseName ( & _CurrentContext - > cgProgramNameSpace , ( jsName ) prog - > id ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( prog - > runtimeElf )
free ( prog - > runtimeElf ) ;
memset ( prog , 0 , sizeof ( _CGprogram ) ) ;
2012-05-06 01:46:55 +00:00
}
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
{
2012-07-23 12:14:38 +00:00
const char * elfFile ;
size_t elfFileSize ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
const char * symtab ;
size_t symbolSize ;
size_t symbolCount ;
const char * symbolstrtab ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
const char * shadertab ;
size_t shadertabSize ;
const char * strtab ;
size_t strtabSize ;
const char * consttab ;
size_t consttabSize ;
} CGELFBinary ;
2012-05-06 01:46:55 +00:00
typedef struct
{
2012-07-23 12:14:38 +00:00
const char * texttab ;
size_t texttabSize ;
const char * paramtab ;
size_t paramtabSize ;
int index ;
} CGELFProgram ;
2012-05-06 01:46:55 +00:00
static bool cgOpenElf ( const void * ptr , size_t size , CGELFBinary * elfBinary )
{
2012-07-28 23:10:15 +00:00
while ( 1 )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
size_t shadertabSize ;
size_t consttabSize ;
size_t strtabSize ;
2012-05-06 01:46:55 +00:00
size_t symbolSize ;
size_t symbolCount ;
const char * symbolstrtab ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
const char * symtab = findSymbolSectionInPlace ( ( const char * ) ptr , size , & symbolSize , & symbolCount , & symbolstrtab ) ;
if ( ! symtab )
break ;
const char * shadertab = findSectionInPlace ( ( const char * ) ptr , size , " .shadertab " , & shadertabSize ) ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
if ( ! shadertab )
break ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
const char * strtab = findSectionInPlace ( ( const char * ) ptr , size , " .strtab " , & strtabSize ) ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
if ( ! strtab )
break ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-30 02:01:54 +00:00
while ( 1 )
2012-05-06 01:46:55 +00:00
{
char sectionName [ 64 ] ;
2012-05-22 16:32:08 +00:00
snprintf ( sectionName , sizeof ( sectionName ) , " .text%04i " , index ) ;
2012-05-06 01:46:55 +00:00
size_t texttabSize ;
const char * texttab = findSectionInPlace ( elfBinary - > elfFile , elfBinary - > elfFileSize , sectionName , & texttabSize ) ;
if ( ! texttab )
break ;
2012-05-22 16:32:08 +00:00
snprintf ( sectionName , sizeof ( sectionName ) , " .paramtab%04i " , index ) ;
2012-05-06 01:46:55 +00: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 )
{
2012-07-28 23:10:15 +00:00
//if no name try to return the first program
2012-07-30 02:01:54 +00:00
int ret ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
if ( name = = NULL | | name [ 0 ] = = ' \0 ' )
2012-07-30 02:01:54 +00:00
ret = 0 ;
2012-07-28 23:10:15 +00:00
else
2012-07-30 02:01:54 +00:00
ret = lookupSymbolValueInPlace ( elfBinary - > symtab , elfBinary - > symbolSize , elfBinary - > symbolCount , elfBinary - > symbolstrtab , name ) ;
2012-07-28 23:10:15 +00:00
2012-07-30 02:01:54 +00:00
if ( ret ! = - 1 )
return cgGetElfProgramByIndex ( elfBinary , ret , elfProgram ) ;
2012-07-28 23:10:15 +00:00
else
return false ;
2012-05-06 01:46:55 +00:00
}
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 ) ) ;
2012-08-06 03:05:16 +00:00
if ( prog = = NULL )
2012-05-06 01:46:55 +00:00
{
_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 ) ;
2012-08-06 03:05:16 +00:00
if ( ! id )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
free ( prog ) ;
2012-05-06 01:46:55 +00:00
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return NULL ;
}
prog - > id = id ;
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 :
2012-07-28 23:10:15 +00:00
success = _RGLGenerateProgram ( prog , FRAGMENT_PROFILE_INDEX , programHeader , ucode , parameterHeader , NULL , stringTable , defaultValues ) ;
2012-05-06 01:46:55 +00:00
break ;
default :
// should never reach here
break ;
}
// if the creation failed, free all resources.
// the error was raised when the error was encoutered.
2012-07-23 12:14:38 +00:00
if ( success = = 0 )
2012-05-06 01:46:55 +00:00
{
// 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.
2012-08-06 03:05:16 +00:00
_RGLCgProgramPushFront ( prog - > parentContext , prog ) ;
if ( _cgProgramCreateHook )
_cgProgramCreateHook ( prog ) ;
2012-05-06 01:46:55 +00:00
// 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.
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 ;
//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 )
{
2012-08-06 03:05:16 +00:00
if ( _cgRTCgcCompileProgramHook )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
_cgRTCgcCompileProgramHook ( program , cgGetProfileString ( profile ) , entry , args , & compiled_program ) ;
2012-08-06 03:05:16 +00:00
if ( ! compiled_program )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_COMPILER_ERROR ) ;
return NULL ;
}
binaryBuffer = compiled_program ;
}
else
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " The CG runtime compiler hasn't been setup. cgRTCgcInit() should be called prior to this function. \n " ) ;
2012-05-06 01:46:55 +00:00
_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');
2012-07-28 23:10:15 +00:00
if ( ! ( * ( unsigned int * ) binaryBuffer = = ElfTag ) )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
//convert NV file to the runtime format
2012-05-06 01:46:55 +00:00
if ( program_type = = CG_BINARY )
{
2012-07-23 09:09:36 +00:00
RARCH_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 " ) ;
2012-05-06 01:46:55 +00:00
}
//convert from NV format to the runtime format
int compiled_program_size = 0 ;
2012-07-30 02:01:54 +00:00
std : : vector < char > stringTableArray ;
std : : vector < float > defaultValuesArray ;
2012-05-06 01:46:55 +00:00
CgBinaryProgram * nvProgram = ( CgBinaryProgram * ) binaryBuffer ;
char * runtimeElfShader = NULL ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
//check the endianness
int totalSize ;
2012-07-28 23:10:15 +00:00
2012-05-06 01:46:55 +00:00
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 ;
2012-07-28 23:10:15 +00:00
2012-08-06 03:05:16 +00:00
int res = convertNvToElfFromMemory ( binaryBuffer , totalSize , 2 , 0 , ( void * * ) & runtimeElfShader , & compiled_program_size , stringTableArray , defaultValuesArray ) ;
2012-05-06 01:46:55 +00:00
if ( res ! = 0 )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Invalid CG binary program. \n " ) ;
2012-05-06 01:46:55 +00:00
_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 ) ;
2012-07-28 23:10:15 +00:00
char * runtimeElf = ( char * ) memalign ( 16 , paddedSize + stringTableSize + defaultTableSize ) ;
2012-05-06 01:46:55 +00:00
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 )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " CG Binary not aligned on 16 bytes, needed for ucode section. \n " ) ;
2012-05-06 01:46:55 +00:00
_RGLCgRaiseError ( CG_PROGRAM_LOAD_ERROR ) ;
return NULL ;
}
bool res = cgOpenElf ( binaryBuffer , 0 , & elfBinary ) ;
2012-08-06 03:05:16 +00:00
if ( ! res )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Not a valid ELF. \n " ) ;
2012-05-06 01:46:55 +00:00
_RGLCgRaiseError ( CG_PROGRAM_LOAD_ERROR ) ;
return NULL ;
}
2012-08-06 03:05:16 +00:00
if ( ! cgGetElfProgramByName ( & elfBinary , entry , & elfProgram ) )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Couldn't find the shader entry in the CG binary. \n " ) ;
2012-05-06 01:46:55 +00:00
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 ) ;
2012-08-06 03:05:16 +00:00
if ( bConvertedToElf )
2012-05-06 01:46:55 +00:00
{
2012-08-06 03:05:16 +00:00
_CGprogram * ptr = _cgGetProgPtr ( prog ) ;
ptr - > runtimeElf = programHeader ;
2012-05-06 01:46:55 +00:00
}
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 )
2012-08-06 03:05:16 +00:00
program_type = CG_BINARY ;
2012-05-06 01:46:55 +00:00
if ( ! _RGLCgCreateProgramChecks ( ctx , profile , program_type ) )
2012-08-06 03:05:16 +00:00
return NULL ;
2012-05-06 01:46:55 +00:00
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
{
2012-08-06 03:05:16 +00:00
fp = fopen ( program_file , " rb " ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
if ( fp = = NULL )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
2012-08-06 03:05:16 +00:00
return ( CGprogram ) NULL ;
2012-05-06 01:46:55 +00:00
}
unsigned int filetag = 0 ;
int res = fread ( & filetag , sizeof ( filetag ) , 1 , fp ) ;
2012-07-30 02:01:54 +00:00
if ( ! res )
2012-05-06 01:46:55 +00:00
{
2012-07-30 02:01:54 +00:00
fclose ( fp ) ;
2012-05-06 01:46:55 +00:00
_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 )
{
2012-07-23 09:09:36 +00:00
RARCH_ERR ( " Couldn't find the shader entry in the CG binary. \n " ) ;
2012-05-06 01:46:55 +00:00
}
else
ret = _RGLCgUpdateProgramAtIndex ( group , index , 1 ) ;
}
}
return ret ;
}
}
}
if ( ! fp )
{
fp = fopen ( program_file , " rb " ) ;
2012-07-23 12:14:38 +00:00
if ( fp = = NULL )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogram ) NULL ;
}
}
size_t file_size = 0 ;
2012-08-06 03:05:16 +00:00
fseek ( fp , 0 , SEEK_END ) ;
file_size = ftell ( fp ) ;
rewind ( fp ) ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
char * ptr = ( char * ) malloc ( file_size + 1 ) ;
if ( ptr = = NULL )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
fclose ( fp ) ;
return ( CGprogram ) NULL ;
}
fread ( ptr , file_size , 1 , fp ) ;
fclose ( fp ) ;
if ( program_type = = CG_SOURCE )
2012-07-28 23:10:15 +00:00
ptr [ file_size ] = ' \0 ' ;
2012-05-06 01:46:55 +00:00
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 ) ;
2012-07-23 12:14:38 +00:00
if ( prog = = NULL )
2012-05-06 01:46:55 +00:00
{
_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 )
2012-08-06 03:05:16 +00:00
{
paddedProgramSize = _RGLPad ( sizeof ( _CGprogram ) , 16 ) ;
ucodeSize = prog - > header . instructionCount * 16 ;
newprog = ( _CGprogram * ) malloc ( paddedProgramSize + ucodeSize ) ;
}
2012-05-06 01:46:55 +00:00
else
2012-08-06 03:05:16 +00:00
{
newprog = ( _CGprogram * ) malloc ( sizeof ( _CGprogram ) ) ;
}
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
if ( newprog = = NULL )
2012-05-06 01:46:55 +00:00
{
_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 )
2012-08-06 03:05:16 +00:00
{
newprog - > ucode = ( char * ) newprog + paddedProgramSize ;
memcpy ( ( char * ) newprog - > ucode , ( char * ) prog - > ucode , ucodeSize ) ;
}
2012-05-06 01:46:55 +00:00
if ( prog - > programGroup )
{
newprog - > programGroup = prog - > programGroup ;
newprog - > programIndexInGroup = - 1 ;
_RGLCgUpdateProgramAtIndex ( newprog - > programGroup , - 1 , 1 ) ;
}
2012-08-06 03:05:16 +00:00
_RGLCgProgramPushFront ( newprog - > parentContext , newprog ) ;
2012-05-06 01:46:55 +00:00
2012-08-06 03:05:16 +00:00
if ( _cgProgramCopyHook )
_cgProgramCopyHook ( newprog , prog ) ;
2012-05-06 01:46:55 +00:00
return newprog - > id ;
}
CG_API void cgDestroyProgram ( CGprogram program )
{
if ( ! CG_IS_PROGRAM ( program ) )
{
_RGLCgRaiseError ( CG_INVALID_PROGRAM_HANDLE_ERROR ) ;
return ;
}
2012-08-06 03:05:16 +00:00
2012-05-06 01:46:55 +00:00
_CGprogram * ptr = _cgGetProgPtr ( program ) ;
2012-08-06 03:05:16 +00:00
2012-07-23 12:14:38 +00:00
if ( ptr = = NULL )
2012-05-06 01:46:55 +00:00
{
_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 )
2012-08-06 03:05:16 +00:00
free ( p ) ;
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-30 02:01:54 +00:00
FILE * fp = fopen ( group_file , " rb " ) ;
2012-05-06 01:46:55 +00:00
2012-07-30 02:01:54 +00:00
if ( fp = = NULL )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_FILE_READ_ERROR ) ;
return ( CGprogramGroup ) NULL ;
}
size_t file_size = 0 ;
fseek ( fp , 0 , SEEK_END ) ;
file_size = ftell ( fp ) ;
rewind ( fp ) ;
2012-07-30 02:01:54 +00:00
char * ptr = ( char * ) malloc ( file_size + 1 ) ;
if ( ptr = = NULL )
2012-05-06 01:46:55 +00:00
{
_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 16:51:06 +00:00
strlcpy ( group - > name , name , sizeof ( group - > name ) ) ;
2012-05-06 01:46:55 +00: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 [ ] =
2012-07-23 12:14:38 +00:00
{
{ ( CGprofile ) 6144 , " CG_PROFILE_START " , 1 } ,
{ ( CGprofile ) 6145 , " unknown " , 1 } ,
2012-05-06 01:46:55 +00:00
# define CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile) \
2012-07-23 12:14:38 +00:00
{ CG_PROFILE_ # # compiler_id_caps , compiler_opt , vertex_profile } ,
2012-05-06 01:46:55 +00:00
# include <Cg/cg_profiles.h>
2012-07-23 12:14:38 +00:00
{ ( CGprofile ) 0 , " " , 0 }
} ;
2012-05-06 01:46:55 +00:00
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 " " ;
}
2012-07-23 09:09:36 +00:00
CG_API CGerror cgGetError ( void )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
CGerror err = _CurrentContext - > RGLcgLastError ;
_CurrentContext - > RGLcgLastError = CG_NO_ERROR ;
return err ;
2012-05-06 01:46:55 +00:00
}
2012-07-23 09:09:36 +00:00
CG_API const char * cgGetErrorString ( CGerror error )
2012-05-06 01:46:55 +00:00
{
2012-07-23 09:09:36 +00:00
static char strbuf [ 256 ] ;
snprintf ( strbuf , sizeof ( strbuf ) , " %d " , error ) ;
return strbuf ;
2012-05-06 01:46:55 +00:00
}
void _RGLCgDestroyContextParam ( CgRuntimeParameter * ptr )
{
2012-07-23 09:09:36 +00:00
if ( _cgParameterDestroyHook ) _cgParameterDestroyHook ( ptr ) ;
_RGLEraseName ( & _CurrentContext - > cgParameterNameSpace , ( jsName ) ( ptr - > id ) ) ;
free ( ptr ) ;
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-28 23:10:15 +00:00
if ( profile = = ( CGprofile ) 7005 )
profile = CG_PROFILE_SCE_VP_RSX ;
if ( profile = = ( CGprofile ) 7006 )
profile = CG_PROFILE_SCE_FP_RSX ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
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 ;
}
2012-05-06 01:46:55 +00:00
}
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 ;
2012-08-02 01:24:14 +00:00
for ( GLuint unit = 0 ; unit < MAX_TEXTURE_UNITS ; + + unit )
2012-05-06 01:46:55 +00:00
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 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 ;
2012-08-02 01:24:14 +00:00
for ( GLuint unit = 0 ; unit < MAX_TEXTURE_UNITS ; + + unit )
2012-05-06 01:46:55 +00:00
_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 void cgGLSetParameter1f ( CGparameter param , float x )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
float v [ 4 ] = { x , x , x , x } ;
ptr - > setterIndex ( ptr , v , CG_GETINDEX ( param ) ) ;
2012-05-06 01:46:55 +00:00
}
CGGL_API void cgGLSetParameter2f ( CGparameter param , float x , float y )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
float v [ 4 ] = { x , y , y , y } ;
ptr - > setterIndex ( ptr , v , CG_GETINDEX ( param ) ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-23 12:14:38 +00:00
CGGL_API void cgGLSetParameterPointer
( CGparameter param ,
GLint fsize ,
GLenum type ,
GLsizei stride ,
const GLvoid * pointer )
2012-05-06 01:46:55 +00:00
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * _ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
2012-05-06 01:46:55 +00:00
2012-07-28 23:10:15 +00:00
_RGLVertexAttribPointerNV (
index ,
fsize ,
type ,
( _ptr - > parameterEntry - > flags & CGP_NORMALIZE ) ? 1 : 0 ,
stride ,
pointer ) ;
2012-05-06 01:46:55 +00:00
}
CGGL_API void cgGLEnableClientState ( CGparameter param )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * _ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
2012-05-06 01:46:55 +00:00
2012-07-23 12:14:38 +00:00
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
_RGLEnableVertexAttribArrayNV ( index ) ;
2012-05-06 01:46:55 +00:00
}
CGGL_API void cgGLDisableClientState ( CGparameter param )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * _ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
const CgParameterResource * parameterResource = _RGLGetParameterResource ( _ptr - > program , _ptr - > parameterEntry ) ;
GLuint index = ( GLuint ) ( parameterResource - > resource - CG_ATTR0 ) ;
_RGLDisableVertexAttribArrayNV ( index ) ;
}
CGGL_API void cgGLSetTextureParameter ( CGparameter param , GLuint texobj )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
ptr - > samplerSetter ( ptr , & texobj , 0 ) ;
}
CGGL_API void cgGLEnableTextureParameter ( CGparameter param )
{
2012-07-30 02:01:54 +00:00
CgRuntimeParameter * ptr = _cgGetParamPtr ( param ) ;
2012-05-06 01:46:55 +00:00
ptr - > samplerSetter ( ptr , NULL , 0 ) ;
}
2012-07-28 23:10:15 +00:00
static void _RGLCgContextPushFront ( _CGcontext * ctx )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
if ( _CurrentContext - > RGLcgContextHead )
{
_CGcontext * head = _cgGetContextPtr ( _CurrentContext - > RGLcgContextHead ) ;
ctx - > next = head ;
}
_CurrentContext - > RGLcgContextHead = ctx - > id ;
2012-05-06 01:46:55 +00:00
}
2012-07-28 23:10:15 +00:00
static void destroy_context ( _CGcontext * ctx )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
if ( _cgContextDestroyHook )
_cgContextDestroyHook ( ctx ) ;
_RGLEraseName ( & _CurrentContext - > cgContextNameSpace , ( jsName ) ctx - > id ) ;
2012-08-06 03:05:16 +00:00
memset ( ctx , 0 , sizeof ( * ctx ) ) ;
ctx - > compileType = CG_UNKNOWN ;
2012-07-28 23:10:15 +00:00
free ( ctx ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-28 23:10:15 +00:00
CG_API CGcontext cgCreateContext ( void )
2012-05-06 01:46:55 +00:00
{
_CGcontext * ptr = NULL ;
ptr = ( _CGcontext * ) malloc ( sizeof ( _CGcontext ) ) ;
2012-07-23 12:14:38 +00:00
if ( ptr = = NULL )
2012-05-06 01:46:55 +00:00
{
_RGLCgRaiseError ( CG_MEMORY_ALLOC_ERROR ) ;
return ( CGcontext ) NULL ;
}
2012-08-06 03:05:16 +00:00
memset ( ptr , 0 , sizeof ( * ptr ) ) ;
ptr - > compileType = CG_UNKNOWN ;
2012-05-06 01:46:55 +00:00
CGcontext result = ( CGcontext ) _RGLCreateName ( & _CurrentContext - > cgContextNameSpace , ptr ) ;
2012-07-30 02:01:54 +00:00
if ( ! result )
{
free ( ptr ) ;
return NULL ;
}
2012-05-06 01:46:55 +00:00
ptr - > id = result ;
ptr - > defaultProgram . parentContext = ptr ;
_RGLCgContextPushFront ( ptr ) ;
if ( _cgContextCreateHook ) _cgContextCreateHook ( ptr ) ;
return result ;
}
2012-07-28 23:10:15 +00:00
CG_API void cgDestroyContext ( CGcontext c )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
if ( ! CG_IS_CONTEXT ( c ) )
2012-05-06 01:46:55 +00:00
{
2012-07-28 23:10:15 +00:00
_RGLCgRaiseError ( CG_INVALID_CONTEXT_HANDLE_ERROR ) ;
return ;
2012-05-06 01:46:55 +00:00
}
_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 ;
2012-07-30 03:32:04 +00:00
if ( ! context_shutdown )
{
RARCH_ERR ( " Cg error: %d. \n " , error ) ;
2012-05-06 01:46:55 +00:00
2012-07-30 03:32:04 +00:00
if ( _CurrentContext - > RGLcgErrorCallbackFunction )
_CurrentContext - > RGLcgErrorCallbackFunction ( ) ;
}
2012-05-06 01:46:55 +00:00
}
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 )
{
2012-07-23 12:14:38 +00:00
_RGLCgRaiseError ( CG_INVALID_PARAMETER_ERROR ) ;
2012-05-06 01:46:55 +00:00
}
void _cgRaiseInvalidParamIndex ( CgRuntimeParameter * p , const void * v , const int index )
{
2012-07-23 12:14:38 +00:00
_RGLCgRaiseError ( CG_INVALID_PARAMETER_ERROR ) ;
2012-05-06 01:46:55 +00:00
}
void _cgRaiseNotMatrixParam ( CgRuntimeParameter * p , const void * v )
{
2012-07-23 12:14:38 +00:00
_RGLCgRaiseError ( CG_NOT_MATRIX_PARAM_ERROR ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-23 12:14:38 +00:00
2012-05-06 01:46:55 +00:00
void _cgRaiseNotMatrixParamIndex ( CgRuntimeParameter * p , const void * v , const int index )
{
2012-07-23 12:14:38 +00:00
_RGLCgRaiseError ( CG_NOT_MATRIX_PARAM_ERROR ) ;
2012-05-06 01:46:55 +00:00
}
2012-07-23 12:14:38 +00:00
void _cgIgnoreSetParam ( CgRuntimeParameter * p , const void * v ) { }
void _cgIgnoreSetParamIndex ( CgRuntimeParameter * p , const void * v , const int index ) { }
2012-05-06 01:46:55 +00:00
# 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 ] ;
}
2012-08-09 20:15:30 +00:00
CGGL_API void cgGLSetMatrixParameterfc ( CGparameter param , const float * matrix )
{
CgRuntimeParameter * ptr = _cgGetParamPtr ( param ) ;
ptr - > settercIndex ( ptr , matrix , CG_GETINDEX ( param ) ) ;
}