Optimisations
This commit is contained in:
parent
cba2fb7ceb
commit
e683b8becb
|
@ -5,75 +5,123 @@
|
|||
|
||||
MAKE_FUNC(POLYMODE)
|
||||
{
|
||||
const Vertex* const start = _glSubmissionTargetStart(target);
|
||||
const VertexExtra* const ve_start = aligned_vector_at(target->extras, 0);
|
||||
|
||||
const GLuint vstride = ATTRIB_POINTERS.vertex.stride;
|
||||
GLuint uvstride = ATTRIB_POINTERS.uv.stride;
|
||||
GLuint ststride = ATTRIB_POINTERS.st.stride;
|
||||
GLuint dstride = ATTRIB_POINTERS.colour.stride;
|
||||
GLuint nstride = ATTRIB_POINTERS.normal.stride;
|
||||
|
||||
const GLubyte* pos = (ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG) ? ATTRIB_POINTERS.vertex.ptr + (first * vstride) : NULL;
|
||||
const GLubyte* uv = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? ATTRIB_POINTERS.uv.ptr + (first * uvstride) : NULL;
|
||||
const GLubyte* col = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? ATTRIB_POINTERS.colour.ptr + (first * dstride) : NULL;
|
||||
const GLubyte* st = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ATTRIB_POINTERS.st.ptr + (first * ststride) : NULL;
|
||||
const GLubyte* n = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? ATTRIB_POINTERS.normal.ptr + (first * nstride) : NULL;
|
||||
|
||||
const float w = 1.0f;
|
||||
|
||||
if(!pos) {
|
||||
static const float w = 1.0f;
|
||||
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
|
||||
/* If we don't have vertices, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
if(!col) {
|
||||
col = (GLubyte*) &U4ONE;
|
||||
dstride = 0;
|
||||
/* This is the best value we have. PROCESS_VERTEX_FLAGS needs to operate on quads and tris and so
|
||||
this need to be divisible by 4 and 3. Even though we should be able to go much higher than this
|
||||
and still be cache-local, trial and error says otherwise... */
|
||||
|
||||
#define BATCH_SIZE 60
|
||||
|
||||
GLuint min = 0;
|
||||
GLuint stride;
|
||||
const GLubyte* ptr;
|
||||
Vertex* it;
|
||||
VertexExtra* ve;
|
||||
|
||||
|
||||
for(int min = 0; min < count; min += BATCH_SIZE) {
|
||||
const Vertex* start = ((Vertex*) _glSubmissionTargetStart(target)) + min;
|
||||
const int_fast32_t loop = ((min + BATCH_SIZE) > count) ? count - min : BATCH_SIZE;
|
||||
const int offset = (first + min);
|
||||
|
||||
stride = ATTRIB_POINTERS.vertex.stride;
|
||||
ptr = ATTRIB_POINTERS.vertex.ptr + (offset * stride);
|
||||
it = (Vertex*) start;
|
||||
|
||||
PREFETCH(ptr);
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
|
||||
PREFETCH(ptr + stride);
|
||||
TransformVertex((const float*) ptr, &w, it->xyz, &it->w);
|
||||
PROCESS_VERTEX_FLAGS(it, min + i);
|
||||
ptr += stride;
|
||||
}
|
||||
|
||||
if(!uv) {
|
||||
uv = (GLubyte*) &F2ZERO;
|
||||
uvstride = 0;
|
||||
stride = ATTRIB_POINTERS.uv.stride;
|
||||
ptr = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? ATTRIB_POINTERS.uv.ptr + ((first + min) * stride) : NULL;
|
||||
it = (Vertex*) start;
|
||||
|
||||
if(ptr) {
|
||||
PREFETCH(ptr);
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
|
||||
PREFETCH(ptr + stride);
|
||||
it->uv[0] = ((float*) ptr)[0];
|
||||
it->uv[1] = ((float*) ptr)[1];
|
||||
ptr += stride;
|
||||
}
|
||||
} else {
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
|
||||
it->uv[0] = 0;
|
||||
it->uv[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stride = ATTRIB_POINTERS.colour.stride;
|
||||
ptr = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? ATTRIB_POINTERS.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];
|
||||
ptr += stride;
|
||||
}
|
||||
} else {
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++it) {
|
||||
*((uint32_t*) it->bgra) = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
start = aligned_vector_at(target->extras, min);
|
||||
|
||||
stride = ATTRIB_POINTERS.st.stride;
|
||||
ptr = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ATTRIB_POINTERS.st.ptr + (offset * stride) : NULL;
|
||||
ve = (VertexExtra*) start;
|
||||
|
||||
if(ptr) {
|
||||
PREFETCH(ptr);
|
||||
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
|
||||
PREFETCH(ptr + stride);
|
||||
ve->st[0] = ((float*) ptr)[0];
|
||||
ve->st[1] = ((float*) ptr)[1];
|
||||
ptr += stride;
|
||||
}
|
||||
} else {
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
|
||||
ve->st[0] = 0;
|
||||
ve->st[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stride = ATTRIB_POINTERS.normal.stride;
|
||||
ptr = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? ATTRIB_POINTERS.normal.ptr + (offset * stride) : NULL;
|
||||
ve = (VertexExtra*) start;
|
||||
|
||||
if(ptr) {
|
||||
PREFETCH(ptr);
|
||||
|
||||
for(int_fast32_t i = 0; i < loop; ++i, ++ve) {
|
||||
PREFETCH(ptr + stride);
|
||||
ve->nxyz[0] = ((float*) ptr)[0];
|
||||
ve->nxyz[1] = ((float*) ptr)[1];
|
||||
ve->nxyz[2] = ((float*) ptr)[2];
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if(!st) {
|
||||
st = (GLubyte*) &F2ZERO;
|
||||
ststride = 0;
|
||||
}
|
||||
|
||||
if(!n) {
|
||||
n = (GLubyte*) &F3Z;
|
||||
nstride = 0;
|
||||
}
|
||||
|
||||
VertexExtra* ve = (VertexExtra*) ve_start;
|
||||
Vertex* it = (Vertex*) start;
|
||||
|
||||
for(int_fast32_t i = 0; i < count; ++i) {
|
||||
TransformVertex((const float*) pos, &w, it->xyz, &it->w);
|
||||
pos += vstride;
|
||||
PREFETCH(pos);
|
||||
|
||||
*((Float2*) it->uv) = *((Float2*) uv);
|
||||
uv += uvstride;
|
||||
PREFETCH(uv);
|
||||
|
||||
*((uint32_t*) it->bgra) = *((uint32_t*) col);
|
||||
col += dstride;
|
||||
PREFETCH(col);
|
||||
|
||||
*((Float2*) ve->st) = *((Float2*) st);
|
||||
st += ststride;
|
||||
PREFETCH(st);
|
||||
|
||||
*((Float3*) ve->nxyz) = *((Float3*) n);
|
||||
n += nstride;
|
||||
PREFETCH(n);
|
||||
|
||||
PROCESS_VERTEX_FLAGS(it, i);
|
||||
|
||||
++it;
|
||||
++ve;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,19 +95,19 @@ void APIENTRY glKosSwapBuffers() {
|
|||
SceneBegin();
|
||||
if(OP_LIST.vector.size > 2) {
|
||||
SceneListBegin(GPU_LIST_OP_POLY);
|
||||
SceneListSubmit(OP_LIST.vector.data, OP_LIST.vector.size);
|
||||
SceneListSubmit((Vertex*) OP_LIST.vector.data, OP_LIST.vector.size);
|
||||
SceneListFinish();
|
||||
}
|
||||
|
||||
if(PT_LIST.vector.size > 2) {
|
||||
SceneListBegin(GPU_LIST_PT_POLY);
|
||||
SceneListSubmit(PT_LIST.vector.data, PT_LIST.vector.size);
|
||||
SceneListSubmit((Vertex*) PT_LIST.vector.data, PT_LIST.vector.size);
|
||||
SceneListFinish();
|
||||
}
|
||||
|
||||
if(TR_LIST.vector.size > 2) {
|
||||
SceneListBegin(GPU_LIST_TR_POLY);
|
||||
SceneListSubmit(TR_LIST.vector.data, TR_LIST.vector.size);
|
||||
SceneListSubmit((Vertex*) TR_LIST.vector.data, TR_LIST.vector.size);
|
||||
SceneListFinish();
|
||||
}
|
||||
SceneFinish();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "gl_assert.h"
|
||||
#include "types.h"
|
||||
|
||||
#define MEMSET(dst, v, size) memset((dst), (v), (size))
|
||||
|
||||
|
@ -260,7 +261,7 @@ typedef float Matrix4x4[16];
|
|||
void SceneBegin();
|
||||
|
||||
void SceneListBegin(GPUList list);
|
||||
void SceneListSubmit(void* src, int n);
|
||||
void SceneListSubmit(Vertex* v2, int n);
|
||||
void SceneListFinish();
|
||||
|
||||
void SceneFinish();
|
||||
|
|
|
@ -64,31 +64,26 @@ GL_FORCE_INLINE void _glPerspectiveDivideVertex(Vertex* vertex, const float h) {
|
|||
}
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _glSubmitHeaderOrVertex(volatile uint32_t* d, const Vertex* v) {
|
||||
#ifndef NDEBUG
|
||||
gl_assert(!isnan(v->xyz[2]));
|
||||
gl_assert(!isnan(v->w));
|
||||
#endif
|
||||
|
||||
#if CLIP_DEBUG
|
||||
fprintf(stderr, "Submitting: %x (%x)\n", v, v->flags);
|
||||
#endif
|
||||
volatile uint32_t *sq = SQ_BASE_ADDRESS;
|
||||
|
||||
static inline void _glFlushBuffer() {}
|
||||
static inline void _glPushHeaderOrVertex(Vertex* v) {
|
||||
uint32_t* s = (uint32_t*) v;
|
||||
d[0] = *(s++);
|
||||
d[1] = *(s++);
|
||||
d[2] = *(s++);
|
||||
d[3] = *(s++);
|
||||
d[4] = *(s++);
|
||||
d[5] = *(s++);
|
||||
d[6] = *(s++);
|
||||
d[7] = *(s++);
|
||||
__asm__("pref @%0" : : "r"(d));
|
||||
d += 8;
|
||||
sq[0] = *(s++);
|
||||
sq[1] = *(s++);
|
||||
sq[2] = *(s++);
|
||||
sq[3] = *(s++);
|
||||
sq[4] = *(s++);
|
||||
sq[5] = *(s++);
|
||||
sq[6] = *(s++);
|
||||
sq[7] = *(s++);
|
||||
__asm__("pref @%0" : : "r"(sq));
|
||||
sq += 8;
|
||||
}
|
||||
|
||||
static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, Vertex* vout) {
|
||||
const static float o = 1.0f / 255.0f;
|
||||
const static float o = 0.003921569f; // 1 / 255
|
||||
const float d0 = v1->w + v1->xyz[2];
|
||||
const float d1 = v2->w + v2->xyz[2];
|
||||
const float t = (fabs(d0) * (1.0f / sqrtf((d1 - d0) * (d1 - d0)))) + 0.000001f;
|
||||
|
@ -117,7 +112,7 @@ static volatile uint32_t* PVR_LMMODE0 = (uint32_t*) 0xA05F6884;
|
|||
static volatile uint32_t *PVR_LMMODE1 = (uint32_t*) 0xA05F6888;
|
||||
static volatile uint32_t *QACR = (uint32_t*) 0xFF000038;
|
||||
|
||||
void SceneListSubmit(void* src, int n) {
|
||||
void SceneListSubmit(Vertex* v2, int n) {
|
||||
/* You need at least a header, and 3 vertices to render anything */
|
||||
if(n < 4) {
|
||||
return;
|
||||
|
@ -134,111 +129,113 @@ void SceneListSubmit(void* src, int n) {
|
|||
//Set QACR registers
|
||||
QACR[1] = QACR[0] = 0x11;
|
||||
|
||||
volatile uint32_t *sq = SQ_BASE_ADDRESS;
|
||||
|
||||
uint32_t clipping_disabled_mask = (_glNearZClippingEnabled()) ? 0 : 0x7;
|
||||
|
||||
#if CLIP_DEBUG
|
||||
Vertex* vertex = (Vertex*) src;
|
||||
for(int i = 0; i < n; ++i) {
|
||||
fprintf(stderr, "{%f, %f, %f, %f}, // %x (%x)\n", vertex[i].xyz[0], vertex[i].xyz[1], vertex[i].xyz[2], vertex[i].w, vertex[i].flags, &vertex[i]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "----\n");
|
||||
#endif
|
||||
uint8_t counter = 0;
|
||||
uint8_t __attribute__((aligned(32))) visible_mask = 0;
|
||||
uint8_t __attribute__((aligned(32))) counter = 0;
|
||||
|
||||
Vertex* v2 = (Vertex*) src;
|
||||
while(n--) {
|
||||
__builtin_prefetch(v2 + 1);
|
||||
sq = SQ_BASE_ADDRESS;
|
||||
|
||||
for(int i = 0; i < n; ++i, ++v2) {
|
||||
switch(v2->flags) {
|
||||
case GPU_CMD_VERTEX_EOL:
|
||||
if(counter < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
break;
|
||||
case GPU_CMD_VERTEX:
|
||||
if(++counter < 3) {
|
||||
v2++;
|
||||
++counter;
|
||||
if(counter < 3) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_glSubmitHeaderOrVertex(sq, v2++);
|
||||
_glPushHeaderOrVertex(v2);
|
||||
counter = 0;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
Vertex* const v0 = v2 - 2;
|
||||
Vertex* const v1 = v2 - 1;
|
||||
|
||||
const uint8_t visible_mask = (
|
||||
visible_mask = (
|
||||
(v0->xyz[2] > -v0->w) << 0 |
|
||||
(v1->xyz[2] > -v1->w) << 1 |
|
||||
(v2->xyz[2] > -v2->w) << 2 |
|
||||
((v2->flags == GPU_CMD_VERTEX_EOL) << 3) |
|
||||
clipping_disabled_mask // This forces everything to be marked visible if clipping is disabled
|
||||
(counter == 0) << 3
|
||||
);
|
||||
|
||||
switch(visible_mask) {
|
||||
case 0:
|
||||
break;
|
||||
case 15: /* All visible, but final vertex in strip */
|
||||
{
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
Vertex __attribute__((aligned(32))) a = *v1;
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(v1, h);
|
||||
_glPushHeaderOrVertex(v1);
|
||||
|
||||
a = *v2;
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(v2, h);
|
||||
_glPushHeaderOrVertex(v2);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/* All visible, push the first vertex and move on */
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
break;
|
||||
case 9:
|
||||
/* First vertex was visible, last in strip */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) scratch[2];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
|
||||
_glClipEdge(v0, v1, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v0, v1, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v2, v0, &b);
|
||||
b.flags = GPU_CMD_VERTEX_EOL;
|
||||
_glClipEdge(v2, v0, b);
|
||||
b->flags = GPU_CMD_VERTEX_EOL;
|
||||
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* First vertex was visible, but not last in strip */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) scratch[2];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
|
||||
_glClipEdge(v0, v1, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v0, v1, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v2, v0, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v2, v0, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
_glPushHeaderOrVertex(b);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
|
@ -246,165 +243,187 @@ void SceneListSubmit(void* src, int n) {
|
|||
/* Second vertex was visible. In self case we need to create a triangle and produce
|
||||
two new vertices: 1-2, and 2-3. */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a;
|
||||
Vertex __attribute__((aligned(32))) c = *v1;
|
||||
_glClipEdge(v0, &c, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
Vertex __attribute__((aligned(32))) scratch[2];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* c = &scratch[1];
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
memcpy_vertex(c, v1);
|
||||
|
||||
_glClipEdge(&c, v2, &a);
|
||||
a.flags = v2->flags;
|
||||
_glClipEdge(v0, c, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glClipEdge(c, v2, a);
|
||||
a->flags = v2->flags;
|
||||
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
case 3: /* First and second vertex were visible */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) c = *v1;
|
||||
Vertex __attribute__((aligned(32))) scratch[3];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
Vertex* c = &scratch[2];
|
||||
|
||||
_glClipEdge(v2, v0, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
memcpy_vertex(c, v1);
|
||||
|
||||
_glClipEdge(v2, v0, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
_glClipEdge(v1, v2, &a);
|
||||
a.flags = v2->flags;
|
||||
_glClipEdge(v1, v2, a);
|
||||
a->flags = v2->flags;
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
_glPushHeaderOrVertex(a);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
case 4:
|
||||
/* Third vertex was visible. */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) c = *v2;
|
||||
Vertex __attribute__((aligned(32))) scratch[3];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
Vertex* c = &scratch[2];
|
||||
|
||||
_glClipEdge(v2, v0, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
memcpy_vertex(c, v2);
|
||||
|
||||
_glClipEdge(v1, v2, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v2, v0, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glClipEdge(v1, v2, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
if(counter % 2 == 1) {
|
||||
_glPushHeaderOrVertex(a);
|
||||
}
|
||||
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) c = *v2;
|
||||
c.flags = GPU_CMD_VERTEX;
|
||||
Vertex __attribute__((aligned(32))) scratch[3];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
Vertex* c = &scratch[2];
|
||||
|
||||
_glClipEdge(v0, v1, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
memcpy_vertex(c, v2);
|
||||
c->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v1, v2, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v0, v1, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v1, v2, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
|
||||
c.flags = GPU_CMD_VERTEX_EOL;
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
c->flags = GPU_CMD_VERTEX_EOL;
|
||||
_glPushHeaderOrVertex(c);
|
||||
}
|
||||
break;
|
||||
case 5: /* First and third vertex were visible */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) c = *v2;
|
||||
c.flags = GPU_CMD_VERTEX;
|
||||
Vertex __attribute__((aligned(32))) scratch[3];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
Vertex* c = &scratch[2];
|
||||
|
||||
_glClipEdge(v0, v1, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
memcpy_vertex(c, v2);
|
||||
c->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v1, v2, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v0, v1, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glClipEdge(v1, v2, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(v0, h);
|
||||
_glSubmitHeaderOrVertex(sq, v0);
|
||||
_glPushHeaderOrVertex(v0);
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
_glPushHeaderOrVertex(c);
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
case 6: /* Second and third vertex were visible */
|
||||
{
|
||||
Vertex __attribute__((aligned(32))) a, b;
|
||||
Vertex __attribute__((aligned(32))) c = *v1;
|
||||
Vertex __attribute__((aligned(32))) scratch[4];
|
||||
Vertex* a = &scratch[0];
|
||||
Vertex* b = &scratch[1];
|
||||
Vertex* c = &scratch[2];
|
||||
Vertex* d = &scratch[3];
|
||||
|
||||
_glClipEdge(v0, v1, &a);
|
||||
a.flags = GPU_CMD_VERTEX;
|
||||
memcpy_vertex(c, v1);
|
||||
memcpy_vertex(d, v2);
|
||||
|
||||
_glClipEdge(v2, v0, &b);
|
||||
b.flags = GPU_CMD_VERTEX;
|
||||
_glClipEdge(v0, v1, a);
|
||||
a->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(&a, h);
|
||||
_glSubmitHeaderOrVertex(sq, &a);
|
||||
_glClipEdge(v2, v0, b);
|
||||
b->flags = GPU_CMD_VERTEX;
|
||||
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(a, h);
|
||||
_glPushHeaderOrVertex(a);
|
||||
|
||||
_glPerspectiveDivideVertex(&b, h);
|
||||
_glSubmitHeaderOrVertex(sq, &b);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(c, h);
|
||||
_glPushHeaderOrVertex(c);
|
||||
|
||||
c = *v2;
|
||||
_glPerspectiveDivideVertex(&c, h);
|
||||
_glSubmitHeaderOrVertex(sq, &c);
|
||||
_glPerspectiveDivideVertex(b, h);
|
||||
_glPushHeaderOrVertex(b);
|
||||
_glPushHeaderOrVertex(c);
|
||||
|
||||
_glPerspectiveDivideVertex(d, h);
|
||||
_glPushHeaderOrVertex(d);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(v2->flags == GPU_CMD_VERTEX_EOL) {
|
||||
counter = 0;
|
||||
} else {
|
||||
--counter;
|
||||
}
|
||||
|
||||
v2++;
|
||||
}
|
||||
_glFlushBuffer();
|
||||
}
|
||||
|
||||
void SceneListFinish() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user