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 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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
)
72 GLubyte
*IOBase
= GET_IOBase (smesa
);
75 cEngineState
= *((GLbyte
volatile *) (IOBase
+ 0x8243));
76 while (((cEngineState
& 0x80) == 0) ||
77 ((cEngineState
& 0x40) == 0) || ((cEngineState
& 0x20) == 0))
79 cEngineState
= *((GLbyte
volatile *) (IOBase
+ 0x8243));
84 Wait2DEngIdle (sisContextPtr smesa
)
86 GLubyte
*IOBase
= GET_IOBase (smesa
);
89 cEngineState
= *((GLbyte
volatile *) (IOBase
+ 0x8243));
90 while (!(cEngineState
& 0x80))
92 cEngineState
= *((GLbyte
volatile *) (IOBase
+ 0x8243));
96 /* To be called from mWait3DCmdQueue. Separate function for profiling
97 * purposes, and speed doesn't matter because we're spinning anyway.
98 * This function should use usleeps to release cpu probably, but I have yet
99 * to see it get called.
102 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
104 while ( *(smesa
->CurrentQueueLenPtr
) < wLen
) {
105 *(smesa
->CurrentQueueLenPtr
) =
106 (*(GLint
*)(GET_IOBase(smesa
) + REG_QueueLen
) & MASK_QueueLen
) - 20;
111 sisCreateContext( const __GLcontextModes
*glVisual
,
112 __DRIcontextPrivate
*driContextPriv
,
113 void *sharedContextPrivate
)
115 GLcontext
*ctx
, *shareCtx
;
116 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
118 sisScreenPtr sisScreen
;
121 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
125 /* Allocate the Mesa context */
126 if (sharedContextPrivate
)
127 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
130 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
, (void *) smesa
,
132 if (smesa
->glCtx
== NULL
) {
136 driContextPriv
->driverPrivate
= smesa
;
139 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
141 smesa
->driContext
= driContextPriv
;
142 smesa
->driScreen
= sPriv
;
143 smesa
->driDrawable
= NULL
;
144 smesa
->hHWContext
= driContextPriv
->hHWContext
;
145 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
146 smesa
->driFd
= sPriv
->fd
;
148 smesa
->virtualX
= sisScreen
->screenX
;
149 smesa
->virtualY
= sisScreen
->screenY
;
150 smesa
->bytesPerPixel
= sisScreen
->cpp
;
151 smesa
->IOBase
= sisScreen
->mmio
.map
;
152 smesa
->Chipset
= sisScreen
->deviceID
;
153 smesa
->irqEnabled
= sisScreen
->irqEnabled
;
155 smesa
->FbBase
= sPriv
->pFB
;
156 smesa
->displayWidth
= sPriv
->fbWidth
;
157 smesa
->frontPitch
= sPriv
->fbStride
;
159 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
160 sisScreen
->sarea_priv_offset
);
162 #if defined(SIS_DUMP)
163 IOBase4Debug
= GET_IOBase (smesa
);
166 /* support ARGB8888 and RGB565 */
167 switch (smesa
->bytesPerPixel
)
170 smesa
->redMask
= 0x00ff0000;
171 smesa
->greenMask
= 0x0000ff00;
172 smesa
->blueMask
= 0x000000ff;
173 smesa
->alphaMask
= 0xff000000;
174 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
177 smesa
->redMask
= 0xf800;
178 smesa
->greenMask
= 0x07e0;
179 smesa
->blueMask
= 0x001f;
180 smesa
->alphaMask
= 0;
181 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
187 /* TODO: index mode */
189 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
190 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
193 smesa
->AGPSize
= sisScreen
->agp
.size
;
194 smesa
->AGPBase
= sisScreen
->agp
.map
;
195 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
197 /* set AGP command buffer */
198 smesa
->AGPCmdModeEnabled
= GL_FALSE
;
199 if (smesa
->AGPSize
!= 0 && getenv("SIS_NO_AGP") == NULL
) {
200 if (sisScreen
->AGPCmdBufSize
!= 0) {
201 smesa
->AGPCmdBufBase
= smesa
->AGPBase
+ sisScreen
->AGPCmdBufOffset
;
202 smesa
->AGPCmdBufAddr
= smesa
->AGPAddr
+ sisScreen
->AGPCmdBufOffset
;
203 smesa
->AGPCmdBufSize
= sisScreen
->AGPCmdBufSize
;
205 smesa
->pAGPCmdBufNext
= (GLint
*)&(smesa
->sarea
->AGPCmdBufNext
);
206 smesa
->AGPCmdModeEnabled
= GL_TRUE
;
210 smesa
->GlobalFlag
= 0L;
214 /* Initialize the software rasterizer and helper modules.
216 _swrast_CreateContext( ctx
);
217 _ac_CreateContext( ctx
);
218 _tnl_CreateContext( ctx
);
219 _swsetup_CreateContext( ctx
);
221 sisDDInitStateFuncs( ctx
);
222 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
224 sisInitTriFuncs( ctx
);
225 sisDDInitDriverFuncs( ctx
);
226 sisDDInitSpanFuncs( ctx
);
227 sisDDInitStencilFuncs( ctx
);
228 sisDDInitTextureFuncs( ctx
);
230 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
233 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
234 smesa
->blockWrite
= GL_FALSE
;
236 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
237 smesa
->TexStates
[i
] = 0;
238 smesa
->PrevTexFormat
[i
] = 0;
245 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
247 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
249 assert( smesa
!= NULL
);
251 if ( smesa
!= NULL
) {
252 _swsetup_DestroyContext( smesa
->glCtx
);
253 _tnl_DestroyContext( smesa
->glCtx
);
254 _ac_DestroyContext( smesa
->glCtx
);
255 _swrast_DestroyContext( smesa
->glCtx
);
257 /* free the Mesa context */
258 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
259 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
262 /* smesa->glCtx->DriverCtx = NULL; */
263 _mesa_destroy_context(smesa
->glCtx
);
270 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
271 __DRIdrawablePrivate
*driDrawPriv
,
272 __DRIdrawablePrivate
*driReadPriv
)
274 if ( driContextPriv
) {
275 GET_CURRENT_CONTEXT(ctx
);
276 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
277 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
279 if ( newSisCtx
!= oldSisCtx
) {
280 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
283 newSisCtx
->driDrawable
= driDrawPriv
;
285 _mesa_make_current2( newSisCtx
->glCtx
,
286 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
287 (GLframebuffer
*) driReadPriv
->driverPrivate
);
289 sisUpdateBufferSize( newSisCtx
);
290 sisUpdateClipping( newSisCtx
->glCtx
);
292 if ( newSisCtx
->glCtx
->Viewport
.Width
== 0 ) {
293 _mesa_set_viewport(newSisCtx
->glCtx
, 0, 0,
294 driDrawPriv
->w
, driDrawPriv
->h
);
297 _mesa_make_current( 0, 0 );
304 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
310 sis_update_render_state( sisContextPtr smesa
)
312 __GLSiSHardware
*prev
= &smesa
->prev
;
314 mWait3DCmdQueue (45);
316 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
317 if (!smesa
->clearTexCache
) {
318 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
320 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
321 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
322 smesa
->clearTexCache
= GL_FALSE
;
326 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
327 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
330 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
332 MMIO(REG_3D_ZSet
, prev
->hwZ
);
333 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
334 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
338 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
339 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
341 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
342 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
343 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
344 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
349 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
350 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
354 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
356 MMIO(REG_3D_FogSet
, prev
->hwFog
);
357 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
358 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
359 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
362 /* Stencil Setting */
363 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
364 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
365 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
368 /* Miscellaneous Setting */
369 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
370 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
371 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
372 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
373 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
376 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
380 sis_update_texture_state (sisContextPtr smesa
)
382 __GLSiSHardware
*prev
= &smesa
->prev
;
384 mWait3DCmdQueue (55);
385 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
386 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
387 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
388 smesa
->clearTexCache
= GL_FALSE
;
391 /* Texture Setting */
392 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
393 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
395 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
396 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
399 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
400 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
403 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
404 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
406 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
407 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
410 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
412 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
413 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
415 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
417 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
418 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
420 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
422 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
423 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
425 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
427 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
428 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
430 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
432 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
433 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
435 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
437 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
438 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
441 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
442 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
443 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
444 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
446 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
447 MMIO(REG_3D_Texture1BorderColor
,
448 prev
->texture
[1].hwTextureBorderColor
);
450 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
451 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
454 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
456 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
457 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
459 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
461 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
462 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
464 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
466 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
467 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
469 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
471 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
472 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
474 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
476 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
477 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
479 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
481 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
482 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
486 /* texture environment */
487 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
488 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
489 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendClr0
);
490 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
492 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
493 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
494 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendClr1
);
495 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
498 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;
502 sis_fatal_error (void)
504 /* free video memory, or the framebuffer device will do it automatically */
506 fprintf(stderr
, "Fatal errors in sis_dri.so\n");