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