/* * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "glheader.h" #include "context.h" #include "matrix.h" #include "simple_list.h" #include "extensions.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" #include "array_cache/acache.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" #include "via_screen.h" #include "via_dri.h" #include "via_state.h" #include "via_tex.h" #include "via_span.h" #include "via_tris.h" #include "via_vb.h" #include "via_ioctl.h" #include "via_fb.h" #ifndef _SOLO #include #endif #include #include "macros.h" viaContextPtr current_mesa; GLuint VIA_DEBUG = 0; GLuint DRAW_FRONT = 0; #define DMA_SIZE 2 GLuint VIA_PERFORMANCE = 0; #ifdef PERFORMANCE_MEASURE GLuint busy = 0; GLuint idle = 0; hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH]; #endif /*=* John Sheng [2003.5.31] agp tex *=*/ extern GLuint agpFullCount; static GLboolean AllocateBuffer(viaContextPtr vmesa) { vmesa->front_base = vmesa->driScreen->pFB; if (vmesa->drawType == GLX_PBUFFER_BIT) { if (vmesa->front.map) via_free_front_buffer(vmesa); if (!via_alloc_front_buffer(vmesa)) return GL_FALSE; } if (vmesa->hasBack) { if (vmesa->back.map) via_free_back_buffer(vmesa); if (!via_alloc_back_buffer(vmesa)) return GL_FALSE; } if (vmesa->hasDepth || vmesa->hasStencil) { if (vmesa->depth.map) via_free_depth_buffer(vmesa); if (!via_alloc_depth_buffer(vmesa)) { via_free_depth_buffer(vmesa); return GL_FALSE; } } return GL_TRUE; } static const GLubyte *viaGetString(GLcontext *ctx, GLenum name) { switch (name) { case GL_VENDOR: return (GLubyte *)"VIA Technology"; case GL_RENDERER: return (GLubyte *)"Mesa DRI VIA CLE266 20020221"; default: return 0; } } void viaReAllocateBuffers(GLframebuffer *drawbuffer) { GLcontext *ctx; viaContextPtr vmesa = current_mesa; ctx = vmesa->glCtx; ctx->DrawBuffer->Width = drawbuffer->Width; ctx->DrawBuffer->Height = drawbuffer->Height; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); #endif ctx->DrawBuffer->Accum = 0; vmesa->driDrawable->w = ctx->DrawBuffer->Width; vmesa->driDrawable->h = ctx->DrawBuffer->Height; LOCK_HARDWARE(vmesa); /* Allocate back & depth buffer */ { int w, h, bpp; w = vmesa->driDrawable->w; h = vmesa->driDrawable->h; /* back buffer */ bpp = vmesa->viaScreen->bitsPerPixel; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp); #endif if (bpp == 32) { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->back.size = w * h * bpp / 8; vmesa->back.pitch = w << 2; } else { w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16; vmesa->back.size = w * h * bpp / 8; vmesa->back.pitch = w << 1; } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "resizebuffer backbuffer: w = %d h = %d bpp = %d sizs = %d\n", w, h, bpp, vmesa->back.size); #endif /* depth buffer */ w = vmesa->driDrawable->w; if (vmesa->hasDepth && vmesa->hasStencil) { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n"); if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n"); #endif } else if (vmesa->hasDepth) { /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */ /*if(vmesa->viaScreen->bitsPerPixel == 32)*/ /*vmesa->depthBits = 16;*/ if (vmesa->depthBits == 16) { w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16; vmesa->depth.size = w * h * 2; vmesa->depth.pitch = w << 1; vmesa->depth.bpp = 16; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n"); #endif } else { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n"); #endif } } else if (vmesa->hasStencil) { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n"); #endif } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "resizebuffer depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", w, h, vmesa->depth.bpp, vmesa->depth.size); #endif /*=* John Sheng [2003.5.31] flip *=*/ { if(vmesa->viaScreen->width == vmesa->driDrawable->w && vmesa->viaScreen->height == vmesa->driDrawable->h) { vmesa->back.pitch = vmesa->front.pitch; vmesa->back.size = vmesa->front.size; } } if (!AllocateBuffer(vmesa)) { FREE(vmesa); } } UNLOCK_HARDWARE(vmesa); #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif } static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) { /* MESA5.0 */ viaContextPtr vmesa = current_mesa; *width = vmesa->driDrawable->w; *height = vmesa->driDrawable->h; } static void viaInitExtensions(GLcontext *ctx) { _mesa_enable_imaging_extensions(ctx); _mesa_enable_extension(ctx, "GL_ARB_multitexture"); _mesa_enable_extension(ctx, "GL_ARB_texture_env_add"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap"); _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias"); /*=* John Sheng [2003.7.18] texture combine *=*/ _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine"); /*=* John Sheng [2003.7.18] texture dot3 *=*/ _mesa_enable_extension(ctx, "GL_ARB_texture_env_dot3"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_dot3"); /*=* John Sheng [2003.7.18] point parameters */ _mesa_enable_extension(ctx, "GL_ARB_point_parameters"); _mesa_enable_extension(ctx, "GL_EXT_point_parameters"); } extern const struct tnl_pipeline_stage _via_fastrender_stage; extern const struct tnl_pipeline_stage _via_render_stage; static const struct tnl_pipeline_stage *via_pipeline[] = { &_tnl_vertex_transform_stage, &_tnl_normal_transform_stage, &_tnl_lighting_stage, &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, /* REMOVE: point attenuation stage */ #if 1 &_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */ &_via_render_stage, /* ADD: modification from _tnl_render_stage */ #endif &_tnl_render_stage, 0, }; static GLboolean AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa) { #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); #endif if (vmesa->dma[0].map && vmesa->dma[1].map) via_free_dma_buffer(vmesa); if (!via_alloc_dma_buffer(vmesa)) { if (vmesa->front.map) via_free_front_buffer(vmesa); if (vmesa->back.map) via_free_back_buffer(vmesa); if (vmesa->depth.map) via_free_depth_buffer(vmesa); return GL_FALSE; } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif return GL_TRUE; } static void InitVertexBuffer(viaContextPtr vmesa) { GLuint *addr; addr = (GLuint *)vmesa->dma[0].map; *addr = 0xF210F110; *addr = (HC_ParaType_NotTex << 16); *addr = 0xcccccccc; *addr = 0xdddddddd; addr = (GLuint *)vmesa->dma[1].map; *addr = 0xF210F110; *addr = (HC_ParaType_NotTex << 16); *addr = 0xcccccccc; *addr = 0xdddddddd; vmesa->dmaIndex = 0; vmesa->dmaLow = DMA_OFFSET; vmesa->dmaHigh = vmesa->dma[0].size; vmesa->dmaAddr = (unsigned char *)vmesa->dma[0].map; vmesa->dmaLastPrim = vmesa->dmaLow; } static void FreeBuffer(viaContextPtr vmesa) { if (vmesa->front.map) via_free_front_buffer(vmesa); if (vmesa->back.map) via_free_back_buffer(vmesa); if (vmesa->depth.map) via_free_depth_buffer(vmesa); if (vmesa->dma[0].map && vmesa->dma[1].map) via_free_dma_buffer(vmesa); } GLboolean viaCreateContext(const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate) { GLcontext *ctx, *shareCtx; viaContextPtr vmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private; drm_via_sarea_t *saPriv = (drm_via_sarea_t *) (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset); struct dd_function_table functions; /* Allocate via context */ vmesa = (viaContextPtr) CALLOC_STRUCT(via_context_t); if (!vmesa) { return GL_FALSE; } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); #endif current_mesa = vmesa; /* pick back buffer */ if (mesaVis->doubleBufferMode) { vmesa->hasBack = GL_TRUE; } else { vmesa->hasBack = GL_FALSE; } /* pick z buffer */ if (mesaVis->haveDepthBuffer) { vmesa->hasDepth = GL_TRUE; vmesa->depthBits = mesaVis->depthBits; } else { vmesa->hasDepth = GL_FALSE; vmesa->depthBits = 0; } /* pick stencil buffer */ if (mesaVis->haveStencilBuffer) { vmesa->hasStencil = GL_TRUE; vmesa->stencilBits = mesaVis->stencilBits; } else { vmesa->hasStencil = GL_FALSE; vmesa->stencilBits = 0; } _mesa_init_driver_functions(&functions); viaInitTextureFuncs(&functions); /* Allocate the Mesa context */ if (sharedContextPrivate) shareCtx = ((viaContextPtr) sharedContextPrivate)->glCtx; else shareCtx = NULL; vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions, (void*) vmesa); vmesa->shareCtx = shareCtx; if (!vmesa->glCtx) { FREE(vmesa); return GL_FALSE; } driContextPriv->driverPrivate = vmesa; ctx = vmesa->glCtx; /* check */ /*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/ /*if (viaScreen->textureSize < 2 * 1024 * 1024) { ctx->Const.MaxTextureLevels = 9; } else if (viaScreen->textureSize < 8 * 1024 * 1024) { ctx->Const.MaxTextureLevels = 10; } else { ctx->Const.MaxTextureLevels = 11; }*/ ctx->Const.MaxTextureLevels = 11; ctx->Const.MaxTextureUnits = 2; ctx->Const.MinLineWidth = 1.0; ctx->Const.MinLineWidthAA = 1.0; ctx->Const.MaxLineWidth = 3.0; ctx->Const.MaxLineWidthAA = 3.0; ctx->Const.LineWidthGranularity = 1.0; ctx->Const.MinPointSize = 1.0; ctx->Const.MinPointSizeAA = 1.0; ctx->Const.MaxPointSize = 3.0; ctx->Const.MaxPointSizeAA = 3.0; ctx->Const.PointSizeGranularity = 1.0; ctx->Driver.GetBufferSize = viaBufferSize; /* ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; *//* FIXME ?? */ ctx->Driver.GetString = viaGetString; ctx->DriverCtx = (void *)vmesa; vmesa->glCtx = ctx; /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); _ac_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); /* Install the customized pipeline: */ _tnl_destroy_pipeline(ctx); _tnl_install_pipeline(ctx, via_pipeline); /* Configure swrast and T&L to match hardware characteristics: */ _swrast_allow_pixel_fog(ctx, GL_FALSE); _swrast_allow_vertex_fog(ctx, GL_TRUE); _tnl_allow_pixel_fog(ctx, GL_FALSE); _tnl_allow_vertex_fog(ctx, GL_TRUE); #ifndef _SOLO /* vmesa->display = dpy; */ vmesa->display = sPriv->display; #endif vmesa->hHWContext = driContextPriv->hHWContext; vmesa->driFd = sPriv->fd; vmesa->driHwLock = &sPriv->pSAREA->lock; vmesa->viaScreen = viaScreen; vmesa->driScreen = sPriv; vmesa->sarea = saPriv; vmesa->glBuffer = NULL; vmesa->texHeap = mmInit(0, viaScreen->textureSize); vmesa->stippleInHw = 1; vmesa->renderIndex = ~0; vmesa->dirty = VIA_UPLOAD_ALL; vmesa->uploadCliprects = GL_TRUE; vmesa->needUploadAllState = 1; make_empty_list(&vmesa->TexObjList); make_empty_list(&vmesa->SwappedOut); vmesa->CurrentTexObj[0] = 0; vmesa->CurrentTexObj[1] = 0; vmesa->dma[0].size = DMA_SIZE * 1024 * 1024; vmesa->dma[1].size = DMA_SIZE * 1024 * 1024; _math_matrix_ctr(&vmesa->ViewportMatrix); viaInitExtensions(ctx); viaInitStateFuncs(ctx); viaInitTextures(ctx); viaInitTriFuncs(ctx); viaInitSpanFuncs(ctx); viaInitIoctlFuncs(ctx); viaInitVB(ctx); viaInitState(ctx); if (getenv("VIA_DEBUG")) VIA_DEBUG = 1; else VIA_DEBUG = 0; if (getenv("DRAW_FRONT")) DRAW_FRONT = 1; else DRAW_FRONT = 0; #ifdef PERFORMANCE_MEASURE if (getenv("VIA_PERFORMANCE")) VIA_PERFORMANCE = 1; else VIA_PERFORMANCE = 0; { int i, j; for (i = 0; i < HASH_TABLE_SIZE; i++) { for (j = 0; j < HASH_TABLE_DEPTH; j ++) { hash_table[i][j].count = 0; sprintf(hash_table[i][j].func, "%s", "NULL"); } } } #endif if (!AllocateDmaBuffer(mesaVis, vmesa)) { fprintf(stderr ,"AllocateDmaBuffer fail\n"); FREE(vmesa); return GL_FALSE; } InitVertexBuffer(vmesa); vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg); vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4); vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400); vmesa->regTranSet = (GLuint *)((GLuint)viaScreen->reg + 0x43C); vmesa->regTranSpace = (GLuint *)((GLuint)viaScreen->reg + 0x440); vmesa->agpBase = viaScreen->agpBase; #ifdef DEBUG if (VIA_DEBUG) { fprintf(stderr, "regEngineStatus = %x\n", *vmesa->regEngineStatus); } if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif { GLboolean saam; int count = 0, fbSize; #ifndef USE_XINERAMA vmesa->saam = 0; #else saam = XineramaIsActive(vmesa->display); if (saam && vmesa->viaScreen->drixinerama) { vmesa->xsi = XineramaQueryScreens(vmesa->display, &count); /* Test RightOf or Down */ if (vmesa->xsi[0].x_org == 0 && vmesa->xsi[0].y_org == 0) { if (vmesa->xsi[1].x_org == vmesa->xsi[1].width) { vmesa->saam = RightOf; } else { vmesa->saam = Down; } } /* Test LeftOf or Up */ else if (vmesa->xsi[0].x_org == vmesa->xsi[0].width) { vmesa->saam = LeftOf; } else if (vmesa->xsi[0].y_org == vmesa->xsi[0].height) { vmesa->saam = Up; } else vmesa->saam = 0; fbSize = vmesa->viaScreen->fbSize; } else vmesa->saam = 0; #endif } vmesa->pSaamRects = (drm_clip_rect_t *) malloc(sizeof(drm_clip_rect_t)); return GL_TRUE; } void viaDestroyContext(__DRIcontextPrivate *driContextPriv) { viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); #endif assert(vmesa); /* should never be null */ viaFlushPrimsLocked(vmesa); WAIT_IDLE /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/ /* Enable VQ */ if (viaScreen->VQEnable) { *vmesa->regTranSet = 0x00fe0000; *vmesa->regTranSet = 0x00fe0000; *vmesa->regTranSpace = 0x00000006; *vmesa->regTranSpace = 0x40008c0f; *vmesa->regTranSpace = 0x44000000; *vmesa->regTranSpace = 0x45080c04; *vmesa->regTranSpace = 0x46800408; } if (vmesa) { /*=* John Sheng [2003.5.31] flip *=*/ if(vmesa->doPageFlip) { *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000; *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004; WAIT_IDLE *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = 0; } /*=* John Sheng [2003.5.31] agp tex *=*/ if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", agpFullCount); _swsetup_DestroyContext(vmesa->glCtx); _tnl_DestroyContext(vmesa->glCtx); _ac_DestroyContext(vmesa->glCtx); _swrast_DestroyContext(vmesa->glCtx); viaFreeVB(vmesa->glCtx); FreeBuffer(vmesa); /* free the Mesa context */ _mesa_destroy_context(vmesa->glCtx); vmesa->glCtx->DriverCtx = NULL; FREE(vmesa); } P_M_R; #ifdef PERFORMANCE_MEASURE if (VIA_PERFORMANCE) fprintf(stderr, "idle = %d\n", idle); if (VIA_PERFORMANCE) fprintf(stderr, "busy = %d\n", busy); #endif #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif } void viaXMesaSetFrontClipRects(viaContextPtr vmesa) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; vmesa->numClipRects = dPriv->numClipRects; vmesa->pClipRects = dPriv->pClipRects; vmesa->drawX = dPriv->x; vmesa->drawY = dPriv->y; vmesa->drawW = dPriv->w; vmesa->drawH = dPriv->h; viaEmitDrawingRectangle(vmesa); vmesa->uploadCliprects = GL_TRUE; } void viaXMesaSetBackClipRects(viaContextPtr vmesa) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; /*=* John Sheng [2003.6.9] fix glxgears dirty screen */ /*if (vmesa->saam) {*/ vmesa->numClipRects = dPriv->numClipRects; vmesa->pClipRects = dPriv->pClipRects; vmesa->drawX = dPriv->x; vmesa->drawY = dPriv->y; vmesa->drawW = dPriv->w; vmesa->drawH = dPriv->h; /*} else { if (dPriv->numBackClipRects == 0) { vmesa->numClipRects = dPriv->numClipRects; vmesa->pClipRects = dPriv->pClipRects; vmesa->drawX = dPriv->x; vmesa->drawY = dPriv->y; vmesa->drawW = dPriv->w; vmesa->drawH = dPriv->h; } else { vmesa->numClipRects = dPriv->numBackClipRects; vmesa->pClipRects = dPriv->pBackClipRects; vmesa->drawX = dPriv->backX; vmesa->drawY = dPriv->backY; vmesa->drawW = dPriv->w; vmesa->drawH = dPriv->h; } }*/ viaEmitDrawingRectangle(vmesa); vmesa->uploadCliprects = GL_TRUE; } void viaXMesaWindowMoved(viaContextPtr vmesa) { GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; GLuint side = 0; __DRIdrawablePrivate *dPriv = vmesa->driDrawable; switch (vmesa->glCtx->Color._DrawDestMask) { case __GL_FRONT_BUFFER_MASK: viaXMesaSetFrontClipRects(vmesa); break; case __GL_BACK_BUFFER_MASK: viaXMesaSetBackClipRects(vmesa); break; default: break; } #ifndef USE_XINERAMA vmesa->viaScreen->fbOffset = 0; vmesa->saam &= ~S1; vmesa->saam |= S0; #else side = vmesa->saam & P_MASK; switch (side) { case RightOf: /* full in screen 1 */ if (vmesa->drawX >= vmesa->xsi[0].width) { vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize; vmesa->drawX = vmesa->drawX - vmesa->xsi[1].width; vmesa->numClipRects = dPriv->numBackClipRects; vmesa->pClipRects = dPriv->pBackClipRects; vmesa->drawX = dPriv->backX; vmesa->drawY = dPriv->backY; vmesa->saam &= ~S0; vmesa->saam |= S1; } /* full in screen 0 */ else if ((vmesa->drawX + vmesa->drawW) <= vmesa->xsi[0].width) { vmesa->viaScreen->fbOffset = 0; vmesa->saam &= ~S1; vmesa->saam |= S0; } /* between screen 0 && screen 1 */ else { vmesa->numSaamRects = dPriv->numBackClipRects; vmesa->pSaamRects = dPriv->pBackClipRects; vmesa->drawXSaam = dPriv->backX; vmesa->drawYSaam = dPriv->backY; vmesa->viaScreen->fbOffset = 0; vmesa->saam |= S0; vmesa->saam |= S1; } break; case LeftOf: /* full in screen 1 */ if (vmesa->drawX + vmesa->drawW <= 0) { vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize; vmesa->drawX = vmesa->drawX + vmesa->xsi[1].width; vmesa->numClipRects = dPriv->numBackClipRects; vmesa->pClipRects = dPriv->pBackClipRects; vmesa->drawX = dPriv->backX; vmesa->drawY = dPriv->backY; vmesa->saam &= ~S0; vmesa->saam |= S1; } /* full in screen 0 */ else if (vmesa->drawX >= 0) { vmesa->viaScreen->fbOffset = 0; vmesa->saam &= ~S1; vmesa->saam |= S0; } /* between screen 0 && screen 1 */ else { vmesa->numSaamRects = dPriv->numBackClipRects; vmesa->pSaamRects = dPriv->pBackClipRects; vmesa->drawXSaam = dPriv->backX; vmesa->drawYSaam = dPriv->backY; vmesa->viaScreen->fbOffset = 0; vmesa->saam |= S0; vmesa->saam |= S1; } break; case Down : /* full in screen 1 */ if (vmesa->drawY >= vmesa->xsi[0].height) { vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize; vmesa->drawY = vmesa->drawY - vmesa->xsi[1].height; vmesa->numClipRects = dPriv->numBackClipRects; vmesa->pClipRects = dPriv->pBackClipRects; vmesa->drawX = dPriv->backX; vmesa->drawY = dPriv->backY; vmesa->saam &= ~S0; vmesa->saam |= S1; } /* full in screen 0 */ else if ((vmesa->drawY + vmesa->drawH) <= vmesa->xsi[0].height) { vmesa->viaScreen->fbOffset = 0; vmesa->saam &= ~S1; vmesa->saam |= S0; } /* between screen 0 && screen 1 */ else { vmesa->numSaamRects = dPriv->numBackClipRects; vmesa->pSaamRects = dPriv->pBackClipRects; vmesa->drawXSaam = dPriv->backX; vmesa->drawYSaam = dPriv->backY; vmesa->viaScreen->fbOffset = 0; vmesa->saam |= S0; vmesa->saam |= S1; } break; case Up : /* full in screen 1 */ if ((vmesa->drawY + vmesa->drawH) <= 0) { vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize; vmesa->drawY = vmesa->drawY + vmesa->xsi[1].height; vmesa->numClipRects = dPriv->numBackClipRects; vmesa->pClipRects = dPriv->pBackClipRects; vmesa->drawX = dPriv->backX; vmesa->drawY = dPriv->backY; vmesa->saam &= ~S0; vmesa->saam |= S1; } /* full in screen 0 */ else if (vmesa->drawY >= 0) { vmesa->viaScreen->fbOffset = 0; vmesa->saam &= ~S1; vmesa->saam |= S0; } /* between screen 0 && screen 1 */ else { vmesa->numSaamRects = dPriv->numBackClipRects; vmesa->pSaamRects = dPriv->pBackClipRects; vmesa->drawXSaam = dPriv->backX; vmesa->drawYSaam = dPriv->backY; vmesa->viaScreen->fbOffset = 0; vmesa->saam |= S0; vmesa->saam |= S1; } break; default: vmesa->viaScreen->fbOffset = 0; } #endif { GLuint pitch, offset; pitch = vmesa->front.pitch; offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel); vmesa->drawXoff = (GLuint)((offset & 0x1f) / bytePerPixel); if (vmesa->saam) { if (vmesa->pSaamRects) { offset = vmesa->viaScreen->fbOffset + (vmesa->pSaamRects[0].y1 * pitch + vmesa->pSaamRects[0].x1 * bytePerPixel); vmesa->drawXoffSaam = (GLuint)((offset & 0x1f) / bytePerPixel); } else vmesa->drawXoffSaam = 0; } else vmesa->drawXoffSaam = 0; } vmesa->glCtx->Driver.Viewport(vmesa->glCtx,0 ,0 ,0 ,0); } GLboolean viaUnbindContext(__DRIcontextPrivate *driContextPriv) { #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif return GL_TRUE; } GLboolean viaMakeCurrent(__DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driDrawPriv, __DRIdrawablePrivate *driReadPriv) { #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); if (VIA_DEBUG) { fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv); fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driDrawPriv); fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driReadPriv); } #endif if (driContextPriv) { viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; current_mesa = vmesa; vmesa->driDrawable = driDrawPriv; if (vmesa->drawType == GLX_PBUFFER_BIT) { int w, h, bpp; w = vmesa->driDrawable->w; h = vmesa->driDrawable->h; bpp = vmesa->viaScreen->bitsPerPixel; if (bpp == 32) { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; vmesa->front.size = w * h * bpp / 8; vmesa->front.pitch = w << 2; } else { w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2; vmesa->front.size = w * h * bpp / 8; vmesa->front.pitch = w << 1; } } /*=* John Sheng [2003.6.20] fix resolution 720x480/720x576 front pitch error *=*/ else { GLuint w; GLuint h; GLuint bpp; bpp = vmesa->viaScreen->bitsPerPixel; h = vmesa->viaScreen->height; w = vmesa->viaScreen->width; if (bpp == 0x20) { w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; vmesa->front.size = w * h * bpp / 8; vmesa->front.pitch = w << 2; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 32); #endif } else if (bpp == 0x10) { w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2; vmesa->front.size = w * h * bpp / 8; vmesa->front.pitch = w << 1; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", 16); #endif } vmesa->front.offset = 0; vmesa->front.map = (char *) vmesa->driScreen->pFB; vmesa->front.size = w * h * vmesa->viaScreen->bitsPerPixel /8; } /* Allocate back & depth buffer */ { int w, h, bpp; w = vmesa->driDrawable->w; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", w); #endif h = vmesa->driDrawable->h; /* back buffer */ bpp = vmesa->viaScreen->bitsPerPixel; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "driScreen->fbBPP = %d\n", bpp); #endif if (bpp == 32) { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; else w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->back.size = w * h * bpp / 8; vmesa->back.pitch = w << 2; } else { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2; else w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16; vmesa->back.size = w * h * bpp / 8; vmesa->back.pitch = w << 1; } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent backbuffer: w = %d h = %d bpp = %d sizs = %d\n", w, h, bpp, vmesa->back.size); #endif /* depth buffer */ w = vmesa->driDrawable->w; if (vmesa->hasDepth && vmesa->hasStencil) { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; else w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 24\n"); if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n"); #endif } else if (vmesa->hasDepth) { /*=* John Sheng [2003.6.16] patch viewperf drv-08 draw nothing */ /*if(vmesa->viaScreen->bitsPerPixel == 32)*/ /*vmesa->depthBits = 16;*/ if (vmesa->depthBits == 16) { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2; else w = BUFFER_ALIGN_WIDTH(w * 2, BUFFER_ALIGNMENT) / 2 + 16; vmesa->depth.size = w * h * 2; vmesa->depth.pitch = w << 1; vmesa->depth.bpp = 16; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 16\n"); #endif } else { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; else w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "depthBits = 32\n"); #endif } } else if (vmesa->hasStencil) { if (vmesa->drawType == GLX_PBUFFER_BIT) w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4; else w = BUFFER_ALIGN_WIDTH(w * 4, BUFFER_ALIGNMENT) / 4 + 8; vmesa->depth.size = w * h * 4; vmesa->depth.pitch = w << 2; vmesa->depth.bpp = 32; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "StencilBits = 8\n"); #endif } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent depthbuffer: w = %d h = %d bpp = %d sizs = %d\n", w, h, vmesa->depth.bpp, vmesa->depth.size); #endif /*=* John Sheng [2003.5.31] flip *=*/ { viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; if(vmesa->viaScreen->width == vmesa->driDrawable->w && vmesa->viaScreen->height == vmesa->driDrawable->h) { vmesa->doPageFlip = GL_FALSE; vmesa->currentPage = 0; vmesa->back.pitch = vmesa->front.pitch; } } if (!AllocateBuffer(vmesa)) { FREE(vmesa); return GL_FALSE; } } _mesa_make_current2(vmesa->glCtx, (GLframebuffer *)driDrawPriv->driverPrivate, (GLframebuffer *)driReadPriv->driverPrivate); #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext); #endif viaXMesaWindowMoved(vmesa); if (!vmesa->glCtx->Viewport.Width) _mesa_set_viewport(vmesa->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h); } else { _mesa_make_current(0,0); } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif return GL_TRUE; } void viaGetLock(viaContextPtr vmesa, GLuint flags) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; __DRIscreenPrivate *sPriv = vmesa->driScreen; drm_via_sarea_t *sarea = vmesa->sarea; int me = vmesa->hHWContext; __DRIdrawablePrivate *pdp; __DRIscreenPrivate *psp; pdp = dPriv; psp = sPriv; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); if (VIA_DEBUG) fprintf(stderr, "drmGetLock - in\n"); #endif drmGetLock(vmesa->driFd, vmesa->hHWContext, flags); do { DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, pdp->driContextPriv->hHWContext); DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); __driUtilUpdateDrawableInfo(dPriv); DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, pdp->driContextPriv->hHWContext); } while (0); if (sarea->ctxOwner != me) { vmesa->uploadCliprects = GL_TRUE; sarea->ctxOwner = me; } viaXMesaWindowMoved(vmesa); #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif } void viaLock(viaContextPtr vmesa, GLuint flags) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; __DRIscreenPrivate *sPriv = vmesa->driScreen; if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); /*=* John Sheng [2003.6.16] for xf43 */ if(dPriv->pStamp == NULL) dPriv->pStamp = &dPriv->lastStamp; if (*(dPriv->pStamp) != dPriv->lastStamp || vmesa->saam) { GLuint scrn; scrn = vmesa->saam & S_MASK; DRM_SPINLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID); if (scrn == S1) __driUtilUpdateDrawableInfo(dPriv); else DRI_VALIDATE_DRAWABLE_INFO_ONCE(dPriv); viaXMesaWindowMoved(vmesa); DRM_SPINUNLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID); } if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); return; } void viaUnLock(viaContextPtr vmesa, GLuint flags) { drm_via_sarea_t *sarea = vmesa->sarea; int me = vmesa->hHWContext; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); if (VIA_DEBUG) fprintf(stderr, "sarea->ctxOwner = %d\n", sarea->ctxOwner); if (VIA_DEBUG) fprintf(stderr, "me = %d\n", me); #endif if (sarea->ctxOwner == me) { sarea->ctxOwner = 0; } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif } void viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate) { __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate; #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); #endif if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { viaContextPtr vmesa; GLcontext *ctx; vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; ctx = vmesa->glCtx; if (ctx->Visual.doubleBufferMode) { _mesa_notifySwapBuffers(ctx); if (vmesa->doPageFlip) { viaPageFlip(dPriv); } else { viaCopyBuffer(dPriv); } } else VIA_FIREVERTICES(vmesa); } else { _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n"); } #ifdef DEBUG if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); #endif }