Merge branch 'kazade_patch_prepare' into 'master'

Kazade patch prepare

See merge request 
This commit is contained in:
Luke Benstead 2020-03-05 20:30:41 +00:00
commit 2f75ff8223
21 changed files with 573 additions and 312 deletions

View File

@ -32,39 +32,35 @@ void _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout, float*
float vec [] = {v2->xyz[0] - v1->xyz[0], v2->xyz[1] - v1->xyz[1], v2->xyz[2] - v1->xyz[2]}; float vec [] = {v2->xyz[0] - v1->xyz[0], v2->xyz[1] - v1->xyz[1], v2->xyz[2] - v1->xyz[2]};
vout->xyz[0] = v1->xyz[0] + (vec[0] * (*t)); vout->xyz[0] = MATH_fmac(vec[0], (*t), v1->xyz[0]);
vout->xyz[1] = v1->xyz[1] + (vec[1] * (*t)); vout->xyz[1] = MATH_fmac(vec[1], (*t), v1->xyz[1]);
vout->xyz[2] = v1->xyz[2] + (vec[2] * (*t)); vout->xyz[2] = MATH_fmac(vec[2], (*t), v1->xyz[2]);
} }
static inline void interpolateFloat(const float v1, const float v2, const float t, float* out) { GL_FORCE_INLINE void interpolateFloat(const float v1, const float v2, const float t, float* out) {
float v = v2 - v1; *out = MATH_fmac(v2 - v1,t, v1);
*out = (v * t) + v1;
} }
static inline void interpolateVec2(const float* v1, const float* v2, const float t, float* out) { GL_FORCE_INLINE void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
interpolateFloat(v1[0], v2[0], t, &out[0]); interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]); interpolateFloat(v1[1], v2[1], t, &out[1]);
} }
static inline void interpolateVec3(const float* v1, const float* v2, const float t, float* out) { GL_FORCE_INLINE void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
interpolateFloat(v1[0], v2[0], t, &out[0]); interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]); interpolateFloat(v1[1], v2[1], t, &out[1]);
interpolateFloat(v1[2], v2[2], t, &out[2]); interpolateFloat(v1[2], v2[2], t, &out[2]);
} }
static inline void interpolateVec4(const float* v1, const float* v2, const float t, float* out) { GL_FORCE_INLINE void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
interpolateFloat(v1[0], v2[0], t, &out[0]); interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]); interpolateFloat(v1[1], v2[1], t, &out[1]);
interpolateFloat(v1[2], v2[2], t, &out[2]); interpolateFloat(v1[2], v2[2], t, &out[2]);
interpolateFloat(v1[3], v2[3], t, &out[3]); interpolateFloat(v1[3], v2[3], t, &out[3]);
} }
static inline void interpolateColour(const uint8_t* v1, const uint8_t* v2, const float t, uint8_t* out) { GL_FORCE_INLINE void interpolateColour(const uint8_t* v1, const uint8_t* v2, const float t, uint8_t* out) {
out[0] = v1[0] + (uint32_t) (((float) (v2[0] - v1[0])) * t); out[0] = v1[0] + (uint32_t) (((float) (v2[0] - v1[0])) * t);
out[1] = v1[1] + (uint32_t) (((float) (v2[1] - v1[1])) * t); out[1] = v1[1] + (uint32_t) (((float) (v2[1] - v1[1])) * t);
out[2] = v1[2] + (uint32_t) (((float) (v2[2] - v1[2])) * t); out[2] = v1[2] + (uint32_t) (((float) (v2[2] - v1[2])) * t);

View File

@ -1,9 +1,4 @@
#ifndef CONFIG_H #pragma once
#define CONFIG_H
/* This figure is derived from the needs of Quake 1 */ /* This figure is derived from the needs of Quake 1 */
#define MAX_TEXTURE_COUNT 1088 #define MAX_TEXTURE_COUNT 1088
#endif // CONFIG_H

View File

@ -443,7 +443,7 @@ static void _fillWithNegZVE(GLuint count, GLfloat* output) {
} }
} }
static void _fillWhiteARGB(GLuint count, GLubyte* output) { GL_FORCE_INLINE void _fillWhiteARGB(GLuint count, GLubyte* output) {
ITERATE(count) { ITERATE(count) {
output[R8IDX] = 255; output[R8IDX] = 255;
output[G8IDX] = 255; output[G8IDX] = 255;
@ -469,26 +469,50 @@ static void _fillZero2fVE(GLuint count, GLfloat* output) {
} }
static void _readVertexData3usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData3usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
static void _readVertexData3uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData3uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
static void _readVertexData4usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData4usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
static void _readVertexData4uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData4uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
static void _readVertexData4usRevARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData4usRevARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
static void _readVertexData4uiRevARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) { static void _readVertexData4uiRevARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
@ -597,7 +621,7 @@ PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) {
return aligned_vector_at(&target->output->vector, target->header_offset); return aligned_vector_at(&target->output->vector, target->header_offset);
} }
Vertex* _glSubmissionTargetStart(SubmissionTarget* target) { GL_INLINE_DEBUG Vertex* _glSubmissionTargetStart(SubmissionTarget* target) {
assert(target->start_offset < target->output->vector.size); assert(target->start_offset < target->output->vector.size);
return aligned_vector_at(&target->output->vector, target->start_offset); return aligned_vector_at(&target->output->vector, target->start_offset);
} }
@ -810,7 +834,15 @@ GL_FORCE_INLINE void _readNormalData(const GLuint first, const GLuint count, Ver
GLubyte* ptr = (GLubyte*) extra->nxyz; GLubyte* ptr = (GLubyte*) extra->nxyz;
ITERATE(count) { ITERATE(count) {
GLfloat* n = (GLfloat*) ptr; GLfloat* n = (GLfloat*) ptr;
vec3f_normalize(n[0], n[1], n[2]); float temp = n[0] * n[0];
temp = MATH_fmac(n[1], n[1], temp);
temp = MATH_fmac(n[2], n[2], temp);
float ilength = MATH_fsrra(temp);
n[0] *= ilength;
n[1] *= ilength;
n[2] *= ilength;
ptr += sizeof(VertexExtra); ptr += sizeof(VertexExtra);
} }
} }
@ -1104,9 +1136,6 @@ static void mat_transform_normal3(const float* xyz, const float* xyzOut, const u
} }
static void light(SubmissionTarget* target) { static void light(SubmissionTarget* target) {
if(!_glIsLightingEnabled()) {
return;
}
static AlignedVector* eye_space_data = NULL; static AlignedVector* eye_space_data = NULL;
@ -1132,16 +1161,6 @@ static void light(SubmissionTarget* target) {
_glPerformLighting(vertex, ES, target->count); _glPerformLighting(vertex, ES, target->count);
} }
GL_FORCE_INLINE float MATH_fsrra(float x) {
__asm__ volatile ("fsrra %[one_div_sqrt]\n"
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
: // no inputs
: // no clobbers
);
return x;
}
GL_FORCE_INLINE void divide(SubmissionTarget* target) { GL_FORCE_INLINE void divide(SubmissionTarget* target) {
TRACE(); TRACE();
@ -1279,7 +1298,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
profiler_checkpoint("generate"); profiler_checkpoint("generate");
if(doLighting) { if(doLighting){
light(target); light(target);
} }
@ -1386,6 +1405,7 @@ void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvo
if(_glCheckImmediateModeInactive(__func__)) { if(_glCheckImmediateModeInactive(__func__)) {
return; return;
} }
_glRecalcFastPath();
submitVertices(mode, 0, count, type, indices); submitVertices(mode, 0, count, type, indices);
} }
@ -1396,6 +1416,7 @@ void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if(_glCheckImmediateModeInactive(__func__)) { if(_glCheckImmediateModeInactive(__func__)) {
return; return;
} }
_glRecalcFastPath();
submitVertices(mode, first, count, GL_UNSIGNED_INT, NULL); submitVertices(mode, first, count, GL_UNSIGNED_INT, NULL);
} }
@ -1421,8 +1442,6 @@ void APIENTRY glEnableClientState(GLenum cap) {
default: default:
_glKosThrowError(GL_INVALID_ENUM, __func__); _glKosThrowError(GL_INVALID_ENUM, __func__);
} }
_glRecalcFastPath();
} }
void APIENTRY glDisableClientState(GLenum cap) { void APIENTRY glDisableClientState(GLenum cap) {
@ -1446,8 +1465,6 @@ void APIENTRY glDisableClientState(GLenum cap) {
default: default:
_glKosThrowError(GL_INVALID_ENUM, __func__); _glKosThrowError(GL_INVALID_ENUM, __func__);
} }
_glRecalcFastPath();
} }
GLuint _glGetActiveClientTexture() { GLuint _glGetActiveClientTexture() {
@ -1458,7 +1475,7 @@ void APIENTRY glClientActiveTextureARB(GLenum texture) {
TRACE(); TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) { if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
_glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB"); _glKosThrowError(GL_INVALID_ENUM, __func__);
} }
if(_glKosHasError()) { if(_glKosHasError()) {
@ -1489,8 +1506,6 @@ void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, cons
tointer->stride = stride; tointer->stride = stride;
tointer->type = type; tointer->type = type;
tointer->size = size; tointer->size = size;
_glRecalcFastPath();
} }
void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
@ -1506,8 +1521,6 @@ void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const
VERTEX_POINTER.stride = stride; VERTEX_POINTER.stride = stride;
VERTEX_POINTER.type = type; VERTEX_POINTER.type = type;
VERTEX_POINTER.size = size; VERTEX_POINTER.size = size;
_glRecalcFastPath();
} }
void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
@ -1523,8 +1536,6 @@ void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const G
DIFFUSE_POINTER.stride = stride; DIFFUSE_POINTER.stride = stride;
DIFFUSE_POINTER.type = type; DIFFUSE_POINTER.type = type;
DIFFUSE_POINTER.size = size; DIFFUSE_POINTER.size = size;
_glRecalcFastPath();
} }
void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {
@ -1550,5 +1561,4 @@ void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * poin
NORMAL_POINTER.type = type; NORMAL_POINTER.type = type;
NORMAL_POINTER.size = (type == GL_UNSIGNED_INT_2_10_10_10_REV) ? 1 : 3; NORMAL_POINTER.size = (type == GL_UNSIGNED_INT_2_10_10_10_REV) ? 1 : 3;
_glRecalcFastPath();
} }

View File

@ -57,6 +57,7 @@ void _glKosPrintError() {
} }
fprintf(stderr, "GL ERROR: %s when calling %s\n", _glErrorEnumAsString(last_error), error_function); fprintf(stderr, "GL ERROR: %s when calling %s\n", _glErrorEnumAsString(last_error), error_function);
_glKosResetError();
} }
GLenum glGetError(void) { GLenum glGetError(void) {

View File

@ -63,6 +63,7 @@ void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) {
} }
void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) { void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
_GL_UNUSED(target);
TRACE(); TRACE();
if(framebuffer) { if(framebuffer) {
@ -76,6 +77,10 @@ void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
} }
void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
_GL_UNUSED(target);
_GL_UNUSED(attachment);
_GL_UNUSED(textarget);
_GL_UNUSED(level);
if(texture != 0 && !glIsTexture(texture)) { if(texture != 0 && !glIsTexture(texture)) {
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError(); _glKosPrintError();
@ -91,62 +96,62 @@ void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum
ACTIVE_FRAMEBUFFER->texture_id = texture; ACTIVE_FRAMEBUFFER->texture_id = texture;
} }
static inline GLubyte A1555(GLushort v) { GL_FORCE_INLINE GLuint A1555(GLuint v) {
const GLuint MASK = (1 << 15); const GLuint MASK = (1 << 15);
return (v & MASK) >> 8; return (v & MASK) >> 8;
} }
static inline GLubyte R1555(GLushort v) { GL_FORCE_INLINE GLuint R1555(GLuint v) {
const GLuint MASK = (31 << 10); const GLuint MASK = (31 << 10);
return (v & MASK) >> 7; return (v & MASK) >> 7;
} }
static inline GLubyte G1555(GLushort v) { GL_FORCE_INLINE GLuint G1555(GLuint v) {
const GLuint MASK = (31 << 5); const GLuint MASK = (31 << 5);
return (v & MASK) >> 2; return (v & MASK) >> 2;
} }
static inline GLubyte B1555(GLushort v) { GL_FORCE_INLINE GLuint B1555(GLuint v) {
const GLuint MASK = (31 << 0); const GLuint MASK = (31 << 0);
return (v & MASK) << 3; return (v & MASK) << 3;
} }
static inline GLubyte A4444(GLushort v) { GL_FORCE_INLINE GLuint A4444(GLuint v) {
const GLuint MASK = (0xF << 12); const GLuint MASK = (0xF << 12);
return (v & MASK) >> 12; return (v & MASK) >> 12;
} }
static inline GLubyte R4444(GLushort v) { GL_FORCE_INLINE GLuint R4444(GLuint v) {
const GLuint MASK = (0xF << 8); const GLuint MASK = (0xF << 8);
return (v & MASK) >> 8; return (v & MASK) >> 8;
} }
static inline GLubyte G4444(GLushort v) { GL_FORCE_INLINE GLuint G4444(GLuint v) {
const GLuint MASK = (0xF << 4); const GLuint MASK = (0xF << 4);
return (v & MASK) >> 4; return (v & MASK) >> 4;
} }
static inline GLubyte B4444(GLushort v) { GL_FORCE_INLINE GLuint B4444(GLuint v) {
const GLuint MASK = (0xF << 0); const GLuint MASK = (0xF << 0);
return (v & MASK) >> 0; return (v & MASK) >> 0;
} }
static inline GLubyte R565(GLushort v) { GL_FORCE_INLINE GLuint R565(GLuint v) {
const GLuint MASK = (31 << 11); const GLuint MASK = (31 << 11);
return (v & MASK) >> 8; return (v & MASK) >> 8;
} }
static inline GLubyte G565(GLushort v) { GL_FORCE_INLINE GLuint G565(GLuint v) {
const GLuint MASK = (63 << 5); const GLuint MASK = (63 << 5);
return (v & MASK) >> 3; return (v & MASK) >> 3;
} }
static inline GLubyte B565(GLushort v) { GL_FORCE_INLINE GLuint B565(GLuint v) {
const GLuint MASK = (31 << 0); const GLuint MASK = (31 << 0);
return (v & MASK) << 3; return (v & MASK) << 3;
} }
GLboolean _glCalculateAverageTexel(GLuint pvrFormat, const GLubyte* src1, const GLubyte* src2, const GLubyte* src3, const GLubyte* src4, GLubyte* t) { static GL_NO_INSTRUMENT GLboolean _glCalculateAverageTexel(GLuint pvrFormat, const GLubyte* src1, const GLubyte* src2, const GLubyte* src3, const GLubyte* src4, GLubyte* t) {
GLuint a, r, g, b; GLuint a, r, g, b;
GLubyte format = ((pvrFormat & (1 << 27)) | (pvrFormat & (1 << 26))) >> 26; GLubyte format = ((pvrFormat & (1 << 27)) | (pvrFormat & (1 << 26))) >> 26;

View File

@ -4,9 +4,9 @@
/* Set the Perspective */ /* Set the Perspective */
void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect, void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect,
GLfloat znear, GLfloat zfar) { GLfloat znear, GLfloat zfar) {
GLdouble fW, fH; GLfloat fW, fH;
fH = tan(angle / 360 * F_PI) * znear; fH = tanf(angle * (F_PI / 360.0f)) * znear;
fW = fH * aspect; fW = fH * aspect;
glFrustum(-fW, fW, -fH, fH, znear, zfar); glFrustum(-fW, fW, -fH, fH, znear, zfar);

View File

@ -192,6 +192,7 @@ void APIENTRY glVertex2fv(const GLfloat* v) {
} }
void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
_GL_UNUSED(w);
glVertex3f(x, y, z); glVertex3f(x, y, z);
} }

View File

@ -15,7 +15,7 @@
static GLfloat SCENE_AMBIENT [] = {0.2f, 0.2f, 0.2f, 1.0f}; static GLfloat SCENE_AMBIENT [] = {0.2f, 0.2f, 0.2f, 1.0f};
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE; static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR; static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE; static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
static LightSource LIGHTS[MAX_LIGHTS]; static LightSource LIGHTS[MAX_LIGHTS];
@ -346,18 +346,8 @@ GL_FORCE_INLINE void _glLightVertexPoint(
#undef _PROCESS_COMPONENT #undef _PROCESS_COMPONENT
} }
GL_FORCE_INLINE float MATH_fsrra(float x) {
__asm__ volatile ("fsrra %[one_div_sqrt]\n"
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
: // no inputs
: // no clobbers
);
return x;
}
GL_FORCE_INLINE void bgra_to_float(const uint8_t* input, GLfloat* output) { GL_FORCE_INLINE void bgra_to_float(const uint8_t* input, GLfloat* output) {
const static float scale = 1.0f / 255.0f; static const float scale = 1.0f / 255.0f;
output[0] = ((float) input[R8IDX]) * scale; output[0] = ((float) input[R8IDX]) * scale;
output[1] = ((float) input[G8IDX]) * scale; output[1] = ((float) input[G8IDX]) * scale;

View File

@ -12,8 +12,6 @@
#define DEG2RAD (0.01745329251994329576923690768489) #define DEG2RAD (0.01745329251994329576923690768489)
/* Viewport mapping */
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
/* Depth range */ /* Depth range */
GLfloat DEPTH_RANGE_MULTIPLIER_L = (1 - 0) / 2; GLfloat DEPTH_RANGE_MULTIPLIER_L = (1 - 0) / 2;
@ -47,8 +45,6 @@ static void _glStoreNearPlane() {
NEAR_PLANE_DISTANCE = -b / (1.0f - a); NEAR_PLANE_DISTANCE = -b / (1.0f - a);
} }
void APIENTRY glDepthRange(GLclampf n, GLclampf f);
static inline void upload_matrix(Matrix4x4* m) { static inline void upload_matrix(Matrix4x4* m) {
mat_load((matrix_t*) m); mat_load((matrix_t*) m);
} }
@ -78,8 +74,8 @@ void _glInitMatrices() {
stack_push(&MATRIX_STACKS[1], IDENTITY); stack_push(&MATRIX_STACKS[1], IDENTITY);
stack_push(&MATRIX_STACKS[2], IDENTITY); stack_push(&MATRIX_STACKS[2], IDENTITY);
memcpy(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4)); memcpy4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4)); memcpy4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
glDepthRange(0.0f, 1.0f); glDepthRange(0.0f, 1.0f);
glViewport(0, 0, vid_mode->width, vid_mode->height); glViewport(0, 0, vid_mode->width, vid_mode->height);
@ -123,7 +119,7 @@ static void transpose(GLfloat* m) {
} }
static void recalculateNormalMatrix() { static void recalculateNormalMatrix() {
memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4)); memcpy4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4));
inverse((GLfloat*) NORMAL_MATRIX); inverse((GLfloat*) NORMAL_MATRIX);
transpose((GLfloat*) NORMAL_MATRIX); transpose((GLfloat*) NORMAL_MATRIX);
} }
@ -465,7 +461,7 @@ GLfloat _glGetNearPlane() {
} }
/* Set the depth range */ /* Set the depth range */
void APIENTRY glDepthRange(GLclampf n, GLclampf f) { void APIENTRY glDepthRangef(GLclampf n, GLclampf f) {
if(n < 0.0f) n = 0.0f; if(n < 0.0f) n = 0.0f;
else if(n > 1.0f) n = 1.0f; else if(n > 1.0f) n = 1.0f;
@ -476,58 +472,55 @@ void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
DEPTH_RANGE_MULTIPLIER_H = (n + f) / 2.0f; DEPTH_RANGE_MULTIPLIER_H = (n + f) / 2.0f;
} }
/* Vector Cross Product - Used by glhLookAtf2 */ void APIENTRY glDepthRange(GLclampf n, GLclampf f){
glDepthRangef(n,f);
}
/* Vector Cross Product - Used by gluLookAt */
static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* result) { static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* result) {
result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[0] = v1[1] * v2[2] - v1[2] * v2[1];
result[1] = v1[2] * v2[0] - v1[0] * v2[2]; result[1] = v1[2] * v2[0] - v1[0] * v2[2];
result[2] = v1[0] * v2[1] - v1[1] * v2[0]; result[2] = v1[0] * v2[1] - v1[1] * v2[0];
} }
/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */ static inline void vec3f_normalize_sh4(float *v){
void glhLookAtf2(const GLfloat* eyePosition3D, float length, ilength;
const GLfloat* center3D,
const GLfloat* upVector3D) {
/* Look-At Matrix */ ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
static Matrix4x4 MatrixLookAt __attribute__((aligned(32))) = { length = MATH_Invert(ilength);
1.0f, 0.0f, 0.0f, 0.0f, if (length)
0.0f, 1.0f, 0.0f, 0.0f, {
0.0f, 0.0f, 1.0f, 0.0f, v[0] *= ilength;
0.0f, 0.0f, 0.0f, 1.0f v[1] *= ilength;
}; v[2] *= ilength;
}
}
GLfloat forward[3]; void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
GLfloat side[3]; GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
GLfloat up[3]; GLfloat upz) {
GLfloat m [16];
GLfloat f [3];
GLfloat u [3];
GLfloat s [3];
vec3f_sub_normalize(center3D[0], center3D[1], center3D[2], f[0] = centerx - eyex;
eyePosition3D[0], eyePosition3D[1], eyePosition3D[2], f[1] = centery - eyey;
forward[0], forward[1], forward[2]); f[2] = centerz - eyez;
//Side = forward x up u[0] = upx;
vec3f_cross(forward, upVector3D, side); u[1] = upy;
vec3f_normalize(side[0], side[1], side[2]); u[2] = upz;
//Recompute up as: up = side x forward vec3f_normalize_sh4(f);
vec3f_cross(side, forward, up); vec3f_cross(f, u, s);
vec3f_normalize_sh4(s);
vec3f_cross(s, f, u);
MatrixLookAt[M0] = side[0]; m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f;
MatrixLookAt[M4] = side[1]; m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f;
MatrixLookAt[M8] = side[2]; m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f;
MatrixLookAt[M12] = 0; m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;
MatrixLookAt[M1] = up[0];
MatrixLookAt[M5] = up[1];
MatrixLookAt[M9] = up[2];
MatrixLookAt[M13] = 0;
MatrixLookAt[M2] = -forward[0];
MatrixLookAt[M6] = -forward[1];
MatrixLookAt[M10] = -forward[2];
MatrixLookAt[M14] = 0;
MatrixLookAt[M3] = MatrixLookAt[11] = MatrixLookAt[15] = 0;
MatrixLookAt[M15] = 1;
static Matrix4x4 trn __attribute__((aligned(32))) = { static Matrix4x4 trn __attribute__((aligned(32))) = {
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
@ -536,26 +529,17 @@ void glhLookAtf2(const GLfloat* eyePosition3D,
0.0f, 0.0f, 0.0f, 1.0f 0.0f, 0.0f, 0.0f, 1.0f
}; };
trn[M12] = -eyePosition3D[0]; trn[M12] = -eyex;
trn[M13] = -eyePosition3D[1]; trn[M13] = -eyey;
trn[M14] = -eyePosition3D[2]; trn[M14] = -eyez;
// Does not modify internal Modelview matrix // Does not modify internal Modelview matrix
upload_matrix(&MatrixLookAt); upload_matrix(&m);
multiply_matrix(&trn); multiply_matrix(&trn);
multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
} }
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
GLfloat upz) {
GLfloat eye [] = { eyex, eyey, eyez };
GLfloat point [] = { centerx, centery, centerz };
GLfloat up [] = { upx, upy, upz };
glhLookAtf2(eye, point, up);
}
void _glApplyRenderMatrix() { void _glApplyRenderMatrix() {
upload_matrix(&SCREENVIEW_MATRIX); upload_matrix(&SCREENVIEW_MATRIX);
multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));

View File

@ -11,12 +11,21 @@
#include "../include/gl.h" #include "../include/gl.h"
#include "../containers/aligned_vector.h" #include "../containers/aligned_vector.h"
#include "../containers/named_array.h" #include "../containers/named_array.h"
#include "sh4_math.h"
#define GL_FORCE_INLINE __attribute__((always_inline)) static __inline__ extern void* memcpy4 (void *dest, const void *src, size_t count);
#define GL_NO_INSTRUMENT inline __attribute__((no_instrument_function))
#define GL_INLINE_DEBUG GL_NO_INSTRUMENT __attribute__((always_inline))
#define GL_FORCE_INLINE static GL_INLINE_DEBUG
#define _GL_UNUSED(x) (void)(x)
#define FASTCPY(dst, src, bytes) \ #define FASTCPY(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes); (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes);
#define FASTCPY4(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes);
#define _PACK4(v) ((v * 0xF) / 0xFF) #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_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_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
@ -109,35 +118,41 @@ typedef struct {
} TexturePalette; } TexturePalette;
typedef struct { typedef struct {
GLushort width; //0
GLushort height;
GLuint color; /* This is the PVR texture format */
GLubyte env;
GLushort mipmap; /* Bitmask of supplied mipmap levels */
GLubyte mipmapCount; /* The number of mipmap levels */
GLubyte uv_clamp;
GLuint index; GLuint index;
GLvoid *data; GLuint color; /* This is the PVR texture format */
GLuint dataStride; //8
GLuint baseDataSize; /* The data size of mipmap level 0 */
GLenum minFilter; GLenum minFilter;
GLenum magFilter; GLenum magFilter;
//16
GLboolean isCompressed; GLvoid *data;
GLboolean isPaletted; TexturePalette* palette;
//24
GLushort width;
GLushort height;
//28
GLushort mipmap; /* Bitmask of supplied mipmap levels */
/* When using the shared palette, this is the bank (0-3) */
GLushort shared_bank;
//32
GLuint dataStride;
//36
GLubyte mipmap_bias;
GLubyte env;
GLubyte mipmapCount; /* The number of mipmap levels */
GLubyte uv_clamp;
//40
/* Mipmap textures have a different /* Mipmap textures have a different
* offset for the base level when supplying the data, this * offset for the base level when supplying the data, this
* keeps track of that. baseDataOffset == 0 * keeps track of that. baseDataOffset == 0
* means that the texture has no mipmaps * means that the texture has no mipmaps
*/ */
GLuint baseDataOffset; GLuint baseDataOffset;
GLuint baseDataSize; /* The data size of mipmap level 0 */
TexturePalette* palette; //48
GLboolean isCompressed;
/* When using the shared palette, this is the bank (0-3) */ GLboolean isPaletted;
GLushort shared_bank; //50
} TextureObject; } TextureObject;
typedef struct { typedef struct {
@ -176,20 +191,6 @@ typedef struct {
float w; float w;
} Vertex; } Vertex;
/* FIXME: SH4 has a swap.w instruction, we should leverage it here! */
#define _SWAP32(x, y) \
do { \
uint32_t t = *((uint32_t*) &x); \
*((uint32_t*) &x) = *((uint32_t*) &y); \
*((uint32_t*) &y) = t; \
} while(0)
/*
*((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \
*((uint32_t*) &y) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \
*((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); */
#define swapVertex(a, b) \ #define swapVertex(a, b) \
do { \ do { \
Vertex c = *a; \ Vertex c = *a; \
@ -307,8 +308,8 @@ GLboolean _glIsBlendingEnabled();
GLboolean _glIsAlphaTestEnabled(); GLboolean _glIsAlphaTestEnabled();
GLboolean _glIsMipmapComplete(const TextureObject* obj); GLboolean _glIsMipmapComplete(const TextureObject* obj);
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level); GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level);
GLuint _glGetMipmapLevelCount(TextureObject* obj); GLuint _glGetMipmapLevelCount(const TextureObject* obj);
GLboolean _glIsLightingEnabled(); GLboolean _glIsLightingEnabled();
GLboolean _glIsLightEnabled(GLubyte light); GLboolean _glIsLightEnabled(GLubyte light);
@ -336,19 +337,8 @@ GLubyte _glKosHasError();
#define MAX_TEXTURE_UNITS 2 #define MAX_TEXTURE_UNITS 2
#define MAX_LIGHTS 8 #define MAX_LIGHTS 8
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) #define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define mat_trans_fv12() { \ #define CLAMP( X, _MIN, _MAX ) ( (X)<(_MIN) ? (_MIN) : ((X)>(_MAX) ? (_MAX) : (X)) )
__asm__ __volatile__( \
"fldi1 fr15\n" \
"ftrv xmtrx, fv12\n" \
"fldi1 fr14\n" \
"fdiv fr15, fr14\n" \
"fmul fr14, fr12\n" \
"fmul fr14, fr13\n" \
: "=f" (__x), "=f" (__y), "=f" (__z) \
: "0" (__x), "1" (__y), "2" (__z) \
: "fr15" ); \
}
#endif // PRIVATE_H #endif // PRIVATE_H

View File

@ -6,6 +6,8 @@
#include "profiler.h" #include "profiler.h"
#include "../containers/aligned_vector.h" #include "../containers/aligned_vector.h"
#if PROFILING_COMPILED
#define MAX_PATH 256 #define MAX_PATH 256
typedef struct { typedef struct {
@ -141,3 +143,4 @@ void profiler_print_stats() {
fprintf(stderr, "%-60s%-20f%-20f%" PRIu64 "\n", result->name, (double)avg, (double)ms, result->total_calls); fprintf(stderr, "%-60s%-20f%-20f%" PRIu64 "\n", result->name, (double)avg, (double)ms, result->total_calls);
} }
} }
#endif

View File

@ -7,12 +7,26 @@ typedef struct {
uint64_t start_time_in_us; uint64_t start_time_in_us;
} Profiler; } Profiler;
#define PROFILING_COMPILED 0
#if PROFILING_COMPILED
Profiler* profiler_push(const char* name); Profiler* profiler_push(const char* name);
void profiler_checkpoint(const char* name); void _profiler_checkpoint(const char* name);
void profiler_pop(); void _profiler_pop();
void profiler_print_stats(); void _profiler_print_stats();
void profiler_enable(); void _profiler_enable();
void profiler_disable(); void _profiler_disable();
#else
#define profiler_push(name);
#define profiler_checkpoint(name);
#define profiler_pop();
#define profiler_print_stats();
#define profiler_enable();
#define profiler_disable();
#endif

54
GL/sh4_math.h Normal file
View File

@ -0,0 +1,54 @@
// ---- sh4_math.h - SH7091 Math Module ----
//
// Version 1.0.8
//
// This file is part of the DreamHAL project, a hardware abstraction library
// primarily intended for use on the SH7091 found in hardware such as the SEGA
// Dreamcast game console.
//
// This math module is hereby released into the public domain in the hope that it
// may prove useful. Now go hit 60 fps! :)
//
// --Moopthehedgehog
//
#pragma once
// 1/x
// (1.0f / sqrt(x)) ^ 2
// This is about 3x faster than fdiv!
static inline __attribute__((always_inline)) float MATH_Invert(float x)
{
asm volatile ("fsrra %[one_div_sqrt]\n\t"
"fmul %[one_div_sqrt], %[one_div_sqrt]\n"
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
: // no inputs
: // no clobbers
);
return x;
}
// 1/sqrt(x)
static inline __attribute__((always_inline)) float MATH_fsrra(float x)
{
asm volatile ("fsrra %[one_div_sqrt]\n"
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
: // no inputs
: // no clobbers
);
return x;
}
// a*b+c
static inline __attribute__((always_inline)) float MATH_fmac(float a, float b, float c)
{
asm volatile ("fmac fr0, %[floatb], %[floatc]\n"
: [floatc] "+f" (c) // outputs, "+" means r/w
: "w" (a), [floatb] "f" (b) // inputs
: // no clobbers
);
return c;
}

View File

@ -18,7 +18,6 @@ pvr_poly_cxt_t* _glGetPVRContext() {
return &GL_CONTEXT; return &GL_CONTEXT;
} }
/* We can't just use the GL_CONTEXT for this state as the two /* 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 * GL states are combined, so we store them separately and then
* calculate the appropriate PVR state from them. */ * calculate the appropriate PVR state from them. */
@ -32,6 +31,8 @@ static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
static GLboolean ALPHA_TEST_ENABLED = GL_FALSE; static GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
static GLboolean POLYGON_OFFSET_ENABLED = GL_FALSE;
static GLboolean NORMALIZE_ENABLED = GL_FALSE; static GLboolean NORMALIZE_ENABLED = GL_FALSE;
GLboolean _glIsSharedTexturePaletteEnabled() { GLboolean _glIsSharedTexturePaletteEnabled() {
@ -84,6 +85,9 @@ static GLenum BLEND_SFACTOR = GL_ONE;
static GLenum BLEND_DFACTOR = GL_ZERO; static GLenum BLEND_DFACTOR = GL_ZERO;
static GLboolean BLEND_ENABLED = GL_FALSE; static GLboolean BLEND_ENABLED = GL_FALSE;
static GLfloat OFFSET_FACTOR = 0.0f;
static GLfloat OFFSET_UNITS = 0.0f;
GLboolean _glIsNormalizeEnabled() { GLboolean _glIsNormalizeEnabled() {
return NORMALIZE_ENABLED; return NORMALIZE_ENABLED;
} }
@ -150,7 +154,7 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) {
return GL_FALSE; return GL_FALSE;
} }
static GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE}; GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE};
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1(); const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1();
@ -187,6 +191,10 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
enableMipmaps = GL_TRUE; enableMipmaps = GL_TRUE;
} }
if(tx1->height != tx1->width){
enableMipmaps = GL_FALSE;
}
if(enableMipmaps) { if(enableMipmaps) {
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) { if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
filter = PVR_FILTER_TRILINEAR1; filter = PVR_FILTER_TRILINEAR1;
@ -215,15 +223,13 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
context->txr.filter = filter; context->txr.filter = filter;
context->txr.width = tx1->width; context->txr.width = tx1->width;
context->txr.height = tx1->height; context->txr.height = tx1->height;
context->txr.mipmap = enableMipmaps;
context->txr.mipmap_bias = tx1->mipmap_bias;
if(enableMipmaps) { if(enableMipmaps) {
context->txr.base = tx1->data; context->txr.base = tx1->data;
context->txr.mipmap = PVR_MIPMAP_ENABLE;
context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
} else { } else {
context->txr.base = tx1->data + tx1->baseDataOffset; context->txr.base = tx1->data + tx1->baseDataOffset;
context->txr.mipmap = PVR_MIPMAP_DISABLE;
context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
} }
context->txr.format = tx1->color; context->txr.format = tx1->color;
@ -338,6 +344,11 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
case GL_NEARZ_CLIPPING_KOS: case GL_NEARZ_CLIPPING_KOS:
_glEnableClipping(GL_TRUE); _glEnableClipping(GL_TRUE);
break; break;
case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL:
POLYGON_OFFSET_ENABLED = GL_TRUE;
break;
case GL_NORMALIZE: case GL_NORMALIZE:
NORMALIZE_ENABLED = GL_TRUE; NORMALIZE_ENABLED = GL_TRUE;
break; break;
@ -395,6 +406,11 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
case GL_NEARZ_CLIPPING_KOS: case GL_NEARZ_CLIPPING_KOS:
_glEnableClipping(GL_FALSE); _glEnableClipping(GL_FALSE);
break; break;
case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL:
POLYGON_OFFSET_ENABLED = GL_FALSE;
break;
case GL_NORMALIZE: case GL_NORMALIZE:
NORMALIZE_ENABLED = GL_FALSE; NORMALIZE_ENABLED = GL_FALSE;
break; break;
@ -423,18 +439,22 @@ GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
/* Depth Testing */ /* Depth Testing */
GLAPI void APIENTRY glClearDepthf(GLfloat depth) { GLAPI void APIENTRY glClearDepthf(GLfloat depth) {
_GL_UNUSED(depth);
} }
GLAPI void APIENTRY glClearDepth(GLfloat depth) { GLAPI void APIENTRY glClearDepth(GLfloat depth) {
_GL_UNUSED(depth);
} }
GLAPI void APIENTRY glDrawBuffer(GLenum mode) { GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
_GL_UNUSED(mode);
} }
GLAPI void APIENTRY glReadBuffer(GLenum mode) { GLAPI void APIENTRY glReadBuffer(GLenum mode) {
_GL_UNUSED(mode);
} }
@ -500,23 +520,30 @@ GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
} }
void glLineWidth(GLfloat width) { void glLineWidth(GLfloat width) {
; _GL_UNUSED(width);
} }
void glPolygonOffset(GLfloat factor, GLfloat units) { void glPolygonOffset(GLfloat factor, GLfloat units) {
; OFFSET_FACTOR = factor;
OFFSET_UNITS = units;
} }
void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {
; _GL_UNUSED(target);
_GL_UNUSED(pname);
_GL_UNUSED(params);
} }
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
; _GL_UNUSED(red);
_GL_UNUSED(green);
_GL_UNUSED(blue);
_GL_UNUSED(alpha);
} }
void glPixelStorei(GLenum pname, GLint param) { void glPixelStorei(GLenum pname, GLint param) {
; _GL_UNUSED(pname);
_GL_UNUSED(param);
} }
@ -538,8 +565,8 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1); PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1);
GLint miny, maxx, maxy; GLint miny, maxx, maxy;
GLsizei gl_scissor_width = CLAMP(width, 0, vid_mode->width); GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 );
GLsizei gl_scissor_height = CLAMP(height, 0, vid_mode->height); GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 );
/* force the origin to the lower left-hand corner of the screen */ /* force the origin to the lower left-hand corner of the screen */
miny = (vid_mode->height - gl_scissor_height) - y; miny = (vid_mode->height - gl_scissor_height) - y;
@ -567,6 +594,10 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) {
return LIGHTING_ENABLED; return LIGHTING_ENABLED;
case GL_BLEND: case GL_BLEND:
return BLEND_ENABLED; return BLEND_ENABLED;
case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL:
return POLYGON_OFFSET_ENABLED;
} }
return GL_FALSE; return GL_FALSE;
@ -581,7 +612,7 @@ static GLenum COMPRESSED_FORMATS [] = {
GL_COMPRESSED_RGB_565_VQ_TWID_KOS GL_COMPRESSED_RGB_565_VQ_TWID_KOS
}; };
static GLint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum); static GLuint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum);
void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
GLuint enabledAttrs = *_glGetEnabledAttributes(); GLuint enabledAttrs = *_glGetEnabledAttributes();
@ -616,13 +647,19 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
switch(pname) { switch(pname) {
case GL_PROJECTION_MATRIX: case GL_PROJECTION_MATRIX:
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16); memcpy4(params, _glGetProjectionMatrix(), sizeof(float) * 16);
break; break;
case GL_MODELVIEW_MATRIX: case GL_MODELVIEW_MATRIX:
memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16); memcpy4(params, _glGetModelViewMatrix(), sizeof(float) * 16);
break;
case GL_POLYGON_OFFSET_FACTOR:
*params = OFFSET_FACTOR;
break;
case GL_POLYGON_OFFSET_UNITS:
*params = OFFSET_UNITS;
break; break;
default: default:
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv"); _glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError(); _glKosPrintError();
break; break;
} }
@ -664,7 +701,7 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
} }
} break; } break;
default: default:
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv"); _glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError(); _glKosPrintError();
break; break;
} }

View File

@ -9,12 +9,11 @@
#include "config.h" #include "config.h"
#include "../include/glext.h" #include "../include/glext.h"
#include "../include/glkos.h" #include "../include/glkos.h"
#include <kos/string.h>
#define CLAMP_U (1<<1) #define CLAMP_U (1<<1)
#define CLAMP_V (1<<0) #define CLAMP_V (1<<0)
#define MAX(x, y) ((x > y) ? x : y)
static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL}; static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
static NamedArray TEXTURE_OBJECTS; static NamedArray TEXTURE_OBJECTS;
static GLubyte ACTIVE_TEXTURE = 0; static GLubyte ACTIVE_TEXTURE = 0;
@ -31,7 +30,7 @@ static TexturePalette* _initTexturePalette() {
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette)); TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
assert(palette); assert(palette);
memset(palette, 0x0, sizeof(TexturePalette)); memset4(palette, 0x0, sizeof(TexturePalette));
palette->bank = -1; palette->bank = -1;
return palette; return palette;
} }
@ -133,7 +132,7 @@ GLubyte _glGetActiveTexture() {
return ACTIVE_TEXTURE; return ACTIVE_TEXTURE;
} }
static GLint _determineStride(GLenum format, GLenum type) { static GLint _determineStride(GLenum format, GLenum type) {
switch(type) { switch(type) {
case GL_BYTE: case GL_BYTE:
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
@ -155,7 +154,7 @@ static GLint _determineStride(GLenum format, GLenum type) {
return -1; return -1;
} }
static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) { static GLuint _glGetMipmapDataOffset(const TextureObject* obj, GLuint level) {
GLuint offset = 0; GLuint offset = 0;
GLuint size = obj->height; GLuint size = obj->height;
@ -163,7 +162,7 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
fprintf(stderr, "ERROR: Accessing memory location of mipmaps on non-square texture\n"); fprintf(stderr, "ERROR: Accessing memory location of mipmaps on non-square texture\n");
return obj->baseDataOffset; return obj->baseDataOffset;
} }
if(obj->isPaletted){ if(obj->isPaletted){
switch(size >> level){ switch(size >> level){
case 1024: case 1024:
@ -200,8 +199,44 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
offset = 0x00003; offset = 0x00003;
break; break;
} }
} else { } else if(obj->isCompressed) {
switch(size >> level) { switch(size >> level){
case 1024:
offset = 0x15556;
break;
case 512:
offset = 0x05556;
break;
case 256:
offset = 0x01556;
break;
case 128:
offset = 0x00556;
break;
case 64:
offset = 0x00156;
break;
case 32:
offset = 0x00056;
break;
case 16:
offset = 0x00016;
break;
case 8:
offset = 0x00006;
break;
case 4:
offset = 0x00002;
break;
case 2:
offset = 0x00001;
break;
case 1:
offset = 0x00000;
break;
}
}else {
switch(size >> level){
case 1024: case 1024:
offset = 0xAAAB0; offset = 0xAAAB0;
break; break;
@ -241,12 +276,12 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
return offset; return offset;
} }
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level) { GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level) {
return ((GLubyte*) obj->data) + _glGetMipmapDataOffset(obj, level); return ((GLubyte*) obj->data) + _glGetMipmapDataOffset(obj, level);
} }
GLuint _glGetMipmapLevelCount(TextureObject* obj) { GLuint _glGetMipmapLevelCount(const TextureObject* obj) {
return 1 + floor(log2(MAX(obj->width, obj->height))); return 1 + floorf(log2f(MAX(obj->width, obj->height)));
} }
static GLuint _glGetMipmapDataSize(TextureObject* obj) { static GLuint _glGetMipmapDataSize(TextureObject* obj) {
@ -318,6 +353,7 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
txr->palette = NULL; txr->palette = NULL;
txr->isCompressed = GL_FALSE; txr->isCompressed = GL_FALSE;
txr->isPaletted = GL_FALSE; txr->isPaletted = GL_FALSE;
txr->mipmap_bias = GL_MAX_TEXTURE_LOD_BIAS_DEFAULT;
/* Not mipmapped by default */ /* Not mipmapped by default */
txr->baseDataOffset = 0; txr->baseDataOffset = 0;
@ -403,18 +439,13 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
TRACE(); TRACE();
GLint target_values [] = {GL_TEXTURE_ENV, 0};
GLint pname_values [] = {GL_TEXTURE_ENV_MODE, 0};
GLint param_values [] = {GL_MODULATE, GL_DECAL, GL_REPLACE, 0};
GLubyte failures = 0; GLubyte failures = 0;
GLint target_values [] = {GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL_EXT, 0};
failures += _glCheckValidEnum(target, target_values, __func__); failures += _glCheckValidEnum(target, target_values, __func__);
failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += _glCheckValidEnum(param, param_values, __func__);
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
if(!active) { if(!active) {
return; return;
} }
@ -422,19 +453,47 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
if(failures) { if(failures) {
return; return;
} }
switch(target){
case GL_TEXTURE_ENV:
{
GLint pname_values [] = {GL_TEXTURE_ENV_MODE, 0};
GLint param_values [] = {GL_MODULATE, GL_DECAL, GL_REPLACE, 0};
failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += _glCheckValidEnum(param, param_values, __func__);
if(failures) {
return;
}
switch(param) { switch(param) {
case GL_MODULATE: case GL_MODULATE:
active->env = PVR_TXRENV_MODULATE; active->env = PVR_TXRENV_MODULATEALPHA;
break; break;
case GL_DECAL: case GL_DECAL:
active->env = PVR_TXRENV_DECAL; active->env = PVR_TXRENV_DECAL;
break; break;
case GL_REPLACE: case GL_REPLACE:
active->env = PVR_TXRENV_REPLACE; active->env = PVR_TXRENV_REPLACE;
break; break;
default: default:
break; break;
}
}
break;
case GL_TEXTURE_FILTER_CONTROL_EXT:
{
GLint pname_values [] = {GL_TEXTURE_LOD_BIAS_EXT, 0};
failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += (param > GL_MAX_TEXTURE_LOD_BIAS_DEFAULT || param < -GL_MAX_TEXTURE_LOD_BIAS_DEFAULT);
if(failures) {
return;
}
active->mipmap_bias = (GL_MAX_TEXTURE_LOD_BIAS_DEFAULT+1)+param; // bring to 1-15 inclusive
}
break;
default:
break;
} }
} }
@ -546,6 +605,8 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
static GLint _cleanInternalFormat(GLint internalFormat) { static GLint _cleanInternalFormat(GLint internalFormat) {
switch (internalFormat) { switch (internalFormat) {
case GL_COLOR_INDEX4_EXT:
return GL_COLOR_INDEX4_EXT;
case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX8_EXT:
return GL_COLOR_INDEX8_EXT; return GL_COLOR_INDEX8_EXT;
case GL_ALPHA: case GL_ALPHA:
@ -616,7 +677,7 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
} }
} }
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) { static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
/* Given a cleaned internalFormat, return the Dreamcast format /* Given a cleaned internalFormat, return the Dreamcast format
* that can hold it * that can hold it
*/ */
@ -668,6 +729,8 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX8_EXT:
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED; return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
case GL_COLOR_INDEX4_EXT:
return PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_TWIDDLED;
default: default:
return 0; return 0;
} }
@ -676,11 +739,11 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
typedef void (*TextureConversionFunc)(const GLubyte*, GLubyte*); typedef void (*TextureConversionFunc)(const GLubyte*, GLubyte*);
static inline void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4; *((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
} }
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */ /* Noop */
GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
dst[0] = source[0]; dst[0] = source[0];
@ -689,11 +752,11 @@ static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
dst[3] = source[3]; dst[3] = source[3];
} }
static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3); *((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
} }
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */ /* Noop */
GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
dst[0] = source[0]; dst[0] = source[0];
@ -702,24 +765,24 @@ static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
dst[3] = 255; dst[3] = 255;
} }
static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3); *((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
} }
static inline void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[3] & 0b11111000) << 8); *((GLushort*) dest) = ((source[3] & 0b11111000) << 8);
} }
static inline void _r8_to_rgb565(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _r8_to_rgb565(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = (source[0] & 0b11111000) << 8; *((GLushort*) dest) = (source[0] & 0b11111000) << 8;
} }
static inline void _rgba4444_to_argb4444(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba4444_to_argb4444(const GLubyte* source, GLubyte* dest) {
GLushort* src = (GLushort*) source; GLushort* src = (GLushort*) source;
*((GLushort*) dest) = ((*src & 0x000F) << 12) | *src >> 4; *((GLushort*) dest) = ((*src & 0x000F) << 12) | *src >> 4;
} }
static inline void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
GLushort src = *((GLushort*) source); GLushort src = *((GLushort*) source);
GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
@ -729,7 +792,7 @@ static inline void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
dst[3] = ((src & 0x000F)) * 2; dst[3] = ((src & 0x000F)) * 2;
} }
static inline void _i8_to_i8(const GLubyte* source, GLubyte* dest) { GL_FORCE_INLINE void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
/* For indexes */ /* For indexes */
GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
*dst = *source; *dst = *source;
@ -880,72 +943,93 @@ void _glAllocateSpaceForMipmaps(TextureObject* active) {
active->baseDataOffset = _glGetMipmapDataOffset(active, 0); active->baseDataOffset = _glGetMipmapDataOffset(active, 0);
} }
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define INFO_MSG(x) printf("%s %s\n", __FILE__ ":" TOSTRING(__LINE__), x)
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *data) { GLenum format, GLenum type, const GLvoid *data) {
TRACE(); TRACE();
if(target != GL_TEXTURE_2D) { if(target != GL_TEXTURE_2D) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
} }
if(format != GL_COLOR_INDEX) { if(format != GL_COLOR_INDEX) {
if(!_isSupportedFormat(format)) { if(!_isSupportedFormat(format)) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
} }
/* Abuse determineStride to see if type is valid */ /* Abuse determineStride to see if type is valid */
if(_determineStride(GL_RGBA, type) == -1) { if(_determineStride(GL_RGBA, type) == -1) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
} }
internalFormat = _cleanInternalFormat(internalFormat); internalFormat = _cleanInternalFormat(internalFormat);
if(internalFormat == -1) { if(internalFormat == -1) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
} }
} else { } else {
if(internalFormat != GL_COLOR_INDEX8_EXT) { if(internalFormat != GL_COLOR_INDEX8_EXT) {
INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__); _glKosThrowError(GL_INVALID_ENUM, __func__);
} }
} }
GLint w = width; GLuint w = width;
if(w < 8 || (w & -w) != w) { GLuint h = height;
/* Width is not a power of two. Must be!*/ if(level == 0){
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); if((w < 8 || (w & -w) != w)) {
} /* Width is not a power of two. Must be!*/
INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
}
GLint h = height;
if(h < 8 || (h & -h) != h) { if((h < 8 || (h & -h) != h)) {
/* height is not a power of two. Must be!*/ /* height is not a power of two. Must be!*/
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
}
} else {
/* Mipmap Errors, kos crashes if 1x1 */
if((h < 2) || (w < 2)){
assert(TEXTURE_UNITS[ACTIVE_TEXTURE]);
TEXTURE_UNITS[ACTIVE_TEXTURE]->mipmap |= (1 << level);
return;
}
} }
if(level < 0) { if(level < 0) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
} }
if(level > 0 && width != height) { if(level > 0 && width != height) {
INFO_MSG("");
fprintf(stderr, "[GL ERROR] Mipmaps cannot be supported on non-square textures\n"); fprintf(stderr, "[GL ERROR] Mipmaps cannot be supported on non-square textures\n");
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
} }
if(border) { if(border) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
} }
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) { if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
INFO_MSG("");
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
} }
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE; GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
if(isPaletted && level > 0) {
/* Paletted textures can't have mipmaps */
_glKosThrowError(GL_INVALID_OPERATION, __func__);
}
if(_glKosHasError()) { if(_glKosHasError()) {
_glKosPrintError(); _glKosPrintError();
return; return;
@ -958,7 +1042,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
assert(active); assert(active);
if(active->data && level == 0) { if(active->data && (level == 0)) {
/* pre-existing texture - check if changed */ /* pre-existing texture - check if changed */
if(active->width != width || if(active->width != width ||
active->height != height || active->height != height ||
@ -968,6 +1052,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
active->data = NULL; active->data = NULL;
active->mipmap = 0; active->mipmap = 0;
active->mipmapCount = 0; active->mipmapCount = 0;
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
active->dataStride = 0; active->dataStride = 0;
active->baseDataOffset = 0; active->baseDataOffset = 0;
active->baseDataSize = 0; active->baseDataSize = 0;
@ -992,6 +1077,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
active->color = pvr_format; active->color = pvr_format;
/* Set the required mipmap count */ /* Set the required mipmap count */
active->mipmapCount = _glGetMipmapLevelCount(active); active->mipmapCount = _glGetMipmapLevelCount(active);
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
active->dataStride = destStride; active->dataStride = destStride;
active->baseDataSize = bytes; active->baseDataSize = bytes;
@ -1336,21 +1422,37 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
} }
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) { GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {
_GL_UNUSED(target);
_GL_UNUSED(start);
_GL_UNUSED(count);
_GL_UNUSED(format);
_GL_UNUSED(type);
_GL_UNUSED(data);
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError(); _glKosPrintError();
} }
GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *data) { GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *data) {
_GL_UNUSED(target);
_GL_UNUSED(format);
_GL_UNUSED(type);
_GL_UNUSED(data);
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError(); _glKosPrintError();
} }
GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params) { GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params) {
_GL_UNUSED(target);
_GL_UNUSED(pname);
_GL_UNUSED(params);
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError(); _glKosPrintError();
} }
GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params) { GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params) {
_GL_UNUSED(target);
_GL_UNUSED(pname);
_GL_UNUSED(params);
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError(); _glKosPrintError();
} }
@ -1358,24 +1460,70 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G
GLAPI void APIENTRY glTexSubImage2D( GLAPI void APIENTRY glTexSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
_GL_UNUSED(target);
_GL_UNUSED(level);
_GL_UNUSED(xoffset);
_GL_UNUSED(yoffset);
_GL_UNUSED(width);
_GL_UNUSED(height);
_GL_UNUSED(format);
_GL_UNUSED(type);
_GL_UNUSED(pixels);
assert(0 && "Not Implemented");
} }
GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
_GL_UNUSED(target);
_GL_UNUSED(level);
_GL_UNUSED(xoffset);
_GL_UNUSED(yoffset);
_GL_UNUSED(x);
_GL_UNUSED(y);
_GL_UNUSED(width);
_GL_UNUSED(height);
assert(0 && "Not Implemented");
} }
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
_GL_UNUSED(target);
_GL_UNUSED(level);
_GL_UNUSED(xoffset);
_GL_UNUSED(x);
_GL_UNUSED(y);
_GL_UNUSED(width);
assert(0 && "Not Implemented");
} }
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
_GL_UNUSED(target);
_GL_UNUSED(level);
_GL_UNUSED(internalformat);
_GL_UNUSED(x);
_GL_UNUSED(y);
_GL_UNUSED(width);
_GL_UNUSED(height);
_GL_UNUSED(border);
assert(0 && "Not Implemented");
} }
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
_GL_UNUSED(target);
_GL_UNUSED(level);
_GL_UNUSED(internalformat);
_GL_UNUSED(x);
_GL_UNUSED(y);
_GL_UNUSED(width);
_GL_UNUSED(border);
assert(0 && "Not Implemented");
} }
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
_GL_UNUSED(x);
_GL_UNUSED(y);
_GL_UNUSED(width);
_GL_UNUSED(height);
_GL_UNUSED(format);
_GL_UNUSED(type);
_GL_UNUSED(pixels);
assert(0 && "Not Implemented");
} }

View File

@ -13,6 +13,7 @@ static inline void* memalign(size_t alignment, size_t size) {
#include <malloc.h> #include <malloc.h>
#endif #endif
#include "../GL/private.h"
#include "aligned_vector.h" #include "aligned_vector.h"
void aligned_vector_init(AlignedVector* vector, unsigned int element_size) { void aligned_vector_init(AlignedVector* vector, unsigned int element_size) {
@ -24,7 +25,6 @@ void aligned_vector_init(AlignedVector* vector, unsigned int element_size) {
aligned_vector_reserve(vector, ALIGNED_VECTOR_CHUNK_SIZE); aligned_vector_reserve(vector, ALIGNED_VECTOR_CHUNK_SIZE);
} }
static inline unsigned int round_to_chunk_size(unsigned int val) { static inline unsigned int round_to_chunk_size(unsigned int val) {
const unsigned int n = val; const unsigned int n = val;
const unsigned int m = ALIGNED_VECTOR_CHUNK_SIZE; const unsigned int m = ALIGNED_VECTOR_CHUNK_SIZE;
@ -32,7 +32,6 @@ static inline unsigned int round_to_chunk_size(unsigned int val) {
return ((n + m - 1) / m) * m; return ((n + m - 1) / m) * m;
} }
void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) { void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
if(element_count == 0) { if(element_count == 0) {
return; return;
@ -54,7 +53,7 @@ void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
assert(vector->data); assert(vector->data);
if(original_data) { if(original_data) {
memcpy(vector->data, original_data, original_byte_size); FASTCPY(vector->data, original_data, original_byte_size);
free(original_data); free(original_data);
} }
@ -74,7 +73,7 @@ void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned
unsigned char* dest = vector->data + (vector->element_size * initial_size); unsigned char* dest = vector->data + (vector->element_size * initial_size);
/* Copy the objects in */ /* Copy the objects in */
memcpy(dest, objs, vector->element_size * count); FASTCPY(dest, objs, vector->element_size * count);
return dest; return dest;
} }
@ -101,25 +100,12 @@ void* aligned_vector_resize(AlignedVector* vector, const unsigned int element_co
} }
} }
void* aligned_vector_at(const AlignedVector* vector, const unsigned int index) {
assert(index < vector->size);
return &vector->data[index * vector->element_size];
}
void* aligned_vector_back(AlignedVector* vector) {
return aligned_vector_at(vector, vector->size - 1);
}
void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) { void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) {
const unsigned int current = vector->size; const unsigned int current = vector->size;
aligned_vector_resize(vector, vector->size + additional_count); aligned_vector_resize(vector, vector->size + additional_count);
return aligned_vector_at(vector, current); return aligned_vector_at(vector, current);
} }
void aligned_vector_clear(AlignedVector* vector) {
vector->size = 0;
}
void aligned_vector_shrink_to_fit(AlignedVector* vector) { void aligned_vector_shrink_to_fit(AlignedVector* vector) {
if(vector->size == 0) { if(vector->size == 0) {
free(vector->data); free(vector->data);
@ -131,7 +117,7 @@ void aligned_vector_shrink_to_fit(AlignedVector* vector) {
vector->data = (unsigned char*) memalign(0x20, new_byte_size); vector->data = (unsigned char*) memalign(0x20, new_byte_size);
if(original_data) { if(original_data) {
memcpy(vector->data, original_data, new_byte_size); FASTCPY(vector->data, original_data, new_byte_size);
free(original_data); free(original_data);
} }

View File

@ -1,3 +1,5 @@
#pragma once
#ifndef ALIGNED_VECTOR_H #ifndef ALIGNED_VECTOR_H
#define ALIGNED_VECTOR_H #define ALIGNED_VECTOR_H
@ -5,6 +7,8 @@
extern "C" { extern "C" {
#endif #endif
#include <assert.h>
typedef struct { typedef struct {
unsigned int size; unsigned int size;
unsigned int capacity; unsigned int capacity;
@ -18,12 +22,19 @@ void aligned_vector_init(AlignedVector* vector, unsigned int element_size);
void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count); void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count);
void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count); void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count);
void* aligned_vector_resize(AlignedVector* vector, const unsigned int element_count); void* aligned_vector_resize(AlignedVector* vector, const unsigned int element_count);
void* aligned_vector_at(const AlignedVector* vector, const unsigned int index); static inline void* aligned_vector_at(const AlignedVector* vector, const unsigned int index) {
assert(index < vector->size);
return &vector->data[index * vector->element_size];
}
void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count); void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count);
void aligned_vector_clear(AlignedVector* vector); static inline void aligned_vector_clear(AlignedVector* vector){
vector->size = 0;
}
void aligned_vector_shrink_to_fit(AlignedVector* vector); void aligned_vector_shrink_to_fit(AlignedVector* vector);
void aligned_vector_cleanup(AlignedVector* vector); void aligned_vector_cleanup(AlignedVector* vector);
void* aligned_vector_back(AlignedVector* vector); static inline void* aligned_vector_back(AlignedVector* vector){
return aligned_vector_at(vector, vector->size - 1);
}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -16,8 +17,7 @@ void named_array_init(NamedArray* array, unsigned int element_size, unsigned int
array->element_size = element_size; array->element_size = element_size;
array->max_element_count = max_elements; array->max_element_count = max_elements;
float c = (float) max_elements / 8.0f; array->marker_count = (unsigned char)((max_elements+8-1)/8);
array->marker_count = (unsigned char) ceil(c);
#ifdef _arch_dreamcast #ifdef _arch_dreamcast
// Use 32-bit aligned memory on the Dreamcast // Use 32-bit aligned memory on the Dreamcast
@ -30,17 +30,6 @@ void named_array_init(NamedArray* array, unsigned int element_size, unsigned int
memset(array->used_markers, 0, sizeof(unsigned char) * array->marker_count); memset(array->used_markers, 0, sizeof(unsigned char) * array->marker_count);
} }
char named_array_used(NamedArray* array, unsigned int id) {
unsigned int i = id / 8;
unsigned int j = id % 8;
assert(i < array->max_element_count);
assert(array->used_markers);
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
return !!(v);
}
void* named_array_alloc(NamedArray* array, unsigned int* new_id) { void* named_array_alloc(NamedArray* array, unsigned int* new_id) {
unsigned int i = 0, j = 0; unsigned int i = 0, j = 0;
for(i = 0; i < array->marker_count; ++i) { for(i = 0; i < array->marker_count; ++i) {

View File

@ -1,3 +1,5 @@
#pragma once
#ifndef NAMED_ARRAY_H #ifndef NAMED_ARRAY_H
#define NAMED_ARRAY_H #define NAMED_ARRAY_H
@ -5,6 +7,8 @@
extern "C" { extern "C" {
#endif #endif
#include "../GL/private.h"
typedef struct { typedef struct {
unsigned int element_size; unsigned int element_size;
unsigned int max_element_count; unsigned int max_element_count;
@ -14,7 +18,13 @@ typedef struct {
} NamedArray; } NamedArray;
void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements); void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements);
char named_array_used(NamedArray* array, unsigned int id); static inline char named_array_used(NamedArray* array, unsigned int id) {
const unsigned int i = id / 8;
const unsigned int j = id % 8;
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
return !!(v);
}
void* named_array_alloc(NamedArray* array, unsigned int* new_id); void* named_array_alloc(NamedArray* array, unsigned int* new_id);
void* named_array_reserve(NamedArray* array, unsigned int id); void* named_array_reserve(NamedArray* array, unsigned int id);

View File

@ -362,6 +362,27 @@ __BEGIN_DECLS
#define GL_RGBA12 0x805A #define GL_RGBA12 0x805A
#define GL_RGBA16 0x805B #define GL_RGBA16 0x805B
/* 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 GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_POLYGON_OFFSET_UNITS 0x2A00
#define GL_POLYGON_OFFSET_POINT 0x2A01
#define GL_POLYGON_OFFSET_LINE 0x2A02
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GLbyte char #define GLbyte char
#define GLshort short #define GLshort short
#define GLint int #define GLint int
@ -471,6 +492,7 @@ GLAPI void APIENTRY glClearDepthf(GLfloat depth);
GLAPI void APIENTRY glDepthMask(GLboolean flag); GLAPI void APIENTRY glDepthMask(GLboolean flag);
GLAPI void APIENTRY glDepthFunc(GLenum func); GLAPI void APIENTRY glDepthFunc(GLenum func);
GLAPI void APIENTRY glDepthRange(GLclampf n, GLclampf f); GLAPI void APIENTRY glDepthRange(GLclampf n, GLclampf f);
GLAPI void APIENTRY glDepthRangef(GLclampf n, GLclampf f);
/* Hints */ /* Hints */
/* Currently Supported Capabilities: /* Currently Supported Capabilities:

View File

@ -190,6 +190,21 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target,
#define glGenerateMipmap glGenerateMipmapEXT #define glGenerateMipmap glGenerateMipmapEXT
#define glCompressedTexImage2D glCompressedTexImage2DARB #define glCompressedTexImage2D glCompressedTexImage2DARB
#ifndef GL_VERSION_1_4
#define GL_VERSION_1_4 1
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
#define GL_TEXTURE_LOD_BIAS 0x8501
#define GL_MAX_TEXTURE_LOD_BIAS_DEFAULT 7
#define GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS -4
#endif
#ifndef GL_EXT_texture_lod_bias
#define GL_EXT_texture_lod_bias 1
#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
#endif /* GL_EXT_texture_lod_bias */
__END_DECLS __END_DECLS
#endif /* !__GL_GLEXT_H */ #endif /* !__GL_GLEXT_H */