diff --git a/ps3/rgl/src/ps3/include/rgl-externs.h b/ps3/rgl/src/ps3/include/rgl-externs.h index bf415220e8..26ab71fb2d 100644 --- a/ps3/rgl/src/ps3/include/rgl-externs.h +++ b/ps3/rgl/src/ps3/include/rgl-externs.h @@ -1,7 +1,5 @@ -void rglGcmFifoFinish (void *data); GLboolean rglGcmFifoReferenceInUse (void *data, GLuint reference); GLuint rglGcmFifoPutReference (void *data); -void rglGcmFifoFlush (void *data); void rglGcmGetTileRegionInfo (void *data, GLuint *address, GLuint *size); GLboolean rglGcmTryResizeTileRegion( GLuint address, GLuint size, void *data); diff --git a/ps3/rgl/src/ps3/include/rgl-inline.h b/ps3/rgl/src/ps3/include/rgl-inline.h index 110fbdc9e5..cd61e8a623 100644 --- a/ps3/rgl/src/ps3/include/rgl-inline.h +++ b/ps3/rgl/src/ps3/include/rgl-inline.h @@ -224,6 +224,73 @@ static inline GLuint rglPlatformGetBitsPerPixel (GLenum internalFormat) (thisContext->current)[1] = ((enable) | ((alphaToCoverage) << 4) | ((alphaToOne) << 8) | ((sampleMask) << 16)); \ (thisContext->current) += 2; +#define rglGcmFifoFinish(ref, offset_bytes) \ + ref = rglGcmFifoPutReference( fifo ); \ + rglGcmFifoFlush( fifo, offset_bytes ); \ + while (rglGcmFifoReferenceInUse(fifo, ref)) \ + sys_timer_usleep(10); + +#define rglGcmFifoReadReference(fifo) (fifo->lastHWReferenceRead = *((volatile GLuint *)&fifo->dmaControl->Reference)) + +#define rglGcmFifoFlush(fifo, offsetInBytes) \ + cellGcmAddressToOffset( fifo->current, ( uint32_t * )&offsetInBytes ); \ + cellGcmFlush(); \ + fifo->dmaControl->Put = offsetInBytes; \ + fifo->lastPutWritten = fifo->current; \ + fifo->lastSWReferenceFlushed = fifo->lastSWReferenceWritten; + +static inline void rglGcmSetFragmentProgramLoad(struct CellGcmContextData *thisContext, const CellCgbFragmentProgramConfiguration *conf, const uint32_t location) +{ + uint32_t rawData = ((conf->offset)&0x1fffffff); + uint32_t shCtrl0; + uint32_t registerCount; + uint32_t texMask; + uint32_t inMask; + uint32_t texMask2D; + uint32_t texMaskCentroid; + uint32_t i; + + (thisContext->current)[0] = (((1) << (18)) | ((0x000008e4))); + (thisContext->current)[1] = ((location+1) | (rawData)); + (thisContext->current) += 2; + + inMask = conf->attributeInputMask; + + (thisContext->current)[0] = (((1) << (18)) | ((0x00001ff4))); + (thisContext->current)[1] = (inMask); + (thisContext->current) += 2; + + + texMask = conf->texCoordsInputMask; + texMask2D = conf->texCoords2D; + texMaskCentroid = conf->texCoordsCentroid; + + for(i=0; texMask; i++) + { + if (texMask&1) + { + uint32_t hwTexCtrl = (texMask2D & 1) | ((texMaskCentroid & 1) << 4); + (thisContext->current)[0] = (((1) << (18)) | ((0x00000b40) + (i) * 4)); + (thisContext->current)[1] = (hwTexCtrl); + (thisContext->current) += 2; + } + texMask >>= 1; + texMask2D >>= 1; + texMaskCentroid >>= 1; + } + + + registerCount = conf->registerCount; + + if (registerCount < 2) + registerCount = 2; + + shCtrl0 = conf->fragmentControl | (registerCount << 24); + (thisContext->current)[0] = (((1) << (18)) | ((0x00001d60))); + (thisContext->current)[1] = (shCtrl0); + (thisContext->current) += 2; +} + static inline void rglGcmSetDrawArrays(struct CellGcmContextData *thisContext, uint8_t mode, uint32_t first, uint32_t count) { @@ -284,6 +351,60 @@ static inline void rglGcmSetDrawArrays(struct CellGcmContextData *thisContext, u (thisContext->current) += 2; } +static inline void rglGcmSetVertexProgramLoad(struct CellGcmContextData *thisContext, const CellCgbVertexProgramConfiguration *conf, const void *ucode) +{ + const uint32_t *rawData; + uint32_t instCount; + uint32_t instIndex; + + rawData = (const uint32_t*)ucode; + instCount = conf->instructionCount; + instIndex = conf->instructionSlot; + + uint32_t loop, rest; + loop = instCount / 8; + rest = (instCount % 8) * 4; + + (thisContext->current)[0] = (((2) << (18)) | ((0x00001e9c))); + (thisContext->current)[1] = (instIndex); + (thisContext->current)[2] = (instIndex); + (thisContext->current) += 3; + + uint32_t i, j; + + for (i = 0; i < loop; i++) + { + thisContext->current[0] = (((32) << (18)) | ((0x00000b80))); + + __builtin_memcpy(&thisContext->current[1], &rawData[0], sizeof(uint32_t)*16); + __builtin_memcpy(&thisContext->current[17], &rawData[16], sizeof(uint32_t)*16); + + thisContext->current += (1 + 32); + rawData += 32; + } + + if (rest > 0) + { + thisContext->current[0] = (((rest) << (18)) | ((0x00000b80))); + for (j = 0; j < rest; j++) + thisContext->current[j+1] = rawData[j]; + thisContext->current += (1 + rest); + } + + + (thisContext->current)[0] = (((1) << (18)) | ((0x00001ff0))); + (thisContext->current)[1] = ((conf->attributeInputMask)); + (thisContext->current) += 2; + + (thisContext->current)[0] = (((1) << (18)) | ((0x00001ef8))); + + if (conf->registerCount <= 32) + (thisContext->current)[1] = ((0xFFFF) | ((32) << 16)); + else + (thisContext->current)[1] = ((0xFFFF) | ((48) << 16)); + (thisContext->current) += 2; +} + static inline void rglGcmFifoGlViewport(void *data, GLclampf zNear, GLclampf zFar) { CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; @@ -582,14 +703,6 @@ static inline void rglPrintFifoFromGet( unsigned int numWords ) rglPrintIt((( uint32_t* )rglGcmState_i.fifo.lastGetRead )[i] ); } -// Determine whether a given location in a command buffer has been passed, by -// using reference markers. -static inline GLboolean rglGcmFifoGlTestFenceRef (const GLuint ref) -{ - rglGcmFifo *fifo = &rglGcmState_i.fifo; - return rglGcmFifoReferenceInUse( fifo, ref ); -} - // Add a reference marker to the command buffer to determine whether a location // in the command buffer has been passed static inline void rglGcmFifoGlIncFenceRef (GLuint *ref) diff --git a/ps3/rgl/src/ps3/rgl_ps3.cpp b/ps3/rgl/src/ps3/rgl_ps3.cpp index 0b3f59883e..5271ecd0b1 100644 --- a/ps3/rgl/src/ps3/rgl_ps3.cpp +++ b/ps3/rgl/src/ps3/rgl_ps3.cpp @@ -1576,54 +1576,25 @@ uint32_t gmmAlloc(void *data, FIFO BUFFER ============================================================ */ -void rglGcmFifoFinish (void *data) -{ - rglGcmFifo *fifo = (rglGcmFifo*)data; - GLuint ref = rglGcmFifoPutReference( fifo ); - - rglGcmFifoFlush( fifo ); - - while (rglGcmFifoReferenceInUse(fifo, ref)) - sys_timer_usleep(10); -} - -void rglGcmFifoFlush (void *data) -{ - rglGcmFifo *fifo = (rglGcmFifo*)data; - unsigned int offsetInBytes = 0; - - cellGcmAddressToOffset( fifo->current, ( uint32_t * )&offsetInBytes ); - - cellGcmFlush(); - - fifo->dmaControl->Put = offsetInBytes; - fifo->lastPutWritten = fifo->current; - - fifo->lastSWReferenceFlushed = fifo->lastSWReferenceWritten; -} - GLuint rglGcmFifoPutReference (void *data) { CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; rglGcmFifo *fifo = (rglGcmFifo*)data; + GLuint ref; + unsigned int offset_bytes = 0; + fifo->lastSWReferenceWritten++; rglGcmSetReferenceCommand(thisContext, fifo->lastSWReferenceWritten ); if (( fifo->lastSWReferenceWritten & 0x7fffffff ) == 0 ) - rglGcmFifoFinish( fifo ); + { + rglGcmFifoFinish(ref, offset_bytes); + } return fifo->lastSWReferenceWritten; } -GLuint rglGcmFifoReadReference (void *data) -{ - rglGcmFifo *fifo = (rglGcmFifo*)data; - GLuint ref = *((volatile GLuint *)&fifo->dmaControl->Reference); - fifo->lastHWReferenceRead = ref; - return ref; -} - GLboolean rglGcmFifoReferenceInUse (void *data, GLuint reference) { rglGcmFifo *fifo = (rglGcmFifo*)data; @@ -1633,10 +1604,13 @@ GLboolean rglGcmFifoReferenceInUse (void *data, GLuint reference) // has the reference already been flushed out ? if (( fifo->lastSWReferenceFlushed - reference ) & 0x80000000 ) - rglGcmFifoFlush( fifo ); + { + unsigned int offset_bytes = 0; + rglGcmFifoFlush(fifo, offset_bytes); + } // read current hw reference - rglGcmFifoReadReference( fifo ); + rglGcmFifoReadReference(fifo); // compare against hw ref value (accounting wrap) if ( !(( fifo->lastHWReferenceRead - reference ) & 0x80000000 ) ) @@ -1680,8 +1654,9 @@ void rglGcmFifoInit (void *data, void *dmaControl, unsigned long dmaPushBufferOf // ensure the ref is initted to 0. if ( rglGcmFifoReadReference( fifo ) != 0 ) { + unsigned int offset_bytes = 0; GCM_FUNC( cellGcmSetReferenceCommand, 0 ); - rglGcmFifoFlush( fifo ); // Here, we jump to this new buffer + rglGcmFifoFlush(fifo, offset_bytes); // Here, we jump to this new buffer // a finish that waits for 0 specifically. while (rglGcmFifoReadReference(fifo) != 0) @@ -1696,11 +1671,28 @@ void rglGcmFifoInit (void *data, void *dmaControl, unsigned long dmaPushBufferOf GL INITIALIZATION ============================================================ */ -void rglGcmSetOpenGLState (void *data) +GLboolean rglGcmInitFromRM( rglGcmResource *rmResource ) { - rglGcmState *rglGcmSt = (rglGcmState*)data; + rglGcmState *rglGcmSt = &rglGcmState_i; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmSt->fifo; CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; - GLuint i; + GLuint i, ref; + unsigned int offset_bytes = 0; + + memset( rglGcmSt, 0, sizeof( *rglGcmSt ) ); + + rglGcmSt->localAddress = rmResource->localAddress; + rglGcmSt->hostMemoryBase = rmResource->hostMemoryBase; + rglGcmSt->hostMemorySize = rmResource->hostMemorySize; + + rglGcmSt->hostNotifierBuffer = NULL; //rmResource->hostNotifierBuffer; + rglGcmSt->semaphores = rmResource->semaphores; + + rglGcmFifoInit( &rglGcmSt->fifo, rmResource->dmaControl, rmResource->dmaPushBufferOffset, (uint32_t*)rmResource->dmaPushBuffer, rmResource->dmaPushBufferSize ); + + rglGcmFifoFinish(ref, offset_bytes); + + // Set the GPU to a known state // initialize the default OpenGL state GCM_FUNC( cellGcmSetBlendColor, 0, 0); @@ -1743,29 +1735,10 @@ void rglGcmSetOpenGLState (void *data) v->w = RGLGCM_MAX_RT_DIMENSION; v->h = RGLGCM_MAX_RT_DIMENSION; rglGcmFifoGlViewport(v, 0.0f, 1.0f ); -} - -GLboolean rglGcmInitFromRM( rglGcmResource *rmResource ) -{ - rglGcmState *rglGcmSt = &rglGcmState_i; - memset( rglGcmSt, 0, sizeof( *rglGcmSt ) ); - - rglGcmSt->localAddress = rmResource->localAddress; - rglGcmSt->hostMemoryBase = rmResource->hostMemoryBase; - rglGcmSt->hostMemorySize = rmResource->hostMemorySize; - - rglGcmSt->hostNotifierBuffer = NULL; //rmResource->hostNotifierBuffer; - rglGcmSt->semaphores = rmResource->semaphores; - - rglGcmFifoInit( &rglGcmSt->fifo, rmResource->dmaControl, rmResource->dmaPushBufferOffset, (uint32_t*)rmResource->dmaPushBuffer, rmResource->dmaPushBufferSize ); - - rglGcmFifoFinish( &rglGcmSt->fifo ); - - // Set the GPU to a known state - rglGcmSetOpenGLState(rglGcmSt); // wait for setup to complete - rglGcmFifoFinish(&rglGcmSt->fifo); + offset_bytes = 0; + rglGcmFifoFinish(ref, offset_bytes); return GL_TRUE; } @@ -1907,11 +1880,13 @@ void rglPsglPlatformExit(void) { RGLcontext* LContext = _CurrentContext; CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + rglGcmFifo * fifo = &rglGcmState_i.fifo; if ( LContext ) { + unsigned int offset_bytes = 0; rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFlush( &rglGcmState_i.fifo ); + rglGcmFifoFlush(fifo, offset_bytes); psglMakeCurrent( NULL, NULL ); rglDeviceExit(); @@ -2335,8 +2310,11 @@ static GLboolean rglDuringDestroyDevice = GL_FALSE; // region is resized or deleted. GLboolean rglGcmTryResizeTileRegion( GLuint address, GLuint size, void* data ) { + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; rglTiledRegion* region = ( rglTiledRegion* )data; int32_t retVal = 0; + GLuint ref; + unsigned int offset_bytes = 0; // delete always succeeds if ( size == 0 ) @@ -2347,11 +2325,12 @@ GLboolean rglGcmTryResizeTileRegion( GLuint address, GLuint size, void* data ) if ( ! rglDuringDestroyDevice ) { + unsigned int offset_bytes = 0; // must wait until RSX is completely idle before calling cellGcmUnbindTile rglGcmUtilWaitForIdle(); retVal = cellGcmUnbindTile( region->id ); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); } return GL_TRUE; } @@ -2373,7 +2352,8 @@ GLboolean rglGcmTryResizeTileRegion( GLuint address, GLuint size, void* data ) retVal = cellGcmBindTile( region->id ); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + offset_bytes = 0; + rglGcmFifoFinish(ref, offset_bytes); return GL_TRUE; } @@ -2779,9 +2759,11 @@ int rglPlatformCreateDevice (void *data) CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; RGLdevice *device = (RGLdevice*)data; rglGcmDevice *gcmDevice = ( rglGcmDevice * )device->platformDevice; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; RGLdeviceParameters* params = &device->deviceParameters; rglDuringDestroyDevice = GL_FALSE; GLboolean result = 0; + GLuint ref; // Tile memory manager init rglGcmTiledMemoryInit(); @@ -2996,11 +2978,12 @@ int rglPlatformCreateDevice (void *data) } else { + unsigned int offset_bytes = 0; rglSetDisplayMode( vm, gcmDevice->color[0].bpp*8, gcmDevice->color[0].pitch ); cellGcmSetFlipMode( gcmDevice->vsync ? CELL_GCM_DISPLAY_VSYNC : CELL_GCM_DISPLAY_HSYNC ); rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); for ( int i = 0; i < params->bufferingMode; ++i ) { @@ -3023,12 +3006,15 @@ int rglPlatformCreateDevice (void *data) void rglPlatformDestroyDevice (void *data) { RGLdevice *device = (RGLdevice*)data; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; rglGcmDevice *gcmDevice = ( rglGcmDevice * )device->platformDevice; RGLdeviceParameters *params = &device->deviceParameters; CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + GLuint ref; + unsigned int offset_bytes = 0; rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); // Stop flip callback if ( rescIsEnabled( params ) ) @@ -3070,6 +3056,8 @@ GLAPI void RGL_EXPORT psglSwap (void) GmmBlock *pBlock = NULL; GmmBlock *pTemp = NULL; GmmAllocator *pAllocator = pGmmLocalAllocator; + rglGcmFifo * fifo = &rglGcmState_i.fifo; + unsigned int offset_bytes = 0; pBlock = pAllocator->pPendingFreeHead; @@ -3148,12 +3136,12 @@ GLAPI void RGL_EXPORT psglSwap (void) context->attribs->DirtyMask = ( 1 << RGL_MAX_VERTEX_ATTRIBS ) - 1; rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFlush( &rglGcmState_i.fifo ); + rglGcmFifoFlush(fifo, offset_bytes); while (sys_semaphore_wait(FlipSem,1000) != CELL_OK); rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFlush( &rglGcmState_i.fifo ); + rglGcmFifoFlush(fifo, offset_bytes); if ( device->deviceParameters.bufferingMode == RGL_BUFFERING_MODE_DOUBLE ) { @@ -4121,11 +4109,15 @@ RGLcontext *psglGetCurrentContext(void) void RGL_EXPORT psglDestroyContext (void *data) { CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; RGLcontext *LContext = (RGLcontext*)data; + GLuint ref; + unsigned int offset_bytes = 0; + if ( _CurrentContext == LContext ) { rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); } while ( LContext->RGLcgContextHead != ( CGcontext )NULL ) diff --git a/ps3/rgl/src/ps3/rgl_ps3_raster.cpp b/ps3/rgl/src/ps3/rgl_ps3_raster.cpp index 7edb686538..313bd4257f 100644 --- a/ps3/rgl/src/ps3/rgl_ps3_raster.cpp +++ b/ps3/rgl/src/ps3/rgl_ps3_raster.cpp @@ -1201,8 +1201,10 @@ GLAPI void APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr char *rglPlatformBufferObjectMap (void *data, GLenum access) { rglBufferObject *bufferObject = (rglBufferObject*)data; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; rglGcmBufferObject *rglBuffer = (rglGcmBufferObject*)bufferObject->platformBufferObject; CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + GLuint ref; if (rglBuffer->mapCount++ == 0) { @@ -1220,9 +1222,10 @@ char *rglPlatformBufferObjectMap (void *data, GLenum access) } else { + unsigned int offset_bytes = 0; // must wait in order to read rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); } rglBuffer->mapAccess = access; @@ -1277,9 +1280,11 @@ GLboolean rglPlatformBufferObjectUnmap (void *data) GLAPI void APIENTRY glClear( GLbitfield mask ) { + unsigned int offset_bytes = 0; RGLcontext* LContext = _CurrentContext; rglGcmDriver *driver = (rglGcmDriver*)_CurrentDevice->rasterDriver; CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + rglGcmFifo * fifo = &rglGcmState_i.fifo; if ( LContext->needValidate & RGL_VALIDATE_FRAMEBUFFER ) { @@ -1321,7 +1326,7 @@ GLAPI void APIENTRY glClear( GLbitfield mask ) rglGcmSetClearSurface(thisContext, CELL_GCM_CLEAR_R | CELL_GCM_CLEAR_G | CELL_GCM_CLEAR_B | CELL_GCM_CLEAR_A ); rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFlush( &rglGcmState_i.fifo ); + rglGcmFifoFlush(fifo, offset_bytes); } rglFramebuffer* rglCreateFramebuffer (void) @@ -1498,8 +1503,12 @@ void rglPlatformFramebuffer::validate (void *data) void *rglPlatformRasterInit (void) { CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; + GLuint ref; + unsigned int offset_bytes = 0; + rglGcmSetInvalidateVertexCache(thisContext); - rglGcmFifoFinish( &rglGcmState_i.fifo ); + rglGcmFifoFinish(ref, offset_bytes); rglGcmDriver *driver = (rglGcmDriver*)malloc(sizeof(rglGcmDriver)); memset(driver, 0, sizeof(rglGcmDriver)); @@ -1685,7 +1694,7 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count) if ( fifo->current + spaceInWords + 1024 > fifo->end ) rglOutOfSpaceCallback( fifo, spaceInWords ); - GCM_FUNC( cellGcmSetVertexProgramLoad, &conf, program->ucode ); + rglGcmSetVertexProgramLoad(thisContext, &conf, program->ucode ); rglGcmSetUserClipPlaneControl(thisContext, 0, 0, 0, 0, 0, 0 ); rglGcmInterpolantState *s = &rglGcmState_i.state.interpolant; @@ -1849,7 +1858,7 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count) /* TODO - look into this */ conf.fragmentControl |= 0 << CELL_GCM_SHIFT_SET_SHADER_CONTROL_CONTROL_TXP; - GCM_FUNC( cellGcmSetFragmentProgramLoad, &conf ); + rglGcmSetFragmentProgramLoad(thisContext, &conf, CELL_GCM_LOCATION_LOCAL); rglGcmSetZMinMaxControl(thisContext, ( program->header.fragmentProgram.flags & CGF_DEPTHREPLACE ) ? RGLGCM_FALSE : RGLGCM_TRUE, RGLGCM_FALSE, RGLGCM_FALSE );