mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
Dreamcast: Further simplifications
This commit is contained in:
parent
b1deff231e
commit
1c61512e64
6 changed files with 106 additions and 145 deletions
|
@ -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
|
||||
|
|
68
third_party/gldc/src/aligned_vector.h
vendored
68
third_party/gldc/src/aligned_vector.h
vendored
|
@ -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;
|
||||
}
|
||||
|
65
third_party/gldc/src/gldc.h
vendored
65
third_party/gldc/src/gldc.h
vendored
|
@ -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
|
||||
|
|
1
third_party/gldc/src/sh4.c
vendored
1
third_party/gldc/src/sh4.c
vendored
|
@ -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;
|
||||
|
||||
|
|
22
third_party/gldc/src/state.c
vendored
22
third_party/gldc/src/state.c
vendored
|
@ -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 {
|
||||
|
|
8
third_party/gldc/src/texture.c
vendored
8
third_party/gldc/src/texture.c
vendored
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue