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