*/
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include "gpu.h"
//#define log_anomaly gpu_log
#define log_anomaly(...)
-struct psx_gpu gpu __attribute__((aligned(2048)));
+struct psx_gpu gpu;
static noinline int do_cmd_buffer(uint32_t *data, int count);
static void finish_vram_transfer(int is_read);
}
}
+// double, for overdraw guard
+#define VRAM_SIZE (1024 * 512 * 2 * 2)
+
+static int map_vram(void)
+{
+ gpu.vram = gpu.mmap(VRAM_SIZE);
+ if (gpu.vram != NULL) {
+ gpu.vram += 4096 / 2;
+ return 0;
+ }
+ else {
+ fprintf(stderr, "could not map vram, expect crashes\n");
+ return -1;
+ }
+}
+
long GPUinit(void)
{
int ret;
ret = vout_init();
-
- gpu.state.enhancement_available = 0;
ret |= renderer_init();
- if (gpu.state.enhancement_available) {
- if (gpu.enhancement_bufer == NULL)
- gpu.enhancement_bufer = malloc(2048 * 1024 * 2 + 1024 * 512 * 2);
- if (gpu.enhancement_bufer == NULL)
- gpu_log("OOM for enhancement buffer\n");
- }
- else if (gpu.enhancement_bufer != NULL) {
- free(gpu.enhancement_bufer);
- gpu.enhancement_bufer = NULL;
- }
-
gpu.state.frame_count = &gpu.zero;
gpu.state.hcnt = &gpu.zero;
gpu.frameskip.active = 0;
gpu.cmd_len = 0;
do_reset();
+ if (gpu.mmap != NULL) {
+ if (map_vram() != 0)
+ ret = -1;
+ }
return ret;
}
long GPUshutdown(void)
{
- return vout_finish();
+ long ret;
+
+ renderer_finish();
+ ret = vout_finish();
+ if (gpu.vram != NULL) {
+ gpu.vram -= 4096 / 2;
+ gpu.munmap(gpu.vram, VRAM_SIZE);
+ }
+ gpu.vram = NULL;
+
+ return ret;
}
void GPUwriteStatus(uint32_t data)
break;
case 0x05:
gpu.screen.x = data & 0x3ff;
- gpu.screen.y = (data >> 10) & 0x3ff;
+ gpu.screen.y = (data >> 10) & 0x1ff;
if (gpu.frameskip.set) {
decide_frameskip_allow(gpu.ex_regs[3]);
if (gpu.frameskip.last_flip_frame != *gpu.state.frame_count) {
gpu.screen.vres = vres[(gpu.status.reg >> 19) & 3];
update_width();
update_height();
+ renderer_notify_res_change();
break;
default:
if ((cmd & 0xf0) == 0x10)
case 1: // save
if (gpu.cmd_len > 0)
flush_cmd_buffer();
- memcpy(freeze->psxVRam, gpu.vram, sizeof(gpu.vram));
+ memcpy(freeze->psxVRam, gpu.vram, 1024 * 512 * 2);
memcpy(freeze->ulControl, gpu.regs, sizeof(gpu.regs));
memcpy(freeze->ulControl + 0xe0, gpu.ex_regs, sizeof(gpu.ex_regs));
freeze->ulStatus = gpu.status.reg;
break;
case 0: // load
- memcpy(gpu.vram, freeze->psxVRam, sizeof(gpu.vram));
+ memcpy(gpu.vram, freeze->psxVRam, 1024 * 512 * 2);
memcpy(gpu.regs, freeze->ulControl, sizeof(gpu.regs));
memcpy(gpu.ex_regs, freeze->ulControl + 0xe0, sizeof(gpu.ex_regs));
gpu.status.reg = freeze->ulStatus;
gpu.state.allow_interlace = cbs->gpu_neon.allow_interlace;
gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable;
+ gpu.mmap = cbs->mmap;
+ gpu.munmap = cbs->munmap;
+
+ // delayed vram mmap
+ if (gpu.vram == NULL)
+ map_vram();
+
if (cbs->pl_vout_set_raw_vram)
cbs->pl_vout_set_raw_vram(gpu.vram);
renderer_set_config(cbs);