Small optimization for big-endian (e.g., PowerPC) systems.
[mesa.git] / src / mesa / drivers / dri / mach64 / mach64_context.h
1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3 * Copyright 2000 Gareth Hughes
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
20 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30 */
31
32 #ifndef __MACH64_CONTEXT_H__
33 #define __MACH64_CONTEXT_H__
34
35 #ifdef GLX_DIRECT_RENDERING
36
37 #include "dri_util.h"
38 #include "drm.h"
39 #include "mach64_drm.h"
40
41 #include "mtypes.h"
42
43 #include "mach64_reg.h"
44
45 #include "texmem.h"
46
47 struct mach64_context;
48 typedef struct mach64_context mach64ContextRec;
49 typedef struct mach64_context *mach64ContextPtr;
50
51 #include "mach64_lock.h"
52 #include "mach64_screen.h"
53
54 /* Experimental driver options */
55 #define MACH64_CLIENT_STATE_EMITS 0
56
57 /* Performace monitoring */
58 #define ENABLE_PERF_BOXES 1
59
60 /* Native vertex format */
61 #define MACH64_NATIVE_VTXFMT 1
62
63 /* Flags for what context state needs to be updated:
64 */
65 #define MACH64_NEW_ALPHA 0x0001
66 #define MACH64_NEW_DEPTH 0x0002
67 #define MACH64_NEW_FOG 0x0004
68 #define MACH64_NEW_CLIP 0x0008
69 #define MACH64_NEW_CULL 0x0010
70 #define MACH64_NEW_MASKS 0x0020
71 #define MACH64_NEW_RENDER_UNUSED 0x0040
72 #define MACH64_NEW_WINDOW 0x0080
73 #define MACH64_NEW_TEXTURE 0x0100
74 #define MACH64_NEW_CONTEXT 0x0200
75 #define MACH64_NEW_ALL 0x03ff
76
77 /* Flags for software fallback cases:
78 */
79 #define MACH64_FALLBACK_TEXTURE 0x0001
80 #define MACH64_FALLBACK_DRAW_BUFFER 0x0002
81 #define MACH64_FALLBACK_READ_BUFFER 0x0004
82 #define MACH64_FALLBACK_STENCIL 0x0008
83 #define MACH64_FALLBACK_RENDER_MODE 0x0010
84 #define MACH64_FALLBACK_MULTIDRAW 0x0020
85 #define MACH64_FALLBACK_LOGICOP 0x0040
86 #define MACH64_FALLBACK_SEP_SPECULAR 0x0080
87 #define MACH64_FALLBACK_BLEND_EQ 0x0100
88 #define MACH64_FALLBACK_BLEND_FUNC 0x0200
89
90 #define CARD32 GLuint /* KW: For building in mesa tree */
91
92 #if MACH64_NATIVE_VTXFMT
93
94 /* The vertex structures.
95 */
96
97 /* The size of this union is not of relevence:
98 */
99 union mach64_vertex_t {
100 GLfloat f[16];
101 GLuint ui[16];
102 GLushort us2[16][2];
103 GLubyte ub4[16][4];
104 };
105
106 typedef union mach64_vertex_t mach64Vertex, *mach64VertexPtr;
107
108 #else
109
110 /* Use the templated vertex format:
111 */
112 #define TAG(x) mach64##x
113 #include "tnl_dd/t_dd_vertex.h"
114 #undef TAG
115
116 #endif /* MACH64_NATIVE_VTXFMT */
117
118 /* Subpixel offsets for window coordinates:
119 * These are enough to fix most glean tests except polygonOffset.
120 * There are also still some gaps that show in e.g. the tunnel Mesa demo
121 * or the lament xscreensaver hack.
122 */
123 #define SUBPIXEL_X (0.0125F)
124 #define SUBPIXEL_Y (0.15F)
125
126
127 typedef void (*mach64_tri_func)( mach64ContextPtr,
128 mach64Vertex *,
129 mach64Vertex *,
130 mach64Vertex * );
131
132 typedef void (*mach64_line_func)( mach64ContextPtr,
133 mach64Vertex *,
134 mach64Vertex * );
135
136 typedef void (*mach64_point_func)( mach64ContextPtr,
137 mach64Vertex * );
138
139 #ifdef TEXMEM
140 struct mach64_texture_object {
141 driTextureObject base;
142
143 GLuint offset;
144
145 GLuint dirty;
146 GLuint age;
147
148 GLint widthLog2;
149 GLint heightLog2;
150 GLint maxLog2;
151
152 GLint hasAlpha;
153 GLint textureFormat;
154
155 /* Have to keep these separate due to how they are programmed.
156 * FIXME: Why don't we just use the tObj values?
157 */
158 GLboolean BilinearMin;
159 GLboolean BilinearMag;
160 GLboolean ClampS;
161 GLboolean ClampT;
162 };
163 #else
164 struct mach64_texture_object {
165 struct mach64_texture_object *next;
166 struct mach64_texture_object *prev;
167 struct gl_texture_object *tObj;
168
169 PMemBlock memBlock;
170 GLuint offset;
171 GLuint size;
172
173 GLuint dirty;
174 GLuint age;
175
176 GLint bound;
177 GLint heap;
178
179 GLint widthLog2;
180 GLint heightLog2;
181 GLint maxLog2;
182
183 GLint hasAlpha;
184 GLint textureFormat;
185
186 /* Have to keep these separate due to how they are programmed.
187 * FIXME: Why don't we just use the tObj values?
188 */
189 GLboolean BilinearMin;
190 GLboolean BilinearMag;
191 GLboolean ClampS;
192 GLboolean ClampT;
193 };
194 #endif
195
196 typedef struct mach64_texture_object mach64TexObj, *mach64TexObjPtr;
197
198
199 struct mach64_context {
200 GLcontext *glCtx;
201
202 /* Driver and hardware state management
203 */
204 GLuint new_state;
205 GLuint dirty; /* Hardware state to be updated */
206 drm_mach64_context_regs_t setup;
207
208 GLuint NewGLState;
209 GLuint Fallback;
210 GLuint SetupIndex;
211 GLuint SetupNewInputs;
212 GLuint RenderIndex;
213 GLfloat hw_viewport[16];
214 GLfloat depth_scale;
215 GLuint vertex_size;
216 GLuint vertex_stride_shift;
217 GLuint vertex_format;
218 GLuint num_verts;
219 GLubyte *verts;
220
221 CARD32 Color; /* Current draw color */
222 CARD32 ClearColor; /* Color used to clear color buffer */
223 CARD32 ClearDepth; /* Value used to clear depth buffer */
224
225 /* Map GL texture units onto hardware
226 */
227 GLint multitex;
228 GLint tmu_source[2];
229 GLint tex_dest[2];
230
231 /* Texture object bookkeeping
232 */
233 mach64TexObjPtr CurrentTexObj[2];
234 #ifdef TEXMEM
235 unsigned nr_heaps;
236 driTexHeap * texture_heaps[ R128_NR_TEX_HEAPS ];
237 driTextureObject swapped;
238 #else
239 mach64TexObj TexObjList[MACH64_NR_TEX_HEAPS];
240 mach64TexObj SwappedOut;
241 memHeap_t *texHeap[MACH64_NR_TEX_HEAPS];
242 GLuint lastTexAge[MACH64_NR_TEX_HEAPS];
243 GLint firstTexHeap, lastTexHeap;
244 #endif
245
246 /* Fallback rasterization functions
247 */
248 mach64_point_func draw_point;
249 mach64_line_func draw_line;
250 mach64_tri_func draw_tri;
251
252 /* Culling */
253 GLfloat backface_sign;
254
255 /* DMA buffers
256 */
257 void *vert_buf;
258 size_t vert_total;
259 unsigned vert_used;
260
261 GLuint hw_primitive;
262 GLenum render_primitive;
263
264 /* Visual, drawable, cliprect and scissor information
265 */
266 GLint drawOffset, drawPitch;
267 GLint drawX, drawY; /* origin of drawable in draw buffer */
268 GLint readOffset, readPitch;
269
270 GLuint numClipRects; /* Cliprects for the draw buffer */
271 drm_clip_rect_t *pClipRects;
272
273 GLint scissor;
274 drm_clip_rect_t ScissorRect; /* Current software scissor */
275
276 /* Mirrors of some DRI state
277 */
278 __DRIcontextPrivate *driContext; /* DRI context */
279 __DRIscreenPrivate *driScreen; /* DRI screen */
280 __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
281
282 unsigned int lastStamp; /* mirror driDrawable->lastStamp */
283
284 drm_context_t hHWContext;
285 drm_hw_lock_t *driHwLock;
286 int driFd;
287
288 mach64ScreenPtr mach64Screen; /* Screen private DRI data */
289 drm_mach64_sarea_t *sarea; /* Private SAREA data */
290
291 GLuint hardwareWentIdle;
292
293 #if ENABLE_PERF_BOXES
294 /* Performance counters
295 */
296 GLuint boxes; /* Draw performance boxes */
297 GLuint c_clears;
298 GLuint c_drawWaits;
299 GLuint c_textureSwaps;
300 GLuint c_textureBytes;
301 GLuint c_agpTextureBytes;
302 GLuint c_texsrc_agp;
303 GLuint c_texsrc_card;
304 GLuint c_vertexBuffers;
305 #endif
306
307 /* VBI
308 */
309 GLuint vbl_seq;
310 GLuint vblank_flags;
311 GLuint do_irqs;
312
313 /* Configuration cache
314 */
315 driOptionCache optionCache;
316 };
317
318 #define MACH64_CONTEXT(ctx) ((mach64ContextPtr)(ctx->DriverCtx))
319
320
321 extern GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
322 __DRIcontextPrivate *driContextPriv,
323 void *sharedContextPrivate );
324
325 extern void mach64DestroyContext( __DRIcontextPrivate * );
326
327 extern GLboolean mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
328 __DRIdrawablePrivate *driDrawPriv,
329 __DRIdrawablePrivate *driReadPriv );
330
331 extern GLboolean mach64UnbindContext( __DRIcontextPrivate *driContextPriv );
332
333 /* ================================================================
334 * Byte ordering
335 */
336 #if MESA_LITTLE_ENDIAN == 1
337 #define LE32_IN( x ) ( *(GLuint *)(x) )
338 #define LE32_IN_FLOAT( x ) ( *(GLfloat *)(x) )
339 #define LE32_OUT( x, y ) do { *(GLuint *)(x) = (y); } while (0)
340 #define LE32_OUT_FLOAT( x, y ) do { *(GLfloat *)(x) = (y); } while (0)
341 #else
342 #include <byteswap.h>
343 #define LE32_IN( x ) bswap_32( *(GLuint *)(x) )
344 #define LE32_IN_FLOAT( x ) \
345 ({ \
346 GLuint __tmp = bswap_32( *(GLuint *)(x) ); \
347 *(GLfloat *)&__tmp; \
348 })
349 #define LE32_OUT( x, y ) do { *(GLuint *)(x) = bswap_32( y ); } while (0)
350 #define LE32_OUT_FLOAT( x, y ) \
351 do { \
352 GLuint __tmp; \
353 *(GLfloat *)&__tmp = (y); \
354 *(GLuint *)(x) = bswap_32( __tmp ); \
355 } while (0)
356 #endif
357
358 /* ================================================================
359 * DMA buffers
360 */
361
362 #define DMALOCALS CARD32 *buf=NULL; int requested=0; int outcount=0
363
364 /* called while locked for interleaved client-side state emits */
365 #define DMAGETPTR( dwords ) \
366 do { \
367 requested = (dwords); \
368 buf = (CARD32 *)mach64AllocDmaLocked( mmesa, ((dwords)*4) ); \
369 outcount = 0; \
370 } while(0)
371
372 #define DMAOUTREG( reg, val ) \
373 do { \
374 LE32_OUT( &buf[outcount++], ADRINDEX( reg ) ); \
375 LE32_OUT( &buf[outcount++], ( val ) ); \
376 } while(0)
377
378 #define DMAADVANCE() \
379 do { \
380 if (outcount < requested) { \
381 mmesa->vert_used -= (requested - outcount) * 4; \
382 } \
383 } while(0)
384
385 /* ================================================================
386 * Debugging:
387 */
388
389 #define DO_DEBUG 1
390
391 #if DO_DEBUG
392 extern int MACH64_DEBUG;
393 #else
394 #define MACH64_DEBUG 0
395 #endif
396
397 #define DEBUG_ALWAYS_SYNC 0x001
398 #define DEBUG_VERBOSE_API 0x002
399 #define DEBUG_VERBOSE_MSG 0x004
400 #define DEBUG_VERBOSE_LRU 0x008
401 #define DEBUG_VERBOSE_DRI 0x010
402 #define DEBUG_VERBOSE_IOCTL 0x020
403 #define DEBUG_VERBOSE_PRIMS 0x040
404 #define DEBUG_VERBOSE_COUNT 0x080
405 #define DEBUG_NOWAIT 0x100
406 #endif
407 #endif /* __MACH64_CONTEXT_H__ */