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