Working 1080p, 720p, 480p videomodes and double buffering.
--- 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 */