applied Felix's patch for configuration system
[mesa.git] / src / mesa / drivers / dri / sis / sis_context.c
1 /**************************************************************************
2
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
28
29 /*
30 * Authors:
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
33 */
34
35 #include "sis_dri.h"
36
37 #include "sis_context.h"
38 #include "sis_state.h"
39 #include "sis_dd.h"
40 #include "sis_span.h"
41 #include "sis_stencil.h"
42 #include "sis_tex.h"
43 #include "sis_tris.h"
44 #include "sis_vb.h"
45
46 #include "imports.h"
47 #include "matrix.h"
48 #include "extensions.h"
49 #include "utils.h"
50
51 #include "swrast/swrast.h"
52 #include "swrast_setup/swrast_setup.h"
53 #include "array_cache/acache.h"
54
55 #include "tnl/tnl.h"
56 #include "tnl/t_pipeline.h"
57
58 int GlobalCurrentHwcx = -1;
59 int GlobalHwcxCountBase = 1;
60 int GlobalCmdQueueLen = 0;
61
62 static const char * const card_extensions[] =
63 {
64 "GL_ARB_multitexture",
65 "GL_EXT_texture_lod_bias",
66 NULL
67 };
68
69 void
70 WaitEngIdle (sisContextPtr smesa)
71 {
72 GLuint engineState;
73
74 do {
75 engineState = MMIO_READ(REG_CommandQueue);
76 } while ((engineState & SiS_EngIdle) != SiS_EngIdle);
77 }
78
79 void
80 Wait2DEngIdle (sisContextPtr smesa)
81 {
82 GLuint engineState;
83
84 do {
85 engineState = MMIO_READ(REG_CommandQueue);
86 } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d);
87 }
88
89 /* To be called from mWait3DCmdQueue. Separate function for profiling
90 * purposes, and speed doesn't matter because we're spinning anyway.
91 */
92 void
93 WaitingFor3dIdle(sisContextPtr smesa, int wLen)
94 {
95 while (*(smesa->CurrentQueueLenPtr) < wLen) {
96 *(smesa->CurrentQueueLenPtr) =
97 (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20;
98 }
99 }
100
101 GLboolean
102 sisCreateContext( const __GLcontextModes *glVisual,
103 __DRIcontextPrivate *driContextPriv,
104 void *sharedContextPrivate )
105 {
106 GLcontext *ctx, *shareCtx;
107 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
108 sisContextPtr smesa;
109 sisScreenPtr sisScreen;
110 int i;
111
112 smesa = (sisContextPtr)CALLOC( sizeof(*smesa) );
113 if ( smesa == NULL )
114 return GL_FALSE;
115
116 /* Allocate the Mesa context */
117 if (sharedContextPrivate)
118 shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx;
119 else
120 shareCtx = NULL;
121 smesa->glCtx = _mesa_create_context( glVisual, shareCtx, (void *) smesa,
122 GL_TRUE);
123 if (smesa->glCtx == NULL) {
124 FREE(smesa);
125 return GL_FALSE;
126 }
127 driContextPriv->driverPrivate = smesa;
128 ctx = smesa->glCtx;
129
130 sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private);
131
132 smesa->driContext = driContextPriv;
133 smesa->driScreen = sPriv;
134 smesa->driDrawable = NULL;
135 smesa->hHWContext = driContextPriv->hHWContext;
136 smesa->driHwLock = &sPriv->pSAREA->lock;
137 smesa->driFd = sPriv->fd;
138
139 smesa->virtualX = sisScreen->screenX;
140 smesa->virtualY = sisScreen->screenY;
141 smesa->bytesPerPixel = sisScreen->cpp;
142 smesa->IOBase = sisScreen->mmio.map;
143 smesa->Chipset = sisScreen->deviceID;
144 smesa->irqEnabled = sisScreen->irqEnabled;
145
146 smesa->FbBase = sPriv->pFB;
147 smesa->displayWidth = sPriv->fbWidth;
148 smesa->frontPitch = sPriv->fbStride;
149
150 smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA +
151 sisScreen->sarea_priv_offset);
152
153 #if defined(SIS_DUMP)
154 IOBase4Debug = GET_IOBase (smesa);
155 #endif
156
157 /* support ARGB8888 and RGB565 */
158 switch (smesa->bytesPerPixel)
159 {
160 case 4:
161 smesa->redMask = 0x00ff0000;
162 smesa->greenMask = 0x0000ff00;
163 smesa->blueMask = 0x000000ff;
164 smesa->alphaMask = 0xff000000;
165 smesa->colorFormat = DST_FORMAT_ARGB_8888;
166 break;
167 case 2:
168 smesa->redMask = 0xf800;
169 smesa->greenMask = 0x07e0;
170 smesa->blueMask = 0x001f;
171 smesa->alphaMask = 0;
172 smesa->colorFormat = DST_FORMAT_RGB_565;
173 break;
174 default:
175 assert (0);
176 }
177
178 /* Parse configuration files */
179 driParseConfigFiles (&smesa->optionCache, &sisScreen->optionCache,
180 sisScreen->driScreen->myNum, "sis");
181
182 /* TODO: index mode */
183
184 smesa->CurrentQueueLenPtr = &(smesa->sarea->QueueLength);
185 smesa->FrameCountPtr = &(smesa->sarea->FrameCount);
186
187 /* set AGP */
188 smesa->AGPSize = sisScreen->agp.size;
189 smesa->AGPBase = sisScreen->agp.map;
190 smesa->AGPAddr = sisScreen->agp.handle;
191
192 /* set AGP command buffer */
193 if (smesa->AGPSize != 0 && sisScreen->AGPCmdBufSize != 0 &&
194 !driQueryOptionb(&smesa->optionCache, "agp_disable"))
195 {
196 smesa->AGPCmdBufBase = smesa->AGPBase + sisScreen->AGPCmdBufOffset;
197 smesa->AGPCmdBufAddr = smesa->AGPAddr + sisScreen->AGPCmdBufOffset;
198 smesa->AGPCmdBufSize = sisScreen->AGPCmdBufSize;
199
200 smesa->pAGPCmdBufNext = (GLint *)&(smesa->sarea->AGPCmdBufNext);
201 smesa->AGPCmdModeEnabled = GL_TRUE;
202 } else {
203 smesa->AGPCmdModeEnabled = GL_FALSE;
204 }
205
206 smesa->GlobalFlag = 0L;
207
208 smesa->Fallback = 0;
209
210 /* Initialize the software rasterizer and helper modules.
211 */
212 _swrast_CreateContext( ctx );
213 _ac_CreateContext( ctx );
214 _tnl_CreateContext( ctx );
215 _swsetup_CreateContext( ctx );
216
217 _swrast_allow_pixel_fog( ctx, GL_TRUE );
218 _swrast_allow_vertex_fog( ctx, GL_FALSE );
219
220 sisDDInitStateFuncs( ctx );
221 sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */
222 sisInitVB( ctx );
223 sisInitTriFuncs( ctx );
224 sisDDInitDriverFuncs( ctx );
225 sisDDInitSpanFuncs( ctx );
226 sisDDInitStencilFuncs( ctx );
227 sisDDInitTextureFuncs( ctx );
228
229 driInitExtensions( ctx, card_extensions, GL_FALSE );
230
231 /* TODO */
232 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
233 smesa->blockWrite = GL_FALSE;
234
235 for (i = 0; i < SIS_MAX_TEXTURES; i++) {
236 smesa->TexStates[i] = 0;
237 smesa->PrevTexFormat[i] = 0;
238 }
239
240 return GL_TRUE;
241 }
242
243 void
244 sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
245 {
246 sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate;
247
248 assert( smesa != NULL );
249
250 if ( smesa != NULL ) {
251 _swsetup_DestroyContext( smesa->glCtx );
252 _tnl_DestroyContext( smesa->glCtx );
253 _ac_DestroyContext( smesa->glCtx );
254 _swrast_DestroyContext( smesa->glCtx );
255
256 /* free the Mesa context */
257 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
258 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
259 * function.
260 */
261 /* smesa->glCtx->DriverCtx = NULL; */
262 _mesa_destroy_context(smesa->glCtx);
263 }
264
265 FREE( smesa );
266 }
267
268 GLboolean
269 sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
270 __DRIdrawablePrivate *driDrawPriv,
271 __DRIdrawablePrivate *driReadPriv )
272 {
273 if ( driContextPriv ) {
274 GET_CURRENT_CONTEXT(ctx);
275 sisContextPtr oldSisCtx = ctx ? SIS_CONTEXT(ctx) : NULL;
276 sisContextPtr newSisCtx = (sisContextPtr) driContextPriv->driverPrivate;
277
278 if ( newSisCtx != oldSisCtx) {
279 newSisCtx->GlobalFlag = GFLAG_ALL;
280 }
281
282 newSisCtx->driDrawable = driDrawPriv;
283
284 _mesa_make_current2( newSisCtx->glCtx,
285 (GLframebuffer *) driDrawPriv->driverPrivate,
286 (GLframebuffer *) driReadPriv->driverPrivate );
287
288 sisUpdateBufferSize( newSisCtx );
289 sisUpdateClipping( newSisCtx->glCtx );
290
291 if ( newSisCtx->glCtx->Viewport.Width == 0 ) {
292 _mesa_set_viewport(newSisCtx->glCtx, 0, 0,
293 driDrawPriv->w, driDrawPriv->h);
294 }
295 } else {
296 _mesa_make_current( 0, 0 );
297 }
298
299 return GL_TRUE;
300 }
301
302 GLboolean
303 sisUnbindContext( __DRIcontextPrivate *driContextPriv )
304 {
305 return GL_TRUE;
306 }
307
308 void
309 sis_update_render_state( sisContextPtr smesa )
310 {
311 __GLSiSHardware *prev = &smesa->prev;
312
313 mWait3DCmdQueue (45);
314
315 if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
316 if (!smesa->clearTexCache) {
317 MMIO(REG_3D_TEnable, prev->hwCapEnable);
318 } else {
319 MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
320 MMIO(REG_3D_TEnable, prev->hwCapEnable);
321 smesa->clearTexCache = GL_FALSE;
322 }
323 }
324
325 if (smesa->GlobalFlag & GFLAG_ENABLESETTING2)
326 MMIO(REG_3D_TEnable2, prev->hwCapEnable2);
327
328 /* Z Setting */
329 if (smesa->GlobalFlag & GFLAG_ZSETTING)
330 {
331 MMIO(REG_3D_ZSet, prev->hwZ);
332 MMIO(REG_3D_ZStWriteMask, prev->hwZMask);
333 MMIO(REG_3D_ZAddress, prev->hwOffsetZ);
334 }
335
336 /* Alpha Setting */
337 if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
338 MMIO(REG_3D_AlphaSet, prev->hwAlpha);
339
340 if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
341 MMIO(REG_3D_DstSet, prev->hwDstSet);
342 MMIO(REG_3D_DstAlphaWriteMask, prev->hwDstMask);
343 MMIO(REG_3D_DstAddress, prev->hwOffsetDest);
344 }
345
346 /* Line Setting */
347 #if 0
348 if (smesa->GlobalFlag & GFLAG_LINESETTING)
349 MMIO(REG_3D_LinePattern, prev->hwLinePattern);
350 #endif
351
352 /* Fog Setting */
353 if (smesa->GlobalFlag & GFLAG_FOGSETTING)
354 {
355 MMIO(REG_3D_FogSet, prev->hwFog);
356 MMIO(REG_3D_FogInverseDistance, prev->hwFogInverse);
357 MMIO(REG_3D_FogFarDistance, prev->hwFogFar);
358 MMIO(REG_3D_FogFactorDensity, prev->hwFogDensity);
359 }
360
361 /* Stencil Setting */
362 if (smesa->GlobalFlag & GFLAG_STENCILSETTING) {
363 MMIO(REG_3D_StencilSet, prev->hwStSetting);
364 MMIO(REG_3D_StencilSet2, prev->hwStSetting2);
365 }
366
367 /* Miscellaneous Setting */
368 if (smesa->GlobalFlag & GFLAG_DSTBLEND)
369 MMIO(REG_3D_DstBlendMode, prev->hwDstSrcBlend);
370 if (smesa->GlobalFlag & GFLAG_CLIPPING) {
371 MMIO(REG_3D_ClipTopBottom, prev->clipTopBottom);
372 MMIO(REG_3D_ClipLeftRight, prev->clipLeftRight);
373 }
374
375 smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
376 }
377
378 void
379 sis_update_texture_state (sisContextPtr smesa)
380 {
381 __GLSiSHardware *prev = &smesa->prev;
382
383 mWait3DCmdQueue (55);
384 if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
385 MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
386 MMIO(REG_3D_TEnable, prev->hwCapEnable);
387 smesa->clearTexCache = GL_FALSE;
388 }
389
390 /* Texture Setting */
391 if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
392 MMIO(REG_3D_TextureSet, prev->texture[0].hwTextureSet);
393
394 if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
395 MMIO(REG_3D_TextureMip, prev->texture[0].hwTextureMip);
396
397 /*
398 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
399 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
400 */
401
402 if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
403 MMIO(REG_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);
404
405 if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
406 switch ((prev->texture[0].hwTextureSet & MASK_TextureLevel) >> 8)
407 {
408 case 11:
409 MMIO(REG_3D_TextureAddress11, prev->texture[0].texOffset11);
410 case 10:
411 MMIO(REG_3D_TextureAddress10, prev->texture[0].texOffset10);
412 MMIO(REG_3D_TexturePitch10, prev->texture[0].texPitch10);
413 case 9:
414 MMIO(REG_3D_TextureAddress9, prev->texture[0].texOffset9);
415 case 8:
416 MMIO(REG_3D_TextureAddress8, prev->texture[0].texOffset8);
417 MMIO(REG_3D_TexturePitch8, prev->texture[0].texPitch89);
418 case 7:
419 MMIO(REG_3D_TextureAddress7, prev->texture[0].texOffset7);
420 case 6:
421 MMIO(REG_3D_TextureAddress6, prev->texture[0].texOffset6);
422 MMIO(REG_3D_TexturePitch6, prev->texture[0].texPitch67);
423 case 5:
424 MMIO(REG_3D_TextureAddress5, prev->texture[0].texOffset5);
425 case 4:
426 MMIO(REG_3D_TextureAddress4, prev->texture[0].texOffset4);
427 MMIO(REG_3D_TexturePitch4, prev->texture[0].texPitch45);
428 case 3:
429 MMIO(REG_3D_TextureAddress3, prev->texture[0].texOffset3);
430 case 2:
431 MMIO(REG_3D_TextureAddress2, prev->texture[0].texOffset2);
432 MMIO(REG_3D_TexturePitch2, prev->texture[0].texPitch23);
433 case 1:
434 MMIO(REG_3D_TextureAddress1, prev->texture[0].texOffset1);
435 case 0:
436 MMIO(REG_3D_TextureAddress0, prev->texture[0].texOffset0);
437 MMIO(REG_3D_TexturePitch0, prev->texture[0].texPitch01);
438 }
439 }
440 if (smesa->GlobalFlag & CFLAG_TEXTURERESET_1)
441 MMIO(REG_3D_Texture1Set, prev->texture[1].hwTextureSet);
442 if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP_1)
443 MMIO(REG_3D_Texture1Mip, prev->texture[1].hwTextureMip);
444
445 if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR_1) {
446 MMIO(REG_3D_Texture1BorderColor,
447 prev->texture[1].hwTextureBorderColor);
448 }
449 if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS_1) {
450 switch ((prev->texture[1].hwTextureSet & MASK_TextureLevel) >> 8)
451 {
452 case 11:
453 MMIO(REG_3D_Texture1Address11, prev->texture[1].texOffset11);
454 case 10:
455 MMIO(REG_3D_Texture1Address10, prev->texture[1].texOffset10);
456 MMIO(REG_3D_Texture1Pitch10, prev->texture[1].texPitch10);
457 case 9:
458 MMIO(REG_3D_Texture1Address9, prev->texture[1].texOffset9);
459 case 8:
460 MMIO(REG_3D_Texture1Address8, prev->texture[1].texOffset8);
461 MMIO(REG_3D_Texture1Pitch8, prev->texture[1].texPitch89);
462 case 7:
463 MMIO(REG_3D_Texture1Address7, prev->texture[1].texOffset7);
464 case 6:
465 MMIO(REG_3D_Texture1Address6, prev->texture[1].texOffset6);
466 MMIO(REG_3D_Texture1Pitch6, prev->texture[1].texPitch67);
467 case 5:
468 MMIO(REG_3D_Texture1Address5, prev->texture[1].texOffset5);
469 case 4:
470 MMIO(REG_3D_Texture1Address4, prev->texture[1].texOffset4);
471 MMIO(REG_3D_Texture1Pitch4, prev->texture[1].texPitch45);
472 case 3:
473 MMIO(REG_3D_Texture1Address3, prev->texture[1].texOffset3);
474 case 2:
475 MMIO(REG_3D_Texture1Address2, prev->texture[1].texOffset2);
476 MMIO(REG_3D_Texture1Pitch2, prev->texture[1].texPitch23);
477 case 1:
478 MMIO(REG_3D_Texture1Address1, prev->texture[1].texOffset1);
479 case 0:
480 MMIO(REG_3D_Texture1Address0, prev->texture[1].texOffset0);
481 MMIO(REG_3D_Texture1Pitch0, prev->texture[1].texPitch01);
482 }
483 }
484
485 /* texture environment */
486 if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
487 MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
488 MMIO(REG_3D_TextureColorBlendSet0, prev->hwTexBlendColor0);
489 MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0);
490 }
491 if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) {
492 MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
493 MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendColor1);
494 MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1);
495 }
496
497 smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
498 }
499
500 void
501 sis_fatal_error (void)
502 {
503 /* free video memory, or the framebuffer device will do it automatically */
504
505 fprintf(stderr, "Fatal errors in sis_dri.so\n");
506 exit (-1);
507 }