Dreamcast: Further simplifications

This commit is contained in:
UnknownShadow200 2024-10-04 18:09:34 +10:00
parent b1deff231e
commit 1c61512e64
6 changed files with 106 additions and 145 deletions

View file

@ -11,14 +11,38 @@
#include "../third_party/gldc/src/gldc.h" #include "../third_party/gldc/src/gldc.h"
static cc_bool renderingDisabled; static cc_bool renderingDisabled;
static cc_bool stateDirty;
#define VERTEX_BUFFER_SIZE 32 * 40000 #define VERTEX_BUFFER_SIZE 32 * 40000
#define PT_ALPHA_REF 0x011c #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---------------------------------------------------------* *---------------------------------------------------------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 autosort = false; // Turn off auto sorting to match traditional GPU behaviour
cc_bool fsaa = false; cc_bool fsaa = false;
AUTOSORT_ENABLED = autosort; AUTOSORT_ENABLED = autosort;
@ -46,12 +70,19 @@ static void InitGLState(void) {
TEXTURES_ENABLED = false; TEXTURES_ENABLED = false;
FOG_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) { void Gfx_Create(void) {
if (!Gfx.Created) InitPowerVR(); if (!Gfx.Created) InitGPU();
if (!Gfx.Created) glKosInit(); if (!Gfx.Created) texmem_init();
InitGLState(); InitGLState();
@ -81,12 +112,12 @@ static PackedCol gfx_clearColor;
void Gfx_SetFaceCulling(cc_bool enabled) { void Gfx_SetFaceCulling(cc_bool enabled) {
CULLING_ENABLED = enabled; CULLING_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
static void SetAlphaBlend(cc_bool enabled) { static void SetAlphaBlend(cc_bool enabled) {
BLEND_ENABLED = enabled; BLEND_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_SetAlphaArgBlend(cc_bool enabled) { } void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
@ -108,19 +139,19 @@ void Gfx_SetDepthWrite(cc_bool enabled) {
if (DEPTH_MASK_ENABLED == enabled) return; if (DEPTH_MASK_ENABLED == enabled) return;
DEPTH_MASK_ENABLED = enabled; DEPTH_MASK_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_SetDepthTest(cc_bool enabled) { void Gfx_SetDepthTest(cc_bool enabled) {
if (DEPTH_TEST_ENABLED == enabled) return; if (DEPTH_TEST_ENABLED == enabled) return;
DEPTH_TEST_ENABLED = enabled; DEPTH_TEST_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
static void SetAlphaTest(cc_bool enabled) { static void SetAlphaTest(cc_bool enabled) {
ALPHA_TEST_ENABLED = enabled; ALPHA_TEST_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_DepthOnlyRendering(cc_bool depthOnly) { 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) { static TextureObject* FindFreeTexture(void) {
// ID 0 is reserved for default texture for (int i = 0; i < MAX_TEXTURE_COUNT; i++)
for (int i = 1; i < MAX_TEXTURE_COUNT; i++)
{ {
TextureObject* tex = &TEXTURE_LIST[i]; TextureObject* tex = &TEXTURE_LIST[i];
if (tex->data == NULL) return tex; if (!tex->data) return tex;
} }
return NULL; return NULL;
} }
@ -380,10 +410,8 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
} }
void Gfx_BindTexture(GfxResourceID texId) { void Gfx_BindTexture(GfxResourceID texId) {
if (!texId) texId = &TEXTURE_LIST[0];
TEXTURE_ACTIVE = (TextureObject*)texId; TEXTURE_ACTIVE = (TextureObject*)texId;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_DeleteTexture(GfxResourceID* texId) { void Gfx_DeleteTexture(GfxResourceID* texId) {
@ -409,7 +437,7 @@ void Gfx_SetFog(cc_bool enabled) {
if (FOG_ENABLED == enabled) return; if (FOG_ENABLED == enabled) return;
FOG_ENABLED = enabled; FOG_ENABLED = enabled;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_SetFogCol(PackedCol color) { void Gfx_SetFogCol(PackedCol color) {
@ -554,16 +582,16 @@ static Vertex* ReserveOutput(AlignedVector* vec, uint32_t elems) {
void DrawQuads(int count, void* src) { void DrawQuads(int count, void* src) {
if (!count) return; 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 // Reserve room for the vertices and header
Vertex* beg = ReserveOutput(vec, vec->size + (header_required) + count); Vertex* beg = ReserveOutput(vec, vec->size + (header_required) + count);
if (!beg) return; if (!beg) return;
if (header_required) { if (header_required) {
apply_poly_header((pvr_poly_hdr_t*)beg, vec->list_type); apply_poly_header((pvr_poly_hdr_t*)beg, vec->list_type);
STATE_DIRTY = false; stateDirty = false;
beg++; beg++;
vec->size += 1; vec->size += 1;
} }
@ -583,7 +611,7 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
gfx_stride = strideSizes[fmt]; gfx_stride = strideSizes[fmt];
TEXTURES_ENABLED = fmt == VERTEX_FORMAT_TEXTURED; TEXTURES_ENABLED = fmt == VERTEX_FORMAT_TEXTURED;
STATE_DIRTY = true; stateDirty = true;
} }
void Gfx_DrawVb_Lines(int verticesCount) { void Gfx_DrawVb_Lines(int verticesCount) {
@ -666,9 +694,9 @@ void Gfx_EndFrame(void) {
pvr_wait_ready(); pvr_wait_ready();
pvr_scene_begin(); pvr_scene_begin();
SubmitList(&OP_LIST); SubmitList(&listOP);
SubmitList(&PT_LIST); SubmitList(&listPT);
SubmitList(&TR_LIST); SubmitList(&listTR);
pvr_scene_finish(); pvr_scene_finish();
} }
@ -676,12 +704,6 @@ void Gfx_OnWindowResize(void) {
Gfx_SetViewport(0, 0, Game.Width, Game.Height); 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) { void Gfx_SetViewport(int x, int y, int w, int h) {
vp_scaleX = w * 0.5f; // hwidth vp_scaleX = w * 0.5f; // hwidth
vp_scaleY = h * -0.5f; // hheight 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) { void Gfx_SetScissor(int x, int y, int w, int h) {
SCISSOR_TEST_ENABLED = x != 0 || y != 0 || w != Game.Width || h != Game.Height; SCISSOR_TEST_ENABLED = x != 0 || y != 0 || w != Game.Width || h != Game.Height;
STATE_DIRTY = true; stateDirty = true;
pvr_poly_hdr_t c; pvr_poly_hdr_t c;
c.cmd = PVR_CMD_USERCLIP; 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.d2 = y >> 5;
c.d3 = ((x + w) >> 5) - 1; c.d3 = ((x + w) >> 5) - 1;
c.d4 = ((y + h) >> 5) - 1; c.d4 = ((y + h) >> 5) - 1;
PushCommand(&c);
VertexList_Append(&listOP, &c);
VertexList_Append(&listPT, &c);
VertexList_Append(&listTR, &c);
} }
#endif #endif

View file

@ -1,68 +0,0 @@
#pragma once
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <malloc.h>
#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;
}

View file

@ -2,7 +2,50 @@
#define PRIVATE_H #define PRIVATE_H
#include <stdint.h> #include <stdint.h>
#include "aligned_vector.h" #include <assert.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>
#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 #define MAX_TEXTURE_COUNT 768
@ -10,10 +53,6 @@
#define GLenum unsigned int #define GLenum unsigned int
#define GLboolean unsigned char #define GLboolean unsigned char
void glKosInit();
void glKosSwapBuffers();
typedef struct { typedef struct {
/* Same 32 byte layout as pvr_vertex_t */ /* Same 32 byte layout as pvr_vertex_t */
uint32_t flags; uint32_t flags;
@ -38,7 +77,7 @@ typedef struct {
} TextureObject; } TextureObject;
void _glInitTextures(); void texmem_init(void);
void* texmem_alloc(size_t size); void* texmem_alloc(size_t size);
void texmem_free(void* ptr); void texmem_free(void* ptr);
@ -62,20 +101,6 @@ extern GLboolean SCISSOR_TEST_ENABLED;
extern GLenum SHADE_MODEL; extern GLenum SHADE_MODEL;
extern GLboolean AUTOSORT_ENABLED; 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); void SceneListSubmit(Vertex* v2, int n);
#endif // PRIVATE_H #endif // PRIVATE_H

View file

@ -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); extern void ProcessVertexList(Vertex* v3, int n, void* sq_addr);
void SceneListSubmit(Vertex* v3, int n) { void SceneListSubmit(Vertex* v3, int n) {
PVR_SET(SPAN_SORT_CFG, 0x0); PVR_SET(SPAN_SORT_CFG, 0x0);
sq = (uint32_t*)MEM_AREA_SQ_BASE; sq = (uint32_t*)MEM_AREA_SQ_BASE;
uint8_t visible_mask = 0; uint8_t visible_mask = 0;

View file

@ -1,12 +1,8 @@
#include <stdbool.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <kos.h> #include <kos.h>
#include <dc/pvr.h> #include <dc/pvr.h>
#include "gldc.h" #include "gldc.h"
GLboolean STATE_DIRTY;
GLboolean DEPTH_TEST_ENABLED; GLboolean DEPTH_TEST_ENABLED;
GLboolean DEPTH_MASK_ENABLED; GLboolean DEPTH_MASK_ENABLED;
@ -23,22 +19,6 @@ GLboolean BLEND_ENABLED;
GLboolean TEXTURES_ENABLED; GLboolean TEXTURES_ENABLED;
GLboolean AUTOSORT_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) { static inline int DimensionFlag(int w) {
switch(w) { switch(w) {
case 16: return 1; 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; int txr_enable, txr_alpha;
if (!TEXTURES_ENABLED || !tx1 || !tx1->data) { if (!TEXTURES_ENABLED || !tx1) {
/* Disable all texturing to start with */ /* Disable all texturing to start with */
txr_enable = PVR_TEXTURE_DISABLE; txr_enable = PVR_TEXTURE_DISABLE;
} else { } else {

View file

@ -11,7 +11,7 @@
* issues with the allocator */ * issues with the allocator */
#define PVR_MEM_BUFFER_SIZE (64 * 1024) #define PVR_MEM_BUFFER_SIZE (64 * 1024)
TextureObject* TEXTURE_ACTIVE = NULL; TextureObject* TEXTURE_ACTIVE;
TextureObject TEXTURE_LIST[MAX_TEXTURE_COUNT]; TextureObject TEXTURE_LIST[MAX_TEXTURE_COUNT];
static void* YALLOC_BASE; static void* YALLOC_BASE;
static size_t YALLOC_SIZE; static size_t YALLOC_SIZE;
@ -20,7 +20,7 @@ static void glDefragmentTextureMemory_KOS(void) {
yalloc_defrag_start(YALLOC_BASE); yalloc_defrag_start(YALLOC_BASE);
/* Replace all texture pointers */ /* 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]; TextureObject* txr = &TEXTURE_LIST[i];
if (!txr->data) continue; if (!txr->data) continue;
@ -31,9 +31,7 @@ static void glDefragmentTextureMemory_KOS(void) {
yalloc_defrag_commit(YALLOC_BASE); yalloc_defrag_commit(YALLOC_BASE);
} }
void _glInitTextures() { void texmem_init() {
TEXTURE_ACTIVE = &TEXTURE_LIST[0];
size_t vram_free = pvr_mem_available(); size_t vram_free = pvr_mem_available();
YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */ YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */
YALLOC_BASE = pvr_mem_malloc(YALLOC_SIZE); YALLOC_BASE = pvr_mem_malloc(YALLOC_SIZE);