attempt to make gles plugin work under RPi
[pcsx_rearmed.git] / plugins / gpu_unai / gpulib_if.cpp
CommitLineData
6f2ee2be 1/***************************************************************************
2* Copyright (C) 2010 PCSX4ALL Team *
3* Copyright (C) 2010 Unai *
4* Copyright (C) 2011 notaz *
5* *
6* This program is free software; you can redistribute it and/or modify *
7* it under the terms of the GNU General Public License as published by *
8* the Free Software Foundation; either version 2 of the License, or *
9* (at your option) any later version. *
10* *
11* This program is distributed in the hope that it will be useful, *
12* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14* GNU General Public License for more details. *
15* *
16* You should have received a copy of the GNU General Public License *
17* along with this program; if not, write to the *
18* Free Software Foundation, Inc., *
19* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
20***************************************************************************/
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
62d7fa95 25#include "../gpulib/gpu.h"
6f2ee2be 26
27#define u8 uint8_t
28#define s8 int8_t
29#define u16 uint16_t
30#define s16 int16_t
31#define u32 uint32_t
32#define s32 int32_t
33#define s64 int64_t
34
8aea5f5a 35#define INLINE static
6f2ee2be 36
37#define FRAME_BUFFER_SIZE (1024*512*2)
38#define FRAME_WIDTH 1024
39#define FRAME_HEIGHT 512
40#define FRAME_OFFSET(x,y) (((y)<<10)+(x))
41
89c0de42 42#define isSkip 0 /* skip frame (info coming from GPU) */
6f2ee2be 43#define alt_fps 0
89c0de42 44static int linesInterlace; /* internal lines interlace */
45static int force_interlace;
6f2ee2be 46
47static bool light = true; /* lighting */
48static bool blend = true; /* blending */
49static bool FrameToRead = false; /* load image in progress */
50static bool FrameToWrite = false; /* store image in progress */
51
52static bool enableAbbeyHack = false; /* Abe's Odyssey hack */
53
54static u8 BLEND_MODE;
55static u8 TEXT_MODE;
56static u8 Masking;
57
58static u16 PixelMSB;
59static u16 PixelData;
60
61///////////////////////////////////////////////////////////////////////////////
62// GPU Global data
63///////////////////////////////////////////////////////////////////////////////
64
65// Dma Transfers info
66static s32 px,py;
67static s32 x_end,y_end;
68static u16* pvram;
69
70static s32 PacketCount;
71static s32 PacketIndex;
72
73// Rasterizer status
74static u32 TextureWindow [4];
75static u32 DrawingArea [4];
76static u32 DrawingOffset [2];
77
78static u16* TBA;
79static u16* CBA;
80
81// Inner Loops
82static s32 u4, du4;
83static s32 v4, dv4;
84static s32 r4, dr4;
85static s32 g4, dg4;
86static s32 b4, db4;
87static u32 lInc;
88static u32 tInc, tMsk;
89
90union GPUPacket
91{
8aea5f5a 92 u32 U4[16];
93 s32 S4[16];
94 u16 U2[32];
95 s16 S2[32];
96 u8 U1[64];
97 s8 S1[64];
6f2ee2be 98};
99
100static GPUPacket PacketBuffer;
101static u16 *GPU_FrameBuffer;
102static u32 GPU_GP1;
103
104///////////////////////////////////////////////////////////////////////////////
105
106#include "../gpu_unai/gpu_fixedpoint.h"
107
108// Inner loop driver instanciation file
109#include "../gpu_unai/gpu_inner.h"
110
111// GPU Raster Macros
112#define GPU_RGB16(rgb) ((((rgb)&0xF80000)>>9)|(((rgb)&0xF800)>>6)|(((rgb)&0xF8)>>3))
113
9ed4ca47 114#define GPU_EXPANDSIGN(x) (((s32)(x)<<21)>>21)
6f2ee2be 115
9ed4ca47 116#define CHKMAX_X 1024
117#define CHKMAX_Y 512
6f2ee2be 118
119#define GPU_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
120
121// GPU internal image drawing functions
122#include "../gpu_unai/gpu_raster_image.h"
123
124// GPU internal line drawing functions
125#include "../gpu_unai/gpu_raster_line.h"
126
127// GPU internal polygon drawing functions
128#include "../gpu_unai/gpu_raster_polygon.h"
129
130// GPU internal sprite drawing functions
131#include "../gpu_unai/gpu_raster_sprite.h"
132
133// GPU command buffer execution/store
134#include "../gpu_unai/gpu_command.h"
135
6f2ee2be 136/////////////////////////////////////////////////////////////////////////////
137
138int renderer_init(void)
139{
140 GPU_FrameBuffer = (u16 *)gpu.vram;
141
142 // s_invTable
143 for(int i=1;i<=(1<<TABLE_BITS);++i)
144 {
145 double v = 1.0 / double(i);
146 #ifdef GPU_TABLE_10_BITS
147 v *= double(0xffffffff>>1);
148 #else
149 v *= double(0x80000000);
150 #endif
151 s_invTable[i-1]=s32(v);
152 }
153
154 return 0;
155}
156
e929dec5 157void renderer_finish(void)
158{
159}
160
161void renderer_notify_res_change(void)
162{
163}
164
6f2ee2be 165extern const unsigned char cmd_lengths[256];
166
b243416b 167int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
6f2ee2be 168{
42a261f1 169 unsigned int cmd = 0, len, i;
b243416b 170 unsigned int *list_start = list;
6f2ee2be 171 unsigned int *list_end = list + list_len;
172
89c0de42 173 linesInterlace = force_interlace;
174#ifndef __ARM_ARCH_7A__ /* XXX */
175 linesInterlace |= gpu.status.interlace;
176#endif
177
6f2ee2be 178 for (; list < list_end; list += 1 + len)
179 {
6f2ee2be 180 cmd = *list >> 24;
181 len = cmd_lengths[cmd];
b243416b 182 if (list + 1 + len > list_end) {
183 cmd = -1;
184 break;
185 }
186
42a261f1 187 #define PRIM cmd
188 PacketBuffer.U4[0] = list[0];
189 for (i = 1; i <= len; i++)
190 PacketBuffer.U4[i] = list[i];
6f2ee2be 191
42a261f1 192 switch (cmd)
6f2ee2be 193 {
42a261f1 194 case 0x02:
195 gpuClearImage();
196 break;
197
198 case 0x20:
199 case 0x21:
200 case 0x22:
201 case 0x23:
202 gpuDrawF3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB]);
203 break;
204
205 case 0x24:
206 case 0x25:
207 case 0x26:
208 case 0x27:
209 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
210 gpuSetTexture(PacketBuffer.U4[4] >> 16);
211 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
212 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB]);
213 else
214 gpuDrawFT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB]);
215 break;
216
217 case 0x28:
218 case 0x29:
219 case 0x2A:
220 case 0x2B: {
221 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | PixelMSB];
222 gpuDrawF3(gpuPolySpanDriver);
223 PacketBuffer.U4[1] = PacketBuffer.U4[4];
224 gpuDrawF3(gpuPolySpanDriver);
225 break;
226 }
227
228 case 0x2C:
229 case 0x2D:
230 case 0x2E:
231 case 0x2F: {
232 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
233 gpuSetTexture(PacketBuffer.U4[4] >> 16);
234 PP gpuPolySpanDriver;
235 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
236 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | PixelMSB];
237 else
238 gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | PixelMSB];
239 gpuDrawFT3(gpuPolySpanDriver);
240 PacketBuffer.U4[1] = PacketBuffer.U4[7];
241 PacketBuffer.U4[2] = PacketBuffer.U4[8];
242 gpuDrawFT3(gpuPolySpanDriver);
243 break;
244 }
245
246 case 0x30:
247 case 0x31:
248 case 0x32:
249 case 0x33:
250 gpuDrawG3(gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB]);
251 break;
252
253 case 0x34:
254 case 0x35:
255 case 0x36:
256 case 0x37:
257 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
258 gpuSetTexture (PacketBuffer.U4[5] >> 16);
259 gpuDrawGT3(gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB]);
260 break;
261
262 case 0x38:
263 case 0x39:
264 case 0x3A:
265 case 0x3B: {
266 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | Masking | Blending | 129 | PixelMSB];
267 gpuDrawG3(gpuPolySpanDriver);
268 PacketBuffer.U4[0] = PacketBuffer.U4[6];
269 PacketBuffer.U4[1] = PacketBuffer.U4[7];
270 gpuDrawG3(gpuPolySpanDriver);
271 break;
272 }
273
274 case 0x3C:
275 case 0x3D:
276 case 0x3E:
277 case 0x3F: {
278 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
279 gpuSetTexture (PacketBuffer.U4[5] >> 16);
280 const PP gpuPolySpanDriver = gpuPolySpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | ((Lighting)?129:0) | PixelMSB];
281 gpuDrawGT3(gpuPolySpanDriver);
282 PacketBuffer.U4[0] = PacketBuffer.U4[9];
283 PacketBuffer.U4[1] = PacketBuffer.U4[10];
284 PacketBuffer.U4[2] = PacketBuffer.U4[11];
285 gpuDrawGT3(gpuPolySpanDriver);
286 break;
287 }
288
289 case 0x40:
290 case 0x41:
291 case 0x42:
292 case 0x43:
293 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
294 break;
295
6f2ee2be 296 case 0x48 ... 0x4F:
297 {
298 u32 num_vertexes = 1;
299 u32 *list_position = &(list[2]);
8aea5f5a 300
8aea5f5a 301 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
6f2ee2be 302
303 while(1)
304 {
8aea5f5a 305 PacketBuffer.U4[1] = PacketBuffer.U4[2];
306 PacketBuffer.U4[2] = *list_position++;
307 gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
308
6f2ee2be 309 num_vertexes++;
804789d7 310 if(list_position >= list_end) {
311 cmd = -1;
312 goto breakloop;
313 }
314 if((*list_position & 0xf000f000) == 0x50005000)
b243416b 315 break;
6f2ee2be 316 }
317
b243416b 318 len += (num_vertexes - 2);
6f2ee2be 319 break;
320 }
321
42a261f1 322 case 0x50:
323 case 0x51:
324 case 0x52:
325 case 0x53:
326 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
327 break;
328
6f2ee2be 329 case 0x58 ... 0x5F:
330 {
331 u32 num_vertexes = 1;
332 u32 *list_position = &(list[2]);
8aea5f5a 333
8aea5f5a 334 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
6f2ee2be 335
336 while(1)
337 {
8aea5f5a 338 PacketBuffer.U4[0] = PacketBuffer.U4[2];
339 PacketBuffer.U4[1] = PacketBuffer.U4[3];
340 PacketBuffer.U4[2] = *list_position++;
341 PacketBuffer.U4[3] = *list_position++;
342 gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
343
6f2ee2be 344 num_vertexes++;
804789d7 345 if(list_position >= list_end) {
346 cmd = -1;
347 goto breakloop;
348 }
349 if((*list_position & 0xf000f000) == 0x50005000)
b243416b 350 break;
6f2ee2be 351 }
352
b243416b 353 len += (num_vertexes - 2) * 2;
6f2ee2be 354 break;
355 }
356
42a261f1 357 case 0x60:
358 case 0x61:
359 case 0x62:
360 case 0x63:
361 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
362 break;
363
364 case 0x64:
365 case 0x65:
366 case 0x66:
367 case 0x67:
368 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
369 gpuSetTexture (GPU_GP1);
370 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
371 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
372 else
373 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
374 break;
375
376 case 0x68:
377 case 0x69:
378 case 0x6A:
379 case 0x6B:
380 PacketBuffer.U4[2] = 0x00010001;
381 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
382 break;
383
384 case 0x70:
385 case 0x71:
386 case 0x72:
387 case 0x73:
388 PacketBuffer.U4[2] = 0x00080008;
389 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
390 break;
391
392 case 0x74:
393 case 0x75:
394 case 0x76:
395 case 0x77:
396 PacketBuffer.U4[3] = 0x00080008;
397 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
398 gpuSetTexture (GPU_GP1);
399 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
400 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
401 else
402 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
403 break;
404
405 case 0x78:
406 case 0x79:
407 case 0x7A:
408 case 0x7B:
409 PacketBuffer.U4[2] = 0x00100010;
410 gpuDrawT(gpuTileSpanDrivers [Blending_Mode | Masking | Blending | (PixelMSB>>3)]);
411 break;
412
413 case 0x7C:
414 case 0x7D:
415#ifdef __arm__
416 if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0)
417 {
418 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
419 gpuSetTexture (GPU_GP1);
420 gpuDrawS16();
421 break;
422 }
423 // fallthrough
424#endif
425 case 0x7E:
426 case 0x7F:
427 PacketBuffer.U4[3] = 0x00100010;
428 gpuSetCLUT (PacketBuffer.U4[2] >> 16);
429 gpuSetTexture (GPU_GP1);
430 if ((PacketBuffer.U1[0]>0x5F) && (PacketBuffer.U1[1]>0x5F) && (PacketBuffer.U1[2]>0x5F))
431 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | (enableAbbeyHack<<7) | PixelMSB]);
432 else
433 gpuDrawS(gpuSpriteSpanDrivers [Blending_Mode | TEXT_MODE | Masking | Blending | Lighting | (enableAbbeyHack<<7) | PixelMSB]);
434 break;
435
436 case 0x80: // vid -> vid
437 gpuMoveImage(); // prim handles updateLace && skip
438 break;
9a6e7816 439#ifdef TEST
440 case 0xA0: // sys -> vid
441 {
442 u32 load_width = list[2] & 0xffff;
443 u32 load_height = list[2] >> 16;
444 u32 load_size = load_width * load_height;
445
446 len += load_size / 2;
447 break;
448 }
42a261f1 449 case 0xC0:
450 break;
451#else
452 case 0xA0: // sys ->vid
453 case 0xC0: // vid -> sys
454 goto breakloop;
9a6e7816 455#endif
42a261f1 456 case 0xE1: {
457 const u32 temp = PacketBuffer.U4[0];
458 GPU_GP1 = (GPU_GP1 & ~0x000007FF) | (temp & 0x000007FF);
459 gpuSetTexture(temp);
460 gpu.ex_regs[1] = temp;
461 break;
462 }
463 case 0xE2: {
464 static const u8 TextureMask[32] = {
465 255, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7,
466 127, 7, 15, 7, 31, 7, 15, 7, 63, 7, 15, 7, 31, 7, 15, 7
467 };
468 const u32 temp = PacketBuffer.U4[0];
469 TextureWindow[0] = ((temp >> 10) & 0x1F) << 3;
470 TextureWindow[1] = ((temp >> 15) & 0x1F) << 3;
471 TextureWindow[2] = TextureMask[(temp >> 0) & 0x1F];
472 TextureWindow[3] = TextureMask[(temp >> 5) & 0x1F];
473 gpuSetTexture(GPU_GP1);
474 gpu.ex_regs[2] = temp;
475 break;
476 }
477 case 0xE3: {
478 const u32 temp = PacketBuffer.U4[0];
479 DrawingArea[0] = temp & 0x3FF;
480 DrawingArea[1] = (temp >> 10) & 0x3FF;
481 gpu.ex_regs[3] = temp;
6f2ee2be 482 break;
42a261f1 483 }
484 case 0xE4: {
485 const u32 temp = PacketBuffer.U4[0];
486 DrawingArea[2] = (temp & 0x3FF) + 1;
487 DrawingArea[3] = ((temp >> 10) & 0x3FF) + 1;
488 gpu.ex_regs[4] = temp;
489 break;
490 }
491 case 0xE5: {
492 const u32 temp = PacketBuffer.U4[0];
493 DrawingOffset[0] = ((long)temp<<(32-11))>>(32-11);
494 DrawingOffset[1] = ((long)temp<<(32-22))>>(32-11);
495 gpu.ex_regs[5] = temp;
496 break;
497 }
498 case 0xE6: {
499 const u32 temp = PacketBuffer.U4[0];
500 Masking = (temp & 0x2) << 1;
501 PixelMSB =(temp & 0x1) << 8;
502 gpu.ex_regs[6] = temp;
503 break;
504 }
6f2ee2be 505 }
506 }
b243416b 507
42a261f1 508breakloop:
b243416b 509 gpu.ex_regs[1] &= ~0x1ff;
510 gpu.ex_regs[1] |= GPU_GP1 & 0x1ff;
511
512 *last_cmd = cmd;
513 return list - list_start;
6f2ee2be 514}
515
516void renderer_sync_ecmds(uint32_t *ecmds)
517{
42a261f1 518 int dummy;
519 do_cmd_list(&ecmds[1], 6, &dummy);
6f2ee2be 520}
521
05740673 522void renderer_update_caches(int x, int y, int w, int h)
6f2ee2be 523{
524}
525
526void renderer_flush_queues(void)
527{
528}
914455e6 529
5440b88e 530void renderer_set_interlace(int enable, int is_odd)
531{
532}
533
9a6e7816 534#ifndef TEST
535
914455e6 536#include "../../frontend/plugin_lib.h"
537
538void renderer_set_config(const struct rearmed_cbs *cbs)
539{
89c0de42 540 force_interlace = cbs->gpu_unai.lineskip;
914455e6 541 enableAbbeyHack = cbs->gpu_unai.abe_hack;
542 light = !cbs->gpu_unai.no_light;
543 blend = !cbs->gpu_unai.no_blend;
9ee0fd5b 544
545 GPU_FrameBuffer = (u16 *)gpu.vram;
914455e6 546}
9a6e7816 547
548#endif
42a261f1 549
550// vim:shiftwidth=2:expandtab