1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
3 * Copyright 2000 Gareth Hughes
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:
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
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.
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * José Fonseca <j_r_fonseca@yahoo.co.uk>
34 #include "simple_list.h"
37 #include "extensions.h"
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "array_cache/acache.h"
44 #include "tnl/t_pipeline.h"
46 #include "drivers/common/driverfuncs.h"
48 #include "mach64_context.h"
49 #include "mach64_ioctl.h"
50 #include "mach64_dd.h"
51 #include "mach64_span.h"
52 #include "mach64_state.h"
53 #include "mach64_tex.h"
54 #include "mach64_tris.h"
55 #include "mach64_vb.h"
61 int MACH64_DEBUG
= (0);
64 static const struct dri_debug_control debug_control
[] =
66 { "sync", DEBUG_ALWAYS_SYNC
},
67 { "api", DEBUG_VERBOSE_API
},
68 { "msg", DEBUG_VERBOSE_MSG
},
69 { "lru", DEBUG_VERBOSE_LRU
},
70 { "dri", DEBUG_VERBOSE_DRI
},
71 { "ioctl", DEBUG_VERBOSE_IOCTL
},
72 { "prims", DEBUG_VERBOSE_PRIMS
},
73 { "count", DEBUG_VERBOSE_COUNT
},
74 { "nowait", DEBUG_NOWAIT
},
78 static const char * const card_extensions
[] =
80 "GL_ARB_multitexture",
81 "GL_EXT_texture_edge_clamp",
82 "GL_MESA_ycbcr_texture",
83 "GL_SGIS_generate_mipmap",
84 "GL_SGIS_texture_edge_clamp",
89 /* Create the device specific context.
91 GLboolean
mach64CreateContext( const __GLcontextModes
*glVisual
,
92 __DRIcontextPrivate
*driContextPriv
,
93 void *sharedContextPrivate
)
95 GLcontext
*ctx
, *shareCtx
;
96 __DRIscreenPrivate
*driScreen
= driContextPriv
->driScreenPriv
;
97 struct dd_function_table functions
;
98 mach64ContextPtr mmesa
;
99 mach64ScreenPtr mach64Screen
;
103 MACH64_DEBUG
= driParseDebugString(getenv("MACH64_DEBUG"), debug_control
);
106 /* Allocate the mach64 context */
107 mmesa
= (mach64ContextPtr
) CALLOC( sizeof(*mmesa
) );
111 /* Init default driver functions then plug in our Mach64-specific functions
112 * (the texture functions are especially important)
114 _mesa_init_driver_functions( &functions
);
115 mach64InitDriverFuncs( &functions
);
116 mach64InitIoctlFuncs( &functions
);
117 mach64InitTextureFuncs( &functions
);
119 /* Allocate the Mesa context */
120 if (sharedContextPrivate
)
121 shareCtx
= ((mach64ContextPtr
) sharedContextPrivate
)->glCtx
;
124 mmesa
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
125 &functions
, (void *)mmesa
);
130 driContextPriv
->driverPrivate
= mmesa
;
133 mmesa
->driContext
= driContextPriv
;
134 mmesa
->driScreen
= driScreen
;
135 mmesa
->driDrawable
= NULL
;
136 mmesa
->hHWContext
= driContextPriv
->hHWContext
;
137 mmesa
->driHwLock
= &driScreen
->pSAREA
->lock
;
138 mmesa
->driFd
= driScreen
->fd
;
140 mach64Screen
= mmesa
->mach64Screen
= (mach64ScreenPtr
)driScreen
->private;
142 mmesa
->sarea
= (ATISAREAPrivPtr
)((char *)driScreen
->pSAREA
+
143 sizeof(XF86DRISAREARec
));
145 mmesa
->CurrentTexObj
[0] = NULL
;
146 mmesa
->CurrentTexObj
[1] = NULL
;
148 make_empty_list( &mmesa
->SwappedOut
);
150 mmesa
->firstTexHeap
= mach64Screen
->firstTexHeap
;
151 mmesa
->lastTexHeap
= mach64Screen
->firstTexHeap
+ mach64Screen
->numTexHeaps
;
153 for ( i
= mmesa
->firstTexHeap
; i
< mmesa
->lastTexHeap
; i
++ ) {
154 make_empty_list( &mmesa
->TexObjList
[i
] );
155 mmesa
->texHeap
[i
] = mmInit( 0, mach64Screen
->texSize
[i
] );
156 mmesa
->lastTexAge
[i
] = -1;
159 mmesa
->RenderIndex
= -1; /* Impossible value */
160 mmesa
->vert_buf
= NULL
;
161 mmesa
->num_verts
= 0;
162 mmesa
->new_state
= MACH64_NEW_ALL
;
163 mmesa
->dirty
= MACH64_UPLOAD_ALL
;
165 /* Set the maximum texture size small enough that we can
166 * guarentee that both texture units can bind a maximal texture
167 * and have them both in memory (on-card or AGP) at once.
168 * Test for 2 textures * bytes/texel * size * size. There's no
169 * need to account for mipmaps since we only upload one level.
171 heap
= mach64Screen
->IsPCI
? MACH64_CARD_HEAP
: MACH64_AGP_HEAP
;
173 if ( mach64Screen
->texSize
[heap
] >= 2 * mach64Screen
->cpp
* 1024*1024 ) {
174 ctx
->Const
.MaxTextureLevels
= 11; /* 1024x1024 */
175 } else if ( mach64Screen
->texSize
[heap
] >= 2 * mach64Screen
->cpp
* 512*512 ) {
176 ctx
->Const
.MaxTextureLevels
= 10; /* 512x512 */
178 ctx
->Const
.MaxTextureLevels
= 9; /* 256x256 */
181 ctx
->Const
.MaxTextureUnits
= 2;
183 #if ENABLE_PERF_BOXES
184 mmesa
->boxes
= ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL
);
187 /* Allocate the vertex buffer
189 mmesa
->vert_buf
= ALIGN_MALLOC(MACH64_BUFFER_SIZE
, 32);
190 if ( !mmesa
->vert_buf
)
192 mmesa
->vert_used
= 0;
193 mmesa
->vert_total
= MACH64_BUFFER_SIZE
;
195 /* Initialize the software rasterizer and helper modules.
197 _swrast_CreateContext( ctx
);
198 _ac_CreateContext( ctx
);
199 _tnl_CreateContext( ctx
);
200 _swsetup_CreateContext( ctx
);
202 /* Install the customized pipeline:
204 /* _tnl_destroy_pipeline( ctx ); */
205 /* _tnl_install_pipeline( ctx, mach64_pipeline ); */
207 /* Configure swrast to match hardware characteristics:
209 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
210 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
212 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
214 mach64InitTriFuncs( ctx
);
215 mach64DDInitDriverFuncs( ctx
);
216 mach64DDInitIoctlFuncs( ctx
);
217 mach64DDInitStateFuncs( ctx
);
218 mach64DDInitSpanFuncs( ctx
);
219 mach64DDInitTextureFuncs( ctx
);
220 mach64DDInitState( mmesa
);
222 mmesa
->do_irqs
= (mmesa
->mach64Screen
->irq
&& !getenv("MACH64_NO_IRQS"));
224 mmesa
->vblank_flags
= (mmesa
->do_irqs
)
225 ? driGetDefaultVBlankFlags(&mmesa
->optionCache
) : VBLANK_FLAG_NO_IRQ
;
227 driContextPriv
->driverPrivate
= (void *)mmesa
;
232 /* Destroy the device specific context.
234 void mach64DestroyContext( __DRIcontextPrivate
*driContextPriv
)
236 mach64ContextPtr mmesa
= (mach64ContextPtr
) driContextPriv
->driverPrivate
;
238 assert(mmesa
); /* should never be null */
240 if (mmesa
->glCtx
->Shared
->RefCount
== 1) {
241 /* This share group is about to go away, free our private
242 * texture object data.
244 mach64TexObjPtr t
, next_t
;
247 for ( i
= mmesa
->firstTexHeap
; i
< mmesa
->lastTexHeap
; i
++ ) {
248 foreach_s ( t
, next_t
, &mmesa
->TexObjList
[i
] ) {
249 mach64DestroyTexObj( mmesa
, t
);
251 mmDestroy( mmesa
->texHeap
[i
] );
252 mmesa
->texHeap
[i
] = NULL
;
255 foreach_s ( t
, next_t
, &mmesa
->SwappedOut
) {
256 mach64DestroyTexObj( mmesa
, t
);
260 _swsetup_DestroyContext( mmesa
->glCtx
);
261 _tnl_DestroyContext( mmesa
->glCtx
);
262 _ac_DestroyContext( mmesa
->glCtx
);
263 _swrast_DestroyContext( mmesa
->glCtx
);
265 mach64FreeVB( mmesa
->glCtx
);
267 /* Free the vertex buffer */
268 if ( mmesa
->vert_buf
)
269 ALIGN_FREE( mmesa
->vert_buf
);
271 /* free the Mesa context */
272 mmesa
->glCtx
->DriverCtx
= NULL
;
273 _mesa_destroy_context(mmesa
->glCtx
);
279 /* Force the context `c' to be the current context and associate with it
283 mach64MakeCurrent( __DRIcontextPrivate
*driContextPriv
,
284 __DRIdrawablePrivate
*driDrawPriv
,
285 __DRIdrawablePrivate
*driReadPriv
)
287 if ( driContextPriv
) {
288 GET_CURRENT_CONTEXT(ctx
);
289 mach64ContextPtr oldMach64Ctx
= ctx
? MACH64_CONTEXT(ctx
) : NULL
;
290 mach64ContextPtr newMach64Ctx
= (mach64ContextPtr
) driContextPriv
->driverPrivate
;
292 if ( newMach64Ctx
!= oldMach64Ctx
) {
293 newMach64Ctx
->new_state
|= MACH64_NEW_CONTEXT
;
294 newMach64Ctx
->dirty
= MACH64_UPLOAD_ALL
;
297 if ( newMach64Ctx
->driDrawable
!= driDrawPriv
) {
298 newMach64Ctx
->driDrawable
= driDrawPriv
;
299 mach64CalcViewport( newMach64Ctx
->glCtx
);
302 _mesa_make_current2( newMach64Ctx
->glCtx
,
303 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
304 (GLframebuffer
*) driReadPriv
->driverPrivate
);
307 newMach64Ctx
->new_state
|= MACH64_NEW_CLIP
;
309 if ( !newMach64Ctx
->glCtx
->Viewport
.Width
) {
310 _mesa_set_viewport(newMach64Ctx
->glCtx
, 0, 0,
311 driDrawPriv
->w
, driDrawPriv
->h
);
314 _mesa_make_current( 0, 0 );
321 /* Force the context `c' to be unbound from its buffer.
324 mach64UnbindContext( __DRIcontextPrivate
*driContextPriv
)