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 #define need_GL_ARB_texture_compression
63 #define need_GL_EXT_secondary_color
64 #include "extension_helper.h"
70 int GlobalCurrentHwcx
= -1;
71 int GlobalHwcxCountBase
= 1;
72 int GlobalCmdQueueLen
= 0;
74 struct dri_extension card_extensions
[] =
76 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
77 { "GL_ARB_multitexture", NULL
},
78 { "GL_ARB_texture_border_clamp", NULL
},
79 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
80 { "GL_ARB_texture_mirrored_repeat", NULL
},
81 { "GL_EXT_texture_lod_bias", NULL
},
82 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
83 { "GL_EXT_stencil_wrap", NULL
},
84 /*{ "GL_MESA_ycbcr_texture", NULL },*/ /* not working yet */
85 { "GL_NV_blend_square", NULL
},
89 static const struct dri_debug_control debug_control
[] =
91 { "fall", DEBUG_FALLBACKS
},
96 WaitEngIdle (sisContextPtr smesa
)
101 engineState
= MMIO_READ(REG_CommandQueue
);
102 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
106 Wait2DEngIdle (sisContextPtr smesa
)
111 engineState
= MMIO_READ(REG_CommandQueue
);
112 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
115 /* To be called from mWait3DCmdQueue. Separate function for profiling
116 * purposes, and speed doesn't matter because we're spinning anyway.
119 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
121 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
122 *(smesa
->CurrentQueueLenPtr
) =
123 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
127 void sisReAllocateBuffers(GLcontext
*ctx
, GLframebuffer
*drawbuffer
,
128 GLuint width
, GLuint height
)
130 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
132 sisUpdateBufferSize(smesa
);
134 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
138 sisCreateContext( const __GLcontextModes
*glVisual
,
139 __DRIcontextPrivate
*driContextPriv
,
140 void *sharedContextPrivate
)
142 GLcontext
*ctx
, *shareCtx
;
143 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
145 sisScreenPtr sisScreen
;
147 struct dd_function_table functions
;
149 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
153 /* Init default driver functions then plug in our SIS-specific functions
154 * (the texture functions are especially important)
156 _mesa_init_driver_functions(&functions
);
157 sisInitDriverFuncs(&functions
);
158 sisInitTextureFuncs(&functions
);
160 /* Allocate the Mesa context */
161 if (sharedContextPrivate
)
162 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
165 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
166 &functions
, (void *) smesa
);
171 driContextPriv
->driverPrivate
= smesa
;
174 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
176 smesa
->driContext
= driContextPriv
;
177 smesa
->driScreen
= sPriv
;
178 smesa
->driDrawable
= NULL
;
179 smesa
->hHWContext
= driContextPriv
->hHWContext
;
180 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
181 smesa
->driFd
= sPriv
->fd
;
183 smesa
->virtualX
= sisScreen
->screenX
;
184 smesa
->virtualY
= sisScreen
->screenY
;
185 smesa
->bytesPerPixel
= sisScreen
->cpp
;
186 smesa
->IOBase
= sisScreen
->mmio
.map
;
187 smesa
->Chipset
= sisScreen
->deviceID
;
189 smesa
->FbBase
= sPriv
->pFB
;
190 smesa
->displayWidth
= sPriv
->fbWidth
;
191 smesa
->front
.pitch
= sPriv
->fbStride
;
193 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
194 sisScreen
->sarea_priv_offset
);
196 /* support ARGB8888 and RGB565 */
197 switch (smesa
->bytesPerPixel
)
200 smesa
->redMask
= 0x00ff0000;
201 smesa
->greenMask
= 0x0000ff00;
202 smesa
->blueMask
= 0x000000ff;
203 smesa
->alphaMask
= 0xff000000;
204 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
207 smesa
->redMask
= 0xf800;
208 smesa
->greenMask
= 0x07e0;
209 smesa
->blueMask
= 0x001f;
210 smesa
->alphaMask
= 0;
211 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
214 sis_fatal_error("Bad bytesPerPixel %d.\n", smesa
->bytesPerPixel
);
217 /* Parse configuration files */
218 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
219 sisScreen
->driScreen
->myNum
, "sis");
222 SIS_DEBUG
= driParseDebugString(getenv("SIS_DEBUG"), debug_control
);
225 /* TODO: index mode */
227 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
228 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
231 smesa
->AGPSize
= sisScreen
->agp
.size
;
232 smesa
->AGPBase
= sisScreen
->agp
.map
;
233 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
235 /* Create AGP command buffer */
236 if (smesa
->AGPSize
!= 0 &&
237 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
239 smesa
->vb
= sisAllocAGP(smesa
, 64 * 1024, &smesa
->vb_agp_handle
);
240 if (smesa
->vb
!= NULL
) {
241 smesa
->using_agp
= GL_TRUE
;
242 smesa
->vb_cur
= smesa
->vb
;
243 smesa
->vb_last
= smesa
->vb
;
244 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
245 smesa
->vb_agp_offset
= ((long)smesa
->vb
- (long)smesa
->AGPBase
+
246 (long)smesa
->AGPAddr
);
249 if (!smesa
->using_agp
) {
250 smesa
->vb
= malloc(64 * 1024);
251 if (smesa
->vb
== NULL
) {
255 smesa
->vb_cur
= smesa
->vb
;
256 smesa
->vb_last
= smesa
->vb
;
257 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
260 smesa
->GlobalFlag
= 0L;
264 /* Initialize the software rasterizer and helper modules.
266 _swrast_CreateContext( ctx
);
267 _ac_CreateContext( ctx
);
268 _tnl_CreateContext( ctx
);
269 _swsetup_CreateContext( ctx
);
271 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
272 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
273 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
274 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
276 /* XXX these should really go right after _mesa_init_driver_functions() */
277 sisDDInitStateFuncs( ctx
);
278 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
279 sisInitTriFuncs( ctx
);
280 sisDDInitSpanFuncs( ctx
);
281 sisDDInitStencilFuncs( ctx
);
283 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
286 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
287 smesa
->blockWrite
= GL_FALSE
;
289 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
290 smesa
->TexStates
[i
] = 0;
291 smesa
->PrevTexFormat
[i
] = 0;
294 if (driQueryOptionb(&smesa
->optionCache
, "no_rast")) {
295 fprintf(stderr
, "disabling 3D acceleration\n");
296 FALLBACK(smesa
, SIS_FALLBACK_DISABLE
, 1);
298 smesa
->texture_depth
= driQueryOptioni(&smesa
->optionCache
, "texture_depth");
304 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
306 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
308 assert( smesa
!= NULL
);
310 if ( smesa
!= NULL
) {
311 _swsetup_DestroyContext( smesa
->glCtx
);
312 _tnl_DestroyContext( smesa
->glCtx
);
313 _ac_DestroyContext( smesa
->glCtx
);
314 _swrast_DestroyContext( smesa
->glCtx
);
316 if (smesa
->using_agp
)
317 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
319 /* free the Mesa context */
320 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
321 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
324 /* smesa->glCtx->DriverCtx = NULL; */
325 _mesa_destroy_context(smesa
->glCtx
);
332 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
333 __DRIdrawablePrivate
*driDrawPriv
,
334 __DRIdrawablePrivate
*driReadPriv
)
336 if ( driContextPriv
) {
337 GET_CURRENT_CONTEXT(ctx
);
338 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
339 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
340 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
342 if ( newSisCtx
!= oldSisCtx
) {
343 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
346 newSisCtx
->driDrawable
= driDrawPriv
;
348 drawBuffer
= (GLframebuffer
*)driDrawPriv
->driverPrivate
;
349 readBuffer
= (GLframebuffer
*)driReadPriv
->driverPrivate
;
351 _mesa_make_current( newSisCtx
->glCtx
, drawBuffer
, readBuffer
);
353 sisUpdateBufferSize( newSisCtx
);
354 sisUpdateClipping( newSisCtx
->glCtx
);
356 _mesa_make_current( NULL
, NULL
, NULL
);
363 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
369 sis_update_render_state( sisContextPtr smesa
)
371 __GLSiSHardware
*prev
= &smesa
->prev
;
373 mWait3DCmdQueue (45);
375 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
376 if (!smesa
->clearTexCache
) {
377 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
379 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
380 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
381 smesa
->clearTexCache
= GL_FALSE
;
385 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
386 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
389 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
391 MMIO(REG_3D_ZSet
, prev
->hwZ
);
392 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
393 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
397 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
398 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
400 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
401 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
402 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
403 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
408 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
409 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
413 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
415 MMIO(REG_3D_FogSet
, prev
->hwFog
);
416 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
417 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
418 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
421 /* Stencil Setting */
422 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
423 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
424 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
427 /* Miscellaneous Setting */
428 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
429 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
430 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
431 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
432 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
435 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
439 sis_update_texture_state (sisContextPtr smesa
)
441 __GLSiSHardware
*prev
= &smesa
->prev
;
443 mWait3DCmdQueue (55);
444 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
445 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
446 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
447 smesa
->clearTexCache
= GL_FALSE
;
450 /* Texture Setting */
451 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
452 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
454 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
455 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
458 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
459 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
462 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
463 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
465 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
466 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
469 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
471 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
472 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
474 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
476 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
477 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
479 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
481 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
482 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
484 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
486 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
487 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
489 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
491 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
492 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
494 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
496 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
497 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
500 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
501 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
502 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
503 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
505 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
506 MMIO(REG_3D_Texture1BorderColor
,
507 prev
->texture
[1].hwTextureBorderColor
);
509 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
510 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
513 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
515 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
516 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
518 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
520 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
521 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
523 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
525 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
526 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
528 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
530 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
531 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
533 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
535 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
536 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
538 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
540 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
541 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
545 /* texture environment */
546 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
547 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
548 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
549 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
551 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
552 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
553 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
554 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
557 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;