comparison src/video/ps3/SDL_ps3render.c @ 3148:104786a909a2 gsoc2009_ps3

Scaling (bilinear) of YUV-Textures working.
author Martin Lowinski <martin@goldtopf.org>
date Fri, 19 Jun 2009 05:22:00 +0000
parents a80760096937
children 0cf7bff804ad
comparison
equal deleted inserted replaced
3147:a80760096937 3148:104786a909a2
38 #include <asm/ps3fb.h> 38 #include <asm/ps3fb.h>
39 39
40 40
41 /* Stores the executable name */ 41 /* Stores the executable name */
42 extern spe_program_handle_t yuv2rgb_spu; 42 extern spe_program_handle_t yuv2rgb_spu;
43 extern spe_program_handle_t bilin_scaler_spu;
43 44
44 /* SDL surface based renderer implementation */ 45 /* SDL surface based renderer implementation */
45 46
46 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window, 47 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window,
47 Uint32 flags); 48 Uint32 flags);
101 102
102 /* Use two buffers in fb? res < 720p */ 103 /* Use two buffers in fb? res < 720p */
103 unsigned int double_buffering; 104 unsigned int double_buffering;
104 105
105 /* SPE threading stuff */ 106 /* SPE threading stuff */
106 spu_data_t * converter_thread_data; 107 spu_data_t *converter_thread_data;
108 spu_data_t *scaler_thread_data;
109
107 /* YUV converting transfer data */ 110 /* YUV converting transfer data */
108 volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128))); 111 volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128)));
112 /* Scaler transfer data */
113 volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128)));
109 } SDL_PS3_RenderData; 114 } SDL_PS3_RenderData;
110 115
111 typedef struct 116 typedef struct
112 { 117 {
113 //SDL_PixelFormat * format; 118 //SDL_PixelFormat * format;
205 210
206 data->current_screen = 0; 211 data->current_screen = 0;
207 212
208 /* Create SPU parms structure */ 213 /* Create SPU parms structure */
209 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); 214 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t));
210 if (data->converter_parms == NULL) { 215 data->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t));
216 if (data->converter_parms == NULL || data->scaler_parms == NULL) {
211 SDL_PS3_DestroyRenderer(renderer); 217 SDL_PS3_DestroyRenderer(renderer);
212 SDL_OutOfMemory(); 218 SDL_OutOfMemory();
213 return NULL; 219 return NULL;
214 } 220 }
215 221
216 /* Set up the SPEs */ 222 /* Set up the SPEs */
217 data->converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); 223 data->converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
218 if (data->converter_thread_data == NULL) { 224 data->scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
225 if (data->converter_thread_data == NULL || data->scaler_thread_data == NULL) {
219 SDL_PS3_DestroyRenderer(renderer); 226 SDL_PS3_DestroyRenderer(renderer);
220 SDL_OutOfMemory(); 227 SDL_OutOfMemory();
221 return NULL; 228 return NULL;
222 } 229 }
230
231 data->scaler_thread_data->program = bilin_scaler_spu;
232 data->scaler_thread_data->program_name = "bilin_scaler_spu";
233 data->scaler_thread_data->keepalive = 0;
234 data->scaler_thread_data->booted = 0;
223 235
224 data->converter_thread_data->program = yuv2rgb_spu; 236 data->converter_thread_data->program = yuv2rgb_spu;
225 data->converter_thread_data->program_name = "yuv2rgb_spu"; 237 data->converter_thread_data->program_name = "yuv2rgb_spu";
226 data->converter_thread_data->keepalive = 1; 238 data->converter_thread_data->keepalive = 1;
227 data->converter_thread_data->booted = 0; 239 data->converter_thread_data->booted = 0;
287 default: 299 default:
288 /* We should never get here (caught above) */ 300 /* We should never get here (caught above) */
289 break; 301 break;
290 } 302 }
291 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV) 303 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
292 && texture->w % 8 == 0 && texture->h % 8 == 0) { 304 && texture->w % 16 == 0 && texture->h % 16 == 0) {
293 data->accelerated = 1; 305 data->accelerated = 1;
294 } 306 }
295 } else { 307 } else {
296 data->pixels = NULL; 308 data->pixels = NULL;
297 data->pixels = SDL_malloc(texture->h * data->pitch); 309 data->pixels = SDL_malloc(texture->h * data->pitch);
335 return SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch); 347 return SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch);
336 } else { 348 } else {
337 Uint8 *src, *dst; 349 Uint8 *src, *dst;
338 int row; 350 int row;
339 size_t length; 351 size_t length;
340 int dstpitch;
341 Uint8 *dstpixels; 352 Uint8 *dstpixels;
342 353
343 src = (Uint8 *) pixels; 354 src = (Uint8 *) pixels;
344 dst = (Uint8 *) dstpixels + rect->y * dstpitch + rect->x 355 dst = (Uint8 *) dstpixels + rect->y * data->pitch + rect->x
345 * SDL_BYTESPERPIXEL(texture->format); 356 * SDL_BYTESPERPIXEL(texture->format);
346 length = rect->w * SDL_BYTESPERPIXEL(texture->format); 357 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
347 for (row = 0; row < rect->h; ++row) { 358 for (row = 0; row < rect->h; ++row) {
348 SDL_memcpy(dst, src, length); 359 SDL_memcpy(dst, src, length);
349 src += pitch; 360 src += pitch;
350 dst += dstpitch; 361 dst += data->pitch;
351 } 362 }
352 } 363 }
353 deprintf(1, "-PS3_UpdateTexture()\n"); 364 deprintf(1, "-PS3_UpdateTexture()\n");
354 return 0; 365 return 0;
355 } 366 }
493 deprintf(1, "dstrect->w = %u\n", dstrect->w); 504 deprintf(1, "dstrect->w = %u\n", dstrect->w);
494 deprintf(1, "dstrect->h = %u\n", dstrect->h); 505 deprintf(1, "dstrect->h = %u\n", dstrect->h);
495 deprintf(1, "dstrect->x = %u\n", dstrect->x); 506 deprintf(1, "dstrect->x = %u\n", dstrect->x);
496 deprintf(1, "dstrect->y = %u\n", dstrect->y); 507 deprintf(1, "dstrect->y = %u\n", dstrect->y);
497 508
509 deprintf(1, "texture->w = %u\n", texture->w);
510 deprintf(1, "texture->h = %u\n", texture->h);
511
498 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 512 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
499 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); 513 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n");
500 if (txdata->accelerated) { 514 if (txdata->accelerated) {
501 deprintf(1, "Use SPE for scaling/converting\n"); 515 deprintf(1, "Use SPE for scaling/converting\n");
502 if (srcrect-> != dstrect->w || srcrect->h != dstrect->h) { 516
503 // do scaling 517 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv;
504 }
505
506 Uint8 *lum, *Cr, *Cb; 518 Uint8 *lum, *Cr, *Cb;
507 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; 519 Uint8 *scaler_out = NULL;
520 Uint8 *dstpixels;
508 switch (swdata->format) { 521 switch (swdata->format) {
509 case SDL_PIXELFORMAT_YV12: 522 case SDL_PIXELFORMAT_YV12:
510 lum = swdata->planes[0]; 523 lum = swdata->planes[0];
511 Cr = swdata->planes[1]; 524 Cr = swdata->planes[1];
512 Cb = swdata->planes[2]; 525 Cb = swdata->planes[2];
518 break; 531 break;
519 default: 532 default:
520 return -1; 533 return -1;
521 } 534 }
522 535
523 data->converter_parms->y_plane = lum; 536 if (srcrect->w != dstrect->w || srcrect->h != dstrect->h) {
524 data->converter_parms->v_plane = Cr; 537 /* Alloc mem for scaled YUV picture */
525 data->converter_parms->u_plane = Cb; 538 scaler_out = (Uint8 *) memalign(16, dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 1));
526 data->converter_parms->src_pixel_width = swdata->w; 539 if (scaler_out == NULL) {
527 data->converter_parms->src_pixel_height = swdata->h; 540 SDL_OutOfMemory();
528 data->converter_parms->dstBuffer = (Uint8 *)data->screen->pixels; 541 return -1;
542 }
543
544 /* Set parms for scaling */
545 data->scaler_parms->src_pixel_width = srcrect->w;
546 data->scaler_parms->src_pixel_height = srcrect->h;
547 data->scaler_parms->dst_pixel_width = dstrect->w;
548 data->scaler_parms->dst_pixel_height = dstrect->h;
549 data->scaler_parms->y_plane = lum;
550 data->scaler_parms->v_plane = Cr;
551 data->scaler_parms->u_plane = Cb;
552 data->scaler_parms->dstBuffer = scaler_out;
553 data->scaler_thread_data->argp = (void *)data->scaler_parms;
554
555 /* Scale the YUV overlay to given size */
556 SPE_Start(data->scaler_thread_data);
557 SPE_Stop(data->scaler_thread_data);
558
559 /* Set parms for converting after scaling */
560 data->converter_parms->y_plane = scaler_out;
561 data->converter_parms->v_plane = scaler_out + dstrect->w * dstrect->h;
562 data->converter_parms->u_plane = scaler_out + dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 2);
563 } else {
564 data->converter_parms->y_plane = lum;
565 data->converter_parms->v_plane = Cr;
566 data->converter_parms->u_plane = Cb;
567 }
568
569 dstpixels = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x
570 * SDL_BYTESPERPIXEL(texture->format);
571 data->converter_parms->src_pixel_width = dstrect->w;
572 data->converter_parms->src_pixel_height = dstrect->h;
573 data->converter_parms->dstBuffer = dstpixels/*(Uint8 *)data->screen->pixels*/;
529 data->converter_thread_data->argp = (void *)data->converter_parms; 574 data->converter_thread_data->argp = (void *)data->converter_parms;
530 575
531 /* Convert YUV overlay to RGB */ 576 /* Convert YUV texture to RGB */
532 SPE_SendMsg(data->converter_thread_data, SPU_START); 577 SPE_SendMsg(data->converter_thread_data, SPU_START);
533 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); 578 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp);
534 579
535 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); 580 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN);
581 if (scaler_out) {
582 free(scaler_out);
583 }
536 } else { 584 } else {
537 deprintf(1, "Use software for scaling/converting\n"); 585 deprintf(1, "Use software for scaling/converting\n");
586 Uint8 *dst;
587 /* FIXME: Not good */
588 dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x
589 * SDL_BYTESPERPIXEL(texture->format);
538 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format, 590 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format,
539 dstrect->w, dstrect->h, data->screen->pixels, 591 dstrect->w, dstrect->h, dst/*data->screen->pixels*/,
540 data->screen->pitch); 592 data->screen->pitch);
541 } 593 }
542 } else { 594 } else {
543 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n"); 595 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n");
544 596
545 Uint8 *src, *dst; 597 Uint8 *src, *dst;
546 int row; 598 int row;
547 size_t length; 599 size_t length;
548 int dstpitch;
549 Uint8 *dstpixels; 600 Uint8 *dstpixels;
550 601
551 src = (Uint8 *) txdata->pixels; 602 src = (Uint8 *) txdata->pixels;
552 dst = (Uint8 *) data->screen->pixels + dstrect->y * dstpitch + dstrect->x 603 dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x
553 * SDL_BYTESPERPIXEL(texture->format); 604 * SDL_BYTESPERPIXEL(texture->format);
554 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format); 605 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format);
555 for (row = 0; row < dstrect->h; ++row) { 606 for (row = 0; row < dstrect->h; ++row) {
556 //deprintf(1, "Copying texture to screen...\n");
557 SDL_memcpy(dst, src, length); 607 SDL_memcpy(dst, src, length);
558 src += dstpitch; 608 src += txdata->pitch;
559 dst += dstpitch; 609 dst += data->screen->pitch;
560 } 610 }
561 } 611 }
562 612
563 deprintf(1, "-SDL_PS3_RenderCopy()\n"); 613 deprintf(1, "-SDL_PS3_RenderCopy()\n");
564 return 0; 614 return 0;
662 SDL_FreeSurface(data->screen); 712 SDL_FreeSurface(data->screen);
663 } 713 }
664 } 714 }
665 715
666 /* Shutdown SPE and related resources */ 716 /* Shutdown SPE and related resources */
717 if (data->scaler_thread_data) {
718 free((void *)data->scaler_thread_data);
719 }
720 if (data->scaler_parms) {
721 free((void *)data->scaler_parms);
722 }
667 if (data->converter_thread_data) { 723 if (data->converter_thread_data) {
668 SPE_Shutdown(data->converter_thread_data); 724 SPE_Shutdown(data->converter_thread_data);
669 free((void *)data->converter_thread_data); 725 free((void *)data->converter_thread_data);
670 } 726 }
671 if (data->converter_parms) { 727 if (data->converter_parms) {