cdriso: clean up after cdda thread removal
[pcsx_rearmed.git] / plugins / gpu_unai / gpulib_if.cpp
... / ...
CommitLineData
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
45static int linesInterlace; /* internal lines interlace */
46static int force_interlace;
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{
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
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
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
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
158void renderer_finish(void)
159{
160}
161
162void renderer_notify_res_change(void)
163{
164}
165
166extern const unsigned char cmd_lengths[256];
167
168int 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
509breakloop:
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
517void renderer_sync_ecmds(uint32_t *ecmds)
518{
519 int dummy;
520 do_cmd_list(&ecmds[1], 6, &dummy);
521}
522
523void renderer_update_caches(int x, int y, int w, int h)
524{
525}
526
527void renderer_flush_queues(void)
528{
529}
530
531void renderer_set_interlace(int enable, int is_odd)
532{
533}
534
535#ifndef TEST
536
537#include "../../frontend/plugin_lib.h"
538
539void 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