1 /* -*- 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>
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/simple_list.h"
35 #include "main/imports.h"
36 #include "main/matrix.h"
37 #include "main/extensions.h"
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.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"
60 #define need_GL_ARB_multisample
61 #define need_GL_ARB_vertex_buffer_object
62 #include "extension_helper.h"
65 int MACH64_DEBUG
= (0);
68 static const struct dri_debug_control debug_control
[] =
70 { "sync", DEBUG_ALWAYS_SYNC
},
71 { "api", DEBUG_VERBOSE_API
},
72 { "msg", DEBUG_VERBOSE_MSG
},
73 { "lru", DEBUG_VERBOSE_LRU
},
74 { "dri", DEBUG_VERBOSE_DRI
},
75 { "ioctl", DEBUG_VERBOSE_IOCTL
},
76 { "prims", DEBUG_VERBOSE_PRIMS
},
77 { "count", DEBUG_VERBOSE_COUNT
},
78 { "nowait", DEBUG_NOWAIT
},
79 { "fall", DEBUG_VERBOSE_FALLBACK
},
83 const struct dri_extension card_extensions
[] =
85 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
86 { "GL_ARB_multitexture", NULL
},
87 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
88 { "GL_EXT_texture_edge_clamp", NULL
},
89 { "GL_MESA_ycbcr_texture", NULL
},
90 { "GL_SGIS_generate_mipmap", NULL
},
95 /* Create the device specific context.
97 GLboolean
mach64CreateContext( const __GLcontextModes
*glVisual
,
98 __DRIcontextPrivate
*driContextPriv
,
99 void *sharedContextPrivate
)
101 GLcontext
*ctx
, *shareCtx
;
102 __DRIscreenPrivate
*driScreen
= driContextPriv
->driScreenPriv
;
103 struct dd_function_table functions
;
104 mach64ContextPtr mmesa
;
105 mach64ScreenPtr mach64Screen
;
107 GLuint
*c_textureSwapsPtr
= NULL
;
110 MACH64_DEBUG
= driParseDebugString(getenv("MACH64_DEBUG"), debug_control
);
113 /* Allocate the mach64 context */
114 mmesa
= (mach64ContextPtr
) CALLOC( sizeof(*mmesa
) );
118 /* Init default driver functions then plug in our Mach64-specific functions
119 * (the texture functions are especially important)
121 _mesa_init_driver_functions( &functions
);
122 mach64InitDriverFuncs( &functions
);
123 mach64InitIoctlFuncs( &functions
);
124 mach64InitTextureFuncs( &functions
);
126 /* Allocate the Mesa context */
127 if (sharedContextPrivate
)
128 shareCtx
= ((mach64ContextPtr
) sharedContextPrivate
)->glCtx
;
131 mmesa
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
132 &functions
, (void *)mmesa
);
137 driContextPriv
->driverPrivate
= mmesa
;
140 mmesa
->driContext
= driContextPriv
;
141 mmesa
->driScreen
= driScreen
;
142 mmesa
->driDrawable
= NULL
;
143 mmesa
->hHWContext
= driContextPriv
->hHWContext
;
144 mmesa
->driHwLock
= &driScreen
->pSAREA
->lock
;
145 mmesa
->driFd
= driScreen
->fd
;
147 mach64Screen
= mmesa
->mach64Screen
= (mach64ScreenPtr
)driScreen
->private;
149 /* Parse configuration files */
150 driParseConfigFiles (&mmesa
->optionCache
, &mach64Screen
->optionCache
,
151 mach64Screen
->driScreen
->myNum
, "mach64");
153 mmesa
->sarea
= (drm_mach64_sarea_t
*)((char *)driScreen
->pSAREA
+
154 sizeof(drm_sarea_t
));
156 mmesa
->CurrentTexObj
[0] = NULL
;
157 mmesa
->CurrentTexObj
[1] = NULL
;
159 (void) memset( mmesa
->texture_heaps
, 0, sizeof( mmesa
->texture_heaps
) );
160 make_empty_list( &mmesa
->swapped
);
162 mmesa
->firstTexHeap
= mach64Screen
->firstTexHeap
;
163 mmesa
->lastTexHeap
= mach64Screen
->firstTexHeap
+ mach64Screen
->numTexHeaps
;
165 for ( i
= mmesa
->firstTexHeap
; i
< mmesa
->lastTexHeap
; i
++ ) {
166 mmesa
->texture_heaps
[i
] = driCreateTextureHeap( i
, mmesa
,
167 mach64Screen
->texSize
[i
],
168 6, /* align to 64-byte boundary, use 12 for page-size boundary */
169 MACH64_NR_TEX_REGIONS
,
170 (drmTextureRegionPtr
)mmesa
->sarea
->tex_list
[i
],
171 &mmesa
->sarea
->tex_age
[i
],
173 sizeof( mach64TexObj
),
174 (destroy_texture_object_t
*) mach64DestroyTexObj
);
176 #if ENABLE_PERF_BOXES
177 c_textureSwapsPtr
= & mmesa
->c_textureSwaps
;
179 driSetTextureSwapCounterLocation( mmesa
->texture_heaps
[i
],
183 mmesa
->RenderIndex
= -1; /* Impossible value */
184 mmesa
->vert_buf
= NULL
;
185 mmesa
->num_verts
= 0;
186 mmesa
->new_state
= MACH64_NEW_ALL
;
187 mmesa
->dirty
= MACH64_UPLOAD_ALL
;
189 /* Set the maximum texture size small enough that we can
190 * guarentee that both texture units can bind a maximal texture
191 * and have them both in memory (on-card or AGP) at once.
192 * Test for 2 textures * bytes/texel * size * size. There's no
193 * need to account for mipmaps since we only upload one level.
196 ctx
->Const
.MaxTextureUnits
= 2;
197 ctx
->Const
.MaxTextureImageUnits
= 2;
198 ctx
->Const
.MaxTextureCoordUnits
= 2;
200 heap
= mach64Screen
->IsPCI
? MACH64_CARD_HEAP
: MACH64_AGP_HEAP
;
202 driCalculateMaxTextureLevels( & mmesa
->texture_heaps
[heap
],
206 10, /* max 2D texture size is 1024x1024 */
207 0, /* 3D textures unsupported. */
208 0, /* cube textures unsupported. */
209 0, /* texture rectangles unsupported. */
210 1, /* mipmapping unsupported. */
211 GL_TRUE
, /* need to have both textures in
212 either local or AGP memory */
215 #if ENABLE_PERF_BOXES
216 mmesa
->boxes
= ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL
);
219 /* Allocate the vertex buffer
221 mmesa
->vert_buf
= ALIGN_MALLOC(MACH64_BUFFER_SIZE
, 32);
222 if ( !mmesa
->vert_buf
)
224 mmesa
->vert_used
= 0;
225 mmesa
->vert_total
= MACH64_BUFFER_SIZE
;
227 /* Initialize the software rasterizer and helper modules.
229 _swrast_CreateContext( ctx
);
230 _vbo_CreateContext( ctx
);
231 _tnl_CreateContext( ctx
);
232 _swsetup_CreateContext( ctx
);
234 /* Install the customized pipeline:
236 /* _tnl_destroy_pipeline( ctx ); */
237 /* _tnl_install_pipeline( ctx, mach64_pipeline ); */
239 /* Configure swrast and T&L to match hardware characteristics:
241 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
242 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
243 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
244 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
246 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
249 mach64InitTriFuncs( ctx
);
250 mach64DDInitStateFuncs( ctx
);
251 mach64DDInitSpanFuncs( ctx
);
252 mach64DDInitState( mmesa
);
254 mmesa
->do_irqs
= (mmesa
->mach64Screen
->irq
&& !getenv("MACH64_NO_IRQS"));
256 driContextPriv
->driverPrivate
= (void *)mmesa
;
258 if (driQueryOptionb(&mmesa
->optionCache
, "no_rast")) {
259 fprintf(stderr
, "disabling 3D acceleration\n");
260 FALLBACK(mmesa
, MACH64_FALLBACK_DISABLE
, 1);
266 /* Destroy the device specific context.
268 void mach64DestroyContext( __DRIcontextPrivate
*driContextPriv
)
270 mach64ContextPtr mmesa
= (mach64ContextPtr
) driContextPriv
->driverPrivate
;
272 assert(mmesa
); /* should never be null */
274 GLboolean release_texture_heaps
;
276 release_texture_heaps
= (mmesa
->glCtx
->Shared
->RefCount
== 1);
278 _swsetup_DestroyContext( mmesa
->glCtx
);
279 _tnl_DestroyContext( mmesa
->glCtx
);
280 _vbo_DestroyContext( mmesa
->glCtx
);
281 _swrast_DestroyContext( mmesa
->glCtx
);
283 if (release_texture_heaps
) {
284 /* This share group is about to go away, free our private
285 * texture object data.
289 for ( i
= mmesa
->firstTexHeap
; i
< mmesa
->lastTexHeap
; i
++ ) {
290 driDestroyTextureHeap( mmesa
->texture_heaps
[i
] );
291 mmesa
->texture_heaps
[i
] = NULL
;
294 assert( is_empty_list( & mmesa
->swapped
) );
297 mach64FreeVB( mmesa
->glCtx
);
299 /* Free the vertex buffer */
300 if ( mmesa
->vert_buf
)
301 ALIGN_FREE( mmesa
->vert_buf
);
303 /* free the Mesa context */
304 mmesa
->glCtx
->DriverCtx
= NULL
;
305 _mesa_destroy_context(mmesa
->glCtx
);
311 /* Force the context `c' to be the current context and associate with it
315 mach64MakeCurrent( __DRIcontextPrivate
*driContextPriv
,
316 __DRIdrawablePrivate
*driDrawPriv
,
317 __DRIdrawablePrivate
*driReadPriv
)
319 if ( driContextPriv
) {
320 GET_CURRENT_CONTEXT(ctx
);
321 mach64ContextPtr oldMach64Ctx
= ctx
? MACH64_CONTEXT(ctx
) : NULL
;
322 mach64ContextPtr newMach64Ctx
= (mach64ContextPtr
) driContextPriv
->driverPrivate
;
324 if ( newMach64Ctx
!= oldMach64Ctx
) {
325 newMach64Ctx
->new_state
|= MACH64_NEW_CONTEXT
;
326 newMach64Ctx
->dirty
= MACH64_UPLOAD_ALL
;
330 if ( newMach64Ctx
->driDrawable
!= driDrawPriv
) {
331 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
332 driDrawPriv
->vblFlags
= (newMach64Ctx
->do_irqs
)
333 ? driGetDefaultVBlankFlags(&newMach64Ctx
->optionCache
)
334 : VBLANK_FLAG_NO_IRQ
;
336 driDrawableInitVBlank( driDrawPriv
);
339 newMach64Ctx
->driDrawable
= driDrawPriv
;
340 mach64CalcViewport( newMach64Ctx
->glCtx
);
343 _mesa_make_current( newMach64Ctx
->glCtx
,
344 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
345 (GLframebuffer
*) driReadPriv
->driverPrivate
);
348 newMach64Ctx
->new_state
|= MACH64_NEW_CLIP
;
350 _mesa_make_current( NULL
, NULL
, NULL
);
357 /* Force the context `c' to be unbound from its buffer.
360 mach64UnbindContext( __DRIcontextPrivate
*driContextPriv
)