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 #include "extension_helper.h"
69 int GlobalCurrentHwcx
= -1;
70 int GlobalHwcxCountBase
= 1;
71 int GlobalCmdQueueLen
= 0;
73 struct dri_extension card_extensions
[] =
75 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
76 { "GL_ARB_multitexture", NULL
},
77 { "GL_ARB_texture_border_clamp", NULL
},
78 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
79 { "GL_ARB_texture_mirrored_repeat", NULL
},
80 { "GL_EXT_texture_lod_bias", NULL
},
81 { "GL_EXT_stencil_wrap", NULL
},
82 /*{ "GL_MESA_ycbcr_texture", NULL },*/ /* not working yet */
83 { "GL_NV_blend_square", NULL
},
87 static const struct dri_debug_control debug_control
[] =
89 { "fall", DEBUG_FALLBACKS
},
94 WaitEngIdle (sisContextPtr smesa
)
99 engineState
= MMIO_READ(REG_CommandQueue
);
100 } while ((engineState
& SiS_EngIdle
) != SiS_EngIdle
);
104 Wait2DEngIdle (sisContextPtr smesa
)
109 engineState
= MMIO_READ(REG_CommandQueue
);
110 } while ((engineState
& SiS_EngIdle2d
) != SiS_EngIdle2d
);
113 /* To be called from mWait3DCmdQueue. Separate function for profiling
114 * purposes, and speed doesn't matter because we're spinning anyway.
117 WaitingFor3dIdle(sisContextPtr smesa
, int wLen
)
119 while (*(smesa
->CurrentQueueLenPtr
) < wLen
) {
120 *(smesa
->CurrentQueueLenPtr
) =
121 (MMIO_READ(REG_CommandQueue
) & MASK_QueueLen
) - 20;
125 void sisReAllocateBuffers(GLcontext
*ctx
, GLframebuffer
*drawbuffer
,
126 GLuint width
, GLuint height
)
128 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
130 sisUpdateBufferSize(smesa
);
132 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
136 sisCreateContext( const __GLcontextModes
*glVisual
,
137 __DRIcontextPrivate
*driContextPriv
,
138 void *sharedContextPrivate
)
140 GLcontext
*ctx
, *shareCtx
;
141 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
143 sisScreenPtr sisScreen
;
145 struct dd_function_table functions
;
147 smesa
= (sisContextPtr
)CALLOC( sizeof(*smesa
) );
151 /* Init default driver functions then plug in our SIS-specific functions
152 * (the texture functions are especially important)
154 _mesa_init_driver_functions(&functions
);
155 sisInitDriverFuncs(&functions
);
156 sisInitTextureFuncs(&functions
);
158 /* Allocate the Mesa context */
159 if (sharedContextPrivate
)
160 shareCtx
= ((sisContextPtr
)sharedContextPrivate
)->glCtx
;
163 smesa
->glCtx
= _mesa_create_context( glVisual
, shareCtx
,
164 &functions
, (void *) smesa
);
169 driContextPriv
->driverPrivate
= smesa
;
172 sisScreen
= smesa
->sisScreen
= (sisScreenPtr
)(sPriv
->private);
174 smesa
->driContext
= driContextPriv
;
175 smesa
->driScreen
= sPriv
;
176 smesa
->driDrawable
= NULL
;
177 smesa
->hHWContext
= driContextPriv
->hHWContext
;
178 smesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
179 smesa
->driFd
= sPriv
->fd
;
181 smesa
->virtualX
= sisScreen
->screenX
;
182 smesa
->virtualY
= sisScreen
->screenY
;
183 smesa
->bytesPerPixel
= sisScreen
->cpp
;
184 smesa
->IOBase
= sisScreen
->mmio
.map
;
185 smesa
->Chipset
= sisScreen
->deviceID
;
187 smesa
->FbBase
= sPriv
->pFB
;
188 smesa
->displayWidth
= sPriv
->fbWidth
;
189 smesa
->front
.pitch
= sPriv
->fbStride
;
191 smesa
->sarea
= (SISSAREAPriv
*)((char *)sPriv
->pSAREA
+
192 sisScreen
->sarea_priv_offset
);
194 /* support ARGB8888 and RGB565 */
195 switch (smesa
->bytesPerPixel
)
198 smesa
->redMask
= 0x00ff0000;
199 smesa
->greenMask
= 0x0000ff00;
200 smesa
->blueMask
= 0x000000ff;
201 smesa
->alphaMask
= 0xff000000;
202 smesa
->colorFormat
= DST_FORMAT_ARGB_8888
;
205 smesa
->redMask
= 0xf800;
206 smesa
->greenMask
= 0x07e0;
207 smesa
->blueMask
= 0x001f;
208 smesa
->alphaMask
= 0;
209 smesa
->colorFormat
= DST_FORMAT_RGB_565
;
212 sis_fatal_error("Bad bytesPerPixel %d.\n", smesa
->bytesPerPixel
);
215 /* Parse configuration files */
216 driParseConfigFiles (&smesa
->optionCache
, &sisScreen
->optionCache
,
217 sisScreen
->driScreen
->myNum
, "sis");
220 SIS_DEBUG
= driParseDebugString(getenv("SIS_DEBUG"), debug_control
);
223 /* TODO: index mode */
225 smesa
->CurrentQueueLenPtr
= &(smesa
->sarea
->QueueLength
);
226 smesa
->FrameCountPtr
= &(smesa
->sarea
->FrameCount
);
229 smesa
->AGPSize
= sisScreen
->agp
.size
;
230 smesa
->AGPBase
= sisScreen
->agp
.map
;
231 smesa
->AGPAddr
= sisScreen
->agp
.handle
;
233 /* Create AGP command buffer */
234 if (smesa
->AGPSize
!= 0 &&
235 !driQueryOptionb(&smesa
->optionCache
, "agp_disable"))
237 smesa
->vb
= sisAllocAGP(smesa
, 64 * 1024, &smesa
->vb_agp_handle
);
238 if (smesa
->vb
!= NULL
) {
239 smesa
->using_agp
= GL_TRUE
;
240 smesa
->vb_cur
= smesa
->vb
;
241 smesa
->vb_last
= smesa
->vb
;
242 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
243 smesa
->vb_agp_offset
= ((long)smesa
->vb
- (long)smesa
->AGPBase
+
244 (long)smesa
->AGPAddr
);
247 if (!smesa
->using_agp
) {
248 smesa
->vb
= malloc(64 * 1024);
249 if (smesa
->vb
== NULL
) {
253 smesa
->vb_cur
= smesa
->vb
;
254 smesa
->vb_last
= smesa
->vb
;
255 smesa
->vb_end
= smesa
->vb
+ 64 * 1024;
258 smesa
->GlobalFlag
= 0L;
262 /* Initialize the software rasterizer and helper modules.
264 _swrast_CreateContext( ctx
);
265 _ac_CreateContext( ctx
);
266 _tnl_CreateContext( ctx
);
267 _swsetup_CreateContext( ctx
);
269 _swrast_allow_pixel_fog( ctx
, GL_TRUE
);
270 _swrast_allow_vertex_fog( ctx
, GL_FALSE
);
271 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
272 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
274 /* XXX these should really go right after _mesa_init_driver_functions() */
275 sisDDInitStateFuncs( ctx
);
276 sisDDInitState( smesa
); /* Initializes smesa->zFormat, important */
277 sisInitTriFuncs( ctx
);
278 sisDDInitSpanFuncs( ctx
);
279 sisDDInitStencilFuncs( ctx
);
281 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
284 /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */
285 smesa
->blockWrite
= GL_FALSE
;
287 for (i
= 0; i
< SIS_MAX_TEXTURES
; i
++) {
288 smesa
->TexStates
[i
] = 0;
289 smesa
->PrevTexFormat
[i
] = 0;
292 if (driQueryOptionb(&smesa
->optionCache
, "no_rast")) {
293 fprintf(stderr
, "disabling 3D acceleration\n");
294 FALLBACK(smesa
, SIS_FALLBACK_DISABLE
, 1);
296 smesa
->texture_depth
= driQueryOptioni(&smesa
->optionCache
, "texture_depth");
302 sisDestroyContext ( __DRIcontextPrivate
*driContextPriv
)
304 sisContextPtr smesa
= (sisContextPtr
)driContextPriv
->driverPrivate
;
306 assert( smesa
!= NULL
);
308 if ( smesa
!= NULL
) {
309 _swsetup_DestroyContext( smesa
->glCtx
);
310 _tnl_DestroyContext( smesa
->glCtx
);
311 _ac_DestroyContext( smesa
->glCtx
);
312 _swrast_DestroyContext( smesa
->glCtx
);
314 if (smesa
->using_agp
)
315 sisFreeAGP(smesa
, smesa
->vb_agp_handle
);
317 /* free the Mesa context */
318 /* XXX: Is the next line needed? The DriverCtx (smesa) reference is
319 * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free
322 /* smesa->glCtx->DriverCtx = NULL; */
323 _mesa_destroy_context(smesa
->glCtx
);
330 sisMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
331 __DRIdrawablePrivate
*driDrawPriv
,
332 __DRIdrawablePrivate
*driReadPriv
)
334 if ( driContextPriv
) {
335 GET_CURRENT_CONTEXT(ctx
);
336 sisContextPtr oldSisCtx
= ctx
? SIS_CONTEXT(ctx
) : NULL
;
337 sisContextPtr newSisCtx
= (sisContextPtr
) driContextPriv
->driverPrivate
;
338 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
340 if ( newSisCtx
!= oldSisCtx
) {
341 newSisCtx
->GlobalFlag
= GFLAG_ALL
;
344 newSisCtx
->driDrawable
= driDrawPriv
;
346 drawBuffer
= (GLframebuffer
*)driDrawPriv
->driverPrivate
;
347 readBuffer
= (GLframebuffer
*)driReadPriv
->driverPrivate
;
349 _mesa_make_current( newSisCtx
->glCtx
, drawBuffer
, readBuffer
);
351 sisUpdateBufferSize( newSisCtx
);
352 sisUpdateClipping( newSisCtx
->glCtx
);
354 _mesa_make_current( NULL
, NULL
, NULL
);
361 sisUnbindContext( __DRIcontextPrivate
*driContextPriv
)
367 sis_update_render_state( sisContextPtr smesa
)
369 __GLSiSHardware
*prev
= &smesa
->prev
;
371 mWait3DCmdQueue (45);
373 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING
) {
374 if (!smesa
->clearTexCache
) {
375 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
377 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
378 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
379 smesa
->clearTexCache
= GL_FALSE
;
383 if (smesa
->GlobalFlag
& GFLAG_ENABLESETTING2
)
384 MMIO(REG_3D_TEnable2
, prev
->hwCapEnable2
);
387 if (smesa
->GlobalFlag
& GFLAG_ZSETTING
)
389 MMIO(REG_3D_ZSet
, prev
->hwZ
);
390 MMIO(REG_3D_ZStWriteMask
, prev
->hwZMask
);
391 MMIO(REG_3D_ZAddress
, prev
->hwOffsetZ
);
395 if (smesa
->GlobalFlag
& GFLAG_ALPHASETTING
)
396 MMIO(REG_3D_AlphaSet
, prev
->hwAlpha
);
398 if (smesa
->GlobalFlag
& GFLAG_DESTSETTING
) {
399 MMIO(REG_3D_DstSet
, prev
->hwDstSet
);
400 MMIO(REG_3D_DstAlphaWriteMask
, prev
->hwDstMask
);
401 MMIO(REG_3D_DstAddress
, prev
->hwOffsetDest
);
406 if (smesa
->GlobalFlag
& GFLAG_LINESETTING
)
407 MMIO(REG_3D_LinePattern
, prev
->hwLinePattern
);
411 if (smesa
->GlobalFlag
& GFLAG_FOGSETTING
)
413 MMIO(REG_3D_FogSet
, prev
->hwFog
);
414 MMIO(REG_3D_FogInverseDistance
, prev
->hwFogInverse
);
415 MMIO(REG_3D_FogFarDistance
, prev
->hwFogFar
);
416 MMIO(REG_3D_FogFactorDensity
, prev
->hwFogDensity
);
419 /* Stencil Setting */
420 if (smesa
->GlobalFlag
& GFLAG_STENCILSETTING
) {
421 MMIO(REG_3D_StencilSet
, prev
->hwStSetting
);
422 MMIO(REG_3D_StencilSet2
, prev
->hwStSetting2
);
425 /* Miscellaneous Setting */
426 if (smesa
->GlobalFlag
& GFLAG_DSTBLEND
)
427 MMIO(REG_3D_DstBlendMode
, prev
->hwDstSrcBlend
);
428 if (smesa
->GlobalFlag
& GFLAG_CLIPPING
) {
429 MMIO(REG_3D_ClipTopBottom
, prev
->clipTopBottom
);
430 MMIO(REG_3D_ClipLeftRight
, prev
->clipLeftRight
);
433 smesa
->GlobalFlag
&= ~GFLAG_RENDER_STATES
;
437 sis_update_texture_state (sisContextPtr smesa
)
439 __GLSiSHardware
*prev
= &smesa
->prev
;
441 mWait3DCmdQueue (55);
442 if (smesa
->clearTexCache
|| (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
)) {
443 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
| MASK_TextureCacheClear
);
444 MMIO(REG_3D_TEnable
, prev
->hwCapEnable
);
445 smesa
->clearTexCache
= GL_FALSE
;
448 /* Texture Setting */
449 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET
)
450 MMIO(REG_3D_TextureSet
, prev
->texture
[0].hwTextureSet
);
452 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP
)
453 MMIO(REG_3D_TextureMip
, prev
->texture
[0].hwTextureMip
);
456 MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh);
457 MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow);
460 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR
)
461 MMIO(REG_3D_TextureBorderColor
, prev
->texture
[0].hwTextureBorderColor
);
463 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS
) {
464 switch ((prev
->texture
[0].hwTextureSet
& MASK_TextureLevel
) >> 8)
467 MMIO(REG_3D_TextureAddress11
, prev
->texture
[0].texOffset11
);
469 MMIO(REG_3D_TextureAddress10
, prev
->texture
[0].texOffset10
);
470 MMIO(REG_3D_TexturePitch10
, prev
->texture
[0].texPitch10
);
472 MMIO(REG_3D_TextureAddress9
, prev
->texture
[0].texOffset9
);
474 MMIO(REG_3D_TextureAddress8
, prev
->texture
[0].texOffset8
);
475 MMIO(REG_3D_TexturePitch8
, prev
->texture
[0].texPitch89
);
477 MMIO(REG_3D_TextureAddress7
, prev
->texture
[0].texOffset7
);
479 MMIO(REG_3D_TextureAddress6
, prev
->texture
[0].texOffset6
);
480 MMIO(REG_3D_TexturePitch6
, prev
->texture
[0].texPitch67
);
482 MMIO(REG_3D_TextureAddress5
, prev
->texture
[0].texOffset5
);
484 MMIO(REG_3D_TextureAddress4
, prev
->texture
[0].texOffset4
);
485 MMIO(REG_3D_TexturePitch4
, prev
->texture
[0].texPitch45
);
487 MMIO(REG_3D_TextureAddress3
, prev
->texture
[0].texOffset3
);
489 MMIO(REG_3D_TextureAddress2
, prev
->texture
[0].texOffset2
);
490 MMIO(REG_3D_TexturePitch2
, prev
->texture
[0].texPitch23
);
492 MMIO(REG_3D_TextureAddress1
, prev
->texture
[0].texOffset1
);
494 MMIO(REG_3D_TextureAddress0
, prev
->texture
[0].texOffset0
);
495 MMIO(REG_3D_TexturePitch0
, prev
->texture
[0].texPitch01
);
498 if (smesa
->GlobalFlag
& CFLAG_TEXTURERESET_1
)
499 MMIO(REG_3D_Texture1Set
, prev
->texture
[1].hwTextureSet
);
500 if (smesa
->GlobalFlag
& GFLAG_TEXTUREMIPMAP_1
)
501 MMIO(REG_3D_Texture1Mip
, prev
->texture
[1].hwTextureMip
);
503 if (smesa
->GlobalFlag
& GFLAG_TEXBORDERCOLOR_1
) {
504 MMIO(REG_3D_Texture1BorderColor
,
505 prev
->texture
[1].hwTextureBorderColor
);
507 if (smesa
->GlobalFlag
& GFLAG_TEXTUREADDRESS_1
) {
508 switch ((prev
->texture
[1].hwTextureSet
& MASK_TextureLevel
) >> 8)
511 MMIO(REG_3D_Texture1Address11
, prev
->texture
[1].texOffset11
);
513 MMIO(REG_3D_Texture1Address10
, prev
->texture
[1].texOffset10
);
514 MMIO(REG_3D_Texture1Pitch10
, prev
->texture
[1].texPitch10
);
516 MMIO(REG_3D_Texture1Address9
, prev
->texture
[1].texOffset9
);
518 MMIO(REG_3D_Texture1Address8
, prev
->texture
[1].texOffset8
);
519 MMIO(REG_3D_Texture1Pitch8
, prev
->texture
[1].texPitch89
);
521 MMIO(REG_3D_Texture1Address7
, prev
->texture
[1].texOffset7
);
523 MMIO(REG_3D_Texture1Address6
, prev
->texture
[1].texOffset6
);
524 MMIO(REG_3D_Texture1Pitch6
, prev
->texture
[1].texPitch67
);
526 MMIO(REG_3D_Texture1Address5
, prev
->texture
[1].texOffset5
);
528 MMIO(REG_3D_Texture1Address4
, prev
->texture
[1].texOffset4
);
529 MMIO(REG_3D_Texture1Pitch4
, prev
->texture
[1].texPitch45
);
531 MMIO(REG_3D_Texture1Address3
, prev
->texture
[1].texOffset3
);
533 MMIO(REG_3D_Texture1Address2
, prev
->texture
[1].texOffset2
);
534 MMIO(REG_3D_Texture1Pitch2
, prev
->texture
[1].texPitch23
);
536 MMIO(REG_3D_Texture1Address1
, prev
->texture
[1].texOffset1
);
538 MMIO(REG_3D_Texture1Address0
, prev
->texture
[1].texOffset0
);
539 MMIO(REG_3D_Texture1Pitch0
, prev
->texture
[1].texPitch01
);
543 /* texture environment */
544 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV
) {
545 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
546 MMIO(REG_3D_TextureColorBlendSet0
, prev
->hwTexBlendColor0
);
547 MMIO(REG_3D_TextureAlphaBlendSet0
, prev
->hwTexBlendAlpha0
);
549 if (smesa
->GlobalFlag
& GFLAG_TEXTUREENV_1
) {
550 MMIO(REG_3D_TextureBlendFactor
, prev
->hwTexEnvColor
);
551 MMIO(REG_3D_TextureColorBlendSet1
, prev
->hwTexBlendColor1
);
552 MMIO(REG_3D_TextureAlphaBlendSet1
, prev
->hwTexBlendAlpha1
);
555 smesa
->GlobalFlag
&= ~GFLAG_TEXTURE_STATES
;