Code reviewed and added SPE API documentation. gsoc2009_ps3
authorMartin Lowinski <martin@goldtopf.org>
Sun, 19 Jul 2009 11:31:47 +0000
branchgsoc2009_ps3
changeset 3150 0cf7bff804ad
parent 3149 b143d794bff1
child 3151 4a88137385f9
Code reviewed and added SPE API documentation.
src/video/ps3/SDL_ps3render.c
src/video/ps3/SDL_ps3spe.c
src/video/ps3/SDL_ps3spe_c.h
src/video/ps3/SDL_ps3video.c
src/video/ps3/SDL_ps3video.h
--- 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);
         }
--- 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
--- 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);
--- 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 */
--- 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)));