Implement 110 clipping
This commit is contained in:
parent
6d814fbc5b
commit
8d26e1b2c4
|
@ -1027,7 +1027,6 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
|
||||||
}
|
}
|
||||||
|
|
||||||
transform(target);
|
transform(target);
|
||||||
|
|
||||||
push(_glSubmissionTargetHeader(target), GL_FALSE, target->output, 0);
|
push(_glSubmissionTargetHeader(target), GL_FALSE, target->output, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
119
GL/flush.c
119
GL/flush.c
|
@ -161,6 +161,81 @@ GL_FORCE_INLINE GLboolean shift(ListIterator* it, Vertex* new_vertex) {
|
||||||
return new_vertex != NULL;
|
return new_vertex != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ListIterator* finish_clip(ListIterator* it) {
|
||||||
|
/* When we've clipped a triangle, we either need to reduce
|
||||||
|
* the triangle_count so that next iteration we move to the next
|
||||||
|
* triangle OR we need to shift away the vertices in the triangle
|
||||||
|
* buffer entirely so next iteration starts a new strip.
|
||||||
|
* FIXME: Do we need to swap the verts in the triangle buffer for winding? */
|
||||||
|
|
||||||
|
if(it->current && isVertex(it->current)) {
|
||||||
|
/* Continue */
|
||||||
|
it->triangle_count--;
|
||||||
|
} else {
|
||||||
|
/* Restart strip */
|
||||||
|
while(it->triangle_count) {
|
||||||
|
shift(it, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ListIterator* clip100(ListIterator* it) {
|
||||||
|
/* First visible only */
|
||||||
|
Vertex* gen2 = push_stack(it);
|
||||||
|
Vertex* gen1 = push_stack(it);
|
||||||
|
|
||||||
|
interpolate_vertex(it->triangle[0], it->triangle[1], gen1);
|
||||||
|
interpolate_vertex(it->triangle[0], it->triangle[2], gen2);
|
||||||
|
|
||||||
|
gen1->flags = PVR_CMD_VERTEX;
|
||||||
|
gen2->flags = PVR_CMD_VERTEX_EOL;
|
||||||
|
|
||||||
|
assert(isVisible(gen1));
|
||||||
|
assert(isVisible(gen2));
|
||||||
|
assert(isVertex(gen1));
|
||||||
|
assert(isVertex(gen2));
|
||||||
|
|
||||||
|
it->it = it->triangle[0];
|
||||||
|
|
||||||
|
return finish_clip(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ListIterator* clip110(ListIterator* it) {
|
||||||
|
/* First two visible. so we need to create 2 new vertices from
|
||||||
|
* A -> C, and B -> C. */
|
||||||
|
Vertex* gen2 = push_stack(it);
|
||||||
|
Vertex* gen1 = push_stack(it);
|
||||||
|
Vertex* cpy = push_stack(it);
|
||||||
|
|
||||||
|
gen1->flags = PVR_CMD_VERTEX;
|
||||||
|
gen2->flags = PVR_CMD_VERTEX_EOL;
|
||||||
|
|
||||||
|
interpolate_vertex(it->triangle[0], it->triangle[2], gen1);
|
||||||
|
interpolate_vertex(it->triangle[1], it->triangle[2], gen2);
|
||||||
|
|
||||||
|
assert(isVisible(gen1));
|
||||||
|
assert(isVisible(gen2));
|
||||||
|
assert(isVertex(gen1));
|
||||||
|
assert(isVertex(gen2));
|
||||||
|
|
||||||
|
/* We copy vertex B, so that things are returned in order */
|
||||||
|
*cpy = *it->triangle[1];
|
||||||
|
|
||||||
|
/* Return A */
|
||||||
|
it->it = it->triangle[0];
|
||||||
|
|
||||||
|
return finish_clip(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ListIterator* clip101(ListIterator* it) {
|
||||||
|
/* First visible and last visible. Need to create two
|
||||||
|
* vertices in between first and last! */
|
||||||
|
|
||||||
|
return finish_clip(it);
|
||||||
|
}
|
||||||
|
|
||||||
ListIterator* _glIteratorNext(ListIterator* it) {
|
ListIterator* _glIteratorNext(ListIterator* it) {
|
||||||
printf("R: %d\n", it->remaining);
|
printf("R: %d\n", it->remaining);
|
||||||
|
|
||||||
|
@ -191,7 +266,7 @@ ListIterator* _glIteratorNext(ListIterator* it) {
|
||||||
if(is_header && it->triangle_count) {
|
if(is_header && it->triangle_count) {
|
||||||
shift(it, NULL);
|
shift(it, NULL);
|
||||||
it->it = it->triangle[0];
|
it->it = it->triangle[0];
|
||||||
printf("Returning before header\n");
|
printf("Returning before header (%d)\n", it->triangle_count);
|
||||||
return it;
|
return it;
|
||||||
} else if(is_header) {
|
} else if(is_header) {
|
||||||
printf("Header\n");
|
printf("Header\n");
|
||||||
|
@ -218,35 +293,10 @@ ListIterator* _glIteratorNext(ListIterator* it) {
|
||||||
return it;
|
return it;
|
||||||
break;
|
break;
|
||||||
case B100: {
|
case B100: {
|
||||||
/* First visible only */
|
return clip100(it);
|
||||||
Vertex* gen2 = push_stack(it);
|
} break;
|
||||||
Vertex* gen1 = push_stack(it);
|
case B110: {
|
||||||
|
return clip110(it);
|
||||||
/* Make sure we transfer the flags.. we don't
|
|
||||||
* want to disrupt the strip */
|
|
||||||
gen1->flags = it->triangle[1]->flags;
|
|
||||||
gen2->flags = it->triangle[2]->flags;
|
|
||||||
|
|
||||||
interpolate_vertex(it->triangle[0], it->triangle[1], gen1);
|
|
||||||
interpolate_vertex(it->triangle[0], it->triangle[2], gen2);
|
|
||||||
it->visibility = B111; /* All visible now, yay! */
|
|
||||||
|
|
||||||
assert(isVisible(gen1));
|
|
||||||
assert(isVisible(gen2));
|
|
||||||
assert(isVertex(gen1));
|
|
||||||
assert(isVertex(gen2));
|
|
||||||
|
|
||||||
it->it = it->triangle[0];
|
|
||||||
|
|
||||||
/* We're returning v0, and we've pushed
|
|
||||||
* v1 and v2 to the stack, so next time
|
|
||||||
* around we'll need to consume and shift
|
|
||||||
* the next vertex from the source list */
|
|
||||||
while(it->triangle_count) {
|
|
||||||
shift(it, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return it;
|
|
||||||
} break;
|
} break;
|
||||||
case B000: {
|
case B000: {
|
||||||
/* If a triangle is invisible, there are 3 situations:
|
/* If a triangle is invisible, there are 3 situations:
|
||||||
|
@ -288,15 +338,16 @@ static void pvr_list_submit(void *src, int n) {
|
||||||
* always submitted (e.g. not clipped) */
|
* always submitted (e.g. not clipped) */
|
||||||
|
|
||||||
ListIterator* it = _glIteratorBegin(src, n);
|
ListIterator* it = _glIteratorBegin(src, n);
|
||||||
|
|
||||||
/* fill/write queues as many times necessary */
|
/* fill/write queues as many times necessary */
|
||||||
while(it) {
|
while(it) {
|
||||||
__asm__("pref @%0" : : "r"(it->current + 1)); /* prefetch 64 bytes for next loop */
|
__asm__("pref @%0" : : "r"(it->it + 1)); /* prefetch 64 bytes for next loop */
|
||||||
|
|
||||||
if(isVertex(it->current)) {
|
if(isVertex(it->it)) {
|
||||||
perspective_divide(it->current);
|
perspective_divide(it->it);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint* s = (GLuint*) it->current;
|
GLuint* s = (GLuint*) it->it;
|
||||||
|
|
||||||
d[0] = *(s++);
|
d[0] = *(s++);
|
||||||
d[1] = *(s++);
|
d[1] = *(s++);
|
||||||
|
|
|
@ -27,12 +27,14 @@ typedef struct {
|
||||||
/* Vertex to read from (this may not exist in the source list) */
|
/* Vertex to read from (this may not exist in the source list) */
|
||||||
Vertex* it;
|
Vertex* it;
|
||||||
|
|
||||||
/* < 8. Bitmask of the last 3 vertices */
|
/* Sliding window into the source view */
|
||||||
Vertex* triangle[3];
|
Vertex* triangle[3];
|
||||||
|
|
||||||
/* Stack of temporary vertices */
|
/* Stack of temporary vertices */
|
||||||
Vertex stack[MAX_STACK];
|
Vertex stack[MAX_STACK];
|
||||||
int8_t stack_idx;
|
int8_t stack_idx;
|
||||||
|
|
||||||
|
/* < 8. Bitmask of the last 3 vertices */
|
||||||
uint8_t visibility;
|
uint8_t visibility;
|
||||||
uint8_t triangle_count;
|
uint8_t triangle_count;
|
||||||
uint8_t padding;
|
uint8_t padding;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user