| /* $XFree86*/ /* -*- c-basic-offset: 3 -*- */ |
| /* |
| * Copyright 2005 Eric Anholt |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * Authors: |
| * Eric Anholt <anholt@FreeBSD.org> |
| * Jim Duchek <jim@linuxpimps.com> -- Utah GLX 6326 code |
| * Alan Cox <alan@redhat.com> -- 6326 Debugging |
| * |
| */ |
| |
| static void TAG(sis_draw_tri_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); |
| sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2); |
| |
| mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 3); |
| SIS_MMIO_WRITE_VERTEX(v0, 0, 0); |
| SIS_MMIO_WRITE_VERTEX(v1, 1, 0); |
| SIS_MMIO_WRITE_VERTEX(v2, 2, 1); |
| } |
| |
| static void TAG(sis_draw_line_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); |
| |
| mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2); |
| SIS_MMIO_WRITE_VERTEX(v0, 0, 0); |
| SIS_MMIO_WRITE_VERTEX(v1, 1, 1); |
| } |
| |
| static void TAG(sis_draw_point_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| |
| mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1); |
| SIS_MMIO_WRITE_VERTEX(v0, 1, 1); |
| } |
| |
| #if !(SIS_STATES & VERT_UV1) |
| static void TAG(sis6326_draw_tri_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); |
| sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2); |
| GLfloat x0, x1, x2; |
| GLfloat y0, y1, y2; |
| GLfloat delt02, diffx02, diffy02, diffy12; |
| GLint dwPrimitiveSet = smesa->dwPrimitiveSet; |
| sisVertex tv0, tv1, tv2; |
| |
| /* XXX Culling? */ |
| |
| tv0 = *v0; |
| tv1 = *v1; |
| tv2 = *v2; |
| tv0.v.y = Y_FLIP(tv0.v.y); |
| tv1.v.y = Y_FLIP(tv1.v.y); |
| tv2.v.y = Y_FLIP(tv2.v.y); |
| v0 = &tv0; |
| v1 = &tv1; |
| v2 = &tv2; |
| |
| /* Cull polygons we won't draw. The hardware draws funky things if it |
| is fed these */ |
| if((((v1->v.x - v0->v.x) * (v0->v.y - v2->v.y)) + |
| ((v1->v.y - v0->v.y) * (v2->v.x - v0->v.x))) < 0) |
| return; |
| y0 = v0->v.y; |
| y1 = v1->v.y; |
| y2 = v2->v.y; |
| |
| |
| if (y0 > y1) { |
| if (y1 > y2) { |
| x0 = v0->v.x; |
| x1 = v1->v.x; |
| x2 = v2->v.x; |
| dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BMID | OP_6326_3D_CBOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT; |
| } else { |
| if (y0 > y2) { |
| x0 = v0->v.x; |
| x1 = v2->v.x; |
| y1 = v2->v.y; |
| dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_CMID | |
| OP_6326_3D_BBOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID; |
| } else { |
| x0 = v2->v.x; |
| y0 = v2->v.y; |
| x1 = v0->v.x; |
| y1 = v0->v.y; |
| dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_AMID | |
| OP_6326_3D_BBOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP; |
| } |
| x2 = v1->v.x; |
| y2 = v1->v.y; |
| } |
| } else { |
| if (y0 > y2) { |
| x0 = v1->v.x; |
| y0 = v1->v.y; |
| x1 = v0->v.x; |
| y1 = v0->v.y; |
| x2 = v2->v.x; |
| dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_AMID | OP_6326_3D_CBOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT; |
| } else { |
| if (y1 > y2) { |
| x0 = v1->v.x; |
| y0 = v1->v.y; |
| x1 = v2->v.x; |
| y1 = v2->v.y; |
| dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_CMID | |
| OP_6326_3D_ABOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID; |
| } else { |
| x0 = v2->v.x; |
| y0 = v2->v.y; |
| x1 = v1->v.x; |
| dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_BMID | |
| OP_6326_3D_ABOT; |
| if ((SIS_STATES & VERT_SMOOTH) == 0) |
| dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP; |
| } |
| x2 = v0->v.x; |
| y2 = v0->v.y; |
| } |
| } |
| |
| if (x1 <= x0 && x1 <= x2) { |
| dwPrimitiveSet |= OP_3D_DIRECTION_LEFT; |
| } else if (x1 < x0 || x1 < x2) { |
| GLfloat tmp; |
| |
| diffx02 = x0 - x2; |
| diffy02 = y0 - y2; |
| diffy12 = y1 - y2; |
| |
| delt02 = diffx02 / diffy02; |
| tmp = x1 - (diffy12 * delt02 + x2); |
| |
| if (tmp <= 0.0) |
| dwPrimitiveSet |= OP_3D_DIRECTION_LEFT; |
| } |
| |
| tv0 = *v0; |
| tv1 = *v1; |
| tv2 = *v2; |
| tv0.v.y = Y_FLIP(tv0.v.y); |
| tv1.v.y = Y_FLIP(tv1.v.y); |
| tv2.v.y = Y_FLIP(tv2.v.y); |
| v0 = &tv0; |
| v1 = &tv1; |
| v2 = &tv2; |
| |
| y0 = v0->v.y; |
| y1 = v1->v.y; |
| y2 = v2->v.y; |
| |
| /* fprintf(stderr, "Vertex0 %f %f %f\n", v0->v.x, v0->v.y, v0->v.z); |
| fprintf(stderr, "Vertex1 %f %f %f\n", v1->v.x, v1->v.y, v1->v.z); |
| fprintf(stderr, "Vertex2 %f %f %f\n", v2->v.x, v2->v.y, v2->v.z);*/ |
| mWait3DCmdQueue(MMIO_VERT_REG_COUNT * 3 + 1); |
| MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); |
| SIS_MMIO_WRITE_VERTEX(v0, 0, 0); |
| SIS_MMIO_WRITE_VERTEX(v1, 1, 0); |
| SIS_MMIO_WRITE_VERTEX(v2, 2, 1); |
| mEndPrimitive(); |
| } |
| |
| static void TAG(sis6326_draw_line_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); |
| GLint dwPrimitiveSet = smesa->dwPrimitiveSet; |
| |
| if (abs(v0->v.y - v1->v.y) > abs(v0->v.x - v1->v.x)) |
| { |
| dwPrimitiveSet |= OP_3D_DIRECTION_VERTICAL; |
| if (v0->v.y > v1->v.y) |
| dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT; |
| else |
| dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT; |
| } else { |
| if (v0->v.y > v1->v.y) |
| dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT; |
| else |
| dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT; |
| } |
| |
| mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2 + 1); |
| MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); |
| SIS_MMIO_WRITE_VERTEX(v0, 0, 0); |
| SIS_MMIO_WRITE_VERTEX(v1, 1, 1); |
| } |
| |
| static void TAG(sis6326_draw_point_mmio)(sisContextPtr smesa, char *verts) |
| { |
| sisVertexPtr v0 = (sisVertexPtr)verts; |
| |
| mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1 + 1); |
| MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet | OP_6326_3D_ATOP); |
| SIS_MMIO_WRITE_VERTEX(v0, 1, 1); |
| } |
| #endif |
| |
| static INLINE void TAG(sis_vert_init)( void ) |
| { |
| sis_tri_func_mmio[SIS_STATES] = TAG(sis_draw_tri_mmio); |
| sis_line_func_mmio[SIS_STATES] = TAG(sis_draw_line_mmio); |
| sis_point_func_mmio[SIS_STATES] = TAG(sis_draw_point_mmio); |
| #if !(SIS_STATES & VERT_UV1) |
| sis_tri_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_tri_mmio); |
| sis_line_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_line_mmio); |
| sis_point_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_point_mmio); |
| #endif |
| } |
| |
| #undef TAG |
| #undef SIS_STATES |