cdriso: unbreak chd cdda
[pcsx_rearmed.git] / plugins / gpu_neon / psx_gpu_if.c
CommitLineData
90ca4913 1/*
2 * (C) GraÅžvydas "notaz" Ignotas, 2011
3 *
4 * This work is licensed under the terms of any of these licenses
5 * (at your option):
6 * - GNU GPL, version 2 or later.
7 * - GNU LGPL, version 2.1 or later.
8 * See the COPYING file in the top-level directory.
9 */
10
11#include <stdio.h>
0b4038f8 12#include <assert.h>
50f9355a 13#include <sys/mman.h>
90ca4913 14
0b4038f8 15#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
2da2fc76 16#ifndef min
17#define min(a, b) ((a) < (b) ? (a) : (b))
18#endif
19#ifndef max
20#define max(a, b) ((a) > (b) ? (a) : (b))
21#endif
0b4038f8 22
652c6b8b 23extern const unsigned char cmd_lengths[256];
24#define command_lengths cmd_lengths
25
b243416b 26static unsigned int *ex_regs;
9ee0fd5b 27static int initialized;
b243416b 28
29#define PCSX
30#define SET_Ex(r, v) \
31 ex_regs[r] = v
32
0b4038f8 33static __attribute__((noinline)) void
34sync_enhancement_buffers(int x, int y, int w, int h);
35
36#include "../gpulib/gpu.h"
90ca4913 37#include "psx_gpu/psx_gpu.c"
90ca4913 38#include "psx_gpu/psx_gpu_parse.c"
90ca4913 39
40static psx_gpu_struct egpu __attribute__((aligned(256)));
41
b243416b 42int do_cmd_list(uint32_t *list, int count, int *last_cmd)
90ca4913 43{
c1817bd9 44 int ret;
45
3f0189c6 46#if defined(__arm__) && defined(NEON_BUILD) && !defined(SIMD_BUILD)
47 // the asm doesn't bother to save callee-save vector regs, so do it here
48 __asm__ __volatile__("":::"q4","q5","q6","q7");
49#endif
50
c1817bd9 51 if (gpu.state.enhancement_active)
52 ret = gpu_parse_enhanced(&egpu, list, count * 4, (u32 *)last_cmd);
53 else
54 ret = gpu_parse(&egpu, list, count * 4, (u32 *)last_cmd);
b243416b 55
3f0189c6 56#if defined(__arm__) && defined(NEON_BUILD) && !defined(SIMD_BUILD)
57 __asm__ __volatile__("":::"q4","q5","q6","q7");
58#endif
59
b243416b 60 ex_regs[1] &= ~0x1ff;
61 ex_regs[1] |= egpu.texture_settings & 0x1ff;
62 return ret;
90ca4913 63}
64
06bc35c8 65#define ENHANCEMENT_BUF_SIZE (1024 * 1024 * 2 * 4 + 4096 * 2)
50f9355a 66
308c6e67 67static void *get_enhancement_bufer(int *x, int *y, int *w, int *h,
fa56d360 68 int *vram_h)
a8be0deb 69{
2da2fc76 70 uint16_t *ret = select_enhancement_buf_ptr(&egpu, *x, *y);
71 if (ret == NULL)
72 return NULL;
a8be0deb 73
74 *x *= 2;
75 *y *= 2;
76 *w = *w * 2;
77 *h = *h * 2;
fa56d360 78 *vram_h = 1024;
a8be0deb 79 return ret;
80}
81
9ee0fd5b 82static void map_enhancement_buffer(void)
90ca4913 83{
9ee0fd5b 84 // currently we use 4x 1024*1024 buffers instead of single 2048*1024
85 // to be able to reuse 1024-width code better (triangle setup,
86 // dithering phase, lines).
a8be0deb 87 egpu.enhancement_buf_ptr = gpu.mmap(ENHANCEMENT_BUF_SIZE);
88 if (egpu.enhancement_buf_ptr == NULL) {
9ee0fd5b 89 fprintf(stderr, "failed to map enhancement buffer\n");
a8be0deb 90 gpu.get_enhancement_bufer = NULL;
91 }
92 else {
93 egpu.enhancement_buf_ptr += 4096 / 2;
94 gpu.get_enhancement_bufer = get_enhancement_bufer;
95 }
9ee0fd5b 96}
e929dec5 97
9ee0fd5b 98int renderer_init(void)
99{
100 if (gpu.vram != NULL) {
101 initialize_psx_gpu(&egpu, gpu.vram);
102 initialized = 1;
e929dec5 103 }
e929dec5 104
a8be0deb 105 if (gpu.mmap != NULL && egpu.enhancement_buf_ptr == NULL)
9ee0fd5b 106 map_enhancement_buffer();
107
108 ex_regs = gpu.ex_regs;
90ca4913 109 return 0;
110}
111
e929dec5 112void renderer_finish(void)
113{
a8be0deb 114 if (egpu.enhancement_buf_ptr != NULL) {
115 egpu.enhancement_buf_ptr -= 4096 / 2;
116 gpu.munmap(egpu.enhancement_buf_ptr, ENHANCEMENT_BUF_SIZE);
06bc35c8 117 }
e929dec5 118 egpu.enhancement_buf_ptr = NULL;
06bc35c8 119 egpu.enhancement_current_buf_ptr = NULL;
9ee0fd5b 120 initialized = 0;
e929dec5 121}
122
50f9355a 123static __attribute__((noinline)) void
124sync_enhancement_buffers(int x, int y, int w, int h)
125{
2da2fc76 126 int i, right = x + w, bottom = y + h;
127 const u16 *src = gpu.vram;
128 // use these because the scanout struct may hold reduced w, h
129 // due to intersection stuff, see the update_enhancement_buf_scanouts() mess
130 int s_w = max(gpu.screen.hres, gpu.screen.w);
131 int s_h = gpu.screen.vres;
132 s_w = min(s_w, 512);
133 for (i = 0; i < ARRAY_SIZE(egpu.enhancement_scanouts); i++) {
134 const struct psx_gpu_scanout *s = &egpu.enhancement_scanouts[i];
135 u16 *dst = select_enhancement_buf_by_index(&egpu, i);
136 int x1, x2, y1, y2;
137 if (s->w == 0) continue;
138 if (s->x >= right) continue;
139 if (s->x + s_w <= x) continue;
140 if (s->y >= bottom) continue;
141 if (s->y + s_h <= y) continue;
142 x1 = max(x, s->x);
143 x2 = min(right, s->x + s_w);
144 y1 = max(y, s->y);
145 y2 = min(bottom, s->y + s_h);
146 scale2x_tiles8(dst + y1 * 1024*2 + x1 * 2,
147 src + y1 * 1024 + x1, (x2 - x1 + 7) / 8u, y2 - y1);
50f9355a 148 }
149}
150
90ca4913 151void renderer_sync_ecmds(uint32_t *ecmds)
152{
b243416b 153 gpu_parse(&egpu, ecmds + 1, 6 * 4, NULL);
90ca4913 154}
155
0b4038f8 156void renderer_update_caches(int x, int y, int w, int h, int state_changed)
90ca4913 157{
05740673 158 update_texture_cache_region(&egpu, x, y, x + w - 1, y + h - 1);
0b4038f8 159
160 if (gpu.state.enhancement_active) {
161 if (state_changed) {
2da2fc76 162 memset(egpu.enhancement_scanouts, 0, sizeof(egpu.enhancement_scanouts));
163 egpu.enhancement_scanout_eselect = 0;
0b4038f8 164 return;
165 }
50f9355a 166 sync_enhancement_buffers(x, y, w, h);
0b4038f8 167 }
90ca4913 168}
169
170void renderer_flush_queues(void)
171{
172 flush_render_block_buffer(&egpu);
173}
174
5440b88e 175void renderer_set_interlace(int enable, int is_odd)
176{
f1359c57 177 egpu.render_mode &= ~(RENDER_INTERLACE_ENABLED|RENDER_INTERLACE_ODD);
5440b88e 178 if (enable)
f1359c57 179 egpu.render_mode |= RENDER_INTERLACE_ENABLED;
5440b88e 180 if (is_odd)
f1359c57 181 egpu.render_mode |= RENDER_INTERLACE_ODD;
5440b88e 182}
183
e929dec5 184void renderer_notify_res_change(void)
185{
2da2fc76 186 renderer_notify_scanout_change(gpu.screen.src_x, gpu.screen.src_y);
0b4038f8 187}
188
2da2fc76 189void renderer_notify_scanout_change(int x, int y)
0b4038f8 190{
2da2fc76 191 if (!gpu.state.enhancement_active || !egpu.enhancement_buf_ptr)
0b4038f8 192 return;
193
2da2fc76 194 update_enhancement_buf_scanouts(&egpu, x, y, gpu.screen.hres, gpu.screen.vres);
e929dec5 195}
196
c1817bd9 197#include "../../frontend/plugin_lib.h"
198
90ca4913 199void renderer_set_config(const struct rearmed_cbs *cbs)
200{
9ee0fd5b 201 if (!initialized) {
202 initialize_psx_gpu(&egpu, gpu.vram);
203 initialized = 1;
204 }
fa56d360 205 if (cbs->pl_set_gpu_caps)
206 cbs->pl_set_gpu_caps(GPU_CAP_SUPPORTS_2X);
0b4038f8 207
208 disable_main_render = cbs->gpu_neon.enhancement_no_main;
209 if (gpu.state.enhancement_enable) {
210 if (gpu.mmap != NULL && egpu.enhancement_buf_ptr == NULL)
211 map_enhancement_buffer();
212 }
90ca4913 213}
0b4038f8 214
215// vim:ts=2:sw=2:expandtab