diff --git a/GL/draw.c b/GL/draw.c index 1809828..0fa99f3 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -826,81 +826,40 @@ static void generateElementsFastPath( #define likely(x) __builtin_expect(!!(x), 1) -static void generateArraysFastPath(SubmissionTarget* target, const GLsizei first, const GLuint count) { - Vertex* start = _glSubmissionTargetStart(target); - VertexExtra* 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; - - /* Copy the pos, uv and color directly in one go */ - 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) { - /* If we don't have vertices, do nothing */ - return; - } - - if(!col) { - col = (GLubyte*) &U4ONE; - dstride = 0; - } - - if(!uv) { - uv = (GLubyte*) &F2ZERO; - uvstride = 0; - } - - if(!st) { - st = (GLubyte*) &F2ZERO; - ststride = 0; - } - - if(!n) { - n = (GLubyte*) &F3Z; - nstride = 0; - } - - int_fast32_t i = count; - VertexExtra* ve = ve_start; - Vertex* it = start; - - while(i--) { - it->flags = GPU_CMD_VERTEX; - 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); - - ++it; - ++ve; - } +#define POLYMODE ALL +#define PROCESS_VERTEX_FLAGS(it, i) { \ + (it)->flags = GPU_CMD_VERTEX; \ } +#include "draw_fastpath.inc" +#undef PROCESS_VERTEX_FLAGS +#undef POLYMODE + +#define POLYMODE QUADS +#define PROCESS_VERTEX_FLAGS(it, i) { \ + if((i + 1) % 4 == 0) { \ + Vertex* prev = ((it) - 1); \ + Vertex t = (*prev); \ + *(prev) = *((it)); \ + *((it)) = t; \ + prev->flags = GPU_CMD_VERTEX; \ + it->flags = GPU_CMD_VERTEX_EOL; \ + } else { \ + it->flags = GPU_CMD_VERTEX; \ + } \ +} +#include "draw_fastpath.inc" +#undef PROCESS_VERTEX_FLAGS +#undef POLYMODE + +#define POLYMODE TRIS +#define PROCESS_VERTEX_FLAGS(it, i) { \ + it->flags = ((i + 1) % 3 == 0) ? GPU_CMD_VERTEX_EOL : GPU_CMD_VERTEX; \ +} +#include "draw_fastpath.inc" +#undef PROCESS_VERTEX_FLAGS +#undef POLYMODE + static void generateArrays(SubmissionTarget* target, const GLsizei first, const GLuint count) { Vertex* start = _glSubmissionTargetStart(target); VertexExtra* ve = aligned_vector_at(target->extras, 0); @@ -927,7 +886,13 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei if(indices) { generateElementsFastPath(target, first, count, indices, type); } else { - generateArraysFastPath(target, first, count); + if(mode == GL_QUADS) { + generateArraysFastPath_QUADS(target, first, count); + } else if(mode == GL_TRIANGLES) { + generateArraysFastPath_TRIS(target, first, count); + } else { + generateArraysFastPath_ALL(target, first, count); + } } } else { if(indices) { @@ -941,10 +906,8 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei // Drawing arrays switch(mode) { case GL_TRIANGLES: - genTriangles(it, count); - break; - case GL_QUADS: - genQuads(it, count); + break; // Already done + case GL_QUADS: // Already done break; case GL_TRIANGLE_FAN: genTriangleFan(it, count); diff --git a/GL/draw_fastpath.inc b/GL/draw_fastpath.inc new file mode 100644 index 0000000..d945d50 --- /dev/null +++ b/GL/draw_fastpath.inc @@ -0,0 +1,79 @@ +/* THIS FILE IS INCLUDED BY draw.c TO AVOID CODE DUPLICATION. IT'S AN UGLY HACK */ + +#define FUNC_NAME(mode) static void generateArraysFastPath##_##mode(SubmissionTarget* target, const GLsizei first, const GLuint count) +#define MAKE_FUNC(mode) FUNC_NAME(mode) + +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) { + /* If we don't have vertices, do nothing */ + return; + } + + if(!col) { + col = (GLubyte*) &U4ONE; + dstride = 0; + } + + if(!uv) { + uv = (GLubyte*) &F2ZERO; + uvstride = 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; + } +}