From f18598cbd2802e61c2cbb1d610630da9b5951169 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 Jan 2004 23:26:19 +0000 Subject: Via Unichrome/cle266 driver (Erdi Chen) --- src/mesa/drivers/dri/unichrome/via_context.c | 1185 ++++++++++++++++++++++++++ 1 file changed, 1185 insertions(+) create mode 100644 src/mesa/drivers/dri/unichrome/via_context.c (limited to 'src/mesa/drivers/dri/unichrome/via_context.c') diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c new file mode 100644 index 0000000000..f38dec03ff --- /dev/null +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -0,0 +1,1185 @@ +/* + * 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 "mem.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 to match hardware characteristics: + */ + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _swrast_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; +#ifdef _SOLO + 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 = (XF86DRIClipRectPtr) malloc(sizeof(XF86DRIClipRectRec)); + return GL_TRUE; +} + +void +viaDestroyContext(__DRIcontextPrivate *driContextPriv) +{ + viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + assert(vmesa); /* should never be null */ + viaFlushPrimsLocked(vmesa); + WAIT_IDLE + 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; + + GLuint destMask = vmesa->glCtx->Color._DrawDestMask; + if (destMask & FRONT_LEFT_BIT) + viaXMesaSetFrontClipRects(vmesa); + if (destMask & BACK_LEFT_BIT) + viaXMesaSetBackClipRects(vmesa); + +#ifdef _SOLO + 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); +#ifdef _SOLO + __driUtilUpdateDrawableInfo(dPriv); +#else + __driUtilUpdateDrawableInfo(vmesa->display, psp->myNum, dPriv); +#endif + 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); + +#ifdef _SOLO + __driUtilUpdateDrawableInfo(dPriv); +#else + if (scrn == S1) + __driUtilUpdateDrawableInfo(vmesa->display, scrn, dPriv); + else + DRI_VALIDATE_DRAWABLE_INFO_ONCE(vmesa->display, scrn, dPriv); +#endif + + 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) { +#ifdef _SOLO + _mesa_notifySwapBuffers(ctx); +#else + _mesa_swapbuffers(ctx); +#endif + 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 +} -- cgit v1.2.3