Start refactoring everything

This commit is contained in:
Luke Benstead 2026-02-23 21:41:00 +00:00
parent ba10615722
commit cb3153d763
12 changed files with 400 additions and 261 deletions

View File

@ -169,104 +169,117 @@ static ReadAttributeFunc calcReadPositionFunc(void) {
static void _fillWhiteARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
_GL_UNUSED(input);
*((uint32_t*) output) = ~0;
float* o = (float*) output;
o[0] = 1.0f;
o[1] = 1.0f;
o[2] = 1.0f;
o[3] = 1.0f;
}
static void _readColour4ubARGB(const GLubyte* input, GLubyte* output) {
output[R8IDX] = input[0];
output[G8IDX] = input[1];
output[B8IDX] = input[2];
output[A8IDX] = input[3];
float* o = (float*) output;
const float f = 1.0f / 255.0f;
o[R8IDX] = ((float)input[0]) * f;
o[G8IDX] = ((float)input[1]) * f;
o[B8IDX] = ((float)input[2]) * f;
o[A8IDX] = ((float)input[3]) * f;
}
static void _readColour3ubARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
output[R8IDX] = input[0];
output[G8IDX] = input[1];
output[B8IDX] = input[2];
output[A8IDX] = 255;
float* o = (float*) output;
const float f = 1.0f / 255.0f;
o[R8IDX] = ((float)input[0]) * f;
o[G8IDX] = ((float)input[1]) * f;
o[B8IDX] = ((float)input[2]) * f;
o[A8IDX] = 1.0f;
}
#define DEF_READ_COLOUR_4_ARGB_FP(prefix, intype) \
static void _readColour##prefix##ARGB(const GLubyte* __restrict in, GLubyte* __restrict out) { \
const intype* input = (const intype*) in; \
out[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255); \
out[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255); \
out[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255); \
out[A8IDX] = (GLubyte) clamp(input[3] * 255.0f, 0, 255); \
float* o = (float*) out; \
o[R8IDX] = input[0]; \
o[G8IDX] = input[1]; \
o[B8IDX] = input[2]; \
o[A8IDX] = input[3]; \
}
#define DEF_READ_COLOUR_3_ARGB_FP(prefix, intype) \
static void _readColour##prefix##ARGB(const GLubyte* __restrict in, GLubyte* __restrict out) { \
const intype* input = (const intype*) in; \
out[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255); \
out[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255); \
out[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255); \
out[A8IDX] = 255; \
float* o = (float*) out; \
o[R8IDX] = input[0]; \
o[G8IDX] = input[1]; \
o[B8IDX] = input[2]; \
o[A8IDX] = 1.0f; \
}
DEF_READ_COLOUR_4_ARGB_FP(4f, float)
DEF_READ_COLOUR_3_ARGB_FP(3f, float)
static void _readColour4dARGB(const GLubyte* __restrict__ in, GLubyte* __restrict__ out) {
const double* input = (const double*) in;
// Convert to float first
// Convert to float first
float r = (float)input[0];
float g = (float)input[1];
float b = (float)input[2];
float b = (float)input[2];
float a = (float)input[3];
out[R8IDX] = (GLubyte) clamp(r * 255.0f, 0, 255);
out[G8IDX] = (GLubyte) clamp(g * 255.0f, 0, 255);
out[B8IDX] = (GLubyte) clamp(b * 255.0f, 0, 255);
out[A8IDX] = (GLubyte) clamp(a * 255.0f, 0, 255);
out[R8IDX] = r;
out[G8IDX] = g;
out[B8IDX] = b;
out[A8IDX] = a;
}
static void _readColour3dARGB(const GLubyte* __restrict__ in, GLubyte* __restrict__ out) {
const double* input = (const double*) in;
// Convert to float first
// Convert to float first
float r = (float)input[0];
float g = (float)input[1];
float b = (float)input[2];
out[R8IDX] = (GLubyte) clamp(r * 255.0f, 0, 255);
out[G8IDX] = (GLubyte) clamp(g * 255.0f, 0, 255);
out[B8IDX] = (GLubyte) clamp(b * 255.0f, 0, 255);
out[R8IDX] = r;
out[G8IDX] = g;
out[B8IDX] = b;
out[A8IDX] = 255;
}
static void _readColour4ubRevARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
argbcpy(output, input);
const float f = 1.0f / 255.0f;
float* o = (float*) output;
o[0] = ((float) input[3]) * f;
o[1] = ((float) input[2]) * f;
o[2] = ((float) input[1]) * f;
o[3] = ((float) input[0]) * f;
}
static void _readColour4fRevARGB(const GLubyte* __restrict__ in, GLubyte* __restrict__ output) {
const float* input = (const float*) in;
output[0] = (GLubyte) clamp(input[0] * 255.0f, 0, 255);
output[1] = (GLubyte) clamp(input[1] * 255.0f, 0, 255);
output[2] = (GLubyte) clamp(input[2] * 255.0f, 0, 255);
output[3] = (GLubyte) clamp(input[3] * 255.0f, 0, 255);
output[0] = input[0];
output[1] = input[1];
output[2] = input[2];
output[3] = input[3];
}
static void _readColour4dRevARGB(const GLubyte* __restrict__ in, GLubyte* __restrict__ output) {
const double* input = (const double*) in;
// Convert to float first
// Convert to float first
float r = (float)input[0];
float g = (float)input[1];
float b = (float)input[2];
float a = (float)input[3];
output[0] = (GLubyte) clamp(r * 255.0f, 0, 255);
output[1] = (GLubyte) clamp(g * 255.0f, 0, 255);
output[2] = (GLubyte) clamp(b * 255.0f, 0, 255);
output[3] = (GLubyte) clamp(a * 255.0f, 0, 255);
output[0] = r;
output[1] = g;
output[2] = b;
output[3] = a;
}
#define DEF_READ_COLOUR_N_ARGB_INT(prefix, intype, max, alpha, i0, i1, i2, i3) \
@ -301,7 +314,7 @@ DEF_READ_COLOUR_4_REV_ARGB_INT(4us, GLushort, UINT16_MAX)
DEF_READ_COLOUR_4_REV_ARGB_INT(4ui, GLuint, UINT32_MAX)
static ReadAttributeFunc calcReadDiffuseFunc(void) {
if((ATTRIB_LIST.enabled & DIFFUSE_ENABLED_FLAG) != DIFFUSE_ENABLED_FLAG) {
if((ATTRIB_LIST.enabled & COLOR_ENABLED_FLAG) != COLOR_ENABLED_FLAG) {
/* Just fill the whole thing white if the attribute is disabled */
return _fillWhiteARGB;
}
@ -334,6 +347,39 @@ static ReadAttributeFunc calcReadDiffuseFunc(void) {
}
}
static ReadAttributeFunc calcReadSecondaryFunc(void) {
if((ATTRIB_LIST.enabled & S_COLOR_ENABLED_FLAG) != S_COLOR_ENABLED_FLAG) {
/* Just fill the whole thing white if the attribute is disabled */
return _fillWhiteARGB;
}
switch(ATTRIB_LIST.s_color.type) {
case GL_DOUBLE:
return (ATTRIB_LIST.s_color.size == 3) ? _readColour3dARGB:
(ATTRIB_LIST.s_color.size == 4) ? _readColour4dARGB:
_readColour4dRevARGB;
default:
case GL_FLOAT:
return (ATTRIB_LIST.s_color.size == 3) ? _readColour3fARGB:
(ATTRIB_LIST.s_color.size == 4) ? _readColour4fARGB:
_readColour4fRevARGB;
case GL_BYTE:
case GL_UNSIGNED_BYTE:
return (ATTRIB_LIST.s_color.size == 3) ? _readColour3ubARGB:
(ATTRIB_LIST.s_color.size == 4) ? _readColour4ubARGB:
_readColour4ubRevARGB;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
return (ATTRIB_LIST.s_color.size == 3) ? _readColour3usARGB:
(ATTRIB_LIST.s_color.size == 4) ? _readColour4usARGB:
_readColour4usRevARGB;
case GL_INT:
case GL_UNSIGNED_INT:
return (ATTRIB_LIST.s_color.size == 3) ? _readColour3uiARGB:
(ATTRIB_LIST.s_color.size == 4) ? _readColour4uiARGB:
_readColour4uiRevARGB;
}
}
static void _fillZero2f(const GLubyte* __restrict__ input, GLubyte* __restrict__ out) {
_GL_UNUSED(input);
@ -531,8 +577,8 @@ void APIENTRY glEnableClientState(GLenum cap) {
ATTRIB_LIST.dirty |= VERTEX_ENABLED_FLAG;
break;
case GL_COLOR_ARRAY:
ATTRIB_LIST.enabled |= DIFFUSE_ENABLED_FLAG;
ATTRIB_LIST.dirty |= DIFFUSE_ENABLED_FLAG;
ATTRIB_LIST.enabled |= COLOR_ENABLED_FLAG;
ATTRIB_LIST.dirty |= COLOR_ENABLED_FLAG;
break;
case GL_NORMAL_ARRAY:
ATTRIB_LIST.enabled |= NORMAL_ENABLED_FLAG;
@ -561,8 +607,8 @@ void APIENTRY glDisableClientState(GLenum cap) {
ATTRIB_LIST.dirty |= VERTEX_ENABLED_FLAG;
break;
case GL_COLOR_ARRAY:
ATTRIB_LIST.enabled &= ~DIFFUSE_ENABLED_FLAG;
ATTRIB_LIST.dirty |= DIFFUSE_ENABLED_FLAG;
ATTRIB_LIST.enabled &= ~COLOR_ENABLED_FLAG;
ATTRIB_LIST.dirty |= COLOR_ENABLED_FLAG;
break;
case GL_NORMAL_ARRAY:
ATTRIB_LIST.enabled &= ~NORMAL_ENABLED_FLAG;
@ -643,7 +689,27 @@ void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const G
ATTRIB_LIST.colour.size = size;
ATTRIB_LIST.colour.stride = stride;
ATTRIB_LIST.dirty |= DIFFUSE_ENABLED_FLAG;
ATTRIB_LIST.dirty |= COLOR_ENABLED_FLAG;
}
void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
TRACE();
stride = (stride) ? stride : ((size == GL_BGRA) ? 4 : size) * byte_size(type);
ATTRIB_LIST.s_color.ptr = pointer;
if(_glStateUnchanged(&ATTRIB_LIST.s_color, size, type, stride)) return;
if(size != 3 && size != 4 && size != GL_BGRA) {
_glKosThrowError(GL_INVALID_VALUE, __func__);
return;
}
ATTRIB_LIST.s_color.type = type;
ATTRIB_LIST.s_color.size = size;
ATTRIB_LIST.s_color.stride = stride;
ATTRIB_LIST.dirty |= S_COLOR_ENABLED_FLAG;
}
void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {
@ -713,13 +779,19 @@ GL_FORCE_INLINE GLuint _glIsVertexDataFastPathCompatible(void) {
}
}
if((ATTRIB_LIST.enabled & DIFFUSE_ENABLED_FLAG)) {
if((ATTRIB_LIST.enabled & COLOR_ENABLED_FLAG)) {
/* FIXME: Shouldn't this be a reversed format? */
if(ATTRIB_LIST.colour.size != GL_BGRA || ATTRIB_LIST.colour.type != GL_UNSIGNED_BYTE) {
return GL_FALSE;
}
}
if((ATTRIB_LIST.enabled & S_COLOR_ENABLED_FLAG)) {
if(ATTRIB_LIST.s_color.size != GL_BGRA || ATTRIB_LIST.s_color.type != GL_UNSIGNED_BYTE) {
return GL_FALSE;
}
}
if((ATTRIB_LIST.enabled & ST_ENABLED_FLAG)) {
if(ATTRIB_LIST.st.size != 2 || ATTRIB_LIST.st.type != GL_FLOAT) {
return GL_FALSE;
@ -744,10 +816,14 @@ void _glUpdateAttributes(void) {
ATTRIB_LIST.uv_func = calcReadUVFunc();
}
if(ATTRIB_LIST.dirty & DIFFUSE_ENABLED_FLAG) {
if(ATTRIB_LIST.dirty & COLOR_ENABLED_FLAG) {
ATTRIB_LIST.colour_func = calcReadDiffuseFunc();
}
if(ATTRIB_LIST.dirty & S_COLOR_ENABLED_FLAG) {
ATTRIB_LIST.s_color_func = calcReadSecondaryFunc();
}
if(ATTRIB_LIST.dirty & ST_ENABLED_FLAG) {
ATTRIB_LIST.st_func = calcReadSTFunc();
}
@ -758,4 +834,4 @@ void _glUpdateAttributes(void) {
ATTRIB_LIST.fast_path = _glIsVertexDataFastPathCompatible();
ATTRIB_LIST.dirty = 0;
}
}

View File

@ -199,7 +199,7 @@ static GL_NO_INLINE void genPoints(Vertex* output, GLuint count) {
static Vertex* draw_line(Vertex* dst, Vertex* v1, Vertex* v2) {
Vertex ov1 = *v1;
Vertex ov2 = *v2;
// TODO don't copy unless dst might overlap v1/v2
// TODO don't copy unless dst might overlap v1/v2
// Essentially "expands" a line into a quad by
// 1) Calculating normal of the line from v1 to v2
@ -263,7 +263,7 @@ static GL_NO_INLINE void genLineLoop(Vertex* output, GLuint count) {
Vertex* dst = output + LINE_LOOP_COUNT(count) - 1;
Vertex* src = output + count - 1;
Vertex last = *src, first = *output;
// Draws line using current and prior vertex
for (; count > 1; count--, src--) {
dst = draw_line(dst, src, src - 1);
@ -302,30 +302,37 @@ static void _readUVData(const GLuint first, const GLuint count, Vertex* it) {
}
}
static void _readSTData(const GLuint first, const GLuint count, VertexExtra* it) {
static void _readSTData(const GLuint first, const GLuint count, Vertex* it) {
const ReadAttributeFunc func = ATTRIB_LIST.st_func;
const GLsizei ststride = ATTRIB_LIST.st.stride;
const GLubyte* stptr = ((GLubyte*) ATTRIB_LIST.st.ptr + (first * ststride));
float temp[2];
ITERATE(count) {
PREFETCH(stptr + ststride);
func(stptr, (GLubyte*) it->st);
func(stptr, (GLubyte*) temp);
stptr += ststride;
it->st[0] = pack_half_float(temp[0]);
it->st[1] = pack_half_float(temp[1]);
++it;
}
}
static void _readNormalData(const GLuint first, const GLuint count, VertexExtra* it) {
static void _readNormalData(const GLuint first, const GLuint count, Vertex* it) {
const ReadAttributeFunc func = ATTRIB_LIST.normal_func;
const GLsizei nstride = ATTRIB_LIST.normal.stride;
const GLubyte* nptr = ((GLubyte*) ATTRIB_LIST.normal.ptr + (first * nstride));
GLfloat n[3];
ITERATE(count) {
func(nptr, (GLubyte*) it->nxyz);
func(nptr, (GLubyte*) n);
nptr += nstride;
if(_glIsNormalizeEnabled()) {
GLfloat* n = (GLfloat*) it->nxyz;
float temp = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
float ilength = MATH_fsrra(temp);
@ -334,6 +341,7 @@ static void _readNormalData(const GLuint first, const GLuint count, VertexExtra*
n[2] *= ilength;
}
it->nxyz = _glPackNormal(n);
++it;
}
}
@ -345,7 +353,7 @@ static void _readDiffuseData(const GLuint first, const GLuint count, Vertex* it)
ITERATE(count) {
PREFETCH(cptr + cstride);
func(cptr, it->bgra);
func(cptr, (GLubyte*) it->argb);
cptr += cstride;
++it;
}
@ -365,7 +373,6 @@ static void generateElements(
GLubyte* nxyz;
Vertex* output = _glSubmissionTargetStart(target);
VertexExtra* ve = aligned_vector_at(target->extras, 0);
uint32_t i = first;
uint32_t idx = 0;
@ -385,6 +392,8 @@ static void generateElements(
const ReadAttributeFunc normal_func = ATTRIB_LIST.normal_func;
const GLuint nstride = ATTRIB_LIST.normal.stride;
float temp[3];
for(; i < first + count; ++i) {
idx = IndexFunc(indices + (i * istride));
@ -396,13 +405,17 @@ static void generateElements(
pos_func(xyz, (GLubyte*) output);
uv_func(uv, (GLubyte*) output->uv);
diffuse_func(bgra, output->bgra);
st_func(st, (GLubyte*) ve->st);
normal_func(nxyz, (GLubyte*) ve->nxyz);
diffuse_func(bgra, (GLubyte*) output->argb);
st_func(st, (GLubyte*) temp);
output->st[0] = pack_half_float(temp[0]);
output->st[1] = pack_half_float(temp[1]);
normal_func(nxyz, (GLubyte*) temp);
output->nxyz = _glPackNormal(temp);
output->flags = GPU_CMD_VERTEX;
++output;
++ve;
}
}
@ -414,8 +427,13 @@ typedef struct {
float u, v;
} Float2;
typedef struct {
float a, r, g, b;
} Float4;
static const Float3 F3Z = {0.0f, 0.0f, 1.0f};
static const Float2 F2ZERO = {0.0f, 0.0f};
static const Float4 F4ZERO = {0.0f, 0.0f, 0.0f, 0.0f};
static void generateElementsFastPath(
SubmissionTarget* target, const GLsizei first, const GLuint count,
@ -435,11 +453,10 @@ static void generateElementsFastPath(
/* Copy the pos, uv and color directly in one go */
const GLubyte* pos = (ATTRIB_LIST.enabled & VERTEX_ENABLED_FLAG) ? ATTRIB_LIST.vertex.ptr : NULL;
const GLubyte* uv = (ATTRIB_LIST.enabled & UV_ENABLED_FLAG) ? ATTRIB_LIST.uv.ptr : NULL;
const GLubyte* col = (ATTRIB_LIST.enabled & DIFFUSE_ENABLED_FLAG) ? ATTRIB_LIST.colour.ptr : NULL;
const GLubyte* col = (ATTRIB_LIST.enabled & COLOR_ENABLED_FLAG) ? ATTRIB_LIST.colour.ptr : NULL;
const GLubyte* st = (ATTRIB_LIST.enabled & ST_ENABLED_FLAG) ? ATTRIB_LIST.st.ptr : NULL;
const GLubyte* n = (ATTRIB_LIST.enabled & NORMAL_ENABLED_FLAG) ? ATTRIB_LIST.normal.ptr : NULL;
VertexExtra* ve = aligned_vector_at(target->extras, 0);
Vertex* it = start;
if(!pos) {
@ -463,27 +480,29 @@ static void generateElementsFastPath(
if(col) {
col = (GLubyte*) ATTRIB_LIST.colour.ptr + (idx * dstride);
MEMCPY4(it->bgra, col, sizeof(uint32_t));
MEMCPY4(it->argb, col, sizeof(float) * 4);
} else {
*((uint32_t*) it->bgra) = ~0;
*((Float4*) it->argb) = F4ZERO;
}
if(st) {
st = (GLubyte*) ATTRIB_LIST.st.ptr + (idx * ststride);
MEMCPY4(ve->st, st, sizeof(float) * 2);
it->st[0] = pack_half_float(st[0]);
it->st[1] = pack_half_float(st[1]);
} else {
*((Float2*) ve->st) = F2ZERO;
it->st[0] = 0.0f;
it->st[1] = 0.0f;
}
if(n) {
n = (GLubyte*) ATTRIB_LIST.normal.ptr + (idx * nstride);
MEMCPY4(ve->nxyz, n, sizeof(float) * 3);
it->nxyz = _glPackNormal((float*) n);
} else {
*((Float3*) ve->nxyz) = F3Z;
float nxyz[3] = {0.0f, 0.0f, 1.0f};
it->nxyz = _glPackNormal(nxyz);
}
it++;
ve++;
}
}
@ -523,13 +542,12 @@ static void generateElementsFastPath(
static void generateArrays(SubmissionTarget* target, const GLsizei first, const GLuint count) {
Vertex* start = _glSubmissionTargetStart(target);
VertexExtra* ve = aligned_vector_at(target->extras, 0);
_readPositionData(first, count, start);
_readDiffuseData(first, count, start);
_readUVData(first, count, start);
_readNormalData(first, count, ve);
_readSTData(first, count, ve);
_readNormalData(first, count, start);
_readSTData(first, count, start);
}
static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei first, const GLuint count,
@ -644,9 +662,9 @@ GL_FORCE_INLINE void apply_poly_header(PolyHeader* header, GLboolean multiTextur
memset(&ctx, 0, sizeof(PolyContext));
ctx.list_type = activePolyList->list_type;
ctx.fmt.color = GPU_CLRFMT_ARGBPACKED;
ctx.fmt.color = GPU_CLRFMT_4FLOATS;
ctx.fmt.uv = GPU_UVFMT_32BIT;
ctx.gen.color_clamp = GPU_CLRCLAMP_DISABLE;
ctx.gen.color_clamp = GPU_CLRCLAMP_ENABLE;
ctx.gen.culling = _calc_pvr_face_culling();
ctx.depth.comparison = _calc_pvr_depth_test();
@ -732,13 +750,9 @@ static SubmissionTarget SUBMISSION_TARGET;
void _glInitSubmissionTarget() {
SubmissionTarget* target = &SUBMISSION_TARGET;
target->extras = NULL;
target->count = 0;
target->output = NULL;
target->header_offset = target->start_offset = 0;
aligned_vector_init(&VERTEX_EXTRAS, sizeof(VertexExtra));
target->extras = &VERTEX_EXTRAS;
}
GL_FORCE_INLINE GLuint calcFinalVertices(GLenum mode, GLuint count) {
@ -761,8 +775,6 @@ GL_FORCE_INLINE GLuint calcFinalVertices(GLenum mode, GLuint count) {
GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type, const GLvoid* indices) {
SubmissionTarget* const target = &SUBMISSION_TARGET;
AlignedVector* const extras = target->extras;
TRACE();
/* Do nothing if vertices aren't enabled */
@ -794,7 +806,6 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
target->output = _glActivePolyList();
gl_assert(target->output);
gl_assert(extras);
uint32_t vector_size = aligned_vector_size(&target->output->vector);
@ -807,9 +818,6 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
gl_assert(target->start_offset >= target->header_offset);
gl_assert(target->count);
/* Make sure we have enough room for all the "extra" data */
aligned_vector_resize(extras, target->count);
/* Make room for the vertices and header */
aligned_vector_extend(&target->output->vector, target->count + (header_required));

View File

@ -20,7 +20,6 @@ MAKE_FUNC(POLYMODE)
GLuint stride;
const GLubyte* ptr;
Vertex* it;
VertexExtra* ve;
for(min = 0; min < count; min += BATCH_SIZE) {
@ -48,22 +47,25 @@ MAKE_FUNC(POLYMODE)
}
stride = ATTRIB_LIST.colour.stride;
ptr = (ATTRIB_LIST.enabled & DIFFUSE_ENABLED_FLAG) ? ATTRIB_LIST.colour.ptr + (offset * stride) : NULL;
ptr = (ATTRIB_LIST.enabled & COLOR_ENABLED_FLAG) ? ATTRIB_LIST.colour.ptr + (offset * stride) : NULL;
it = (Vertex*) start;
if(ptr) {
PREFETCH(ptr);
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
PREFETCH(ptr + stride);
it->bgra[0] = ptr[0];
it->bgra[1] = ptr[1];
it->bgra[2] = ptr[2];
it->bgra[3] = ptr[3];
it->argb[0] = ptr[0];
it->argb[1] = ptr[1];
it->argb[2] = ptr[2];
it->argb[3] = ptr[3];
ptr += stride;
}
} else {
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
*((uint32_t*) it->bgra) = ~0;
it->argb[0] = 0.0f;
it->argb[1] = 0.0f;
it->argb[2] = 0.0f;
it->argb[3] = 0.0f;
}
}
@ -79,47 +81,42 @@ MAKE_FUNC(POLYMODE)
ptr += stride;
}
start = aligned_vector_at(target->extras, min);
stride = ATTRIB_LIST.st.stride;
ptr = (ATTRIB_LIST.enabled & ST_ENABLED_FLAG) ? ATTRIB_LIST.st.ptr + (offset * stride) : NULL;
ve = (VertexExtra*) start;
it = (Vertex*) start;
if(ptr) {
PREFETCH(ptr);
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
PREFETCH(ptr + stride);
ve->st[0] = ((float*) ptr)[0];
ve->st[1] = ((float*) ptr)[1];
it->st[0] = pack_half_float(((float*) ptr)[0]);
it->st[1] = pack_half_float(((float*) ptr)[1]);
ptr += stride;
}
} else {
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
ve->st[0] = 0;
ve->st[1] = 0;
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
it->st[0] = pack_half_float(0.0f);
it->st[1] = pack_half_float(0.0f);
}
}
stride = ATTRIB_LIST.normal.stride;
ptr = (ATTRIB_LIST.enabled & NORMAL_ENABLED_FLAG) ? ATTRIB_LIST.normal.ptr + (offset * stride) : NULL;
ve = (VertexExtra*) start;
it = (Vertex*) start;
if(ptr) {
PREFETCH(ptr);
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
PREFETCH(ptr + stride);
ve->nxyz[0] = ((float*) ptr)[0];
ve->nxyz[1] = ((float*) ptr)[1];
ve->nxyz[2] = ((float*) ptr)[2];
it->nxyz = _glPackNormal((float*) ptr);
ptr += stride;
}
} else {
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
ve->nxyz[0] = 0;
ve->nxyz[1] = 0;
ve->nxyz[2] = 0;
float nxyz[3] = {0.0f, 0.0f, 1.0f};
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
it->nxyz = _glPackNormal(nxyz);
}
}
}

View File

@ -16,7 +16,7 @@ GLboolean IMMEDIATE_MODE_ACTIVE = GL_FALSE;
static GLenum ACTIVE_POLYGON_MODE = GL_TRIANGLES;
static GLfloat __attribute__((aligned(32))) NORMAL[3] = {0.0f, 0.0f, 1.0f};
static GLubyte __attribute__((aligned(32))) COLOR[4] = {255, 255, 255, 255}; /* ARGB order for speed */
static GLfloat __attribute__((aligned(32))) COLOR[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* ARGB order for speed */
static GLfloat __attribute__((aligned(32))) UV_COORD[2] = {0.0f, 0.0f};
static GLfloat __attribute__((aligned(32))) ST_COORD[2] = {0.0f, 0.0f};
@ -65,11 +65,11 @@ void _glInitImmediateMode(GLuint initial_size) {
IM_ATTRIBS.st.size = 2;
IM_ATTRIBS.colour.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7);
IM_ATTRIBS.colour.size = GL_BGRA; /* Flipped color order */
IM_ATTRIBS.colour.type = GL_UNSIGNED_BYTE;
IM_ATTRIBS.colour.size = 4;
IM_ATTRIBS.colour.type = GL_FLOAT;
IM_ATTRIBS.colour.stride = sizeof(IMVertex);
IM_ATTRIBS.normal.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7) + sizeof(uint32_t);
IM_ATTRIBS.normal.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 11);
IM_ATTRIBS.normal.stride = sizeof(IMVertex);
IM_ATTRIBS.normal.type = GL_FLOAT;
IM_ATTRIBS.normal.size = 3;
@ -86,16 +86,7 @@ void APIENTRY glBegin(GLenum mode) {
}
void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
COLOR[A8IDX] = (GLubyte)(a * 255.0f);
COLOR[R8IDX] = (GLubyte)(r * 255.0f);
COLOR[G8IDX] = (GLubyte)(g * 255.0f);
COLOR[B8IDX] = (GLubyte)(b * 255.0f);
}
void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[A8IDX] = a;
COLOR[R8IDX] = r;
@ -103,58 +94,74 @@ void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
COLOR[B8IDX] = b;
}
void APIENTRY glColor4ubv(const GLubyte *v) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[A8IDX] = v[3];
COLOR[R8IDX] = v[0];
COLOR[G8IDX] = v[1];
COLOR[B8IDX] = v[2];
const float m = 1.0f / 255.0f;
COLOR[A8IDX] = ((float)a) * m;
COLOR[R8IDX] = ((float)r) * m;
COLOR[G8IDX] = ((float)g) * m;
COLOR[B8IDX] = ((float)b) * m;
}
void APIENTRY glColor4ubv(const GLubyte *v) {
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
const float m = 1.0f / 255.0f;
COLOR[A8IDX] = ((float) v[3]) * m;
COLOR[R8IDX] = ((float) v[0]) * m;
COLOR[G8IDX] = ((float) v[1]) * m;
COLOR[B8IDX] = ((float) v[2]) * m;
}
void APIENTRY glColor4fv(const GLfloat* v) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[B8IDX] = (GLubyte)(v[2] * 255);
COLOR[G8IDX] = (GLubyte)(v[1] * 255);
COLOR[R8IDX] = (GLubyte)(v[0] * 255);
COLOR[A8IDX] = (GLubyte)(v[3] * 255);
COLOR[B8IDX] = v[2];
COLOR[G8IDX] = v[1];
COLOR[R8IDX] = v[0];
COLOR[A8IDX] = v[3];
}
void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[B8IDX] = (GLubyte)(b * 255.0f);
COLOR[G8IDX] = (GLubyte)(g * 255.0f);
COLOR[R8IDX] = (GLubyte)(r * 255.0f);
COLOR[A8IDX] = 255;
COLOR[B8IDX] = b;
COLOR[G8IDX] = g;
COLOR[R8IDX] = r;
COLOR[A8IDX] = 1.0f;
}
void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[A8IDX] = 255;
COLOR[R8IDX] = red;
COLOR[G8IDX] = green;
COLOR[B8IDX] = blue;
const float m = 1.0f / 255.0f;
COLOR[A8IDX] = 1.0f;
COLOR[R8IDX] = ((float) red) * m;
COLOR[G8IDX] = ((float) green) * m;
COLOR[B8IDX] = ((float) blue) * m;
}
void APIENTRY glColor3ubv(const GLubyte *v) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[A8IDX] = 255;
COLOR[R8IDX] = v[0];
COLOR[G8IDX] = v[1];
COLOR[B8IDX] = v[2];
const float m = 1.0f / 255.0f;
COLOR[A8IDX] = 1.0f;
COLOR[R8IDX] = ((float) v[0]) * m;
COLOR[G8IDX] = ((float) v[1]) * m;
COLOR[B8IDX] = ((float) v[2]) * m;
}
void APIENTRY glColor3fv(const GLfloat* v) {
IM_ATTRIBS.enabled |= DIFFUSE_ENABLED_FLAG;
IM_ATTRIBS.enabled |= COLOR_ENABLED_FLAG;
COLOR[A8IDX] = 255;
COLOR[R8IDX] = (GLubyte)(v[0] * 255);
COLOR[G8IDX] = (GLubyte)(v[1] * 255);
COLOR[B8IDX] = (GLubyte)(v[2] * 255);
COLOR[A8IDX] = 1.0f;
COLOR[R8IDX] = v[0];
COLOR[G8IDX] = v[1];
COLOR[B8IDX] = v[2];
}
typedef union punned {
@ -259,12 +266,12 @@ void APIENTRY glEnd() {
IM_ATTRIBS.uv.ptr = IM_ATTRIBS.vertex.ptr + 12;
IM_ATTRIBS.st.ptr = IM_ATTRIBS.uv.ptr + 8;
IM_ATTRIBS.colour.ptr = IM_ATTRIBS.st.ptr + 8;
IM_ATTRIBS.normal.ptr = IM_ATTRIBS.colour.ptr + 4;
IM_ATTRIBS.normal.ptr = IM_ATTRIBS.colour.ptr + 16;
/* Redirect attrib state */
AttribPointerList stashed_state = ATTRIB_LIST;
ATTRIB_LIST = IM_ATTRIBS;
glDrawArrays(ACTIVE_POLYGON_MODE, 0, aligned_vector_header(&VERTICES)->size);
ATTRIB_LIST = stashed_state;

View File

@ -355,52 +355,33 @@ void APIENTRY glColorMaterial(GLenum face, GLenum mode) {
_glSetColorMaterialMode(mode);
}
GL_FORCE_INLINE void bgra_to_float(const uint8_t* input, GLfloat* output) {
static const float scale = 1.0f / 255.0f;
output[0] = ((float) input[R8IDX]) * scale;
output[1] = ((float) input[G8IDX]) * scale;
output[2] = ((float) input[B8IDX]) * scale;
output[3] = ((float) input[A8IDX]) * scale;
}
void _glUpdateColourMaterialA(const GLubyte* argb) {
void _glUpdateColourMaterialA(const float* colour) {
Material* material = _glActiveMaterial();
float colour[4];
bgra_to_float(argb, colour);
vec4cpy(material->ambient, colour);
GLenum mask = _glColorMaterialMode();
_glPrecalcLightingValues(mask);
}
void _glUpdateColourMaterialD(const GLubyte* argb) {
void _glUpdateColourMaterialD(const float* colour) {
Material* material = _glActiveMaterial();
float colour[4];
bgra_to_float(argb, colour);
vec4cpy(material->diffuse, colour);
GLenum mask = _glColorMaterialMode();
_glPrecalcLightingValues(mask);
}
void _glUpdateColourMaterialE(const GLubyte* argb) {
void _glUpdateColourMaterialE(const float* colour) {
Material* material = _glActiveMaterial();
float colour[4];
bgra_to_float(argb, colour);
vec4cpy(material->emissive, colour);
GLenum mask = _glColorMaterialMode();
_glPrecalcLightingValues(mask);
}
void _glUpdateColourMaterialAD(const GLubyte* argb) {
void _glUpdateColourMaterialAD(const float* colour) {
Material* material = _glActiveMaterial();
float colour[4];
bgra_to_float(argb, colour);
vec4cpy(material->ambient, colour);
vec4cpy(material->diffuse, colour);
@ -499,17 +480,16 @@ GL_FORCE_INLINE void _glLightVertexPoint(
#undef _PROCESS_COMPONENT
}
void _glPerformLighting(Vertex* vertices, VertexExtra* extra, const uint32_t count) {
void _glPerformLighting(Vertex* vertices, const uint32_t count) {
GLubyte i;
GLuint j;
Material* material = _glActiveMaterial();
Vertex* vertex = vertices;
VertexExtra* data = extra;
/* Calculate the colour material function once */
void (*updateColourMaterial)(const GLubyte*) = NULL;
void (*updateColourMaterial)(const GLfloat*) = NULL;
if(_glIsColorMaterialEnabled()) {
GLenum mode = _glColorMaterialMode();
@ -533,10 +513,10 @@ void _glPerformLighting(Vertex* vertices, VertexExtra* extra, const uint32_t cou
return;
}
for(j = 0; j < count; ++j, ++vertex, ++data) {
for(j = 0; j < count; ++j, ++vertex) {
/* Calculate the ambient lighting and set up colour material */
if(updateColourMaterial) {
updateColourMaterial(vertex->bgra);
updateColourMaterial(vertex->argb);
}
/* Copy the base colour across */
@ -549,9 +529,12 @@ void _glPerformLighting(Vertex* vertices, VertexExtra* extra, const uint32_t cou
float Vz = -vertex->xyz[2];
VEC3_NORMALIZE(Vx, Vy, Vz);
const float Nx = data->nxyz[0];
const float Ny = data->nxyz[1];
const float Nz = data->nxyz[2];
float nxyz[3];
_glUnpackNormal(vertex->nxyz, nxyz);
const float Nx = nxyz[0];
const float Ny = nxyz[1];
const float Nz = nxyz[2];
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
LightSource* light = _glLightAt(i);
@ -631,10 +614,10 @@ void _glPerformLighting(Vertex* vertices, VertexExtra* extra, const uint32_t cou
}
}
vertex->bgra[R8IDX] = clamp(finalColour[0] * 255.0f, 0, 255);
vertex->bgra[G8IDX] = clamp(finalColour[1] * 255.0f, 0, 255);
vertex->bgra[B8IDX] = clamp(finalColour[2] * 255.0f, 0, 255);
vertex->bgra[A8IDX] = clamp(finalColour[3] * 255.0f, 0, 255);
vertex->argb[R8IDX] = finalColour[0];
vertex->argb[G8IDX] = finalColour[1];
vertex->argb[B8IDX] = finalColour[2];
vertex->argb[A8IDX] = finalColour[3];
}
}

View File

@ -64,7 +64,7 @@ GL_FORCE_INLINE float _glFastInvert(float x) {
GL_FORCE_INLINE void _glPerspectiveDivideVertex(Vertex* vertex, int count) {
TRACE();
for(int v = 0; v < count; ++v) {
for(int v = 0; v < count; ++v) {
const float f = _glFastInvert(vertex[v].w);
/* Convert to screenspace */
@ -87,7 +87,7 @@ GL_FORCE_INLINE void _glPerspectiveDivideVertex(Vertex* vertex, int count) {
static uintptr_t sq_dest_addr = 0;
static inline void _glPushHeaderOrVertex(Vertex* v, size_t count) {
static inline void _glPushHeader(Vertex* v, size_t count) {
TRACE();
#if CLIP_DEBUG
@ -97,6 +97,17 @@ static inline void _glPushHeaderOrVertex(Vertex* v, size_t count) {
sq_fast_cpy((void *)sq_dest_addr, v, count);
}
static inline void _glPushVertex(Vertex* v, size_t count) {
TRACE();
#if CLIP_DEBUG
fprintf(stderr, "{%f, %f, %f, %f}, // %x (%x)\n", v->xyz[0], v->xyz[1], v->xyz[2], v->w, v->flags, v);
#endif
sq_fast_cpy((void *)sq_dest_addr, v, count * 2);
}
static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, Vertex* vout) {
const float d0 = v1->w + v1->xyz[2];
const float d1 = v2->w + v2->xyz[2];
@ -113,10 +124,10 @@ static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, V
vout->w = invt * v1->w + t * v2->w;
vout->bgra[0] = invt * v1->bgra[0] + t * v2->bgra[0];
vout->bgra[1] = invt * v1->bgra[1] + t * v2->bgra[1];
vout->bgra[2] = invt * v1->bgra[2] + t * v2->bgra[2];
vout->bgra[3] = invt * v1->bgra[3] + t * v2->bgra[3];
vout->argb[0] = invt * v1->argb[0] + t * v2->argb[0];
vout->argb[1] = invt * v1->argb[1] + t * v2->argb[1];
vout->argb[2] = invt * v1->argb[2] + t * v2->argb[2];
vout->argb[3] = invt * v1->argb[3] + t * v2->argb[3];
}
#define SPAN_SORT_CFG 0x005F8030
@ -176,7 +187,7 @@ void SceneListSubmit(Vertex* vertices, int n) {
do { queued_vertex = &qv; *queued_vertex = *(v); } while(0)
#define SUBMIT_QUEUED_VERTEX(sflags) \
do { if(queued_vertex) { queued_vertex->flags = (sflags); _glPushHeaderOrVertex(queued_vertex, 1); queued_vertex = NULL; } } while(0)
do { if(queued_vertex) { queued_vertex->flags = (sflags); _glPushVertex(queued_vertex, 1); queued_vertex = NULL; } } while(0)
int visible_mask = 0;
sq_dest_addr = (uintptr_t)SQ_MASK_DEST(PVR_TA_INPUT);
@ -184,7 +195,7 @@ void SceneListSubmit(Vertex* vertices, int n) {
Vertex* v0 = vertices;
for(int i = 0; i < n - 1; ++i, ++v0) {
if(is_header(v0)) {
_glPushHeaderOrVertex(v0, 1);
_glPushHeader(v0, 1);
visible_mask = 0;
continue;
}
@ -210,7 +221,7 @@ void SceneListSubmit(Vertex* vertices, int n) {
_glPerspectiveDivideVertex(v0, 2);
v1->flags = GPU_CMD_VERTEX_EOL;
_glPushHeaderOrVertex(v0, 2);
_glPushVertex(v0, 2);
} else {
// If the previous triangle wasn't all visible, and we
// queued a vertex - we force it to be EOL and submit
@ -260,10 +271,10 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = GPU_CMD_VERTEX;
_glPerspectiveDivideVertex(v0, 1);
_glPushHeaderOrVertex(v0, 1);
_glPushVertex(v0, 1);
_glPerspectiveDivideVertex(a, 2);
_glPushHeaderOrVertex(a, 2);
_glPushVertex(a, 2);
QUEUE_VERTEX(b);
break;
@ -277,9 +288,9 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = v2->flags;
_glPerspectiveDivideVertex(a, 3);
_glPushHeaderOrVertex(a, 1);
_glPushVertex(a, 1);
_glPushHeaderOrVertex(c, 1);
_glPushVertex(c, 1);
QUEUE_VERTEX(b);
break;
@ -293,7 +304,7 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = GPU_CMD_VERTEX;
_glPerspectiveDivideVertex(a, 3);
_glPushHeaderOrVertex(a, 2);
_glPushVertex(a, 2);
QUEUE_VERTEX(c);
break;
@ -304,16 +315,16 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = GPU_CMD_VERTEX;
_glPerspectiveDivideVertex(v0, 1);
_glPushHeaderOrVertex(v0, 1);
_glPushVertex(v0, 1);
_glClipEdge(v1, v2, a);
a->flags = v2->flags;
_glPerspectiveDivideVertex(a, 3);
_glPushHeaderOrVertex(c, 1);
_glPushVertex(c, 1);
_glPushHeaderOrVertex(b, 2);
_glPushVertex(b, 2);
QUEUE_VERTEX(a);
break;
@ -328,11 +339,9 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = GPU_CMD_VERTEX;
_glPerspectiveDivideVertex(a, 4);
_glPushHeaderOrVertex(a, 1);
_glPushHeaderOrVertex(c, 1);
_glPushHeaderOrVertex(b, 2);
_glPushVertex(a, 1);
_glPushVertex(c, 1);
_glPushVertex(b, 2);
QUEUE_VERTEX(d);
break;
@ -347,15 +356,15 @@ void SceneListSubmit(Vertex* vertices, int n) {
b->flags = GPU_CMD_VERTEX;
_glPerspectiveDivideVertex(v0, 1);
_glPushHeaderOrVertex(v0, 1);
_glPushVertex(v0, 1);
_glPerspectiveDivideVertex(a, 3);
_glPushHeaderOrVertex(a, 1);
_glPushVertex(a, 1);
_glPushHeaderOrVertex(c, 1);
_glPushVertex(c, 1);
_glPushVertex(b, 1);
_glPushHeaderOrVertex(b, 1);
QUEUE_VERTEX(c);
break;
default:

View File

@ -43,8 +43,9 @@ extern void* memcpy4 (void *dest, const void *src, size_t count);
#define VERTEX_ENABLED_FLAG (1 << 0)
#define UV_ENABLED_FLAG (1 << 1)
#define ST_ENABLED_FLAG (1 << 2)
#define DIFFUSE_ENABLED_FLAG (1 << 3)
#define COLOR_ENABLED_FLAG (1 << 3)
#define NORMAL_ENABLED_FLAG (1 << 4)
#define S_COLOR_ENABLED_FLAG (1 << 5)
#define MAX_TEXTURE_SIZE 1024
@ -282,9 +283,6 @@ typedef struct __attribute__((aligned(32))) {
uint32_t header_offset; // The offset of the header in the output list
uint32_t start_offset; // The offset into the output list
uint32_t count; // The number of vertices in this output
/* Pointer to count * VertexExtra; */
AlignedVector* extras;
} SubmissionTarget;
Vertex* _glSubmissionTargetStart(SubmissionTarget* target);
@ -299,10 +297,10 @@ typedef enum {
} ClipResult;
#define A8IDX 3
#define R8IDX 2
#define G8IDX 1
#define B8IDX 0
#define A8IDX 0
#define R8IDX 1
#define G8IDX 2
#define B8IDX 3
struct SubmissionTarget;
@ -354,9 +352,10 @@ typedef void (*ReadAttributeFunc)(const GLubyte*, GLubyte*);
typedef struct {
AttribPointer vertex; // 16
AttribPointer colour; // 32
AttribPointer uv; // 48
AttribPointer st; // 64
AttribPointer normal; // 80
AttribPointer s_color; // 48
AttribPointer uv; // 64
AttribPointer st; // 80
AttribPointer normal; // 96
GLuint enabled; // list of currently enabled/used attributes
GLuint dirty; // list of attributes that need state recalculating
@ -364,6 +363,7 @@ typedef struct {
ReadAttributeFunc vertex_func;
ReadAttributeFunc colour_func;
ReadAttributeFunc s_color_func;
ReadAttributeFunc uv_func;
ReadAttributeFunc st_func;
ReadAttributeFunc normal_func;
@ -448,7 +448,7 @@ GL_FORCE_INLINE GLboolean _glCheckImmediateModeInactive(const char* func) {
return GL_FALSE;
}
extern void _glPerformLighting(Vertex* vertices, VertexExtra* extra, const uint32_t count);
extern void _glPerformLighting(Vertex* vertices, const uint32_t count);
unsigned char _glIsClippingEnabled();
void _glEnableClipping(unsigned char v);
@ -494,6 +494,12 @@ void _glTnlUpdateLighting(void);
void _glTnlUpdateTextureMatrix(void);
void _glTnlUpdateColorMatrix(void);
uint32_t _glPackNormal(const GLfloat* nxyz);
void _glUnpackNormal(uint32_t packed, float* nxyz);
half_float_t _glPackHalfFloat(float f);
float _glUnpackHalfFloat(half_float_t h);
/* This is from KOS pvr_buffers.c */
#define PVR_MIN_Z 0.0001f

View File

@ -28,6 +28,7 @@ static struct {
GLboolean scissor_test_enabled;
GLboolean fog_enabled;
GLboolean depth_mask_enabled;
GLboolean secondary_color_enabled;
struct {
GLint x;
@ -250,12 +251,12 @@ GLenum _glGetGpuBlendDstFactor() {
return GPU_BLEND_SRCALPHA;
case GL_SRC_COLOR:
// actually 'src' color in PVR2 when used as dst blend factor
return GPU_BLEND_DESTCOLOR;
return GPU_BLEND_DESTCOLOR;
case GL_DST_ALPHA:
return GPU_BLEND_DESTALPHA;
case GL_ONE_MINUS_SRC_COLOR:
// actually 'src' color in PVR2 when used as dst blend factor
return GPU_BLEND_INVDESTCOLOR;
return GPU_BLEND_INVDESTCOLOR;
case GL_ONE_MINUS_SRC_ALPHA:
return GPU_BLEND_INVSRCALPHA;
case GL_ONE_MINUS_DST_ALPHA:
@ -440,6 +441,12 @@ void _glInitContext() {
GLAPI void APIENTRY glEnable(GLenum cap) {
switch(cap) {
case GL_COLOR_SUM:
if(GPUState.secondary_color_enabled != GL_TRUE) {
GPUState.secondary_color_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
}
break;
case GL_TEXTURE_2D:
if(TEXTURES_ENABLED[_glGetActiveTexture()] != GL_TRUE) {
TEXTURES_ENABLED[_glGetActiveTexture()] = GL_TRUE;
@ -551,6 +558,12 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
GLAPI void APIENTRY glDisable(GLenum cap) {
switch(cap) {
case GL_COLOR_SUM:
if(GPUState.secondary_color_enabled != GL_FALSE) {
GPUState.secondary_color_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
}
break;
case GL_TEXTURE_2D:
if(TEXTURES_ENABLED[_glGetActiveTexture()] != GL_FALSE) {
TEXTURES_ENABLED[_glGetActiveTexture()] = GL_FALSE;
@ -956,7 +969,7 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
*params = (enabledAttrs & VERTEX_ENABLED_FLAG) == VERTEX_ENABLED_FLAG;
break;
case GL_COLOR_ARRAY:
*params = (enabledAttrs & DIFFUSE_ENABLED_FLAG) == DIFFUSE_ENABLED_FLAG;
*params = (enabledAttrs & COLOR_ENABLED_FLAG) == COLOR_ENABLED_FLAG;
break;
case GL_NORMAL_ARRAY:
*params = (enabledAttrs & NORMAL_ENABLED_FLAG) == NORMAL_ENABLED_FLAG;

View File

@ -5,6 +5,7 @@
#include <math.h>
#include <limits.h>
#include "types.h"
#include "private.h"
#include "platform.h"
@ -41,29 +42,31 @@ static void transformVertices(SubmissionTarget* target) {
uint32_t count = target->count;
ITERATE(count) {
TransformVertex(it->xyz[0], it->xyz[1], it->xyz[2], it->w,
TransformVertex(it->xyz[0], it->xyz[1], it->xyz[2], it->w,
it->xyz, &it->w);
it++;
}
}
static void mat_transform_normal3(VertexExtra* extra, const uint32_t count) {
static void mat_transform_normal3(Vertex* v, const uint32_t count) {
ITERATE(count) {
TransformNormalNoMod(extra->nxyz, extra->nxyz);
extra++;
float nxyz[3];
_glUnpackNormal(v->nxyz, nxyz);
TransformNormalNoMod(nxyz, nxyz);
v->nxyz = _glPackNormal(nxyz);
v++;
}
}
static void lightingEffect(SubmissionTarget* target) {
/* Perform lighting calculations and manipulate the colour */
Vertex* vertex = _glSubmissionTargetStart(target);
VertexExtra* extra = aligned_vector_at(target->extras, 0);
_glMatrixLoadNormal();
mat_transform_normal3(extra, target->count);
mat_transform_normal3(vertex, target->count);
_glPerformLighting(vertex, extra, target->count);
_glPerformLighting(vertex, target->count);
}
void _glTnlUpdateLighting(void) {
@ -76,7 +79,6 @@ static void textureEffect(SubmissionTarget* target) {
Matrix4x4* m = _glGetTextureMatrix();
UploadMatrix4x4(m);
float coords[4];
float* ptr = (float*)m;
Vertex* it = _glSubmissionTargetStart(target);
uint32_t count = target->count;
@ -105,11 +107,11 @@ static void colorEffect(SubmissionTarget* target) {
uint32_t count = target->count;
ITERATE(count) {
TransformVertex(it->bgra[2], it->bgra[1], it->bgra[0], it->bgra[3], coords, &coords[3]);
it->bgra[2] = clamp(coords[0], 0, 255);
it->bgra[1] = clamp(coords[1], 0, 255);
it->bgra[0] = clamp(coords[2], 0, 255);
it->bgra[3] = clamp(coords[3], 0, 255);
TransformVertex(it->argb[2], it->argb[1], it->argb[0], it->argb[3], coords, &coords[3]);
it->argb[R8IDX] = coords[0];
it->argb[G8IDX] = coords[1];
it->argb[B8IDX] = coords[2];
it->argb[A8IDX] = coords[3];
it++;
}
}

View File

@ -2,15 +2,28 @@
#include <stdint.h>
typedef uint16_t half_float_t;
/*
*
* Right this will take some explaining. This vertex matches one of the 64 byte vertex
* structures that the PVR supports, with the following "adjustments" (aka, abuse of free bytes)
* There are 8 unused bytes anyway, and we steal the 4 bytes of the offset color alpha channel
* which we don't really need.
* glSecondaryColor doesn't support an alpha channel, and it's unusual that you would need it
* for the offset color. It's much more useful as a cache-friendly space for something else
*
* Normal is stored as X + Y, packed into half floats. Z is reconstructed (as normals should have a length of 1)
*/
typedef struct {
/* Same 32 byte layout as pvr_vertex_t */
uint32_t flags;
float xyz[3];
float uv[2];
uint8_t bgra[4];
/* In the pvr_vertex_t structure, this next 4 bytes is oargb
* but we're not using that for now, so having W here makes the code
* simpler */
float w;
uint32_t nxyz;
float argb[4];
float offset_rgb[3];
half_float_t st[2];
} __attribute__ ((aligned (32))) Vertex;

View File

@ -13,3 +13,24 @@ void APIENTRY glVertexPackColor4fKOS(GLVertexKOS* vertex, float r, float g, floa
vertex->bgra[1] = (g * 255.0f);
vertex->bgra[0] = (b * 255.0f);
}
uint32_t _glPackNormal(const GLfloat* nxyz) {
uint8_t bx = (uint8_t)((nxyz[0] + 1) * 127.5);
uint8_t by = (uint8_t)((nxyz[1] + 1) * 127.5);
uint8_t bz = (uint8_t)((nxyz[2] + 1) * 127.5);
return (bx << 16) | (by << 8) | bz;
}
void _glUnpackNormal(uint32_t packed, float* nxyz) {
nxyz[0] = ((packed >> 16) & 0xFF) / 127.5 - 1;
nxyz[1] = ((packed >> 8) & 0xFF) / 127.5 - 1;
nxyz[2] = (packed & 0xFF) / 127.5 - 1;
}
half_float_t _glPackHalfFloat(float f) {
}
float _glUnpackHalfFloat(half_float_t h) {
}

View File

@ -445,6 +445,11 @@ __BEGIN_DECLS
#define GL_POLYGON_OFFSET_LINE 0x2A02
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_COLOR_SUM 0x8458
#define GL_CURRENT_SECONDARY_COLOR 0x8459
#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
#define GL_SECONDARY_COLOR_ARRAY 0x845E
#define GLbyte char
#define GLshort short
#define GLint int
@ -661,14 +666,13 @@ GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type,
GLAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
/* If a Normal Pointer is set and GL Lighting has been enabled,
Vertex Lighting will be used instead of glColorPointer */
GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
/* Use either this OR glNormalPointer to color vertices, NOT both */
GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
GLAPI void APIENTRY glColorPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
GLAPI void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
/* Array Data Submission */
GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count);
GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);