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