RetroArch/console/rgl/ps3/device_ctx.cpp
2012-05-06 03:47:35 +02:00

1333 lines
44 KiB
C++

#include <stdio.h>
#include "rgl.h"
#include "private.h"
#include <string.h>
#include <sdk_version.h>
#include <cell/gcm.h>
#include <cell/resc.h>
#include <sysutil/sysutil_sysparam.h>
#include <sys/synchronization.h>
using namespace cell::Gcm;
#define _RGL_MAX_TILED_REGIONS 15
#define _RGL_TILED_BUFFER_ALIGNMENT 0x10000
#define _RGL_TILED_BUFFER_HEIGHT_ALIGNMENT 64
#define _RGL_FIFO_SIZE (65536)
#define _RGL_DMA_PUSH_BUFFER_PREFETCH_PADDING 0x1000
#define RGL_UTIL_LABEL_INDEX 253
extern void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args );
typedef struct
{
int id;
GLuint offset;
GLuint size;
GLuint pitch;
GLuint bank;
} jsTiledRegion;
typedef struct
{
jsTiledRegion region[_RGL_MAX_TILED_REGIONS];
} jsTiledMemoryManager;
PSGLdevice *_CurrentDevice = NULL;
static GLboolean _RGLDuringDestroyDevice = GL_FALSE;
static jsTiledMemoryManager _RGLTiledMemoryManager;
static RGLResource _RGLResource;
static sys_semaphore_t FlipSem;
static volatile uint32_t *labelAddress = NULL;
static const uint32_t WaitLabelIndex = 111;
extern GLuint nvFenceCounter;
RGLState _RGLState;
typedef struct
{
int width;
int height;
unsigned char hwMode;
} VideoMode;
static const VideoMode sysutilModes[] =
{
{720, 480, CELL_VIDEO_OUT_RESOLUTION_480},
{720, 576, CELL_VIDEO_OUT_RESOLUTION_576},
{1280, 720, CELL_VIDEO_OUT_RESOLUTION_720},
{960, 1080, CELL_VIDEO_OUT_RESOLUTION_960x1080},
{1280, 1080, CELL_VIDEO_OUT_RESOLUTION_1280x1080},
{1440, 1080, CELL_VIDEO_OUT_RESOLUTION_1440x1080},
{1600, 1080, CELL_VIDEO_OUT_RESOLUTION_1600x1080},
{1920, 1080, CELL_VIDEO_OUT_RESOLUTION_1080},
};
static unsigned int validPitch[] =
{
0x0200,
0x0300,
0x0400,
0x0500,
0x0600,
0x0700,
0x0800,
0x0A00,
0x0C00,
0x0D00,
0x0E00,
0x1000,
0x1400,
0x1800,
0x1A00,
0x1C00,
0x2000,
0x2800,
0x3000,
0x3400,
0x3800,
0x4000,
0x5000,
0x6000,
0x6800,
0x7000,
0x8000,
0xA000,
0xC000,
0xD000,
0xE000,
0x10000,
};
static const unsigned int validPitchCount = sizeof( validPitch ) / sizeof( validPitch[0] );
static const int sysutilModeCount = sizeof( sysutilModes ) / sizeof( sysutilModes[0] );
static inline void _RGLPrintIt( unsigned int v )
{
printf( "%02x %02x %02x %02x : ", ( v >> 24 )&0xff, ( v >> 16 )&0xff, ( v >> 8 )&0xff, v&0xff );
for ( unsigned int mask = ( 0x1 << 31 ), i = 1; mask != 0; mask >>= 1, i++ )
printf( "%d%s", ( v & mask ) ? 1 : 0, ( i % 8 == 0 ) ? " " : "" );
printf( "\n" );
}
static inline void _RGLPrintFifoFromPut( unsigned int numWords )
{
for ( int i = -numWords; i <= -1; i++ )
_RGLPrintIt((( uint32_t* )_RGLState.fifo.current )[i] );
}
static inline void _RGLPrintFifoFromGet( unsigned int numWords )
{
for ( int i = -numWords; i <= -1; i++ )
_RGLPrintIt((( uint32_t* )_RGLState.fifo.lastGetRead )[i] );
}
static GLuint _RGLFifoReadReference( RGLFifo *fifo )
{
GLuint ref = *(( volatile GLuint * ) & fifo->dmaControl->Reference );
fifo->lastHWReferenceRead = ref;
return ref;
}
static GLboolean _RGLFifoReferenceInUse( RGLFifo *fifo, GLuint reference )
{
if ( !(( fifo->lastHWReferenceRead - reference ) & 0x80000000 ) )
return GL_FALSE;
if (( fifo->lastSWReferenceFlushed - reference ) & 0x80000000 )
{
_RGLFifoFlush( fifo );
}
_RGLFifoReadReference( fifo );
if ( !(( fifo->lastHWReferenceRead - reference ) & 0x80000000 ) )
return GL_FALSE;
return GL_TRUE;
}
static GLuint _RGLFifoPutReference( RGLFifo *fifo )
{
fifo->lastSWReferenceWritten++;
cellGcmSetReferenceCommandInline ( &_RGLState.fifo, fifo->lastSWReferenceWritten );
if (( fifo->lastSWReferenceWritten & 0x7fffffff ) == 0 )
{
_RGLFifoFinish( fifo );
}
return fifo->lastSWReferenceWritten;
}
void _RGLFifoFinish( RGLFifo *fifo )
{
GLuint ref = _RGLFifoPutReference( fifo );
_RGLFifoFlush( fifo );
for ( ;; )
{
if ( !_RGLFifoReferenceInUse( fifo, ref ) )
break;
sys_timer_usleep( 10 );
}
}
static void _RGLFifoInit( RGLFifo *fifo, void *dmaControl, unsigned long dmaPushBufferOffset, uint32_t *dmaPushBuffer, GLuint dmaPushBufferSize )
{
fifo->fifoBlockSize = DEFAULT_FIFO_BLOCK_SIZE;
fifo->begin = ( uint32_t * ) dmaPushBuffer;
fifo->end = fifo->begin + ( fifo->fifoBlockSize / sizeof( uint32_t ) ) - 1;
fifo->current = fifo->begin;
fifo->lastGetRead = fifo->current;
fifo->lastPutWritten = fifo->current;
fifo->dmaPushBufferBegin = dmaPushBuffer;
fifo->dmaPushBufferEnd = ( uint32_t * )(( size_t )dmaPushBuffer + dmaPushBufferSize ) - 1;
fifo->dmaControl = ( RGLControlDma* )dmaControl;
fifo->dmaPushBufferOffset = dmaPushBufferOffset;
fifo->dmaPushBufferSizeInWords = dmaPushBufferSize / sizeof( uint32_t );
fifo->lastHWReferenceRead = 0;
fifo->lastSWReferenceWritten = 0;
fifo->lastSWReferenceFlushed = 0;
gCellGcmCurrentContext = fifo;
gCellGcmCurrentContext->callback = ( CellGcmContextCallback )_RGLOutOfSpaceCallback;
if ( _RGLFifoReadReference( fifo ) != 0 )
{
cellGcmSetReferenceCommandInline ( &_RGLState.fifo, 0);
_RGLFifoFlush( fifo );
for ( ;; )
{
if ( _RGLFifoReadReference( fifo ) == 0 )
break;
sys_timer_usleep( 10 );
}
}
fifo->dmaPushBufferGPU = dmaPushBuffer;
fifo->spuid = 0;
}
static GLboolean _RGLInitFromRM( RGLResource *rmResource )
{
RGLState *RGLSt = &_RGLState;
RGLInterpolantState *s = &_RGLState.state.interpolant;
RGLBlendState *blend = &_RGLState.state.blend;
GLfloat ref;
GLuint i, hwColor;
ref = 0.0f;
memset( RGLSt, 0, sizeof( *RGLSt ) );
RGLSt->localAddress = rmResource->localAddress;
RGLSt->hostMemoryBase = rmResource->hostMemoryBase;
RGLSt->hostMemorySize = rmResource->hostMemorySize;
RGLSt->semaphores = rmResource->semaphores;
_RGLFifoInit( &RGLSt->fifo, rmResource->dmaControl, rmResource->dmaPushBufferOffset, ( uint32_t * )rmResource->dmaPushBuffer, rmResource->dmaPushBufferSize );
_RGLFifoFinish( &RGLSt->fifo );
RGL_CALC_COLOR_LE_ARGB8( &hwColor, RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f) );
blend->alphaFunc = CELL_GCM_ALWAYS;
blend->alphaRef = ref;
ref = RGL_CLAMPF_01( ref );
cellGcmSetAlphaFuncInline( &_RGLState.fifo, CELL_GCM_ALWAYS, RGL_QUICK_FLOAT2UINT( ref * 255.0f ));
cellGcmSetBlendColorInline( &_RGLState.fifo, hwColor, hwColor);
cellGcmSetBlendEquationInline( &_RGLState.fifo, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD );
cellGcmSetBlendFuncInline( &_RGLState.fifo, CELL_GCM_ONE, CELL_GCM_ZERO, CELL_GCM_ONE, CELL_GCM_ZERO );
cellGcmSetClearColorInline( &_RGLState.fifo, hwColor);
cellGcmSetAlphaTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetBlendEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetAlphaTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetBlendEnableMrtInline( &_RGLState.fifo, CELL_GCM_FALSE, CELL_GCM_FALSE, CELL_GCM_FALSE);
cellGcmSetLogicOpEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetCullFaceEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetCullFaceEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetDepthBoundsTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetDepthTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetPolygonOffsetFillEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetPolygonOffsetLineEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetRestartIndexEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetFragmentProgramGammaEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetScissorInline( &_RGLState.fifo, 0, 0, 4095, 4095);
cellGcmSetStencilTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetTwoSidedStencilTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetTwoSideLightEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetVertexAttribOutputMaskInline( &_RGLState.fifo, s->vertexProgramAttribMask & s->fragmentProgramAttribMask);
cellGcmSetPointSpriteControlInline( &_RGLState.fifo, CELL_GCM_FALSE, 1, 0);
cellGcmSetFrequencyDividerOperationInline( &_RGLState.fifo, 0);
cellGcmSetDitherEnableInline( &_RGLState.fifo, CELL_GCM_TRUE);
cellGcmSetRestartIndexInline( &_RGLState.fifo, 0);
cellGcmSetShadeModeInline( &_RGLState.fifo, CELL_GCM_SMOOTH);
for ( i = 0; i < CELL_GCM_MAX_TEXIMAGE_COUNT; i++ )
{
cellGcmSetTextureAddressInline( &_RGLState.fifo, i, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_WRAP, CELL_GCM_TEXTURE_CLAMP_TO_EDGE, CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL, CELL_GCM_TEXTURE_ZFUNC_NEVER, 0 );
cellGcmSetTextureFilterInline( &_RGLState.fifo, i, 0, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX );
cellGcmSetTextureControlInline( &_RGLState.fifo, i, CELL_GCM_TRUE, 0, 12 << 8, CELL_GCM_TEXTURE_MAX_ANISO_1 );
}
_RGLFifoGlViewport( 0, 0, CELL_GCM_MAX_RT_DIMENSION, CELL_GCM_MAX_RT_DIMENSION, 0.0f, 1.0f );
_RGLFifoFinish( &RGLSt->fifo );
return GL_TRUE;
}
GLboolean _RGLInit( PSGLinitOptions* options, RGLResource *resource )
{
if ( !_RGLInitFromRM( resource ) )
{
fprintf( stderr, "PSGL GCM failed initialisation" );
return GL_FALSE;
}
if ( gmmInit( resource->localAddress,
resource->localAddress,
resource->localSize,
resource->hostMemoryBase,
resource->hostMemoryBase + resource->hostMemoryReserved,
resource->hostMemorySize - resource->hostMemoryReserved ) == GMM_ERROR )
{
fprintf( stderr, "Could not init GPU memory manager" );
_RGLDestroy();
return GL_FALSE;
}
_RGLState.semaphores->userSemaphores[_RGL_SEMA_FENCE].val = nvFenceCounter;
_RGLState.labelValue = 1;
return GL_TRUE;
}
void _RGLDestroy( void )
{
RGLState *RGLSt = &_RGLState;
memset( RGLSt, 0, sizeof( *RGLSt ) );
}
static inline int rescIsEnabled( PSGLdeviceParameters* params )
{
return params->enable & ( PSGL_DEVICE_PARAMETERS_RESC_RENDER_WIDTH_HEIGHT |
PSGL_DEVICE_PARAMETERS_RESC_RATIO_MODE |
PSGL_DEVICE_PARAMETERS_RESC_PAL_TEMPORAL_MODE |
PSGL_DEVICE_PARAMETERS_RESC_INTERLACE_MODE |
PSGL_DEVICE_PARAMETERS_RESC_ADJUST_ASPECT_RATIO );
}
static inline const VideoMode *findModeByResolution( int width, int height )
{
for ( int i = 0;i < sysutilModeCount;++i )
{
const VideoMode *vm = sysutilModes + i;
if (( vm->width == width ) && ( vm->height == height ) ) return vm;
}
return NULL;
}
static const VideoMode *findModeByEnum( GLenum TVStandard )
{
const VideoMode *vm = NULL;
switch ( TVStandard )
{
case PSGL_TV_STANDARD_NTSC_M:
case PSGL_TV_STANDARD_NTSC_J:
case PSGL_TV_STANDARD_HD480P:
case PSGL_TV_STANDARD_HD480I:
vm = &(sysutilModes[0]);
break;
case PSGL_TV_STANDARD_PAL_M:
case PSGL_TV_STANDARD_PAL_B:
case PSGL_TV_STANDARD_PAL_D:
case PSGL_TV_STANDARD_PAL_G:
case PSGL_TV_STANDARD_PAL_H:
case PSGL_TV_STANDARD_PAL_I:
case PSGL_TV_STANDARD_PAL_N:
case PSGL_TV_STANDARD_PAL_NC:
case PSGL_TV_STANDARD_HD576I:
case PSGL_TV_STANDARD_HD576P:
vm = &(sysutilModes[1]);
break;
case PSGL_TV_STANDARD_HD720P:
case PSGL_TV_STANDARD_1280x720_ON_VESA_1280x768:
case PSGL_TV_STANDARD_1280x720_ON_VESA_1280x1024:
vm = &(sysutilModes[2]);
break;
case PSGL_TV_STANDARD_HD1080I:
case PSGL_TV_STANDARD_HD1080P:
case PSGL_TV_STANDARD_1920x1080_ON_VESA_1920x1200:
vm = &(sysutilModes[3]);
break;
default:
vm = &(sysutilModes[2]);
break;
}
return vm;
}
static VideoMode _sysutilDetectedVideoMode;
const VideoMode *_RGLDetectVideoMode (void)
{
CellVideoOutState videoState;
int ret = cellVideoOutGetState( CELL_VIDEO_OUT_PRIMARY, 0, &videoState );
if ( ret < 0 )
{
printf("RGL WARN: couldn't read the video configuration, using a default 720p resolution.\n");
videoState.displayMode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
videoState.displayMode.resolutionId = CELL_VIDEO_OUT_RESOLUTION_720;
}
CellVideoOutResolution resolution;
cellVideoOutGetResolution( videoState.displayMode.resolutionId, &resolution );
_sysutilDetectedVideoMode.width = resolution.width;
_sysutilDetectedVideoMode.height = resolution.height;
_sysutilDetectedVideoMode.hwMode = videoState.displayMode.resolutionId;
return &_sysutilDetectedVideoMode;
}
static void _RGLFlipCallbackFunction(const uint32_t head)
{
int res = sys_semaphore_post(FlipSem,1);
(void)res;
}
static void _RGLVblankCallbackFunction(const uint32_t head)
{
(void)head;
int status = *labelAddress;
switch(status)
{
case 2:
if (cellGcmGetFlipStatus()==0)
{
cellGcmResetFlipStatus();
*labelAddress=1;
}
break;
case 1:
*labelAddress = 0;
break;
default:
break;
}
}
static void _RGLRescVblankCallbackFunction(const uint32_t head)
{
(void)head;
int status = *labelAddress;
switch(status)
{
case 2:
if (cellRescGetFlipStatus()==0)
{
cellRescResetFlipStatus();
*labelAddress=1;
}
break;
case 1:
*labelAddress = 0;
break;
default:
break;
}
}
static unsigned int findValidPitch( unsigned int pitch )
{
if ( pitch <= validPitch[0] ) return validPitch[0];
else
{
for ( GLuint i = 0;i < validPitchCount - 1;++i )
{
if (( pitch > validPitch[i] ) && ( pitch <= validPitch[i+1] ) ) return validPitch[i+1];
}
return validPitch[validPitchCount-1];
}
}
int32_t _RGLOutOfSpaceCallback( struct CellGcmContextData* fifoContext, uint32_t spaceInWords )
{
uint32_t *nextbegin, *nextend, nextbeginoffset, nextendoffset;
RGLFifo * fifo = &_RGLState.fifo;
cellGcmFlushUnsafeInline((CellGcmContextData*)fifo);
uint32_t * tmp = ( uint32_t * )(( char* )fifo->dmaPushBufferBegin - fifo->dmaPushBufferOffset + ( *(( volatile GLuint* ) & fifo->dmaControl->Get ) ) );
if (( tmp >= fifo->begin ) && ( tmp <= fifo->end ) ) fifo->lastGetRead = tmp;
if(fifo->end != fifo->dmaPushBufferEnd)
{
nextbegin = (uint32_t *)fifo->end + 1;
nextend = nextbegin + fifo->fifoBlockSize/sizeof(uint32_t) - 1;
}
else
{
nextbegin = (uint32_t *)fifo->dmaPushBufferBegin;
nextend = nextbegin + (fifo->fifoBlockSize)/sizeof(uint32_t) - 1;
}
cellGcmAddressToOffset(nextbegin, &nextbeginoffset);
cellGcmAddressToOffset(nextend, &nextendoffset);
cellGcmSetJumpCommandUnsafeInline((CellGcmContextData*)fifo, nextbeginoffset);
fifo->begin = nextbegin;
fifo->current = nextbegin;
fifo->end = nextend;
const GLuint nopsAtBegin = 8;
uint32_t get = fifo->dmaControl->Get;
while(((get >= nextbeginoffset) && (get <= nextendoffset))
|| (get < fifo->dmaPushBufferOffset) || (get > fifo->dmaPushBufferOffset +
fifo->dmaPushBufferSizeInWords*sizeof(uint32_t)))
{
sys_timer_usleep(30);
get = fifo->dmaControl->Get;
}
for ( GLuint i = 0; i < nopsAtBegin; i++ )
{
fifo->current[0] = RGL_NOP;
fifo->current++;
}
return CELL_OK;
};
void _RGLGraphicsHandler( const uint32_t head )
{
RGLFifo *fifo = &_RGLState.fifo;
uint32_t *tmp = ( uint32_t * )(( char* )fifo->dmaPushBufferBegin - fifo->dmaPushBufferOffset + ( *(( volatile GLuint* ) & fifo->dmaControl->Get ) ) );
if (( tmp >= fifo->begin ) && ( tmp <= fifo->end ) ) fifo->lastGetRead = tmp;
printf("RGL: Current PSGL FIFO info \n" );
printf("RGL: Fifo Begin %p End %p Current %p and Get %p \n",
_RGLState.fifo.begin, _RGLState.fifo.end, _RGLState.fifo.current,
_RGLState.fifo.lastGetRead );
printf("RGL: Last 10 words of the PSGL Fifo from the ppu put/current position \n" );
_RGLPrintFifoFromPut( 10 );
printf("RGL: Last 10 words of the PSGL Fifo from the gpu get position \n" );
_RGLPrintFifoFromGet( 10 );
}
static int _RGLInitRM( RGLResource *gcmResource, unsigned int hostMemorySize, int inSysMem, unsigned int dmaPushBufferSize )
{
memset( gcmResource, 0, sizeof( RGLResource ) );
const unsigned int iDPM2DataAreaSize = 0;
dmaPushBufferSize = _RGLPad( dmaPushBufferSize, _RGL_HOST_BUFFER_ALIGNMENT );
gcmResource->hostMemorySize = _RGLPad( _RGL_FIFO_SIZE + hostMemorySize + dmaPushBufferSize + _RGL_DMA_PUSH_BUFFER_PREFETCH_PADDING + iDPM2DataAreaSize + (RGL_LM_MAX_TOTAL_QUERIES * sizeof( GLuint )), 1 << 20 );
if ( gcmResource->hostMemorySize > 0 )
gcmResource->hostMemoryBase = ( char * )memalign( 1 << 20, gcmResource->hostMemorySize );
if ( cellGcmInit( _RGL_FIFO_SIZE, gcmResource->hostMemorySize, gcmResource->hostMemoryBase ) != 0 )
{
printf("RGL: RSXIF failed initialization\n" );
return GL_FALSE;
}
cellGcmSetDebugOutputLevel( CELL_GCM_DEBUG_LEVEL2 );
cellGcmSetGraphicsHandler( &_RGLGraphicsHandler );
CellGcmConfig config;
cellGcmGetConfiguration( &config );
gcmResource->localAddress = ( char * )config.localAddress;
gcmResource->localSize = config.localSize;
gcmResource->MemoryClock = config.memoryFrequency;
gcmResource->GraphicsClock = config.coreFrequency;
gcmResource->semaphores = ( RGLSemaphoreMemory * )cellGcmGetLabelAddress( 0 );
gcmResource->dmaControl = ( char* ) cellGcmGetControlRegister() - (( char * ) & (( RGLControlDma* )0 )->Put - ( char * )0 );
cellGcmFinish( 1 );
gcmResource->hostMemorySize -= dmaPushBufferSize + _RGL_DMA_PUSH_BUFFER_PREFETCH_PADDING;
gcmResource->dmaPushBuffer = gcmResource->hostMemoryBase + gcmResource->hostMemorySize;
gcmResource->dmaPushBufferOffset = ( char * )gcmResource->dmaPushBuffer - ( char * )gcmResource->hostMemoryBase;
gcmResource->dmaPushBufferSize = dmaPushBufferSize;
gcmResource->hostMemoryReserved = _RGL_FIFO_SIZE;
cellGcmSetJumpCommand(( char * )gcmResource->dmaPushBuffer - ( char * )gcmResource->hostMemoryBase );
gCellGcmCurrentContext->callback = ( CellGcmContextCallback )_RGLOutOfSpaceCallback;
printf( "RGL: MClk: %f Mhz NVClk: %f Mhz\n", ( float )gcmResource->MemoryClock / 1E6, ( float )gcmResource->GraphicsClock / 1E6 );
printf( "RGL: Video Memory: %i MB\n", gcmResource->localSize / ( 1024*1024 ) );
printf( "RGL: localAddress mapped at %p\n", gcmResource->localAddress );
printf( "RGL: push buffer at %p - %p (size = 0x%X), offset=0x%lx\n",
gcmResource->dmaPushBuffer, ( char* )gcmResource->dmaPushBuffer + gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferOffset );
printf( "RGL: dma control at %p\n", gcmResource->dmaControl );
return 1;
}
void _RGLDeviceInit( PSGLinitOptions* options )
{
GLuint fifoSize = _RGL_FIFO_SIZE_DEFAULT;
GLuint hostSize = _RGL_HOST_SIZE_DEFAULT;
if ( options != NULL )
{
if ( options->enable & PSGL_INIT_FIFO_SIZE )
fifoSize = options->fifoSize;
if ( options->enable & PSGL_INIT_HOST_MEMORY_SIZE )
hostSize = options->hostMemorySize;
}
if ( !_RGLInitRM( &_RGLResource, hostSize, 0, fifoSize ) )
{
printf("RGL: RM resource failed initialisation\n" );
return;
}
bool retval = _RGLInit( options, &_RGLResource );
(void)retval;
}
static void _RGLDestroyRM( RGLResource* gcmResource )
{
if ( gcmResource->hostMemoryBase )
free( gcmResource->hostMemoryBase );
memset(( void* )gcmResource, 0, sizeof( RGLResource ) );
return;
}
void _RGLDeviceExit()
{
_RGLDestroy();
_RGLDestroyRM( &_RGLResource );
}
static GLuint _RGLAllocCreateRegion(GLuint size, GLint tag, void* data )
{
uint32_t id = gmmAlloc(1, size);
if ( id != GMM_ERROR )
{
if ( _RGLTryResizeTileRegion( (GLuint)gmmIdToOffset(id), ((GmmBaseBlock *)id)->size, data ) )
gmmSetTileAttrib( id, tag, data );
else
{
gmmFree( id );
id = GMM_ERROR;
}
}
return id;
}
GLboolean _RGLAllocateColorSurface(
GLuint width,
GLuint height,
GLuint bitsPerPixel,
GLuint *id,
GLuint *pitchAllocated,
GLuint *bytesAllocated )
{
jsTiledMemoryManager* mm = &_RGLTiledMemoryManager;
const unsigned int pitch = width * bitsPerPixel / 8;
const unsigned int tiledPitch = findValidPitch( pitch );
if ( tiledPitch < pitch )
*pitchAllocated = _RGLPad( pitch, tiledPitch );
else
*pitchAllocated = tiledPitch;
GLuint padSize = _RGL_TILED_BUFFER_ALIGNMENT;
while (( padSize % ( tiledPitch*8 ) ) != 0 )
padSize += _RGL_TILED_BUFFER_ALIGNMENT;
height = _RGLPad( height, _RGL_TILED_BUFFER_HEIGHT_ALIGNMENT );
*bytesAllocated = _RGLPad(( *pitchAllocated ) * height, padSize );
const GLuint tag = *pitchAllocated | ( 0x0 );
*id = gmmAllocExtendedTileBlock(*bytesAllocated, tag);
if ( *id == GMM_ERROR )
{
for ( int i = 0; i < _RGL_MAX_TILED_REGIONS; ++i )
{
if ( mm->region[i].size == 0 )
{
mm->region[i].id = i;
mm->region[i].pitch = *pitchAllocated;
mm->region[i].bank = 0x0;
*id = _RGLAllocCreateRegion(*bytesAllocated, tag, &mm->region[i] );
break;
}
}
}
if ( *id == GMM_ERROR )
{
*bytesAllocated = 0;
*pitchAllocated = 0;
}
else
printf("RGL: Allocating GPU memory (tiled): %d bytes allocated at id 0x%08x.\n", *bytesAllocated, *id );
return *bytesAllocated > 0;
}
PSGLdevice* psglCreateDeviceAuto( GLenum colorFormat, GLenum depthFormat, GLenum multisamplingMode )
{
PSGLdeviceParameters parameters;
parameters.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT | PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT | PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE;
parameters.colorFormat = colorFormat;
parameters.depthFormat = GL_NONE;
parameters.multisamplingMode = GL_MULTISAMPLING_NONE_SCE;
return psglCreateDeviceExtended( &parameters );
}
static void rescInit( const PSGLdeviceParameters* params, RGLDevice *gcmDevice )
{
printf("RGL WARN: RESC is enabled.\n");
GLboolean result = 0;
CellRescBufferMode dstBufferMode;
if ( params->width == 720 && params->height == 480 ) dstBufferMode = CELL_RESC_720x480;
else if ( params->width == 720 && params->height == 576 ) dstBufferMode = CELL_RESC_720x576;
else if ( params->width == 1280 && params->height == 720 ) dstBufferMode = CELL_RESC_1280x720;
else if ( params->width == 1920 && params->height == 1080 ) dstBufferMode = CELL_RESC_1920x1080;
else
{
dstBufferMode = CELL_RESC_720x480;
printf("RGL: Invalid display resolution for resolution conversion: %ux%u. Defaulting to 720x480...\n", params->width, params->height );
}
CellRescInitConfig conf;
memset( &conf, 0, sizeof( CellRescInitConfig ) );
conf.size = sizeof( CellRescInitConfig );
conf.resourcePolicy = CELL_RESC_MINIMUM_GPU_LOAD | CELL_RESC_CONSTANT_VRAM;
conf.supportModes = CELL_RESC_720x480 | CELL_RESC_720x576 | CELL_RESC_1280x720 | CELL_RESC_1920x1080;
conf.ratioMode = ( params->rescRatioMode == RESC_RATIO_MODE_FULLSCREEN ) ? CELL_RESC_FULLSCREEN :
( params->rescRatioMode == RESC_RATIO_MODE_PANSCAN ) ? CELL_RESC_PANSCAN : CELL_RESC_LETTERBOX;
conf.palTemporalMode = ( params->rescPalTemporalMode == RESC_PAL_TEMPORAL_MODE_60_DROP ) ? CELL_RESC_PAL_60_DROP :
( params->rescPalTemporalMode == RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE ) ? CELL_RESC_PAL_60_INTERPOLATE :
( params->rescPalTemporalMode == RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_30_DROP ) ? CELL_RESC_PAL_60_INTERPOLATE_30_DROP :
( params->rescPalTemporalMode == RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_DROP_FLEXIBLE ) ? CELL_RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE : CELL_RESC_PAL_50;
conf.interlaceMode = ( params->rescInterlaceMode == RESC_INTERLACE_MODE_INTERLACE_FILTER ) ? CELL_RESC_INTERLACE_FILTER : CELL_RESC_NORMAL_BILINEAR;
cellRescInit( &conf );
GLuint size;
GLuint colorBuffersPitch;
uint32_t numColorBuffers = cellRescGetNumColorBuffers( dstBufferMode, ( CellRescPalTemporalMode )conf.palTemporalMode, 0 );
result = _RGLAllocateColorSurface( params->width, params->height * numColorBuffers,
4*8, &(gcmDevice->RescColorBuffersId), &colorBuffersPitch, &size );
CellRescDsts dsts = { CELL_RESC_SURFACE_A8R8G8B8, colorBuffersPitch, 1 };
cellRescSetDsts( dstBufferMode, &dsts );
cellRescSetDisplayMode( dstBufferMode );
int32_t colorBuffersSize, vertexArraySize, fragmentShaderSize;
cellRescGetBufferSize( &colorBuffersSize, &vertexArraySize, &fragmentShaderSize );
gcmDevice->RescVertexArrayId = gmmAlloc(0, vertexArraySize);
gcmDevice->RescFragmentShaderId = gmmAlloc(0, fragmentShaderSize);
cellRescSetBufferAddress( gmmIdToAddress(gcmDevice->RescColorBuffersId),
gmmIdToAddress(gcmDevice->RescVertexArrayId),
gmmIdToAddress(gcmDevice->RescFragmentShaderId) );
cellRescAdjustAspectRatio( params->horizontalScale, params->verticalScale );
if ((params->enable & PSGL_DEVICE_PARAMETERS_RESC_INTERLACE_MODE) &&
(params->rescInterlaceMode == RESC_INTERLACE_MODE_INTERLACE_FILTER))
{
const unsigned int tableLength = 32;
unsigned int tableSize = sizeof(uint16_t) * 4 * tableLength;
void *interlaceTable = gmmIdToAddress(gmmAlloc(0, tableSize));
int32_t errorCode = cellRescCreateInterlaceTable(interlaceTable,params->renderHeight,CELL_RESC_ELEMENT_HALF,tableLength);
(void)errorCode;
}
}
static void _RGLSetDisplayMode( const VideoMode *vm, GLushort bitsPerPixel, GLuint pitch )
{
CellVideoOutConfiguration videocfg;
memset( &videocfg, 0, sizeof( videocfg ) );
videocfg.resolutionId = vm->hwMode;
videocfg.format = ( bitsPerPixel == 32 ) ? CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8 : CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT;
videocfg.pitch = pitch;
videocfg.aspect = CELL_VIDEO_OUT_ASPECT_AUTO;
cellVideoOutConfigure( CELL_VIDEO_OUT_PRIMARY, &videocfg, NULL, 0 );
}
static int _RGLPlatformCreateDevice( PSGLdevice* device )
{
RGLDevice *gcmDevice = ( RGLDevice * )device->platformDevice;
PSGLdeviceParameters* params = &device->deviceParameters;
jsTiledMemoryManager* mm = &_RGLTiledMemoryManager;
_RGLDuringDestroyDevice = GL_FALSE;
GLboolean result = 0;
int32_t retVal;
memset( mm->region, 0, sizeof( mm->region ) );
for ( int i = 0;i < _RGL_MAX_TILED_REGIONS;++i )
retVal = cellGcmUnbindTile( i );
const VideoMode *vm = NULL;
if ( params->enable & PSGL_DEVICE_PARAMETERS_TV_STANDARD )
{
vm = findModeByEnum( params->TVStandard );
if ( !vm ) return -1;
params->width = vm->width;
params->height = vm->height;
}
else if ( params->enable & PSGL_DEVICE_PARAMETERS_WIDTH_HEIGHT )
{
vm = findModeByResolution( params->width, params->height );
if ( !vm ) return -1;
}
else
{
vm = _RGLDetectVideoMode();
if ( !vm ) return -1;
params->width = vm->width;
params->height = vm->height;
}
if ( !(params->enable & PSGL_DEVICE_PARAMETERS_RESC_RENDER_WIDTH_HEIGHT) )
{
params->renderWidth = params->width;
params->renderHeight = params->height;
}
if ( rescIsEnabled( params ) )
rescInit( params, gcmDevice );
gcmDevice->deviceType = 0;
gcmDevice->TVStandard = params->TVStandard;
gcmDevice->vsync = rescIsEnabled( params ) ? GL_TRUE : GL_FALSE;
gcmDevice->ms = NULL;
const GLuint width = params->renderWidth;
const GLuint height = params->renderHeight;
for ( int i = 0; i < params->bufferingMode; ++i )
{
gcmDevice->color[i].source = _RGL_SURFACE_SOURCE_DEVICE;
gcmDevice->color[i].width = width;
gcmDevice->color[i].height = height;
gcmDevice->color[i].bpp = 4;
gcmDevice->color[i].format = RGL_ARGB8;
gcmDevice->color[i].pool = _RGL_SURFACE_POOL_LINEAR;
GLuint size;
result = _RGLAllocateColorSurface(width, height,
gcmDevice->color[i].bpp*8, &gcmDevice->color[i].dataId,
&gcmDevice->color[i].pitch, &size );
}
memset( &gcmDevice->rt, 0, sizeof( RGLRenderTargetEx ) );
gcmDevice->rt.colorBufferCount = 1;
gcmDevice->rt.yInverted = GL_TRUE;
gcmDevice->rt.width = width;
gcmDevice->rt.height = height;
_RGLFifoGlViewport( 0, 0, width, height );
GLuint hwColor;
RGL_CALC_COLOR_LE_ARGB8( &hwColor, RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f), RGL_CLAMPF_01(0.0f) );
cellGcmSetClearColorInline( &_RGLState.fifo, hwColor);
gcmDevice->rt.colorFormat = RGL_ARGB8;
for ( int i = 0; i < params->bufferingMode; ++i )
{
gcmDevice->rt.colorId[0] = gcmDevice->color[i].dataId;
gcmDevice->rt.colorPitch[0] = gcmDevice->color[i].pitch;
_RGLFifoGlSetRenderTarget( &gcmDevice->rt );
cellGcmSetClearSurfaceInline ( &_RGLState.fifo, CELL_GCM_CLEAR_R | CELL_GCM_CLEAR_G | CELL_GCM_CLEAR_B | CELL_GCM_CLEAR_A);
}
gcmDevice->scanBuffer = 0;
if ( params->bufferingMode == PSGL_BUFFERING_MODE_SINGLE )
gcmDevice->drawBuffer = 0;
else if ( params->bufferingMode == PSGL_BUFFERING_MODE_DOUBLE )
gcmDevice->drawBuffer = 1;
else if ( params->bufferingMode == PSGL_BUFFERING_MODE_TRIPLE )
gcmDevice->drawBuffer = 2;
sys_semaphore_attribute_t attr;
sys_semaphore_attribute_initialize(attr);
sys_semaphore_value_t initial_val = 0;
sys_semaphore_value_t max_val = 1;
switch (device->deviceParameters.bufferingMode)
{
case PSGL_BUFFERING_MODE_SINGLE:
initial_val = 0;
max_val = 1;
break;
case PSGL_BUFFERING_MODE_DOUBLE:
initial_val = 1;
max_val = 2;
break;
case PSGL_BUFFERING_MODE_TRIPLE:
initial_val = 2;
max_val = 3;
break;
default:
break;
}
int res = sys_semaphore_create(&FlipSem, &attr, initial_val, max_val);
(void)res;
if ( rescIsEnabled( params ) )
cellRescSetFlipHandler(_RGLFlipCallbackFunction);
else
cellGcmSetFlipHandler(_RGLFlipCallbackFunction);
labelAddress = (volatile uint32_t *)cellGcmGetLabelAddress(WaitLabelIndex);
*labelAddress = 0;
if ( rescIsEnabled( params ) )
cellRescSetVBlankHandler(_RGLRescVblankCallbackFunction);
else
cellGcmSetVBlankHandler(_RGLVblankCallbackFunction);
if ( rescIsEnabled( params ) )
{
for ( int i = 0; i < params->bufferingMode; ++i )
{
CellRescSrc rescSrc;
rescSrc.format = CELL_GCM_TEXTURE_A8R8G8B8 | CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_NR;
rescSrc.pitch = gcmDevice->color[i].pitch;
rescSrc.width = width;
rescSrc.height = height;
rescSrc.offset = gmmIdToOffset( gcmDevice->color[i].dataId );
if ( cellRescSetSrc( i, &rescSrc ) != CELL_OK )
{
printf("RGL: Registering display buffer %d failed\n", i );
return -1;
}
}
}
else
{
_RGLSetDisplayMode( vm, gcmDevice->color[0].bpp*8, gcmDevice->color[0].pitch );
cellGcmSetFlipMode( gcmDevice->vsync ? CELL_GCM_DISPLAY_VSYNC : CELL_GCM_DISPLAY_HSYNC );
cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo);
_RGLFifoFinish( &_RGLState.fifo );
for ( int i = 0; i < params->bufferingMode; ++i )
{
if ( cellGcmSetDisplayBuffer( i, gmmIdToOffset( gcmDevice->color[i].dataId ), gcmDevice->color[i].pitch , width, height ) != CELL_OK )
{
printf("RGL: Registering display buffer %d failed\n", i );
return -1;
}
}
}
gcmDevice->swapFifoRef = _RGLFifoPutReference( &_RGLState.fifo );
gcmDevice->swapFifoRef2 = gcmDevice->swapFifoRef;
return 0;
}
PSGLdevice* psglCreateDeviceExtended( const PSGLdeviceParameters *parameters )
{
PSGLdevice *device = ( PSGLdevice * )malloc( sizeof( PSGLdevice ) + sizeof(RGLDevice) );
if ( !device )
{
_RGLSetError( GL_OUT_OF_MEMORY );
return NULL;
}
memset( device, 0, sizeof( PSGLdevice ) + sizeof(RGLDevice) );
PSGLdeviceParameters defaultParameters;
defaultParameters.enable = 0;
defaultParameters.colorFormat = GL_ARGB_SCE;
defaultParameters.depthFormat = GL_NONE;
defaultParameters.multisamplingMode = GL_MULTISAMPLING_NONE_SCE;
defaultParameters.TVStandard = PSGL_TV_STANDARD_NONE;
defaultParameters.connector = PSGL_DEVICE_CONNECTOR_NONE;
defaultParameters.bufferingMode = PSGL_BUFFERING_MODE_DOUBLE;
defaultParameters.width = 0;
defaultParameters.height = 0;
defaultParameters.renderWidth = 0;
defaultParameters.renderHeight = 0;
defaultParameters.rescRatioMode = RESC_RATIO_MODE_LETTERBOX;
defaultParameters.rescPalTemporalMode = RESC_PAL_TEMPORAL_MODE_50_NONE;
defaultParameters.rescInterlaceMode = RESC_INTERLACE_MODE_NORMAL_BILINEAR;
defaultParameters.horizontalScale = 1.0f;
defaultParameters.verticalScale = 1.0f;
memcpy( &device->deviceParameters, parameters, sizeof( PSGLdeviceParameters ) );
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_COLOR_FORMAT ) == 0 )
device->deviceParameters.colorFormat = defaultParameters.colorFormat;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_TV_STANDARD ) == 0 )
device->deviceParameters.TVStandard = defaultParameters.TVStandard;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_CONNECTOR ) == 0 )
device->deviceParameters.connector = defaultParameters.connector;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_BUFFERING_MODE ) == 0 )
device->deviceParameters.bufferingMode = defaultParameters.bufferingMode;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_WIDTH_HEIGHT ) == 0 )
{
device->deviceParameters.width = defaultParameters.width;
device->deviceParameters.height = defaultParameters.height;
}
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_RESC_RENDER_WIDTH_HEIGHT ) == 0 )
{
device->deviceParameters.renderWidth = defaultParameters.renderWidth;
device->deviceParameters.renderHeight = defaultParameters.renderHeight;
}
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_RESC_RATIO_MODE ) == 0 )
device->deviceParameters.rescRatioMode = defaultParameters.rescRatioMode;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_RESC_PAL_TEMPORAL_MODE ) == 0 )
device->deviceParameters.rescPalTemporalMode = defaultParameters.rescPalTemporalMode;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_RESC_INTERLACE_MODE ) == 0 )
device->deviceParameters.rescInterlaceMode = defaultParameters.rescInterlaceMode;
if (( parameters->enable & PSGL_DEVICE_PARAMETERS_RESC_ADJUST_ASPECT_RATIO ) == 0 )
{
device->deviceParameters.horizontalScale = defaultParameters.horizontalScale;
device->deviceParameters.verticalScale = defaultParameters.verticalScale;
}
device->rasterDriver = NULL;
int result = _RGLPlatformCreateDevice( device );
if ( result < 0 )
{
if(device != NULL)
free( device );
return NULL;
}
return device;
}
GLfloat psglGetDeviceAspectRatio( const PSGLdevice * device )
{
CellVideoOutState videoState;
cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState);
switch (videoState.displayMode.aspect)
{
case CELL_VIDEO_OUT_ASPECT_4_3:
return 4.0f/3.0f;
case CELL_VIDEO_OUT_ASPECT_16_9:
return 16.0f/9.0f;
}
return 16.0f/9.0f;
}
void psglGetDeviceDimensions( const PSGLdevice * device, GLuint *width, GLuint *height )
{
*width = device->deviceParameters.width;
*height = device->deviceParameters.height;
}
void psglGetRenderBufferDimensions( const PSGLdevice * device, GLuint *width, GLuint *height )
{
*width = device->deviceParameters.renderWidth;
*height = device->deviceParameters.renderHeight;
}
void psglDestroyDevice( PSGLdevice *device )
{
if ( _CurrentDevice == device ) psglMakeCurrent( NULL, NULL );
if ( device->rasterDriver )
free( device->rasterDriver );
RGLDevice *gcmDevice = ( RGLDevice * )device->platformDevice;
PSGLdeviceParameters* params = &device->deviceParameters;
cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo);
_RGLFifoFinish( &_RGLState.fifo );
if ( rescIsEnabled( params ) )
cellRescSetFlipHandler(NULL);
else
cellGcmSetFlipHandler(NULL);
if ( rescIsEnabled( &device->deviceParameters ) )
cellRescSetVBlankHandler(NULL);
else
cellGcmSetVBlankHandler(NULL);
int res = sys_semaphore_destroy(FlipSem);
(void)res;
if ( rescIsEnabled( params ) )
{
cellRescExit();
gmmFree(gcmDevice->RescColorBuffersId);
gmmFree(gcmDevice->RescVertexArrayId);
gmmFree(gcmDevice->RescFragmentShaderId);
}
_RGLDuringDestroyDevice = GL_TRUE;
for ( int i = 0; i < params->bufferingMode; ++i )
{
if ( gcmDevice->color[i].pool != _RGL_SURFACE_POOL_NONE )
gmmFree( gcmDevice->color[i].dataId );
}
_RGLDuringDestroyDevice = GL_FALSE;
if(device != NULL)
free( device );
}
static void *_RGLPlatformRasterInit (void)
{
RGLDriver *driver = ( RGLDriver * )malloc( sizeof( RGLDriver ) );
cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo);
_RGLFifoFinish( &_RGLState.fifo );
memset( driver, 0, sizeof( RGLDriver ) );
driver->rt.yInverted = CELL_GCM_TRUE;
driver->invalidateVertexCache = GL_FALSE;
driver->flushBufferCount = 0;
driver->colorBufferMask = 0x1;
return driver;
}
void psglMakeCurrent( PSGLcontext *context, PSGLdevice *device )
{
if ( context && device )
{
_CurrentContext = context;
_CurrentDevice = device;
if ( !device->rasterDriver )
device->rasterDriver = _RGLPlatformRasterInit();
_RGLAttachContext( device, context );
}
else
{
_CurrentContext = NULL;
_CurrentDevice = NULL;
}
}
PSGLdevice *psglGetCurrentDevice()
{
return _CurrentDevice;
}
extern void gmmUpdateFreeList (const uint8_t location);
GLAPI void psglSwap( void )
{
PSGLcontext *LContext = _CurrentContext;
PSGLdevice *device = _CurrentDevice;
RGLFifo *fifo = &_RGLState.fifo;
gmmUpdateFreeList(CELL_GCM_LOCATION_LOCAL);
gmmUpdateFreeList(CELL_GCM_LOCATION_MAIN);
RGLDevice *gcmDevice = ( RGLDevice * )device->platformDevice;
const GLuint drawBuffer = gcmDevice->drawBuffer;
GLboolean vsync = _CurrentContext->VSync;
if ( vsync != gcmDevice->vsync )
{
if ( ! rescIsEnabled( &device->deviceParameters ) )
{
cellGcmSetFlipMode( vsync ? CELL_GCM_DISPLAY_VSYNC : CELL_GCM_DISPLAY_HSYNC );
gcmDevice->vsync = vsync;
}
}
if ( device->deviceParameters.bufferingMode == PSGL_BUFFERING_MODE_TRIPLE )
{
if ( rescIsEnabled( &device->deviceParameters ) )
cellRescSetWaitFlip();
else
cellGcmSetWaitFlip();
}
if ( rescIsEnabled( &device->deviceParameters ) )
{
int32_t res = cellRescSetConvertAndFlip(( uint8_t ) drawBuffer );
if ( res != CELL_OK )
{
printf("RGL WARN: RESC cellRescSetConvertAndFlip returned error code %d.\n", res);
if ( _CurrentContext ) _CurrentContext->needValidate |= PSGL_VALIDATE_FRAMEBUFFER;
return;
}
}
else
cellGcmSetFlip(( uint8_t ) drawBuffer );
if ( device->deviceParameters.bufferingMode != PSGL_BUFFERING_MODE_TRIPLE )
{
if ( rescIsEnabled( &device->deviceParameters ) )
cellRescSetWaitFlip();
else
cellGcmSetWaitFlip();
}
cellGcmSetPolySmoothEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetLineStippleEnableInline( &_RGLState.fifo, CELL_GCM_FALSE );
cellGcmSetPolygonStippleEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetDepthBoundsTestEnable( &_RGLState.fifo, CELL_GCM_FALSE);
cellGcmSetDitherEnableInline( &_RGLState.fifo, CELL_GCM_FALSE);
LContext->needValidate = PSGL_VALIDATE_ALL;
for ( int unit = 0;unit < _RGL_MAX_TEXTURE_UNITS;unit++ )
LContext->TextureCoordsUnits[unit].TextureMatrixStack.dirty = GL_TRUE;
LContext->ModelViewMatrixStack.dirty = GL_TRUE;
LContext->ProjectionMatrixStack.dirty = GL_TRUE;
LContext->attribs->DirtyMask = ( 1 << _RGL_MAX_VERTEX_ATTRIBS ) - 1;
cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo);
_RGLFifoFlush( fifo );
while(sys_semaphore_wait(FlipSem, 1000) != CELL_OK);
cellGcmSetInvalidateVertexCacheInline( &_RGLState.fifo);
_RGLFifoFlush( fifo );
if ( device->deviceParameters.bufferingMode == PSGL_BUFFERING_MODE_DOUBLE )
{
gcmDevice->drawBuffer = gcmDevice->scanBuffer;
gcmDevice->scanBuffer = drawBuffer;
gcmDevice->rt.colorId[0] = gcmDevice->color[gcmDevice->drawBuffer].dataId;
gcmDevice->rt.colorPitch[0] = gcmDevice->color[gcmDevice->drawBuffer].pitch;
}
else if ( device->deviceParameters.bufferingMode == PSGL_BUFFERING_MODE_TRIPLE )
{
gcmDevice->drawBuffer = gcmDevice->scanBuffer;
if ( gcmDevice->scanBuffer == 2 )
gcmDevice->scanBuffer = 0;
else
gcmDevice->scanBuffer++;
gcmDevice->rt.colorId[0] = gcmDevice->color[gcmDevice->drawBuffer].dataId;
gcmDevice->rt.colorPitch[0] = gcmDevice->color[gcmDevice->drawBuffer].pitch;
}
}
static inline void _RGLUtilWaitForIdle (void)
{
cellGcmSetWriteBackEndLabelInline( &_RGLState.fifo, RGL_UTIL_LABEL_INDEX, _RGLState.labelValue);
cellGcmSetWaitLabelInline( &_RGLState.fifo, RGL_UTIL_LABEL_INDEX, _RGLState.labelValue);
_RGLState.labelValue++;
cellGcmSetWriteBackEndLabelInline( &_RGLState.fifo, RGL_UTIL_LABEL_INDEX, _RGLState.labelValue);
cellGcmFlush();
while( *(cellGcmGetLabelAddress( RGL_UTIL_LABEL_INDEX)) != _RGLState.labelValue)
sys_timer_usleep(30);
_RGLState.labelValue++;
}
GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data )
{
jsTiledRegion* region = ( jsTiledRegion* )data;
int32_t retVal = 0;
if ( size == 0 )
{
region->offset = 0;
region->size = 0;
region->pitch = 0;
if ( ! _RGLDuringDestroyDevice )
{
_RGLUtilWaitForIdle();
retVal = cellGcmUnbindTile( region->id );
_RGLFifoFinish( &_RGLState.fifo );
}
return GL_TRUE;
}
region->offset = address;
region->size = size;
_RGLUtilWaitForIdle();
retVal = cellGcmSetTileInfo(region->id, CELL_GCM_LOCATION_LOCAL,
region->offset, region->size, region->pitch, CELL_GCM_COMPMODE_DISABLED, 0,
region->bank );
retVal = cellGcmBindTile( region->id );
_RGLFifoFinish( &_RGLState.fifo );
return GL_TRUE;
}
void _RGLGetTileRegionInfo( void* data, GLuint *address, GLuint *size )
{
jsTiledRegion* region = ( jsTiledRegion* )data;
*address = region->offset;
*size = region->size;
}