void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint(NULL); schedf("%s: ", reason); // This prevents drawing to the screen, which makes the test faster. HAS_DISPLAY = 0; for (int y = 0; y < 1; ++y) { for (int x = 0; x < 1; ++x) { // For the purposes of this test, ignore alpha. schedf("%06x", buf[y * 512 + x] & 0x00FFFFFF); } schedf("\n"); flushschedf(); } HAS_DISPLAY = 1; // Reset. memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
int main(int argc, char *argv[]) { testMemcpy("sceDmacMemcpy", &sceDmacMemcpy); testMemcpy("sceDmacTryMemcpy", &sceDmacTryMemcpy); checkpointNext("Size of copy:"); // Approximate speed: 225 MB/s. checkpoint(" sceDmacMemcpy 1MB: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00100000)); checkpoint(" sceDmacTryMemcpy 1MB: %08x", sceDmacTryMemcpy((void*)0x04000000, (void*)0x04100000, 0x00100000)); checkpoint(" sceDmacMemcpy 1KB: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00000400)); checkpoint(" sceDmacMemcpy 512B: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00000200)); // This is suspiciously consistent, but maybe it's just chance. checkpoint(" sceDmacMemcpy 272B: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00000110)); checkpoint(" sceDmacMemcpy 271B: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x0000010F)); checkpoint(" sceDmacMemcpy 257B: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00000101)); checkpoint(" sceDmacMemcpy 256B: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00000100)); checkpointNext("Concurrent copies:"); SceUID copyThread = sceKernelCreateThread("dmac", &dmacCopyFunc, 0x10, 0x1000, 0, NULL); sceKernelStartThread(copyThread, 0, NULL); checkpoint(" sceDmacTryMemcpy 1MB: %08x", sceDmacTryMemcpy((void*)0x04000000, (void*)0x04100000, 0x00100000)); checkpoint(" sceDmacMemcpy 1MB: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00100000)); checkpointNext("memalign:"); void *ptr; ptr = memalign(128 , 2048); checkpoint("%d", ((int)ptr) % 128); ptr = memalign(1024, 2048); checkpoint("%d", ((int)ptr) % 1024); //ptr = memalign(100 , 2048); checkpoint("%d", ((int)ptr) % 100); //checkpoint("%i bytes available", oslGetRamStatus().maxAvailable); return 0; }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, sceGeEdramGetAddr(), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint("%s: COLOR=%08x", reason, buf[0]); // Reset. memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void drawUploadTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Okay, let's draw a totally different pattern in memory. for (int y = 0; y < 272; ++y) { for (int x = 0; x < 512; ++x) { copybuf[y * 512 + x] = (x & 1) + (y & 1); } } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display out pattern. displayBuffer("Pattern"); }
void testBlendFunc(const char *title, u32 prev, u32 c, int op, int src, int dst, u32 fixa, u32 fixb) { for (size_t i = 0; i < sizeof(copybuf) / 4; ++i) { copybuf[i] = prev; } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceGuStart(GU_DIRECT, list); sceGuEnable(GU_BLEND); sceGuBlendFunc(op, src, dst, fixa, fixb); sceGuEnable(GU_STENCIL_TEST); sceGuStencilFunc(GU_ALWAYS, 0xAA, 0xFF); sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); drawBoxCommands(c); sceGuFinish(); sceGuSync(GU_SYNC_WAIT, GU_SYNC_WHAT_DONE); displayBuffer(title); sceGuDisable(GU_BLEND); }
void init() { sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, 512); sceGuDispBuffer(480, 272, fbp0, 512); sceGuDepthBuffer(dbp0, 512); sceGuOffset(2048 - (240 / 2), 2048 - (136 / 2)); sceGuViewport(2048, 2048, 240, 136); sceGuDepthRange(65535, 0); sceGuDepthMask(0); sceGuScissor(0, 0, 480, 272); sceGuEnable(GU_SCISSOR_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuDisable(GU_TEXTURE_2D); ScePspFMatrix4 ones = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, }; sceGuSetMatrix(GU_MODEL, &ones); sceGuSetMatrix(GU_VIEW, &ones); sceGuSetMatrix(GU_PROJECTION, &ones); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); displayBuffer("Initial"); }
void init() { void *fbp0 = 0; drawbuf = (u32 *)sceGeEdramGetAddr(); sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, fbp0, BUF_WIDTH); sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint(reason); // This prevents drawing to the screen, which makes the test faster. HAS_DISPLAY = 0; for (int y = 0; y < 272; ++y) { for (int x = 0; x < 480; ++x) { if (buf[y * 512 + x] != 0) { schedf("%x", buf[y * 512 + x]); } else { schedf(" "); } } schedf("\n"); flushschedf(); } HAS_DISPLAY = 1; }
void drawIntraTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Next, let's copy from this buffer to itself. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), (u8 *)getBufAddr(0) + sizeof(copybuf) / 2, sizeof(copybuf) / 2); sceKernelDcacheWritebackInvalidateAll(); // Now download should display a different buffer. displayBuffer("Spliced buffer"); }
void drawInterTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); // First draw a texture to buffer 1. We'll use a clut here from memory. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); // Second, another texture to buffer 2. With a different clut so that they are visibly different. switchBuf(1, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddThree, vertices1); sceDisplayWaitVblank(); // Okay, at this point we have two buffers. Let's display one to make sure download works. displayBuffer("Initial download"); // Next, let's copy between them. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(1), getBufAddr(0), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display the other buffer. displayBuffer("Copied buffer"); }
/* @@@@@@@@@@@@@@@@@@@@@ RE_RenderScene Draw a 3D view into a part of the window, then return to 2D drawing. Rendering a scene may require multiple views to be rendered to handle mirrors, @@@@@@@@@@@@@@@@@@@@@ */ void RE_RenderScene( const refdef_t *fd ) { viewParms_t parms; int startTime; if ( !tr.registered ) { return; } GLimp_LogComment( "====== RE_RenderScene =====\n" ); if ( r_norefresh->integer ) { return; } startTime = ri.Milliseconds(); if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel"); } #if 1 Com_Memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) ); #else sceKernelDcacheWritebackInvalidateRange(tr.refdef.text, sizeof( tr.refdef.text )); sceKernelDcacheWritebackInvalidateRange(fd->text, sizeof( tr.refdef.text )); sceDmacMemcpy(tr.refdef.text, fd->text, sizeof( tr.refdef.text )); //vfpu memcpy sceKernelDcacheWritebackInvalidateRange(tr.refdef.text, sizeof( tr.refdef.text )); #endif tr.refdef.x = fd->x; tr.refdef.y = fd->y; tr.refdef.width = fd->width; tr.refdef.height = fd->height; tr.refdef.fov_x = fd->fov_x; tr.refdef.fov_y = fd->fov_y; VectorCopy( fd->vieworg, tr.refdef.vieworg ); VectorCopy( fd->viewaxis[0], tr.refdef.viewaxis[0] ); VectorCopy( fd->viewaxis[1], tr.refdef.viewaxis[1] ); VectorCopy( fd->viewaxis[2], tr.refdef.viewaxis[2] ); tr.refdef.time = fd->time; tr.refdef.rdflags = fd->rdflags; // copy the areamask data over and note if it has changed, which // will force a reset of the visible leafs even if the view hasn't moved tr.refdef.areamaskModified = qfalse; if ( ! (tr.refdef.rdflags & RDF_NOWORLDMODEL) ) { int areaDiff; int i; // compare the area bits areaDiff = 0; for (i = 0 ; i < MAX_MAP_AREA_BYTES/4 ; i++) { areaDiff |= ((int *)tr.refdef.areamask)[i] ^ ((int *)fd->areamask)[i]; ((int *)tr.refdef.areamask)[i] = ((int *)fd->areamask)[i]; } if ( areaDiff ) { // a door just opened or something tr.refdef.areamaskModified = qtrue; } } // derived info tr.refdef.floatTime = tr.refdef.time * 0.001f; tr.refdef.numDrawSurfs = r_firstSceneDrawSurf; tr.refdef.drawSurfs = backEndData[tr.smpFrame]->drawSurfs; tr.refdef.num_entities = r_numentities - r_firstSceneEntity; tr.refdef.entities = &backEndData[tr.smpFrame]->entities[r_firstSceneEntity]; tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight; tr.refdef.dlights = &backEndData[tr.smpFrame]->dlights[r_firstSceneDlight]; tr.refdef.numPolys = r_numpolys - r_firstScenePoly; tr.refdef.polys = &backEndData[tr.smpFrame]->polys[r_firstScenePoly]; // turn off dynamic lighting globally by clearing all the // dlights if it needs to be disabled or if vertex lighting is enabled if ( r_dynamiclight->integer == 0 || r_vertexLight->integer == 1 || glConfig.hardwareType == GLHW_PERMEDIA2 ) { tr.refdef.num_dlights = 0; } // a single frame may have multiple scenes draw inside it -- // a 3D game view, 3D status bar renderings, 3D menus, etc. // They need to be distinguished by the light flare code, because // the visibility state for a given surface may be different in // each scene / view. tr.frameSceneNum++; tr.sceneCount++; // setup view parms for the initial view // // set up viewport // The refdef takes 0-at-the-top y coordinates, so // convert to GL's 0-at-the-bottom space // Com_Memset( &parms, 0, sizeof( parms ) ); parms.viewportX = tr.refdef.x; parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height ); parms.viewportWidth = tr.refdef.width; parms.viewportHeight = tr.refdef.height; parms.isPortal = qfalse; parms.fovX = tr.refdef.fov_x; parms.fovY = tr.refdef.fov_y; VectorCopy( fd->vieworg, parms.por.origin ); VectorCopy( fd->viewaxis[0], parms.por.axis[0] ); VectorCopy( fd->viewaxis[1], parms.por.axis[1] ); VectorCopy( fd->viewaxis[2], parms.por.axis[2] ); VectorCopy( fd->vieworg, parms.pvsOrigin ); R_RenderView( &parms ); // the next scene rendered in this frame will tack on after this one r_firstSceneDrawSurf = tr.refdef.numDrawSurfs; r_firstSceneEntity = r_numentities; r_firstSceneDlight = r_numdlights; r_firstScenePoly = r_numpolys; tr.frontEndMsec += ri.Milliseconds() - startTime; }
void RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts, int numPolys ) { srfPoly_t *poly; int i, j; int fogIndex; fog_t *fog; vec3_t bounds[2]; if ( !tr.registered ) { return; } if ( !hShader ) { ri.Printf( PRINT_WARNING, "WARNING: RE_AddPolyToScene: NULL poly shader\n"); return; } for ( j = 0; j < numPolys; j++ ) { if ( r_numpolyverts + numVerts > max_polyverts || r_numpolys >= max_polys ) { /* NOTE TTimo this was initially a PRINT_WARNING but it happens a lot with high fighting scenes and particles since we don't plan on changing the const and making for room for those effects simply cut this message to developer only */ ri.Printf( PRINT_DEVELOPER, "WARNING: RE_AddPolyToScene: r_max_polys or r_max_polyverts reached\n"); return; } poly = &backEndData[tr.smpFrame]->polys[r_numpolys]; poly->surfaceType = SF_POLY; poly->hShader = hShader; poly->numVerts = numVerts; poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts]; #if 1 Com_Memcpy( poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts ) ); #else sceKernelDcacheWritebackInvalidateRange(poly->verts, numVerts * sizeof( *verts )); sceKernelDcacheWritebackInvalidateRange(&verts[numVerts*j], numVerts * sizeof( *verts )); sceDmacMemcpy(poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts )); //vfpu memcpy sceKernelDcacheWritebackInvalidateRange(poly->verts, numVerts * sizeof( *verts )); #endif if ( glConfig.hardwareType == GLHW_RAGEPRO ) { poly->verts->modulate[0] = 255; poly->verts->modulate[1] = 255; poly->verts->modulate[2] = 255; poly->verts->modulate[3] = 255; } // done. r_numpolys++; r_numpolyverts += numVerts; // if no world is loaded if ( tr.world == NULL ) { fogIndex = 0; } // see if it is in a fog volume else if ( tr.world->numfogs == 1 ) { fogIndex = 0; } else { // find which fog volume the poly is in VectorCopy( poly->verts[0].xyz, bounds[0] ); VectorCopy( poly->verts[0].xyz, bounds[1] ); for ( i = 1 ; i < poly->numVerts ; i++ ) { AddPointToBounds( poly->verts[i].xyz, bounds[0], bounds[1] ); } for ( fogIndex = 1 ; fogIndex < tr.world->numfogs ; fogIndex++ ) { fog = &tr.world->fogs[fogIndex]; if ( bounds[1][0] >= fog->bounds[0][0] && bounds[1][1] >= fog->bounds[0][1] && bounds[1][2] >= fog->bounds[0][2] && bounds[0][0] <= fog->bounds[1][0] && bounds[0][1] <= fog->bounds[1][1] && bounds[0][2] <= fog->bounds[1][2] ) { break; } } if ( fogIndex == tr.world->numfogs ) { fogIndex = 0; } } poly->fogIndex = fogIndex; } }
int dmacCopyFunc(SceSize argc, void *argp) { checkpoint(" * thread: %08x", sceDmacMemcpy((void*)0x04000000, (void*)0x04100000, 0x00100000)); }
void resetBuffer() { memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }