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"
48 #include "extensions.h"
51 #include "swrast/swrast.h"
52 #include "swrast_setup/swrast_setup.h"
53 #include "array_cache/acache.h"
56 #include "tnl/t_pipeline.h"
58 int GlobalCurrentHwcx
= -1;
59 int GlobalHwcxCountBase
= 1;
60 int GlobalCmdQueueLen
= 0;
62 static const char * const card_extensions
[] =
64 "GL_ARB_multitexture",
65 "GL_EXT_texture_lod_bias",
70 WaitEngIdle (sisContextPtr smesa
)
75 engineState
= MMIO_READ(REG_CommandQueue
);
76 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
80 Wait2DEngIdle (sisContextPtr smesa
)
85 engineState
= MMIO_READ(REG_CommandQueue
);
86 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
89 /* To be called from mWait3DCmdQueue. Separate function for profiling
90 * purposes, and speed doesn't matter because we're spinning anyway.
93 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
95 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
96 *(smesa
->CurrentQueueLenPtr
) =
97 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
102 sisCreateContext( const __GLcontextModes
*glVisual
,
103 __DRIcontextPrivate
*driContextPriv
,
104 void *sharedContextPrivate
)
106 GLcontext
*ctx
, *shareCtx
;
107 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
109 sisScreenPtr sisScreen
;
112 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
116 /* Allocate the Mesa context */
117 if (sharedContextPrivate
)
118 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
121 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
, (void *) smesa
,
123 if (smesa
->glCtx
== NULL
) {
127 driContextPriv
->driverPrivate
= smesa
;
130 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
132 smesa
->driContext
= driContextPriv
;
133 smesa
->driScreen
= sPriv
;
134 smesa
->driDrawable
= NULL
;
135 smesa
->hHWContext
= driContextPriv
->hHWContext
;
136 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
137 smesa
->driFd
= sPriv
->fd
;
139 smesa
->virtualX
= sisScreen
->screenX
;
140 smesa
->virtualY
= sisScreen
->screenY
;
141 smesa
->bytesPerPixel
= sisScreen
->cpp
;
142 smesa
->IOBase
= sisScreen
->mmio
.map
;
143 smesa
->Chipset
= sisScreen
->deviceID
;
144 smesa
->irqEnabled
= sisScreen
->irqEnabled
;
146 smesa
->FbBase
= sPriv
->pFB
;
147 smesa
->displayWidth
= sPriv
->fbWidth
;
148 smesa
->frontPitch
= sPriv
->fbStride
;
150 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
151 sisScreen
->sarea_priv_offset
);
153 #if defined(SIS_DUMP)
154 IOBase4Debug
= GET_IOBase (smesa
);
157 /* support ARGB8888 and RGB565 */
158 switch (smesa
->bytesPerPixel
)
161 smesa
->redMask
= 0x00ff0000;
162 smesa
->greenMask
= 0x0000ff00;
163 smesa
->blueMask
= 0x000000ff;
164 smesa
->alphaMask
= 0xff000000;
165 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
168 smesa
->redMask
= 0xf800;
169 smesa
->greenMask
= 0x07e0;
170 smesa
->blueMask
= 0x001f;
171 smesa
->alphaMask
= 0;
172 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
178 /* Parse configuration files */
179 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
180 sisScreen
->driScreen
->myNum
, "sis");
182 /* TODO: index mode */
184 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
185 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
188 smesa
->AGPSize
= sisScreen
->agp
.size
;
189 smesa
->AGPBase
= sisScreen
->agp
.map
;
190 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
192 /* set AGP command buffer */
193 if (smesa
->AGPSize
!= 0 && sisScreen
->AGPCmdBufSize
!= 0 &&
194 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
196 smesa
->AGPCmdBufBase
= smesa
->AGPBase
+ sisScreen
->AGPCmdBufOffset
;
197 smesa
->AGPCmdBufAddr
= smesa
->AGPAddr
+ sisScreen
->AGPCmdBufOffset
;
198 smesa
->AGPCmdBufSize
= sisScreen
->AGPCmdBufSize
;
200 smesa
->pAGPCmdBufNext
= (GLint
*)&(smesa
->sarea
->AGPCmdBufNext
);
201 smesa
->AGPCmdModeEnabled
= GL_TRUE
;
203 smesa
->AGPCmdModeEnabled
= GL_FALSE
;
206 smesa
->GlobalFlag
= 0L;
210 /* Initialize the software rasterizer and helper modules.
212 _swrast_CreateContext( ctx
);
213 _ac_CreateContext( ctx
);
214 _tnl_CreateContext( ctx
);
215 _swsetup_CreateContext( ctx
);
217 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
218 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
220 sisDDInitStateFuncs( ctx
);
221 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
223 sisInitTriFuncs( ctx
);
224 sisDDInitDriverFuncs( ctx
);
225 sisDDInitSpanFuncs( ctx
);
226 sisDDInitStencilFuncs( ctx
);
227 sisDDInitTextureFuncs( ctx
);
229 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
232 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
233 smesa
->blockWrite
= GL_FALSE
;
235 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
236 smesa
->TexStates
[i
] = 0;
237 smesa
->PrevTexFormat
[i
] = 0;
244 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
246 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
248 assert( smesa
!= NULL
);
250 if ( smesa
!= NULL
) {
251 _swsetup_DestroyContext( smesa
->glCtx
);
252 _tnl_DestroyContext( smesa
->glCtx
);
253 _ac_DestroyContext( smesa
->glCtx
);
254 _swrast_DestroyContext( smesa
->glCtx
);
256 /* free the Mesa context */
257 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
258 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
261 /* smesa->glCtx->DriverCtx = NULL; */
262 _mesa_destroy_context(smesa
->glCtx
);
269 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
270 __DRIdrawablePrivate
*driDrawPriv
,
271 __DRIdrawablePrivate
*driReadPriv
)
273 if ( driContextPriv
) {
274 GET_CURRENT_CONTEXT(ctx
);
275 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
276 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
278 if ( newSisCtx
!= oldSisCtx
) {
279 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
282 newSisCtx
->driDrawable
= driDrawPriv
;
284 _mesa_make_current2( newSisCtx
->glCtx
,
285 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
286 (GLframebuffer
*) driReadPriv
->driverPrivate
);
288 sisUpdateBufferSize( newSisCtx
);
289 sisUpdateClipping( newSisCtx
->glCtx
);
291 if ( newSisCtx
->glCtx
->Viewport
.Width
== 0 ) {
292 _mesa_set_viewport(newSisCtx
->glCtx
, 0, 0,
293 driDrawPriv
->w
, driDrawPriv
->h
);
296 _mesa_make_current( 0, 0 );
303 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
309 sis_update_render_state( sisContextPtr smesa
)
311 __GLSiSHardware
*prev
= &smesa
->prev
;
313 mWait3DCmdQueue (45);
315 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
316 if (!smesa
->clearTexCache
) {
317 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
319 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
320 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
321 smesa
->clearTexCache
= GL_FALSE
;
325 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
326 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
329 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
331 MMIO(REG_3D_ZSet
, prev
->hwZ
);
332 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
333 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
337 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
338 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
340 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
341 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
342 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
343 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
348 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
349 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
353 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
355 MMIO(REG_3D_FogSet
, prev
->hwFog
);
356 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
357 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
358 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
361 /* Stencil Setting */
362 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
363 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
364 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
367 /* Miscellaneous Setting */
368 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
369 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
370 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
371 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
372 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
375 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
379 sis_update_texture_state (sisContextPtr smesa
)
381 __GLSiSHardware
*prev
= &smesa
->prev
;
383 mWait3DCmdQueue (55);
384 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
385 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
386 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
387 smesa
->clearTexCache
= GL_FALSE
;
390 /* Texture Setting */
391 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
392 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
394 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
395 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
398 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
399 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
402 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
403 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
405 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
406 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
409 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
411 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
412 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
414 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
416 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
417 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
419 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
421 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
422 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
424 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
426 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
427 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
429 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
431 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
432 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
434 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
436 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
437 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
440 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
441 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
442 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
443 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
445 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
446 MMIO(REG_3D_Texture1BorderColor
,
447 prev
->texture
[1].hwTextureBorderColor
);
449 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
450 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
453 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
455 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
456 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
458 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
460 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
461 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
463 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
465 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
466 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
468 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
470 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
471 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
473 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
475 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
476 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
478 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
480 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
481 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
485 /* texture environment */
486 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
487 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
488 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
489 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
491 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
492 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
493 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
494 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
497 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;
501 sis_fatal_error (void)
503 /* free video memory, or the framebuffer device will do it automatically */
505 fprintf(stderr
, "Fatal errors in sis_dri.so\n");