Fix some winding issues
This commit is contained in:
parent
b17104afea
commit
6fb15ee4c7
|
@ -1,6 +1,9 @@
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
#include "sh4.h"
|
#include "sh4.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CLIP_DEBUG 0
|
||||||
|
|
||||||
#define TA_SQ_ADDR (unsigned int *)(void *) \
|
#define TA_SQ_ADDR (unsigned int *)(void *) \
|
||||||
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))
|
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))
|
||||||
|
|
||||||
|
@ -76,6 +79,10 @@ GL_FORCE_INLINE void _glSubmitHeaderOrVertex(const Vertex* v) {
|
||||||
assert(!isnan(v->w));
|
assert(!isnan(v->w));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
printf("Submitting: %x (%x)\n", v, v->flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t *s = (uint32_t*) v;
|
uint32_t *s = (uint32_t*) v;
|
||||||
__asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */
|
__asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */
|
||||||
d[0] = *(s++);
|
d[0] = *(s++);
|
||||||
|
@ -145,11 +152,8 @@ GL_FORCE_INLINE void ShiftTriangle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
tri_count--;
|
tri_count--;
|
||||||
if(strip_count % 2 == 0) {
|
triangle[0] = triangle[1];
|
||||||
triangle[1] = triangle[2];
|
triangle[1] = triangle[2];
|
||||||
} else {
|
|
||||||
triangle[0] = triangle[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
triangle[2].v = NULL;
|
triangle[2].v = NULL;
|
||||||
|
@ -157,6 +161,22 @@ GL_FORCE_INLINE void ShiftTriangle() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GL_FORCE_INLINE void ShiftRotateTriangle() {
|
||||||
|
if(!tri_count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(triangle[0].v < triangle[1].v) {
|
||||||
|
triangle[0] = triangle[2];
|
||||||
|
} else {
|
||||||
|
triangle[1] = triangle[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
tri_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SceneListSubmit(void* src, int n) {
|
void SceneListSubmit(void* src, int n) {
|
||||||
/* Do everything, everywhere, all at once */
|
/* Do everything, everywhere, all at once */
|
||||||
|
|
||||||
|
@ -171,7 +191,11 @@ void SceneListSubmit(void* src, int n) {
|
||||||
tri_count = 0;
|
tri_count = 0;
|
||||||
strip_count = 0;
|
strip_count = 0;
|
||||||
|
|
||||||
for(int i = 0; i < n; ++i) {
|
#if CLIP_DEBUG
|
||||||
|
printf("----\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(int i = 0; i < n; ++i, ++vertex) {
|
||||||
PREFETCH(vertex + 1);
|
PREFETCH(vertex + 1);
|
||||||
|
|
||||||
bool is_last_in_strip = glIsLastVertex(vertex->flags);
|
bool is_last_in_strip = glIsLastVertex(vertex->flags);
|
||||||
|
@ -191,26 +215,35 @@ void SceneListSubmit(void* src, int n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tri_count < 3) {
|
if(tri_count < 3) {
|
||||||
++vertex;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
printf("SC: %d\n", strip_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If we got here, then triangle contains 3 vertices */
|
/* If we got here, then triangle contains 3 vertices */
|
||||||
int visible_mask = triangle[0].visible | (triangle[1].visible << 1) | (triangle[2].visible << 2);
|
int visible_mask = triangle[0].visible | (triangle[1].visible << 1) | (triangle[2].visible << 2);
|
||||||
if(visible_mask == 7) {
|
if(visible_mask == 7) {
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
printf("Visible\n");
|
||||||
|
#endif
|
||||||
/* All the vertices are visible! We divide and submit v0, then shift */
|
/* All the vertices are visible! We divide and submit v0, then shift */
|
||||||
_glPerspectiveDivideVertex(triangle[0].v, h);
|
_glPerspectiveDivideVertex(vertex - 2, h);
|
||||||
_glSubmitHeaderOrVertex(triangle[0].v);
|
_glSubmitHeaderOrVertex(vertex - 2);
|
||||||
|
|
||||||
if(is_last_in_strip) {
|
if(is_last_in_strip) {
|
||||||
_glPerspectiveDivideVertex(triangle[1].v, h);
|
_glPerspectiveDivideVertex(vertex - 1, h);
|
||||||
_glSubmitHeaderOrVertex(triangle[1].v);
|
_glSubmitHeaderOrVertex(vertex - 1);
|
||||||
_glPerspectiveDivideVertex(triangle[2].v, h);
|
_glPerspectiveDivideVertex(vertex, h);
|
||||||
_glSubmitHeaderOrVertex(triangle[2].v);
|
_glSubmitHeaderOrVertex(vertex);
|
||||||
ClearTriangle();
|
tri_count = 0;
|
||||||
strip_count = 0;
|
strip_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShiftRotateTriangle();
|
||||||
|
|
||||||
} else if(visible_mask) {
|
} else if(visible_mask) {
|
||||||
/* Clipping time!
|
/* Clipping time!
|
||||||
|
|
||||||
|
@ -225,8 +258,26 @@ void SceneListSubmit(void* src, int n) {
|
||||||
Unfortunately we have to copy vertices here, because if we persp-divide a vertex it may
|
Unfortunately we have to copy vertices here, because if we persp-divide a vertex it may
|
||||||
be used in a subsequent triangle in the strip and would end up being double divided.
|
be used in a subsequent triangle in the strip and would end up being double divided.
|
||||||
*/
|
*/
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
printf("Clip: %d, SC: %d\n", visible_mask, strip_count);
|
||||||
|
printf("%d, %d, %d\n", triangle[0].v - (Vertex*) src - 1, triangle[1].v - (Vertex*) src - 1, triangle[2].v - (Vertex*) src - 1);
|
||||||
|
#endif
|
||||||
Vertex tmp;
|
Vertex tmp;
|
||||||
|
if(strip_count > 3) {
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
printf("Flush\n");
|
||||||
|
#endif
|
||||||
|
tmp = *(vertex - 2);
|
||||||
|
/* If we had triangles ahead of this one, submit and finalize */
|
||||||
|
_glPerspectiveDivideVertex(&tmp, h);
|
||||||
|
_glSubmitHeaderOrVertex(&tmp);
|
||||||
|
|
||||||
|
tmp = *(vertex - 1);
|
||||||
|
tmp.flags = GPU_CMD_VERTEX_EOL;
|
||||||
|
_glPerspectiveDivideVertex(&tmp, h);
|
||||||
|
_glSubmitHeaderOrVertex(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
switch(visible_mask) {
|
switch(visible_mask) {
|
||||||
case 1: {
|
case 1: {
|
||||||
/* 0, 0a, 2a */
|
/* 0, 0a, 2a */
|
||||||
|
@ -319,7 +370,7 @@ void SceneListSubmit(void* src, int n) {
|
||||||
_glSubmitHeaderOrVertex(&tmp);
|
_glSubmitHeaderOrVertex(&tmp);
|
||||||
|
|
||||||
_glClipEdge(triangle[1].v, triangle[2].v, &tmp);
|
_glClipEdge(triangle[1].v, triangle[2].v, &tmp);
|
||||||
tmp.flags = GPU_CMD_VERTEX;
|
tmp.flags = GPU_CMD_VERTEX_EOL;
|
||||||
_glPerspectiveDivideVertex(&tmp, h);
|
_glPerspectiveDivideVertex(&tmp, h);
|
||||||
_glSubmitHeaderOrVertex(&tmp);
|
_glSubmitHeaderOrVertex(&tmp);
|
||||||
} break;
|
} break;
|
||||||
|
@ -354,14 +405,22 @@ void SceneListSubmit(void* src, int n) {
|
||||||
if(is_last_in_strip) {
|
if(is_last_in_strip) {
|
||||||
tri_count = 0;
|
tri_count = 0;
|
||||||
strip_count = 0;
|
strip_count = 0;
|
||||||
|
} else {
|
||||||
|
ShiftRotateTriangle();
|
||||||
|
strip_count = 2;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
/* Invisible? Move to the next in the strip */
|
||||||
|
|
||||||
/* If this was the last vertex in the strip, we're done with the
|
if(is_last_in_strip) {
|
||||||
strip so we need to wipe out the tri_count */
|
tri_count = 0;
|
||||||
ShiftTriangle();
|
strip_count = 0;
|
||||||
++vertex;
|
}
|
||||||
|
strip_count = 2;
|
||||||
|
ShiftRotateTriangle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for both store queues to complete */
|
/* Wait for both store queues to complete */
|
||||||
d = (uint32_t *)0xe0000000;
|
d = (uint32_t *)0xe0000000;
|
||||||
d[0] = d[8] = 0;
|
d[0] = d[8] = 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user