Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / mga / mgacontext.h
1 /*
2  * Copyright 2000-2001 VA Linux Systems, Inc.
3  * All Rights Reserved.
4  *
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:
11  *
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
14  * Software.
15  *
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.
23  *
24  * Authors:
25  *    Keith Whitwell <keith@tungstengraphics.com>
26  */
27
28 #ifndef MGALIB_INC
29 #define MGALIB_INC
30
31 #include <stdint.h>
32 #include "drm.h"
33 #include "mga_drm.h"
34 #include "dri_util.h"
35 #include "xf86drm.h"
36 #include "main/mtypes.h"
37 #include "main/mm.h"
38 #include "main/colormac.h"
39 #include "main/macros.h"
40 #include "texmem.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 #define MGA_FALLBACK_DISABLE        0x100
66
67
68 /* Use the templated vertex formats:
69  */
70 #define TAG(x) mga##x
71 #include "tnl_dd/t_dd_vertex.h"
72 #undef TAG
73
74 typedef struct mga_context_t mgaContext;
75 typedef struct mga_context_t *mgaContextPtr;
76
77 typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *,
78                                mgaVertex * );
79 typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * );
80 typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * );
81
82
83
84 /* Texture environment color
85  */
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 ))
92
93 struct mga_texture_object_s;
94 struct mga_screen_private_s;
95
96 #define G200_TEX_MAXLEVELS 5
97 #define G400_TEX_MAXLEVELS 11
98
99 typedef struct mga_texture_object_s
100 {
101    driTextureObject   base;
102
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.
109     * 
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)).
116     * 
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.
120     * 
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.
125     *
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.
131     *
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.
141     * 
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
144     * used.
145     */
146    GLuint             offsets[G400_TEX_MAXLEVELS];
147
148    int                texelBytes;
149    GLuint             age;
150
151    drm_mga_texture_regs_t setup;
152
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.
156     */
157    GLboolean          border_fallback;
158    /* Depending on multitxturing and environment color
159     * GL_BLEND may have to be a software fallback.
160     */
161    GLboolean texenv_fallback;
162 } mgaTextureObject_t;
163
164 struct mga_hw_state {
165    GLuint   specen;
166    GLuint   cull;
167    GLuint   cull_dualtex;
168    GLuint   stencil;
169    GLuint   stencilctl;
170    GLuint   stencil_enable;
171    GLuint   zmode;
172    GLuint   rop;
173    GLuint   alpha_func;
174    GLuint   alpha_func_enable;
175    GLuint   blend_func;
176    GLuint   blend_func_enable;
177    GLuint   alpha_sel;
178 };
179
180 struct mga_context_t {
181
182    struct gl_context *glCtx;
183    unsigned int lastStamp;              /* fullscreen breaks dpriv->laststamp,
184                                          * need to shadow it here. */
185
186    /* Hardware state management
187     */
188    struct mga_hw_state hw;
189
190    /* Bookkeeping for texturing
191     */
192    unsigned           nr_heaps;
193    driTexHeap       * texture_heaps[ MGA_NR_TEX_HEAPS ];
194    driTextureObject   swapped;
195
196    struct mga_texture_object_s *CurrentTexObj[2];
197
198
199    /* Map GL texture units onto hardware.
200     */
201    GLuint tmu_source[2];
202    
203    int texture_depth;
204
205    /* Manage fallbacks
206     */
207    GLuint Fallback;  
208
209    /* Texture environment color.
210     */
211    unsigned int envcolor[2];
212    GLboolean fcol_used;
213    GLboolean force_dualtex;
214
215    /* Rasterization state 
216     */
217    GLuint SetupNewInputs;
218    GLuint SetupIndex;
219    GLuint RenderIndex;
220    
221    GLuint hw_primitive;
222    GLenum raster_primitive;
223    GLenum render_primitive;
224
225    GLubyte *verts;
226    GLint vertex_stride_shift;
227    GLuint vertex_format;                
228    GLuint vertex_size;
229
230    /* Fallback rasterization functions 
231     */
232    mga_point_func draw_point;
233    mga_line_func draw_line;
234    mga_tri_func draw_tri;
235
236
237    /* Manage driver and hardware state
238     */
239    GLuint        NewGLState; 
240    GLuint        dirty;
241
242    drm_mga_context_regs_t setup;
243
244    GLuint        ClearColor;
245    GLuint        ClearDepth;
246    GLuint        poly_stipple;
247    GLfloat       depth_scale;
248
249    GLuint        depth_clear_mask;
250    GLuint        stencil_clear_mask;
251    GLuint        hw_stencil;
252    GLuint        haveHwStipple;
253    GLfloat       hw_viewport[16];
254
255    /* Dma buffers
256     */
257    drmBufPtr  vertex_dma_buffer;
258    drmBufPtr  iload_buffer;
259
260    int64_t swap_ust;
261    int64_t swap_missed_ust;
262
263    GLuint swap_count;
264    GLuint swap_missed_count;
265
266    uint32_t last_frame_fence;
267
268    /* Drawable, cliprect and scissor information
269     */
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 */
273    int readOffset;
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;
280    int scissor;
281
282    drm_clip_rect_t tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS];
283
284
285    /* Texture aging and DMA based aging.
286     */
287    unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age  */
288    unsigned int dirtyAge;               /* buffer age for synchronization */
289
290    GLuint primary_offset;
291
292    /* Mirrors of some DRI state.
293     */
294    drm_context_t hHWContext;
295    drm_hw_lock_t *driHwLock;
296    int driFd;
297    __DRIdrawable *driDrawable;
298    __DRIdrawable *driReadable;
299
300    __DRIscreen *driScreen;
301    struct mga_screen_private_s *mgaScreen;
302    drm_mga_sarea_t *sarea;
303
304    /* Configuration cache
305     */
306    driOptionCache optionCache;
307 };
308
309 #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx))
310
311
312
313
314 /* ================================================================
315  * Debugging:
316  */
317 #define DO_DEBUG                1
318
319 #if DO_DEBUG
320 extern int MGA_DEBUG;
321 #else
322 #define MGA_DEBUG               0
323 #endif
324
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
330
331 static INLINE GLuint mgaPackColor(GLuint cpp,
332                                   GLubyte r, GLubyte g,
333                                   GLubyte b, GLubyte a)
334 {
335    switch (cpp) {
336    case 2:
337       return PACK_COLOR_565( r, g, b );
338    case 4:
339       return PACK_COLOR_8888( a, r, g, b );
340    default:
341       return 0;
342    }
343 }
344
345
346 /*
347  * Subpixel offsets for window coordinates:
348  */
349 #define SUBPIXEL_X (-0.5F)
350 #define SUBPIXEL_Y (-0.5F + 0.125)
351
352
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
358
359 #endif