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",
72 WaitEngIdle (sisContextPtr smesa
)
77 engineState
= MMIO_READ(REG_CommandQueue
);
78 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
82 Wait2DEngIdle (sisContextPtr smesa
)
87 engineState
= MMIO_READ(REG_CommandQueue
);
88 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
91 /* To be called from mWait3DCmdQueue. Separate function for profiling
92 * purposes, and speed doesn't matter because we're spinning anyway.
95 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
97 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
98 *(smesa
->CurrentQueueLenPtr
) =
99 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
104 sisCreateContext( const __GLcontextModes
*glVisual
,
105 __DRIcontextPrivate
*driContextPriv
,
106 void *sharedContextPrivate
)
108 GLcontext
*ctx
, *shareCtx
;
109 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
111 sisScreenPtr sisScreen
;
113 struct dd_function_table functions
;
115 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
119 /* Init default driver functions then plug in our SIS-specific functions
120 * (the texture functions are especially important)
122 _mesa_init_driver_functions(&functions
);
123 sisInitDriverFuncs(&functions
);
124 sisInitTextureFuncs(&functions
);
126 /* Allocate the Mesa context */
127 if (sharedContextPrivate
)
128 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
131 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
132 &functions
, (void *) smesa
);
137 driContextPriv
->driverPrivate
= smesa
;
140 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
142 smesa
->driContext
= driContextPriv
;
143 smesa
->driScreen
= sPriv
;
144 smesa
->driDrawable
= NULL
;
145 smesa
->hHWContext
= driContextPriv
->hHWContext
;
146 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
147 smesa
->driFd
= sPriv
->fd
;
149 smesa
->virtualX
= sisScreen
->screenX
;
150 smesa
->virtualY
= sisScreen
->screenY
;
151 smesa
->bytesPerPixel
= sisScreen
->cpp
;
152 smesa
->IOBase
= sisScreen
->mmio
.map
;
153 smesa
->Chipset
= sisScreen
->deviceID
;
154 smesa
->irqEnabled
= sisScreen
->irqEnabled
;
156 smesa
->FbBase
= sPriv
->pFB
;
157 smesa
->displayWidth
= sPriv
->fbWidth
;
158 smesa
->frontPitch
= sPriv
->fbStride
;
160 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
161 sisScreen
->sarea_priv_offset
);
163 #if defined(SIS_DUMP)
164 IOBase4Debug
= GET_IOBase (smesa
);
167 /* support ARGB8888 and RGB565 */
168 switch (smesa
->bytesPerPixel
)
171 smesa
->redMask
= 0x00ff0000;
172 smesa
->greenMask
= 0x0000ff00;
173 smesa
->blueMask
= 0x000000ff;
174 smesa
->alphaMask
= 0xff000000;
175 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
178 smesa
->redMask
= 0xf800;
179 smesa
->greenMask
= 0x07e0;
180 smesa
->blueMask
= 0x001f;
181 smesa
->alphaMask
= 0;
182 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
185 sis_fatal_error("Bad bytesPerPixel.\n");
188 /* Parse configuration files */
189 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
190 sisScreen
->driScreen
->myNum
, "sis");
192 /* TODO: index mode */
194 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
195 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
198 smesa
->AGPSize
= sisScreen
->agp
.size
;
199 smesa
->AGPBase
= sisScreen
->agp
.map
;
200 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
202 /* Create AGP command buffer */
203 if (smesa
->AGPSize
!= 0 &&
204 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
206 smesa
->vb
= sisAllocAGP(smesa
, 64 * 1024, &smesa
->vb_agp_handle
);
207 if (smesa
->vb
!= NULL
) {
208 smesa
->using_agp
= GL_TRUE
;
209 smesa
->vb_cur
= smesa
->vb
;
210 smesa
->vb_last
= smesa
->vb
;
211 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
212 smesa
->vb_agp_offset
= ((long)smesa
->vb
- (long)smesa
->AGPBase
+
213 (long)smesa
->AGPAddr
);
216 if (!smesa
->using_agp
) {
217 smesa
->vb
= malloc(64 * 1024);
218 if (smesa
->vb
== NULL
) {
222 smesa
->vb_cur
= smesa
->vb
;
223 smesa
->vb_last
= smesa
->vb
;
224 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
227 smesa
->GlobalFlag
= 0L;
231 /* Initialize the software rasterizer and helper modules.
233 _swrast_CreateContext( ctx
);
234 _ac_CreateContext( ctx
);
235 _tnl_CreateContext( ctx
);
236 _swsetup_CreateContext( ctx
);
238 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
239 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
240 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
241 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
243 /* XXX these should really go right after _mesa_init_driver_functions() */
244 sisDDInitStateFuncs( ctx
);
245 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
246 sisInitTriFuncs( ctx
);
247 sisDDInitSpanFuncs( ctx
);
248 sisDDInitStencilFuncs( ctx
);
250 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
253 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
254 smesa
->blockWrite
= GL_FALSE
;
256 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
257 smesa
->TexStates
[i
] = 0;
258 smesa
->PrevTexFormat
[i
] = 0;
265 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
267 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
269 assert( smesa
!= NULL
);
271 if ( smesa
!= NULL
) {
272 _swsetup_DestroyContext( smesa
->glCtx
);
273 _tnl_DestroyContext( smesa
->glCtx
);
274 _ac_DestroyContext( smesa
->glCtx
);
275 _swrast_DestroyContext( smesa
->glCtx
);
277 if (smesa
->using_agp
)
278 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
280 /* free the Mesa context */
281 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
282 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
285 /* smesa->glCtx->DriverCtx = NULL; */
286 _mesa_destroy_context(smesa
->glCtx
);
293 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
294 __DRIdrawablePrivate
*driDrawPriv
,
295 __DRIdrawablePrivate
*driReadPriv
)
297 if ( driContextPriv
) {
298 GET_CURRENT_CONTEXT(ctx
);
299 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
300 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
302 if ( newSisCtx
!= oldSisCtx
) {
303 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
306 newSisCtx
->driDrawable
= driDrawPriv
;
308 _mesa_make_current2( newSisCtx
->glCtx
,
309 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
310 (GLframebuffer
*) driReadPriv
->driverPrivate
);
312 sisUpdateBufferSize( newSisCtx
);
313 sisUpdateClipping( newSisCtx
->glCtx
);
315 if ( newSisCtx
->glCtx
->Viewport
.Width
== 0 ) {
316 _mesa_set_viewport(newSisCtx
->glCtx
, 0, 0,
317 driDrawPriv
->w
, driDrawPriv
->h
);
320 _mesa_make_current( 0, 0 );
327 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
333 sis_update_render_state( sisContextPtr smesa
)
335 __GLSiSHardware
*prev
= &smesa
->prev
;
337 mWait3DCmdQueue (45);
339 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
340 if (!smesa
->clearTexCache
) {
341 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
343 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
344 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
345 smesa
->clearTexCache
= GL_FALSE
;
349 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
350 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
353 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
355 MMIO(REG_3D_ZSet
, prev
->hwZ
);
356 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
357 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
361 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
362 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
364 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
365 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
366 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
367 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
372 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
373 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
377 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
379 MMIO(REG_3D_FogSet
, prev
->hwFog
);
380 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
381 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
382 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
385 /* Stencil Setting */
386 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
387 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
388 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
391 /* Miscellaneous Setting */
392 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
393 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
394 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
395 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
396 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
399 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
403 sis_update_texture_state (sisContextPtr smesa
)
405 __GLSiSHardware
*prev
= &smesa
->prev
;
407 mWait3DCmdQueue (55);
408 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
409 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
410 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
411 smesa
->clearTexCache
= GL_FALSE
;
414 /* Texture Setting */
415 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
416 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
418 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
419 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
422 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
423 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
426 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
427 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
429 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
430 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
433 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
435 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
436 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
438 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
440 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
441 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
443 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
445 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
446 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
448 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
450 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
451 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
453 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
455 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
456 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
458 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
460 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
461 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
464 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
465 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
466 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
467 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
469 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
470 MMIO(REG_3D_Texture1BorderColor
,
471 prev
->texture
[1].hwTextureBorderColor
);
473 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
474 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
477 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
479 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
480 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
482 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
484 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
485 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
487 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
489 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
490 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
492 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
494 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
495 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
497 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
499 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
500 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
502 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
504 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
505 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
509 /* texture environment */
510 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
511 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
512 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
513 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
515 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
516 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
517 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
518 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
521 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;