Merge git://proxy01.pd.intel.com:9419/git/mesa/mesa into crestline
[mesa.git] / src / mesa / drivers / dri / mach64 / mach64_context.c
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 #include "glheader.h"
33 #include "context.h"
34 #include "simple_list.h"
35 #include "imports.h"
36 #include "matrix.h"
37 #include "extensions.h"
38
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "vbo/vbo.h"
42
43 #include "tnl/tnl.h"
44 #include "tnl/t_pipeline.h"
45
46 #include "drivers/common/driverfuncs.h"
47
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"
56
57 #include "utils.h"
58 #include "vblank.h"
59
60 #define need_GL_ARB_multisample
61 #include "extension_helper.h"
62
63 #ifndef MACH64_DEBUG
64 int MACH64_DEBUG = (0);
65 #endif
66
67 static const struct dri_debug_control debug_control[] =
68 {
69 { "sync", DEBUG_ALWAYS_SYNC },
70 { "api", DEBUG_VERBOSE_API },
71 { "msg", DEBUG_VERBOSE_MSG },
72 { "lru", DEBUG_VERBOSE_LRU },
73 { "dri", DEBUG_VERBOSE_DRI },
74 { "ioctl", DEBUG_VERBOSE_IOCTL },
75 { "prims", DEBUG_VERBOSE_PRIMS },
76 { "count", DEBUG_VERBOSE_COUNT },
77 { "nowait", DEBUG_NOWAIT },
78 { "fall", DEBUG_VERBOSE_FALLBACK },
79 { NULL, 0 }
80 };
81
82 const struct dri_extension card_extensions[] =
83 {
84 { "GL_ARB_multisample", GL_ARB_multisample_functions },
85 { "GL_ARB_multitexture", NULL },
86 { "GL_EXT_texture_edge_clamp", NULL },
87 { "GL_MESA_ycbcr_texture", NULL },
88 { "GL_SGIS_generate_mipmap", NULL },
89 { NULL, NULL }
90 };
91
92
93 /* Create the device specific context.
94 */
95 GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
96 __DRIcontextPrivate *driContextPriv,
97 void *sharedContextPrivate )
98 {
99 GLcontext *ctx, *shareCtx;
100 __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv;
101 struct dd_function_table functions;
102 mach64ContextPtr mmesa;
103 mach64ScreenPtr mach64Screen;
104 int i, heap;
105 GLuint *c_textureSwapsPtr = NULL;
106
107 #if DO_DEBUG
108 MACH64_DEBUG = driParseDebugString(getenv("MACH64_DEBUG"), debug_control);
109 #endif
110
111 /* Allocate the mach64 context */
112 mmesa = (mach64ContextPtr) CALLOC( sizeof(*mmesa) );
113 if ( !mmesa )
114 return GL_FALSE;
115
116 /* Init default driver functions then plug in our Mach64-specific functions
117 * (the texture functions are especially important)
118 */
119 _mesa_init_driver_functions( &functions );
120 mach64InitDriverFuncs( &functions );
121 mach64InitIoctlFuncs( &functions );
122 mach64InitTextureFuncs( &functions );
123
124 /* Allocate the Mesa context */
125 if (sharedContextPrivate)
126 shareCtx = ((mach64ContextPtr) sharedContextPrivate)->glCtx;
127 else
128 shareCtx = NULL;
129 mmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
130 &functions, (void *)mmesa);
131 if (!mmesa->glCtx) {
132 FREE(mmesa);
133 return GL_FALSE;
134 }
135 driContextPriv->driverPrivate = mmesa;
136 ctx = mmesa->glCtx;
137
138 mmesa->driContext = driContextPriv;
139 mmesa->driScreen = driScreen;
140 mmesa->driDrawable = NULL;
141 mmesa->hHWContext = driContextPriv->hHWContext;
142 mmesa->driHwLock = &driScreen->pSAREA->lock;
143 mmesa->driFd = driScreen->fd;
144
145 mach64Screen = mmesa->mach64Screen = (mach64ScreenPtr)driScreen->private;
146
147 /* Parse configuration files */
148 driParseConfigFiles (&mmesa->optionCache, &mach64Screen->optionCache,
149 mach64Screen->driScreen->myNum, "mach64");
150
151 mmesa->sarea = (drm_mach64_sarea_t *)((char *)driScreen->pSAREA +
152 sizeof(drm_sarea_t));
153
154 mmesa->CurrentTexObj[0] = NULL;
155 mmesa->CurrentTexObj[1] = NULL;
156
157 (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
158 make_empty_list( &mmesa->swapped );
159
160 mmesa->firstTexHeap = mach64Screen->firstTexHeap;
161 mmesa->lastTexHeap = mach64Screen->firstTexHeap + mach64Screen->numTexHeaps;
162
163 for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
164 mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa,
165 mach64Screen->texSize[i],
166 6, /* align to 64-byte boundary, use 12 for page-size boundary */
167 MACH64_NR_TEX_REGIONS,
168 (drmTextureRegionPtr)mmesa->sarea->tex_list[i],
169 &mmesa->sarea->tex_age[i],
170 &mmesa->swapped,
171 sizeof( mach64TexObj ),
172 (destroy_texture_object_t *) mach64DestroyTexObj );
173
174 #if ENABLE_PERF_BOXES
175 c_textureSwapsPtr = & mmesa->c_textureSwaps;
176 #endif
177 driSetTextureSwapCounterLocation( mmesa->texture_heaps[i],
178 c_textureSwapsPtr );
179 }
180
181 mmesa->RenderIndex = -1; /* Impossible value */
182 mmesa->vert_buf = NULL;
183 mmesa->num_verts = 0;
184 mmesa->new_state = MACH64_NEW_ALL;
185 mmesa->dirty = MACH64_UPLOAD_ALL;
186
187 /* Set the maximum texture size small enough that we can
188 * guarentee that both texture units can bind a maximal texture
189 * and have them both in memory (on-card or AGP) at once.
190 * Test for 2 textures * bytes/texel * size * size. There's no
191 * need to account for mipmaps since we only upload one level.
192 */
193
194 ctx->Const.MaxTextureUnits = 2;
195 ctx->Const.MaxTextureImageUnits = 2;
196 ctx->Const.MaxTextureCoordUnits = 2;
197
198 heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP;
199
200 driCalculateMaxTextureLevels( & mmesa->texture_heaps[heap],
201 1,
202 & ctx->Const,
203 mach64Screen->cpp,
204 10, /* max 2D texture size is 1024x1024 */
205 0, /* 3D textures unsupported. */
206 0, /* cube textures unsupported. */
207 0, /* texture rectangles unsupported. */
208 1, /* mipmapping unsupported. */
209 GL_TRUE, /* need to have both textures in
210 either local or AGP memory */
211 0 );
212
213 #if ENABLE_PERF_BOXES
214 mmesa->boxes = ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL );
215 #endif
216
217 /* Allocate the vertex buffer
218 */
219 mmesa->vert_buf = ALIGN_MALLOC(MACH64_BUFFER_SIZE, 32);
220 if ( !mmesa->vert_buf )
221 return GL_FALSE;
222 mmesa->vert_used = 0;
223 mmesa->vert_total = MACH64_BUFFER_SIZE;
224
225 /* Initialize the software rasterizer and helper modules.
226 */
227 _swrast_CreateContext( ctx );
228 _vbo_CreateContext( ctx );
229 _tnl_CreateContext( ctx );
230 _swsetup_CreateContext( ctx );
231
232 /* Install the customized pipeline:
233 */
234 /* _tnl_destroy_pipeline( ctx ); */
235 /* _tnl_install_pipeline( ctx, mach64_pipeline ); */
236
237 /* Configure swrast and T&L to match hardware characteristics:
238 */
239 _swrast_allow_pixel_fog( ctx, GL_FALSE );
240 _swrast_allow_vertex_fog( ctx, GL_TRUE );
241 _tnl_allow_pixel_fog( ctx, GL_FALSE );
242 _tnl_allow_vertex_fog( ctx, GL_TRUE );
243
244 driInitExtensions( ctx, card_extensions, GL_TRUE );
245
246 mach64InitVB( ctx );
247 mach64InitTriFuncs( ctx );
248 mach64DDInitStateFuncs( ctx );
249 mach64DDInitSpanFuncs( ctx );
250 mach64DDInitState( mmesa );
251
252 mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
253
254 mmesa->vblank_flags = (mmesa->do_irqs)
255 ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
256
257 driContextPriv->driverPrivate = (void *)mmesa;
258
259 if (driQueryOptionb(&mmesa->optionCache, "no_rast")) {
260 fprintf(stderr, "disabling 3D acceleration\n");
261 FALLBACK(mmesa, MACH64_FALLBACK_DISABLE, 1);
262 }
263
264 return GL_TRUE;
265 }
266
267 /* Destroy the device specific context.
268 */
269 void mach64DestroyContext( __DRIcontextPrivate *driContextPriv )
270 {
271 mach64ContextPtr mmesa = (mach64ContextPtr) driContextPriv->driverPrivate;
272
273 assert(mmesa); /* should never be null */
274 if ( mmesa ) {
275 GLboolean release_texture_heaps;
276
277 release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
278
279 _swsetup_DestroyContext( mmesa->glCtx );
280 _tnl_DestroyContext( mmesa->glCtx );
281 _vbo_DestroyContext( mmesa->glCtx );
282 _swrast_DestroyContext( mmesa->glCtx );
283
284 if (release_texture_heaps) {
285 /* This share group is about to go away, free our private
286 * texture object data.
287 */
288 int i;
289
290 for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
291 driDestroyTextureHeap( mmesa->texture_heaps[i] );
292 mmesa->texture_heaps[i] = NULL;
293 }
294
295 assert( is_empty_list( & mmesa->swapped ) );
296 }
297
298 mach64FreeVB( mmesa->glCtx );
299
300 /* Free the vertex buffer */
301 if ( mmesa->vert_buf )
302 ALIGN_FREE( mmesa->vert_buf );
303
304 /* free the Mesa context */
305 mmesa->glCtx->DriverCtx = NULL;
306 _mesa_destroy_context(mmesa->glCtx);
307
308 FREE( mmesa );
309 }
310 }
311
312 /* Force the context `c' to be the current context and associate with it
313 * buffer `b'.
314 */
315 GLboolean
316 mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
317 __DRIdrawablePrivate *driDrawPriv,
318 __DRIdrawablePrivate *driReadPriv )
319 {
320 if ( driContextPriv ) {
321 GET_CURRENT_CONTEXT(ctx);
322 mach64ContextPtr oldMach64Ctx = ctx ? MACH64_CONTEXT(ctx) : NULL;
323 mach64ContextPtr newMach64Ctx = (mach64ContextPtr) driContextPriv->driverPrivate;
324
325 if ( newMach64Ctx != oldMach64Ctx ) {
326 newMach64Ctx->new_state |= MACH64_NEW_CONTEXT;
327 newMach64Ctx->dirty = MACH64_UPLOAD_ALL;
328 }
329
330
331 driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags,
332 &newMach64Ctx->vbl_seq );
333
334 if ( newMach64Ctx->driDrawable != driDrawPriv ) {
335 newMach64Ctx->driDrawable = driDrawPriv;
336 mach64CalcViewport( newMach64Ctx->glCtx );
337 }
338
339 _mesa_make_current( newMach64Ctx->glCtx,
340 (GLframebuffer *) driDrawPriv->driverPrivate,
341 (GLframebuffer *) driReadPriv->driverPrivate );
342
343
344 newMach64Ctx->new_state |= MACH64_NEW_CLIP;
345 } else {
346 _mesa_make_current( NULL, NULL, NULL );
347 }
348
349 return GL_TRUE;
350 }
351
352
353 /* Force the context `c' to be unbound from its buffer.
354 */
355 GLboolean
356 mach64UnbindContext( __DRIcontextPrivate *driContextPriv )
357 {
358 return GL_TRUE;
359 }