Merge branch 'kazade_patch_prepare' into 'master'

Kazade patch prepare

See merge request simulant/GLdc!52
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]};
vout->xyz[0] = v1->xyz[0] + (vec[0] * (*t));
vout->xyz[1] = v1->xyz[1] + (vec[1] * (*t));
vout->xyz[2] = v1->xyz[2] + (vec[2] * (*t));
vout->xyz[0] = MATH_fmac(vec[0], (*t), v1->xyz[0]);
vout->xyz[1] = MATH_fmac(vec[1], (*t), v1->xyz[1]);
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) {
float v = v2 - v1;
*out = (v * t) + v1;
GL_FORCE_INLINE void interpolateFloat(const float v1, const float v2, const float t, float* out) {
*out = MATH_fmac(v2 - v1,t, v1);
}
static inline void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
GL_FORCE_INLINE void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]);
}
static inline void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
GL_FORCE_INLINE void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]);
interpolateFloat(v1[2], v2[2], t, &out[2]);
}
static inline void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
/* FIXME: SH4 has an asm instruction for this */
GL_FORCE_INLINE void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
interpolateFloat(v1[0], v2[0], t, &out[0]);
interpolateFloat(v1[1], v2[1], t, &out[1]);
interpolateFloat(v1[2], v2[2], t, &out[2]);
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[1] = v1[1] + (uint32_t) (((float) (v2[1] - v1[1])) * t);
out[2] = v1[2] + (uint32_t) (((float) (v2[2] - v1[2])) * t);

View File

@ -1,9 +1,4 @@
#ifndef CONFIG_H
#define CONFIG_H
#pragma once
/* This figure is derived from the needs of Quake 1 */
#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) {
output[R8IDX] = 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) {
_GL_UNUSED(input);
_GL_UNUSED(count);
_GL_UNUSED(stride);
_GL_UNUSED(output);
assert(0 && "Not Implemented");
}
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");
}
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");
}
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");
}
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");
}
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");
}
@ -597,7 +621,7 @@ PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) {
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);
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;
ITERATE(count) {
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);
}
}
@ -1104,9 +1136,6 @@ static void mat_transform_normal3(const float* xyz, const float* xyzOut, const u
}
static void light(SubmissionTarget* target) {
if(!_glIsLightingEnabled()) {
return;
}
static AlignedVector* eye_space_data = NULL;
@ -1132,16 +1161,6 @@ static void light(SubmissionTarget* target) {
_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) {
TRACE();
@ -1279,7 +1298,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
profiler_checkpoint("generate");
if(doLighting) {
if(doLighting){
light(target);
}
@ -1386,6 +1405,7 @@ void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvo
if(_glCheckImmediateModeInactive(__func__)) {
return;
}
_glRecalcFastPath();
submitVertices(mode, 0, count, type, indices);
}
@ -1396,6 +1416,7 @@ void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if(_glCheckImmediateModeInactive(__func__)) {
return;
}
_glRecalcFastPath();
submitVertices(mode, first, count, GL_UNSIGNED_INT, NULL);
}
@ -1421,8 +1442,6 @@ void APIENTRY glEnableClientState(GLenum cap) {
default:
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
_glRecalcFastPath();
}
void APIENTRY glDisableClientState(GLenum cap) {
@ -1446,8 +1465,6 @@ void APIENTRY glDisableClientState(GLenum cap) {
default:
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
_glRecalcFastPath();
}
GLuint _glGetActiveClientTexture() {
@ -1458,7 +1475,7 @@ void APIENTRY glClientActiveTextureARB(GLenum texture) {
TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
_glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB");
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
if(_glKosHasError()) {
@ -1489,8 +1506,6 @@ void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, cons
tointer->stride = stride;
tointer->type = type;
tointer->size = size;
_glRecalcFastPath();
}
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.type = type;
VERTEX_POINTER.size = size;
_glRecalcFastPath();
}
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.type = type;
DIFFUSE_POINTER.size = size;
_glRecalcFastPath();
}
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.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);
_glKosResetError();
}
GLenum glGetError(void) {

View File

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

View File

@ -4,9 +4,9 @@
/* Set the Perspective */
void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect,
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;
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) {
_GL_UNUSED(w);
glVertex3f(x, y, z);
}

View File

@ -15,7 +15,7 @@
static GLfloat SCENE_AMBIENT [] = {0.2f, 0.2f, 0.2f, 1.0f};
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
static LightSource LIGHTS[MAX_LIGHTS];
@ -346,18 +346,8 @@ GL_FORCE_INLINE void _glLightVertexPoint(
#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) {
const static float scale = 1.0f / 255.0f;
static const float scale = 1.0f / 255.0f;
output[0] = ((float) input[R8IDX]) * scale;
output[1] = ((float) input[G8IDX]) * scale;

View File

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

View File

@ -11,12 +11,21 @@
#include "../include/gl.h"
#include "../containers/aligned_vector.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) \
(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 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) )
@ -109,35 +118,41 @@ typedef struct {
} TexturePalette;
typedef struct {
GLushort width;
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;
//0
GLuint index;
GLvoid *data;
GLuint dataStride;
GLuint baseDataSize; /* The data size of mipmap level 0 */
GLuint color; /* This is the PVR texture format */
//8
GLenum minFilter;
GLenum magFilter;
GLboolean isCompressed;
GLboolean isPaletted;
//16
GLvoid *data;
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
* offset for the base level when supplying the data, this
* keeps track of that. baseDataOffset == 0
* means that the texture has no mipmaps
*/
GLuint baseDataOffset;
TexturePalette* palette;
/* When using the shared palette, this is the bank (0-3) */
GLushort shared_bank;
GLuint baseDataSize; /* The data size of mipmap level 0 */
//48
GLboolean isCompressed;
GLboolean isPaletted;
//50
} TextureObject;
typedef struct {
@ -176,20 +191,6 @@ typedef struct {
float w;
} 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) \
do { \
Vertex c = *a; \
@ -307,8 +308,8 @@ GLboolean _glIsBlendingEnabled();
GLboolean _glIsAlphaTestEnabled();
GLboolean _glIsMipmapComplete(const TextureObject* obj);
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level);
GLuint _glGetMipmapLevelCount(TextureObject* obj);
GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level);
GLuint _glGetMipmapLevelCount(const TextureObject* obj);
GLboolean _glIsLightingEnabled();
GLboolean _glIsLightEnabled(GLubyte light);
@ -336,19 +337,8 @@ GLubyte _glKosHasError();
#define MAX_TEXTURE_UNITS 2
#define MAX_LIGHTS 8
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
#define mat_trans_fv12() { \
__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" ); \
}
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define CLAMP( X, _MIN, _MAX ) ( (X)<(_MIN) ? (_MIN) : ((X)>(_MAX) ? (_MAX) : (X)) )
#endif // PRIVATE_H

View File

@ -6,6 +6,8 @@
#include "profiler.h"
#include "../containers/aligned_vector.h"
#if PROFILING_COMPILED
#define MAX_PATH 256
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);
}
}
#endif

View File

@ -7,12 +7,26 @@ typedef struct {
uint64_t start_time_in_us;
} Profiler;
#define PROFILING_COMPILED 0
#if PROFILING_COMPILED
Profiler* profiler_push(const char* name);
void profiler_checkpoint(const char* name);
void profiler_pop();
void _profiler_checkpoint(const char* name);
void _profiler_pop();
void profiler_print_stats();
void _profiler_print_stats();
void profiler_enable();
void profiler_disable();
void _profiler_enable();
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;
}
/* 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. */
@ -32,6 +31,8 @@ static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
static GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
static GLboolean POLYGON_OFFSET_ENABLED = GL_FALSE;
static GLboolean NORMALIZE_ENABLED = GL_FALSE;
GLboolean _glIsSharedTexturePaletteEnabled() {
@ -84,6 +85,9 @@ static GLenum BLEND_SFACTOR = GL_ONE;
static GLenum BLEND_DFACTOR = GL_ZERO;
static GLboolean BLEND_ENABLED = GL_FALSE;
static GLfloat OFFSET_FACTOR = 0.0f;
static GLfloat OFFSET_UNITS = 0.0f;
GLboolean _glIsNormalizeEnabled() {
return NORMALIZE_ENABLED;
}
@ -150,7 +154,7 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) {
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) {
const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1();
@ -187,6 +191,10 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
enableMipmaps = GL_TRUE;
}
if(tx1->height != tx1->width){
enableMipmaps = GL_FALSE;
}
if(enableMipmaps) {
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
filter = PVR_FILTER_TRILINEAR1;
@ -215,15 +223,13 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
context->txr.filter = filter;
context->txr.width = tx1->width;
context->txr.height = tx1->height;
context->txr.mipmap = enableMipmaps;
context->txr.mipmap_bias = tx1->mipmap_bias;
if(enableMipmaps) {
context->txr.base = tx1->data;
context->txr.mipmap = PVR_MIPMAP_ENABLE;
context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
} else {
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;
@ -338,6 +344,11 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
case GL_NEARZ_CLIPPING_KOS:
_glEnableClipping(GL_TRUE);
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:
NORMALIZE_ENABLED = GL_TRUE;
break;
@ -395,6 +406,11 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
case GL_NEARZ_CLIPPING_KOS:
_glEnableClipping(GL_FALSE);
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:
NORMALIZE_ENABLED = GL_FALSE;
break;
@ -423,18 +439,22 @@ GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
/* Depth Testing */
GLAPI void APIENTRY glClearDepthf(GLfloat depth) {
_GL_UNUSED(depth);
}
GLAPI void APIENTRY glClearDepth(GLfloat depth) {
_GL_UNUSED(depth);
}
GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
_GL_UNUSED(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) {
;
_GL_UNUSED(width);
}
void glPolygonOffset(GLfloat factor, GLfloat units) {
;
OFFSET_FACTOR = factor;
OFFSET_UNITS = units;
}
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) {
;
_GL_UNUSED(red);
_GL_UNUSED(green);
_GL_UNUSED(blue);
_GL_UNUSED(alpha);
}
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);
GLint miny, maxx, maxy;
GLsizei gl_scissor_width = CLAMP(width, 0, vid_mode->width);
GLsizei gl_scissor_height = CLAMP(height, 0, vid_mode->height);
GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 );
GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 );
/* force the origin to the lower left-hand corner of the screen */
miny = (vid_mode->height - gl_scissor_height) - y;
@ -567,6 +594,10 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) {
return LIGHTING_ENABLED;
case GL_BLEND:
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;
@ -581,7 +612,7 @@ static GLenum COMPRESSED_FORMATS [] = {
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) {
GLuint enabledAttrs = *_glGetEnabledAttributes();
@ -616,13 +647,19 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
switch(pname) {
case GL_PROJECTION_MATRIX:
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16);
memcpy4(params, _glGetProjectionMatrix(), sizeof(float) * 16);
break;
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;
default:
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv");
_glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError();
break;
}
@ -664,7 +701,7 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
}
} break;
default:
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv");
_glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError();
break;
}

View File

@ -9,12 +9,11 @@
#include "config.h"
#include "../include/glext.h"
#include "../include/glkos.h"
#include <kos/string.h>
#define CLAMP_U (1<<1)
#define CLAMP_V (1<<0)
#define MAX(x, y) ((x > y) ? x : y)
static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
static NamedArray TEXTURE_OBJECTS;
static GLubyte ACTIVE_TEXTURE = 0;
@ -31,7 +30,7 @@ static TexturePalette* _initTexturePalette() {
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
assert(palette);
memset(palette, 0x0, sizeof(TexturePalette));
memset4(palette, 0x0, sizeof(TexturePalette));
palette->bank = -1;
return palette;
}
@ -133,7 +132,7 @@ GLubyte _glGetActiveTexture() {
return ACTIVE_TEXTURE;
}
static GLint _determineStride(GLenum format, GLenum type) {
static GLint _determineStride(GLenum format, GLenum type) {
switch(type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
@ -155,7 +154,7 @@ static GLint _determineStride(GLenum format, GLenum type) {
return -1;
}
static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
static GLuint _glGetMipmapDataOffset(const TextureObject* obj, GLuint level) {
GLuint offset = 0;
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");
return obj->baseDataOffset;
}
if(obj->isPaletted){
switch(size >> level){
case 1024:
@ -200,8 +199,44 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
offset = 0x00003;
break;
}
} else {
switch(size >> level) {
} else if(obj->isCompressed) {
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:
offset = 0xAAAB0;
break;
@ -241,12 +276,12 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
return offset;
}
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level) {
GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level) {
return ((GLubyte*) obj->data) + _glGetMipmapDataOffset(obj, level);
}
GLuint _glGetMipmapLevelCount(TextureObject* obj) {
return 1 + floor(log2(MAX(obj->width, obj->height)));
GLuint _glGetMipmapLevelCount(const TextureObject* obj) {
return 1 + floorf(log2f(MAX(obj->width, obj->height)));
}
static GLuint _glGetMipmapDataSize(TextureObject* obj) {
@ -318,6 +353,7 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
txr->palette = NULL;
txr->isCompressed = GL_FALSE;
txr->isPaletted = GL_FALSE;
txr->mipmap_bias = GL_MAX_TEXTURE_LOD_BIAS_DEFAULT;
/* Not mipmapped by default */
txr->baseDataOffset = 0;
@ -403,18 +439,13 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
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;
GLint target_values [] = {GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL_EXT, 0};
failures += _glCheckValidEnum(target, target_values, __func__);
failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += _glCheckValidEnum(param, param_values, __func__);
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
if(!active) {
return;
}
@ -422,19 +453,47 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
if(failures) {
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) {
case GL_MODULATE:
active->env = PVR_TXRENV_MODULATE;
break;
case GL_DECAL:
active->env = PVR_TXRENV_DECAL;
break;
case GL_REPLACE:
active->env = PVR_TXRENV_REPLACE;
break;
default:
break;
switch(param) {
case GL_MODULATE:
active->env = PVR_TXRENV_MODULATEALPHA;
break;
case GL_DECAL:
active->env = PVR_TXRENV_DECAL;
break;
case GL_REPLACE:
active->env = PVR_TXRENV_REPLACE;
break;
default:
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) {
switch (internalFormat) {
case GL_COLOR_INDEX4_EXT:
return GL_COLOR_INDEX4_EXT;
case GL_COLOR_INDEX8_EXT:
return GL_COLOR_INDEX8_EXT;
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
* 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;
case GL_COLOR_INDEX8_EXT:
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
case GL_COLOR_INDEX4_EXT:
return PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_TWIDDLED;
default:
return 0;
}
@ -676,11 +739,11 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
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;
}
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */
GLubyte* dst = (GLubyte*) dest;
dst[0] = source[0];
@ -689,11 +752,11 @@ static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
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);
}
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
GL_FORCE_INLINE void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */
GLubyte* dst = (GLubyte*) dest;
dst[0] = source[0];
@ -702,24 +765,24 @@ static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
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);
}
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);
}
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;
}
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*) 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);
GLubyte* dst = (GLubyte*) dest;
@ -729,7 +792,7 @@ static inline void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
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 */
GLubyte* dst = (GLubyte*) dest;
*dst = *source;
@ -880,72 +943,93 @@ void _glAllocateSpaceForMipmaps(TextureObject* active) {
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,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *data) {
TRACE();
if(target != GL_TEXTURE_2D) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
if(format != GL_COLOR_INDEX) {
if(!_isSupportedFormat(format)) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
/* Abuse determineStride to see if type is valid */
if(_determineStride(GL_RGBA, type) == -1) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
internalFormat = _cleanInternalFormat(internalFormat);
if(internalFormat == -1) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
}
} else {
if(internalFormat != GL_COLOR_INDEX8_EXT) {
INFO_MSG("");
_glKosThrowError(GL_INVALID_ENUM, __func__);
}
}
GLint w = width;
if(w < 8 || (w & -w) != w) {
/* Width is not a power of two. Must be!*/
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
}
GLuint w = width;
GLuint h = height;
if(level == 0){
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) {
/* height is not a power of two. Must be!*/
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
if((h < 8 || (h & -h) != h)) {
/* height is not a power of two. Must be!*/
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) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
}
if(level > 0 && width != height) {
INFO_MSG("");
fprintf(stderr, "[GL ERROR] Mipmaps cannot be supported on non-square textures\n");
_glKosThrowError(GL_INVALID_OPERATION, __func__);
}
if(border) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
INFO_MSG("");
_glKosThrowError(GL_INVALID_VALUE, __func__);
}
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
INFO_MSG("");
_glKosThrowError(GL_INVALID_OPERATION, __func__);
}
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()) {
_glKosPrintError();
return;
@ -958,7 +1042,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
assert(active);
if(active->data && level == 0) {
if(active->data && (level == 0)) {
/* pre-existing texture - check if changed */
if(active->width != width ||
active->height != height ||
@ -968,6 +1052,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
active->data = NULL;
active->mipmap = 0;
active->mipmapCount = 0;
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
active->dataStride = 0;
active->baseDataOffset = 0;
active->baseDataSize = 0;
@ -992,6 +1077,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
active->color = pvr_format;
/* Set the required mipmap count */
active->mipmapCount = _glGetMipmapLevelCount(active);
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
active->dataStride = destStride;
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) {
_GL_UNUSED(target);
_GL_UNUSED(start);
_GL_UNUSED(count);
_GL_UNUSED(format);
_GL_UNUSED(type);
_GL_UNUSED(data);
_glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError();
}
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__);
_glKosPrintError();
}
GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params) {
_GL_UNUSED(target);
_GL_UNUSED(pname);
_GL_UNUSED(params);
_glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError();
}
GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params) {
_GL_UNUSED(target);
_GL_UNUSED(pname);
_GL_UNUSED(params);
_glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError();
}
@ -1358,24 +1460,70 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G
GLAPI void APIENTRY glTexSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset,
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) {
_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) {
_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) {
_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) {
_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) {
_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>
#endif
#include "../GL/private.h"
#include "aligned_vector.h"
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);
}
static inline unsigned int round_to_chunk_size(unsigned int val) {
const unsigned int n = val;
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;
}
void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
if(element_count == 0) {
return;
@ -54,7 +53,7 @@ void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
assert(vector->data);
if(original_data) {
memcpy(vector->data, original_data, original_byte_size);
FASTCPY(vector->data, original_data, original_byte_size);
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);
/* Copy the objects in */
memcpy(dest, objs, vector->element_size * count);
FASTCPY(dest, objs, vector->element_size * count);
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) {
const unsigned int current = vector->size;
aligned_vector_resize(vector, vector->size + additional_count);
return aligned_vector_at(vector, current);
}
void aligned_vector_clear(AlignedVector* vector) {
vector->size = 0;
}
void aligned_vector_shrink_to_fit(AlignedVector* vector) {
if(vector->size == 0) {
free(vector->data);
@ -131,7 +117,7 @@ void aligned_vector_shrink_to_fit(AlignedVector* vector) {
vector->data = (unsigned char*) memalign(0x20, new_byte_size);
if(original_data) {
memcpy(vector->data, original_data, new_byte_size);
FASTCPY(vector->data, original_data, new_byte_size);
free(original_data);
}

View File

@ -1,3 +1,5 @@
#pragma once
#ifndef ALIGNED_VECTOR_H
#define ALIGNED_VECTOR_H
@ -5,6 +7,8 @@
extern "C" {
#endif
#include <assert.h>
typedef struct {
unsigned int size;
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_push_back(AlignedVector* vector, const void* objs, unsigned int 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_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_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
}

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.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->max_element_count = max_elements;
float c = (float) max_elements / 8.0f;
array->marker_count = (unsigned char) ceil(c);
array->marker_count = (unsigned char)((max_elements+8-1)/8);
#ifdef _arch_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);
}
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) {
unsigned int i = 0, j = 0;
for(i = 0; i < array->marker_count; ++i) {

View File

@ -1,3 +1,5 @@
#pragma once
#ifndef NAMED_ARRAY_H
#define NAMED_ARRAY_H
@ -5,6 +7,8 @@
extern "C" {
#endif
#include "../GL/private.h"
typedef struct {
unsigned int element_size;
unsigned int max_element_count;
@ -14,7 +18,13 @@ typedef struct {
} NamedArray;
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_reserve(NamedArray* array, unsigned int id);

View File

@ -362,6 +362,27 @@ __BEGIN_DECLS
#define GL_RGBA12 0x805A
#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 GLshort short
#define GLint int
@ -471,6 +492,7 @@ GLAPI void APIENTRY glClearDepthf(GLfloat depth);
GLAPI void APIENTRY glDepthMask(GLboolean flag);
GLAPI void APIENTRY glDepthFunc(GLenum func);
GLAPI void APIENTRY glDepthRange(GLclampf n, GLclampf f);
GLAPI void APIENTRY glDepthRangef(GLclampf n, GLclampf f);
/* Hints */
/* Currently Supported Capabilities:

View File

@ -190,6 +190,21 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target,
#define glGenerateMipmap glGenerateMipmapEXT
#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
#endif /* !__GL_GLEXT_H */