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