#include <stdlib.h> /* for calloc */
#include "gpu.h"
+#include "gpu_timing.h"
#include "../../libpcsxcore/gpu.h" // meh
#include "../../frontend/plugin_lib.h"
struct psx_gpu gpu;
-static noinline int do_cmd_buffer(uint32_t *data, int count);
+static noinline int do_cmd_buffer(uint32_t *data, int count, int *cpu_cycles);
static void finish_vram_transfer(int is_read);
static noinline void do_cmd_reset(void)
{
+ int dummy = 0;
renderer_sync();
-
if (unlikely(gpu.cmd_len > 0))
- do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
+ do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len, &dummy);
gpu.cmd_len = 0;
if (unlikely(gpu.dma.h > 0))
gpu.frameskip.active = 0;
if (!gpu.frameskip.active && gpu.frameskip.pending_fill[0] != 0) {
- int dummy;
- do_cmd_list(gpu.frameskip.pending_fill, 3, &dummy);
+ int dummy = 0;
+ do_cmd_list(gpu.frameskip.pending_fill, 3, &dummy, &dummy);
gpu.frameskip.pending_fill[0] = 0;
}
}
}
}
-// double, for overdraw guard
-#define VRAM_SIZE ((1024 * 512 * 2 * 2) + 4096)
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
// Minimum 16-byte VRAM alignment needed by gpu_unai's pixel-skipping
// renderer/downscaler it uses in high res modes:
#define VRAM_ALIGN 16
#endif
+// double, for overdraw guard + at least 1 page before
+#define VRAM_SIZE ((1024 * 512 * 2 * 2) + max(VRAM_ALIGN, 4096))
+
// vram ptr received from mmap/malloc/alloc (will deallocate using this)
static uint16_t *vram_ptr_orig = NULL;
static int map_vram(void)
{
#if GPULIB_USE_MMAP
- gpu.vram = vram_ptr_orig = gpu.mmap(VRAM_SIZE + (VRAM_ALIGN-1));
+ gpu.vram = vram_ptr_orig = gpu.mmap(VRAM_SIZE);
#else
- gpu.vram = vram_ptr_orig = calloc(VRAM_SIZE + (VRAM_ALIGN-1), 1);
+ gpu.vram = vram_ptr_orig = calloc(VRAM_SIZE, 1);
#endif
if (gpu.vram != NULL && gpu.vram != (void *)(intptr_t)-1) {
// 4kb guard in front
gpu.gpu_state_change(PGS_VRAM_TRANSFER_END);
}
-static void do_vram_copy(const uint32_t *params)
+static void do_vram_copy(const uint32_t *params, int *cpu_cycles)
{
const uint32_t sx = LE32TOH(params[0]) & 0x3FF;
const uint32_t sy = (LE32TOH(params[0]) >> 16) & 0x1FF;
uint16_t lbuf[128];
uint32_t x, y;
+ *cpu_cycles += gput_copy(w, h);
if (sx == dx && sy == dy && msb == 0)
return;
static noinline int do_cmd_list_skip(uint32_t *data, int count, int *last_cmd)
{
- int cmd = 0, pos = 0, len, dummy, v;
+ int cmd = 0, pos = 0, len, dummy = 0, v;
int skip = 1;
gpu.frameskip.pending_fill[0] = 0;
case 0x02:
if ((LE32TOH(list[2]) & 0x3ff) > gpu.screen.w || ((LE32TOH(list[2]) >> 16) & 0x1ff) > gpu.screen.h)
// clearing something large, don't skip
- do_cmd_list(list, 3, &dummy);
+ do_cmd_list(list, 3, &dummy, &dummy);
else
memcpy(gpu.frameskip.pending_fill, list, 3 * 4);
break;
return pos;
}
-static noinline int do_cmd_buffer(uint32_t *data, int count)
+static noinline int do_cmd_buffer(uint32_t *data, int count, int *cpu_cycles)
{
int cmd, pos;
uint32_t old_e3 = gpu.ex_regs[3];
cmd = -1; // incomplete cmd, can't consume yet
break;
}
- do_vram_copy(data + pos + 1);
+ do_vram_copy(data + pos + 1, cpu_cycles);
vram_dirty = 1;
pos += 4;
continue;
if (gpu.frameskip.active && (gpu.frameskip.allow || ((LE32TOH(data[pos]) >> 24) & 0xf0) == 0xe0))
pos += do_cmd_list_skip(data + pos, count - pos, &cmd);
else {
- pos += do_cmd_list(data + pos, count - pos, &cmd);
+ pos += do_cmd_list(data + pos, count - pos, cpu_cycles, &cmd);
vram_dirty = 1;
}
static noinline void flush_cmd_buffer(void)
{
- int left = do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len);
+ int dummy = 0, left;
+ left = do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len, &dummy);
if (left > 0)
memmove(gpu.cmd_buffer, gpu.cmd_buffer + gpu.cmd_len - left, left * 4);
if (left != gpu.cmd_len) {
void GPUwriteDataMem(uint32_t *mem, int count)
{
- int left;
+ int dummy = 0, left;
log_io("gpu_dma_write %p %d\n", mem, count);
if (unlikely(gpu.cmd_len > 0))
flush_cmd_buffer();
- left = do_cmd_buffer(mem, count);
+ left = do_cmd_buffer(mem, count, &dummy);
if (left)
log_anomaly("GPUwriteDataMem: discarded %d/%d words\n", left, count);
}
{
uint32_t addr, *list, ld_addr = 0;
int len, left, count;
- long cpu_cycles = 0;
+ int cpu_cycles = 0;
preload(rambase + (start_addr & 0x1fffff) / 4);
}
if (len) {
- left = do_cmd_buffer(list + 1, len);
+ left = do_cmd_buffer(list + 1, len, &cpu_cycles);
if (left) {
memcpy(gpu.cmd_buffer, list + 1 + len - left, left * 4);
gpu.cmd_len = left;