Dreamcast: Simplify gldc code a bit, to hopefully alleviate the minor performance reduction from disabling LTO

This commit is contained in:
UnknownShadow200 2023-09-30 12:36:41 +10:00
parent b07f6575ba
commit 08e2238a49
12 changed files with 176 additions and 546 deletions

View File

@ -489,7 +489,7 @@ static void Gfx_RestoreState(void) {
gfx_format = -1;
glAlphaFunc(GL_GREATER, 0.5f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(PVR_BLEND_SRCALPHA, PVR_BLEND_INVSRCALPHA);
glDepthFunc(GL_LEQUAL);
}

View File

@ -3,7 +3,7 @@ SOURCE_DIRS := src src/yalloc
C_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
OBJS := $(notdir $(C_FILES:%.c=%.o))
C_FLAGS = -O3 -DNDEBUG -mfsrra -mfsca -ffp-contract=fast -ffast-math -O3 -mpretend-cmove -fexpensive-optimizations -fomit-frame-pointer -finline-functions -flto -fno-fat-lto-objects -ml -m4-single-only -ffunction-sections -fdata-sections -std=gnu99
C_FLAGS = -O3 -DNDEBUG -mfsrra -mfsca -ffp-contract=fast -ffast-math -O3 -mpretend-cmove -fexpensive-optimizations -fomit-frame-pointer -finline-functions -ml -m4-single-only -ffunction-sections -fdata-sections -std=gnu99
C_DEFINES = -DDREAMCAST -DNDEBUG -D__DREAMCAST__ -D__arch_dreamcast -D_arch_dreamcast -D_arch_sub_pristine

View File

@ -27,24 +27,6 @@ __BEGIN_DECLS
#define GL_TRIANGLE_STRIP 0x0005
#define GL_QUADS 0x0007
/* FrontFaceDirection */
#define GL_CW 0x0900
#define GL_CCW 0x0901
#define GL_NONE 0
#define GL_FRONT_LEFT 0x0400
#define GL_FRONT_RIGHT 0x0401
#define GL_BACK_LEFT 0x0402
#define GL_BACK_RIGHT 0x0403
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_LEFT 0x0406
#define GL_RIGHT 0x0407
#define GL_FRONT_AND_BACK 0x0408
#define GL_CULL_FACE 0x0B44
#define GL_CULL_FACE_MODE 0x0B45
#define GL_FRONT_FACE 0x0B46
/* Scissor box */
#define GL_SCISSOR_TEST 0x0008 /* capability bit */
#define GL_SCISSOR_BOX 0x0C10
@ -62,24 +44,9 @@ __BEGIN_DECLS
#define GL_DEPTH_BITS 0x0D56
#define GL_DEPTH_FUNC 0x0B74
#define GL_DEPTH_WRITEMASK 0x0B72
#define GL_DEPTH_COMPONENT 0x1902
/* Blending: Simply Need to Map GL constants to PVR constants */
#define GL_BLEND_DST 0x0BE0
#define GL_BLEND_SRC 0x0BE1
#define GL_BLEND 0x0BE2 /* capability bit */
#define GL_ZERO 0x0
#define GL_ONE 0x1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
/* Blending */
#define GL_BLEND 0x0BE2 /* capability bit */
/* Misc texture constants */
#define GL_TEXTURE_2D 0x0001 /* capability bit */
@ -134,21 +101,7 @@ __BEGIN_DECLS
#define GL_RGBA 0x1908
/* Polygons */
#define GL_POINT 0x1B00
#define GL_LINE 0x1B01
#define GL_FILL 0x1B02
#define GL_CW 0x0900
#define GL_CCW 0x0901
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_POLYGON_MODE 0x0B40
#define GL_POLYGON_SMOOTH 0x0B41
#define GL_POLYGON_STIPPLE 0x0B42
#define GL_EDGE_FLAG 0x0B43
#define GL_CULL_FACE 0x0B44
#define GL_CULL_FACE_MODE 0x0B45
#define GL_FRONT_FACE 0x0B46
#define GLbyte char
#define GLshort short
@ -207,10 +160,6 @@ GLAPI void glDepthFunc(GLenum func);
GLAPI void glDepthRange(GLclampf n, GLclampf f);
GLAPI void glDepthRangef(GLclampf n, GLclampf f);
/* Culling */
GLAPI void glFrontFace(GLenum mode);
GLAPI void glCullFace(GLenum mode);
/* Shading - Flat or Goraud */
GLAPI void glShadeModel(GLenum mode);

View File

@ -25,31 +25,3 @@ void aligned_vector_init(AlignedVector* vector, uint32_t element_size) {
assert(ptr);
(void) ptr;
}
void aligned_vector_shrink_to_fit(AlignedVector* vector) {
AlignedVectorHeader* const hdr = &vector->hdr;
if(hdr->size == 0) {
uint32_t element_size = hdr->element_size;
free(vector->data);
/* Reallocate the header */
vector->data = NULL;
hdr->size = hdr->capacity = 0;
hdr->element_size = element_size;
} else {
uint32_t new_byte_size = (hdr->size * hdr->element_size);
uint8_t* original_data = vector->data;
vector->data = (unsigned char*) memalign(0x20, new_byte_size);
if(original_data) {
FASTCPY(vector->data, original_data, new_byte_size);
free(original_data);
}
hdr->capacity = hdr->size;
}
}
void aligned_vector_cleanup(AlignedVector* vector) {
aligned_vector_clear(vector);
aligned_vector_shrink_to_fit(vector);
}

View File

@ -209,9 +209,6 @@ AV_FORCE_INLINE void aligned_vector_clear(AlignedVector* vector){
hdr->size = 0;
}
void aligned_vector_shrink_to_fit(AlignedVector* vector);
void aligned_vector_cleanup(AlignedVector* vector);
#ifdef __cplusplus
}
#endif

View File

@ -111,7 +111,7 @@ GL_FORCE_INLINE void divide(SubmissionTarget* target) {
/* Perform perspective divide on each vertex */
Vertex* vertex = _glSubmissionTargetStart(target);
const float h = GetVideoMode()->height;
const float h = vid_mode->height;
ITERATE(target->count) {
const float f = MATH_Fast_Invert(vertex->w);
@ -135,23 +135,19 @@ GL_FORCE_INLINE void divide(SubmissionTarget* target) {
}
GL_FORCE_INLINE int _calc_pvr_face_culling() {
if(!_glIsCullingEnabled()) {
if(!CULLING_ENABLED) {
return GPU_CULLING_SMALL;
} else {
if(_glGetCullFace() == GL_BACK) {
return (_glGetFrontFace() == GL_CW) ? GPU_CULLING_CCW : GPU_CULLING_CW;
} else {
return (_glGetFrontFace() == GL_CCW) ? GPU_CULLING_CCW : GPU_CULLING_CW;
}
return GPU_CULLING_CW;
}
}
GL_FORCE_INLINE int _calc_pvr_depth_test() {
if(!_glIsDepthTestEnabled()) {
if(!DEPTH_TEST_ENABLED) {
return GPU_DEPTHCMP_ALWAYS;
}
switch(_glGetDepthFunc()) {
switch(DEPTH_FUNC) {
case GL_NEVER:
return GPU_DEPTHCMP_NEVER;
case GL_LESS:
@ -173,40 +169,15 @@ GL_FORCE_INLINE int _calc_pvr_depth_test() {
}
}
GL_FORCE_INLINE int _calcPVRBlendFactor(GLenum factor) {
switch(factor) {
case GL_ZERO:
return GPU_BLEND_ZERO;
case GL_SRC_ALPHA:
return GPU_BLEND_SRCALPHA;
case GL_DST_COLOR:
return GPU_BLEND_DESTCOLOR;
case GL_DST_ALPHA:
return GPU_BLEND_DESTALPHA;
case GL_ONE_MINUS_DST_COLOR:
return GPU_BLEND_INVDESTCOLOR;
case GL_ONE_MINUS_SRC_ALPHA:
return GPU_BLEND_INVSRCALPHA;
case GL_ONE_MINUS_DST_ALPHA:
return GPU_BLEND_INVDESTALPHA;
case GL_ONE:
return GPU_BLEND_ONE;
default:
fprintf(stderr, "Invalid blend mode: %u\n", (unsigned int) factor);
return GPU_BLEND_ONE;
}
}
GL_FORCE_INLINE void _updatePVRBlend(PolyContext* context) {
if(_glIsBlendingEnabled() || _glIsAlphaTestEnabled()) {
if(BLEND_ENABLED || ALPHA_TEST_ENABLED) {
context->gen.alpha = GPU_ALPHA_ENABLE;
} else {
context->gen.alpha = GPU_ALPHA_DISABLE;
}
context->blend.src = _calcPVRBlendFactor(_glGetBlendSourceFactor());
context->blend.dst = _calcPVRBlendFactor(_glGetBlendDestFactor());
context->blend.src = BLEND_SRC_FACTOR;
context->blend.dst = BLEND_DST_FACTOR;
}
GL_FORCE_INLINE void apply_poly_header(PolyHeader* header, PolyList* activePolyList) {
@ -223,17 +194,17 @@ GL_FORCE_INLINE void apply_poly_header(PolyHeader* header, PolyList* activePolyL
ctx.gen.culling = _calc_pvr_face_culling();
ctx.depth.comparison = _calc_pvr_depth_test();
ctx.depth.write = _glIsDepthWriteEnabled() ? GPU_DEPTHWRITE_ENABLE : GPU_DEPTHWRITE_DISABLE;
ctx.depth.write = DEPTH_MASK_ENABLED ? GPU_DEPTHWRITE_ENABLE : GPU_DEPTHWRITE_DISABLE;
ctx.gen.shading = (_glGetShadeModel() == GL_SMOOTH) ? GPU_SHADE_GOURAUD : GPU_SHADE_FLAT;
ctx.gen.shading = (SHADE_MODEL == GL_SMOOTH) ? GPU_SHADE_GOURAUD : GPU_SHADE_FLAT;
if(_glIsScissorTestEnabled()) {
if(SCISSOR_TEST_ENABLED) {
ctx.gen.clip_mode = GPU_USERCLIP_INSIDE;
} else {
ctx.gen.clip_mode = GPU_USERCLIP_DISABLE;
}
if(_glIsFogEnabled()) {
if(FOG_ENABLED) {
ctx.gen.fog_type = GPU_FOG_TABLE;
} else {
ctx.gen.fog_type = GPU_FOG_DISABLE;
@ -243,12 +214,12 @@ GL_FORCE_INLINE void apply_poly_header(PolyHeader* header, PolyList* activePolyL
if(ctx.list_type == GPU_LIST_OP_POLY) {
/* Opaque polys are always one/zero */
ctx.blend.src = GPU_BLEND_ONE;
ctx.blend.dst = GPU_BLEND_ZERO;
ctx.blend.src = PVR_BLEND_ONE;
ctx.blend.dst = PVR_BLEND_ZERO;
} else if(ctx.list_type == GPU_LIST_PT_POLY) {
/* Punch-through polys require fixed blending and depth modes */
ctx.blend.src = GPU_BLEND_SRCALPHA;
ctx.blend.dst = GPU_BLEND_INVSRCALPHA;
ctx.blend.src = PVR_BLEND_SRCALPHA;
ctx.blend.dst = PVR_BLEND_INVSRCALPHA;
ctx.depth.comparison = GPU_DEPTHCMP_LEQUAL;
} else if(ctx.list_type == GPU_LIST_TR_POLY && AUTOSORT_ENABLED) {
/* Autosort mode requires this mode for transparent polys */
@ -305,7 +276,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count) {
uint32_t vector_size = aligned_vector_size(&target->output->vector);
GLboolean header_required = (vector_size == 0) || _glGPUStateIsDirty();
GLboolean header_required = (vector_size == 0) || STATE_DIRTY;
target->count = count * 6 / 4; // quads -> triangles
target->header_offset = vector_size;
@ -320,7 +291,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count) {
if(header_required) {
apply_poly_header(_glSubmissionTargetHeader(target), target->output);
_glGPUStateMarkClean();
STATE_DIRTY = GL_FALSE;
}
generateQuads(target, first, count);

View File

@ -16,18 +16,6 @@ PolyList TR_LIST;
GLboolean AUTOSORT_ENABLED = GL_FALSE;
PolyList* _glOpaquePolyList() {
return &OP_LIST;
}
PolyList* _glPunchThruPolyList() {
return &PT_LIST;
}
PolyList *_glTransparentPolyList() {
return &TR_LIST;
}
void APIENTRY glKosInitConfig(GLdcConfig* config) {
config->autosort_enabled = GL_FALSE;
@ -41,8 +29,6 @@ void APIENTRY glKosInitConfig(GLdcConfig* config) {
void APIENTRY glKosInitEx(GLdcConfig* config) {
TRACE();
puts("\nWelcome to GLdc!\n");
InitGPU(config->autosort_enabled, config->fsaa_enabled);
AUTOSORT_ENABLED = config->autosort_enabled;
@ -74,26 +60,27 @@ void APIENTRY glKosInit() {
void APIENTRY glKosSwapBuffers() {
TRACE();
pvr_wait_ready();
SceneBegin();
pvr_scene_begin();
if(aligned_vector_header(&OP_LIST.vector)->size > 2) {
SceneListBegin(GPU_LIST_OP_POLY);
pvr_list_begin(GPU_LIST_OP_POLY);
SceneListSubmit((Vertex*) aligned_vector_front(&OP_LIST.vector), aligned_vector_size(&OP_LIST.vector));
SceneListFinish();
pvr_list_finish();
}
if(aligned_vector_header(&PT_LIST.vector)->size > 2) {
SceneListBegin(GPU_LIST_PT_POLY);
pvr_list_begin(GPU_LIST_PT_POLY);
SceneListSubmit((Vertex*) aligned_vector_front(&PT_LIST.vector), aligned_vector_size(&PT_LIST.vector));
SceneListFinish();
pvr_list_finish();
}
if(aligned_vector_header(&TR_LIST.vector)->size > 2) {
SceneListBegin(GPU_LIST_TR_POLY);
pvr_list_begin(GPU_LIST_TR_POLY);
SceneListSubmit((Vertex*) aligned_vector_front(&TR_LIST.vector), aligned_vector_size(&TR_LIST.vector));
SceneListFinish();
pvr_list_finish();
}
SceneFinish();
pvr_scene_finish();
aligned_vector_clear(&OP_LIST.vector);
aligned_vector_clear(&PT_LIST.vector);

View File

@ -32,17 +32,6 @@ typedef enum GPUList {
GPU_LIST_PT_POLY = 4
} GPUList;
typedef enum GPUBlend {
GPU_BLEND_ZERO = 0,
GPU_BLEND_ONE = 1,
GPU_BLEND_DESTCOLOR = 2,
GPU_BLEND_INVDESTCOLOR = 3,
GPU_BLEND_SRCALPHA = 4,
GPU_BLEND_INVSRCALPHA = 5,
GPU_BLEND_DESTALPHA = 6,
GPU_BLEND_INVDESTALPHA = 7
} GPUBlend;
typedef enum GPUDepthCompare {
GPU_DEPTHCMP_NEVER = 0,
GPU_DEPTHCMP_LESS = 1,
@ -146,13 +135,6 @@ typedef enum GPUTextureEnv {
GPU_TXRENV_MODULATEALPHA = 3
} GPUTextureEnv;
typedef struct VideoMode {
uint16_t width;
uint16_t height;
} VideoMode;
const VideoMode* GetVideoMode();
/* Duplication of pvr_poly_cxt_t from KOS so that we can
* compile on non-KOS platforms for testing */
@ -241,15 +223,7 @@ enum GPUCommand {
GPU_CMD_SPRITE = 0xA0000000
};
typedef float Matrix4x4[16];
void SceneBegin();
void SceneListBegin(GPUList list);
void SceneListSubmit(Vertex* v2, int n);
void SceneListFinish();
void SceneFinish();
#define GPU_TA_CMD_TYPE_SHIFT 24
#define GPU_TA_CMD_TYPE_MASK (7 << GPU_TA_CMD_TYPE_SHIFT)

View File

@ -24,15 +24,6 @@ extern void* memcpy4 (void *dest, const void *src, size_t count);
#define GL_FORCE_INLINE static GL_INLINE_DEBUG
#define _GL_UNUSED(x) (void)(x)
#define _PACK4(v) ((v * 0xF) / 0xFF)
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
#define PACK_ARGB1555(a,r,g,b) \
(((GLushort)(a > 0) << 15) | (((GLushort) r >> 3) << 10) | (((GLushort)g >> 3) << 5) | ((GLushort)b >> 3))
#define PACK_RGB565(r,g,b) \
((((GLushort)r & 0xf8) << 8) | (((GLushort) g & 0xfc) << 3) | ((GLushort) b >> 3))
#define TRACE_ENABLED 0
#define TRACE() if(TRACE_ENABLED) {fprintf(stderr, "%s\n", __func__);} (void) 0
@ -90,35 +81,6 @@ typedef struct {
} __attribute__((aligned(32))) TextureObject;
#define argbcpy(dst, src) \
*((GLuint*) dst) = *((const GLuint*) src) \
typedef struct {
float xy[2];
} _glvec2;
typedef struct {
float xyz[3];
} _glvec3;
typedef struct {
float xyzw[4];
} _glvec4;
#define vec2cpy(dst, src) \
*((_glvec2*) dst) = *((_glvec2*) src)
#define vec3cpy(dst, src) \
*((_glvec3*) dst) = *((_glvec3*) src)
#define vec4cpy(dst, src) \
*((_glvec4*) dst) = *((_glvec4*) src)
GL_FORCE_INLINE float clamp(float d, float min, float max) {
return (d < min) ? min : (d > max) ? max : d;
}
GL_FORCE_INLINE void memcpy_vertex(Vertex *dest, const Vertex *src) {
#ifdef __DREAMCAST__
_Complex float double_scratch;
@ -179,56 +141,46 @@ typedef enum {
} ClipResult;
#define A8IDX 3
#define R8IDX 2
#define G8IDX 1
#define B8IDX 0
struct SubmissionTarget;
PolyList* _glOpaquePolyList();
PolyList* _glPunchThruPolyList();
PolyList *_glTransparentPolyList();
void _glInitAttributePointers();
void _glInitContext();
void _glInitMatrices();
void _glInitSubmissionTarget();
void _glMatrixLoadModelViewProjection();
GLubyte _glInitTextures();
void _glUpdatePVRTextureContext(PolyContext* context, GLshort textureUnit);
GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func);
GLenum _glGetShadeModel();
extern TextureObject* TEXTURE_ACTIVE;
extern GLboolean TEXTURES_ENABLED;
GLboolean _glIsBlendingEnabled();
GLboolean _glIsAlphaTestEnabled();
GLboolean _glIsCullingEnabled();
GLboolean _glIsDepthTestEnabled();
GLboolean _glIsDepthWriteEnabled();
GLboolean _glIsScissorTestEnabled();
GLboolean _glIsFogEnabled();
GLenum _glGetDepthFunc();
GLenum _glGetCullFace();
GLenum _glGetFrontFace();
GLenum _glGetBlendSourceFactor();
GLenum _glGetBlendDestFactor();
extern GLenum DEPTH_FUNC;
extern GLboolean DEPTH_TEST_ENABLED;
extern GLboolean DEPTH_MASK_ENABLED;
extern GLboolean CULLING_ENABLED;
extern GLboolean FOG_ENABLED;
extern GLboolean ALPHA_TEST_ENABLED;
extern GLboolean SCISSOR_TEST_ENABLED;
extern GLenum SHADE_MODEL;
extern GLboolean BLEND_ENABLED;
extern GLenum BLEND_SRC_FACTOR;
extern GLenum BLEND_DST_FACTOR;
extern PolyList OP_LIST;
extern PolyList PT_LIST;
extern PolyList TR_LIST;
GL_FORCE_INLINE PolyList* _glActivePolyList() {
if(_glIsBlendingEnabled()) {
if(BLEND_ENABLED) {
return &TR_LIST;
} else if(_glIsAlphaTestEnabled()) {
} else if(ALPHA_TEST_ENABLED) {
return &PT_LIST;
} else {
return &OP_LIST;
@ -257,10 +209,6 @@ GL_FORCE_INLINE void _glKosThrowError(GLenum error, const char *function) {
}
}
GL_FORCE_INLINE GLubyte _glKosHasError() {
return (LAST_ERROR != GL_NO_ERROR) ? GL_TRUE : GL_FALSE;
}
GL_FORCE_INLINE void _glKosResetError() {
LAST_ERROR = GL_NO_ERROR;
sprintf(ERROR_FUNCTION, "\n");
@ -275,13 +223,8 @@ GLuint _glFreeContiguousTextureMemory();
void _glApplyScissor(bool force);
GLboolean _glNearZClippingEnabled();
GLboolean _glGPUStateIsDirty();
void _glGPUStateMarkClean();
void _glGPUStateMarkDirty();
#define MAX_GLDC_TEXTURE_UNITS 2
extern GLboolean ZNEAR_CLIPPING_ENABLED;
extern GLboolean STATE_DIRTY;
/* This is from KOS pvr_buffers.c */

View File

@ -11,15 +11,6 @@
#define SQ_BASE_ADDRESS (void*) 0xe0000000
GL_FORCE_INLINE bool glIsVertex(const float flags) {
return flags == GPU_CMD_VERTEX_EOL || flags == GPU_CMD_VERTEX;
}
GL_FORCE_INLINE bool glIsLastVertex(const float flags) {
return flags == GPU_CMD_VERTEX_EOL;
}
void InitGPU(_Bool autosort, _Bool fsaa) {
pvr_init_params_t params = {
/* Enable opaque and translucent polygons with size 32 and 32 */
@ -45,15 +36,6 @@ void InitGPU(_Bool autosort, _Bool fsaa) {
}
}
void SceneBegin() {
pvr_wait_ready();
pvr_scene_begin();
}
void SceneListBegin(GPUList list) {
pvr_list_begin(list);
}
GL_FORCE_INLINE float _glFastInvert(float x) {
return (1.f / __builtin_sqrtf(x * x));
}
@ -144,7 +126,7 @@ void SceneListSubmit(Vertex* v2, int n) {
return;
}
const float h = GetVideoMode()->height;
const float h = vid_mode->height;
PVR_SET(SPAN_SORT_CFG, 0x0);
@ -453,18 +435,3 @@ void SceneListSubmit(Vertex* v2, int n) {
_glFlushBuffer();
}
void SceneListFinish() {
pvr_list_finish();
}
void SceneFinish() {
pvr_scene_finish();
}
const VideoMode* GetVideoMode() {
static VideoMode mode;
mode.width = vid_mode->width;
mode.height = vid_mode->height;
return &mode;
}

View File

@ -4,147 +4,37 @@
#include "private.h"
GLboolean STATE_DIRTY = GL_TRUE;
static struct {
GLboolean is_dirty;
GLenum DEPTH_FUNC = GL_LESS;
GLboolean DEPTH_TEST_ENABLED = GL_FALSE;
GLboolean DEPTH_MASK_ENABLED = GL_FALSE;
/* We can't just use the GL_CONTEXT for this state as the two
* GL states are combined, so we store them separately and then
* calculate the appropriate PVR state from them. */
GLenum depth_func;
GLboolean depth_test_enabled;
GLenum cull_face;
GLenum front_face;
GLboolean culling_enabled;
GLboolean znear_clipping_enabled;
GLboolean alpha_test_enabled;
GLboolean scissor_test_enabled;
GLboolean fog_enabled;
GLboolean depth_mask_enabled;
GLboolean CULLING_ENABLED = GL_FALSE;
struct {
GLint x;
GLint y;
GLsizei width;
GLsizei height;
GLboolean applied;
} scissor_rect;
GLboolean FOG_ENABLED = GL_FALSE;
GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
GLenum blend_sfactor;
GLenum blend_dfactor;
GLboolean blend_enabled;
GLboolean SCISSOR_TEST_ENABLED = GL_FALSE;
GLenum SHADE_MODEL = GL_SMOOTH;
GLboolean ZNEAR_CLIPPING_ENABLED = GL_TRUE;
GLenum shade_model;
} GPUState = {
.is_dirty = GL_TRUE,
.depth_func = GL_LESS,
.depth_test_enabled = GL_FALSE,
.cull_face = GL_BACK,
.front_face = GL_CCW,
.culling_enabled = GL_FALSE,
.znear_clipping_enabled = GL_TRUE,
.alpha_test_enabled = GL_FALSE,
.scissor_test_enabled = GL_FALSE,
.fog_enabled = GL_FALSE,
.depth_mask_enabled = GL_FALSE,
.scissor_rect = {0, 0, 640, 480, false},
.blend_sfactor = GL_ONE,
.blend_dfactor = GL_ZERO,
.blend_enabled = GL_FALSE,
.shade_model = GL_SMOOTH
};
void _glGPUStateMarkClean() {
GPUState.is_dirty = GL_FALSE;
}
void _glGPUStateMarkDirty() {
GPUState.is_dirty = GL_TRUE;
}
GLboolean _glGPUStateIsDirty() {
return GPUState.is_dirty;
}
GLboolean _glIsDepthTestEnabled() {
return GPUState.depth_test_enabled;
}
GLenum _glGetDepthFunc() {
return GPUState.depth_func;
}
GLboolean _glIsDepthWriteEnabled() {
return GPUState.depth_mask_enabled;
}
GLenum _glGetShadeModel() {
return GPUState.shade_model;
}
GLboolean _glIsBlendingEnabled() {
return GPUState.blend_enabled;
}
GLboolean _glIsAlphaTestEnabled() {
return GPUState.alpha_test_enabled;
}
GLboolean _glIsCullingEnabled() {
return GPUState.culling_enabled;
}
GLenum _glGetCullFace() {
return GPUState.cull_face;
}
GLenum _glGetFrontFace() {
return GPUState.front_face;
}
GLboolean _glIsFogEnabled() {
return GPUState.fog_enabled;
}
GLboolean _glIsScissorTestEnabled() {
return GPUState.scissor_test_enabled;
}
GLboolean _glNearZClippingEnabled() {
return GPUState.znear_clipping_enabled;
}
void _glApplyScissor(bool force);
GLenum _glGetBlendSourceFactor() {
return GPUState.blend_sfactor;
}
GLenum _glGetBlendDestFactor() {
return GPUState.blend_dfactor;
}
GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) {
GLubyte found = 0;
while(*values != 0) {
if(*values == param) {
found++;
break;
}
values++;
}
if(!found) {
_glKosThrowError(GL_INVALID_ENUM, func);
return GL_TRUE;
}
return GL_FALSE;
}
GLboolean BLEND_ENABLED = GL_FALSE;
GLenum BLEND_SRC_FACTOR = PVR_BLEND_ZERO;
GLenum BLEND_DST_FACTOR = PVR_BLEND_ONE;
GLboolean TEXTURES_ENABLED = GL_FALSE;
static struct {
GLint x;
GLint y;
GLsizei width;
GLsizei height;
GLboolean applied;
} scissor_rect = {0, 0, 640, 480, false};
void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
const TextureObject *tx1 = TEXTURE_ACTIVE;
@ -158,7 +48,7 @@ void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
return;
}
context->txr.alpha = (GPUState.blend_enabled || GPUState.alpha_test_enabled) ? GPU_TXRALPHA_ENABLE : GPU_TXRALPHA_DISABLE;
context->txr.alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? GPU_TXRALPHA_ENABLE : GPU_TXRALPHA_DISABLE;
GLuint filter = GPU_FILTER_NEAREST;
@ -183,18 +73,14 @@ void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
}
void _glInitContext() {
const VideoMode* mode = GetVideoMode();
GPUState.scissor_rect.x = 0;
GPUState.scissor_rect.y = 0;
GPUState.scissor_rect.width = mode->width;
GPUState.scissor_rect.height = mode->height;
scissor_rect.x = 0;
scissor_rect.y = 0;
scissor_rect.width = vid_mode->width;
scissor_rect.height = vid_mode->height;
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glDisable(GL_ALPHA_TEST);
@ -210,51 +96,44 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
case GL_TEXTURE_2D:
if(TEXTURES_ENABLED != GL_TRUE) {
TEXTURES_ENABLED = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
break;
case GL_CULL_FACE: {
if(GPUState.culling_enabled != GL_TRUE) {
GPUState.culling_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
CULLING_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
} break;
case GL_DEPTH_TEST: {
if(GPUState.depth_test_enabled != GL_TRUE) {
GPUState.depth_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
if(DEPTH_TEST_ENABLED != GL_TRUE) {
DEPTH_TEST_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_BLEND: {
if(GPUState.blend_enabled != GL_TRUE) {
GPUState.blend_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
if(BLEND_ENABLED != GL_TRUE) {
BLEND_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_SCISSOR_TEST: {
if(GPUState.scissor_test_enabled != GL_TRUE) {
GPUState.scissor_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
SCISSOR_TEST_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
} break;
case GL_FOG:
if(GPUState.fog_enabled != GL_TRUE) {
GPUState.fog_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
if(FOG_ENABLED != GL_TRUE) {
FOG_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
break;
case GL_ALPHA_TEST: {
if(GPUState.alpha_test_enabled != GL_TRUE) {
GPUState.alpha_test_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
if(ALPHA_TEST_ENABLED != GL_TRUE) {
ALPHA_TEST_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_NEARZ_CLIPPING_KOS:
if(GPUState.znear_clipping_enabled != GL_TRUE) {
GPUState.znear_clipping_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
ZNEAR_CLIPPING_ENABLED = GL_TRUE;
STATE_DIRTY = GL_TRUE;
break;
default:
break;
@ -266,51 +145,44 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
case GL_TEXTURE_2D:
if(TEXTURES_ENABLED != GL_FALSE) {
TEXTURES_ENABLED = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
STATE_DIRTY = GL_TRUE;
}
break;
case GL_CULL_FACE: {
if(GPUState.culling_enabled != GL_FALSE) {
GPUState.culling_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
CULLING_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
} break;
case GL_DEPTH_TEST: {
if(GPUState.depth_test_enabled != GL_FALSE) {
GPUState.depth_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
if(DEPTH_TEST_ENABLED != GL_FALSE) {
DEPTH_TEST_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_BLEND: {
if(GPUState.blend_enabled != GL_FALSE) {
GPUState.blend_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
if(BLEND_ENABLED != GL_FALSE) {
BLEND_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_SCISSOR_TEST: {
if(GPUState.scissor_test_enabled != GL_FALSE) {
GPUState.scissor_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
SCISSOR_TEST_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
} break;
case GL_FOG:
if(GPUState.fog_enabled != GL_FALSE) {
GPUState.fog_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
if(FOG_ENABLED != GL_FALSE) {
FOG_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
}
break;
case GL_ALPHA_TEST: {
if(GPUState.alpha_test_enabled != GL_FALSE) {
GPUState.alpha_test_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
if(ALPHA_TEST_ENABLED != GL_FALSE) {
ALPHA_TEST_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
}
} break;
case GL_NEARZ_CLIPPING_KOS:
if(GPUState.znear_clipping_enabled != GL_FALSE) {
GPUState.znear_clipping_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
ZNEAR_CLIPPING_ENABLED = GL_FALSE;
STATE_DIRTY = GL_TRUE;
break;
default:
break;
@ -328,49 +200,28 @@ GLAPI void APIENTRY glClearDepth(GLfloat depth) {
}
GLAPI void APIENTRY glDepthMask(GLboolean flag) {
if(GPUState.depth_mask_enabled != flag) {
GPUState.depth_mask_enabled = flag;
GPUState.is_dirty = GL_TRUE;
if(DEPTH_MASK_ENABLED != flag) {
DEPTH_MASK_ENABLED = flag;
STATE_DIRTY = GL_TRUE;
}
}
GLAPI void APIENTRY glDepthFunc(GLenum func) {
if(GPUState.depth_func != func) {
GPUState.depth_func = func;
GPUState.is_dirty = GL_TRUE;
}
}
/* Culling */
GLAPI void APIENTRY glFrontFace(GLenum mode) {
if(GPUState.front_face != mode) {
GPUState.front_face = mode;
GPUState.is_dirty = GL_TRUE;
}
}
GLAPI void APIENTRY glCullFace(GLenum mode) {
if(GPUState.cull_face != mode) {
GPUState.cull_face = mode;
GPUState.is_dirty = GL_TRUE;
}
DEPTH_FUNC = func;
STATE_DIRTY = GL_TRUE;
}
/* Shading - Flat or Goraud */
GLAPI void APIENTRY glShadeModel(GLenum mode) {
if(GPUState.shade_model != mode) {
GPUState.shade_model = mode;
GPUState.is_dirty = GL_TRUE;
}
SHADE_MODEL = mode;
STATE_DIRTY = GL_TRUE;
}
/* Blending */
GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
if(GPUState.blend_dfactor != dfactor || GPUState.blend_sfactor != sfactor) {
GPUState.blend_sfactor = sfactor;
GPUState.blend_dfactor = dfactor;
GPUState.is_dirty = GL_TRUE;
}
BLEND_SRC_FACTOR = sfactor;
BLEND_DST_FACTOR = dfactor;
STATE_DIRTY = GL_TRUE;
}
@ -381,19 +232,19 @@ GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
if(GPUState.scissor_rect.x == x &&
GPUState.scissor_rect.y == y &&
GPUState.scissor_rect.width == width &&
GPUState.scissor_rect.height == height) {
if(scissor_rect.x == x &&
scissor_rect.y == y &&
scissor_rect.width == width &&
scissor_rect.height == height) {
return;
}
GPUState.scissor_rect.x = x;
GPUState.scissor_rect.y = y;
GPUState.scissor_rect.width = width;
GPUState.scissor_rect.height = height;
GPUState.scissor_rect.applied = false;
GPUState.is_dirty = GL_TRUE; // FIXME: do we need this?
scissor_rect.x = x;
scissor_rect.y = y;
scissor_rect.width = width;
scissor_rect.height = height;
scissor_rect.applied = false;
STATE_DIRTY = GL_TRUE; // FIXME: do we need this?
_glApplyScissor(false);
}
@ -423,12 +274,12 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
*/
void _glApplyScissor(bool force) {
/* Don't do anyting if clipping is disabled */
if(!GPUState.scissor_test_enabled) {
if(!SCISSOR_TEST_ENABLED) {
return;
}
/* Don't apply if we already applied - nothing changed */
if(GPUState.scissor_rect.applied && !force) {
if(scissor_rect.applied && !force) {
return;
}
@ -436,14 +287,12 @@ void _glApplyScissor(bool force) {
GLint miny, maxx, maxy;
const VideoMode* vid_mode = GetVideoMode();
GLsizei scissor_width = MAX(MIN(GPUState.scissor_rect.width, vid_mode->width), 0);
GLsizei scissor_height = MAX(MIN(GPUState.scissor_rect.height, vid_mode->height), 0);
GLsizei scissor_width = MAX(MIN(scissor_rect.width, vid_mode->width), 0);
GLsizei scissor_height = MAX(MIN(scissor_rect.height, vid_mode->height), 0);
/* force the origin to the lower left-hand corner of the screen */
miny = (vid_mode->height - scissor_height) - GPUState.scissor_rect.y;
maxx = (scissor_width + GPUState.scissor_rect.x);
miny = (vid_mode->height - scissor_height) - scissor_rect.y;
maxx = (scissor_width + scissor_rect.x);
maxy = (scissor_height + miny);
/* load command structure while mapping screen coords to TA tiles */
@ -453,16 +302,16 @@ void _glApplyScissor(bool force) {
uint16_t vw = vid_mode->width >> 5;
uint16_t vh = vid_mode->height >> 5;
c.sx = CLAMP(GPUState.scissor_rect.x >> 5, 0, vw);
c.sx = CLAMP(scissor_rect.x >> 5, 0, vw);
c.sy = CLAMP(miny >> 5, 0, vh);
c.ex = CLAMP((maxx >> 5) - 1, 0, vw);
c.ey = CLAMP((maxy >> 5) - 1, 0, vh);
aligned_vector_push_back(&_glOpaquePolyList()->vector, &c, 1);
aligned_vector_push_back(&_glPunchThruPolyList()->vector, &c, 1);
aligned_vector_push_back(&_glTransparentPolyList()->vector, &c, 1);
aligned_vector_push_back(&OP_LIST.vector, &c, 1);
aligned_vector_push_back(&PT_LIST.vector, &c, 1);
aligned_vector_push_back(&TR_LIST.vector, &c, 1);
GPUState.scissor_rect.applied = true;
scissor_rect.applied = true;
}
void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
@ -494,3 +343,24 @@ const GLubyte *glGetString(GLenum name) {
return (const GLubyte*) "GL_KOS_ERROR: ENUM Unsupported\n";
}
Viewport VIEWPORT = {
0, 0, 640, 480, 320.0f, 240.0f, 320.0f, 240.0f
};
void _glInitMatrices() {
glViewport(0, 0, vid_mode->width, vid_mode->height);
}
/* Set the GL viewport */
void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
VIEWPORT.x = x;
VIEWPORT.y = y;
VIEWPORT.width = width;
VIEWPORT.height = height;
VIEWPORT.hwidth = ((GLfloat) VIEWPORT.width) * 0.5f;
VIEWPORT.hheight = ((GLfloat) VIEWPORT.height) * 0.5f;
VIEWPORT.x_plus_hwidth = VIEWPORT.x + VIEWPORT.hwidth;
VIEWPORT.y_plus_hheight = VIEWPORT.y + VIEWPORT.hheight;
}

View File

@ -132,7 +132,7 @@ void APIENTRY gldcBindTexture(GLuint id) {
gl_assert(TEXTURE_OBJECTS.element_size > 0);
_glGPUStateMarkDirty();
STATE_DIRTY = GL_TRUE;
}
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
@ -235,7 +235,7 @@ void APIENTRY gldcAllocTexture(GLsizei w, GLsizei h, GLenum format, GLenum type)
* code less flexible to change in the future */
active->color &= ~(1 << 26);
_glGPUStateMarkDirty();
STATE_DIRTY = GL_TRUE;
}
GLAPI void APIENTRY gldcGetTexture(GLvoid** data, GLsizei* width, GLsizei* height) {