Make SiS a little more like other drivers: Add SIS_DEBUG (only option being
[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_alloc.h"
45
46 #include "imports.h"
47 #include "matrix.h"
48 #include "extensions.h"
49 #include "utils.h"
50 #include "framebuffer.h"
51
52 #include "drivers/common/driverfuncs.h"
53
54 #include "swrast/swrast.h"
55 #include "swrast_setup/swrast_setup.h"
56 #include "array_cache/acache.h"
57
58 #include "tnl/tnl.h"
59 #include "tnl/t_pipeline.h"
60
61 #define need_GL_ARB_multisample
62 #include "extension_helper.h"
63
64 #ifndef SIS_DEBUG
65 int SIS_DEBUG = 0;
66 #endif
67
68 int GlobalCurrentHwcx = -1;
69 int GlobalHwcxCountBase = 1;
70 int GlobalCmdQueueLen = 0;
71
72 struct dri_extension card_extensions[] =
73 {
74 { "GL_ARB_multisample", GL_ARB_multisample_functions },
75 { "GL_ARB_multitexture", NULL },
76 { "GL_EXT_texture_lod_bias", NULL },
77 { "GL_NV_blend_square", NULL },
78 { NULL, NULL }
79 };
80
81 static const struct dri_debug_control debug_control[] =
82 {
83 { "fall", DEBUG_FALLBACKS },
84 { NULL, 0 }
85 };
86
87 void
88 WaitEngIdle (sisContextPtr smesa)
89 {
90 GLuint engineState;
91
92 do {
93 engineState = MMIO_READ(REG_CommandQueue);
94 } while ((engineState & SiS_EngIdle) != SiS_EngIdle);
95 }
96
97 void
98 Wait2DEngIdle (sisContextPtr smesa)
99 {
100 GLuint engineState;
101
102 do {
103 engineState = MMIO_READ(REG_CommandQueue);
104 } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d);
105 }
106
107 /* To be called from mWait3DCmdQueue. Separate function for profiling
108 * purposes, and speed doesn't matter because we're spinning anyway.
109 */
110 void
111 WaitingFor3dIdle(sisContextPtr smesa, int wLen)
112 {
113 while (*(smesa->CurrentQueueLenPtr) < wLen) {
114 *(smesa->CurrentQueueLenPtr) =
115 (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20;
116 }
117 }
118
119 void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
120 GLuint width, GLuint height)
121 {
122 sisContextPtr smesa = SIS_CONTEXT(ctx);
123
124 sisUpdateBufferSize(smesa);
125
126 _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
127 }
128
129 GLboolean
130 sisCreateContext( const __GLcontextModes *glVisual,
131 __DRIcontextPrivate *driContextPriv,
132 void *sharedContextPrivate )
133 {
134 GLcontext *ctx, *shareCtx;
135 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
136 sisContextPtr smesa;
137 sisScreenPtr sisScreen;
138 int i;
139 struct dd_function_table functions;
140
141 smesa = (sisContextPtr)CALLOC( sizeof(*smesa) );
142 if (smesa == NULL)
143 return GL_FALSE;
144
145 /* Init default driver functions then plug in our SIS-specific functions
146 * (the texture functions are especially important)
147 */
148 _mesa_init_driver_functions(&functions);
149 sisInitDriverFuncs(&functions);
150 sisInitTextureFuncs(&functions);
151
152 /* Allocate the Mesa context */
153 if (sharedContextPrivate)
154 shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx;
155 else
156 shareCtx = NULL;
157 smesa->glCtx = _mesa_create_context( glVisual, shareCtx,
158 &functions, (void *) smesa);
159 if (!smesa->glCtx) {
160 FREE(smesa);
161 return GL_FALSE;
162 }
163 driContextPriv->driverPrivate = smesa;
164 ctx = smesa->glCtx;
165
166 sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private);
167
168 smesa->driContext = driContextPriv;
169 smesa->driScreen = sPriv;
170 smesa->driDrawable = NULL;
171 smesa->hHWContext = driContextPriv->hHWContext;
172 smesa->driHwLock = &sPriv->pSAREA->lock;
173 smesa->driFd = sPriv->fd;
174
175 smesa->virtualX = sisScreen->screenX;
176 smesa->virtualY = sisScreen->screenY;
177 smesa->bytesPerPixel = sisScreen->cpp;
178 smesa->IOBase = sisScreen->mmio.map;
179 smesa->Chipset = sisScreen->deviceID;
180
181 smesa->FbBase = sPriv->pFB;
182 smesa->displayWidth = sPriv->fbWidth;
183 smesa->front.pitch = sPriv->fbStride;
184
185 smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA +
186 sisScreen->sarea_priv_offset);
187
188 /* support ARGB8888 and RGB565 */
189 switch (smesa->bytesPerPixel)
190 {
191 case 4:
192 smesa->redMask = 0x00ff0000;
193 smesa->greenMask = 0x0000ff00;
194 smesa->blueMask = 0x000000ff;
195 smesa->alphaMask = 0xff000000;
196 smesa->colorFormat = DST_FORMAT_ARGB_8888;
197 break;
198 case 2:
199 smesa->redMask = 0xf800;
200 smesa->greenMask = 0x07e0;
201 smesa->blueMask = 0x001f;
202 smesa->alphaMask = 0;
203 smesa->colorFormat = DST_FORMAT_RGB_565;
204 break;
205 default:
206 sis_fatal_error("Bad bytesPerPixel %d.\n", smesa->bytesPerPixel);
207 }
208
209 /* Parse configuration files */
210 driParseConfigFiles (&smesa->optionCache, &sisScreen->optionCache,
211 sisScreen->driScreen->myNum, "sis");
212
213 #if DO_DEBUG
214 SIS_DEBUG = driParseDebugString(getenv("SIS_DEBUG"), debug_control);
215 #endif
216
217 /* TODO: index mode */
218
219 smesa->CurrentQueueLenPtr = &(smesa->sarea->QueueLength);
220 smesa->FrameCountPtr = &(smesa->sarea->FrameCount);
221
222 /* set AGP */
223 smesa->AGPSize = sisScreen->agp.size;
224 smesa->AGPBase = sisScreen->agp.map;
225 smesa->AGPAddr = sisScreen->agp.handle;
226
227 /* Create AGP command buffer */
228 if (smesa->AGPSize != 0 &&
229 !driQueryOptionb(&smesa->optionCache, "agp_disable"))
230 {
231 smesa->vb = sisAllocAGP(smesa, 64 * 1024, &smesa->vb_agp_handle);
232 if (smesa->vb != NULL) {
233 smesa->using_agp = GL_TRUE;
234 smesa->vb_cur = smesa->vb;
235 smesa->vb_last = smesa->vb;
236 smesa->vb_end = smesa->vb + 64 * 1024;
237 smesa->vb_agp_offset = ((long)smesa->vb - (long)smesa->AGPBase +
238 (long)smesa->AGPAddr);
239 }
240 }
241 if (!smesa->using_agp) {
242 smesa->vb = malloc(64 * 1024);
243 if (smesa->vb == NULL) {
244 FREE(smesa);
245 return GL_FALSE;
246 }
247 smesa->vb_cur = smesa->vb;
248 smesa->vb_last = smesa->vb;
249 smesa->vb_end = smesa->vb + 64 * 1024;
250 }
251
252 smesa->GlobalFlag = 0L;
253
254 smesa->Fallback = 0;
255
256 /* Initialize the software rasterizer and helper modules.
257 */
258 _swrast_CreateContext( ctx );
259 _ac_CreateContext( ctx );
260 _tnl_CreateContext( ctx );
261 _swsetup_CreateContext( ctx );
262
263 _swrast_allow_pixel_fog( ctx, GL_TRUE );
264 _swrast_allow_vertex_fog( ctx, GL_FALSE );
265 _tnl_allow_pixel_fog( ctx, GL_TRUE );
266 _tnl_allow_vertex_fog( ctx, GL_FALSE );
267
268 /* XXX these should really go right after _mesa_init_driver_functions() */
269 sisDDInitStateFuncs( ctx );
270 sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */
271 sisInitTriFuncs( ctx );
272 sisDDInitSpanFuncs( ctx );
273 sisDDInitStencilFuncs( ctx );
274
275 driInitExtensions( ctx, card_extensions, GL_FALSE );
276
277 /* TODO */
278 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
279 smesa->blockWrite = GL_FALSE;
280
281 for (i = 0; i < SIS_MAX_TEXTURES; i++) {
282 smesa->TexStates[i] = 0;
283 smesa->PrevTexFormat[i] = 0;
284 }
285
286 if (driQueryOptionb(&smesa->optionCache, "no_rast")) {
287 fprintf(stderr, "disabling 3D acceleration\n");
288 FALLBACK(smesa, SIS_FALLBACK_DISABLE, 1);
289 }
290
291 return GL_TRUE;
292 }
293
294 void
295 sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
296 {
297 sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate;
298
299 assert( smesa != NULL );
300
301 if ( smesa != NULL ) {
302 _swsetup_DestroyContext( smesa->glCtx );
303 _tnl_DestroyContext( smesa->glCtx );
304 _ac_DestroyContext( smesa->glCtx );
305 _swrast_DestroyContext( smesa->glCtx );
306
307 if (smesa->using_agp)
308 sisFreeAGP(smesa, smesa->vb_agp_handle);
309
310 /* free the Mesa context */
311 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
312 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
313 * function.
314 */
315 /* smesa->glCtx->DriverCtx = NULL; */
316 _mesa_destroy_context(smesa->glCtx);
317 }
318
319 FREE( smesa );
320 }
321
322 GLboolean
323 sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
324 __DRIdrawablePrivate *driDrawPriv,
325 __DRIdrawablePrivate *driReadPriv )
326 {
327 if ( driContextPriv ) {
328 GET_CURRENT_CONTEXT(ctx);
329 sisContextPtr oldSisCtx = ctx ? SIS_CONTEXT(ctx) : NULL;
330 sisContextPtr newSisCtx = (sisContextPtr) driContextPriv->driverPrivate;
331 struct gl_framebuffer *drawBuffer, *readBuffer;
332
333 if ( newSisCtx != oldSisCtx) {
334 newSisCtx->GlobalFlag = GFLAG_ALL;
335 }
336
337 newSisCtx->driDrawable = driDrawPriv;
338
339 drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
340 readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
341
342 _mesa_make_current( newSisCtx->glCtx, drawBuffer, readBuffer );
343
344 sisUpdateBufferSize( newSisCtx );
345 sisUpdateClipping( newSisCtx->glCtx );
346 } else {
347 _mesa_make_current( NULL, NULL, NULL );
348 }
349
350 return GL_TRUE;
351 }
352
353 GLboolean
354 sisUnbindContext( __DRIcontextPrivate *driContextPriv )
355 {
356 return GL_TRUE;
357 }
358
359 void
360 sis_update_render_state( sisContextPtr smesa )
361 {
362 __GLSiSHardware *prev = &smesa->prev;
363
364 mWait3DCmdQueue (45);
365
366 if (smesa->GlobalFlag & GFLAG_ENABLESETTING) {
367 if (!smesa->clearTexCache) {
368 MMIO(REG_3D_TEnable, prev->hwCapEnable);
369 } else {
370 MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
371 MMIO(REG_3D_TEnable, prev->hwCapEnable);
372 smesa->clearTexCache = GL_FALSE;
373 }
374 }
375
376 if (smesa->GlobalFlag & GFLAG_ENABLESETTING2)
377 MMIO(REG_3D_TEnable2, prev->hwCapEnable2);
378
379 /* Z Setting */
380 if (smesa->GlobalFlag & GFLAG_ZSETTING)
381 {
382 MMIO(REG_3D_ZSet, prev->hwZ);
383 MMIO(REG_3D_ZStWriteMask, prev->hwZMask);
384 MMIO(REG_3D_ZAddress, prev->hwOffsetZ);
385 }
386
387 /* Alpha Setting */
388 if (smesa->GlobalFlag & GFLAG_ALPHASETTING)
389 MMIO(REG_3D_AlphaSet, prev->hwAlpha);
390
391 if (smesa->GlobalFlag & GFLAG_DESTSETTING) {
392 MMIO(REG_3D_DstSet, prev->hwDstSet);
393 MMIO(REG_3D_DstAlphaWriteMask, prev->hwDstMask);
394 MMIO(REG_3D_DstAddress, prev->hwOffsetDest);
395 }
396
397 /* Line Setting */
398 #if 0
399 if (smesa->GlobalFlag & GFLAG_LINESETTING)
400 MMIO(REG_3D_LinePattern, prev->hwLinePattern);
401 #endif
402
403 /* Fog Setting */
404 if (smesa->GlobalFlag & GFLAG_FOGSETTING)
405 {
406 MMIO(REG_3D_FogSet, prev->hwFog);
407 MMIO(REG_3D_FogInverseDistance, prev->hwFogInverse);
408 MMIO(REG_3D_FogFarDistance, prev->hwFogFar);
409 MMIO(REG_3D_FogFactorDensity, prev->hwFogDensity);
410 }
411
412 /* Stencil Setting */
413 if (smesa->GlobalFlag & GFLAG_STENCILSETTING) {
414 MMIO(REG_3D_StencilSet, prev->hwStSetting);
415 MMIO(REG_3D_StencilSet2, prev->hwStSetting2);
416 }
417
418 /* Miscellaneous Setting */
419 if (smesa->GlobalFlag & GFLAG_DSTBLEND)
420 MMIO(REG_3D_DstBlendMode, prev->hwDstSrcBlend);
421 if (smesa->GlobalFlag & GFLAG_CLIPPING) {
422 MMIO(REG_3D_ClipTopBottom, prev->clipTopBottom);
423 MMIO(REG_3D_ClipLeftRight, prev->clipLeftRight);
424 }
425
426 smesa->GlobalFlag &= ~GFLAG_RENDER_STATES;
427 }
428
429 void
430 sis_update_texture_state (sisContextPtr smesa)
431 {
432 __GLSiSHardware *prev = &smesa->prev;
433
434 mWait3DCmdQueue (55);
435 if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) {
436 MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear);
437 MMIO(REG_3D_TEnable, prev->hwCapEnable);
438 smesa->clearTexCache = GL_FALSE;
439 }
440
441 /* Texture Setting */
442 if (smesa->GlobalFlag & CFLAG_TEXTURERESET)
443 MMIO(REG_3D_TextureSet, prev->texture[0].hwTextureSet);
444
445 if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP)
446 MMIO(REG_3D_TextureMip, prev->texture[0].hwTextureMip);
447
448 /*
449 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
450 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
451 */
452
453 if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR)
454 MMIO(REG_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor);
455
456 if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) {
457 switch ((prev->texture[0].hwTextureSet & MASK_TextureLevel) >> 8)
458 {
459 case 11:
460 MMIO(REG_3D_TextureAddress11, prev->texture[0].texOffset11);
461 case 10:
462 MMIO(REG_3D_TextureAddress10, prev->texture[0].texOffset10);
463 MMIO(REG_3D_TexturePitch10, prev->texture[0].texPitch10);
464 case 9:
465 MMIO(REG_3D_TextureAddress9, prev->texture[0].texOffset9);
466 case 8:
467 MMIO(REG_3D_TextureAddress8, prev->texture[0].texOffset8);
468 MMIO(REG_3D_TexturePitch8, prev->texture[0].texPitch89);
469 case 7:
470 MMIO(REG_3D_TextureAddress7, prev->texture[0].texOffset7);
471 case 6:
472 MMIO(REG_3D_TextureAddress6, prev->texture[0].texOffset6);
473 MMIO(REG_3D_TexturePitch6, prev->texture[0].texPitch67);
474 case 5:
475 MMIO(REG_3D_TextureAddress5, prev->texture[0].texOffset5);
476 case 4:
477 MMIO(REG_3D_TextureAddress4, prev->texture[0].texOffset4);
478 MMIO(REG_3D_TexturePitch4, prev->texture[0].texPitch45);
479 case 3:
480 MMIO(REG_3D_TextureAddress3, prev->texture[0].texOffset3);
481 case 2:
482 MMIO(REG_3D_TextureAddress2, prev->texture[0].texOffset2);
483 MMIO(REG_3D_TexturePitch2, prev->texture[0].texPitch23);
484 case 1:
485 MMIO(REG_3D_TextureAddress1, prev->texture[0].texOffset1);
486 case 0:
487 MMIO(REG_3D_TextureAddress0, prev->texture[0].texOffset0);
488 MMIO(REG_3D_TexturePitch0, prev->texture[0].texPitch01);
489 }
490 }
491 if (smesa->GlobalFlag & CFLAG_TEXTURERESET_1)
492 MMIO(REG_3D_Texture1Set, prev->texture[1].hwTextureSet);
493 if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP_1)
494 MMIO(REG_3D_Texture1Mip, prev->texture[1].hwTextureMip);
495
496 if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR_1) {
497 MMIO(REG_3D_Texture1BorderColor,
498 prev->texture[1].hwTextureBorderColor);
499 }
500 if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS_1) {
501 switch ((prev->texture[1].hwTextureSet & MASK_TextureLevel) >> 8)
502 {
503 case 11:
504 MMIO(REG_3D_Texture1Address11, prev->texture[1].texOffset11);
505 case 10:
506 MMIO(REG_3D_Texture1Address10, prev->texture[1].texOffset10);
507 MMIO(REG_3D_Texture1Pitch10, prev->texture[1].texPitch10);
508 case 9:
509 MMIO(REG_3D_Texture1Address9, prev->texture[1].texOffset9);
510 case 8:
511 MMIO(REG_3D_Texture1Address8, prev->texture[1].texOffset8);
512 MMIO(REG_3D_Texture1Pitch8, prev->texture[1].texPitch89);
513 case 7:
514 MMIO(REG_3D_Texture1Address7, prev->texture[1].texOffset7);
515 case 6:
516 MMIO(REG_3D_Texture1Address6, prev->texture[1].texOffset6);
517 MMIO(REG_3D_Texture1Pitch6, prev->texture[1].texPitch67);
518 case 5:
519 MMIO(REG_3D_Texture1Address5, prev->texture[1].texOffset5);
520 case 4:
521 MMIO(REG_3D_Texture1Address4, prev->texture[1].texOffset4);
522 MMIO(REG_3D_Texture1Pitch4, prev->texture[1].texPitch45);
523 case 3:
524 MMIO(REG_3D_Texture1Address3, prev->texture[1].texOffset3);
525 case 2:
526 MMIO(REG_3D_Texture1Address2, prev->texture[1].texOffset2);
527 MMIO(REG_3D_Texture1Pitch2, prev->texture[1].texPitch23);
528 case 1:
529 MMIO(REG_3D_Texture1Address1, prev->texture[1].texOffset1);
530 case 0:
531 MMIO(REG_3D_Texture1Address0, prev->texture[1].texOffset0);
532 MMIO(REG_3D_Texture1Pitch0, prev->texture[1].texPitch01);
533 }
534 }
535
536 /* texture environment */
537 if (smesa->GlobalFlag & GFLAG_TEXTUREENV) {
538 MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
539 MMIO(REG_3D_TextureColorBlendSet0, prev->hwTexBlendColor0);
540 MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0);
541 }
542 if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) {
543 MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor);
544 MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendColor1);
545 MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1);
546 }
547
548 smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES;
549 }
550