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