From 1c61512e642cd2b7091a222e9a529dcbe241a4b3 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 4 Oct 2024 18:09:34 +1000 Subject: [PATCH] Dreamcast: Further simplifications --- src/Graphics_Dreamcast.c | 87 +++++++++++++++++---------- third_party/gldc/src/aligned_vector.h | 68 --------------------- third_party/gldc/src/gldc.h | 65 ++++++++++++++------ third_party/gldc/src/sh4.c | 1 + third_party/gldc/src/state.c | 22 +------ third_party/gldc/src/texture.c | 8 +-- 6 files changed, 106 insertions(+), 145 deletions(-) delete mode 100644 third_party/gldc/src/aligned_vector.h diff --git a/src/Graphics_Dreamcast.c b/src/Graphics_Dreamcast.c index 523557bc2..9fc3d6054 100644 --- a/src/Graphics_Dreamcast.c +++ b/src/Graphics_Dreamcast.c @@ -11,14 +11,38 @@ #include "../third_party/gldc/src/gldc.h" static cc_bool renderingDisabled; +static cc_bool stateDirty; #define VERTEX_BUFFER_SIZE 32 * 40000 #define PT_ALPHA_REF 0x011c +/*########################################################################################################################* +*-------------------------------------------------------Vertex list-------------------------------------------------------* +*#########################################################################################################################*/ +static void VertexList_Append(AlignedVector* list, const void* cmd) { + void* dst = aligned_vector_reserve(list, list->size + 1); + assert(dst); + + memcpy(dst, cmd, VERTEX_SIZE); + list->size++; +} + + /*########################################################################################################################* *---------------------------------------------------------General---------------------------------------------------------* *#########################################################################################################################*/ -static void InitPowerVR(void) { +static AlignedVector listOP; +static AlignedVector listPT; +static AlignedVector listTR; + +static CC_INLINE AlignedVector* ActivePolyList(void) { + if (gfx_alphaBlend) return &listTR; + if (gfx_alphaTest) return &listPT; + + return &listOP; +} + +static void InitGPU(void) { cc_bool autosort = false; // Turn off auto sorting to match traditional GPU behaviour cc_bool fsaa = false; AUTOSORT_ENABLED = autosort; @@ -46,12 +70,19 @@ static void InitGLState(void) { TEXTURES_ENABLED = false; FOG_ENABLED = false; - STATE_DIRTY = true; + stateDirty = true; + listOP.list_type = PVR_LIST_OP_POLY; + listPT.list_type = PVR_LIST_PT_POLY; + listTR.list_type = PVR_LIST_TR_POLY; + + aligned_vector_reserve(&listOP, 1024 * 3); + aligned_vector_reserve(&listPT, 512 * 3); + aligned_vector_reserve(&listTR, 1024 * 3); } void Gfx_Create(void) { - if (!Gfx.Created) InitPowerVR(); - if (!Gfx.Created) glKosInit(); + if (!Gfx.Created) InitGPU(); + if (!Gfx.Created) texmem_init(); InitGLState(); @@ -81,12 +112,12 @@ static PackedCol gfx_clearColor; void Gfx_SetFaceCulling(cc_bool enabled) { CULLING_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } static void SetAlphaBlend(cc_bool enabled) { BLEND_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_SetAlphaArgBlend(cc_bool enabled) { } @@ -108,19 +139,19 @@ void Gfx_SetDepthWrite(cc_bool enabled) { if (DEPTH_MASK_ENABLED == enabled) return; DEPTH_MASK_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_SetDepthTest(cc_bool enabled) { if (DEPTH_TEST_ENABLED == enabled) return; DEPTH_TEST_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } static void SetAlphaTest(cc_bool enabled) { ALPHA_TEST_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_DepthOnlyRendering(cc_bool depthOnly) { @@ -321,11 +352,10 @@ static void ConvertTexture(cc_uint16* dst, struct Bitmap* bmp, int rowWidth) { } static TextureObject* FindFreeTexture(void) { - // ID 0 is reserved for default texture - for (int i = 1; i < MAX_TEXTURE_COUNT; i++) + for (int i = 0; i < MAX_TEXTURE_COUNT; i++) { TextureObject* tex = &TEXTURE_LIST[i]; - if (tex->data == NULL) return tex; + if (!tex->data) return tex; } return NULL; } @@ -380,10 +410,8 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i } void Gfx_BindTexture(GfxResourceID texId) { - if (!texId) texId = &TEXTURE_LIST[0]; - TEXTURE_ACTIVE = (TextureObject*)texId; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_DeleteTexture(GfxResourceID* texId) { @@ -409,7 +437,7 @@ void Gfx_SetFog(cc_bool enabled) { if (FOG_ENABLED == enabled) return; FOG_ENABLED = enabled; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_SetFogCol(PackedCol color) { @@ -554,16 +582,16 @@ static Vertex* ReserveOutput(AlignedVector* vec, uint32_t elems) { void DrawQuads(int count, void* src) { if (!count) return; - AlignedVector* vec = _glActivePolyList(); + AlignedVector* vec = ActivePolyList(); - uint32_t header_required = (vec->size == 0) || STATE_DIRTY; + uint32_t header_required = (vec->size == 0) || stateDirty; // Reserve room for the vertices and header Vertex* beg = ReserveOutput(vec, vec->size + (header_required) + count); if (!beg) return; if (header_required) { apply_poly_header((pvr_poly_hdr_t*)beg, vec->list_type); - STATE_DIRTY = false; + stateDirty = false; beg++; vec->size += 1; } @@ -583,7 +611,7 @@ void Gfx_SetVertexFormat(VertexFormat fmt) { gfx_stride = strideSizes[fmt]; TEXTURES_ENABLED = fmt == VERTEX_FORMAT_TEXTURED; - STATE_DIRTY = true; + stateDirty = true; } void Gfx_DrawVb_Lines(int verticesCount) { @@ -666,9 +694,9 @@ void Gfx_EndFrame(void) { pvr_wait_ready(); pvr_scene_begin(); - SubmitList(&OP_LIST); - SubmitList(&PT_LIST); - SubmitList(&TR_LIST); + SubmitList(&listOP); + SubmitList(&listPT); + SubmitList(&listTR); pvr_scene_finish(); } @@ -676,12 +704,6 @@ void Gfx_OnWindowResize(void) { Gfx_SetViewport(0, 0, Game.Width, Game.Height); } -static void PushCommand(void* cmd) { - aligned_vector_push_back(&OP_LIST, cmd, 1); - aligned_vector_push_back(&PT_LIST, cmd, 1); - aligned_vector_push_back(&TR_LIST, cmd, 1); -} - void Gfx_SetViewport(int x, int y, int w, int h) { vp_scaleX = w * 0.5f; // hwidth vp_scaleY = h * -0.5f; // hheight @@ -691,7 +713,7 @@ void Gfx_SetViewport(int x, int y, int w, int h) { void Gfx_SetScissor(int x, int y, int w, int h) { SCISSOR_TEST_ENABLED = x != 0 || y != 0 || w != Game.Width || h != Game.Height; - STATE_DIRTY = true; + stateDirty = true; pvr_poly_hdr_t c; c.cmd = PVR_CMD_USERCLIP; @@ -701,6 +723,9 @@ void Gfx_SetScissor(int x, int y, int w, int h) { c.d2 = y >> 5; c.d3 = ((x + w) >> 5) - 1; c.d4 = ((y + h) >> 5) - 1; - PushCommand(&c); + + VertexList_Append(&listOP, &c); + VertexList_Append(&listPT, &c); + VertexList_Append(&listTR, &c); } #endif diff --git a/third_party/gldc/src/aligned_vector.h b/third_party/gldc/src/aligned_vector.h deleted file mode 100644 index 3a3710a88..000000000 --- a/third_party/gldc/src/aligned_vector.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#define AV_FORCE_INLINE static __attribute__((always_inline)) inline -#define AV_ELEMENT_SIZE 32 - -typedef struct { - uint32_t size; - uint32_t capacity; - uint32_t list_type; - uint32_t padding[5]; - uint8_t* data; -} __attribute__((aligned(32))) AlignedVector; - -#define ALIGNED_VECTOR_CHUNK_SIZE 256u - -#define av_assert(x) \ - do {\ - if(!(x)) {\ - fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\ - exit(1);\ - }\ - } while(0); \ - -#define ROUND_TO_CHUNK_SIZE(v) \ - ((((v) + ALIGNED_VECTOR_CHUNK_SIZE - 1) / ALIGNED_VECTOR_CHUNK_SIZE) * ALIGNED_VECTOR_CHUNK_SIZE) - -AV_FORCE_INLINE void* aligned_vector_reserve(AlignedVector* vector, uint32_t element_count) { - uint32_t original_byte_size = (vector->size * AV_ELEMENT_SIZE); - - if(element_count < vector->capacity) { - return vector->data + original_byte_size; - } - - /* We overallocate so that we don't make small allocations during push backs */ - element_count = ROUND_TO_CHUNK_SIZE(element_count); - - uint32_t new_byte_size = (element_count * AV_ELEMENT_SIZE); - uint8_t* original_data = vector->data; - - uint8_t* data = (uint8_t*) memalign(0x20, new_byte_size); - if (!data) return NULL; - - memcpy(data, original_data, original_byte_size); - free(original_data); - - vector->data = data; - vector->capacity = element_count; - return vector->data + original_byte_size; -} - -AV_FORCE_INLINE void* aligned_vector_push_back(AlignedVector* vector, const void* objs, uint32_t count) { - uint8_t* dest = (uint8_t*) aligned_vector_reserve(vector, vector->size + count); - assert(dest); - - /* Copy the objects in */ - memcpy(dest, objs, count * AV_ELEMENT_SIZE); - - vector->size += count; - return dest; -} - diff --git a/third_party/gldc/src/gldc.h b/third_party/gldc/src/gldc.h index da381f3a3..0dcbee0d4 100644 --- a/third_party/gldc/src/gldc.h +++ b/third_party/gldc/src/gldc.h @@ -2,7 +2,50 @@ #define PRIVATE_H #include -#include "aligned_vector.h" +#include +#include +#include +#include + +#define AV_FORCE_INLINE static __attribute__((always_inline)) inline +#define VERTEX_SIZE 32 + +typedef struct { + uint32_t size; + uint32_t capacity; + uint32_t list_type; + uint8_t* data; +} __attribute__((aligned(32))) AlignedVector; + +#define ALIGNED_VECTOR_CHUNK_SIZE 256u + +#define ROUND_TO_CHUNK_SIZE(v) \ + ((((v) + ALIGNED_VECTOR_CHUNK_SIZE - 1) / ALIGNED_VECTOR_CHUNK_SIZE) * ALIGNED_VECTOR_CHUNK_SIZE) + +AV_FORCE_INLINE void* aligned_vector_reserve(AlignedVector* vector, uint32_t element_count) { + uint32_t original_byte_size = (vector->size * VERTEX_SIZE); + + if(element_count < vector->capacity) { + return vector->data + original_byte_size; + } + + /* We overallocate so that we don't make small allocations during push backs */ + element_count = ROUND_TO_CHUNK_SIZE(element_count); + + uint32_t new_byte_size = (element_count * VERTEX_SIZE); + uint8_t* original_data = vector->data; + + uint8_t* data = (uint8_t*) memalign(0x20, new_byte_size); + if (!data) return NULL; + + memcpy(data, original_data, original_byte_size); + free(original_data); + + vector->data = data; + vector->capacity = element_count; + return data + original_byte_size; +} + #define MAX_TEXTURE_COUNT 768 @@ -10,10 +53,6 @@ #define GLenum unsigned int #define GLboolean unsigned char - -void glKosInit(); -void glKosSwapBuffers(); - typedef struct { /* Same 32 byte layout as pvr_vertex_t */ uint32_t flags; @@ -38,7 +77,7 @@ typedef struct { } TextureObject; -void _glInitTextures(); +void texmem_init(void); void* texmem_alloc(size_t size); void texmem_free(void* ptr); @@ -62,20 +101,6 @@ extern GLboolean SCISSOR_TEST_ENABLED; extern GLenum SHADE_MODEL; extern GLboolean AUTOSORT_ENABLED; - -extern AlignedVector OP_LIST; -extern AlignedVector PT_LIST; -extern AlignedVector TR_LIST; - -GL_FORCE_INLINE AlignedVector* _glActivePolyList() { - if (BLEND_ENABLED) return &TR_LIST; - if (ALPHA_TEST_ENABLED) return &PT_LIST; - - return &OP_LIST; -} - -extern GLboolean STATE_DIRTY; - void SceneListSubmit(Vertex* v2, int n); #endif // PRIVATE_H diff --git a/third_party/gldc/src/sh4.c b/third_party/gldc/src/sh4.c index 786d3e0cc..e2aeb4c66 100644 --- a/third_party/gldc/src/sh4.c +++ b/third_party/gldc/src/sh4.c @@ -373,6 +373,7 @@ static void SubmitClipped(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3, uint8_ extern void ProcessVertexList(Vertex* v3, int n, void* sq_addr); void SceneListSubmit(Vertex* v3, int n) { PVR_SET(SPAN_SORT_CFG, 0x0); + sq = (uint32_t*)MEM_AREA_SQ_BASE; uint8_t visible_mask = 0; diff --git a/third_party/gldc/src/state.c b/third_party/gldc/src/state.c index 9fc497f41..d587a0c91 100644 --- a/third_party/gldc/src/state.c +++ b/third_party/gldc/src/state.c @@ -1,12 +1,8 @@ -#include #include -#include #include #include #include "gldc.h" -GLboolean STATE_DIRTY; - GLboolean DEPTH_TEST_ENABLED; GLboolean DEPTH_MASK_ENABLED; @@ -23,22 +19,6 @@ GLboolean BLEND_ENABLED; GLboolean TEXTURES_ENABLED; GLboolean AUTOSORT_ENABLED; -AlignedVector OP_LIST; -AlignedVector PT_LIST; -AlignedVector TR_LIST; - -void glKosInit() { - _glInitTextures(); - - OP_LIST.list_type = PVR_LIST_OP_POLY; - PT_LIST.list_type = PVR_LIST_PT_POLY; - TR_LIST.list_type = PVR_LIST_TR_POLY; - - aligned_vector_reserve(&OP_LIST, 1024 * 3); - aligned_vector_reserve(&PT_LIST, 512 * 3); - aligned_vector_reserve(&TR_LIST, 1024 * 3); -} - static inline int DimensionFlag(int w) { switch(w) { case 16: return 1; @@ -82,7 +62,7 @@ void apply_poly_header(pvr_poly_hdr_t* dst, int list_type) { } int txr_enable, txr_alpha; - if (!TEXTURES_ENABLED || !tx1 || !tx1->data) { + if (!TEXTURES_ENABLED || !tx1) { /* Disable all texturing to start with */ txr_enable = PVR_TEXTURE_DISABLE; } else { diff --git a/third_party/gldc/src/texture.c b/third_party/gldc/src/texture.c index 35180a52e..c94b08fab 100644 --- a/third_party/gldc/src/texture.c +++ b/third_party/gldc/src/texture.c @@ -11,7 +11,7 @@ * issues with the allocator */ #define PVR_MEM_BUFFER_SIZE (64 * 1024) -TextureObject* TEXTURE_ACTIVE = NULL; +TextureObject* TEXTURE_ACTIVE; TextureObject TEXTURE_LIST[MAX_TEXTURE_COUNT]; static void* YALLOC_BASE; static size_t YALLOC_SIZE; @@ -20,7 +20,7 @@ static void glDefragmentTextureMemory_KOS(void) { yalloc_defrag_start(YALLOC_BASE); /* Replace all texture pointers */ - for(int i = 1; i < MAX_TEXTURE_COUNT; i++) + for(int i = 0; i < MAX_TEXTURE_COUNT; i++) { TextureObject* txr = &TEXTURE_LIST[i]; if (!txr->data) continue; @@ -31,9 +31,7 @@ static void glDefragmentTextureMemory_KOS(void) { yalloc_defrag_commit(YALLOC_BASE); } -void _glInitTextures() { - TEXTURE_ACTIVE = &TEXTURE_LIST[0]; - +void texmem_init() { size_t vram_free = pvr_mem_available(); YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */ YALLOC_BASE = pvr_mem_malloc(YALLOC_SIZE);