Rename the various function types in t_context.h to include a tnl_ prefix.
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_render.c
1 /*
2 * Copyright 2001 by Alan Hourihane.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
23 *
24 * 3DLabs Gamma driver.
25 *
26 */
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31 #include "imports.h"
32 #include "mtypes.h"
33
34 #include "tnl/t_context.h"
35
36 #include "gamma_context.h"
37 #include "gamma_tris.h"
38 #include "gamma_vb.h"
39
40
41 /* !! Should template this eventually !! */
42
43 static void gamma_emit( GLcontext *ctx, GLuint start, GLuint end)
44 {
45 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
46 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
47 GLfloat (*coord)[4];
48 GLuint coord_stride;
49 GLfloat (*col)[4];
50 GLuint col_stride;
51 int i;
52 GLuint tc0_stride = 0;
53 GLfloat (*tc0)[4] = 0;
54 GLuint tc0_size = 0;
55
56 col = VB->ColorPtr[0]->data;
57 col_stride = VB->ColorPtr[0]->stride;
58
59 if (ctx->Texture.Unit[0]._ReallyEnabled) {
60 tc0_stride = VB->TexCoordPtr[0]->stride;
61 tc0 = VB->TexCoordPtr[0]->data;
62 tc0_size = VB->TexCoordPtr[0]->size;
63 coord = VB->ClipPtr->data;
64 coord_stride = VB->ClipPtr->stride;
65 } else {
66 coord = VB->NdcPtr->data;
67 coord_stride = VB->NdcPtr->stride;
68 }
69
70 if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 4) {
71 for (i=start; i < end; i++) {
72 CHECK_DMA_BUFFER(gmesa, 9);
73 WRITEF(gmesa->buf, Tq4, tc0[i][3]);
74 WRITEF(gmesa->buf, Tr4, tc0[i][2]);
75 WRITEF(gmesa->buf, Tt4, tc0[i][0]);
76 WRITEF(gmesa->buf, Ts4, tc0[i][1]);
77 WRITE(gmesa->buf, PackedColor4, *(uint32_t*)col[i]);
78 WRITEF(gmesa->buf, Vw, coord[i][3]);
79 WRITEF(gmesa->buf, Vz, coord[i][2]);
80 WRITEF(gmesa->buf, Vy, coord[i][1]);
81 WRITEF(gmesa->buf, Vx4, coord[i][0]);
82 }
83 } else if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 2) {
84 for (i=start; i < end; i++) {
85 CHECK_DMA_BUFFER(gmesa, 7);
86 WRITEF(gmesa->buf, Tt2, tc0[i][0]);
87 WRITEF(gmesa->buf, Ts2, tc0[i][1]);
88 WRITE(gmesa->buf, PackedColor4, *(uint32_t*)col[i]);
89 WRITEF(gmesa->buf, Vw, coord[i][3]);
90 WRITEF(gmesa->buf, Vz, coord[i][2]);
91 WRITEF(gmesa->buf, Vy, coord[i][1]);
92 WRITEF(gmesa->buf, Vx4, coord[i][0]);
93 }
94 } else {
95 for (i=start; i < end; i++) {
96 CHECK_DMA_BUFFER(gmesa, 4);
97 WRITE(gmesa->buf, PackedColor4, *(uint32_t*)col[i]);
98 WRITEF(gmesa->buf, Vz, coord[i][2]);
99 WRITEF(gmesa->buf, Vy, coord[i][1]);
100 WRITEF(gmesa->buf, Vx3, coord[i][0]);
101 }
102 }
103 }
104
105 #define HAVE_POINTS 1
106 #define HAVE_LINES 1
107 #define HAVE_LINE_STRIPS 1
108 #define HAVE_TRIANGLES 1
109 #define HAVE_TRI_STRIPS 1
110 #define HAVE_TRI_STRIP_1 0
111 #define HAVE_TRI_FANS 1
112 #define HAVE_QUADS 1
113 #define HAVE_QUAD_STRIPS 1
114 #define HAVE_POLYGONS 1
115
116 #define HAVE_ELTS 0
117
118
119 static const GLuint hw_prim[GL_POLYGON+1] = {
120 B_PrimType_Points,
121 B_PrimType_Lines,
122 B_PrimType_LineLoop,
123 B_PrimType_LineStrip,
124 B_PrimType_Triangles,
125 B_PrimType_TriangleStrip,
126 B_PrimType_TriangleFan,
127 B_PrimType_Quads,
128 B_PrimType_QuadStrip,
129 B_PrimType_Polygon
130 };
131
132 static __inline void gammaStartPrimitive( gammaContextPtr gmesa, GLenum prim )
133 {
134 CHECK_DMA_BUFFER(gmesa, 1);
135 WRITE(gmesa->buf, Begin, gmesa->Begin | hw_prim[prim]);
136 }
137
138 static __inline void gammaEndPrimitive( gammaContextPtr gmesa )
139 {
140 GLcontext *ctx = gmesa->glCtx;
141
142 if ( ctx->Line.SmoothFlag ||
143 ctx->Polygon.SmoothFlag ||
144 ctx->Point.SmoothFlag ) {
145 CHECK_DMA_BUFFER(gmesa, 1);
146 WRITE(gmesa->buf, FlushSpan, 0);
147 }
148
149 CHECK_DMA_BUFFER(gmesa, 1);
150 WRITE(gmesa->buf, End, 0);
151 }
152
153 #define LOCAL_VARS gammaContextPtr gmesa = GAMMA_CONTEXT(ctx)
154 #define INIT( prim ) gammaStartPrimitive( gmesa, prim )
155 #define FLUSH() gammaEndPrimitive( gmesa )
156 #define GET_CURRENT_VB_MAX_VERTS() \
157 (gmesa->bufSize - gmesa->bufCount) / 2
158 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
159 GAMMA_DMA_BUFFER_SIZE / 2
160
161 #define ALLOC_VERTS( nr ) (void *)0 /* todo: explicit alloc */
162 #define EMIT_VERTS( ctx, j, nr, buf ) (gamma_emit(ctx, j, (j)+(nr)), (void *)0)
163
164 #define TAG(x) gamma_##x
165 #include "tnl_dd/t_dd_dmatmp.h"
166
167
168 /**********************************************************************/
169 /* Render pipeline stage */
170 /**********************************************************************/
171
172
173 static GLboolean gamma_run_render( GLcontext *ctx,
174 struct tnl_pipeline_stage *stage )
175 {
176 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
177 TNLcontext *tnl = TNL_CONTEXT(ctx);
178 struct vertex_buffer *VB = &tnl->vb;
179 GLuint i;
180 tnl_render_func *tab;
181
182 /* GH: THIS IS A HACK!!! */
183 if (VB->ClipOrMask || gmesa->RenderIndex != 0)
184 return GL_TRUE; /* don't handle clipping here */
185
186 /* We don't do elts */
187 if (VB->Elts || !gamma_validate_render( ctx, VB ))
188 return GL_TRUE;
189
190 tab = TAG(render_tab_verts);
191
192 tnl->Driver.Render.Start( ctx );
193
194 for (i = 0 ; i < VB->PrimitiveCount ; i++)
195 {
196 GLuint prim = VB->Primitive[i].mode;
197 GLuint start = VB->Primitive[i].start;
198 GLuint length = VB->Primitive[i].count;
199
200 if (!length)
201 continue;
202
203 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim);
204 }
205
206 tnl->Driver.Render.Finish( ctx );
207
208 return GL_FALSE; /* finished the pipe */
209 }
210
211
212 static void gamma_check_render( GLcontext *ctx,
213 struct tnl_pipeline_stage *stage )
214 {
215 stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
216 }
217
218
219 static void dtr( struct tnl_pipeline_stage *stage )
220 {
221 (void)stage;
222 }
223
224
225 const struct tnl_pipeline_stage _gamma_render_stage =
226 {
227 "gamma render",
228 (_DD_NEW_SEPARATE_SPECULAR |
229 _NEW_TEXTURE|
230 _NEW_FOG|
231 _NEW_RENDERMODE), /* re-check (new inputs) */
232 0, /* re-run (always runs) */
233 GL_TRUE, /* active */
234 0, 0, /* inputs (set in check_render), outputs */
235 0, 0, /* changed_inputs, private */
236 dtr, /* destructor */
237 gamma_check_render, /* check - initially set to alloc data */
238 gamma_run_render /* run */
239 };