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"
64 int GlobalCurrentHwcx
= -1;
65 int GlobalHwcxCountBase
= 1;
66 int GlobalCmdQueueLen
= 0;
68 struct dri_extension card_extensions
[] =
70 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
71 { "GL_ARB_multitexture", NULL
},
72 { "GL_EXT_texture_lod_bias", NULL
},
73 { "GL_NV_blend_square", NULL
},
78 WaitEngIdle (sisContextPtr smesa
)
83 engineState
= MMIO_READ(REG_CommandQueue
);
84 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
88 Wait2DEngIdle (sisContextPtr smesa
)
93 engineState
= MMIO_READ(REG_CommandQueue
);
94 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
97 /* To be called from mWait3DCmdQueue. Separate function for profiling
98 * purposes, and speed doesn't matter because we're spinning anyway.
101 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
103 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
104 *(smesa
->CurrentQueueLenPtr
) =
105 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
109 void sisReAllocateBuffers(GLcontext
*ctx
, GLframebuffer
*drawbuffer
,
110 GLuint width
, GLuint height
)
112 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
114 sisUpdateBufferSize(smesa
);
116 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
120 sisCreateContext( const __GLcontextModes
*glVisual
,
121 __DRIcontextPrivate
*driContextPriv
,
122 void *sharedContextPrivate
)
124 GLcontext
*ctx
, *shareCtx
;
125 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
127 sisScreenPtr sisScreen
;
129 struct dd_function_table functions
;
131 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
135 /* Init default driver functions then plug in our SIS-specific functions
136 * (the texture functions are especially important)
138 _mesa_init_driver_functions(&functions
);
139 sisInitDriverFuncs(&functions
);
140 sisInitTextureFuncs(&functions
);
142 /* Allocate the Mesa context */
143 if (sharedContextPrivate
)
144 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
147 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
148 &functions
, (void *) smesa
);
153 driContextPriv
->driverPrivate
= smesa
;
156 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
158 smesa
->driContext
= driContextPriv
;
159 smesa
->driScreen
= sPriv
;
160 smesa
->driDrawable
= NULL
;
161 smesa
->hHWContext
= driContextPriv
->hHWContext
;
162 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
163 smesa
->driFd
= sPriv
->fd
;
165 smesa
->virtualX
= sisScreen
->screenX
;
166 smesa
->virtualY
= sisScreen
->screenY
;
167 smesa
->bytesPerPixel
= sisScreen
->cpp
;
168 smesa
->IOBase
= sisScreen
->mmio
.map
;
169 smesa
->Chipset
= sisScreen
->deviceID
;
171 smesa
->FbBase
= sPriv
->pFB
;
172 smesa
->displayWidth
= sPriv
->fbWidth
;
173 smesa
->front
.pitch
= sPriv
->fbStride
;
175 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
176 sisScreen
->sarea_priv_offset
);
178 /* support ARGB8888 and RGB565 */
179 switch (smesa
->bytesPerPixel
)
182 smesa
->redMask
= 0x00ff0000;
183 smesa
->greenMask
= 0x0000ff00;
184 smesa
->blueMask
= 0x000000ff;
185 smesa
->alphaMask
= 0xff000000;
186 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
189 smesa
->redMask
= 0xf800;
190 smesa
->greenMask
= 0x07e0;
191 smesa
->blueMask
= 0x001f;
192 smesa
->alphaMask
= 0;
193 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
196 sis_fatal_error("Bad bytesPerPixel %d.\n", smesa
->bytesPerPixel
);
199 /* Parse configuration files */
200 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
201 sisScreen
->driScreen
->myNum
, "sis");
203 /* TODO: index mode */
205 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
206 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
209 smesa
->AGPSize
= sisScreen
->agp
.size
;
210 smesa
->AGPBase
= sisScreen
->agp
.map
;
211 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
213 /* Create AGP command buffer */
214 if (smesa
->AGPSize
!= 0 &&
215 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
217 smesa
->vb
= sisAllocAGP(smesa
, 64 * 1024, &smesa
->vb_agp_handle
);
218 if (smesa
->vb
!= NULL
) {
219 smesa
->using_agp
= GL_TRUE
;
220 smesa
->vb_cur
= smesa
->vb
;
221 smesa
->vb_last
= smesa
->vb
;
222 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
223 smesa
->vb_agp_offset
= ((long)smesa
->vb
- (long)smesa
->AGPBase
+
224 (long)smesa
->AGPAddr
);
227 if (!smesa
->using_agp
) {
228 smesa
->vb
= malloc(64 * 1024);
229 if (smesa
->vb
== NULL
) {
233 smesa
->vb_cur
= smesa
->vb
;
234 smesa
->vb_last
= smesa
->vb
;
235 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
238 smesa
->GlobalFlag
= 0L;
242 /* Initialize the software rasterizer and helper modules.
244 _swrast_CreateContext( ctx
);
245 _ac_CreateContext( ctx
);
246 _tnl_CreateContext( ctx
);
247 _swsetup_CreateContext( ctx
);
249 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
250 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
251 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
252 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
254 /* XXX these should really go right after _mesa_init_driver_functions() */
255 sisDDInitStateFuncs( ctx
);
256 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
257 sisInitTriFuncs( ctx
);
258 sisDDInitSpanFuncs( ctx
);
259 sisDDInitStencilFuncs( ctx
);
261 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
264 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
265 smesa
->blockWrite
= GL_FALSE
;
267 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
268 smesa
->TexStates
[i
] = 0;
269 smesa
->PrevTexFormat
[i
] = 0;
276 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
278 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
280 assert( smesa
!= NULL
);
282 if ( smesa
!= NULL
) {
283 _swsetup_DestroyContext( smesa
->glCtx
);
284 _tnl_DestroyContext( smesa
->glCtx
);
285 _ac_DestroyContext( smesa
->glCtx
);
286 _swrast_DestroyContext( smesa
->glCtx
);
288 if (smesa
->using_agp
)
289 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
291 /* free the Mesa context */
292 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
293 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
296 /* smesa->glCtx->DriverCtx = NULL; */
297 _mesa_destroy_context(smesa
->glCtx
);
304 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
305 __DRIdrawablePrivate
*driDrawPriv
,
306 __DRIdrawablePrivate
*driReadPriv
)
308 if ( driContextPriv
) {
309 GET_CURRENT_CONTEXT(ctx
);
310 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
311 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
312 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
314 if ( newSisCtx
!= oldSisCtx
) {
315 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
318 newSisCtx
->driDrawable
= driDrawPriv
;
320 drawBuffer
= (GLframebuffer
*)driDrawPriv
->driverPrivate
;
321 readBuffer
= (GLframebuffer
*)driReadPriv
->driverPrivate
;
323 _mesa_make_current( newSisCtx
->glCtx
, drawBuffer
, readBuffer
);
325 sisUpdateBufferSize( newSisCtx
);
326 sisUpdateClipping( newSisCtx
->glCtx
);
328 _mesa_make_current( NULL
, NULL
, NULL
);
335 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
341 sis_update_render_state( sisContextPtr smesa
)
343 __GLSiSHardware
*prev
= &smesa
->prev
;
345 mWait3DCmdQueue (45);
347 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
348 if (!smesa
->clearTexCache
) {
349 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
351 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
352 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
353 smesa
->clearTexCache
= GL_FALSE
;
357 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
358 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
361 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
363 MMIO(REG_3D_ZSet
, prev
->hwZ
);
364 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
365 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
369 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
370 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
372 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
373 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
374 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
375 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
380 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
381 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
385 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
387 MMIO(REG_3D_FogSet
, prev
->hwFog
);
388 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
389 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
390 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
393 /* Stencil Setting */
394 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
395 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
396 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
399 /* Miscellaneous Setting */
400 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
401 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
402 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
403 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
404 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
407 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
411 sis_update_texture_state (sisContextPtr smesa
)
413 __GLSiSHardware
*prev
= &smesa
->prev
;
415 mWait3DCmdQueue (55);
416 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
417 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
418 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
419 smesa
->clearTexCache
= GL_FALSE
;
422 /* Texture Setting */
423 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
424 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
426 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
427 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
430 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
431 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
434 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
435 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
437 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
438 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
441 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
443 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
444 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
446 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
448 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
449 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
451 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
453 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
454 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
456 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
458 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
459 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
461 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
463 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
464 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
466 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
468 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
469 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
472 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
473 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
474 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
475 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
477 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
478 MMIO(REG_3D_Texture1BorderColor
,
479 prev
->texture
[1].hwTextureBorderColor
);
481 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
482 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
485 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
487 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
488 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
490 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
492 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
493 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
495 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
497 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
498 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
500 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
502 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
503 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
505 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
507 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
508 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
510 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
512 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
513 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
517 /* texture environment */
518 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
519 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
520 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
521 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
523 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
524 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
525 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
526 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
529 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;