Refactor "class" texture environments to be implemented in terms of
[mesa.git] / src / mesa / drivers / dri / mga / mgacontext.h
1 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/
2 /*
3 * Copyright 2000-2001 VA Linux Systems, Inc.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29 #ifndef MGALIB_INC
30 #define MGALIB_INC
31
32 #include <inttypes.h>
33 #include "dri_util.h"
34 #include "mtypes.h"
35 #include "xf86drm.h"
36 #include "mm.h"
37 #include "mga_sarea.h"
38 #include "colormac.h"
39 #include "texmem.h"
40 #include "macros.h"
41 #include "xmlconfig.h"
42
43 #define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask))
44 #define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK))
45 #define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT))
46
47 #define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200)
48 #define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400)
49
50
51 /* SoftwareFallback
52 * - texture env GL_BLEND -- can be fixed
53 * - 1D and 3D textures
54 * - incomplete textures
55 * - GL_DEPTH_FUNC == GL_NEVER not in h/w
56 */
57 #define MGA_FALLBACK_TEXTURE 0x1
58 #define MGA_FALLBACK_DRAW_BUFFER 0x2
59 #define MGA_FALLBACK_READ_BUFFER 0x4
60 #define MGA_FALLBACK_BLEND 0x8
61 #define MGA_FALLBACK_RENDERMODE 0x10
62 #define MGA_FALLBACK_STENCIL 0x20
63 #define MGA_FALLBACK_DEPTH 0x40
64 #define MGA_FALLBACK_BORDER_MODE 0x80
65
66
67 /* Use the templated vertex formats:
68 */
69 #define TAG(x) mga##x
70 #include "tnl_dd/t_dd_vertex.h"
71 #undef TAG
72
73 typedef struct mga_context_t mgaContext;
74 typedef struct mga_context_t *mgaContextPtr;
75
76 typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *,
77 mgaVertex * );
78 typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * );
79 typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * );
80
81
82
83 /* Texture environment color
84 */
85 #define RGB_ZERO(c) (((c) & 0xffffff) == 0x000000)
86 #define RGB_ONE(c) (((c) & 0xffffff) == 0xffffff)
87 #define ALPHA_ZERO(c) (((c) >> 24) == 0x00)
88 #define ALPHA_ONE(c) (((c) >> 24) == 0xff)
89 #define RGBA_EQUAL(c) ((c) == PACK_COLOR_8888( (c) & 0xff, (c) & 0xff, \
90 (c) & 0xff, (c) & 0xff ))
91
92 struct mga_texture_object_s;
93 struct mga_screen_private_s;
94
95 #define G200_TEX_MAXLEVELS 5
96 #define G400_TEX_MAXLEVELS 11
97
98 typedef struct mga_texture_object_s
99 {
100 driTextureObject base;
101
102 /* The G200 only has the ability to use 5 mipmap levels (including the
103 * base level). The G400 does not have this restriction, but it still
104 * only has 5 offset pointers in the hardware. The trick on the G400 is
105 * upto the first 4 offset pointers point to mipmap levels. The last
106 * offset pointer tells how large the preceeding mipmap is. This value is
107 * then used to determine where the remaining mipmaps are.
108 *
109 * For example, if the first offsets[0] through offsets[2] are used as
110 * pointers, then offset[3] will be the size of the mipmap pointed to by
111 * offsets[2]. So mipmap level 3 will be at (offsets[2]+offsets[3]). For
112 * each successive mipmap level, offsets[3] is divided by 4 and added to
113 * the previous address. So mipmap level 4 will be at
114 * (offsets[2]+offsets[3]+(offsets[3] / 4)).
115 *
116 * The last pointer is selected by setting TO_texorgoffsetsel in its
117 * pointer. In the previous example, offset[2] would have
118 * TO_texorgoffsetsel or'ed in before writing it to the hardware.
119 *
120 * In the current driver all of the mipmaps are packed together linearly
121 * with mipmap level 0. Therefore offsets[0] points to the base of the
122 * texture (and has TO_texorgoffsetsel or'ed in), and offsets[1] is the
123 * size of the base texture.
124 *
125 * There is a possible optimization available here. At times the driver
126 * may not be able to allocate a single block of memory for the complete
127 * texture without ejecting some other textures from memory. It may be
128 * possible to put some of the lower mipmap levels (i.e., the larger
129 * mipmaps) in memory separate from the higher levels.
130 *
131 * The implementation should be fairly obvious, but getting "right" would
132 * likely be non-trivial. A first allocation for the entire texture would
133 * be attempted with a flag that says "don't eject other textures." If
134 * that failed, an additional allocation would be attmpted for just the
135 * base map. The process would repeat with the block of lower maps. The
136 * tricky parts would be in detecting when some of the levels had been
137 * ejected from texture memory by other textures and preventing the
138 * 4th allocation (for all the smallest mipmap levels) from kicking out
139 * any of the first three.
140 *
141 * This array holds G400_TEX_MAXLEVELS pointers to remove an if-statement
142 * in a loop in mgaSetTexImages. Values past G200_TEX_MAXLEVELS are not
143 * used.
144 */
145 GLuint offsets[G400_TEX_MAXLEVELS];
146
147 int texelBytes;
148 GLuint age;
149
150 mga_texture_regs_t setup;
151
152 /* If one texture dimension wraps with GL_CLAMP and the other with
153 * GL_CLAMP_TO_EDGE, we have to fallback to software. We would also have
154 * to fallback for GL_CLAMP_TO_BORDER.
155 */
156 GLboolean border_fallback;
157 /* Depending on multitxturing and environment color
158 * GL_BLEND may have to be a software fallback.
159 */
160 GLboolean texenv_fallback;
161 } mgaTextureObject_t;
162
163 struct mga_hw_state {
164 GLuint specen;
165 GLuint cull;
166 GLuint cull_dualtex;
167 GLuint stencil;
168 GLuint stencilctl;
169 GLuint stencil_enable;
170 GLuint zmode;
171 GLuint rop;
172 GLuint alpha_func;
173 GLuint alpha_func_enable;
174 GLuint blend_func;
175 GLuint blend_func_enable;
176 GLuint alpha_sel;
177 };
178
179 struct mga_context_t {
180
181 GLcontext *glCtx;
182 unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp,
183 * need to shadow it here. */
184
185 /* Hardware state management
186 */
187 struct mga_hw_state hw;
188
189 /* Bookkeeping for texturing
190 */
191 unsigned nr_heaps;
192 driTexHeap * texture_heaps[ MGA_NR_TEX_HEAPS ];
193 driTextureObject swapped;
194
195 struct mga_texture_object_s *CurrentTexObj[2];
196
197
198 /* Map GL texture units onto hardware.
199 */
200 GLuint tmu_source[2];
201
202 int texture_depth;
203
204 /* Manage fallbacks
205 */
206 GLuint Fallback;
207
208 /* Texture environment color.
209 */
210 unsigned int envcolor[2];
211 GLboolean fcol_used;
212 GLboolean force_dualtex;
213
214 /* Rasterization state
215 */
216 GLuint SetupNewInputs;
217 GLuint SetupIndex;
218 GLuint RenderIndex;
219
220 GLuint hw_primitive;
221 GLenum raster_primitive;
222 GLenum render_primitive;
223
224 GLubyte *verts;
225 GLint vertex_stride_shift;
226 GLuint vertex_format;
227 GLuint vertex_size;
228
229 /* Fallback rasterization functions
230 */
231 mga_point_func draw_point;
232 mga_line_func draw_line;
233 mga_tri_func draw_tri;
234
235
236 /* Manage driver and hardware state
237 */
238 GLuint NewGLState;
239 GLuint dirty;
240
241 mga_context_regs_t setup;
242
243 GLuint ClearColor;
244 GLuint ClearDepth;
245 GLuint poly_stipple;
246 GLfloat depth_scale;
247
248 GLuint depth_clear_mask;
249 GLuint stencil_clear_mask;
250 GLuint hw_stencil;
251 GLuint haveHwStipple;
252 GLfloat hw_viewport[16];
253
254 /* Dma buffers
255 */
256 drmBufPtr vertex_dma_buffer;
257 drmBufPtr iload_buffer;
258
259 /* VBI
260 */
261 GLuint vbl_seq;
262 GLuint vblank_flags;
263
264 int64_t swap_ust;
265 int64_t swap_missed_ust;
266
267 GLuint swap_count;
268 GLuint swap_missed_count;
269
270 PFNGLXGETUSTPROC get_ust;
271
272 /* Drawable, cliprect and scissor information
273 */
274 int dirty_cliprects; /* which sets of cliprects are uptodate? */
275 int draw_buffer; /* which buffer are we rendering to */
276 unsigned int drawOffset; /* draw buffer address in space */
277 int readOffset;
278 int drawX, drawY; /* origin of drawable in draw buffer */
279 int lastX, lastY; /* detect DSTORG bug */
280 GLuint numClipRects; /* cliprects for the draw buffer */
281 XF86DRIClipRectPtr pClipRects;
282 XF86DRIClipRectRec draw_rect;
283 XF86DRIClipRectRec scissor_rect;
284 int scissor;
285
286 XF86DRIClipRectRec tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS];
287
288
289 /* Texture aging and DMA based aging.
290 */
291 unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */
292 unsigned int dirtyAge; /* buffer age for synchronization */
293
294 GLuint primary_offset;
295
296 /* Mirrors of some DRI state.
297 */
298 drmContext hHWContext;
299 drmLock *driHwLock;
300 int driFd;
301 __DRIdrawablePrivate *driDrawable;
302 __DRIdrawablePrivate *driReadable;
303
304 /**
305 * Drawable used by Mesa for software fallbacks for reading and
306 * writing. It is set by Mesa's \c SetBuffer callback, and will always be
307 * either \c mga_context_t::driDrawable or \c mga_context_t::driReadable.
308 */
309 __DRIdrawablePrivate *mesa_drawable;
310
311 __DRIscreenPrivate *driScreen;
312 struct mga_screen_private_s *mgaScreen;
313 MGASAREAPrivPtr sarea;
314
315 /* Configuration cache
316 */
317 driOptionCache optionCache;
318 };
319
320 #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx))
321
322
323
324
325 /* ================================================================
326 * Debugging:
327 */
328 #define DO_DEBUG 1
329
330 #if DO_DEBUG
331 extern int MGA_DEBUG;
332 #else
333 #define MGA_DEBUG 0
334 #endif
335
336 #define DEBUG_VERBOSE_MSG 0x01
337 #define DEBUG_VERBOSE_DRI 0x02
338 #define DEBUG_VERBOSE_IOCTL 0x04
339 #define DEBUG_VERBOSE_TEXTURE 0x08
340 #define DEBUG_VERBOSE_FALLBACK 0x10
341
342 static __inline__ GLuint mgaPackColor(GLuint cpp,
343 GLubyte r, GLubyte g,
344 GLubyte b, GLubyte a)
345 {
346 switch (cpp) {
347 case 2:
348 return PACK_COLOR_565( r, g, b );
349 case 4:
350 return PACK_COLOR_8888( a, r, g, b );
351 default:
352 return 0;
353 }
354 }
355
356
357 /*
358 * Subpixel offsets for window coordinates:
359 */
360 #define SUBPIXEL_X (-0.5F)
361 #define SUBPIXEL_Y (-0.5F + 0.125)
362
363
364 #define MGA_WA_TRIANGLES 0x18000000
365 #define MGA_WA_TRISTRIP_T0 0x02010200
366 #define MGA_WA_TRIFAN_T0 0x01000408
367 #define MGA_WA_TRISTRIP_T0T1 0x02010400
368 #define MGA_WA_TRIFAN_T0T1 0x01000810
369
370 #endif