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"
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

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
#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
@ -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

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

View file

@ -1,12 +1,8 @@
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <kos.h>
#include <dc/pvr.h>
#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 {

View file

@ -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);