Working 1080p, 720p, 480p videomodes and double buffering. gsoc2009_ps3
authorMartin Lowinski <martin@goldtopf.org>
Thu, 06 Aug 2009 12:24:47 +0000
branchgsoc2009_ps3
changeset 3152 7f3341cccf42
parent 3151 4a88137385f9
child 3153 a16c4ec43631
Working 1080p, 720p, 480p videomodes and double buffering.
src/video/ps3/SDL_ps3modes.c
src/video/ps3/SDL_ps3render.c
src/video/ps3/SDL_ps3video.c
src/video/ps3/SDL_ps3video.h
--- a/src/video/ps3/SDL_ps3modes.c	Tue Jul 21 05:33:11 2009 +0000
+++ b/src/video/ps3/SDL_ps3modes.c	Thu Aug 06 12:24:47 2009 +0000
@@ -34,7 +34,7 @@
     unsigned long vid = 0;
 
     modedata = (PS3_DisplayModeData *) SDL_malloc(sizeof(*modedata));
-    if (!displaydata) {
+    if (!modedata) {
         return;
     }
 
@@ -64,22 +64,53 @@
     deprintf(1, "-PS3_InitModes()\n");
 }
 
+static SDL_DisplayMode ps3fb_modedb[] = {
+    /* VESA */
+    {SDL_PIXELFORMAT_RGB888, 1280, 768, 0, NULL}, // WXGA
+    {SDL_PIXELFORMAT_RGB888, 1280, 1024, 0, NULL}, // SXGA
+    {SDL_PIXELFORMAT_RGB888, 1920, 1200, 0, NULL}, // WUXGA
+    /* Native resolutions (progressive, "fullscreen") */
+    {SDL_PIXELFORMAT_RGB888, 720, 480, 0, NULL}, // 480p
+    {SDL_PIXELFORMAT_RGB888, 1280, 720, 0, NULL}, // 720p
+    {SDL_PIXELFORMAT_RGB888, 1920, 1080, 0, NULL} // 1080p
+};
+
+static PS3_DisplayModeData ps3fb_data[] = {
+    {11}, {12}, {13}, {130}, {131}, {133}, 
+};
+
 void
 PS3_GetDisplayModes(_THIS) {
     deprintf(1, "+PS3_GetDisplayModes()\n");
+    SDL_DisplayMode mode;
+    unsigned int nummodes;
+
+    nummodes = sizeof(ps3fb_modedb) / sizeof(SDL_DisplayMode);
+
+    int n;
+    for (n=0; n<nummodes; ++n) {
+        /* Get driver specific mode data */
+        ps3fb_modedb[n].driverdata = &ps3fb_data[n];
+
+        /* Add DisplayMode to list */
+        deprintf(2, "Adding resolution %u x %u\n", ps3fb_modedb[n].w, ps3fb_modedb[n].h);
+        SDL_AddDisplayMode(_this->current_display, &ps3fb_modedb[n]);
+    }
     deprintf(1, "-PS3_GetDisplayModes()\n");
 }
 
-static int
+int
 PS3_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
 {
     deprintf(1, "+PS3_SetDisplayMode()\n");
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
-    SDL_DisplayData *dispdata = (SDL_DisplayData *) mode->driverdata;
+    PS3_DisplayModeData *dispdata = (PS3_DisplayModeData *) mode->driverdata;
 
-    /* We don't care about the current DisplayMode for now */
+    /* Set the new DisplayMode */
+    deprintf(2, "Setting PS3FB_MODE to %u\n", dispdata->mode);
     if (ioctl(data->fbdev, PS3FB_IOCTL_SETMODE, (unsigned long)&dispdata->mode)) {
-        SDL_SetError("Could not set videomode\n");
+        deprintf(2, "Could not set PS3FB_MODE\n");
+        SDL_SetError("Could not set PS3FB_MODE\n");
         return -1;
     }
 
@@ -90,6 +121,16 @@
 void
 PS3_QuitModes(_THIS) {
     deprintf(1, "+PS3_QuitModes()\n");
+
+    /* There was no mem allocated for driverdata */
+    int i, j;
+    for (i = _this->num_displays; i--;) {
+        SDL_VideoDisplay *display = &_this->displays[i];
+        for (j = display->num_display_modes; j--;) {
+            display->display_modes[j].driverdata = NULL;
+        }
+    }
+
     deprintf(1, "-PS3_QuitModes()\n");
 }
 
--- a/src/video/ps3/SDL_ps3render.c	Tue Jul 21 05:33:11 2009 +0000
+++ b/src/video/ps3/SDL_ps3render.c	Thu Aug 06 12:24:47 2009 +0000
@@ -46,6 +46,7 @@
 
 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window,
                                               Uint32 flags);
+static int SDL_PS3_DisplayModeChanged(SDL_Renderer * renderer);
 static int SDL_PS3_ActivateRenderer(SDL_Renderer * renderer);
 static int SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y);
 static int SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1,
@@ -126,8 +127,6 @@
     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;
 } PS3_TextureData;
 
 SDL_Renderer *
@@ -136,8 +135,10 @@
     deprintf(1, "+SDL_PS3_CreateRenderer()\n");
     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     SDL_DisplayMode *displayMode = &display->current_mode;
+    SDL_VideoData *devdata = display->device->driverdata;
     SDL_Renderer *renderer;
     SDL_PS3_RenderData *data;
+    struct ps3fb_ioctl_res res;
     int i, n;
     int bpp;
     Uint32 Rmask, Gmask, Bmask, Amask;
@@ -169,6 +170,7 @@
     renderer->LockTexture = PS3_LockTexture;
     renderer->UnlockTexture = PS3_UnlockTexture;
     renderer->ActivateRenderer = SDL_PS3_ActivateRenderer;
+    renderer->DisplayModeChanged = SDL_PS3_DisplayModeChanged;
     renderer->RenderPoint = SDL_PS3_RenderPoint;
     renderer->RenderLine = SDL_PS3_RenderLine;
     renderer->RenderFill = SDL_PS3_RenderFill;
@@ -179,14 +181,20 @@
     renderer->info.flags = 0;
     renderer->window = window->id;
     renderer->driverdata = data;
-    //Setup_SoftwareRenderer(renderer);
 
     deprintf(1, "window->w = %u\n", window->w);
     deprintf(1, "window->h = %u\n", window->h);
 
     data->double_buffering = 0;
 
-    if (flags & SDL_RENDERER_PRESENTFLIP2) {
+    /* Get ps3 screeninfo */
+    if (ioctl(devdata->fbdev, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0) {
+        SDL_SetError("[PS3] PS3FB_IOCTL_SCREENINFO failed");
+    }
+    deprintf(2, "res.num_frames = %d\n", res.num_frames);
+
+    /* Only use double buffering if enough fb memory is available */
+    if (res.num_frames > 1) {
         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
         n = 2;
         data->double_buffering = 1;
@@ -233,13 +241,13 @@
         return NULL;
     }
 
-    /* Set up the SPE scaler */
+    /* Set up the SPE scaler (booted) */
     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 */
+    /* Set up the SPE converter (always running) */
     data->converter_thread_data->program = yuv2rgb_spu;
     data->converter_thread_data->program_name = "yuv2rgb_spu";
     data->converter_thread_data->keepalive = 1;
@@ -261,6 +269,14 @@
     return 0;
 }
 
+static int SDL_PS3_DisplayModeChanged(SDL_Renderer * renderer) {
+    deprintf(1, "+PS3_DisplayModeChanged()\n");
+    SDL_PS3_RenderData *data = (SDL_PS3_RenderData *) renderer->driverdata;
+
+    deprintf(1, "-PS3_DisplayModeChanged()\n");
+    return 0;
+}
+
 static int
 PS3_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) {
     deprintf(1, "+PS3_CreateTexture()\n");
@@ -271,7 +287,6 @@
         return -1;
     }
     data->pitch = (texture->w * SDL_BYTESPERPIXEL(texture->format));
-    data->accelerated = 0;
 
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
         /* Use SDLs SW_YUVTexture */
@@ -313,7 +328,6 @@
         }
         if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
                 && texture->w % 16 == 0 && texture->h % 16 == 0) {
-            data->accelerated = 1;
         }
     } else {
         data->pixels = NULL;
@@ -385,15 +399,16 @@
     PS3_TextureData *data = (PS3_TextureData *) texture->driverdata;
 
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
+        deprintf(1, "-PS3_LockTexture()\n");
         return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, pitch);
     } else {
         *pixels =
             (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
                       rect->x * SDL_BYTESPERPIXEL(texture->format));
         *pitch = data->pitch;
+        deprintf(1, "-PS3_LockTexture()\n");
         return 0;
     }
-    deprintf(1, "-PS3_LockTexture()\n");
 }
 
 static void
@@ -522,7 +537,9 @@
 
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
         deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n");
-        if (txdata->accelerated) {
+        if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
+                && texture->w % 8 == 0 && texture->h % 8 == 0
+                && dstrect->w % 8 == 0 && dstrect->h % 8 == 0) {
             deprintf(1, "Use SPE for scaling/converting\n");
 
             SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv;
@@ -630,7 +647,6 @@
 SDL_PS3_RenderPresent(SDL_Renderer * renderer)
 {
     deprintf(1, "+SDL_PS3_RenderPresent()\n");
-    static int frame_number;
     SDL_PS3_RenderData *data =
         (SDL_PS3_RenderData *) renderer->driverdata;
     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
@@ -656,6 +672,7 @@
     /* Adjust centering */
     data->bounded_width = window->w < fb_vinfo.xres ? window->w : fb_vinfo.xres;
     data->bounded_height = window->h < fb_vinfo.yres ? window->h : fb_vinfo.yres;
+    /* We could use SDL's CENTERED flag for centering */
     data->offset_left = (fb_vinfo.xres - data->bounded_width) >> 1;
     data->offset_top = (fb_vinfo.yres - data->bounded_height) >> 1;
     data->center[0] = devdata->frame_buffer + data->offset_left * /*txdata->bpp/8*/ 4 +
@@ -695,7 +712,7 @@
     ioctl(devdata->fbdev, PS3FB_IOCTL_FSEL, (unsigned long)&data->current_screen);
 
     /* Update the flipping chain, if any */
-    if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2 && data->double_buffering) {
+    if (data->double_buffering) {
         data->current_screen = (data->current_screen + 1) % 2;
     }
     deprintf(1, "-SDL_PS3_RenderPresent()\n");
--- a/src/video/ps3/SDL_ps3video.c	Tue Jul 21 05:33:11 2009 +0000
+++ b/src/video/ps3/SDL_ps3video.c	Thu Aug 06 12:24:47 2009 +0000
@@ -59,27 +59,29 @@
 static int
 PS3_Available(void)
 {
-    deprintf(1, "PS3_Available()\n");
+    deprintf(1, "+PS3_Available()\n");
     const char *envr = SDL_getenv("SDL_VIDEODRIVER");
     if ((envr) && (SDL_strcmp(envr, PS3VID_DRIVER_NAME) == 0)) {
         return (1);
     }
 
+    deprintf(1, "-PS3_Available()\n");
     return (0);
 }
 
 static void
 PS3_DeleteDevice(SDL_VideoDevice * device)
 {
-    deprintf(1, "PS3_DeleteDevice()\n");
+    deprintf(1, "+PS3_DeleteDevice()\n");
     SDL_free(device->driverdata);
     SDL_free(device);
+    deprintf(1, "-PS3_DeleteDevice()\n");
 }
 
 static SDL_VideoDevice *
 PS3_CreateDevice(int devindex)
 {
-    deprintf(1, "PS3_CreateDevice()\n");
+    deprintf(1, "+PS3_CreateDevice()\n");
     SDL_VideoDevice *device;
     SDL_VideoData *data;
 
@@ -109,6 +111,7 @@
 
     device->free = PS3_DeleteDevice;
 
+    deprintf(1, "-PS3_CreateDevice()\n");
     return device;
 }
 
@@ -213,6 +216,8 @@
     deprintf(1, "PS3_VideoQuit()\n");
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
 
+    PS3_QuitModes(_this);
+
     /* Unmap framebuffer */
     if (data->frame_buffer) {
         struct fb_fix_screeninfo fb_finfo;
@@ -231,7 +236,7 @@
     }
 
     /* Close device */
-    if (data->fbdev > 0) {
+    if (data->fbdev) {
         /* Give control of frame buffer back to kernel */
         ioctl(data->fbdev, PS3FB_IOCTL_OFF, 0);
         close(data->fbdev);
--- a/src/video/ps3/SDL_ps3video.h	Tue Jul 21 05:33:11 2009 +0000
+++ b/src/video/ps3/SDL_ps3video.h	Thu Aug 06 12:24:47 2009 +0000
@@ -36,7 +36,7 @@
  * 2: SPE debug messages
  * 3: Memory adresses
  */
-#define DEBUG_LEVEL 1
+#define DEBUG_LEVEL 0
 
 #ifdef DEBUG_LEVEL
 #define deprintf( level, fmt, args... ) \
@@ -68,10 +68,10 @@
     volatile struct fb_writer_parms_t * fb_parms __attribute__((aligned(128)));
 } SDL_VideoData;
 
-typedef struct
+typedef struct SDL_DisplayModeData
 {
     unsigned long mode;
-    struct ps3fb_ioctl_res res;
+    //struct ps3fb_ioctl_res res;
 } PS3_DisplayModeData;
 
 #endif /* _SDL_ps3video_h */