src/video/ps2gs/SDL_gsyuv.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 21 Feb 2006 08:46:50 +0000
changeset 1402 d910939febfa
parent 1361 19418e4422cb
child 1643 51038e80ae59
permissions -rw-r--r--
Use consistent identifiers for the various platforms we support.
Make sure every source file includes SDL_config.h, so the proper system
headers are chosen.
slouken@70
     1
/*
slouken@70
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@70
     4
slouken@70
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@70
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@70
     9
slouken@70
    10
    This library is distributed in the hope that it will be useful,
slouken@70
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@70
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@70
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@70
    18
slouken@70
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@70
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@70
    23
slouken@70
    24
/* This is the Playstation 2 implementation of YUV video overlays */
slouken@70
    25
slouken@70
    26
#include <fcntl.h>
slouken@70
    27
#include <unistd.h>
slouken@70
    28
#include <sys/ioctl.h>
slouken@70
    29
#include <sys/mman.h>
slouken@70
    30
#include <asm/page.h>		/* For definition of PAGE_SIZE */
slouken@70
    31
slouken@70
    32
#include "SDL_video.h"
slouken@70
    33
#include "SDL_gsyuv_c.h"
slouken@1361
    34
#include "../SDL_yuvfuncs.h"
slouken@70
    35
slouken@70
    36
/* The maximum number of 16x16 pixel block converted at once */
slouken@70
    37
#define MAX_MACROBLOCKS	1024	/* 2^10 macroblocks at once */
slouken@70
    38
slouken@70
    39
/* The functions used to manipulate video overlays */
slouken@70
    40
static struct private_yuvhwfuncs gs_yuvfuncs = {
slouken@70
    41
	GS_LockYUVOverlay,
slouken@70
    42
	GS_UnlockYUVOverlay,
slouken@70
    43
	GS_DisplayYUVOverlay,
slouken@70
    44
	GS_FreeYUVOverlay
slouken@70
    45
};
slouken@70
    46
slouken@70
    47
struct private_yuvhwdata {
slouken@70
    48
	int ipu_fd;
slouken@70
    49
	Uint8 *pixels;
slouken@70
    50
	int macroblocks;
slouken@70
    51
	int dma_len;
slouken@70
    52
	caddr_t dma_mem;
slouken@70
    53
	caddr_t ipu_imem;
slouken@70
    54
	caddr_t ipu_omem;
slouken@70
    55
	caddr_t dma_tags;
slouken@70
    56
	unsigned long long *stretch_x1y1;
slouken@70
    57
	unsigned long long *stretch_x2y2;
slouken@70
    58
	struct ps2_plist plist;
slouken@70
    59
slouken@70
    60
	/* These are just so we don't have to allocate them separately */
slouken@70
    61
	Uint16 pitches[3];
slouken@70
    62
	Uint8 *planes[3];
slouken@70
    63
};
slouken@70
    64
slouken@70
    65
static int power_of_2(int value)
slouken@70
    66
{
slouken@70
    67
	int shift;
slouken@70
    68
slouken@70
    69
	for ( shift = 0; (1<<shift) < value; ++shift ) {
slouken@70
    70
		/* Keep looking */ ;
slouken@70
    71
	}
slouken@70
    72
	return(shift);
slouken@70
    73
}
slouken@70
    74
slouken@70
    75
SDL_Overlay *GS_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
slouken@70
    76
{
slouken@70
    77
	SDL_Overlay *overlay;
slouken@70
    78
	struct private_yuvhwdata *hwdata;
slouken@70
    79
	int map_offset;
slouken@70
    80
	unsigned long long *tags;
slouken@70
    81
	caddr_t base;
slouken@70
    82
	int bpp;
slouken@70
    83
	int fbp, fbw, psm;
slouken@70
    84
	int x, y, w, h;
slouken@70
    85
	int pnum;
slouken@70
    86
	struct ps2_packet *packet;
slouken@70
    87
	struct ps2_packet tex_packet;
slouken@70
    88
slouken@70
    89
	/* We can only decode blocks of 16x16 pixels */
slouken@70
    90
	if ( (width & 15) || (height & 15) ) {
slouken@70
    91
		SDL_SetError("Overlay width/height must be multiples of 16");
slouken@70
    92
		return(NULL);
slouken@70
    93
	}
slouken@70
    94
	/* Make sure the image isn't too large for a single DMA transfer */
slouken@70
    95
	if ( ((width/16) * (height/16)) > MAX_MACROBLOCKS ) {
slouken@70
    96
		SDL_SetError("Overlay too large (maximum size: %d pixels)",
slouken@70
    97
		             MAX_MACROBLOCKS * 16 * 16);
slouken@70
    98
		return(NULL);
slouken@70
    99
	}
slouken@70
   100
slouken@70
   101
	/* Double-check the requested format.  For simplicity, we'll only
slouken@70
   102
	   support planar YUV formats.
slouken@70
   103
	 */
slouken@70
   104
	switch (format) {
slouken@70
   105
	    case SDL_YV12_OVERLAY:
slouken@70
   106
	    case SDL_IYUV_OVERLAY:
slouken@70
   107
		/* Supported planar YUV format */
slouken@70
   108
		break;
slouken@70
   109
	    default:
slouken@70
   110
		SDL_SetError("Unsupported YUV format");
slouken@70
   111
		return(NULL);
slouken@70
   112
	}
slouken@70
   113
slouken@70
   114
	/* Create the overlay structure */
slouken@1336
   115
	overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
slouken@70
   116
	if ( overlay == NULL ) {
slouken@70
   117
		SDL_OutOfMemory();
slouken@70
   118
		return(NULL);
slouken@70
   119
	}
slouken@1336
   120
	SDL_memset(overlay, 0, (sizeof *overlay));
slouken@70
   121
slouken@70
   122
	/* Fill in the basic members */
slouken@70
   123
	overlay->format = format;
slouken@70
   124
	overlay->w = width;
slouken@70
   125
	overlay->h = height;
slouken@70
   126
slouken@70
   127
	/* Set up the YUV surface function structure */
slouken@70
   128
	overlay->hwfuncs = &gs_yuvfuncs;
slouken@70
   129
	overlay->hw_overlay = 1;
slouken@70
   130
slouken@70
   131
	/* Create the pixel data */
slouken@1336
   132
	hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
slouken@70
   133
	overlay->hwdata = hwdata;
slouken@70
   134
	if ( hwdata == NULL ) {
slouken@70
   135
		SDL_FreeYUVOverlay(overlay);
slouken@70
   136
		SDL_OutOfMemory();
slouken@70
   137
		return(NULL);
slouken@70
   138
	}
slouken@70
   139
	hwdata->ipu_fd = -1;
slouken@1336
   140
	hwdata->pixels = (Uint8 *)SDL_malloc(width*height*2);
slouken@70
   141
	if ( hwdata->pixels == NULL ) {
slouken@70
   142
		SDL_FreeYUVOverlay(overlay);
slouken@70
   143
		SDL_OutOfMemory();
slouken@70
   144
		return(NULL);
slouken@70
   145
	}
slouken@70
   146
	hwdata->macroblocks = (width/16) * (height/16);
slouken@70
   147
slouken@70
   148
	/* Find the pitch and offset values for the overlay */
slouken@70
   149
	overlay->pitches = hwdata->pitches;
slouken@70
   150
	overlay->pixels = hwdata->planes;
slouken@70
   151
	switch (format) {
slouken@70
   152
	    case SDL_YV12_OVERLAY:
slouken@70
   153
	    case SDL_IYUV_OVERLAY:
slouken@70
   154
		overlay->pitches[0] = overlay->w;
slouken@70
   155
		overlay->pitches[1] = overlay->pitches[0] / 2;
slouken@70
   156
		overlay->pitches[2] = overlay->pitches[0] / 2;
slouken@70
   157
	        overlay->pixels[0] = hwdata->pixels;
slouken@70
   158
	        overlay->pixels[1] = overlay->pixels[0] +
slouken@70
   159
		                     overlay->pitches[0] * overlay->h;
slouken@70
   160
	        overlay->pixels[2] = overlay->pixels[1] +
slouken@70
   161
		                     overlay->pitches[1] * overlay->h / 2;
slouken@70
   162
		overlay->planes = 3;
slouken@70
   163
		break;
slouken@70
   164
	    default:
slouken@70
   165
		/* We should never get here (caught above) */
slouken@70
   166
		break;
slouken@70
   167
	}
slouken@70
   168
slouken@70
   169
	/* Theoretically we could support several concurrent decode
slouken@70
   170
	   streams queueing up on the same file descriptor, but for
slouken@70
   171
	   simplicity we'll support only one.  Opening the IPU more
slouken@70
   172
	   than once will fail with EBUSY.
slouken@70
   173
	*/
slouken@70
   174
	hwdata->ipu_fd = open("/dev/ps2ipu", O_RDWR);
slouken@70
   175
	if ( hwdata->ipu_fd < 0 ) {
slouken@70
   176
		SDL_FreeYUVOverlay(overlay);
slouken@70
   177
		SDL_SetError("Playstation 2 IPU busy");
slouken@70
   178
		return(NULL);
slouken@70
   179
	}
slouken@70
   180
slouken@70
   181
	/* Allocate a DMA area for pixel conversion */
slouken@70
   182
	bpp = this->screen->format->BytesPerPixel;
slouken@70
   183
	map_offset = (mapped_len + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
slouken@70
   184
	hwdata->dma_len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8) +
slouken@70
   185
	                  width * height * bpp +
slouken@70
   186
	                  hwdata->macroblocks * (16 * sizeof(long long)) +
slouken@70
   187
	                  12 * sizeof(long long);
slouken@70
   188
	hwdata->dma_mem = mmap(0, hwdata->dma_len, PROT_READ|PROT_WRITE,
slouken@70
   189
	                       MAP_SHARED, memory_fd, map_offset);
slouken@70
   190
	if ( hwdata->dma_mem == MAP_FAILED ) {
slouken@70
   191
		hwdata->ipu_imem = (caddr_t)0;
slouken@70
   192
		SDL_FreeYUVOverlay(overlay);
slouken@70
   193
		SDL_SetError("Unable to map %d bytes for DMA", hwdata->dma_len);
slouken@70
   194
		return(NULL);
slouken@70
   195
	}
slouken@70
   196
	hwdata->ipu_imem = hwdata->dma_mem;
slouken@70
   197
	hwdata->ipu_omem = hwdata->ipu_imem +
slouken@70
   198
	                   hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8);
slouken@70
   199
	hwdata->dma_tags = hwdata->ipu_omem + width * height * bpp;
slouken@70
   200
slouken@70
   201
	/* Allocate memory for the DMA packets */
slouken@70
   202
	hwdata->plist.num = hwdata->macroblocks * 4 + 1;
slouken@1336
   203
	hwdata->plist.packet = (struct ps2_packet *)SDL_malloc(
slouken@70
   204
	                       hwdata->plist.num*sizeof(struct ps2_packet));
slouken@70
   205
	if ( ! hwdata->plist.packet ) {
slouken@70
   206
		SDL_FreeYUVOverlay(overlay);
slouken@70
   207
		SDL_OutOfMemory();
slouken@70
   208
		return(NULL);
slouken@70
   209
	}
slouken@70
   210
	pnum = 0;
slouken@70
   211
	packet = hwdata->plist.packet;
slouken@70
   212
slouken@70
   213
	/* Set up the tags to send the image to the screen */
slouken@70
   214
	tags = (unsigned long long *)hwdata->dma_tags;
slouken@70
   215
	base = hwdata->ipu_omem;
slouken@70
   216
	fbp = screen_image.fbp;
slouken@70
   217
	fbw = screen_image.fbw;
slouken@70
   218
	psm = screen_image.psm;
slouken@136
   219
	y = screen_image.y + screen_image.h;	/* Offscreen video memory */
slouken@70
   220
	for ( h=height/16; h; --h ) {
slouken@70
   221
		x = 0;			/* Visible video memory */
slouken@70
   222
		for ( w=width/16; w; --w ) {
slouken@70
   223
			/* The head tag */
slouken@70
   224
			packet[pnum].ptr = &tags[0];
slouken@70
   225
			packet[pnum].len = 10 * sizeof(*tags);
slouken@70
   226
			++pnum;
slouken@70
   227
			tags[0] = 4 | (1LL << 60);	/* GIFtag */
slouken@70
   228
			tags[1] = 0x0e;			/* A+D */
slouken@70
   229
			tags[2] = ((unsigned long long)fbp << 32) |
slouken@70
   230
			          ((unsigned long long)fbw << 48) |
slouken@70
   231
			          ((unsigned long long)psm << 56);
slouken@70
   232
			tags[3] = PS2_GS_BITBLTBUF;
slouken@70
   233
			tags[4] = ((unsigned long long)x << 32) |
slouken@70
   234
			          ((unsigned long long)y << 48);
slouken@70
   235
			tags[5] = PS2_GS_TRXPOS;
slouken@70
   236
			tags[6] = (unsigned long long)16 |
slouken@70
   237
			          ((unsigned long long)16 << 32);
slouken@70
   238
			tags[7] = PS2_GS_TRXREG;
slouken@70
   239
			tags[8] = 0;
slouken@70
   240
			tags[9] = PS2_GS_TRXDIR;
slouken@70
   241
			/* Now the actual image data */
slouken@70
   242
			packet[pnum].ptr = &tags[10];
slouken@70
   243
			packet[pnum].len = 2 * sizeof(*tags);
slouken@70
   244
			++pnum;
slouken@70
   245
			tags[10] = ((16*16*bpp) >> 4) | (2LL << 58);
slouken@70
   246
			tags[11] = 0;
slouken@70
   247
			packet[pnum].ptr = (void *)base;
slouken@70
   248
			packet[pnum].len = 16 * 16 * bpp;
slouken@70
   249
			++pnum;
slouken@70
   250
			packet[pnum].ptr = &tags[12];
slouken@70
   251
			packet[pnum].len = 2 * sizeof(*tags);
slouken@70
   252
			++pnum;
slouken@70
   253
			tags[12] = (0 >> 4) | (1 << 15) | (2LL << 58);
slouken@70
   254
			tags[13] = 0;
slouken@70
   255
slouken@70
   256
			tags += 16;
slouken@70
   257
			base += 16 * 16 * bpp;
slouken@70
   258
slouken@70
   259
			x += 16;
slouken@70
   260
		}
slouken@70
   261
		y += 16;
slouken@70
   262
	}
slouken@70
   263
slouken@70
   264
	/* Set up the texture memory area for the video */
slouken@70
   265
	tex_packet.ptr = tags;
slouken@70
   266
	tex_packet.len = 8 * sizeof(*tags);
slouken@70
   267
	tags[0] = 3 | (1LL << 60);	/* GIFtag */
slouken@70
   268
	tags[1] = 0x0e;			/* A+D */
slouken@136
   269
	tags[2] = ((screen_image.y + screen_image.h) * screen_image.w) / 64 +
slouken@70
   270
	          ((unsigned long long)fbw << 14) +
slouken@70
   271
	          ((unsigned long long)psm << 20) +
slouken@70
   272
	          ((unsigned long long)power_of_2(width) << 26) +
slouken@70
   273
	          ((unsigned long long)power_of_2(height) << 30) +
slouken@70
   274
	          ((unsigned long long)1 << 34) +
slouken@70
   275
	          ((unsigned long long)1 << 35);
slouken@70
   276
	tags[3] = PS2_GS_TEX0_1;
slouken@70
   277
	tags[4] = (1 << 5) + (1 << 6);
slouken@70
   278
	tags[5] = PS2_GS_TEX1_1;
slouken@70
   279
	tags[6] = 0;
slouken@70
   280
	tags[7] = PS2_GS_TEXFLUSH;
slouken@70
   281
	ioctl(console_fd, PS2IOC_SEND, &tex_packet);
slouken@70
   282
slouken@70
   283
	/* Set up the tags for scaling the image */
slouken@70
   284
	packet[pnum].ptr = tags;
slouken@70
   285
	packet[pnum].len = 12 * sizeof(*tags);
slouken@70
   286
	++pnum;
slouken@70
   287
	tags[0] = 5 | (1LL << 60);	/* GIFtag */
slouken@70
   288
	tags[1] = 0x0e;			/* A+D */
slouken@70
   289
	tags[2] = 6 + (1 << 4) + (1 << 8);
slouken@70
   290
	tags[3] = PS2_GS_PRIM;
slouken@70
   291
	tags[4] = ((unsigned long long)0 * 16) +
slouken@70
   292
	           (((unsigned long long)0 * 16) << 16);
slouken@70
   293
	tags[5] = PS2_GS_UV;
slouken@70
   294
	tags[6] = 0; /* X1, Y1 */
slouken@70
   295
	tags[7] = PS2_GS_XYZ2;
slouken@70
   296
	hwdata->stretch_x1y1 = &tags[6];
slouken@70
   297
	tags[8] = ((unsigned long long)overlay->w * 16) +
slouken@70
   298
	           (((unsigned long long)overlay->h * 16) << 16);
slouken@70
   299
	tags[9] = PS2_GS_UV;
slouken@70
   300
	tags[10] = 0; /* X2, Y2 */
slouken@70
   301
	tags[11] = PS2_GS_XYZ2;
slouken@70
   302
	hwdata->stretch_x2y2 = &tags[10];
slouken@70
   303
slouken@70
   304
	/* We're all done.. */
slouken@70
   305
	return(overlay);
slouken@70
   306
}
slouken@70
   307
slouken@70
   308
int GS_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
slouken@70
   309
{
slouken@70
   310
	return(0);
slouken@70
   311
}
slouken@70
   312
slouken@70
   313
void GS_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
slouken@70
   314
{
slouken@70
   315
	return;
slouken@70
   316
}
slouken@70
   317
slouken@70
   318
int GS_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
slouken@70
   319
{
slouken@70
   320
	struct private_yuvhwdata *hwdata;
slouken@70
   321
	__u32 cmd;
slouken@70
   322
	struct ps2_packet packet;
slouken@70
   323
	int h, w, i;
slouken@70
   324
	Uint32 *lum, *Cr, *Cb;
slouken@70
   325
	int lum_pitch;
slouken@70
   326
	int crb_pitch;
slouken@70
   327
	Uint32 *lum_src, *Cr_src, *Cb_src;
slouken@70
   328
	Uint32 *src, *dst;
slouken@70
   329
	unsigned int x, y;
slouken@70
   330
	SDL_Surface *screen;
slouken@70
   331
slouken@70
   332
	/* Find out where the various portions of the image are */
slouken@70
   333
	hwdata = overlay->hwdata;
slouken@70
   334
	switch (overlay->format) {
slouken@70
   335
	    case SDL_YV12_OVERLAY:
slouken@70
   336
		lum = (Uint32 *)overlay->pixels[0];
slouken@70
   337
		Cr =  (Uint32 *)overlay->pixels[1];
slouken@70
   338
		Cb =  (Uint32 *)overlay->pixels[2];
slouken@70
   339
		break;
slouken@70
   340
	    case SDL_IYUV_OVERLAY:
slouken@70
   341
		lum = (Uint32 *)overlay->pixels[0];
slouken@70
   342
		Cr =  (Uint32 *)overlay->pixels[2];
slouken@70
   343
		Cb =  (Uint32 *)overlay->pixels[1];
slouken@70
   344
	    default:
slouken@543
   345
		SDL_SetError("Unsupported YUV format in blit (?)");
slouken@70
   346
		return(-1);
slouken@70
   347
	}
slouken@70
   348
	dst = (Uint32 *)hwdata->ipu_imem;
slouken@70
   349
	lum_pitch = overlay->w/4;
slouken@70
   350
	crb_pitch = (overlay->w/2)/4;
slouken@70
   351
slouken@70
   352
	/* Copy blocks of 16x16 pixels to the DMA area */
slouken@70
   353
	for ( h=overlay->h/16; h; --h ) {
slouken@70
   354
		lum_src = lum;
slouken@70
   355
		Cr_src = Cr;
slouken@70
   356
		Cb_src = Cb;
slouken@70
   357
		for ( w=overlay->w/16; w; --w ) {
slouken@70
   358
			src = lum_src;
slouken@70
   359
			for ( i=0; i<16; ++i ) {
slouken@70
   360
				dst[0] = src[0];
slouken@70
   361
				dst[1] = src[1];
slouken@70
   362
				dst[2] = src[2];
slouken@70
   363
				dst[3] = src[3];
slouken@70
   364
				src += lum_pitch;
slouken@70
   365
				dst += 4;
slouken@70
   366
			}
slouken@70
   367
			src = Cb_src;
slouken@70
   368
			for ( i=0; i<8; ++i ) {
slouken@70
   369
				dst[0] = src[0];
slouken@70
   370
				dst[1] = src[1];
slouken@70
   371
				src += crb_pitch;
slouken@70
   372
				dst += 2;
slouken@70
   373
			}
slouken@70
   374
			src = Cr_src;
slouken@70
   375
			for ( i=0; i<8; ++i ) {
slouken@70
   376
				dst[0] = src[0];
slouken@70
   377
				dst[1] = src[1];
slouken@70
   378
				src += crb_pitch;
slouken@70
   379
				dst += 2;
slouken@70
   380
			}
slouken@70
   381
			lum_src += 16 / 4;
slouken@70
   382
			Cb_src += 8 / 4;
slouken@70
   383
			Cr_src += 8 / 4;
slouken@70
   384
		}
slouken@70
   385
		lum += lum_pitch * 16;
slouken@70
   386
		Cr += crb_pitch * 8;
slouken@70
   387
		Cb += crb_pitch * 8;
slouken@70
   388
	}
slouken@70
   389
slouken@70
   390
	/* Send the macroblock data to the IPU */
slouken@70
   391
#ifdef DEBUG_YUV
slouken@70
   392
	fprintf(stderr, "Sending data to IPU..\n");
slouken@70
   393
#endif
slouken@70
   394
	packet.ptr = hwdata->ipu_imem;
slouken@70
   395
	packet.len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8);
slouken@70
   396
	ioctl(hwdata->ipu_fd, PS2IOC_SENDA, &packet);
slouken@70
   397
slouken@70
   398
	/* Trigger the DMA to the IPU for conversion */
slouken@70
   399
#ifdef DEBUG_YUV
slouken@70
   400
	fprintf(stderr, "Trigging conversion command\n");
slouken@70
   401
#endif
slouken@70
   402
	cmd = (7 << 28) + hwdata->macroblocks;
slouken@70
   403
	if ( screen_image.psm == PS2_GS_PSMCT16 ) {
slouken@70
   404
		cmd += (1 << 27) +	/* Output RGB 555 */
slouken@70
   405
		       (1 << 26);	/* Dither output */
slouken@70
   406
	}
slouken@70
   407
	ioctl(hwdata->ipu_fd, PS2IOC_SIPUCMD, &cmd);
slouken@70
   408
slouken@70
   409
	/* Retrieve the converted image from the IPU */
slouken@70
   410
#ifdef DEBUG_YUV
slouken@70
   411
	fprintf(stderr, "Retrieving data from IPU..\n");
slouken@70
   412
#endif
slouken@70
   413
	packet.ptr = hwdata->ipu_omem;
slouken@70
   414
	packet.len = overlay->w * overlay->h *
slouken@70
   415
	             this->screen->format->BytesPerPixel;
slouken@70
   416
	ioctl(hwdata->ipu_fd, PS2IOC_RECV, &packet);
slouken@70
   417
slouken@70
   418
#ifdef DEBUG_YUV
slouken@70
   419
	fprintf(stderr, "Copying image to screen..\n");
slouken@70
   420
#endif
slouken@70
   421
	/* Wait for previous DMA to complete */
slouken@70
   422
	ioctl(console_fd, PS2IOC_SENDQCT, 1);
slouken@70
   423
slouken@70
   424
	/* Send the current image to the screen and scale it */
slouken@70
   425
	screen = this->screen;
slouken@70
   426
	x = (unsigned int)dstrect->x;
slouken@70
   427
	y = (unsigned int)dstrect->y;
slouken@70
   428
	if ( screen->offset ) {
slouken@70
   429
		x += (screen->offset % screen->pitch) /
slouken@70
   430
		     screen->format->BytesPerPixel;
slouken@70
   431
		y += (screen->offset / screen->pitch);
slouken@70
   432
	}
slouken@136
   433
	y += screen_image.y;
slouken@70
   434
	*hwdata->stretch_x1y1 = (x * 16) + ((y * 16) << 16);
slouken@70
   435
	x += (unsigned int)dstrect->w;
slouken@70
   436
	y += (unsigned int)dstrect->h;
slouken@70
   437
	*hwdata->stretch_x2y2 = (x * 16) + ((y * 16) << 16);
slouken@70
   438
	return ioctl(console_fd, PS2IOC_SENDL, &hwdata->plist);
slouken@70
   439
}
slouken@70
   440
slouken@70
   441
void GS_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
slouken@70
   442
{
slouken@70
   443
	struct private_yuvhwdata *hwdata;
slouken@70
   444
slouken@70
   445
	hwdata = overlay->hwdata;
slouken@70
   446
	if ( hwdata ) {
slouken@70
   447
		if ( hwdata->ipu_fd >= 0 ) {
slouken@70
   448
			close(hwdata->ipu_fd);
slouken@70
   449
		}
slouken@70
   450
		if ( hwdata->dma_mem ) {
slouken@70
   451
			munmap(hwdata->dma_mem, hwdata->dma_len);
slouken@70
   452
		}
slouken@70
   453
		if ( hwdata->plist.packet ) {
slouken@1336
   454
			SDL_free(hwdata->plist.packet);
slouken@70
   455
		}
slouken@70
   456
		if ( hwdata->pixels ) {
slouken@1336
   457
			SDL_free(hwdata->pixels);
slouken@70
   458
		}
slouken@1336
   459
		SDL_free(hwdata);
slouken@70
   460
	}
slouken@70
   461
}