From: quzar <qu...@us...> - 2025-01-04 23:28:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via c27605764db8ce5fa1a0dcb97042f581f6489483 (commit) via 332849239339b6f9c03262409af7432be7df2087 (commit) via a7b91654aa5f09f8cec425972b7e16c40de3a068 (commit) via 8b5678199a54459aeaa27b4e2e25a8cdb400cbd5 (commit) via 1354971121aa233f09865f874b6fdd0c3e4b583f (commit) via cd5d5209e023002a296a2a70767f385844be29fb (commit) via c36af5c408315f846f685740c247f40788b204f6 (commit) via 0aff2640833cadc17b24784b8912bc605b4c3b55 (commit) via 1314a7b2efe4caacb5aa4d6bdeae6c4185f8260a (commit) via 0059576045f2d437ab19c4e786b703d68c9eb964 (commit) via f015717383fbe72bf171bee54b4abb60928d2345 (commit) via ea5e113375ca4dcc552dbe78d1d586e741e23241 (commit) via 8448dfbd22363124ffc5121b171c325176b34229 (commit) via 51f122fa0d94834a4603df4cd7baa07753176f4d (commit) via 528a91b7ee47bb20e38d010852a0643fc28d955e (commit) via 6321f11fb0ab6e921a5d675a960958cfc4adb3c8 (commit) via 55261b67b197a4a3d276bb46807f0466c60c8e5f (commit) via dfcb36237c952afed34c47aeb37f87200c222a29 (commit) via 6bedd3a455b7bc7e2bfa21d2731af682de2dfe75 (commit) from 3ac9880e61d086cd62d31bbad63d4998821a4858 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c27605764db8ce5fa1a0dcb97042f581f6489483 Merge: 33284923 ea5e1133 Author: Donald Haase <qu...@ya...> Date: Sat Jan 4 18:26:51 2025 -0500 Merge pull request #874 from KallistiOS/pvr_refresh_I PVR Function Prototypes Cleanup (pvr.h refactor #539 part 1) commit 332849239339b6f9c03262409af7432be7df2087 Merge: a7b91654 13549711 Author: Donald Haase <qu...@ya...> Date: Sat Jan 4 18:13:58 2025 -0500 Merge pull request #879 from pcercuei/pvr-fix-sq-with-dma pvr: Do not check DMA completion in pvr_sq functions commit a7b91654aa5f09f8cec425972b7e16c40de3a068 Merge: 8b567819 00595760 Author: Donald Haase <qu...@ya...> Date: Sat Jan 4 18:11:24 2025 -0500 Merge pull request #859 from pcercuei/pvr-get-front-buffer Add pvr_wait_render_done() and pvr_get_front_buffer() commit 8b5678199a54459aeaa27b4e2e25a8cdb400cbd5 Merge: cd5d5209 c36af5c4 Author: Donald Haase <qu...@ya...> Date: Sat Jan 4 18:01:36 2025 -0500 Merge pull request #866 from pcercuei/pvr-fix-dma-mode pvr: Fix direct rendering when DMA mode is enabled commit 1354971121aa233f09865f874b6fdd0c3e4b583f Author: Paul Cercueil <pa...@cr...> Date: Fri Jan 3 18:42:52 2025 +0100 pvr: Do not check DMA completion in pvr_sq functions The only reason why you would want to wait for any pending DMA transfer to complete before using the SQs is when the DMA transfer targets the TA, in which case a SQ transfer to the TA would be asking for trouble. However, the PVR scene code is already making sure that the TA is ready before a new list can be opened; this means that it is guaranteed that lists configured for DMA will be done transferring before anything is transferred to the TA via SQs. Therefore, with the current driver code, there is no point in waiting for DMA completion. With that said, the code actually did not wait for DMA completion, but was doing something much worse: in the case where a DMA transfer was in progress, it would simply display an error, and return without processing the SQ transfer. This caused heavy errors, including crashes, for instance when a list's "EOL marker" could not be added. Address this issue by simply not checking for the DMA completion in the pvr_sq functions. Fixes #878. Signed-off-by: Paul Cercueil <pa...@cr...> commit cd5d5209e023002a296a2a70767f385844be29fb Merge: 3ac9880e 0aff2640 Author: Donald Haase <qu...@ya...> Date: Thu Dec 26 11:08:09 2024 -0500 Merge pull request #861 from DC-SWAT/gd_dma_cache_fix Fix and improve CPU cache management for devices on G1 bus. commit c36af5c408315f846f685740c247f40788b204f6 Author: Paul Cercueil <pa...@cr...> Date: Mon Dec 9 15:56:04 2024 +0100 pvr: Fix direct rendering when DMA mode is enabled The "pvr_state.lists_closed" was reset only when DMA mode was not enabled. This caused problems when the geometry was only submitted via direct rendering. Signed-off-by: Paul Cercueil <pa...@cr...> commit 0aff2640833cadc17b24784b8912bc605b4c3b55 Author: DC-SWAT <sw...@21...> Date: Wed Dec 4 11:12:40 2024 +0700 g1ata: Improved check for the need for CPU cache manage. commit 1314a7b2efe4caacb5aa4d6bdeae6c4185f8260a Author: DC-SWAT <sw...@21...> Date: Wed Dec 4 11:12:35 2024 +0700 cdrom: Alignment check and manage CPU cache for sector read. commit 0059576045f2d437ab19c4e786b703d68c9eb964 Author: Paul Cercueil <pa...@cr...> Date: Tue Dec 3 21:16:48 2024 +0100 pvr: Add pvr_init() flag to disable vertex buffer double-buffering Having a double-buffering mechanism for the vertex buffer makes it possible to upload geometry data to the Tile Accelerator while the PVR is busy rendering the previous scene. However, it means having two buffers for the geometry data. Some applications may prefer using a much smaller vertex buffer to lower VRAM usage, even if it means the TA and PVR cannot be used at the same time. Signed-off-by: Paul Cercueil <pa...@cr...> commit f015717383fbe72bf171bee54b4abb60928d2345 Author: Paul Cercueil <pa...@cr...> Date: Fri Nov 29 13:54:26 2024 +0100 pvr: Add pvr_get_front_buffer() This function can be used to retrieve a pointer to the front buffer, aka. the last fully rendered buffer that is either being displayed right now, or is queued to be displayed. Signed-off-by: Paul Cercueil <pa...@cr...> commit ea5e113375ca4dcc552dbe78d1d586e741e23241 Author: QuzarDC <qu...@co...> Date: Thu Nov 28 22:06:50 2024 -0500 Update pvr_mem function prototype types commit 8448dfbd22363124ffc5121b171c325176b34229 Author: Paul Cercueil <pa...@cr...> Date: Sat Nov 9 21:36:24 2024 +0100 pvr: add pvr_wait_render_done() This function can be used to wait until the PVR is done rendering a previous scene. This can be useful for instance to make sure that the PVR is done using textures that have to be updated, before updating those. Signed-off-by: Paul Cercueil <pa...@cr...> commit 51f122fa0d94834a4603df4cd7baa07753176f4d Author: QuzarDC <qu...@co...> Date: Thu Nov 28 00:21:25 2024 -0500 Clean up function prototypes in pvr_fog commit 528a91b7ee47bb20e38d010852a0643fc28d955e Author: QuzarDC <qu...@co...> Date: Wed Nov 27 21:42:52 2024 -0500 Clean up function typing in pvr_scene. commit 6321f11fb0ab6e921a5d675a960958cfc4adb3c8 Author: QuzarDC <qu...@co...> Date: Tue Nov 26 15:39:12 2024 -0500 Update init functions to constify params. commit 55261b67b197a4a3d276bb46807f0466c60c8e5f Author: QuzarDC <qu...@co...> Date: Tue Nov 26 11:52:19 2024 -0500 Update typing in pvr_set_shadow_scale - Updated enable param to bool, as well as the logic that clamped it. - Updated examples to use the new type. commit dfcb36237c952afed34c47aeb37f87200c222a29 Author: QuzarDC <qu...@co...> Date: Tue Nov 26 11:32:27 2024 -0500 Clean up typing in pvr dma - Update block parameter of loads and blocking var to bool. - Update source pointers of loads to const. - Update pvr_dma_ready to return a bool. commit 6bedd3a455b7bc7e2bfa21d2731af682de2dfe75 Author: QuzarDC <qu...@co...> Date: Tue Nov 26 10:49:40 2024 -0500 Clean up typing for pvr_buffers.c - Use bool rather than int for 'presort'. - Set the param of pvr_allocate_buffers to a const. ----------------------------------------------------------------------- Summary of changes: examples/dreamcast/pvr/cheap_shadow/shadow.c | 6 +- .../dreamcast/pvr/modifier_volume_zclip/example.c | 2 +- kernel/arch/dreamcast/hardware/cdrom.c | 36 ++++++++-- kernel/arch/dreamcast/hardware/g1ata.c | 33 ++++++--- kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c | 8 +-- kernel/arch/dreamcast/hardware/pvr/pvr_dma.c | 34 +++------ kernel/arch/dreamcast/hardware/pvr/pvr_fog.c | 10 +-- .../dreamcast/hardware/pvr/pvr_init_shutdown.c | 11 ++- kernel/arch/dreamcast/hardware/pvr/pvr_internal.h | 8 ++- kernel/arch/dreamcast/hardware/pvr/pvr_irq.c | 4 +- kernel/arch/dreamcast/hardware/pvr/pvr_mem.c | 6 +- kernel/arch/dreamcast/hardware/pvr/pvr_misc.c | 24 ++++++- kernel/arch/dreamcast/hardware/pvr/pvr_scene.c | 34 ++++++--- kernel/arch/dreamcast/include/dc/cdrom.h | 11 ++- kernel/arch/dreamcast/include/dc/g1ata.h | 10 ++- kernel/arch/dreamcast/include/dc/pvr.h | 83 +++++++++++++++------- 16 files changed, 220 insertions(+), 100 deletions(-) diff --git a/examples/dreamcast/pvr/cheap_shadow/shadow.c b/examples/dreamcast/pvr/cheap_shadow/shadow.c index 08e38724..349f5126 100644 --- a/examples/dreamcast/pvr/cheap_shadow/shadow.c +++ b/examples/dreamcast/pvr/cheap_shadow/shadow.c @@ -96,11 +96,11 @@ int check_start(void) { if(state->joyy > 64) { shadow = CLAMP(0.0f, 1.0f, shadow + 0.01f); - pvr_set_shadow_scale(1, shadow); + pvr_set_shadow_scale(true, shadow); } else if(state->joyy < -64) { shadow = CLAMP(0.0f, 1.0f, shadow - 0.01f); - pvr_set_shadow_scale(1, shadow); + pvr_set_shadow_scale(true, shadow); } if(state->buttons & CONT_START) @@ -212,7 +212,7 @@ int main(int argc, char *argv[]) { /* Enable Cheap Shadow mode and set affected polygons to be at half of their normal intensity. */ - pvr_set_shadow_scale(1, shadow); + pvr_set_shadow_scale(true, shadow); setup(); diff --git a/examples/dreamcast/pvr/modifier_volume_zclip/example.c b/examples/dreamcast/pvr/modifier_volume_zclip/example.c index 564137bc..ef7eb608 100644 --- a/examples/dreamcast/pvr/modifier_volume_zclip/example.c +++ b/examples/dreamcast/pvr/modifier_volume_zclip/example.c @@ -252,7 +252,7 @@ int main(int argc, char* argv[]) pvr_init(¶ms); pvr_set_bg_color(0, 0.5f, 1.0f); /* Enable cheap shadow */ - pvr_set_shadow_scale(1, 0.5f); + pvr_set_shadow_scale(true, 0.5f); /* init plane */ box_tex = pvr_mem_malloc(256 * 256 * 2); diff --git a/kernel/arch/dreamcast/hardware/cdrom.c b/kernel/arch/dreamcast/hardware/cdrom.c index 09ec0ca6..70a4cabb 100644 --- a/kernel/arch/dreamcast/hardware/cdrom.c +++ b/kernel/arch/dreamcast/hardware/cdrom.c @@ -5,12 +5,13 @@ Copyright (C) 2000 Megan Potter Copyright (C) 2014 Lawrence Sebald Copyright (C) 2014 Donald Haase - Copyright (C) 2023 Ruslan Rostovtsev + Copyright (C) 2023, 2024 Ruslan Rostovtsev Copyright (C) 2024 Andy Barajas */ #include <assert.h> +#include <arch/cache.h> #include <arch/timer.h> #include <arch/memory.h> @@ -55,6 +56,8 @@ typedef int gdc_cmd_hnd_t; /* The G1 ATA access mutex */ mutex_t _g1_ata_mutex = MUTEX_INITIALIZER; +static int cur_sector_size = 2048; + /* Shortcut to cdrom_reinit_ex. Typically this is the only thing changed. */ int cdrom_set_sector_size(int size) { return cdrom_reinit_ex(-1, -1, size); @@ -215,6 +218,7 @@ int cdrom_change_datatype(int sector_part, int cdxa, int sector_size) { params[2] = cdxa; /* CD-XA mode 1/2 */ params[3] = sector_size; /* sector size */ + cur_sector_size = sector_size; return syscall_gdrom_sector_mode(params); } @@ -265,10 +269,10 @@ int cdrom_read_sectors_ex(void *buffer, int sector, int cnt, int mode) { int is_test; } params; int rv = ERR_OK; + uintptr_t buf_addr = ((uintptr_t)buffer); params.sec = sector; /* Starting sector */ params.num = cnt; /* Number of sectors */ - params.buffer = buffer; /* Output buffer */ params.is_test = 0; /* Enable test mode */ /* The DMA mode blocks the thread it is called in by the way we execute @@ -276,10 +280,34 @@ int cdrom_read_sectors_ex(void *buffer, int sector, int cnt, int mode) { /* XXX: DMA Mode may conflict with using a second G1ATA device. More testing is needed from someone with such a device. */ - if(mode == CDROM_READ_DMA) + if(mode == CDROM_READ_DMA) { + if(buf_addr & 0x1f) { + dbglog(DBG_ERROR, "cdrom_read_sectors_ex: Unaligned memory for DMA (32-byte).\n"); + return ERR_SYS; + } + /* Use the physical memory address. */ + params.buffer = (void *)(buf_addr & MEM_AREA_CACHE_MASK); + + /* Invalidate the CPU cache only for cacheable memory areas. + Otherwise, it is assumed that either this operation is unnecessary + (another DMA is being used) or that the caller is responsible + for managing the CPU data cache. + */ + if((buf_addr & MEM_AREA_P2_BASE) != MEM_AREA_P2_BASE) { + /* Invalidate the dcache over the range of the data. */ + dcache_inval_range(buf_addr, cnt * cur_sector_size); + } rv = cdrom_exec_cmd(CMD_DMAREAD, ¶ms); - else if(mode == CDROM_READ_PIO) + } + else if(mode == CDROM_READ_PIO) { + params.buffer = buffer; + + if(buf_addr & 0x01) { + dbglog(DBG_ERROR, "cdrom_read_sectors_ex: Unaligned memory for PIO (2-byte).\n"); + return ERR_SYS; + } rv = cdrom_exec_cmd(CMD_PIOREAD, ¶ms); + } return rv; } diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index badc9ebc..35dad2db 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -20,6 +20,7 @@ #include <arch/timer.h> #include <arch/cache.h> #include <arch/irq.h> +#include <arch/memory.h> /* This file implements support for accessing devices over the G1 bus by the @@ -618,7 +619,7 @@ out: int g1_ata_read_lba_dma(uint64_t sector, size_t count, void *buf, int block) { int lba28, old, can_lba48 = CAN_USE_LBA48(); - uint32_t addr; + uintptr_t addr; uint8_t cmd; /* Make sure we're actually being asked to do work... */ @@ -661,7 +662,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, void *buf, } /* Check the alignment of the address. */ - addr = ((uint32_t)buf) & 0x0FFFFFFF; + addr = (uintptr_t)buf; if(addr & 0x1F) { dbglog(DBG_ERROR, "g1_ata_read_lba_dma: Unaligned output address\n"); @@ -669,11 +670,19 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, void *buf, return -1; } - if((addr >> 24) == 0x0C) { + /* Invalidate the CPU cache only for cacheable memory areas. + Otherwise, it is assumed that either this operation is unnecessary + (another DMA is being used) or that the caller is responsible + for managing the CPU data cache. + */ + if((addr & MEM_AREA_P2_BASE) != MEM_AREA_P2_BASE) { /* Invalidate the dcache over the range of the data. */ - dcache_inval_range((uint32)buf, count * 512); + dcache_inval_range(addr, count * 512); } + /* Use the physical memory address. */ + addr &= MEM_AREA_CACHE_MASK; + /* Lock the mutex. It will be unlocked later in the IRQ handler. */ if(g1_ata_mutex_lock()) return -1; @@ -801,7 +810,7 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const void *buf) { int g1_ata_write_lba_dma(uint64_t sector, size_t count, const void *buf, int block) { int cmd, lba28, old, can_lba48 = CAN_USE_LBA48(); - uint32_t addr; + uintptr_t addr; /* Make sure we're actually being asked to do work... */ if(!count) @@ -843,7 +852,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const void *buf, } /* Check the alignment of the address. */ - addr = ((uint32_t)buf) & 0x0FFFFFFF; + addr = (uintptr_t)buf; if(addr & 0x1F) { dbglog(DBG_ERROR, "g1_ata_write_lba_dma: Unaligned input address\n"); @@ -851,11 +860,19 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const void *buf, return -1; } - if((addr >> 24) == 0x0C) { + /* Flush the CPU cache only for cacheable memory areas. + Otherwise, it is assumed that either this operation is unnecessary + (another DMA is being used) or that the caller is responsible + for managing the CPU data cache. + */ + if((addr & MEM_AREA_P2_BASE) != MEM_AREA_P2_BASE) { /* Flush the dcache over the range of the data. */ - dcache_flush_range((uint32)buf, count * 512); + dcache_flush_range(addr, count * 512); } + /* Use the physical memory address. */ + addr &= MEM_AREA_CACHE_MASK; + /* Lock the mutex. It will be unlocked in the IRQ handler later. */ if(g1_ata_mutex_lock()) return -1; diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c b/kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c index 0d5bc628..9c251acb 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_buffers.c @@ -34,7 +34,7 @@ /* Fill Tile Matrix buffers. This function takes a base address and sets up the rendering structures there. Each tile of the screen (32x32) receives a small buffer space. */ -static void pvr_init_tile_matrix(int which, int presort) { +static void pvr_init_tile_matrix(int which, bool presort) { volatile pvr_ta_buffers_t *buf; int x, y, tn; uint32 *vr; /* Note: We're working in 4-byte pointer maths in this function */ @@ -125,14 +125,14 @@ static void pvr_init_tile_matrix(int which, int presort) { } /* Fill all tile matrices */ -void pvr_init_tile_matrices(int presort) { +void pvr_init_tile_matrices(bool presort) { int i; for(i = 0; i < 2; i++) pvr_init_tile_matrix(i, presort); } -void pvr_set_presort_mode(int presort) { +void pvr_set_presort_mode(bool presort) { pvr_init_tile_matrix(pvr_state.ta_target, presort); } @@ -151,7 +151,7 @@ up and placed at 0x000000 and 0x400000. #define BUF_ALIGN_MASK (BUF_ALIGN - 1) #define APPLY_ALIGNMENT(addr) (((addr) + BUF_ALIGN_MASK) & ~BUF_ALIGN_MASK) -void pvr_allocate_buffers(pvr_init_params_t *params) { +void pvr_allocate_buffers(const pvr_init_params_t *params) { volatile pvr_ta_buffers_t *buf; volatile pvr_frame_buffers_t *fbuf; int i, j; diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_dma.c b/kernel/arch/dreamcast/hardware/pvr/pvr_dma.c index 521a5215..40ed9cd9 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_dma.c +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_dma.c @@ -24,7 +24,7 @@ /* Signaling semaphore */ static semaphore_t dma_done; -static int32_t dma_blocking; +static bool dma_blocking; static pvr_dma_callback_t dma_callback; static void *dma_cbdata; @@ -62,7 +62,7 @@ static void pvr_dma_irq_hnd(uint32_t code, void *data) { if(dma_blocking) { sem_signal(&dma_done); thd_schedule(1, 0); - dma_blocking = 0; + dma_blocking = false; } } @@ -96,7 +96,7 @@ static uintptr_t pvr_dest_addr(uintptr_t dest, pvr_dma_type_t type) { } int pvr_dma_transfer(const void *src, uintptr_t dest, size_t count, - pvr_dma_type_t type, int block, + pvr_dma_type_t type, bool block, pvr_dma_callback_t callback, void *cbdata) { uintptr_t src_addr = ((uintptr_t)src); @@ -146,30 +146,30 @@ int pvr_dma_transfer(const void *src, uintptr_t dest, size_t count, } /* Count is in bytes. */ -int pvr_txr_load_dma(void *src, pvr_ptr_t dest, size_t count, int block, +int pvr_txr_load_dma(const void *src, pvr_ptr_t dest, size_t count, bool block, pvr_dma_callback_t callback, void *cbdata) { return pvr_dma_transfer(src, (uintptr_t)dest, count, PVR_DMA_VRAM64, block, callback, cbdata); } -int pvr_dma_load_ta(void *src, size_t count, int block, +int pvr_dma_load_ta(const void *src, size_t count, bool block, pvr_dma_callback_t callback, void *cbdata) { return pvr_dma_transfer(src, (uintptr_t)0, count, PVR_DMA_TA, block, callback, cbdata); } -int pvr_dma_yuv_conv(void *src, size_t count, int block, +int pvr_dma_yuv_conv(const void *src, size_t count, bool block, pvr_dma_callback_t callback, void *cbdata) { return pvr_dma_transfer(src, (uintptr_t)0, count, PVR_DMA_YUV, block, callback, cbdata); } -int pvr_dma_ready(void) { +bool pvr_dma_ready(void) { return pvr_dma[PVR_DST] == 0; } void pvr_dma_init(void) { /* Create an initially blocked semaphore */ sem_init(&dma_done, 0); - dma_blocking = 0; + dma_blocking = false; dma_callback = NULL; dma_cbdata = 0; @@ -200,12 +200,6 @@ void pvr_dma_shutdown(void) { void *pvr_sq_load(void *dest, const void *src, size_t n, pvr_dma_type_t type) { void *dma_area_ptr; - if(pvr_dma[PVR_DST] != 0) { - dbglog(DBG_ERROR, "pvr_sq_load: PVR DMA has not finished\n"); - errno = EINPROGRESS; - return NULL; - } - dma_area_ptr = (void *)pvr_dest_addr((uintptr_t)dest, type); sq_cpy(dma_area_ptr, src, n); @@ -216,12 +210,6 @@ void *pvr_sq_load(void *dest, const void *src, size_t n, pvr_dma_type_t type) { void *pvr_sq_set16(void *dest, uint32_t c, size_t n, pvr_dma_type_t type) { void *dma_area_ptr; - if(pvr_dma[PVR_DST] != 0) { - dbglog(DBG_ERROR, "pvr_sq_set16: PVR DMA has not finished\n"); - errno = EINPROGRESS; - return NULL; - } - dma_area_ptr = (void *)pvr_dest_addr((uintptr_t)dest, type); sq_set16(dma_area_ptr, c, n); @@ -232,12 +220,6 @@ void *pvr_sq_set16(void *dest, uint32_t c, size_t n, pvr_dma_type_t type) { void *pvr_sq_set32(void *dest, uint32_t c, size_t n, pvr_dma_type_t type) { void *dma_area_ptr; - if(pvr_dma[PVR_DST] != 0) { - dbglog(DBG_ERROR, "pvr_sq_set32: PVR DMA has not finished\n"); - errno = EINPROGRESS; - return NULL; - } - dma_area_ptr = (void *)pvr_dest_addr((uintptr_t)dest, type); sq_set32(dma_area_ptr, c, n); diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_fog.c b/kernel/arch/dreamcast/hardware/pvr/pvr_fog.c index 9b5aaa61..b7da92d3 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_fog.c +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_fog.c @@ -158,7 +158,7 @@ union ieee32_t { /* A fast negative argument only exp function - That is it treats any * argument as a negative number */ -float neg_exp(float arg) { +static float neg_exp(float arg) { float result, f; int k; @@ -206,7 +206,7 @@ float neg_exp(float arg) { The special values for infinity and NaN are not dealt with at all. */ -uint32 float16(float f) { +static uint32 float16(float f) { union ieee32_t float32; uint32 float16; uint32 sign, exponent, mantissa; @@ -343,14 +343,14 @@ void pvr_fog_table_linear(float start, float end) { * 0th entry is farthest from eye. Last entry is nearest to eye. * The larger the value the heavier the fog. */ -void pvr_fog_table_custom(float tbl1[]) { +void pvr_fog_table_custom(float *table) { uint32 idx, i; uint32 value, valh, vall; - valh = (uint32)(fog_alpha * 255.0f * CLAMP01(tbl1[0])) & 0xff; + valh = (uint32)(fog_alpha * 255.0f * CLAMP01(table[0])) & 0xff; for(idx = PVR_FOG_TABLE_BASE, i = 1; idx < TABLE_LEN; idx += 4, i++) { - vall = (uint32)(fog_alpha * 255.0f * CLAMP01(tbl1[i])) & 0xff; + vall = (uint32)(fog_alpha * 255.0f * CLAMP01(table[i])) & 0xff; value = (((valh) << 8 & 0xff00) + vall); PVR_SET(idx, value); valh = vall; diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_init_shutdown.c b/kernel/arch/dreamcast/hardware/pvr/pvr_init_shutdown.c index cbe77d70..c70758cf 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_init_shutdown.c +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_init_shutdown.c @@ -25,7 +25,7 @@ and translucent lists, and 0's for everything else; 512k of vertex buffer. This is equivalent to the old ta_init_defaults() for now. */ int pvr_init_defaults(void) { - pvr_init_params_t params = { + const pvr_init_params_t params = { /* Enable opaque and translucent polygons with size 16 */ { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0 }, @@ -42,7 +42,10 @@ int pvr_init_defaults(void) { 0, /* Extra OPBs */ - 3 + 3, + + /* Vertex buffer double-buffering enabled */ + 0 }; return pvr_init(¶ms); @@ -52,7 +55,7 @@ int pvr_init_defaults(void) { and using the specified parameters; note that bins and vertex buffers come from the texture memory pool! Expects that a 2D mode was initialized already using the vid_* API. */ -int pvr_init(pvr_init_params_t *params) { +int pvr_init(const pvr_init_params_t *params) { /* If we're already initialized, fail */ if(pvr_state.valid == 1) { dbglog(DBG_WARNING, "pvr: pvr_init called twice!\n"); @@ -89,6 +92,8 @@ int pvr_init(pvr_init_params_t *params) { // Copy over FSAA setting. pvr_state.fsaa = params->fsaa_enabled; + pvr_state.vbuf_doublebuf = !params->vbuf_doublebuf_disabled; + /* Everything's clear, do the initial buffer pointer setup */ pvr_allocate_buffers(params); diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_internal.h b/kernel/arch/dreamcast/hardware/pvr/pvr_internal.h index 4c7c72da..22114dc3 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_internal.h +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_internal.h @@ -16,6 +16,7 @@ code. If something is needed from this, an external interface should be added to dc/pvr.h. */ +#include <stdbool.h> #include <kos/mutex.h> /**** State stuff ***************************************************/ @@ -210,6 +211,9 @@ typedef struct { // Non-zero if FSAA was enabled at init time. int fsaa; + // Non-zero if using double-buffering for the vertex buffer. + int vbuf_doublebuf; + // Non-zero if we are rendering to a texture int to_texture[2]; @@ -248,10 +252,10 @@ typedef struct pvr_bkg_poly { /**** pvr_buffers.c ***************************************************/ /* Initialize buffers for TA/ISP/TSP usage */ -void pvr_allocate_buffers(pvr_init_params_t *params); +void pvr_allocate_buffers(const pvr_init_params_t *params); /* Fill the tile matrices (after it's initialized) */ -void pvr_init_tile_matrices(int presort); +void pvr_init_tile_matrices(bool presort); /**** pvr_misc.c ******************************************************/ diff --git a/kernel/arch/dreamcast/hardware/pvr/pvr_irq.c b/kernel/arch/dreamcast/hardware/pvr/pvr_irq.c index 9d456c32..13848d29 100644 --- a/kernel/arch/dreamcast/hardware/pvr/pvr_irq.c +++ b/kernel/arch/dreamcast/hardware/pvr/pvr_irq.c @@ -112,7 +112,7 @@ static void pvr_render_lists(void) { // Begin rendering from the dirty TA buffer into the clean // frame buffer. //DBG(("start_render(%d -> %d)\n", pvr_state.ta_target, pvr_state.view_target ^ 1)); - pvr_state.ta_target ^= 1; + pvr_state.ta_target ^= pvr_state.vbuf_doublebuf; pvr_begin_queued_render(); pvr_state.render_busy = 1; pvr_sync_stats(PVR_SYNC_RNDSTART); @@ -191,6 +191,8 @@ void pvr_int_handler(uint32 code, void *data) { ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |