i965: Gen6 no longer has the IFF instruction; always use IF.
[mesa.git] / src / mesa / drivers / dri / sis / sis_tritmp.h
1 /* $XFree86*/ /* -*- c-basic-offset: 3 -*- */
2 /*
3 * Copyright 2005 Eric Anholt
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <anholt@FreeBSD.org>
27 * Jim Duchek <jim@linuxpimps.com> -- Utah GLX 6326 code
28 * Alan Cox <alan@redhat.com> -- 6326 Debugging
29 *
30 */
31
32 static void TAG(sis_draw_tri_mmio)(sisContextPtr smesa, char *verts)
33 {
34 sisVertexPtr v0 = (sisVertexPtr)verts;
35 sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
36 sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2);
37
38 mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 3);
39 SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
40 SIS_MMIO_WRITE_VERTEX(v1, 1, 0);
41 SIS_MMIO_WRITE_VERTEX(v2, 2, 1);
42 }
43
44 static void TAG(sis_draw_line_mmio)(sisContextPtr smesa, char *verts)
45 {
46 sisVertexPtr v0 = (sisVertexPtr)verts;
47 sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
48
49 mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2);
50 SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
51 SIS_MMIO_WRITE_VERTEX(v1, 1, 1);
52 }
53
54 static void TAG(sis_draw_point_mmio)(sisContextPtr smesa, char *verts)
55 {
56 sisVertexPtr v0 = (sisVertexPtr)verts;
57
58 mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1);
59 SIS_MMIO_WRITE_VERTEX(v0, 1, 1);
60 }
61
62 #if !(SIS_STATES & VERT_UV1)
63 static void TAG(sis6326_draw_tri_mmio)(sisContextPtr smesa, char *verts)
64 {
65 sisVertexPtr v0 = (sisVertexPtr)verts;
66 sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
67 sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2);
68 GLfloat x0, x1, x2;
69 GLfloat y0, y1, y2;
70 GLfloat delt02, diffx02, diffy02, diffy12;
71 GLint dwPrimitiveSet = smesa->dwPrimitiveSet;
72 sisVertex tv0, tv1, tv2;
73
74 /* XXX Culling? */
75
76 tv0 = *v0;
77 tv1 = *v1;
78 tv2 = *v2;
79 tv0.v.y = Y_FLIP(tv0.v.y);
80 tv1.v.y = Y_FLIP(tv1.v.y);
81 tv2.v.y = Y_FLIP(tv2.v.y);
82 v0 = &tv0;
83 v1 = &tv1;
84 v2 = &tv2;
85
86 /* Cull polygons we won't draw. The hardware draws funky things if it
87 is fed these */
88 if((((v1->v.x - v0->v.x) * (v0->v.y - v2->v.y)) +
89 ((v1->v.y - v0->v.y) * (v2->v.x - v0->v.x))) < 0)
90 return;
91 y0 = v0->v.y;
92 y1 = v1->v.y;
93 y2 = v2->v.y;
94
95
96 if (y0 > y1) {
97 if (y1 > y2) {
98 x0 = v0->v.x;
99 x1 = v1->v.x;
100 x2 = v2->v.x;
101 dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BMID | OP_6326_3D_CBOT;
102 if ((SIS_STATES & VERT_SMOOTH) == 0)
103 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT;
104 } else {
105 if (y0 > y2) {
106 x0 = v0->v.x;
107 x1 = v2->v.x;
108 y1 = v2->v.y;
109 dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_CMID |
110 OP_6326_3D_BBOT;
111 if ((SIS_STATES & VERT_SMOOTH) == 0)
112 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID;
113 } else {
114 x0 = v2->v.x;
115 y0 = v2->v.y;
116 x1 = v0->v.x;
117 y1 = v0->v.y;
118 dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_AMID |
119 OP_6326_3D_BBOT;
120 if ((SIS_STATES & VERT_SMOOTH) == 0)
121 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP;
122 }
123 x2 = v1->v.x;
124 y2 = v1->v.y;
125 }
126 } else {
127 if (y0 > y2) {
128 x0 = v1->v.x;
129 y0 = v1->v.y;
130 x1 = v0->v.x;
131 y1 = v0->v.y;
132 x2 = v2->v.x;
133 dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_AMID | OP_6326_3D_CBOT;
134 if ((SIS_STATES & VERT_SMOOTH) == 0)
135 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT;
136 } else {
137 if (y1 > y2) {
138 x0 = v1->v.x;
139 y0 = v1->v.y;
140 x1 = v2->v.x;
141 y1 = v2->v.y;
142 dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_CMID |
143 OP_6326_3D_ABOT;
144 if ((SIS_STATES & VERT_SMOOTH) == 0)
145 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID;
146 } else {
147 x0 = v2->v.x;
148 y0 = v2->v.y;
149 x1 = v1->v.x;
150 dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_BMID |
151 OP_6326_3D_ABOT;
152 if ((SIS_STATES & VERT_SMOOTH) == 0)
153 dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP;
154 }
155 x2 = v0->v.x;
156 y2 = v0->v.y;
157 }
158 }
159
160 if (x1 <= x0 && x1 <= x2) {
161 dwPrimitiveSet |= OP_3D_DIRECTION_LEFT;
162 } else if (x1 < x0 || x1 < x2) {
163 GLfloat tmp;
164
165 diffx02 = x0 - x2;
166 diffy02 = y0 - y2;
167 diffy12 = y1 - y2;
168
169 delt02 = diffx02 / diffy02;
170 tmp = x1 - (diffy12 * delt02 + x2);
171
172 if (tmp <= 0.0)
173 dwPrimitiveSet |= OP_3D_DIRECTION_LEFT;
174 }
175
176 tv0 = *v0;
177 tv1 = *v1;
178 tv2 = *v2;
179 tv0.v.y = Y_FLIP(tv0.v.y);
180 tv1.v.y = Y_FLIP(tv1.v.y);
181 tv2.v.y = Y_FLIP(tv2.v.y);
182 v0 = &tv0;
183 v1 = &tv1;
184 v2 = &tv2;
185
186 y0 = v0->v.y;
187 y1 = v1->v.y;
188 y2 = v2->v.y;
189
190 /* fprintf(stderr, "Vertex0 %f %f %f\n", v0->v.x, v0->v.y, v0->v.z);
191 fprintf(stderr, "Vertex1 %f %f %f\n", v1->v.x, v1->v.y, v1->v.z);
192 fprintf(stderr, "Vertex2 %f %f %f\n", v2->v.x, v2->v.y, v2->v.z);*/
193 mWait3DCmdQueue(MMIO_VERT_REG_COUNT * 3 + 1);
194 MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
195 SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
196 SIS_MMIO_WRITE_VERTEX(v1, 1, 0);
197 SIS_MMIO_WRITE_VERTEX(v2, 2, 1);
198 mEndPrimitive();
199 }
200
201 static void TAG(sis6326_draw_line_mmio)(sisContextPtr smesa, char *verts)
202 {
203 sisVertexPtr v0 = (sisVertexPtr)verts;
204 sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4);
205 GLint dwPrimitiveSet = smesa->dwPrimitiveSet;
206
207 if (abs(v0->v.y - v1->v.y) > abs(v0->v.x - v1->v.x))
208 {
209 dwPrimitiveSet |= OP_3D_DIRECTION_VERTICAL;
210 if (v0->v.y > v1->v.y)
211 dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT;
212 else
213 dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT;
214 } else {
215 if (v0->v.y > v1->v.y)
216 dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT;
217 else
218 dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT;
219 }
220
221 mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2 + 1);
222 MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
223 SIS_MMIO_WRITE_VERTEX(v0, 0, 0);
224 SIS_MMIO_WRITE_VERTEX(v1, 1, 1);
225 }
226
227 static void TAG(sis6326_draw_point_mmio)(sisContextPtr smesa, char *verts)
228 {
229 sisVertexPtr v0 = (sisVertexPtr)verts;
230
231 mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1 + 1);
232 MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet | OP_6326_3D_ATOP);
233 SIS_MMIO_WRITE_VERTEX(v0, 1, 1);
234 }
235 #endif
236
237 static INLINE void TAG(sis_vert_init)( void )
238 {
239 sis_tri_func_mmio[SIS_STATES] = TAG(sis_draw_tri_mmio);
240 sis_line_func_mmio[SIS_STATES] = TAG(sis_draw_line_mmio);
241 sis_point_func_mmio[SIS_STATES] = TAG(sis_draw_point_mmio);
242 #if !(SIS_STATES & VERT_UV1)
243 sis_tri_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_tri_mmio);
244 sis_line_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_line_mmio);
245 sis_point_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_point_mmio);
246 #endif
247 }
248
249 #undef TAG
250 #undef SIS_STATES