Added ps3 video driver based on the dummy driver. gsoc2009_ps3
authorMartin Lowinski <martin@goldtopf.org>
Fri, 29 May 2009 09:50:21 +0000
branchgsoc2009_ps3
changeset 31413df74541339b
parent 3140 9ef99b844c60
child 3142 c146645a770e
Added ps3 video driver based on the dummy driver.
Added spulib for copying to framebuffer.
Added SPU managing functions.
Added open/close and taking control of the framebuffer.
configure.in
include/SDL_config.h.in
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/ps3/SDL_ps3events.c
src/video/ps3/SDL_ps3events_c.h
src/video/ps3/SDL_ps3render.c
src/video/ps3/SDL_ps3render_c.h
src/video/ps3/SDL_ps3video.c
src/video/ps3/SDL_ps3video.h
src/video/ps3/spulibs/Makefile
src/video/ps3/spulibs/fb_writer.c
src/video/ps3/spulibs/spu_common.h
     1.1 --- a/configure.in	Sat May 23 22:49:46 2009 +0000
     1.2 +++ b/configure.in	Fri May 29 09:50:21 2009 +0000
     1.3 @@ -1501,6 +1501,33 @@
     1.4      fi
     1.5  }
     1.6  
     1.7 +dnl See if we're running on PlayStation 3 Cell hardware
     1.8 +CheckPS3()
     1.9 +{
    1.10 +  AC_ARG_ENABLE(video-ps3,
    1.11 +                AC_HELP_STRING([--enable-video-ps3], [use PlayStation 3 Cell driver [[default=yes]]]),
    1.12 +                , enable_video_ps3=yes)
    1.13 +  if test x$enable_video = xyes -a x$enable_video_ps3 = xyes; then 
    1.14 +    AC_MSG_CHECKING(for PlayStation 3 Cell support)
    1.15 +    video_ps3=no
    1.16 +    AC_TRY_COMPILE([
    1.17 +      #include <linux/fb.h>
    1.18 +      #include <asm/ps3fb.h>
    1.19 +    ],[  
    1.20 +    ],[  
    1.21 +      video_ps3=yes
    1.22 +    ])   
    1.23 +    AC_MSG_RESULT($video_ps3)
    1.24 +    if test x$video_ps3 = xyes; then 
    1.25 +      AC_DEFINE(SDL_VIDEO_DRIVER_PS3)
    1.26 +      SOURCES="$SOURCES $srcdir/src/video/ps3/*.c"
    1.27 +      EXTRA_CFLAGS="$EXTRA_CFLAGS -I/opt/cell/sdk/usr/include"
    1.28 +      EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L/opt/cell/sdk/usr/lib -lspe2 -lfb_writer_spu"
    1.29 +      have_video=yes
    1.30 +    fi   
    1.31 +  fi
    1.32 +}
    1.33 +
    1.34  dnl Find the SVGAlib includes and libraries
    1.35  CheckSVGA()
    1.36  {
    1.37 @@ -2380,6 +2407,7 @@
    1.38          CheckDirectFB
    1.39          CheckFusionSound
    1.40          CheckPS2GS
    1.41 +        CheckPS3
    1.42          CheckSVGA
    1.43          CheckVGL
    1.44          CheckWscons
     2.1 --- a/include/SDL_config.h.in	Sat May 23 22:49:46 2009 +0000
     2.2 +++ b/include/SDL_config.h.in	Fri May 29 09:50:21 2009 +0000
     2.3 @@ -287,6 +287,7 @@
     2.4  #undef SDL_VIDEO_DRIVER_PHOTON
     2.5  #undef SDL_VIDEO_DRIVER_QNXGF
     2.6  #undef SDL_VIDEO_DRIVER_PS2GS
     2.7 +#undef SDL_VIDEO_DRIVER_PS3
     2.8  #undef SDL_VIDEO_DRIVER_RISCOS
     2.9  #undef SDL_VIDEO_DRIVER_SVGALIB
    2.10  #undef SDL_VIDEO_DRIVER_VGL
     3.1 --- a/src/video/SDL_sysvideo.h	Sat May 23 22:49:46 2009 +0000
     3.2 +++ b/src/video/SDL_sysvideo.h	Fri May 29 09:50:21 2009 +0000
     3.3 @@ -355,6 +355,9 @@
     3.4  #if SDL_VIDEO_DRIVER_PS2GS
     3.5  extern VideoBootStrap PS2GS_bootstrap;
     3.6  #endif
     3.7 +#if SDL_VIDEO_DRIVER_PS3
     3.8 +extern VideoBootStrap PS3_bootstrap;
     3.9 +#endif
    3.10  #if SDL_VIDEO_DRIVER_VGL
    3.11  extern VideoBootStrap VGL_bootstrap;
    3.12  #endif
     4.1 --- a/src/video/SDL_video.c	Sat May 23 22:49:46 2009 +0000
     4.2 +++ b/src/video/SDL_video.c	Fri May 29 09:50:21 2009 +0000
     4.3 @@ -73,6 +73,9 @@
     4.4  #if SDL_VIDEO_DRIVER_PS2GS
     4.5      &PS2GS_bootstrap,
     4.6  #endif
     4.7 +#if SDL_VIDEO_DRIVER_PS3
     4.8 +    &PS3_bootstrap,
     4.9 +#endif
    4.10  #if SDL_VIDEO_DRIVER_VGL
    4.11      &VGL_bootstrap,
    4.12  #endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/video/ps3/SDL_ps3events.c	Fri May 29 09:50:21 2009 +0000
     5.3 @@ -0,0 +1,36 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997-2009 Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Lesser General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2.1 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Lesser General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Lesser General Public
    5.19 +    License along with this library; if not, write to the Free Software
    5.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +#include "SDL_config.h"
    5.26 +
    5.27 +#include "../../events/SDL_sysevents.h"
    5.28 +#include "../../events/SDL_events_c.h"
    5.29 +
    5.30 +#include "SDL_ps3video.h"
    5.31 +#include "SDL_ps3events_c.h"
    5.32 +
    5.33 +void
    5.34 +PS3_PumpEvents(_THIS)
    5.35 +{
    5.36 +    /* do nothing. */
    5.37 +}
    5.38 +
    5.39 +/* vi: set ts=4 sw=4 expandtab: */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/video/ps3/SDL_ps3events_c.h	Fri May 29 09:50:21 2009 +0000
     6.3 @@ -0,0 +1,28 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2009 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Lesser General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2.1 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Lesser General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Lesser General Public
    6.19 +    License along with this library; if not, write to the Free Software
    6.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +#include "SDL_config.h"
    6.26 +
    6.27 +#include "SDL_ps3video.h"
    6.28 +
    6.29 +extern void PS3_PumpEvents(_THIS);
    6.30 +
    6.31 +/* vi: set ts=4 sw=4 expandtab: */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/video/ps3/SDL_ps3render.c	Fri May 29 09:50:21 2009 +0000
     7.3 @@ -0,0 +1,317 @@
     7.4 +/*
     7.5 +    SDL - Simple DirectMedia Layer
     7.6 +    Copyright (C) 1997-2009 Sam Lantinga
     7.7 +
     7.8 +    This library is free software; you can redistribute it and/or
     7.9 +    modify it under the terms of the GNU Lesser General Public
    7.10 +    License as published by the Free Software Foundation; either
    7.11 +    version 2.1 of the License, or (at your option) any later version.
    7.12 +
    7.13 +    This library is distributed in the hope that it will be useful,
    7.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.16 +    Lesser General Public License for more details.
    7.17 +
    7.18 +    You should have received a copy of the GNU Lesser General Public
    7.19 +    License along with this library; if not, write to the Free Software
    7.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    7.21 +
    7.22 +    Sam Lantinga
    7.23 +    slouken@libsdl.org
    7.24 +*/
    7.25 +#include "SDL_config.h"
    7.26 +
    7.27 +#include "SDL_video.h"
    7.28 +#include "../SDL_sysvideo.h"
    7.29 +#include "../SDL_yuv_sw_c.h"
    7.30 +#include "../SDL_renderer_sw.h"
    7.31 +
    7.32 +/* Debugging
    7.33 + * 0: No debug messages
    7.34 + * 1: Video debug messages
    7.35 + * 2: SPE debug messages
    7.36 + * 3: Memory adresses
    7.37 + */
    7.38 +#define DEBUG_LEVEL 2
    7.39 +
    7.40 +#ifdef DEBUG_LEVEL
    7.41 +#define deprintf( level, fmt, args... ) \
    7.42 +    do \
    7.43 +{ \
    7.44 +    if ( (unsigned)(level) <= DEBUG_LEVEL ) \
    7.45 +    { \
    7.46 +        fprintf( stdout, fmt, ##args ); \
    7.47 +        fflush( stdout ); \
    7.48 +    } \
    7.49 +} while ( 0 )
    7.50 +#else
    7.51 +#define deprintf( level, fmt, args... )
    7.52 +#endif
    7.53 +
    7.54 +/* SDL surface based renderer implementation */
    7.55 +
    7.56 +static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window,
    7.57 +                                              Uint32 flags);
    7.58 +static int SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y);
    7.59 +static int SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1,
    7.60 +                                int x2, int y2);
    7.61 +static int SDL_PS3_RenderFill(SDL_Renderer * renderer,
    7.62 +                                const SDL_Rect * rect);
    7.63 +static int SDL_PS3_RenderCopy(SDL_Renderer * renderer,
    7.64 +                                SDL_Texture * texture,
    7.65 +                                const SDL_Rect * srcrect,
    7.66 +                                const SDL_Rect * dstrect);
    7.67 +static void SDL_PS3_RenderPresent(SDL_Renderer * renderer);
    7.68 +static void SDL_PS3_DestroyRenderer(SDL_Renderer * renderer);
    7.69 +
    7.70 +
    7.71 +SDL_RenderDriver SDL_PS3_RenderDriver = {
    7.72 +    SDL_PS3_CreateRenderer,
    7.73 +    {
    7.74 +     "ps3",
    7.75 +     (/*SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |*/
    7.76 +      SDL_RENDERER_PRESENTFLIP2 /*| SDL_RENDERER_PRESENTFLIP3 |
    7.77 +      SDL_RENDERER_PRESENTDISCARD*/),
    7.78 +     }
    7.79 +};
    7.80 +
    7.81 +typedef struct
    7.82 +{
    7.83 +    int current_screen;
    7.84 +    SDL_Surface *screens[3];
    7.85 +} SDL_PS3_RenderData;
    7.86 +
    7.87 +SDL_Renderer *
    7.88 +SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags)
    7.89 +{
    7.90 +    deprintf(1, "SDL_PS3_CreateRenderer()\n");
    7.91 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
    7.92 +    SDL_DisplayMode *displayMode = &display->current_mode;
    7.93 +    SDL_Renderer *renderer;
    7.94 +    SDL_PS3_RenderData *data;
    7.95 +    int i, n;
    7.96 +    int bpp;
    7.97 +    Uint32 Rmask, Gmask, Bmask, Amask;
    7.98 +
    7.99 +    if (!SDL_PixelFormatEnumToMasks
   7.100 +        (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
   7.101 +        SDL_SetError("Unknown display format");
   7.102 +        return NULL;
   7.103 +    }
   7.104 +
   7.105 +    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
   7.106 +    if (!renderer) {
   7.107 +        SDL_OutOfMemory();
   7.108 +        return NULL;
   7.109 +    }
   7.110 +
   7.111 +    data = (SDL_PS3_RenderData *) SDL_malloc(sizeof(*data));
   7.112 +    if (!data) {
   7.113 +        SDL_PS3_DestroyRenderer(renderer);
   7.114 +        SDL_OutOfMemory();
   7.115 +        return NULL;
   7.116 +    }
   7.117 +    SDL_zerop(data);
   7.118 +
   7.119 +    renderer->RenderPoint = SDL_PS3_RenderPoint;
   7.120 +    renderer->RenderLine = SDL_PS3_RenderLine;
   7.121 +    renderer->RenderFill = SDL_PS3_RenderFill;
   7.122 +    renderer->RenderCopy = SDL_PS3_RenderCopy;
   7.123 +    renderer->RenderPresent = SDL_PS3_RenderPresent;
   7.124 +    renderer->DestroyRenderer = SDL_PS3_DestroyRenderer;
   7.125 +    renderer->info.name = SDL_PS3_RenderDriver.info.name;
   7.126 +    renderer->info.flags = 0;
   7.127 +    renderer->window = window->id;
   7.128 +    renderer->driverdata = data;
   7.129 +    Setup_SoftwareRenderer(renderer);
   7.130 +
   7.131 +    if (flags & SDL_RENDERER_PRESENTFLIP2) {
   7.132 +        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
   7.133 +        n = 2;
   7.134 +    } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
   7.135 +        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
   7.136 +        n = 3;
   7.137 +    } else {
   7.138 +        renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
   7.139 +        n = 1;
   7.140 +    }
   7.141 +    for (i = 0; i < n; ++i) {
   7.142 +        data->screens[i] =
   7.143 +            SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask,
   7.144 +                                 Bmask, Amask);
   7.145 +        if (!data->screens[i]) {
   7.146 +            SDL_PS3_DestroyRenderer(renderer);
   7.147 +            return NULL;
   7.148 +        }
   7.149 +        /* Allocate aligned memory for pixels */
   7.150 +        SDL_free(data->screens[i]->pixels);
   7.151 +        data->screens[i]->pixels = (void *)memalign(16, data->screens[i]->h * data->screens[i]->pitch);
   7.152 +        if (!data->screens[i]->pixels) {
   7.153 +            SDL_FreeSurface(data->screens[i]);
   7.154 +            SDL_OutOfMemory();
   7.155 +            return NULL;
   7.156 +        }
   7.157 +        SDL_memset(data->screens[i]->pixels, 0, data->screens[i]->h * data->screens[i]->pitch);
   7.158 +        SDL_SetSurfacePalette(data->screens[i], display->palette);
   7.159 +    }
   7.160 +    data->current_screen = 0;
   7.161 +
   7.162 +    return renderer;
   7.163 +}
   7.164 +
   7.165 +static int
   7.166 +SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y)
   7.167 +{
   7.168 +    SDL_PS3_RenderData *data =
   7.169 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.170 +    SDL_Surface *target = data->screens[data->current_screen];
   7.171 +    int status;
   7.172 +
   7.173 +    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
   7.174 +        renderer->blendMode == SDL_BLENDMODE_MASK) {
   7.175 +        Uint32 color =
   7.176 +            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
   7.177 +                        renderer->a);
   7.178 +
   7.179 +        status = SDL_DrawPoint(target, x, y, color);
   7.180 +    } else {
   7.181 +        status =
   7.182 +            SDL_BlendPoint(target, x, y, renderer->blendMode, renderer->r,
   7.183 +                           renderer->g, renderer->b, renderer->a);
   7.184 +    }
   7.185 +    return status;
   7.186 +}
   7.187 +
   7.188 +static int
   7.189 +SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   7.190 +{
   7.191 +    SDL_PS3_RenderData *data =
   7.192 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.193 +    SDL_Surface *target = data->screens[data->current_screen];
   7.194 +    int status;
   7.195 +
   7.196 +    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
   7.197 +        renderer->blendMode == SDL_BLENDMODE_MASK) {
   7.198 +        Uint32 color =
   7.199 +            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
   7.200 +                        renderer->a);
   7.201 +
   7.202 +        status = SDL_DrawLine(target, x1, y1, x2, y2, color);
   7.203 +    } else {
   7.204 +        status =
   7.205 +            SDL_BlendLine(target, x1, y1, x2, y2, renderer->blendMode,
   7.206 +                          renderer->r, renderer->g, renderer->b, renderer->a);
   7.207 +    }
   7.208 +    return status;
   7.209 +}
   7.210 +
   7.211 +static int
   7.212 +SDL_PS3_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
   7.213 +{
   7.214 +    deprintf(1, "SDL_PS3_RenderFill()\n");
   7.215 +    SDL_PS3_RenderData *data =
   7.216 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.217 +    SDL_Surface *target = data->screens[data->current_screen];
   7.218 +    SDL_Rect real_rect = *rect;
   7.219 +    int status;
   7.220 +
   7.221 +    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   7.222 +        Uint32 color =
   7.223 +            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
   7.224 +                        renderer->a);
   7.225 +
   7.226 +        status = SDL_FillRect(target, &real_rect, color);
   7.227 +    } else {
   7.228 +        status =
   7.229 +            SDL_BlendRect(target, &real_rect, renderer->blendMode,
   7.230 +                          renderer->r, renderer->g, renderer->b, renderer->a);
   7.231 +    }
   7.232 +    return status;
   7.233 +}
   7.234 +
   7.235 +static int
   7.236 +SDL_PS3_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   7.237 +                     const SDL_Rect * srcrect, const SDL_Rect * dstrect)
   7.238 +{
   7.239 +    deprintf(1, "SDL_PS3_RenderCopy()\n");
   7.240 +    SDL_PS3_RenderData *data =
   7.241 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.242 +    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   7.243 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   7.244 +
   7.245 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   7.246 +        SDL_Surface *target = data->screens[data->current_screen];
   7.247 +        void *pixels =
   7.248 +            (Uint8 *) target->pixels + dstrect->y * target->pitch +
   7.249 +            dstrect->x * target->format->BytesPerPixel;
   7.250 +        return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
   7.251 +                                   srcrect, display->current_mode.format,
   7.252 +                                   dstrect->w, dstrect->h, pixels,
   7.253 +                                   target->pitch);
   7.254 +    } else {
   7.255 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   7.256 +        SDL_Surface *target = data->screens[data->current_screen];
   7.257 +        SDL_Rect real_srcrect = *srcrect;
   7.258 +        SDL_Rect real_dstrect = *dstrect;
   7.259 +
   7.260 +        return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
   7.261 +    }
   7.262 +}
   7.263 +
   7.264 +static void
   7.265 +SDL_PS3_RenderPresent(SDL_Renderer * renderer)
   7.266 +{
   7.267 +    deprintf(1, "SDL_PS3_RenderPresent()\n");
   7.268 +    static int frame_number;
   7.269 +    SDL_PS3_RenderData *data =
   7.270 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.271 +
   7.272 +    /* Send the data to the display */
   7.273 +    if (SDL_getenv("SDL_VIDEO_PS3_SAVE_FRAMES")) {
   7.274 +        char file[128];
   7.275 +        SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
   7.276 +                     renderer->window, ++frame_number);
   7.277 +        SDL_SaveBMP(data->screens[data->current_screen], file);
   7.278 +    }
   7.279 +
   7.280 +    /* Update the flipping chain, if any */
   7.281 +    if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
   7.282 +        data->current_screen = (data->current_screen + 1) % 2;
   7.283 +    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
   7.284 +        data->current_screen = (data->current_screen + 1) % 3;
   7.285 +    }
   7.286 +
   7.287 +    /* How to access the framebuffer from here? 
   7.288 +    unsigned long crt = 0;
   7.289 +    unsigned int s_center_index = 0;
   7.290 +    unsigned int * s_center[2];
   7.291 +    s_center[0] = frame_buffer;
   7.292 +    // Wait for vsync
   7.293 +    deprintf(1, "[PS3] Wait for vsync\n");
   7.294 +    ioctl(fbdev, FBIO_WAITFORVSYNC, &crt);
   7.295 +    // Page flip
   7.296 +    deprintf(1, "[PS3] Page flip to buffer #%u 0x%x\n", s_center_index, s_center[s_center_index]);
   7.297 +    ioctl(fbdev, PS3FB_IOCTL_FSEL, (unsigned long)&s_center_index);
   7.298 +    */
   7.299 +}
   7.300 +
   7.301 +static void
   7.302 +SDL_PS3_DestroyRenderer(SDL_Renderer * renderer)
   7.303 +{
   7.304 +    deprintf(1, "SDL_PS3_DestroyRenderer()\n");
   7.305 +    SDL_PS3_RenderData *data =
   7.306 +        (SDL_PS3_RenderData *) renderer->driverdata;
   7.307 +    int i;
   7.308 +
   7.309 +    if (data) {
   7.310 +        for (i = 0; i < SDL_arraysize(data->screens); ++i) {
   7.311 +            if (data->screens[i]) {
   7.312 +                SDL_FreeSurface(data->screens[i]);
   7.313 +            }
   7.314 +        }
   7.315 +        SDL_free(data);
   7.316 +    }
   7.317 +    SDL_free(renderer);
   7.318 +}
   7.319 +
   7.320 +/* vi: set ts=4 sw=4 expandtab: */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/video/ps3/SDL_ps3render_c.h	Fri May 29 09:50:21 2009 +0000
     8.3 @@ -0,0 +1,29 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997-2009 Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Lesser General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2.1 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Lesser General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Lesser General Public
    8.19 +    License along with this library; if not, write to the Free Software
    8.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@libsdl.org
    8.24 +*/
    8.25 +#include "SDL_config.h"
    8.26 +
    8.27 +/* Default framebuffer device on PS3 */
    8.28 +/* SDL surface based renderer implementation */
    8.29 +
    8.30 +extern SDL_RenderDriver SDL_PS3_RenderDriver;
    8.31 +
    8.32 +/* vi: set ts=4 sw=4 expandtab: */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/video/ps3/SDL_ps3video.c	Fri May 29 09:50:21 2009 +0000
     9.3 @@ -0,0 +1,381 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997-2009 Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Lesser General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2.1 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Lesser General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Lesser General Public
    9.19 +    License along with this library; if not, write to the Free Software
    9.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@libsdl.org
    9.24 +*/
    9.25 +#include "SDL_config.h"
    9.26 +
    9.27 +/* SDL PS3 video driver implementation based on dummy video driver
    9.28 + *
    9.29 + * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion
    9.30 + *  of this was cut-and-pasted from Stephane Peter's work in the AAlib
    9.31 + *  SDL video driver.  Renamed to "DUMMY" by Sam Lantinga.
    9.32 + */
    9.33 +
    9.34 +#include "SDL_video.h"
    9.35 +#include "SDL_mouse.h"
    9.36 +#include "../SDL_sysvideo.h"
    9.37 +#include "../SDL_pixels_c.h"
    9.38 +#include "../../events/SDL_events_c.h"
    9.39 +#include "spulibs/spu_common.h"
    9.40 +
    9.41 +#include "SDL_ps3video.h"
    9.42 +#include "SDL_ps3events_c.h"
    9.43 +#include "SDL_ps3render_c.h"
    9.44 +
    9.45 +#include <fcntl.h>
    9.46 +#include <linux/fb.h>
    9.47 +#include <asm/ps3fb.h>
    9.48 +#include <libspe2.h>
    9.49 +#include <sys/mman.h>
    9.50 +
    9.51 +#define PS3VID_DRIVER_NAME "ps3"
    9.52 +
    9.53 +/* Initialization/Query functions */
    9.54 +static int PS3_VideoInit(_THIS);
    9.55 +static int PS3_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
    9.56 +static void PS3_VideoQuit(_THIS);
    9.57 +
    9.58 +/* SPU specific functions */
    9.59 +int SPE_Start(_THIS, spu_data_t * spe_data);
    9.60 +int SPE_Stop(_THIS, spu_data_t * spe_data);
    9.61 +int SPE_Boot(_THIS, spu_data_t * spe_data);
    9.62 +int SPE_Shutdown(_THIS, spu_data_t * spe_data);
    9.63 +int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
    9.64 +int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
    9.65 +void SPE_RunContext(void *thread_argp);
    9.66 +
    9.67 +/* Stores the SPE executable name of fb_writer_spu */
    9.68 +extern spe_program_handle_t fb_writer_spu;
    9.69 +
    9.70 +/* PS3 driver bootstrap functions */
    9.71 +
    9.72 +static int
    9.73 +PS3_Available(void)
    9.74 +{
    9.75 +    deprintf(1, "PS3_Available()\n");
    9.76 +    const char *envr = SDL_getenv("SDL_VIDEODRIVER");
    9.77 +    if ((envr) && (SDL_strcmp(envr, PS3VID_DRIVER_NAME) == 0)) {
    9.78 +        return (1);
    9.79 +    }
    9.80 +
    9.81 +    return (0);
    9.82 +}
    9.83 +
    9.84 +static void
    9.85 +PS3_DeleteDevice(SDL_VideoDevice * device)
    9.86 +{
    9.87 +    deprintf(1, "PS3_DeleteDevice()\n");
    9.88 +    SDL_free(device->driverdata);
    9.89 +    SDL_free(device);
    9.90 +}
    9.91 +
    9.92 +static SDL_VideoDevice *
    9.93 +PS3_CreateDevice(int devindex)
    9.94 +{
    9.95 +    deprintf(1, "PS3_CreateDevice()\n");
    9.96 +    SDL_VideoDevice *device;
    9.97 +    SDL_VideoData *data;
    9.98 +
    9.99 +    /* Initialize all variables that we clean on shutdown */
   9.100 +    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
   9.101 +    if (!device) {
   9.102 +        SDL_OutOfMemory();
   9.103 +        if (device) {
   9.104 +            SDL_free(device);
   9.105 +        }
   9.106 +        return (0);
   9.107 +    }
   9.108 +    data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
   9.109 +    if (!data) {
   9.110 +        SDL_OutOfMemory();
   9.111 +        SDL_free(device);
   9.112 +        return (0);
   9.113 +    }
   9.114 +    device->driverdata = data;
   9.115 +
   9.116 +    /* Set the function pointers */
   9.117 +    device->VideoInit = PS3_VideoInit;
   9.118 +    device->VideoQuit = PS3_VideoQuit;
   9.119 +    device->SetDisplayMode = PS3_SetDisplayMode;
   9.120 +    device->PumpEvents = PS3_PumpEvents;
   9.121 +
   9.122 +    device->free = PS3_DeleteDevice;
   9.123 +
   9.124 +    return device;
   9.125 +}
   9.126 +
   9.127 +VideoBootStrap PS3_bootstrap = {
   9.128 +    PS3VID_DRIVER_NAME, "SDL PS3 Cell video driver",
   9.129 +    PS3_Available, PS3_CreateDevice
   9.130 +};
   9.131 +
   9.132 +
   9.133 +int
   9.134 +PS3_VideoInit(_THIS)
   9.135 +{
   9.136 +    deprintf(1, "PS3_VideoInit()\n");
   9.137 +
   9.138 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   9.139 +    SDL_DisplayMode mode;
   9.140 +
   9.141 +    /* Use a fake 32-bpp desktop mode */
   9.142 +    mode.format = SDL_PIXELFORMAT_RGB888;
   9.143 +    //mode.w = 1024;
   9.144 +    //mode.h = 768;
   9.145 +    mode.w = 1920;
   9.146 +    mode.h = 1080;
   9.147 +    mode.refresh_rate = 0;
   9.148 +    mode.driverdata = NULL;
   9.149 +    SDL_AddBasicVideoDisplay(&mode);
   9.150 +    SDL_AddRenderDriver(0, &SDL_PS3_RenderDriver);
   9.151 +
   9.152 +    SDL_zero(mode);
   9.153 +    SDL_AddDisplayMode(0, &mode);
   9.154 +
   9.155 +    /* 
   9.156 +     *PS3 stuff 
   9.157 +     */
   9.158 +
   9.159 +    /* Create SPU fb_parms and thread structure */
   9.160 +    data->fb_parms = (struct fb_writer_parms_t *)
   9.161 +        memalign(16, sizeof(struct fb_writer_parms_t));
   9.162 +    data->fb_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
   9.163 +    if (data->fb_parms == NULL || data->fb_thread_data == NULL) {
   9.164 +        SDL_OutOfMemory();
   9.165 +        return -1;
   9.166 +    }
   9.167 +    data->fb_thread_data->program = fb_writer_spu;
   9.168 +    data->fb_thread_data->program_name = "fb_writer_spu";
   9.169 +    data->fb_thread_data->argp = (void *)data->fb_parms;
   9.170 +    data->fb_thread_data->keepalive = 1;
   9.171 +    data->fb_thread_data->booted = 0;
   9.172 +
   9.173 +    SPE_Start(_this, data->fb_thread_data);
   9.174 +
   9.175 +    /* Open the device */
   9.176 +    data->fbdev = open(PS3DEV, O_RDWR);
   9.177 +    if (data->fbdev < 0) {
   9.178 +        SDL_SetError("[PS3] Unable to open device %s", PS3DEV);
   9.179 +        return -1;
   9.180 +    }
   9.181 +
   9.182 +    /* Take control of frame buffer from kernel, for details see
   9.183 +     * http://felter.org/wesley/files/ps3/linux-20061110-docs/ApplicationProgrammingEnvironment.html
   9.184 +     * kernel will no longer flip the screen itself
   9.185 +     */
   9.186 +    ioctl(data->fbdev, PS3FB_IOCTL_ON, 0);
   9.187 +
   9.188 +    /* Unblank screen */
   9.189 +    ioctl(data->fbdev, FBIOBLANK, 0);
   9.190 +
   9.191 +    struct fb_fix_screeninfo fb_finfo;
   9.192 +    if (ioctl(data->fbdev, FBIOGET_FSCREENINFO, &fb_finfo)) {
   9.193 +        SDL_SetError("[PS3] Can't get fixed screeninfo");
   9.194 +        return (0);
   9.195 +    }
   9.196 +
   9.197 +    /* Note: on PS3, fb_finfo.smem_len is enough for double buffering */
   9.198 +    if ((data->frame_buffer = (uint8_t *)mmap(0, fb_finfo.smem_len,
   9.199 +        PROT_READ | PROT_WRITE, MAP_SHARED,
   9.200 +        data->fbdev, 0)) == (uint8_t *) - 1) {
   9.201 +        SDL_SetError("[PS3] Can't mmap for %s", PS3DEV);
   9.202 +        return (0);
   9.203 +    } else {
   9.204 +        //current->flags |= SDL_DOUBLEBUF;
   9.205 +    }
   9.206 +
   9.207 +    /* Blank screen */
   9.208 +    memset(data->frame_buffer, 0x00, fb_finfo.smem_len);
   9.209 +
   9.210 +    /* We're done! */
   9.211 +    return 0;
   9.212 +}
   9.213 +
   9.214 +static int
   9.215 +PS3_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
   9.216 +{
   9.217 +    deprintf(1, "PS3_SetDisplayMode()\n");
   9.218 +    return 0;
   9.219 +}
   9.220 +
   9.221 +void
   9.222 +PS3_VideoQuit(_THIS)
   9.223 +{
   9.224 +    deprintf(1, "PS3_VideoQuit()\n");
   9.225 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   9.226 +    if (data->frame_buffer) {
   9.227 +        struct fb_fix_screeninfo fb_finfo;
   9.228 +        if (ioctl(data->fbdev, FBIOGET_FSCREENINFO, &fb_finfo) != -1) {
   9.229 +            munmap(data->frame_buffer, fb_finfo.smem_len);
   9.230 +            data->frame_buffer = 0;
   9.231 +        }
   9.232 +    }
   9.233 +
   9.234 +    if (data->fb_parms)
   9.235 +        free((void *)data->fb_parms);
   9.236 +    if (data->fb_thread_data) {
   9.237 +        SPE_Shutdown(_this, data->fb_thread_data);
   9.238 +        free((void *)data->fb_thread_data);
   9.239 +    }
   9.240 +}
   9.241 +
   9.242 +
   9.243 +/*
   9.244 + * SPE handling
   9.245 + */
   9.246 +
   9.247 +/* Start the SPE thread */
   9.248 +int SPE_Start(_THIS, spu_data_t * spe_data)
   9.249 +{
   9.250 +  deprintf(2, "[PS3->SPU] Start SPE: %s\n", spe_data->program_name);
   9.251 +  if (!(spe_data->booted))
   9.252 +    SPE_Boot(_this, spe_data);
   9.253 +
   9.254 +  /* To allow re-running of context, spe_ctx_entry has to be set before each call */
   9.255 +  spe_data->entry = SPE_DEFAULT_ENTRY;
   9.256 +  spe_data->error_code = 0;
   9.257 +
   9.258 +  /* Create SPE thread and run */
   9.259 +  deprintf(2, "[PS3->SPU] Create Thread: %s\n", spe_data->program_name);
   9.260 +  if (pthread_create
   9.261 +      (&spe_data->thread, NULL, (void *)&SPE_RunContext, (void *)spe_data)) {
   9.262 +    deprintf(2, "[PS3->SPU] Could not create pthread for spe: %s\n", spe_data->program_name);
   9.263 +    SDL_SetError("[PS3->SPU] Could not create pthread for spe");
   9.264 +    return -1;
   9.265 +  }
   9.266 +
   9.267 +  if (spe_data->keepalive)
   9.268 +    SPE_WaitForMsg(_this, spe_data, SPU_READY);
   9.269 +}
   9.270 +
   9.271 +
   9.272 +/* Stop the SPE thread */
   9.273 +int SPE_Stop(_THIS, spu_data_t * spe_data)
   9.274 +{
   9.275 +  deprintf(2, "[PS3->SPU] Stop SPE: %s\n", spe_data->program_name);
   9.276 +  /* Wait for SPE thread to complete */
   9.277 +  deprintf(2, "[PS3->SPU] Wait for SPE thread to complete: %s\n", spe_data->program_name);
   9.278 +  if (pthread_join(spe_data->thread, NULL)) {
   9.279 +    deprintf(2, "[PS3->SPU] Failed joining the thread: %s\n", spe_data->program_name);
   9.280 +    SDL_SetError("[PS3->SPU] Failed joining the thread");
   9.281 +    return -1;
   9.282 +  }
   9.283 +
   9.284 +  return 0;
   9.285 +}
   9.286 +
   9.287 +/* Create SPE context and load program */
   9.288 +int SPE_Boot(_THIS, spu_data_t * spe_data)
   9.289 +{
   9.290 +  /* Create SPE context */
   9.291 +  deprintf(2, "[PS3->SPU] Create SPE Context: %s\n", spe_data->program_name);
   9.292 +  spe_data->ctx = spe_context_create(0, NULL);
   9.293 +  if (spe_data->ctx == NULL) {
   9.294 +    deprintf(2, "[PS3->SPU] Failed creating SPE context: %s\n", spe_data->program_name);
   9.295 +    SDL_SetError("[PS3->SPU] Failed creating SPE context");
   9.296 +    return -1;
   9.297 +  }
   9.298 +
   9.299 +  /* Load SPE object into SPE local store */
   9.300 +  deprintf(2, "[PS3->SPU] Load Program into SPE: %s\n", spe_data->program_name);
   9.301 +  if (spe_program_load(spe_data->ctx, &spe_data->program)) {
   9.302 +    deprintf(2, "[PS3->SPU] Failed loading program into SPE context: %s\n", spe_data->program_name);
   9.303 +    SDL_SetError
   9.304 +        ("[PS3->SPU] Failed loading program into SPE context");
   9.305 +    return -1;
   9.306 +  }
   9.307 +  spe_data->booted = 1;
   9.308 +  deprintf(2, "[PS3->SPU] SPE boot successful\n");
   9.309 +
   9.310 +  return 0;
   9.311 +}
   9.312 +
   9.313 +/* (Stop and) shutdown the SPE */
   9.314 +int SPE_Shutdown(_THIS, spu_data_t * spe_data)
   9.315 +{
   9.316 +  if (spe_data->keepalive && spe_data->booted) {
   9.317 +    SPE_SendMsg(_this, spe_data, SPU_EXIT);
   9.318 +    SPE_Stop(_this, spe_data);
   9.319 +  }
   9.320 +
   9.321 +  /* Destroy SPE context */
   9.322 +  deprintf(2, "[PS3->SPU] Destroy SPE context: %s\n", spe_data->program_name);
   9.323 +  if (spe_context_destroy(spe_data->ctx)) {
   9.324 +    deprintf(2, "[PS3->SPU] Failed destroying context: %s\n", spe_data->program_name);
   9.325 +    SDL_SetError("[PS3->SPU] Failed destroying context");
   9.326 +    return -1;
   9.327 +  }
   9.328 +  deprintf(2, "[PS3->SPU] SPE shutdown successful: %s\n", spe_data->program_name);
   9.329 +  return 0;
   9.330 +}
   9.331 +
   9.332 +/* Send message to the SPE via mailboxe */
   9.333 +int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg)
   9.334 +{
   9.335 +  deprintf(2, "[PS3->SPU] Sending message %u to %s\n", msg, spe_data->program_name);
   9.336 +  /* Send one message, block until message was sent */
   9.337 +  unsigned int spe_in_mbox_msgs[1];
   9.338 +  spe_in_mbox_msgs[0] = msg;
   9.339 +  int in_mbox_write = spe_in_mbox_write(spe_data->ctx, spe_in_mbox_msgs, 1, SPE_MBOX_ALL_BLOCKING);
   9.340 +
   9.341 +  if (1 > in_mbox_write) {
   9.342 +    deprintf(2, "[PS3->SPU] No message could be written to %s\n", spe_data->program_name);
   9.343 +    SDL_SetError("[PS3->SPU] No message could be written");
   9.344 +    return -1;
   9.345 +  }
   9.346 +  return 0;
   9.347 +}
   9.348 +
   9.349 +
   9.350 +/* Read 1 message from SPE, block until at least 1 message was received */
   9.351 +int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg)
   9.352 +{
   9.353 +  deprintf(2, "[PS3->SPU] Waiting for message from %s\n", spe_data->program_name);
   9.354 +  unsigned int out_messages[1];
   9.355 +  while (!spe_out_mbox_status(spe_data->ctx));
   9.356 +  int mbox_read = spe_out_mbox_read(spe_data->ctx, out_messages, 1);
   9.357 +  deprintf(2, "[PS3->SPU] Got message from %s, message was %u\n", spe_data->program_name, out_messages[0]);
   9.358 +  if (out_messages[0] == msg)
   9.359 +    return 0;
   9.360 +  else
   9.361 +    return -1;
   9.362 +}
   9.363 +
   9.364 +/* Re-runnable invocation of the spe_context_run call */
   9.365 +void SPE_RunContext(void *thread_argp)
   9.366 +{ 
   9.367 +  /* argp is the pointer to argument to be passed to the SPE program */
   9.368 +  spu_data_t *args = (spu_data_t *) thread_argp;
   9.369 +  deprintf(3, "[PS3->SPU] void* argp=0x%x\n", (unsigned int)args->argp);
   9.370 +  
   9.371 +  /* Run it.. */
   9.372 +  deprintf(2, "[PS3->SPU] Run SPE program: %s\n", args->program_name);
   9.373 +  if (spe_context_run
   9.374 +      (args->ctx, &args->entry, 0, (void *)args->argp, NULL,
   9.375 +       NULL) < 0) {
   9.376 +    deprintf(2, "[PS3->SPU] Failed running SPE context: %s\n", args->program_name);
   9.377 +    SDL_SetError("[PS3->SPU] Failed running SPE context: %s", args->program_name);
   9.378 +    exit(1);
   9.379 +  }
   9.380 +
   9.381 +  pthread_exit(NULL);
   9.382 +}
   9.383 +
   9.384 +/* vi: set ts=4 sw=4 expandtab: */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/video/ps3/SDL_ps3video.h	Fri May 29 09:50:21 2009 +0000
    10.3 @@ -0,0 +1,84 @@
    10.4 +/*
    10.5 +    SDL - Simple DirectMedia Layer
    10.6 +    Copyright (C) 1997-2009 Sam Lantinga
    10.7 +
    10.8 +    This library is free software; you can redistribute it and/or
    10.9 +    modify it under the terms of the GNU Lesser General Public
   10.10 +    License as published by the Free Software Foundation; either
   10.11 +    version 2.1 of the License, or (at your option) any later version.
   10.12 +
   10.13 +    This library is distributed in the hope that it will be useful,
   10.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   10.16 +    Lesser General Public License for more details.
   10.17 +
   10.18 +    You should have received a copy of the GNU Lesser General Public
   10.19 +    License along with this library; if not, write to the Free Software
   10.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   10.21 +
   10.22 +    Sam Lantinga
   10.23 +    slouken@libsdl.org
   10.24 +*/
   10.25 +#include "SDL_config.h"
   10.26 +
   10.27 +#include <libspe2.h>
   10.28 +
   10.29 +#ifndef _SDL_ps3video_h
   10.30 +#define _SDL_ps3video_h
   10.31 +
   10.32 +#include "../SDL_sysvideo.h"
   10.33 +
   10.34 +/* Debugging
   10.35 + * 0: No debug messages
   10.36 + * 1: Video debug messages
   10.37 + * 2: SPE debug messages
   10.38 + * 3: Memory adresses
   10.39 + */
   10.40 +#define DEBUG_LEVEL 2
   10.41 +
   10.42 +#ifdef DEBUG_LEVEL
   10.43 +#define deprintf( level, fmt, args... ) \
   10.44 +    do \
   10.45 +{ \
   10.46 +    if ( (unsigned)(level) <= DEBUG_LEVEL ) \
   10.47 +    { \
   10.48 +        fprintf( stdout, fmt, ##args ); \
   10.49 +        fflush( stdout ); \
   10.50 +    } \
   10.51 +} while ( 0 )
   10.52 +#else
   10.53 +#define deprintf( level, fmt, args... )
   10.54 +#endif
   10.55 +
   10.56 +/* Default framebuffer device on PS3 */
   10.57 +#define PS3DEV "/dev/fb0"
   10.58 +
   10.59 +/* SPU thread data */
   10.60 +typedef struct spu_data {
   10.61 +    spe_context_ptr_t ctx;
   10.62 +    pthread_t thread;
   10.63 +    spe_program_handle_t program;
   10.64 +    char * program_name;
   10.65 +    unsigned int booted;
   10.66 +    unsigned int keepalive;
   10.67 +    unsigned int entry;
   10.68 +    int error_code;
   10.69 +    void * argp;
   10.70 +} spu_data_t;
   10.71 +
   10.72 +/* Private display data */
   10.73 +typedef struct SDL_VideoData
   10.74 +{
   10.75 +    /* Framebuffer device descriptor */
   10.76 +    int fbdev;
   10.77 +    /* mmap'd access to fbdev */
   10.78 +    uint8_t * frame_buffer; 
   10.79 +    /* SPE threading stuff */
   10.80 +    spu_data_t * fb_thread_data;
   10.81 +    /* Framebuffer transfer data */
   10.82 +    volatile struct fb_writer_parms_t * fb_parms __attribute__((aligned(128)));
   10.83 +} SDL_VideoData;
   10.84 +
   10.85 +#endif /* _SDL_ps3video_h */
   10.86 +
   10.87 +/* vi: set ts=4 sw=4 expandtab: */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/video/ps3/spulibs/Makefile	Fri May 29 09:50:21 2009 +0000
    11.3 @@ -0,0 +1,83 @@
    11.4 +# This Makefile is for building the CELL BE SPU libs
    11.5 +# libfb_writer_spu.so, libyuv2rgb_spu.so, libbilin_scaler_spu.so
    11.6 +
    11.7 +# Toolchain
    11.8 +SPU_GCC=/usr/bin/spu-gcc
    11.9 +PPU_GCC=/usr/bin/gcc
   11.10 +PPU_EMBEDSPU=/usr/bin/embedspu
   11.11 +PPU_AR=/usr/bin/ar
   11.12 +PPU_LD=/usr/bin/ld
   11.13 +INSTALL=/usr/bin/install
   11.14 +
   11.15 +SPU_CFLAGS=-W -Wall -Winline -Wno-main -I. -I /usr/spu/include -I /opt/cell/sdk/usr/spu/include -finline-limit=10000 -Winline -ftree-vectorize -funroll-loops -fmodulo-sched -ffast-math -fPIC -O2
   11.16 +
   11.17 +# Usually /usr/lib, depending on your distribution
   11.18 +PREFIX=/usr/lib
   11.19 +
   11.20 +
   11.21 +all: libfb_writer_spu.a libfb_writer_spu.so
   11.22 +#				libyuv2rgb_spu.so libyuv2rgb_spu.a \
   11.23 +#				libbilin_scaler_spu.so libbilin_scaler_spu.a
   11.24 +
   11.25 +
   11.26 +# fb_writer
   11.27 +fb_writer_spu-embed.o: fb_writer.c spu_common.h
   11.28 +	$(SPU_GCC) $(SPU_CFLAGS) -o fb_writer_spu fb_writer.c -lm
   11.29 +	$(PPU_EMBEDSPU) -m32 fb_writer_spu fb_writer_spu fb_writer_spu-embed.o
   11.30 +
   11.31 +libfb_writer_spu.so: fb_writer_spu-embed.o
   11.32 +	$(PPU_LD) -o libfb_writer_spu.so -shared -soname=libfb_writer_spu.so fb_writer_spu-embed.o
   11.33 +
   11.34 +libfb_writer_spu.a: fb_writer_spu-embed.o
   11.35 +	$(PPU_AR) -qcs libfb_writer_spu.a fb_writer_spu-embed.o
   11.36 +
   11.37 +
   11.38 +# yuv2rgb_converter
   11.39 +yuv2rgb_spu-embed.o: yuv2rgb_converter.c spu_common.h
   11.40 +	$(SPU_GCC) $(SPU_CFLAGS) -o yuv2rgb_spu yuv2rgb_converter.c -lm
   11.41 +	$(PPU_EMBEDSPU) -m32 yuv2rgb_spu yuv2rgb_spu yuv2rgb_spu-embed.o
   11.42 +
   11.43 +libyuv2rgb_spu.a: yuv2rgb_spu-embed.o
   11.44 +	$(PPU_AR) -qcs libyuv2rgb_spu.a yuv2rgb_spu-embed.o
   11.45 +
   11.46 +libyuv2rgb_spu.so: yuv2rgb_spu-embed.o
   11.47 +	$(PPU_LD) -o libyuv2rgb_spu.so -shared -soname=libyuv2rgb_spu.so yuv2rgb_spu-embed.o
   11.48 +
   11.49 +
   11.50 +# bilin_scaler
   11.51 +bilin_scaler_spu-embed.o: bilin_scaler.c spu_common.h
   11.52 +	$(SPU_GCC) $(SPU_CFLAGS) -o bilin_scaler_spu bilin_scaler.c -lm
   11.53 +	$(PPU_EMBEDSPU) -m32 bilin_scaler_spu bilin_scaler_spu bilin_scaler_spu-embed.o
   11.54 +
   11.55 +libbilin_scaler_spu.a: bilin_scaler_spu-embed.o
   11.56 +	$(PPU_AR) -qcs libbilin_scaler_spu.a bilin_scaler_spu-embed.o
   11.57 +
   11.58 +libbilin_scaler_spu.so: bilin_scaler_spu-embed.o
   11.59 +	$(PPU_LD) -o libbilin_scaler_spu.so -shared -soname=libbilin_scaler_spu.so bilin_scaler_spu-embed.o
   11.60 +
   11.61 +install: libfb_writer_spu.a libfb_writer_spu.so
   11.62 +#				libyuv2rgb_spu.so libyuv2rgb_spu.a \
   11.63 +#				libbilin_scaler_spu.so libbilin_scaler_spu.a
   11.64 +	$(INSTALL) -c -m 0755 libfb_writer_spu.so $(PREFIX)/.
   11.65 +	$(INSTALL) -c -m 0655 libfb_writer_spu.a $(PREFIX)/.
   11.66 +#	$(INSTALL) -c -m 0755 libyuv2rgb_spu.so $(PREFIX)/.
   11.67 +#	$(INSTALL) -c -m 0655 libyuv2rgb_spu.a $(PREFIX)/.
   11.68 +#	$(INSTALL) -c -m 0755 libbilin_scaler_spu.so $(PREFIX)/.
   11.69 +#	$(INSTALL) -c -m 0655 libbilin_scaler_spu.a $(PREFIX)/.
   11.70 +
   11.71 +
   11.72 +uninstall: $(PREFIX)/libfb_writer_spu.so $(PREFIX)/libfb_writer_spu.a
   11.73 +#		$(PREFIX)/libyuv2rgb_spu.so $(PREFIX)/libyuv2rgb_spu.a \
   11.74 +#		$(PREFIX)/libbilin_scaler_spu.so $(PREFIX)/libbilin_scaler_spu.a
   11.75 +	rm -f $(PREFIX)/libfb_writer_spu.a
   11.76 +	rm -f $(PREFIX)/libfb_writer_spu.so
   11.77 +#	rm -f $(PREFIX)/libyuv2rgb_spu.so
   11.78 +#	rm -f $(PREFIX)/libyuv2rgb_spu.a
   11.79 +#	rm -f $(PREFIX)/libbilin_scaler_spu.so
   11.80 +#	rm -f $(PREFIX)/libbilin_scaler_spu.a
   11.81 +
   11.82 +
   11.83 +clean:
   11.84 +	rm -f bilin_scaler_spu-embed.o libbilin_scaler_spu.so libbilin_scaler_spu.a bilin_scaler_spu
   11.85 +	rm -f yuv2rgb_spu-embed.o libyuv2rgb_spu.so libyuv2rgb_spu.a yuv2rgb_spu
   11.86 +	rm -f fb_writer_spu-embed.o libfb_writer_spu.so libfb_writer_spu.a fb_writer_spu
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/video/ps3/spulibs/fb_writer.c	Fri May 29 09:50:21 2009 +0000
    12.3 @@ -0,0 +1,193 @@
    12.4 +/*
    12.5 + * SDL - Simple DirectMedia Layer
    12.6 + * CELL BE Support for PS3 Framebuffer
    12.7 + * Copyright (C) 2008, 2009 International Business Machines Corporation
    12.8 + *
    12.9 + * This library is free software; you can redistribute it and/or modify it
   12.10 + * under the terms of the GNU Lesser General Public License as published
   12.11 + * by the Free Software Foundation; either version 2.1 of the License, or
   12.12 + * (at your option) any later version.
   12.13 + *
   12.14 + * This library is distributed in the hope that it will be useful, but
   12.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of
   12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.17 + * Lesser General Public License for more details.
   12.18 + *
   12.19 + * You should have received a copy of the GNU Lesser General Public
   12.20 + * License along with this library; if not, write to the Free Software
   12.21 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
   12.22 + * USA
   12.23 + *
   12.24 + *  Martin Lowinski  <lowinski [at] de [dot] ibm [ibm] com>
   12.25 + *  Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
   12.26 + *  SPE code based on research by:
   12.27 + *  Rene Becker
   12.28 + *  Thimo Emmerich
   12.29 + */
   12.30 +
   12.31 +#include "spu_common.h"
   12.32 +
   12.33 +#include <spu_intrinsics.h>
   12.34 +#include <spu_mfcio.h>
   12.35 +#include <stdio.h>
   12.36 +#include <string.h>
   12.37 +
   12.38 +// Debugging
   12.39 +//#define DEBUG
   12.40 +
   12.41 +#ifdef DEBUG
   12.42 +#define deprintf(fmt, args... ) \
   12.43 +	fprintf( stdout, fmt, ##args ); \
   12.44 +	fflush( stdout );
   12.45 +#else
   12.46 +#define deprintf( fmt, args... )
   12.47 +#endif
   12.48 +
   12.49 +void cpy_to_fb(unsigned int);
   12.50 +
   12.51 +/* fb_writer_spu parms */
   12.52 +static volatile struct fb_writer_parms_t parms __attribute__ ((aligned(128)));
   12.53 +
   12.54 +/* Code running on SPU */
   12.55 +int main(unsigned long long spe_id __attribute__ ((unused)), unsigned long long argp __attribute__ ((unused)))
   12.56 +{
   12.57 +	deprintf("[SPU] fb_writer_spu is up... (on SPE #%llu)\n", spe_id);
   12.58 +	uint32_t ea_mfc, mbox;
   12.59 +	// send ready message
   12.60 +	spu_write_out_mbox(SPU_READY);
   12.61 +
   12.62 +	while (1) {
   12.63 +		/* Check mailbox */
   12.64 +		mbox = spu_read_in_mbox();
   12.65 +		deprintf("[SPU] Message is %u\n", mbox);
   12.66 +		switch (mbox) {
   12.67 +			case SPU_EXIT:
   12.68 +				deprintf("[SPU] fb_writer goes down...\n");
   12.69 +				return 0;
   12.70 +			case SPU_START:
   12.71 +				break;
   12.72 +			default:
   12.73 +				deprintf("[SPU] Cannot handle message\n");
   12.74 +				continue;
   12.75 +		}
   12.76 +
   12.77 +		/* Tag Manager setup */
   12.78 +		unsigned int tags;
   12.79 +		tags = mfc_multi_tag_reserve(5);
   12.80 +		if (tags == MFC_TAG_INVALID) {
   12.81 +			deprintf("[SPU] Failed to reserve mfc tags on fb_writer\n");
   12.82 +			return 0;
   12.83 +		}
   12.84 +
   12.85 +		/* Framebuffer parms */
   12.86 +		ea_mfc = spu_read_in_mbox();
   12.87 +		deprintf("[SPU] Message on fb_writer is %u\n", ea_mfc);
   12.88 +		spu_mfcdma32(&parms, (unsigned int)ea_mfc,
   12.89 +				sizeof(struct fb_writer_parms_t), tags,
   12.90 +				MFC_GET_CMD);
   12.91 +		deprintf("[SPU] argp = %u\n", (unsigned int)argp);
   12.92 +		DMA_WAIT_TAG(tags);
   12.93 +
   12.94 +		/* Copy parms->data to framebuffer */
   12.95 +		deprintf("[SPU] Copying to framebuffer started\n");
   12.96 +		cpy_to_fb(tags);
   12.97 +		deprintf("[SPU] Copying to framebuffer done!\n");
   12.98 +
   12.99 +		mfc_multi_tag_release(tags, 5);
  12.100 +		deprintf("[SPU] fb_writer_spu... done!\n");
  12.101 +		/* Send FIN msg */
  12.102 +		spu_write_out_mbox(SPU_FIN);
  12.103 +	}
  12.104 +
  12.105 +	return 0;
  12.106 +}
  12.107 +
  12.108 +void cpy_to_fb(unsigned int tag_id_base)
  12.109 +{
  12.110 +	unsigned int i;
  12.111 +	unsigned char current_buf;
  12.112 +	uint8_t *in = parms.data;
  12.113 +
  12.114 +	/* Align fb pointer which was centered before */
  12.115 +	uint8_t *fb =
  12.116 +	    (unsigned char *)((unsigned int)parms.center & 0xFFFFFFF0);
  12.117 +
  12.118 +	uint32_t bounded_input_height = parms.bounded_input_height;
  12.119 +	uint32_t bounded_input_width = parms.bounded_input_width;
  12.120 +	uint32_t fb_pixel_size = parms.fb_pixel_size;
  12.121 +
  12.122 +	uint32_t out_line_stride = parms.out_line_stride;
  12.123 +	uint32_t in_line_stride = parms.in_line_stride;
  12.124 +	uint32_t in_line_size = bounded_input_width * fb_pixel_size;
  12.125 +
  12.126 +	current_buf = 0;
  12.127 +
  12.128 +	/* Local store buffer */
  12.129 +	static volatile uint8_t buf[4][BUFFER_SIZE]
  12.130 +	    __attribute__ ((aligned(128)));
  12.131 +	/* do 4-times multibuffering using DMA list, process in two steps */
  12.132 +	for (i = 0; i < bounded_input_height >> 2; i++) {
  12.133 +		/* first buffer */
  12.134 +		DMA_WAIT_TAG(tag_id_base + 1);
  12.135 +		// retrieve buffer
  12.136 +		spu_mfcdma32(buf[0], (unsigned int)in, in_line_size,
  12.137 +			     tag_id_base + 1, MFC_GETB_CMD);
  12.138 +		DMA_WAIT_TAG(tag_id_base + 1);
  12.139 +		// store buffer
  12.140 +		spu_mfcdma32(buf[0], (unsigned int)fb, in_line_size,
  12.141 +			     tag_id_base + 1, MFC_PUTB_CMD);
  12.142 +		in += in_line_stride;
  12.143 +		fb += out_line_stride;
  12.144 +		deprintf("[SPU] 1st buffer copied in=0x%x, fb=0x%x\n", in,
  12.145 +		       fb);
  12.146 +
  12.147 +		/* second buffer */
  12.148 +		DMA_WAIT_TAG(tag_id_base + 2);
  12.149 +		// retrieve buffer
  12.150 +		spu_mfcdma32(buf[1], (unsigned int)in, in_line_size,
  12.151 +			     tag_id_base + 2, MFC_GETB_CMD);
  12.152 +		DMA_WAIT_TAG(tag_id_base + 2);
  12.153 +		// store buffer
  12.154 +		spu_mfcdma32(buf[1], (unsigned int)fb, in_line_size,
  12.155 +			     tag_id_base + 2, MFC_PUTB_CMD);
  12.156 +		in += in_line_stride;
  12.157 +		fb += out_line_stride;
  12.158 +		deprintf("[SPU] 2nd buffer copied in=0x%x, fb=0x%x\n", in,
  12.159 +		       fb);
  12.160 +
  12.161 +		/* third buffer */
  12.162 +		DMA_WAIT_TAG(tag_id_base + 3);
  12.163 +		// retrieve buffer
  12.164 +		spu_mfcdma32(buf[2], (unsigned int)in, in_line_size,
  12.165 +			     tag_id_base + 3, MFC_GETB_CMD);
  12.166 +		DMA_WAIT_TAG(tag_id_base + 3);
  12.167 +		// store buffer
  12.168 +		spu_mfcdma32(buf[2], (unsigned int)fb, in_line_size,
  12.169 +			     tag_id_base + 3, MFC_PUTB_CMD);
  12.170 +		in += in_line_stride;
  12.171 +		fb += out_line_stride;
  12.172 +		deprintf("[SPU] 3rd buffer copied in=0x%x, fb=0x%x\n", in,
  12.173 +		       fb);
  12.174 +
  12.175 +		/* fourth buffer */
  12.176 +		DMA_WAIT_TAG(tag_id_base + 4);
  12.177 +		// retrieve buffer
  12.178 +		spu_mfcdma32(buf[3], (unsigned int)in, in_line_size,
  12.179 +			     tag_id_base + 4, MFC_GETB_CMD);
  12.180 +		DMA_WAIT_TAG(tag_id_base + 4);
  12.181 +		// store buffer
  12.182 +		spu_mfcdma32(buf[3], (unsigned int)fb, in_line_size,
  12.183 +			     tag_id_base + 4, MFC_PUTB_CMD);
  12.184 +		in += in_line_stride;
  12.185 +		fb += out_line_stride;
  12.186 +		deprintf("[SPU] 4th buffer copied in=0x%x, fb=0x%x\n", in,
  12.187 +		       fb);
  12.188 +		deprintf("[SPU] Loop #%i, bounded_input_height=%i\n", i,
  12.189 +		       bounded_input_height >> 2);
  12.190 +	}
  12.191 +	DMA_WAIT_TAG(tag_id_base + 2);
  12.192 +	DMA_WAIT_TAG(tag_id_base + 3);
  12.193 +	DMA_WAIT_TAG(tag_id_base + 4);
  12.194 +}
  12.195 +
  12.196 +
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/video/ps3/spulibs/spu_common.h	Fri May 29 09:50:21 2009 +0000
    13.3 @@ -0,0 +1,108 @@
    13.4 +/*
    13.5 + * SDL - Simple DirectMedia Layer
    13.6 + * CELL BE Support for PS3 Framebuffer
    13.7 + * Copyright (C) 2008, 2009 International Business Machines Corporation
    13.8 + *
    13.9 + * This library is free software; you can redistribute it and/or modify it
   13.10 + * under the terms of the GNU Lesser General Public License as published
   13.11 + * by the Free Software Foundation; either version 2.1 of the License, or
   13.12 + * (at your option) any later version.
   13.13 + *
   13.14 + * This library is distributed in the hope that it will be useful, but
   13.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of
   13.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.17 + * Lesser General Public License for more details.
   13.18 + *
   13.19 + * You should have received a copy of the GNU Lesser General Public
   13.20 + * License along with this library; if not, write to the Free Software
   13.21 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
   13.22 + * USA
   13.23 + *
   13.24 + *  Martin Lowinski  <lowinski [at] de [dot] ibm [ibm] com>
   13.25 + *  Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
   13.26 + *  SPE code based on research by:
   13.27 + *  Rene Becker
   13.28 + *  Thimo Emmerich
   13.29 + */
   13.30 +
   13.31 +/* Common definitions/makros for SPUs */
   13.32 +
   13.33 +#ifndef _SPU_COMMON_H
   13.34 +#define _SPU_COMMON_H
   13.35 +
   13.36 +#include <stdio.h>
   13.37 +#include <stdint.h>
   13.38 +#include <string.h>
   13.39 +
   13.40 +/* Tag management */
   13.41 +#define DMA_WAIT_TAG(_tag)     \
   13.42 +    mfc_write_tag_mask(1<<(_tag)); \
   13.43 +    mfc_read_tag_status_all();
   13.44 +
   13.45 +/* SPU mailbox messages */
   13.46 +#define SPU_READY	0
   13.47 +#define SPU_START	1
   13.48 +#define SPU_FIN		2
   13.49 +#define SPU_EXIT	3
   13.50 +
   13.51 +/* Tags */
   13.52 +#define RETR_BUF	0
   13.53 +#define STR_BUF		1
   13.54 +#define TAG_INIT	2
   13.55 +
   13.56 +/* Buffersizes */
   13.57 +#define MAX_HDTV_WIDTH 1920
   13.58 +#define MAX_HDTV_HEIGHT 1080
   13.59 +/* One stride of HDTV */
   13.60 +#define BUFFER_SIZE 7680
   13.61 +
   13.62 +/* fb_writer ppu/spu exchange parms */
   13.63 +struct fb_writer_parms_t {
   13.64 +	uint8_t *data;
   13.65 +	uint8_t *center;
   13.66 +	uint32_t out_line_stride;
   13.67 +	uint32_t in_line_stride;
   13.68 +	uint32_t bounded_input_height;
   13.69 +	uint32_t bounded_input_width;
   13.70 +	uint32_t fb_pixel_size;
   13.71 +
   13.72 +	/* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
   13.73 +	char padding[4];
   13.74 +} __attribute__((aligned(128)));
   13.75 +
   13.76 +/* yuv2rgb ppu/spu exchange parms */
   13.77 +struct yuv2rgb_parms_t {
   13.78 +	uint8_t* y_plane;
   13.79 +	uint8_t* v_plane;
   13.80 +	uint8_t* u_plane;
   13.81 +
   13.82 +	uint8_t* dstBuffer;
   13.83 +
   13.84 +	unsigned int src_pixel_width;
   13.85 +	unsigned int src_pixel_height;
   13.86 +
   13.87 +	/* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
   13.88 +	char padding[128 - ((4 * sizeof(uint8_t *) + 2 * sizeof(unsigned int)) & 0x7F)];
   13.89 +} __attribute__((aligned(128)));
   13.90 +
   13.91 +/* bilin_scaler ppu/spu exchange parms */
   13.92 +struct scale_parms_t {
   13.93 +	uint8_t* y_plane;
   13.94 +	uint8_t* v_plane;
   13.95 +	uint8_t* u_plane;
   13.96 +
   13.97 +	uint8_t* dstBuffer;
   13.98 +
   13.99 +	unsigned int src_pixel_width;
  13.100 +	unsigned int src_pixel_height;
  13.101 +
  13.102 +	unsigned int dst_pixel_width;
  13.103 +	unsigned int dst_pixel_height;
  13.104 +
  13.105 +	/* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
  13.106 +	char padding[128 - ((4 * sizeof(uint8_t *) + 4 * sizeof(unsigned int)) & 0x7F)];
  13.107 +} __attribute__((aligned(128)));
  13.108 +
  13.109 +#endif /* _SPU_COMMON_H */
  13.110 +
  13.111 +