frontend: handle double res rendering, enable on x86_64
[pcsx_rearmed.git] / plugins / dfxvideo / gpulib_if.c
CommitLineData
b094071f 1/***************************************************************************
2 copyright : (C) 2001 by Pete Bernert, 2011 notaz
3
4 ***************************************************************************/
5/***************************************************************************
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. See also the license.txt file for *
11 * additional informations. *
12 * *
13 ***************************************************************************/
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
62d7fa95 18#include "../gpulib/gpu.h"
f3af2eb5 19#include "../../include/arm_features.h"
b094071f 20
a903b131
JW
21#ifdef THREAD_RENDERING
22#include "../gpulib/gpulib_thread_if.h"
23#define do_cmd_list real_do_cmd_list
24#define renderer_init real_renderer_init
25#define renderer_finish real_renderer_finish
26#define renderer_sync_ecmds real_renderer_sync_ecmds
27#define renderer_update_caches real_renderer_update_caches
28#define renderer_flush_queues real_renderer_flush_queues
29#define renderer_set_interlace real_renderer_set_interlace
30#define renderer_set_config real_renderer_set_config
31#define renderer_notify_res_change real_renderer_notify_res_change
32#define renderer_notify_update_lace real_renderer_notify_update_lace
33#define renderer_sync real_renderer_sync
34#define ex_regs scratch_ex_regs
35#endif
36
b094071f 37#define u32 uint32_t
38
39#define INFO_TW 0
40#define INFO_DRAWSTART 1
41#define INFO_DRAWEND 2
42#define INFO_DRAWOFF 3
43
44#define SHADETEXBIT(x) ((x>>24) & 0x1)
45#define SEMITRANSBIT(x) ((x>>25) & 0x1)
46#define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
47
48#define DATAREGISTERMODES unsigned short
49
50#define DR_NORMAL 0
51#define DR_VRAMTRANSFER 1
52
53#define GPUSTATUS_READYFORVRAM 0x08000000
54
55// byteswappings
56
495d603c
PC
57#define SWAP16(x) __builtin_bswap16(x)
58#define SWAP32(x) __builtin_bswap32(x)
b094071f 59
ffe97735 60#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
b094071f 61
62// big endian config
63#define HOST2LE32(x) SWAP32(x)
64#define HOST2BE32(x) (x)
65#define LE2HOST32(x) SWAP32(x)
66#define BE2HOST32(x) (x)
67
68#define HOST2LE16(x) SWAP16(x)
69#define HOST2BE16(x) (x)
70#define LE2HOST16(x) SWAP16(x)
71#define BE2HOST16(x) (x)
72
73#else
74
75// little endian config
76#define HOST2LE32(x) (x)
77#define HOST2BE32(x) SWAP32(x)
78#define LE2HOST32(x) (x)
79#define BE2HOST32(x) SWAP32(x)
80
81#define HOST2LE16(x) (x)
82#define HOST2BE16(x) SWAP16(x)
83#define LE2HOST16(x) (x)
84#define BE2HOST16(x) SWAP16(x)
85
86#endif
87
f3af2eb5 88#define GETLEs16(X) ((int16_t)GETLE16((uint16_t *)(X)))
b094071f 89
f3af2eb5 90#define GETLE16(X) LE2HOST16(*(uint16_t *)(X))
91#define GETLE32_(X) LE2HOST32(*(uint32_t *)(X))
92#define PUTLE16(X, Y) do{*((uint16_t *)(X))=HOST2LE16((uint16_t)(Y));}while(0)
93#define PUTLE32_(X, Y) do{*((uint32_t *)(X))=HOST2LE32((uint32_t)(Y));}while(0)
94#if defined(__arm__) && !defined(HAVE_ARMV6)
95// for (very) old ARMs with no unaligned loads?
96#define GETLE32(X) (*(uint16_t *)(X)|((uint32_t)((uint16_t *)(X))[1]<<16))
b094071f 97#define PUTLE32(X, Y) do{uint16_t *p_=(uint16_t *)(X);uint32_t y_=Y;p_[0]=y_;p_[1]=y_>>16;}while(0)
98#else
99#define GETLE32 GETLE32_
100#define PUTLE32 PUTLE32_
101#endif
102
103/////////////////////////////////////////////////////////////////////////////
104
105typedef struct VRAMLOADTTAG
106{
107 short x;
108 short y;
109 short Width;
110 short Height;
111 short RowsRemaining;
112 short ColsRemaining;
113 unsigned short *ImagePtr;
114} VRAMLoad_t;
115
116/////////////////////////////////////////////////////////////////////////////
117
118typedef struct PSXPOINTTAG
119{
120 int32_t x;
121 int32_t y;
122} PSXPoint_t;
123
124typedef struct PSXSPOINTTAG
125{
126 short x;
127 short y;
128} PSXSPoint_t;
129
130typedef struct PSXRECTTAG
131{
132 short x0;
133 short x1;
134 short y0;
135 short y1;
136} PSXRect_t;
137
138// linux defines for some windows stuff
139
140#define FALSE 0
141#define TRUE 1
142#define BOOL unsigned short
143#define LOWORD(l) ((unsigned short)(l))
144#define HIWORD(l) ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
145#define max(a,b) (((a) > (b)) ? (a) : (b))
146#define min(a,b) (((a) < (b)) ? (a) : (b))
147#define DWORD uint32_t
148#ifndef __int64
149#define __int64 long long int
150#endif
151
152typedef struct RECTTAG
153{
154 int left;
155 int top;
156 int right;
157 int bottom;
158}RECT;
159
160/////////////////////////////////////////////////////////////////////////////
161
162typedef struct TWINTAG
163{
164 PSXRect_t Position;
165 int xmask, ymask;
166} TWin_t;
167
168/////////////////////////////////////////////////////////////////////////////
169
170typedef struct PSXDISPLAYTAG
171{
172 PSXPoint_t DisplayModeNew;
173 PSXPoint_t DisplayMode;
174 PSXPoint_t DisplayPosition;
175 PSXPoint_t DisplayEnd;
176
177 int32_t Double;
178 int32_t Height;
179 int32_t PAL;
180 int32_t InterlacedNew;
181 int32_t Interlaced;
182 int32_t RGB24New;
183 int32_t RGB24;
184 PSXSPoint_t DrawOffset;
185 int32_t Disabled;
186 PSXRect_t Range;
187
188} PSXDisplay_t;
189
190/////////////////////////////////////////////////////////////////////////////
191
192// draw.c
193
194extern int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
195extern int32_t GlobalTextABR,GlobalTextPAGE;
196extern short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;
197extern long lLowerpart;
198extern BOOL bCheckMask;
199extern unsigned short sSetMask;
200extern unsigned long lSetMask;
201extern short g_m1;
202extern short g_m2;
203extern short g_m3;
204extern short DrawSemiTrans;
205
206// prim.c
207
208extern BOOL bUsingTWin;
209extern TWin_t TWin;
210extern void (*primTableJ[256])(unsigned char *);
211extern void (*primTableSkip[256])(unsigned char *);
212extern unsigned short usMirror;
213extern int iDither;
214extern uint32_t dwCfgFixes;
215extern uint32_t dwActFixes;
216extern int iUseFixes;
217extern int iUseDither;
218extern BOOL bDoVSyncUpdate;
219extern int32_t drawX;
220extern int32_t drawY;
221extern int32_t drawW;
222extern int32_t drawH;
223
224// gpu.h
225
226#define OPAQUEON 10
227#define OPAQUEOFF 11
228
229#define KEY_RESETTEXSTORE 1
230#define KEY_SHOWFPS 2
231#define KEY_RESETOPAQUE 4
232#define KEY_RESETDITHER 8
233#define KEY_RESETFILTER 16
234#define KEY_RESETADVBLEND 32
235#define KEY_BADTEXTURES 128
236#define KEY_CHECKTHISOUT 256
237
ffe97735 238#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
b094071f 239#define RED(x) (x & 0xff)
240#define BLUE(x) ((x>>16) & 0xff)
241#define GREEN(x) ((x>>8) & 0xff)
242#define COLOR(x) (x & 0xffffff)
ffe97735 243#else
b094071f 244#define RED(x) ((x>>24) & 0xff)
245#define BLUE(x) ((x>>8) & 0xff)
246#define GREEN(x) ((x>>16) & 0xff)
247#define COLOR(x) SWAP32(x & 0xffffff)
248#endif
249
250PSXDisplay_t PSXDisplay;
251unsigned char *psxVub;
b094071f 252unsigned short *psxVuw;
253unsigned short *psxVuw_eom;
b094071f 254
255long lGPUstatusRet;
256uint32_t lGPUInfoVals[16];
257
258VRAMLoad_t VRAMWrite;
259VRAMLoad_t VRAMRead;
260
261DATAREGISTERMODES DataWriteMode;
262DATAREGISTERMODES DataReadMode;
263
264BOOL bCheckMask = FALSE;
265unsigned short sSetMask = 0;
266unsigned long lSetMask = 0;
267long lLowerpart;
268
62d7fa95 269#include "soft.c"
270#include "prim.c"
b094071f 271
272/////////////////////////////////////////////////////////////////////////////
273
9ee0fd5b 274static void set_vram(void *vram)
b094071f 275{
9ee0fd5b 276 psxVub=vram;
b094071f 277 psxVuw=(unsigned short *)psxVub;
b094071f 278 psxVuw_eom=psxVuw+1024*512; // pre-calc of end of vram
9ee0fd5b 279}
280
281int renderer_init(void)
282{
283 set_vram(gpu.vram);
b094071f 284
285 PSXDisplay.RGB24 = FALSE; // init some stuff
286 PSXDisplay.Interlaced = FALSE;
287 PSXDisplay.DrawOffset.x = 0;
288 PSXDisplay.DrawOffset.y = 0;
289 PSXDisplay.DisplayMode.x= 320;
290 PSXDisplay.DisplayMode.y= 240;
291 PSXDisplay.Disabled = FALSE;
292 PSXDisplay.Range.x0=0;
293 PSXDisplay.Range.x1=0;
294 PSXDisplay.Double = 1;
295
296 DataWriteMode = DR_NORMAL;
297 lGPUstatusRet = 0x14802000;
298
299 return 0;
300}
301
e929dec5 302void renderer_finish(void)
303{
304}
305
306void renderer_notify_res_change(void)
307{
308}
309
b094071f 310extern const unsigned char cmd_lengths[256];
311
fc99395c 312int do_cmd_list(uint32_t *list, int list_len, int *last_cmd)
b094071f 313{
b243416b 314 unsigned int cmd = 0, len;
fc99395c 315 uint32_t *list_start = list;
316 uint32_t *list_end = list + list_len;
b094071f 317
318 for (; list < list_end; list += 1 + len)
319 {
495d603c 320 cmd = GETLE32(list) >> 24;
b094071f 321 len = cmd_lengths[cmd];
b243416b 322 if (list + 1 + len > list_end) {
323 cmd = -1;
324 break;
325 }
326
327#ifndef TEST
328 if (cmd == 0xa0 || cmd == 0xc0)
329 break; // image i/o, forward to upper layer
330 else if ((cmd & 0xf8) == 0xe0)
495d603c 331 gpu.ex_regs[cmd & 7] = GETLE32(list);
b243416b 332#endif
b094071f 333
334 primTableJ[cmd]((void *)list);
335
336 switch(cmd)
337 {
338 case 0x48 ... 0x4F:
339 {
b243416b 340 u32 num_vertexes = 2;
341 u32 *list_position = &(list[3]);
b094071f 342
343 while(1)
344 {
804789d7 345 if(list_position >= list_end) {
346 cmd = -1;
347 goto breakloop;
348 }
349
495d603c 350 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
b094071f 351 break;
352
353 list_position++;
354 num_vertexes++;
355 }
356
b243416b 357 len += (num_vertexes - 2);
b094071f 358 break;
359 }
360
361 case 0x58 ... 0x5F:
362 {
b243416b 363 u32 num_vertexes = 2;
364 u32 *list_position = &(list[4]);
b094071f 365
366 while(1)
367 {
804789d7 368 if(list_position >= list_end) {
369 cmd = -1;
370 goto breakloop;
371 }
372
495d603c 373 if((*list_position & HOST2LE32(0xf000f000)) == HOST2LE32(0x50005000))
b094071f 374 break;
375
376 list_position += 2;
377 num_vertexes++;
378 }
379
b243416b 380 len += (num_vertexes - 2) * 2;
b094071f 381 break;
382 }
383
9a6e7816 384#ifdef TEST
b094071f 385 case 0xA0: // sys -> vid
386 {
9a6e7816 387 short *slist = (void *)list;
495d603c
PC
388 u32 load_width = LE2HOST32(slist[4]);
389 u32 load_height = LE2HOST32(slist[5]);
b094071f 390 u32 load_size = load_width * load_height;
391
392 len += load_size / 2;
393 break;
394 }
9a6e7816 395#endif
b094071f 396 }
397 }
b243416b 398
804789d7 399breakloop:
b243416b 400 gpu.ex_regs[1] &= ~0x1ff;
401 gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
402
403 *last_cmd = cmd;
404 return list - list_start;
b094071f 405}
406
3e629be9 407void renderer_sync_ecmds(uint32_t *ecmds_)
5b745e5b 408{
3e629be9 409#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
410 // the funcs below expect LE
411 uint32_t i, ecmds[8];
412 for (i = 1; i <= 6; i++)
413 ecmds[i] = HTOLE32(ecmds_[i]);
414#else
415 uint32_t *ecmds = ecmds_;
416#endif
5b745e5b 417 cmdTexturePage((unsigned char *)&ecmds[1]);
418 cmdTextureWindow((unsigned char *)&ecmds[2]);
419 cmdDrawAreaStart((unsigned char *)&ecmds[3]);
420 cmdDrawAreaEnd((unsigned char *)&ecmds[4]);
421 cmdDrawOffset((unsigned char *)&ecmds[5]);
422 cmdSTP((unsigned char *)&ecmds[6]);
423}
424
05740673 425void renderer_update_caches(int x, int y, int w, int h)
b094071f 426{
427}
428
429void renderer_flush_queues(void)
430{
431}
914455e6 432
5440b88e 433void renderer_set_interlace(int enable, int is_odd)
434{
435}
436
c765eb86
JW
437void renderer_sync(void)
438{
439}
440
441void renderer_notify_update_lace(int updated)
442{
443}
444
914455e6 445#include "../../frontend/plugin_lib.h"
446
447void renderer_set_config(const struct rearmed_cbs *cbs)
448{
449 iUseDither = cbs->gpu_peops.iUseDither;
450 dwActFixes = cbs->gpu_peops.dwActFixes;
fa56d360 451 if (cbs->pl_set_gpu_caps)
452 cbs->pl_set_gpu_caps(0);
9ee0fd5b 453 set_vram(gpu.vram);
914455e6 454}