aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornotaz2015-01-10 21:54:34 +0200
committernotaz2015-01-12 03:01:01 +0200
commit09159d99cd07a084d8643f87c6c23e86c79060ff (patch)
tree0bbbe468d1961d34298d10bc3e73a224c6b3e36c
parent8f5f2dd5a70f47322614eda6f97304808447199c (diff)
downloadpcsx_rearmed-09159d99cd07a084d8643f87c6c23e86c79060ff.tar.gz
pcsx_rearmed-09159d99cd07a084d8643f87c6c23e86c79060ff.tar.bz2
pcsx_rearmed-09159d99cd07a084d8643f87c6c23e86c79060ff.zip
gpulib: use more conservative loop detection
the old one was causing too many cache misses
-rw-r--r--plugins/gpulib/gpu.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c
index c9b05d4..0e6fe63 100644
--- a/plugins/gpulib/gpu.c
+++ b/plugins/gpulib/gpu.c
@@ -521,7 +521,7 @@ void GPUwriteData(uint32_t data)
long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
{
- uint32_t addr, *list;
+ uint32_t addr, *list, ld_addr = 0;
uint32_t *llist_entry = NULL;
int len, left, count;
long cpu_cycles = 0;
@@ -542,7 +542,7 @@ long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
log_io("gpu_dma_chain\n");
addr = start_addr & 0xffffff;
- for (count = 0; addr != 0xffffff; count++)
+ for (count = 0; (addr & 0x800000) == 0; count++)
{
list = rambase + (addr & 0x1fffff) / 4;
len = list[0] >> 24;
@@ -555,28 +555,37 @@ long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
log_io(".chain %08x #%d\n", (list - rambase) * 4, len);
- // loop detection marker
- // (bit23 set causes DMA error on real machine, so
- // unlikely to be ever set by the game)
- list[0] |= 0x800000;
-
if (len) {
left = do_cmd_buffer(list + 1, len);
if (left)
log_anomaly("GPUdmaChain: discarded %d/%d words\n", left, len);
}
- if (addr & 0x800000)
- break;
+ #define LD_THRESHOLD (8*1024)
+ if (count >= LD_THRESHOLD) {
+ if (count == LD_THRESHOLD) {
+ ld_addr = addr;
+ continue;
+ }
+
+ // loop detection marker
+ // (bit23 set causes DMA error on real machine, so
+ // unlikely to be ever set by the game)
+ list[0] |= 0x800000;
+ }
}
- // remove loop detection markers
- addr = start_addr & 0x1fffff;
- while (count-- > 0) {
- list = rambase + addr / 4;
- addr = list[0] & 0x1fffff;
- list[0] &= ~0x800000;
+ if (ld_addr != 0) {
+ // remove loop detection markers
+ count -= LD_THRESHOLD + 2;
+ addr = ld_addr & 0x1fffff;
+ while (count-- > 0) {
+ list = rambase + addr / 4;
+ addr = list[0] & 0x1fffff;
+ list[0] &= ~0x800000;
+ }
}
+
if (llist_entry)
*llist_entry &= ~0x800000;