2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
28 * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
29 * \author Others at VIA Technologies?
30 * \author Others at S3 Graphics?
36 #include "simple_list.h"
37 #include "extensions.h"
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
42 #include "array_cache/acache.h"
44 #include "tnl/t_pipeline.h"
46 #include "drivers/common/driverfuncs.h"
48 #include "via_screen.h"
51 #include "via_state.h"
56 #include "via_ioctl.h"
60 #include <X11/Xlibint.h>
65 #define DRIVER_DATE "20020221"
69 viaContextPtr current_mesa
;
71 GLuint DRAW_FRONT
= 0;
73 GLuint VIA_PERFORMANCE
= 0;
74 #ifdef PERFORMANCE_MEASURE
77 hash_element hash_table
[HASH_TABLE_SIZE
][HASH_TABLE_DEPTH
];
79 /*=* John Sheng [2003.5.31] agp tex *=*/
80 extern GLuint agpFullCount
;
83 AllocateBuffer(viaContextPtr vmesa
)
85 vmesa
->front_base
= vmesa
->driScreen
->pFB
;
86 if (vmesa
->drawType
== GLX_PBUFFER_BIT
) {
88 via_free_front_buffer(vmesa
);
89 if (!via_alloc_front_buffer(vmesa
))
95 via_free_back_buffer(vmesa
);
96 if (!via_alloc_back_buffer(vmesa
))
100 if (vmesa
->hasDepth
|| vmesa
->hasStencil
) {
101 if (vmesa
->depth
.map
)
102 via_free_depth_buffer(vmesa
);
103 if (!via_alloc_depth_buffer(vmesa
)) {
104 via_free_depth_buffer(vmesa
);
113 * Return various strings for \c glGetString.
116 * This function should look at the PCI ID of the chipset to determine what
117 * name to use. Users with a KM400, for example, might get confused when
118 * the driver says "CLE266". Having the correct information may also help
119 * folks on the DRI mailing lists debug problems for people.
123 static const GLubyte
*viaGetString(GLcontext
*ctx
, GLenum name
)
125 static char buffer
[128];
131 return (GLubyte
*)"VIA Technology";
134 offset
= driGetRendererString( buffer
, "CLE266", DRIVER_DATE
, 0 );
135 return (GLubyte
*)buffer
;
142 void viaReAllocateBuffers(GLframebuffer
*drawbuffer
)
145 viaContextPtr vmesa
= current_mesa
;
148 ctx
->DrawBuffer
->Width
= drawbuffer
->Width
;
149 ctx
->DrawBuffer
->Height
= drawbuffer
->Height
;
152 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
154 ctx
->DrawBuffer
->Accum
= 0;
156 vmesa
->driDrawable
->w
= ctx
->DrawBuffer
->Width
;
157 vmesa
->driDrawable
->h
= ctx
->DrawBuffer
->Height
;
158 LOCK_HARDWARE(vmesa
);
160 /* Allocate back & depth buffer */
163 w
= vmesa
->driDrawable
->w
;
164 h
= vmesa
->driDrawable
->h
;
166 bpp
= vmesa
->viaScreen
->bitsPerPixel
;
168 if (VIA_DEBUG
) fprintf(stderr
, "driScreen->fbBPP = %d\n", bpp
);
171 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
172 vmesa
->back
.size
= w
* h
* bpp
/ 8;
173 vmesa
->back
.pitch
= w
<< 2;
176 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2 + 16;
177 vmesa
->back
.size
= w
* h
* bpp
/ 8;
178 vmesa
->back
.pitch
= w
<< 1;
181 if (VIA_DEBUG
) fprintf(stderr
, "resizebuffer backbuffer: w = %d h = %d bpp = %d sizs = %d\n",
182 w
, h
, bpp
, vmesa
->back
.size
);
185 w
= vmesa
->driDrawable
->w
;
186 if (vmesa
->hasDepth
&& vmesa
->hasStencil
) {
187 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
188 vmesa
->depth
.size
= w
* h
* 4;
189 vmesa
->depth
.pitch
= w
<< 2;
190 vmesa
->depth
.bpp
= 32;
192 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 24\n");
193 if (VIA_DEBUG
) fprintf(stderr
, "StencilBits = 8\n");
196 else if (vmesa
->hasDepth
) {
197 /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
198 /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
199 /*vmesa->depthBits = 16;*/
201 if (vmesa
->depthBits
== 16) {
202 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2 + 16;
203 vmesa
->depth
.size
= w
* h
* 2;
204 vmesa
->depth
.pitch
= w
<< 1;
205 vmesa
->depth
.bpp
= 16;
207 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 16\n");
211 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
212 vmesa
->depth
.size
= w
* h
* 4;
213 vmesa
->depth
.pitch
= w
<< 2;
214 vmesa
->depth
.bpp
= 32;
216 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 32\n");
220 else if (vmesa
->hasStencil
) {
221 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
222 vmesa
->depth
.size
= w
* h
* 4;
223 vmesa
->depth
.pitch
= w
<< 2;
224 vmesa
->depth
.bpp
= 32;
226 if (VIA_DEBUG
) fprintf(stderr
, "StencilBits = 8\n");
230 if (VIA_DEBUG
) fprintf(stderr
, "resizebuffer depthbuffer: w = %d h = %d bpp = %d sizs = %d\n",
231 w
, h
, vmesa
->depth
.bpp
, vmesa
->depth
.size
);
233 /*=* John Sheng [2003.5.31] flip *=*/
235 if(vmesa
->viaScreen
->width
== vmesa
->driDrawable
->w
&&
236 vmesa
->viaScreen
->height
== vmesa
->driDrawable
->h
) {
237 vmesa
->back
.pitch
= vmesa
->front
.pitch
;
238 vmesa
->back
.size
= vmesa
->front
.size
;
242 if (!AllocateBuffer(vmesa
)) {
246 UNLOCK_HARDWARE(vmesa
);
248 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
251 static void viaBufferSize(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
255 viaContextPtr vmesa
= current_mesa
;
256 *width
= vmesa
->driDrawable
->w
;
257 *height
= vmesa
->driDrawable
->h
;
260 /* Extension strings exported by the Unichrome driver.
262 static const char * const card_extensions
[] =
264 "GL_ARB_multitexture",
265 "GL_ARB_point_parameters", /* John Sheng [2003.7.18] point param. */
266 "GL_ARB_texture_env_add",
267 "GL_ARB_texture_env_combine", /* John Sheng [2003.7.18] tex combine */
268 "GL_ARB_texture_env_dot3", /* John Sheng [2003.7.18] tex dot3 */
269 "GL_EXT_point_parameters", /* John Sheng [2003.7.18] point param. */
270 "GL_EXT_stencil_wrap",
271 "GL_EXT_texture_env_add",
272 "GL_EXT_texture_env_combine", /* John Sheng [2003.7.18] tex combine */
273 "GL_EXT_texture_env_dot3", /* John Sheng [2003.7.18] tex dot3 */
274 "GL_EXT_texture_lod_bias",
278 extern const struct tnl_pipeline_stage _via_fastrender_stage
;
279 extern const struct tnl_pipeline_stage _via_render_stage
;
281 static const struct tnl_pipeline_stage
*via_pipeline
[] = {
282 &_tnl_vertex_transform_stage
,
283 &_tnl_normal_transform_stage
,
284 &_tnl_lighting_stage
,
285 &_tnl_fog_coordinate_stage
,
287 &_tnl_texture_transform_stage
,
288 /* REMOVE: point attenuation stage */
290 &_via_fastrender_stage
, /* ADD: unclipped rastersetup-to-dma */
291 &_via_render_stage
, /* ADD: modification from _tnl_render_stage */
299 AllocateDmaBuffer(const GLvisual
*visual
, viaContextPtr vmesa
)
302 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
304 if (vmesa
->dma
[0].map
&& vmesa
->dma
[1].map
)
305 via_free_dma_buffer(vmesa
);
307 if (!via_alloc_dma_buffer(vmesa
)) {
308 if (vmesa
->front
.map
)
309 via_free_front_buffer(vmesa
);
311 via_free_back_buffer(vmesa
);
312 if (vmesa
->depth
.map
)
313 via_free_depth_buffer(vmesa
);
318 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
324 InitVertexBuffer(viaContextPtr vmesa
)
328 addr
= (GLuint
*)vmesa
->dma
[0].map
;
330 *addr
= (HC_ParaType_NotTex
<< 16);
334 addr
= (GLuint
*)vmesa
->dma
[1].map
;
336 *addr
= (HC_ParaType_NotTex
<< 16);
341 vmesa
->dmaLow
= DMA_OFFSET
;
342 vmesa
->dmaHigh
= vmesa
->dma
[0].size
;
343 vmesa
->dmaAddr
= (unsigned char *)vmesa
->dma
[0].map
;
344 vmesa
->dmaLastPrim
= vmesa
->dmaLow
;
348 FreeBuffer(viaContextPtr vmesa
)
350 if (vmesa
->front
.map
)
351 via_free_front_buffer(vmesa
);
354 via_free_back_buffer(vmesa
);
356 if (vmesa
->depth
.map
)
357 via_free_depth_buffer(vmesa
);
359 if (vmesa
->dma
[0].map
&& vmesa
->dma
[1].map
)
360 via_free_dma_buffer(vmesa
);
364 viaCreateContext(const __GLcontextModes
*mesaVis
,
365 __DRIcontextPrivate
*driContextPriv
,
366 void *sharedContextPrivate
)
368 GLcontext
*ctx
, *shareCtx
;
370 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
371 viaScreenPrivate
*viaScreen
= (viaScreenPrivate
*)sPriv
->private;
372 drm_via_sarea_t
*saPriv
= (drm_via_sarea_t
*)
373 (((GLubyte
*)sPriv
->pSAREA
) + viaScreen
->sareaPrivOffset
);
374 struct dd_function_table functions
;
376 /* Allocate via context */
377 vmesa
= (viaContextPtr
) CALLOC_STRUCT(via_context_t
);
382 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
384 current_mesa
= vmesa
;
385 /* pick back buffer */
386 if (mesaVis
->doubleBufferMode
) {
387 vmesa
->hasBack
= GL_TRUE
;
390 vmesa
->hasBack
= GL_FALSE
;
393 if (mesaVis
->haveDepthBuffer
) {
394 vmesa
->hasDepth
= GL_TRUE
;
395 vmesa
->depthBits
= mesaVis
->depthBits
;
398 vmesa
->hasDepth
= GL_FALSE
;
399 vmesa
->depthBits
= 0;
401 /* pick stencil buffer */
402 if (mesaVis
->haveStencilBuffer
) {
403 vmesa
->hasStencil
= GL_TRUE
;
404 vmesa
->stencilBits
= mesaVis
->stencilBits
;
407 vmesa
->hasStencil
= GL_FALSE
;
408 vmesa
->stencilBits
= 0;
411 _mesa_init_driver_functions(&functions
);
412 viaInitTextureFuncs(&functions
);
414 /* Allocate the Mesa context */
415 if (sharedContextPrivate
)
416 shareCtx
= ((viaContextPtr
) sharedContextPrivate
)->glCtx
;
420 vmesa
->glCtx
= _mesa_create_context(mesaVis
, shareCtx
, &functions
, (void*) vmesa
);
422 vmesa
->shareCtx
= shareCtx
;
428 driContextPriv
->driverPrivate
= vmesa
;
433 /*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/
434 /*if (viaScreen->textureSize < 2 * 1024 * 1024) {
435 ctx->Const.MaxTextureLevels = 9;
437 else if (viaScreen->textureSize < 8 * 1024 * 1024) {
438 ctx->Const.MaxTextureLevels = 10;
441 ctx->Const.MaxTextureLevels = 11;
443 ctx
->Const
.MaxTextureLevels
= 11;
445 ctx
->Const
.MaxTextureUnits
= 2;
447 ctx
->Const
.MinLineWidth
= 1.0;
448 ctx
->Const
.MinLineWidthAA
= 1.0;
449 ctx
->Const
.MaxLineWidth
= 3.0;
450 ctx
->Const
.MaxLineWidthAA
= 3.0;
451 ctx
->Const
.LineWidthGranularity
= 1.0;
453 ctx
->Const
.MinPointSize
= 1.0;
454 ctx
->Const
.MinPointSizeAA
= 1.0;
455 ctx
->Const
.MaxPointSize
= 3.0;
456 ctx
->Const
.MaxPointSizeAA
= 3.0;
457 ctx
->Const
.PointSizeGranularity
= 1.0;
459 ctx
->Driver
.GetBufferSize
= viaBufferSize
;
460 /* ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; *//* FIXME ?? */
461 ctx
->Driver
.GetString
= viaGetString
;
463 ctx
->DriverCtx
= (void *)vmesa
;
466 /* Initialize the software rasterizer and helper modules.
468 _swrast_CreateContext(ctx
);
469 _ac_CreateContext(ctx
);
470 _tnl_CreateContext(ctx
);
471 _swsetup_CreateContext(ctx
);
473 /* Install the customized pipeline:
475 _tnl_destroy_pipeline(ctx
);
476 _tnl_install_pipeline(ctx
, via_pipeline
);
478 /* Configure swrast and T&L to match hardware characteristics:
480 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
481 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
482 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
483 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
486 /* vmesa->display = dpy; */
487 vmesa
->display
= sPriv
->display
;
490 vmesa
->hHWContext
= driContextPriv
->hHWContext
;
491 vmesa
->driFd
= sPriv
->fd
;
492 vmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
494 vmesa
->viaScreen
= viaScreen
;
495 vmesa
->driScreen
= sPriv
;
496 vmesa
->sarea
= saPriv
;
497 vmesa
->glBuffer
= NULL
;
499 vmesa
->texHeap
= mmInit(0, viaScreen
->textureSize
);
500 vmesa
->stippleInHw
= 1;
501 vmesa
->renderIndex
= ~0;
502 vmesa
->dirty
= VIA_UPLOAD_ALL
;
503 vmesa
->uploadCliprects
= GL_TRUE
;
504 vmesa
->needUploadAllState
= 1;
506 make_empty_list(&vmesa
->TexObjList
);
507 make_empty_list(&vmesa
->SwappedOut
);
509 vmesa
->CurrentTexObj
[0] = 0;
510 vmesa
->CurrentTexObj
[1] = 0;
512 vmesa
->dma
[0].size
= DMA_SIZE
* 1024 * 1024;
513 vmesa
->dma
[1].size
= DMA_SIZE
* 1024 * 1024;
515 _math_matrix_ctr(&vmesa
->ViewportMatrix
);
517 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
518 viaInitStateFuncs(ctx
);
519 viaInitTextures(ctx
);
520 viaInitTriFuncs(ctx
);
521 viaInitSpanFuncs(ctx
);
522 viaInitIoctlFuncs(ctx
);
526 if (getenv("VIA_DEBUG"))
531 if (getenv("DRAW_FRONT"))
536 #ifdef PERFORMANCE_MEASURE
537 if (getenv("VIA_PERFORMANCE"))
544 for (i
= 0; i
< HASH_TABLE_SIZE
; i
++) {
545 for (j
= 0; j
< HASH_TABLE_DEPTH
; j
++) {
546 hash_table
[i
][j
].count
= 0;
547 sprintf(hash_table
[i
][j
].func
, "%s", "NULL");
553 if (!AllocateDmaBuffer(mesaVis
, vmesa
)) {
554 fprintf(stderr
,"AllocateDmaBuffer fail\n");
559 InitVertexBuffer(vmesa
);
561 vmesa
->regMMIOBase
= (GLuint
*)((GLuint
)viaScreen
->reg
);
562 vmesa
->pnGEMode
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x4);
563 vmesa
->regEngineStatus
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x400);
564 vmesa
->regTranSet
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x43C);
565 vmesa
->regTranSpace
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x440);
566 vmesa
->agpBase
= viaScreen
->agpBase
;
569 fprintf(stderr
, "regEngineStatus = %x\n", *vmesa
->regEngineStatus
);
572 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
576 int count
= 0, fbSize
;
580 saam
= XineramaIsActive(vmesa
->display
);
581 if (saam
&& vmesa
->viaScreen
->drixinerama
) {
582 vmesa
->xsi
= XineramaQueryScreens(vmesa
->display
, &count
);
583 /* Test RightOf or Down */
584 if (vmesa
->xsi
[0].x_org
== 0 && vmesa
->xsi
[0].y_org
== 0) {
585 if (vmesa
->xsi
[1].x_org
== vmesa
->xsi
[1].width
) {
586 vmesa
->saam
= RightOf
;
592 /* Test LeftOf or Up */
593 else if (vmesa
->xsi
[0].x_org
== vmesa
->xsi
[0].width
) {
594 vmesa
->saam
= LeftOf
;
596 else if (vmesa
->xsi
[0].y_org
== vmesa
->xsi
[0].height
) {
603 fbSize
= vmesa
->viaScreen
->fbSize
;
610 vmesa
->pSaamRects
= (drm_clip_rect_t
*) malloc(sizeof(drm_clip_rect_t
));
615 viaDestroyContext(__DRIcontextPrivate
*driContextPriv
)
617 viaContextPtr vmesa
= (viaContextPtr
)driContextPriv
->driverPrivate
;
618 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
619 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
620 viaScreenPrivate
*viaScreen
= (viaScreenPrivate
*)sPriv
->private;
622 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
624 assert(vmesa
); /* should never be null */
625 viaFlushPrimsLocked(vmesa
);
627 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
629 if (viaScreen
->VQEnable
) {
630 *vmesa
->regTranSet
= 0x00fe0000;
631 *vmesa
->regTranSet
= 0x00fe0000;
632 *vmesa
->regTranSpace
= 0x00000006;
633 *vmesa
->regTranSpace
= 0x40008c0f;
634 *vmesa
->regTranSpace
= 0x44000000;
635 *vmesa
->regTranSpace
= 0x45080c04;
636 *vmesa
->regTranSpace
= 0x46800408;
639 /*=* John Sheng [2003.5.31] flip *=*/
640 if(vmesa
->doPageFlip
) {
641 *((volatile GLuint
*)((GLuint
)vmesa
->regMMIOBase
+ 0x43c)) = 0x00fe0000;
642 *((volatile GLuint
*)((GLuint
)vmesa
->regMMIOBase
+ 0x440)) = 0x00001004;
644 *((volatile GLuint
*)((GLuint
)vmesa
->regMMIOBase
+ 0x214)) = 0;
646 /*=* John Sheng [2003.5.31] agp tex *=*/
647 if(VIA_DEBUG
) fprintf(stderr
, "agpFullCount = %d\n", agpFullCount
);
649 _swsetup_DestroyContext(vmesa
->glCtx
);
650 _tnl_DestroyContext(vmesa
->glCtx
);
651 _ac_DestroyContext(vmesa
->glCtx
);
652 _swrast_DestroyContext(vmesa
->glCtx
);
653 viaFreeVB(vmesa
->glCtx
);
655 /* free the Mesa context */
656 _mesa_destroy_context(vmesa
->glCtx
);
657 vmesa
->glCtx
->DriverCtx
= NULL
;
663 #ifdef PERFORMANCE_MEASURE
664 if (VIA_PERFORMANCE
) fprintf(stderr
, "idle = %d\n", idle
);
665 if (VIA_PERFORMANCE
) fprintf(stderr
, "busy = %d\n", busy
);
668 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
672 void viaXMesaSetFrontClipRects(viaContextPtr vmesa
)
674 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
676 vmesa
->numClipRects
= dPriv
->numClipRects
;
677 vmesa
->pClipRects
= dPriv
->pClipRects
;
678 vmesa
->drawX
= dPriv
->x
;
679 vmesa
->drawY
= dPriv
->y
;
680 vmesa
->drawW
= dPriv
->w
;
681 vmesa
->drawH
= dPriv
->h
;
683 viaEmitDrawingRectangle(vmesa
);
684 vmesa
->uploadCliprects
= GL_TRUE
;
687 void viaXMesaSetBackClipRects(viaContextPtr vmesa
)
689 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
690 /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
691 /*if (vmesa->saam) {*/
692 vmesa
->numClipRects
= dPriv
->numClipRects
;
693 vmesa
->pClipRects
= dPriv
->pClipRects
;
694 vmesa
->drawX
= dPriv
->x
;
695 vmesa
->drawY
= dPriv
->y
;
696 vmesa
->drawW
= dPriv
->w
;
697 vmesa
->drawH
= dPriv
->h
;
700 if (dPriv->numBackClipRects == 0) {
701 vmesa->numClipRects = dPriv->numClipRects;
702 vmesa->pClipRects = dPriv->pClipRects;
703 vmesa->drawX = dPriv->x;
704 vmesa->drawY = dPriv->y;
705 vmesa->drawW = dPriv->w;
706 vmesa->drawH = dPriv->h;
709 vmesa->numClipRects = dPriv->numBackClipRects;
710 vmesa->pClipRects = dPriv->pBackClipRects;
711 vmesa->drawX = dPriv->backX;
712 vmesa->drawY = dPriv->backY;
713 vmesa->drawW = dPriv->w;
714 vmesa->drawH = dPriv->h;
717 viaEmitDrawingRectangle(vmesa
);
718 vmesa
->uploadCliprects
= GL_TRUE
;
721 void viaXMesaWindowMoved(viaContextPtr vmesa
)
723 GLuint bytePerPixel
= vmesa
->viaScreen
->bitsPerPixel
>> 3;
725 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
727 switch (vmesa
->glCtx
->Color
._DrawDestMask
) {
728 case __GL_FRONT_BUFFER_MASK
:
729 viaXMesaSetFrontClipRects(vmesa
);
731 case __GL_BACK_BUFFER_MASK
:
732 viaXMesaSetBackClipRects(vmesa
);
739 vmesa
->viaScreen
->fbOffset
= 0;
743 side
= vmesa
->saam
& P_MASK
;
747 /* full in screen 1 */
748 if (vmesa
->drawX
>= vmesa
->xsi
[0].width
) {
749 vmesa
->viaScreen
->fbOffset
= vmesa
->viaScreen
->fbSize
;
750 vmesa
->drawX
= vmesa
->drawX
- vmesa
->xsi
[1].width
;
751 vmesa
->numClipRects
= dPriv
->numBackClipRects
;
752 vmesa
->pClipRects
= dPriv
->pBackClipRects
;
753 vmesa
->drawX
= dPriv
->backX
;
754 vmesa
->drawY
= dPriv
->backY
;
758 /* full in screen 0 */
759 else if ((vmesa
->drawX
+ vmesa
->drawW
) <= vmesa
->xsi
[0].width
) {
760 vmesa
->viaScreen
->fbOffset
= 0;
764 /* between screen 0 && screen 1 */
766 vmesa
->numSaamRects
= dPriv
->numBackClipRects
;
767 vmesa
->pSaamRects
= dPriv
->pBackClipRects
;
768 vmesa
->drawXSaam
= dPriv
->backX
;
769 vmesa
->drawYSaam
= dPriv
->backY
;
770 vmesa
->viaScreen
->fbOffset
= 0;
776 /* full in screen 1 */
777 if (vmesa
->drawX
+ vmesa
->drawW
<= 0) {
778 vmesa
->viaScreen
->fbOffset
= vmesa
->viaScreen
->fbSize
;
779 vmesa
->drawX
= vmesa
->drawX
+ vmesa
->xsi
[1].width
;
780 vmesa
->numClipRects
= dPriv
->numBackClipRects
;
781 vmesa
->pClipRects
= dPriv
->pBackClipRects
;
782 vmesa
->drawX
= dPriv
->backX
;
783 vmesa
->drawY
= dPriv
->backY
;
787 /* full in screen 0 */
788 else if (vmesa
->drawX
>= 0) {
789 vmesa
->viaScreen
->fbOffset
= 0;
793 /* between screen 0 && screen 1 */
795 vmesa
->numSaamRects
= dPriv
->numBackClipRects
;
796 vmesa
->pSaamRects
= dPriv
->pBackClipRects
;
797 vmesa
->drawXSaam
= dPriv
->backX
;
798 vmesa
->drawYSaam
= dPriv
->backY
;
799 vmesa
->viaScreen
->fbOffset
= 0;
805 /* full in screen 1 */
806 if (vmesa
->drawY
>= vmesa
->xsi
[0].height
) {
807 vmesa
->viaScreen
->fbOffset
= vmesa
->viaScreen
->fbSize
;
808 vmesa
->drawY
= vmesa
->drawY
- vmesa
->xsi
[1].height
;
809 vmesa
->numClipRects
= dPriv
->numBackClipRects
;
810 vmesa
->pClipRects
= dPriv
->pBackClipRects
;
811 vmesa
->drawX
= dPriv
->backX
;
812 vmesa
->drawY
= dPriv
->backY
;
816 /* full in screen 0 */
817 else if ((vmesa
->drawY
+ vmesa
->drawH
) <= vmesa
->xsi
[0].height
) {
818 vmesa
->viaScreen
->fbOffset
= 0;
822 /* between screen 0 && screen 1 */
824 vmesa
->numSaamRects
= dPriv
->numBackClipRects
;
825 vmesa
->pSaamRects
= dPriv
->pBackClipRects
;
826 vmesa
->drawXSaam
= dPriv
->backX
;
827 vmesa
->drawYSaam
= dPriv
->backY
;
828 vmesa
->viaScreen
->fbOffset
= 0;
834 /* full in screen 1 */
835 if ((vmesa
->drawY
+ vmesa
->drawH
) <= 0) {
836 vmesa
->viaScreen
->fbOffset
= vmesa
->viaScreen
->fbSize
;
837 vmesa
->drawY
= vmesa
->drawY
+ vmesa
->xsi
[1].height
;
838 vmesa
->numClipRects
= dPriv
->numBackClipRects
;
839 vmesa
->pClipRects
= dPriv
->pBackClipRects
;
840 vmesa
->drawX
= dPriv
->backX
;
841 vmesa
->drawY
= dPriv
->backY
;
845 /* full in screen 0 */
846 else if (vmesa
->drawY
>= 0) {
847 vmesa
->viaScreen
->fbOffset
= 0;
851 /* between screen 0 && screen 1 */
853 vmesa
->numSaamRects
= dPriv
->numBackClipRects
;
854 vmesa
->pSaamRects
= dPriv
->pBackClipRects
;
855 vmesa
->drawXSaam
= dPriv
->backX
;
856 vmesa
->drawYSaam
= dPriv
->backY
;
857 vmesa
->viaScreen
->fbOffset
= 0;
863 vmesa
->viaScreen
->fbOffset
= 0;
868 GLuint pitch
, offset
;
869 pitch
= vmesa
->front
.pitch
;
870 offset
= vmesa
->viaScreen
->fbOffset
+ (vmesa
->drawY
* pitch
+ vmesa
->drawX
* bytePerPixel
);
871 vmesa
->drawXoff
= (GLuint
)((offset
& 0x1f) / bytePerPixel
);
873 if (vmesa
->pSaamRects
) {
874 offset
= vmesa
->viaScreen
->fbOffset
+ (vmesa
->pSaamRects
[0].y1
* pitch
+
875 vmesa
->pSaamRects
[0].x1
* bytePerPixel
);
876 vmesa
->drawXoffSaam
= (GLuint
)((offset
& 0x1f) / bytePerPixel
);
879 vmesa
->drawXoffSaam
= 0;
882 vmesa
->drawXoffSaam
= 0;
885 vmesa
->glCtx
->Driver
.Viewport(vmesa
->glCtx
,0 ,0 ,0 ,0);
889 viaUnbindContext(__DRIcontextPrivate
*driContextPriv
)
892 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
893 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
899 viaMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
900 __DRIdrawablePrivate
*driDrawPriv
,
901 __DRIdrawablePrivate
*driReadPriv
)
904 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
907 fprintf(stderr
, "driContextPriv = %08x\n", (GLuint
)driContextPriv
);
908 fprintf(stderr
, "driContextPriv = %08x\n", (GLuint
)driDrawPriv
);
909 fprintf(stderr
, "driContextPriv = %08x\n", (GLuint
)driReadPriv
);
913 if (driContextPriv
) {
914 viaContextPtr vmesa
= (viaContextPtr
)driContextPriv
->driverPrivate
;
915 current_mesa
= vmesa
;
917 vmesa
->driDrawable
= driDrawPriv
;
918 if (vmesa
->drawType
== GLX_PBUFFER_BIT
) {
921 w
= vmesa
->driDrawable
->w
;
922 h
= vmesa
->driDrawable
->h
;
923 bpp
= vmesa
->viaScreen
->bitsPerPixel
;
925 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
926 vmesa
->front
.size
= w
* h
* bpp
/ 8;
927 vmesa
->front
.pitch
= w
<< 2;
930 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2;
931 vmesa
->front
.size
= w
* h
* bpp
/ 8;
932 vmesa
->front
.pitch
= w
<< 1;
935 /*=* John Sheng [2003.6.20] fix resolution 720x480/720x576 front pitch error *=*/
940 bpp
= vmesa
->viaScreen
->bitsPerPixel
;
941 h
= vmesa
->viaScreen
->height
;
942 w
= vmesa
->viaScreen
->width
;
944 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
945 vmesa
->front
.size
= w
* h
* bpp
/ 8;
946 vmesa
->front
.pitch
= w
<< 2;
948 if (VIA_DEBUG
) fprintf(stderr
, "viaScreen->bitsPerPixel = %d\n", 32);
951 else if (bpp
== 0x10) {
952 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2;
953 vmesa
->front
.size
= w
* h
* bpp
/ 8;
954 vmesa
->front
.pitch
= w
<< 1;
956 if (VIA_DEBUG
) fprintf(stderr
, "viaScreen->bitsPerPixel = %d\n", 16);
959 vmesa
->front
.offset
= 0;
960 vmesa
->front
.map
= (char *) vmesa
->driScreen
->pFB
;
961 vmesa
->front
.size
= w
* h
* vmesa
->viaScreen
->bitsPerPixel
/8;
964 /* Allocate back & depth buffer */
968 w
= vmesa
->driDrawable
->w
;
970 if (VIA_DEBUG
) fprintf(stderr
, "viaMakeCurrent: w = %d\n", w
);
972 h
= vmesa
->driDrawable
->h
;
975 bpp
= vmesa
->viaScreen
->bitsPerPixel
;
977 if (VIA_DEBUG
) fprintf(stderr
, "driScreen->fbBPP = %d\n", bpp
);
980 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
981 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
983 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
985 vmesa
->back
.size
= w
* h
* bpp
/ 8;
986 vmesa
->back
.pitch
= w
<< 2;
989 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
990 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2;
992 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2 + 16;
994 vmesa
->back
.size
= w
* h
* bpp
/ 8;
995 vmesa
->back
.pitch
= w
<< 1;
998 if (VIA_DEBUG
) fprintf(stderr
, "viaMakeCurrent backbuffer: w = %d h = %d bpp = %d sizs = %d\n",
999 w
, h
, bpp
, vmesa
->back
.size
);
1002 w
= vmesa
->driDrawable
->w
;
1004 if (vmesa
->hasDepth
&& vmesa
->hasStencil
) {
1005 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
1006 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
1008 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
1010 vmesa
->depth
.size
= w
* h
* 4;
1011 vmesa
->depth
.pitch
= w
<< 2;
1012 vmesa
->depth
.bpp
= 32;
1014 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 24\n");
1015 if (VIA_DEBUG
) fprintf(stderr
, "StencilBits = 8\n");
1018 else if (vmesa
->hasDepth
) {
1020 /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */
1021 /*if(vmesa->viaScreen->bitsPerPixel == 32)*/
1022 /*vmesa->depthBits = 16;*/
1024 if (vmesa
->depthBits
== 16) {
1025 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
1026 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2;
1028 w
= BUFFER_ALIGN_WIDTH(w
* 2, BUFFER_ALIGNMENT
) / 2 + 16;
1030 vmesa
->depth
.size
= w
* h
* 2;
1031 vmesa
->depth
.pitch
= w
<< 1;
1032 vmesa
->depth
.bpp
= 16;
1034 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 16\n");
1038 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
1039 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
1041 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
1043 vmesa
->depth
.size
= w
* h
* 4;
1044 vmesa
->depth
.pitch
= w
<< 2;
1045 vmesa
->depth
.bpp
= 32;
1047 if (VIA_DEBUG
) fprintf(stderr
, "depthBits = 32\n");
1051 else if (vmesa
->hasStencil
) {
1052 if (vmesa
->drawType
== GLX_PBUFFER_BIT
)
1053 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4;
1055 w
= BUFFER_ALIGN_WIDTH(w
* 4, BUFFER_ALIGNMENT
) / 4 + 8;
1057 vmesa
->depth
.size
= w
* h
* 4;
1058 vmesa
->depth
.pitch
= w
<< 2;
1059 vmesa
->depth
.bpp
= 32;
1061 if (VIA_DEBUG
) fprintf(stderr
, "StencilBits = 8\n");
1065 if (VIA_DEBUG
) fprintf(stderr
, "viaMakeCurrent depthbuffer: w = %d h = %d bpp = %d sizs = %d\n",
1066 w
, h
, vmesa
->depth
.bpp
, vmesa
->depth
.size
);
1068 /*=* John Sheng [2003.5.31] flip *=*/
1070 viaContextPtr vmesa
= (viaContextPtr
)driContextPriv
->driverPrivate
;
1071 if(vmesa
->viaScreen
->width
== vmesa
->driDrawable
->w
&&
1072 vmesa
->viaScreen
->height
== vmesa
->driDrawable
->h
) {
1073 vmesa
->doPageFlip
= GL_FALSE
;
1074 vmesa
->currentPage
= 0;
1075 vmesa
->back
.pitch
= vmesa
->front
.pitch
;
1079 if (!AllocateBuffer(vmesa
)) {
1084 _mesa_make_current2(vmesa
->glCtx
,
1085 (GLframebuffer
*)driDrawPriv
->driverPrivate
,
1086 (GLframebuffer
*)driReadPriv
->driverPrivate
);
1088 if (VIA_DEBUG
) fprintf(stderr
, "Context %d MakeCurrent\n", vmesa
->hHWContext
);
1090 viaXMesaWindowMoved(vmesa
);
1091 if (!vmesa
->glCtx
->Viewport
.Width
)
1092 _mesa_set_viewport(vmesa
->glCtx
, 0, 0,
1093 driDrawPriv
->w
, driDrawPriv
->h
);
1096 _mesa_make_current(0,0);
1100 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
1105 void viaGetLock(viaContextPtr vmesa
, GLuint flags
)
1107 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
1108 __DRIscreenPrivate
*sPriv
= vmesa
->driScreen
;
1109 drm_via_sarea_t
*sarea
= vmesa
->sarea
;
1110 int me
= vmesa
->hHWContext
;
1111 __DRIdrawablePrivate
*pdp
;
1112 __DRIscreenPrivate
*psp
;
1116 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
1117 if (VIA_DEBUG
) fprintf(stderr
, "drmGetLock - in\n");
1119 drmGetLock(vmesa
->driFd
, vmesa
->hHWContext
, flags
);
1122 DRM_UNLOCK(psp
->fd
, &psp
->pSAREA
->lock
,
1123 pdp
->driContextPriv
->hHWContext
);
1124 DRM_SPINLOCK(&psp
->pSAREA
->drawable_lock
, psp
->drawLockID
);
1125 __driUtilUpdateDrawableInfo(dPriv
);
1126 DRM_SPINUNLOCK(&psp
->pSAREA
->drawable_lock
, psp
->drawLockID
);
1127 DRM_LIGHT_LOCK(psp
->fd
, &psp
->pSAREA
->lock
,
1128 pdp
->driContextPriv
->hHWContext
);
1131 if (sarea
->ctxOwner
!= me
) {
1132 vmesa
->uploadCliprects
= GL_TRUE
;
1133 sarea
->ctxOwner
= me
;
1136 viaXMesaWindowMoved(vmesa
);
1138 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
1142 void viaLock(viaContextPtr vmesa
, GLuint flags
)
1144 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
1145 __DRIscreenPrivate
*sPriv
= vmesa
->driScreen
;
1147 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
1149 /*=* John Sheng [2003.6.16] for xf43 */
1150 if(dPriv
->pStamp
== NULL
)
1151 dPriv
->pStamp
= &dPriv
->lastStamp
;
1153 if (*(dPriv
->pStamp
) != dPriv
->lastStamp
|| vmesa
->saam
) {
1155 scrn
= vmesa
->saam
& S_MASK
;
1157 DRM_SPINLOCK(&sPriv
->pSAREA
->drawable_lock
, sPriv
->drawLockID
);
1160 __driUtilUpdateDrawableInfo(dPriv
);
1162 DRI_VALIDATE_DRAWABLE_INFO_ONCE(dPriv
);
1164 viaXMesaWindowMoved(vmesa
);
1165 DRM_SPINUNLOCK(&sPriv
->pSAREA
->drawable_lock
, sPriv
->drawLockID
);
1168 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
1173 void viaUnLock(viaContextPtr vmesa
, GLuint flags
)
1175 drm_via_sarea_t
*sarea
= vmesa
->sarea
;
1176 int me
= vmesa
->hHWContext
;
1179 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
1180 if (VIA_DEBUG
) fprintf(stderr
, "sarea->ctxOwner = %d\n", sarea
->ctxOwner
);
1181 if (VIA_DEBUG
) fprintf(stderr
, "me = %d\n", me
);
1183 if (sarea
->ctxOwner
== me
) {
1184 sarea
->ctxOwner
= 0;
1187 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
1192 viaSwapBuffers(__DRIdrawablePrivate
*drawablePrivate
)
1194 __DRIdrawablePrivate
*dPriv
= (__DRIdrawablePrivate
*)drawablePrivate
;
1196 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
1198 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
1199 viaContextPtr vmesa
;
1202 vmesa
= (viaContextPtr
)dPriv
->driContextPriv
->driverPrivate
;
1204 if (ctx
->Visual
.doubleBufferMode
) {
1205 _mesa_notifySwapBuffers(ctx
);
1206 if (vmesa
->doPageFlip
) {
1210 viaCopyBuffer(dPriv
);
1214 VIA_FIREVERTICES(vmesa
);
1217 _mesa_problem(NULL
, "viaSwapBuffers: drawable has no context!\n");
1220 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);