don't use __ARM_ARCH_7A__
[pcsx_rearmed.git] / plugins / gpu_unai / gpulib_if.cpp
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>
25 #include "../gpulib/gpu.h"
26 #include "arm_features.h"
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
36 #define INLINE static
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
43 #define isSkip 0 /* skip frame (info coming from GPU) */
44 #define alt_fps 0
45 static int linesInterlace;  /* internal lines interlace */
46 static int force_interlace;
47
48 static bool light = true; /* lighting */
49 static bool blend = true; /* blending */
50 static bool FrameToRead = false; /* load image in progress */
51 static bool FrameToWrite = false; /* store image in progress */
52
53 static bool enableAbbeyHack = false; /* Abe's Odyssey hack */
54
55 static u8 BLEND_MODE;
56 static u8 TEXT_MODE;
57 static u8 Masking;
58
59 static u16 PixelMSB;
60 static u16 PixelData;
61
62 ///////////////////////////////////////////////////////////////////////////////
63 //  GPU Global data
64 ///////////////////////////////////////////////////////////////////////////////
65
66 //  Dma Transfers info
67 static s32              px,py;
68 static s32              x_end,y_end;
69 static u16*  pvram;
70
71 static s32 PacketCount;
72 static s32 PacketIndex;
73
74 //  Rasterizer status
75 static u32 TextureWindow [4];
76 static u32 DrawingArea   [4];
77 static u32 DrawingOffset [2];
78
79 static u16* TBA;
80 static u16* CBA;
81
82 //  Inner Loops
83 static s32   u4, du4;
84 static s32   v4, dv4;
85 static s32   r4, dr4;
86 static s32   g4, dg4;
87 static s32   b4, db4;
88 static u32   lInc;
89 static u32   tInc, tMsk;
90
91 union GPUPacket
92 {
93         u32 U4[16];
94         s32 S4[16];
95         u16 U2[32];
96         s16 S2[32];
97         u8  U1[64];
98         s8  S1[64];
99 };
100
101 static GPUPacket PacketBuffer;
102 static u16  *GPU_FrameBuffer;
103 static 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
115 #define GPU_EXPANDSIGN(x)  (((s32)(x)<<21)>>21)
116
117 #define CHKMAX_X 1024
118 #define CHKMAX_Y 512
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
137 /////////////////////////////////////////////////////////////////////////////
138
139 int 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
158 void renderer_finish(void)
159 {
160 }
161
162 void renderer_notify_res_change(void)
163 {
164 }
165
166 extern const unsigned char cmd_lengths[256];
167
168 int do_cmd_list(unsigned int *list, int list_len, int *last_cmd)
169 {
170   unsigned int cmd = 0, len, i;
171   unsigned int *list_start = list;
172   unsigned int *list_end = list + list_len;
173
174   linesInterlace = force_interlace;
175 #ifdef HAVE_PRE_ARMV7 /* XXX */
176   linesInterlace |= gpu.status.interlace;
177 #endif
178
179   for (; list < list_end; list += 1 + len)
180   {
181     cmd = *list >> 24;
182     len = cmd_lengths[cmd];
183     if (list + 1 + len > list_end) {
184       cmd = -1;
185       break;
186     }
187
188     #define PRIM cmd
189     PacketBuffer.U4[0] = list[0];
190     for (i = 1; i <= len; i++)
191       PacketBuffer.U4[i] = list[i];
192
193     switch (cmd)
194     {
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
297       case 0x48 ... 0x4F:
298       {
299         u32 num_vertexes = 1;
300         u32 *list_position = &(list[2]);
301
302         gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
303
304         while(1)
305         {
306           PacketBuffer.U4[1] = PacketBuffer.U4[2];
307           PacketBuffer.U4[2] = *list_position++;
308           gpuDrawLF(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
309
310           num_vertexes++;
311           if(list_position >= list_end) {
312             cmd = -1;
313             goto breakloop;
314           }
315           if((*list_position & 0xf000f000) == 0x50005000)
316             break;
317         }
318
319         len += (num_vertexes - 2);
320         break;
321       }
322
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
330       case 0x58 ... 0x5F:
331       {
332         u32 num_vertexes = 1;
333         u32 *list_position = &(list[2]);
334
335         gpuDrawLG(gpuPixelDrivers [ (Blending_Mode | Masking | Blending | (PixelMSB>>3)) >> 1]);
336
337         while(1)
338         {
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
345           num_vertexes++;
346           if(list_position >= list_end) {
347             cmd = -1;
348             goto breakloop;
349           }
350           if((*list_position & 0xf000f000) == 0x50005000)
351             break;
352         }
353
354         len += (num_vertexes - 2) * 2;
355         break;
356       }
357
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;
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       }
450       case 0xC0:
451         break;
452 #else
453       case 0xA0:          //  sys ->vid
454       case 0xC0:          //  vid -> sys
455         goto breakloop;
456 #endif
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;
483         break;
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];
494         DrawingOffset[0] = ((s32)temp<<(32-11))>>(32-11);
495         DrawingOffset[1] = ((s32)temp<<(32-22))>>(32-11);
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       }
506     }
507   }
508
509 breakloop:
510   gpu.ex_regs[1] &= ~0x1ff;
511   gpu.ex_regs[1] |= GPU_GP1 & 0x1ff;
512
513   *last_cmd = cmd;
514   return list - list_start;
515 }
516
517 void renderer_sync_ecmds(uint32_t *ecmds)
518 {
519   int dummy;
520   do_cmd_list(&ecmds[1], 6, &dummy);
521 }
522
523 void renderer_update_caches(int x, int y, int w, int h)
524 {
525 }
526
527 void renderer_flush_queues(void)
528 {
529 }
530
531 void renderer_set_interlace(int enable, int is_odd)
532 {
533 }
534
535 #ifndef TEST
536
537 #include "../../frontend/plugin_lib.h"
538
539 void renderer_set_config(const struct rearmed_cbs *cbs)
540 {
541   force_interlace = cbs->gpu_unai.lineskip;
542   enableAbbeyHack = cbs->gpu_unai.abe_hack;
543   light = !cbs->gpu_unai.no_light;
544   blend = !cbs->gpu_unai.no_blend;
545
546   GPU_FrameBuffer = (u16 *)gpu.vram;
547 }
548
549 #endif
550
551 // vim:shiftwidth=2:expandtab