2 * Copyright 2000-2001 VA Linux Systems, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
36 #include "main/mtypes.h"
38 #include "main/colormac.h"
39 #include "main/macros.h"
41 #include "xmlconfig.h"
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))
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)
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
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 #define MGA_FALLBACK_DISABLE 0x100
68 /* Use the templated vertex formats:
71 #include "tnl_dd/t_dd_vertex.h"
74 typedef struct mga_context_t mgaContext;
75 typedef struct mga_context_t *mgaContextPtr;
77 typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *,
79 typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * );
80 typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * );
84 /* Texture environment color
86 #define RGB_ZERO(c) (((c) & 0xffffff) == 0x000000)
87 #define RGB_ONE(c) (((c) & 0xffffff) == 0xffffff)
88 #define ALPHA_ZERO(c) (((c) >> 24) == 0x00)
89 #define ALPHA_ONE(c) (((c) >> 24) == 0xff)
90 #define RGBA_EQUAL(c) ((c) == PACK_COLOR_8888( (c) & 0xff, (c) & 0xff, \
91 (c) & 0xff, (c) & 0xff ))
93 struct mga_texture_object_s;
94 struct mga_screen_private_s;
96 #define G200_TEX_MAXLEVELS 5
97 #define G400_TEX_MAXLEVELS 11
99 typedef struct mga_texture_object_s
101 driTextureObject base;
103 /* The G200 only has the ability to use 5 mipmap levels (including the
104 * base level). The G400 does not have this restriction, but it still
105 * only has 5 offset pointers in the hardware. The trick on the G400 is
106 * upto the first 4 offset pointers point to mipmap levels. The last
107 * offset pointer tells how large the preceeding mipmap is. This value is
108 * then used to determine where the remaining mipmaps are.
110 * For example, if the first offsets[0] through offsets[2] are used as
111 * pointers, then offset[3] will be the size of the mipmap pointed to by
112 * offsets[2]. So mipmap level 3 will be at (offsets[2]+offsets[3]). For
113 * each successive mipmap level, offsets[3] is divided by 4 and added to
114 * the previous address. So mipmap level 4 will be at
115 * (offsets[2]+offsets[3]+(offsets[3] / 4)).
117 * The last pointer is selected by setting TO_texorgoffsetsel in its
118 * pointer. In the previous example, offset[2] would have
119 * TO_texorgoffsetsel or'ed in before writing it to the hardware.
121 * In the current driver all of the mipmaps are packed together linearly
122 * with mipmap level 0. Therefore offsets[0] points to the base of the
123 * texture (and has TO_texorgoffsetsel or'ed in), and offsets[1] is the
124 * size of the base texture.
126 * There is a possible optimization available here. At times the driver
127 * may not be able to allocate a single block of memory for the complete
128 * texture without ejecting some other textures from memory. It may be
129 * possible to put some of the lower mipmap levels (i.e., the larger
130 * mipmaps) in memory separate from the higher levels.
132 * The implementation should be fairly obvious, but getting "right" would
133 * likely be non-trivial. A first allocation for the entire texture would
134 * be attempted with a flag that says "don't eject other textures." If
135 * that failed, an additional allocation would be attmpted for just the
136 * base map. The process would repeat with the block of lower maps. The
137 * tricky parts would be in detecting when some of the levels had been
138 * ejected from texture memory by other textures and preventing the
139 * 4th allocation (for all the smallest mipmap levels) from kicking out
140 * any of the first three.
142 * This array holds G400_TEX_MAXLEVELS pointers to remove an if-statement
143 * in a loop in mgaSetTexImages. Values past G200_TEX_MAXLEVELS are not
146 GLuint offsets[G400_TEX_MAXLEVELS];
151 drm_mga_texture_regs_t setup;
153 /* If one texture dimension wraps with GL_CLAMP and the other with
154 * GL_CLAMP_TO_EDGE, we have to fallback to software. We would also have
155 * to fallback for GL_CLAMP_TO_BORDER.
157 GLboolean border_fallback;
158 /* Depending on multitxturing and environment color
159 * GL_BLEND may have to be a software fallback.
161 GLboolean texenv_fallback;
162 } mgaTextureObject_t;
164 struct mga_hw_state {
170 GLuint stencil_enable;
174 GLuint alpha_func_enable;
176 GLuint blend_func_enable;
180 struct mga_context_t {
182 struct gl_context *glCtx;
183 unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp,
184 * need to shadow it here. */
186 /* Hardware state management
188 struct mga_hw_state hw;
190 /* Bookkeeping for texturing
193 driTexHeap * texture_heaps[ MGA_NR_TEX_HEAPS ];
194 driTextureObject swapped;
196 struct mga_texture_object_s *CurrentTexObj[2];
199 /* Map GL texture units onto hardware.
201 GLuint tmu_source[2];
209 /* Texture environment color.
211 unsigned int envcolor[2];
213 GLboolean force_dualtex;
215 /* Rasterization state
217 GLuint SetupNewInputs;
222 GLenum raster_primitive;
223 GLenum render_primitive;
226 GLint vertex_stride_shift;
227 GLuint vertex_format;
230 /* Fallback rasterization functions
232 mga_point_func draw_point;
233 mga_line_func draw_line;
234 mga_tri_func draw_tri;
237 /* Manage driver and hardware state
242 drm_mga_context_regs_t setup;
249 GLuint depth_clear_mask;
250 GLuint stencil_clear_mask;
252 GLuint haveHwStipple;
253 GLfloat hw_viewport[16];
257 drmBufPtr vertex_dma_buffer;
258 drmBufPtr iload_buffer;
261 int64_t swap_missed_ust;
264 GLuint swap_missed_count;
266 uint32_t last_frame_fence;
268 /* Drawable, cliprect and scissor information
270 int dirty_cliprects; /* which sets of cliprects are uptodate? */
271 int draw_buffer; /* which buffer are we rendering to */
272 unsigned int drawOffset; /* draw buffer address in space */
274 int drawX, drawY; /* origin of drawable in draw buffer */
275 int lastX, lastY; /* detect DSTORG bug */
276 GLuint numClipRects; /* cliprects for the draw buffer */
277 drm_clip_rect_t *pClipRects;
278 drm_clip_rect_t draw_rect;
279 drm_clip_rect_t scissor_rect;
282 drm_clip_rect_t tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS];
285 /* Texture aging and DMA based aging.
287 unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */
288 unsigned int dirtyAge; /* buffer age for synchronization */
290 GLuint primary_offset;
292 /* Mirrors of some DRI state.
294 drm_context_t hHWContext;
295 drm_hw_lock_t *driHwLock;
297 __DRIdrawable *driDrawable;
298 __DRIdrawable *driReadable;
300 __DRIscreen *driScreen;
301 struct mga_screen_private_s *mgaScreen;
302 drm_mga_sarea_t *sarea;
304 /* Configuration cache
306 driOptionCache optionCache;
309 #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx))
314 /* ================================================================
320 extern int MGA_DEBUG;
325 #define DEBUG_VERBOSE_MSG 0x01
326 #define DEBUG_VERBOSE_DRI 0x02
327 #define DEBUG_VERBOSE_IOCTL 0x04
328 #define DEBUG_VERBOSE_TEXTURE 0x08
329 #define DEBUG_VERBOSE_FALLBACK 0x10
331 static INLINE GLuint mgaPackColor(GLuint cpp,
332 GLubyte r, GLubyte g,
333 GLubyte b, GLubyte a)
337 return PACK_COLOR_565( r, g, b );
339 return PACK_COLOR_8888( a, r, g, b );
347 * Subpixel offsets for window coordinates:
349 #define SUBPIXEL_X (-0.5F)
350 #define SUBPIXEL_Y (-0.5F + 0.125)
353 #define MGA_WA_TRIANGLES 0x18000000
354 #define MGA_WA_TRISTRIP_T0 0x02010200
355 #define MGA_WA_TRIFAN_T0 0x01000408
356 #define MGA_WA_TRISTRIP_T0T1 0x02010400
357 #define MGA_WA_TRIFAN_T0T1 0x01000810