aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxgpu/image.c
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-12-18 16:30:02 +0100
committerGitHub <noreply@github.com>2022-12-18 16:30:02 +0100
commitb12b716a9e54c4f1892795a136d6ffeb088ff001 (patch)
tree5888e4a77b207f24ccd9ad148d1c74e9c33400e9 /libpsn00b/psxgpu/image.c
parent77306e187ef1a7ad5d3508ae9acb38edc5b68255 (diff)
parenta3359c0e7d85bf4752cda3b00892ecd5ef691077 (diff)
downloadpsn00bsdk-b12b716a9e54c4f1892795a136d6ffeb088ff001.tar.gz
Merge pull request #68 from spicyjpeg/bugfix
Bugfixes, psxcd rewrite, psxgpu and CMake tweaks (v0.22)
Diffstat (limited to 'libpsn00b/psxgpu/image.c')
-rw-r--r--libpsn00b/psxgpu/image.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/libpsn00b/psxgpu/image.c b/libpsn00b/psxgpu/image.c
index bbdb7c8..fc018a4 100644
--- a/libpsn00b/psxgpu/image.c
+++ b/libpsn00b/psxgpu/image.c
@@ -1,6 +1,10 @@
/*
* PSn00bSDK GPU library (image and VRAM transfer functions)
* (C) 2022 spicyjpeg - MPL licensed
+ *
+ * TODO: MoveImage() is currently commented out as it won't trigger a DMA IRQ,
+ * making it unusable as a draw queue command. A way around this (perhaps using
+ * the GPU IRQ?) shall be found.
*/
#include <stdint.h>
@@ -8,7 +12,17 @@
#include <psxgpu.h>
#include <hwregs_c.h>
-#define DMA_CHUNK_LENGTH 8
+#define QUEUE_LENGTH 16
+#define DMA_CHUNK_LENGTH 8
+
+/* Internal globals */
+
+// LoadImage() and StoreImage() run asynchronously but may be called with a
+// pointer to a RECT struct in the stack, which might no longer be valid by the
+// time the transfer is actually started. This buffer is used to store a copy
+// of all RECTs passed to LoadImage()/StoreImage() as a workaround.
+static RECT _saved_rects[QUEUE_LENGTH];
+static int _next_saved_rect = 0;
/* Private utilities */
@@ -47,21 +61,33 @@ static void _dma_transfer(const RECT *rect, uint32_t *data, int write) {
/* VRAM transfer API */
int LoadImage(const RECT *rect, const uint32_t *data) {
+ int index = _next_saved_rect;
+
+ _saved_rects[index] = *rect;
+ _next_saved_rect = (index + 1) % QUEUE_LENGTH;
+
return EnqueueDrawOp(
- (void *) &_dma_transfer, (uint32_t) rect, (uint32_t) data, 1
+ (void *) &_dma_transfer,
+ (uint32_t) &_saved_rects[index],
+ (uint32_t) data,
+ 1
);
}
int StoreImage(const RECT *rect, uint32_t *data) {
+ int index = _next_saved_rect;
+
+ _saved_rects[index] = *rect;
+ _next_saved_rect = (index + 1) % QUEUE_LENGTH;
+
return EnqueueDrawOp(
- (void *) &_dma_transfer, (uint32_t) rect, (uint32_t) data, 0
+ (void *) &_dma_transfer,
+ (uint32_t) &_saved_rects[index],
+ (uint32_t) data,
+ 0
);
}
-int MoveImage(const RECT *rect, int x, int y) {
- return EnqueueDrawOp((void *) &MoveImage2, (uint32_t) rect, x, y);
-}
-
void LoadImage2(const RECT *rect, const uint32_t *data) {
_dma_transfer(rect, (uint32_t *) data, 1);
}
@@ -70,14 +96,14 @@ void StoreImage2(const RECT *rect, uint32_t *data) {
_dma_transfer(rect, data, 0);
}
-void MoveImage2(const RECT *rect, int x, int y) {
+/*void MoveImage2(const RECT *rect, int x, int y) {
GPU_GP0 = 0x80000000;
//GPU_GP0 = rect->x | (rect->y << 16);
GPU_GP0 = *((const uint32_t *) &(rect->x));
GPU_GP0 = (x & 0xffff) | (y << 16);
//GPU_GP0 = rect->w | (rect->h << 16);
GPU_GP0 = *((const uint32_t *) &(rect->w));
-}
+}*/
/* .TIM image parsers */