3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keith@tungstengraphics.com>
29 #include "math/m_translate.h"
31 #if (HAVE_HW_VIEWPORT)
32 #define UNVIEWPORT_VARS
33 #define UNVIEWPORT_X(x) x
34 #define UNVIEWPORT_Y(x) x
35 #define UNVIEWPORT_Z(x) x
42 #ifndef CHECK_HW_DIVIDE
43 #define CHECK_HW_DIVIDE 1
46 /* These don't need to be duplicated, but there's currently nowhere
47 * really convenient to put them. Need to build some actual .o files in
50 static void copy_pv_rgba4_spec5( struct gl_context
*ctx
, GLuint edst
, GLuint esrc
)
53 GLubyte
*verts
= GET_VERTEX_STORE();
54 GLuint size
= GET_VERTEX_SIZE();
55 GLuint
*dst
= (GLuint
*)(verts
+ (edst
* size
));
56 GLuint
*src
= (GLuint
*)(verts
+ (esrc
* size
));
61 static void copy_pv_rgba4( struct gl_context
*ctx
, GLuint edst
, GLuint esrc
)
64 GLubyte
*verts
= GET_VERTEX_STORE();
65 GLuint size
= GET_VERTEX_SIZE();
66 GLuint
*dst
= (GLuint
*)(verts
+ (edst
* size
));
67 GLuint
*src
= (GLuint
*)(verts
+ (esrc
* size
));
71 static void copy_pv_rgba3( struct gl_context
*ctx
, GLuint edst
, GLuint esrc
)
74 GLubyte
*verts
= GET_VERTEX_STORE();
75 GLuint size
= GET_VERTEX_SIZE();
76 GLuint
*dst
= (GLuint
*)(verts
+ (edst
* size
));
77 GLuint
*src
= (GLuint
*)(verts
+ (esrc
* size
));
82 void TAG(translate_vertex
)(struct gl_context
*ctx
,
87 GLuint format
= GET_VERTEX_FORMAT();
88 GLfloat
*s
= ctx
->Viewport
._WindowMap
.m
;
91 if (format
== TINY_VERTEX_FORMAT
) {
92 if (HAVE_HW_VIEWPORT
) {
93 dst
->attrib
[VARYING_SLOT_POS
][0] = s
[0] * src
->v
.x
+ s
[12];
94 dst
->attrib
[VARYING_SLOT_POS
][1] = s
[5] * src
->v
.y
+ s
[13];
95 dst
->attrib
[VARYING_SLOT_POS
][2] = s
[10] * src
->v
.z
+ s
[14];
96 dst
->attrib
[VARYING_SLOT_POS
][3] = 1.0;
98 dst
->attrib
[VARYING_SLOT_POS
][0] = UNVIEWPORT_X( src
->v
.x
);
99 dst
->attrib
[VARYING_SLOT_POS
][1] = UNVIEWPORT_Y( src
->v
.y
);
100 dst
->attrib
[VARYING_SLOT_POS
][2] = UNVIEWPORT_Z( src
->v
.z
);
101 dst
->attrib
[VARYING_SLOT_POS
][3] = 1.0;
104 dst
->color
[0] = src
->tv
.color
.red
;
105 dst
->color
[1] = src
->tv
.color
.green
;
106 dst
->color
[2] = src
->tv
.color
.blue
;
107 dst
->color
[3] = src
->tv
.color
.alpha
;
110 if (HAVE_HW_VIEWPORT
) {
111 if (HAVE_HW_DIVIDE
&& CHECK_HW_DIVIDE
) {
112 GLfloat oow
= 1.0 / src
->v
.w
;
113 dst
->attrib
[VARYING_SLOT_POS
][0] = s
[0] * src
->v
.x
* oow
+ s
[12];
114 dst
->attrib
[VARYING_SLOT_POS
][1] = s
[5] * src
->v
.y
* oow
+ s
[13];
115 dst
->attrib
[VARYING_SLOT_POS
][2] = s
[10] * src
->v
.z
* oow
+ s
[14];
116 dst
->attrib
[VARYING_SLOT_POS
][3] = oow
;
118 dst
->attrib
[VARYING_SLOT_POS
][0] = s
[0] * src
->v
.x
+ s
[12];
119 dst
->attrib
[VARYING_SLOT_POS
][1] = s
[5] * src
->v
.y
+ s
[13];
120 dst
->attrib
[VARYING_SLOT_POS
][2] = s
[10] * src
->v
.z
+ s
[14];
121 dst
->attrib
[VARYING_SLOT_POS
][3] = src
->v
.w
;
124 dst
->attrib
[VARYING_SLOT_POS
][0] = UNVIEWPORT_X( src
->v
.x
);
125 dst
->attrib
[VARYING_SLOT_POS
][1] = UNVIEWPORT_Y( src
->v
.y
);
126 dst
->attrib
[VARYING_SLOT_POS
][2] = UNVIEWPORT_Z( src
->v
.z
);
127 dst
->attrib
[VARYING_SLOT_POS
][3] = src
->v
.w
;
130 dst
->color
[0] = src
->v
.color
.red
;
131 dst
->color
[1] = src
->v
.color
.green
;
132 dst
->color
[2] = src
->v
.color
.blue
;
133 dst
->color
[3] = src
->v
.color
.alpha
;
135 dst
->attrib
[VARYING_SLOT_COL1
][0] = UBYTE_TO_FLOAT(src
->v
.specular
.red
);
136 dst
->attrib
[VARYING_SLOT_COL1
][1] = UBYTE_TO_FLOAT(src
->v
.specular
.green
);
137 dst
->attrib
[VARYING_SLOT_COL1
][2] = UBYTE_TO_FLOAT(src
->v
.specular
.blue
);
139 dst
->attrib
[VARYING_SLOT_FOGC
][0] = UBYTE_TO_FLOAT(src
->v
.specular
.alpha
);
141 if (HAVE_PTEX_VERTICES
&&
142 ((HAVE_TEX2_VERTICES
&& format
== PROJ_TEX3_VERTEX_FORMAT
) ||
143 (format
== PROJ_TEX1_VERTEX_FORMAT
))) {
145 dst
->attrib
[VARYING_SLOT_TEX0
][0] = src
->pv
.u0
;
146 dst
->attrib
[VARYING_SLOT_TEX0
][1] = src
->pv
.v0
;
147 dst
->attrib
[VARYING_SLOT_TEX0
][3] = src
->pv
.q0
;
149 dst
->attrib
[VARYING_SLOT_TEX1
][0] = src
->pv
.u1
;
150 dst
->attrib
[VARYING_SLOT_TEX1
][1] = src
->pv
.v1
;
151 dst
->attrib
[VARYING_SLOT_TEX1
][3] = src
->pv
.q1
;
153 if (HAVE_TEX2_VERTICES
) {
154 dst
->attrib
[VARYING_SLOT_TEX2
][0] = src
->pv
.u2
;
155 dst
->attrib
[VARYING_SLOT_TEX2
][1] = src
->pv
.v2
;
156 dst
->attrib
[VARYING_SLOT_TEX2
][3] = src
->pv
.q2
;
159 if (HAVE_TEX3_VERTICES
) {
160 dst
->attrib
[VARYING_SLOT_TEX3
][0] = src
->pv
.u3
;
161 dst
->attrib
[VARYING_SLOT_TEX3
][1] = src
->pv
.v3
;
162 dst
->attrib
[VARYING_SLOT_TEX3
][3] = src
->pv
.q3
;
166 dst
->attrib
[VARYING_SLOT_TEX0
][0] = src
->v
.u0
;
167 dst
->attrib
[VARYING_SLOT_TEX0
][1] = src
->v
.v0
;
168 dst
->attrib
[VARYING_SLOT_TEX0
][3] = 1.0;
170 dst
->attrib
[VARYING_SLOT_TEX1
][0] = src
->v
.u1
;
171 dst
->attrib
[VARYING_SLOT_TEX1
][1] = src
->v
.v1
;
172 dst
->attrib
[VARYING_SLOT_TEX1
][3] = 1.0;
174 if (HAVE_TEX2_VERTICES
) {
175 dst
->attrib
[VARYING_SLOT_TEX2
][0] = src
->v
.u2
;
176 dst
->attrib
[VARYING_SLOT_TEX2
][1] = src
->v
.v2
;
177 dst
->attrib
[VARYING_SLOT_TEX2
][3] = 1.0;
180 if (HAVE_TEX3_VERTICES
) {
181 dst
->attrib
[VARYING_SLOT_TEX3
][0] = src
->v
.u3
;
182 dst
->attrib
[VARYING_SLOT_TEX3
][1] = src
->v
.v3
;
183 dst
->attrib
[VARYING_SLOT_TEX3
][3] = 1.0;
188 dst
->pointSize
= ctx
->Point
.Size
;
192 /* prototype to silence warning */
193 void TAG(print_vertex
)( struct gl_context
*ctx
, const VERTEX
*v
);
196 void TAG(print_vertex
)( struct gl_context
*ctx
, const VERTEX
*v
)
199 GLuint format
= GET_VERTEX_FORMAT();
201 fprintf(stderr
, "(%x) ", format
);
204 #if HAVE_TINY_VERTICES
205 case TINY_VERTEX_FORMAT
:
206 fprintf(stderr
, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n",
207 v
->v
.x
, v
->v
.y
, v
->v
.z
,
214 #if HAVE_NOTEX_VERTICES
215 case NOTEX_VERTEX_FORMAT
:
216 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n",
217 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
225 v
->v
.specular
.alpha
);
228 #if HAVE_TEX0_VERTICES
229 case TEX0_VERTEX_FORMAT
:
230 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n",
231 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
240 #if HAVE_TEX1_VERTICES
241 case TEX1_VERTEX_FORMAT
:
242 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n",
243 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
254 #if HAVE_PTEX_VERTICES
255 case PROJ_TEX1_VERTEX_FORMAT
:
256 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n",
257 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
271 fprintf(stderr
, "???\n");
275 fprintf(stderr
, "\n");
280 /* Interpolate the elements of the VB not included in typical hardware
283 * NOTE: All these arrays are guarenteed by tnl to be writeable and
286 #ifndef INTERP_QUALIFIER
287 #define INTERP_QUALIFIER static
290 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
293 INTERP_QUALIFIER
void TAG(interp_extras
)( struct gl_context
*ctx
,
295 GLuint dst
, GLuint out
, GLuint in
,
296 GLboolean force_boundary
)
299 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
301 if (VB
->BackfaceColorPtr
) {
302 assert(VB
->BackfaceColorPtr
->stride
== 4 * sizeof(GLfloat
));
305 GET_COLOR(VB
->BackfaceColorPtr
, dst
),
306 GET_COLOR(VB
->BackfaceColorPtr
, out
),
307 GET_COLOR(VB
->BackfaceColorPtr
, in
) );
309 if (VB
->BackfaceSecondaryColorPtr
) {
311 GET_COLOR(VB
->BackfaceSecondaryColorPtr
, dst
),
312 GET_COLOR(VB
->BackfaceSecondaryColorPtr
, out
),
313 GET_COLOR(VB
->BackfaceSecondaryColorPtr
, in
) );
318 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
321 INTERP_VERTEX(ctx
, t
, dst
, out
, in
, force_boundary
);
324 INTERP_QUALIFIER
void TAG(copy_pv_extras
)( struct gl_context
*ctx
,
325 GLuint dst
, GLuint src
)
328 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
330 if (VB
->BackfaceColorPtr
) {
331 COPY_4FV( GET_COLOR(VB
->BackfaceColorPtr
, dst
),
332 GET_COLOR(VB
->BackfaceColorPtr
, src
) );
334 if (VB
->BackfaceSecondaryColorPtr
) {
335 COPY_4FV( GET_COLOR(VB
->BackfaceSecondaryColorPtr
, dst
),
336 GET_COLOR(VB
->BackfaceSecondaryColorPtr
, src
) );
340 COPY_PV_VERTEX(ctx
, dst
, src
);
344 #undef INTERP_QUALIFIER