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