1 /**************************************************************************
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
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:
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
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.
26 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
37 #include "sis_context.h"
38 #include "sis_state.h"
41 #include "sis_stencil.h"
44 #include "sis_alloc.h"
48 #include "extensions.h"
51 #include "drivers/common/driverfuncs.h"
53 #include "swrast/swrast.h"
54 #include "swrast_setup/swrast_setup.h"
55 #include "array_cache/acache.h"
58 #include "tnl/t_pipeline.h"
60 int GlobalCurrentHwcx
= -1;
61 int GlobalHwcxCountBase
= 1;
62 int GlobalCmdQueueLen
= 0;
64 static const char * const card_extensions
[] =
66 "GL_ARB_multitexture",
67 "GL_EXT_texture_lod_bias",
73 WaitEngIdle (sisContextPtr smesa
)
78 engineState
= MMIO_READ(REG_CommandQueue
);
79 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
83 Wait2DEngIdle (sisContextPtr smesa
)
88 engineState
= MMIO_READ(REG_CommandQueue
);
89 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
92 /* To be called from mWait3DCmdQueue. Separate function for profiling
93 * purposes, and speed doesn't matter because we're spinning anyway.
96 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
98 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
99 *(smesa
->CurrentQueueLenPtr
) =
100 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
105 sisCreateContext( const __GLcontextModes
*glVisual
,
106 __DRIcontextPrivate
*driContextPriv
,
107 void *sharedContextPrivate
)
109 GLcontext
*ctx
, *shareCtx
;
110 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
112 sisScreenPtr sisScreen
;
114 struct dd_function_table functions
;
116 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
120 /* Init default driver functions then plug in our SIS-specific functions
121 * (the texture functions are especially important)
123 _mesa_init_driver_functions(&functions
);
124 sisInitDriverFuncs(&functions
);
125 sisInitTextureFuncs(&functions
);
127 /* Allocate the Mesa context */
128 if (sharedContextPrivate
)
129 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
132 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
133 &functions
, (void *) smesa
);
138 driContextPriv
->driverPrivate
= smesa
;
141 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
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
;
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
;
157 smesa
->FbBase
= sPriv
->pFB
;
158 smesa
->displayWidth
= sPriv
->fbWidth
;
159 smesa
->frontPitch
= sPriv
->fbStride
;
161 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
162 sisScreen
->sarea_priv_offset
);
164 #if defined(SIS_DUMP)
165 IOBase4Debug
= GET_IOBase (smesa
);
168 /* support ARGB8888 and RGB565 */
169 switch (smesa
->bytesPerPixel
)
172 smesa
->redMask
= 0x00ff0000;
173 smesa
->greenMask
= 0x0000ff00;
174 smesa
->blueMask
= 0x000000ff;
175 smesa
->alphaMask
= 0xff000000;
176 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
179 smesa
->redMask
= 0xf800;
180 smesa
->greenMask
= 0x07e0;
181 smesa
->blueMask
= 0x001f;
182 smesa
->alphaMask
= 0;
183 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
186 sis_fatal_error("Bad bytesPerPixel.\n");
189 /* Parse configuration files */
190 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
191 sisScreen
->driScreen
->myNum
, "sis");
193 /* TODO: index mode */
195 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
196 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
199 smesa
->AGPSize
= sisScreen
->agp
.size
;
200 smesa
->AGPBase
= sisScreen
->agp
.map
;
201 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
203 /* Create AGP command buffer */
204 if (smesa
->AGPSize
!= 0 &&
205 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
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
);
217 if (!smesa
->using_agp
) {
218 smesa
->vb
= malloc(64 * 1024);
219 if (smesa
->vb
== NULL
) {
223 smesa
->vb_cur
= smesa
->vb
;
224 smesa
->vb_last
= smesa
->vb
;
225 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
228 smesa
->GlobalFlag
= 0L;
232 /* Initialize the software rasterizer and helper modules.
234 _swrast_CreateContext( ctx
);
235 _ac_CreateContext( ctx
);
236 _tnl_CreateContext( ctx
);
237 _swsetup_CreateContext( ctx
);
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
);
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
);
251 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
254 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
255 smesa
->blockWrite
= GL_FALSE
;
257 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
258 smesa
->TexStates
[i
] = 0;
259 smesa
->PrevTexFormat
[i
] = 0;
266 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
268 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
270 assert( smesa
!= NULL
);
272 if ( smesa
!= NULL
) {
273 _swsetup_DestroyContext( smesa
->glCtx
);
274 _tnl_DestroyContext( smesa
->glCtx
);
275 _ac_DestroyContext( smesa
->glCtx
);
276 _swrast_DestroyContext( smesa
->glCtx
);
278 if (smesa
->using_agp
)
279 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
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
286 /* smesa->glCtx->DriverCtx = NULL; */
287 _mesa_destroy_context(smesa
->glCtx
);
294 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
295 __DRIdrawablePrivate
*driDrawPriv
,
296 __DRIdrawablePrivate
*driReadPriv
)
298 if ( driContextPriv
) {
299 GET_CURRENT_CONTEXT(ctx
);
300 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
301 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
303 if ( newSisCtx
!= oldSisCtx
) {
304 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
307 newSisCtx
->driDrawable
= driDrawPriv
;
309 _mesa_make_current2( newSisCtx
->glCtx
,
310 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
311 (GLframebuffer
*) driReadPriv
->driverPrivate
);
313 sisUpdateBufferSize( newSisCtx
);
314 sisUpdateClipping( newSisCtx
->glCtx
);
316 if ( newSisCtx
->glCtx
->Viewport
.Width
== 0 ) {
317 _mesa_set_viewport(newSisCtx
->glCtx
, 0, 0,
318 driDrawPriv
->w
, driDrawPriv
->h
);
321 _mesa_make_current( 0, 0 );
328 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
334 sis_update_render_state( sisContextPtr smesa
)
336 __GLSiSHardware
*prev
= &smesa
->prev
;
338 mWait3DCmdQueue (45);
340 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
341 if (!smesa
->clearTexCache
) {
342 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
344 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
345 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
346 smesa
->clearTexCache
= GL_FALSE
;
350 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
351 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
354 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
356 MMIO(REG_3D_ZSet
, prev
->hwZ
);
357 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
358 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
362 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
363 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
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
);
373 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
374 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
378 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
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
);
386 /* Stencil Setting */
387 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
388 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
389 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
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
);
400 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
404 sis_update_texture_state (sisContextPtr smesa
)
406 __GLSiSHardware
*prev
= &smesa
->prev
;
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
;
415 /* Texture Setting */
416 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
417 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
419 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
420 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
423 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
424 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
427 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
428 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
430 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
431 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
434 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
436 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
437 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
439 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
441 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
442 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
444 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
446 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
447 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
449 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
451 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
452 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
454 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
456 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
457 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
459 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
461 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
462 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
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
);
470 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
471 MMIO(REG_3D_Texture1BorderColor
,
472 prev
->texture
[1].hwTextureBorderColor
);
474 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
475 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
478 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
480 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
481 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
483 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
485 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
486 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
488 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
490 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
491 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
493 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
495 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
496 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
498 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
500 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
501 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
503 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
505 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
506 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
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
);
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
);
522 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;