# HG changeset patch # User Martin Lowinski # Date 1248003107 0 # Node ID 0cf7bff804ade0cbd19549829556ac3682523e9c # Parent b143d794bff1e81711fdee27102c00fffcfd261e Code reviewed and added SPE API documentation. diff -r b143d794bff1 -r 0cf7bff804ad src/video/ps3/SDL_ps3render.c --- a/src/video/ps3/SDL_ps3render.c Sun Jun 21 03:55:21 2009 +0000 +++ b/src/video/ps3/SDL_ps3render.c Sun Jul 19 11:31:47 2009 +0000 @@ -74,7 +74,12 @@ "ps3", (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTDISCARD | - SDL_RENDERER_ACCELERATED) + SDL_RENDERER_ACCELERATED), + (SDL_TEXTUREMODULATE_NONE), + (SDL_BLENDMODE_NONE), + /* We use bilinear scaling on the SPE for YV12 & IYUV + * (width and height % 8 = 0) */ + (SDL_TEXTURESCALEMODE_SLOW) } }; @@ -83,6 +88,7 @@ int current_screen; SDL_Surface *screen; SDL_VideoDisplay *display; + /* adress of the centered image in the framebuffer (double buffered) */ uint8_t *center[2]; /* width of input (bounded by writeable width) */ @@ -115,9 +121,10 @@ typedef struct { - //SDL_PixelFormat * format; int pitch; - volatile void *pixels;// __attribute__((aligned(128))); we don't need alignment here + /* Image data */ + volatile void *pixels; + /* Use software renderer for not supported formats */ SDL_SW_YUVTexture *yuv; /* Can we use the SPE to process this texture? */ unsigned int accelerated; @@ -155,14 +162,12 @@ } SDL_zerop(data); -#if 1 renderer->CreateTexture = PS3_CreateTexture; renderer->DestroyTexture = PS3_DestroyTexture; renderer->QueryTexturePixels = PS3_QueryTexturePixels; renderer->UpdateTexture = PS3_UpdateTexture; renderer->LockTexture = PS3_LockTexture; renderer->UnlockTexture = PS3_UnlockTexture; -#endif renderer->ActivateRenderer = SDL_PS3_ActivateRenderer; renderer->RenderPoint = SDL_PS3_RenderPoint; renderer->RenderLine = SDL_PS3_RenderLine; @@ -228,11 +233,13 @@ return NULL; } + /* Set up the SPE scaler */ data->scaler_thread_data->program = bilin_scaler_spu; data->scaler_thread_data->program_name = "bilin_scaler_spu"; data->scaler_thread_data->keepalive = 0; data->scaler_thread_data->booted = 0; + /* Set up the SPE converter */ data->converter_thread_data->program = yuv2rgb_spu; data->converter_thread_data->program_name = "yuv2rgb_spu"; data->converter_thread_data->keepalive = 1; @@ -277,6 +284,10 @@ /* but align pixels */ SDL_free(data->yuv->pixels); data->yuv->pixels = (Uint8 *)memalign(16, texture->w * texture->h * 2); + if (!data->yuv->pixels) { + SDL_OutOfMemory(); + return -1; + } /* Redo: Find the pitch and offset values for the overlay */ SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) data->yuv; @@ -497,6 +508,7 @@ PS3_TextureData *txdata = (PS3_TextureData *) texture->driverdata; SDL_VideoData *devdata = display->device->driverdata; + /* Debug info */ deprintf(1, "srcrect->w = %u\n", srcrect->w); deprintf(1, "srcrect->h = %u\n", srcrect->h); deprintf(1, "srcrect->x = %u\n", srcrect->x); @@ -505,7 +517,6 @@ deprintf(1, "dstrect->h = %u\n", dstrect->h); deprintf(1, "dstrect->x = %u\n", dstrect->x); deprintf(1, "dstrect->y = %u\n", dstrect->y); - deprintf(1, "texture->w = %u\n", texture->w); deprintf(1, "texture->h = %u\n", texture->h); @@ -577,6 +588,7 @@ SPE_SendMsg(data->converter_thread_data, SPU_START); SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); + /* We can probably move that to RenderPresent() */ SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); if (scaler_out) { free(scaler_out); @@ -625,16 +637,6 @@ SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_VideoData *devdata = display->device->driverdata; -#if 0 - /* Send the data to the display */ - if (SDL_getenv("SDL_VIDEO_PS3_SAVE_FRAMES")) { - char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - renderer->window, ++frame_number); - SDL_SaveBMP(data->screen[data->current_screen], file); - } -#endif - /* Send the data to the screen */ /* Get screeninfo */ struct fb_fix_screeninfo fb_finfo; @@ -645,6 +647,7 @@ if (ioctl(devdata->fbdev, FBIOGET_VSCREENINFO, &fb_vinfo)) { SDL_SetError("[PS3] Can't get VSCREENINFO"); } + /* 16 and 15 bpp is reported as 16 bpp */ //txdata->bpp = fb_vinfo.bits_per_pixel; //if (txdata->bpp == 16) @@ -673,11 +676,11 @@ devdata->fb_parms->fb_pixel_size = 4;//SDL_BYTESPERPIXEL(window->format); deprintf(3, "[PS3->SPU] fb_thread_data->argp = 0x%x\n", devdata->fb_thread_data->argp); - + /* Copying.. */ SPE_SendMsg(devdata->fb_thread_data, SPU_START); SPE_SendMsg(devdata->fb_thread_data, (unsigned int)devdata->fb_thread_data->argp); - + SPE_WaitForMsg(devdata->fb_thread_data, SPU_FIN); /* Wait for vsync */ @@ -713,7 +716,7 @@ } } - /* Shutdown SPE and related resources */ + /* Shutdown SPE and release related resources */ if (data->scaler_thread_data) { free((void *)data->scaler_thread_data); } diff -r b143d794bff1 -r 0cf7bff804ad src/video/ps3/SDL_ps3spe.c --- a/src/video/ps3/SDL_ps3spe.c Sun Jun 21 03:55:21 2009 +0000 +++ b/src/video/ps3/SDL_ps3spe.c Sun Jul 19 11:31:47 2009 +0000 @@ -28,6 +28,30 @@ #include "SDL_ps3render_c.h" +/* This SPE API basically provides 3 ways to run and control a program + * on the SPE: + * - Start and stop the program (keepalive=0). + * SPE_Start() will implicitly boot up the program, create a thread and run + * the context. + * SPE_Stop() will join the (terminated) thread (may block) and return. + * - Boot the program and run it (keepalive=0). + * SPE_Boot() will create a context and load the program and finally start + * the context with SPE_Start(). + * SPE_Stop() will savely end the program. + * - Boot, Run and send messages to the program (keepalive=1). + * Start the program by using one of the methods described above. When + * received the READY-message the program is in its infinite loop waiting + * for new messages. + * Every time you run the program, send SPU_START and the address of the + * according struct using SPE_SendMsg(). + * SPE_WaitForMsg() will than wait for SPU_FIN and is blocking. + * SPE_Shutdown() sends SPU_EXIT and finally stops the program. + * + * Therefor the SPE program + * - either runs once and returns + * - or runs in an infinite loop and is controlled by messages. + */ + /* Start the SPE thread */ int SPE_Start(spu_data_t * spe_data) { @@ -146,11 +170,11 @@ /* Re-runnable invocation of the spe_context_run call */ void SPE_RunContext(void *thread_argp) -{ +{ /* argp is the pointer to argument to be passed to the SPE program */ spu_data_t *args = (spu_data_t *) thread_argp; deprintf(3, "[PS3->SPU] void* argp=0x%x\n", (unsigned int)args->argp); - + /* Run it.. */ deprintf(2, "[PS3->SPU] Run SPE program: %s\n", args->program_name); if (spe_context_run diff -r b143d794bff1 -r 0cf7bff804ad src/video/ps3/SDL_ps3spe_c.h --- a/src/video/ps3/SDL_ps3spe_c.h Sun Jun 21 03:55:21 2009 +0000 +++ b/src/video/ps3/SDL_ps3spe_c.h Sun Jul 19 11:31:47 2009 +0000 @@ -28,20 +28,27 @@ #ifndef _SDL_ps3spe_h #define _SDL_ps3spe_h -/* SPU thread data */ +/* SPU handling data */ typedef struct spu_data { + /* Context to be executed */ spe_context_ptr_t ctx; spe_program_handle_t program; + /* Thread running the context */ pthread_t thread; + /* For debugging */ char * program_name; + /* SPE_Start() or SPE_Boot() called */ unsigned int booted; + /* Runs the program in an infinite loop? */ unsigned int keepalive; unsigned int entry; + /* Exit code of the program */ int error_code; + /* Arguments passed to the program */ void * argp; } spu_data_t; -/* SPU specific functions */ +/* SPU specific API functions */ int SPE_Start(spu_data_t * spe_data); int SPE_Stop(spu_data_t * spe_data); int SPE_Boot(spu_data_t * spe_data); diff -r b143d794bff1 -r 0cf7bff804ad src/video/ps3/SDL_ps3video.c --- a/src/video/ps3/SDL_ps3video.c Sun Jun 21 03:55:21 2009 +0000 +++ b/src/video/ps3/SDL_ps3video.c Sun Jul 19 11:31:47 2009 +0000 @@ -144,8 +144,8 @@ //display.current_mode = mode; #endif - /* - *PS3 stuff + /* + *PS3 stuff */ /* Create SPU fb_parms and thread structure */ diff -r b143d794bff1 -r 0cf7bff804ad src/video/ps3/SDL_ps3video.h --- a/src/video/ps3/SDL_ps3video.h Sun Jun 21 03:55:21 2009 +0000 +++ b/src/video/ps3/SDL_ps3video.h Sun Jul 19 11:31:47 2009 +0000 @@ -61,8 +61,8 @@ /* Framebuffer device descriptor */ int fbdev; /* mmap'd access to fbdev */ - uint8_t * frame_buffer; - /* SPE threading stuff */ + uint8_t * frame_buffer; + /* SPE threading stuff of the framebuffer */ spu_data_t * fb_thread_data; /* Framebuffer transfer data */ volatile struct fb_writer_parms_t * fb_parms __attribute__((aligned(128)));