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"
50 #include "framebuffer.h"
52 #include "drivers/common/driverfuncs.h"
54 #include "swrast/swrast.h"
55 #include "swrast_setup/swrast_setup.h"
56 #include "array_cache/acache.h"
59 #include "tnl/t_pipeline.h"
61 #define need_GL_ARB_multisample
62 #include "extension_helper.h"
68 int GlobalCurrentHwcx
= -1;
69 int GlobalHwcxCountBase
= 1;
70 int GlobalCmdQueueLen
= 0;
72 struct dri_extension card_extensions
[] =
74 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
75 { "GL_ARB_multitexture", NULL
},
76 { "GL_EXT_texture_lod_bias", NULL
},
77 { "GL_NV_blend_square", NULL
},
81 static const struct dri_debug_control debug_control
[] =
83 { "fall", DEBUG_FALLBACKS
},
88 WaitEngIdle (sisContextPtr smesa
)
93 engineState
= MMIO_READ(REG_CommandQueue
);
94 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
98 Wait2DEngIdle (sisContextPtr smesa
)
103 engineState
= MMIO_READ(REG_CommandQueue
);
104 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
107 /* To be called from mWait3DCmdQueue. Separate function for profiling
108 * purposes, and speed doesn't matter because we're spinning anyway.
111 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
113 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
114 *(smesa
->CurrentQueueLenPtr
) =
115 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
119 void sisReAllocateBuffers(GLcontext
*ctx
, GLframebuffer
*drawbuffer
,
120 GLuint width
, GLuint height
)
122 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
124 sisUpdateBufferSize(smesa
);
126 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
130 sisCreateContext( const __GLcontextModes
*glVisual
,
131 __DRIcontextPrivate
*driContextPriv
,
132 void *sharedContextPrivate
)
134 GLcontext
*ctx
, *shareCtx
;
135 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
137 sisScreenPtr sisScreen
;
139 struct dd_function_table functions
;
141 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
145 /* Init default driver functions then plug in our SIS-specific functions
146 * (the texture functions are especially important)
148 _mesa_init_driver_functions(&functions
);
149 sisInitDriverFuncs(&functions
);
150 sisInitTextureFuncs(&functions
);
152 /* Allocate the Mesa context */
153 if (sharedContextPrivate
)
154 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
157 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
158 &functions
, (void *) smesa
);
163 driContextPriv
->driverPrivate
= smesa
;
166 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
168 smesa
->driContext
= driContextPriv
;
169 smesa
->driScreen
= sPriv
;
170 smesa
->driDrawable
= NULL
;
171 smesa
->hHWContext
= driContextPriv
->hHWContext
;
172 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
173 smesa
->driFd
= sPriv
->fd
;
175 smesa
->virtualX
= sisScreen
->screenX
;
176 smesa
->virtualY
= sisScreen
->screenY
;
177 smesa
->bytesPerPixel
= sisScreen
->cpp
;
178 smesa
->IOBase
= sisScreen
->mmio
.map
;
179 smesa
->Chipset
= sisScreen
->deviceID
;
181 smesa
->FbBase
= sPriv
->pFB
;
182 smesa
->displayWidth
= sPriv
->fbWidth
;
183 smesa
->front
.pitch
= sPriv
->fbStride
;
185 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
186 sisScreen
->sarea_priv_offset
);
188 /* support ARGB8888 and RGB565 */
189 switch (smesa
->bytesPerPixel
)
192 smesa
->redMask
= 0x00ff0000;
193 smesa
->greenMask
= 0x0000ff00;
194 smesa
->blueMask
= 0x000000ff;
195 smesa
->alphaMask
= 0xff000000;
196 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
199 smesa
->redMask
= 0xf800;
200 smesa
->greenMask
= 0x07e0;
201 smesa
->blueMask
= 0x001f;
202 smesa
->alphaMask
= 0;
203 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
206 sis_fatal_error("Bad bytesPerPixel %d.\n", smesa
->bytesPerPixel
);
209 /* Parse configuration files */
210 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
211 sisScreen
->driScreen
->myNum
, "sis");
214 SIS_DEBUG
= driParseDebugString(getenv("SIS_DEBUG"), debug_control
);
217 /* TODO: index mode */
219 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
220 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
223 smesa
->AGPSize
= sisScreen
->agp
.size
;
224 smesa
->AGPBase
= sisScreen
->agp
.map
;
225 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
227 /* Create AGP command buffer */
228 if (smesa
->AGPSize
!= 0 &&
229 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
231 smesa
->vb
= sisAllocAGP(smesa
, 64 * 1024, &smesa
->vb_agp_handle
);
232 if (smesa
->vb
!= NULL
) {
233 smesa
->using_agp
= GL_TRUE
;
234 smesa
->vb_cur
= smesa
->vb
;
235 smesa
->vb_last
= smesa
->vb
;
236 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
237 smesa
->vb_agp_offset
= ((long)smesa
->vb
- (long)smesa
->AGPBase
+
238 (long)smesa
->AGPAddr
);
241 if (!smesa
->using_agp
) {
242 smesa
->vb
= malloc(64 * 1024);
243 if (smesa
->vb
== NULL
) {
247 smesa
->vb_cur
= smesa
->vb
;
248 smesa
->vb_last
= smesa
->vb
;
249 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
252 smesa
->GlobalFlag
= 0L;
256 /* Initialize the software rasterizer and helper modules.
258 _swrast_CreateContext( ctx
);
259 _ac_CreateContext( ctx
);
260 _tnl_CreateContext( ctx
);
261 _swsetup_CreateContext( ctx
);
263 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
264 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
265 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
266 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
268 /* XXX these should really go right after _mesa_init_driver_functions() */
269 sisDDInitStateFuncs( ctx
);
270 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
271 sisInitTriFuncs( ctx
);
272 sisDDInitSpanFuncs( ctx
);
273 sisDDInitStencilFuncs( ctx
);
275 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
278 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
279 smesa
->blockWrite
= GL_FALSE
;
281 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
282 smesa
->TexStates
[i
] = 0;
283 smesa
->PrevTexFormat
[i
] = 0;
286 if (driQueryOptionb(&smesa
->optionCache
, "no_rast")) {
287 fprintf(stderr
, "disabling 3D acceleration\n");
288 FALLBACK(smesa
, SIS_FALLBACK_DISABLE
, 1);
295 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
297 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
299 assert( smesa
!= NULL
);
301 if ( smesa
!= NULL
) {
302 _swsetup_DestroyContext( smesa
->glCtx
);
303 _tnl_DestroyContext( smesa
->glCtx
);
304 _ac_DestroyContext( smesa
->glCtx
);
305 _swrast_DestroyContext( smesa
->glCtx
);
307 if (smesa
->using_agp
)
308 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
310 /* free the Mesa context */
311 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
312 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
315 /* smesa->glCtx->DriverCtx = NULL; */
316 _mesa_destroy_context(smesa
->glCtx
);
323 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
324 __DRIdrawablePrivate
*driDrawPriv
,
325 __DRIdrawablePrivate
*driReadPriv
)
327 if ( driContextPriv
) {
328 GET_CURRENT_CONTEXT(ctx
);
329 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
330 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
331 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
333 if ( newSisCtx
!= oldSisCtx
) {
334 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
337 newSisCtx
->driDrawable
= driDrawPriv
;
339 drawBuffer
= (GLframebuffer
*)driDrawPriv
->driverPrivate
;
340 readBuffer
= (GLframebuffer
*)driReadPriv
->driverPrivate
;
342 _mesa_make_current( newSisCtx
->glCtx
, drawBuffer
, readBuffer
);
344 sisUpdateBufferSize( newSisCtx
);
345 sisUpdateClipping( newSisCtx
->glCtx
);
347 _mesa_make_current( NULL
, NULL
, NULL
);
354 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
360 sis_update_render_state( sisContextPtr smesa
)
362 __GLSiSHardware
*prev
= &smesa
->prev
;
364 mWait3DCmdQueue (45);
366 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
367 if (!smesa
->clearTexCache
) {
368 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
370 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
371 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
372 smesa
->clearTexCache
= GL_FALSE
;
376 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
377 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
380 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
382 MMIO(REG_3D_ZSet
, prev
->hwZ
);
383 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
384 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
388 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
389 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
391 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
392 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
393 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
394 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
399 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
400 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
404 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
406 MMIO(REG_3D_FogSet
, prev
->hwFog
);
407 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
408 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
409 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
412 /* Stencil Setting */
413 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
414 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
415 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
418 /* Miscellaneous Setting */
419 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
420 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
421 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
422 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
423 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
426 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
430 sis_update_texture_state (sisContextPtr smesa
)
432 __GLSiSHardware
*prev
= &smesa
->prev
;
434 mWait3DCmdQueue (55);
435 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
436 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
437 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
438 smesa
->clearTexCache
= GL_FALSE
;
441 /* Texture Setting */
442 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
443 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
445 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
446 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
449 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
450 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
453 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
454 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
456 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
457 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
460 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
462 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
463 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
465 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
467 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
468 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
470 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
472 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
473 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
475 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
477 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
478 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
480 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
482 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
483 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
485 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
487 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
488 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
491 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
492 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
493 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
494 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
496 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
497 MMIO(REG_3D_Texture1BorderColor
,
498 prev
->texture
[1].hwTextureBorderColor
);
500 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
501 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
504 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
506 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
507 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
509 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
511 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
512 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
514 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
516 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
517 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
519 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
521 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
522 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
524 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
526 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
527 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
529 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
531 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
532 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
536 /* texture environment */
537 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
538 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
539 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
540 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
542 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
543 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
544 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
545 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
548 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;