diff options
Diffstat (limited to 'src/mesa/drivers/dri/sis/sis_alloc.c')
-rw-r--r-- | src/mesa/drivers/dri/sis/sis_alloc.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/sis/sis_alloc.c b/src/mesa/drivers/dri/sis/sis_alloc.c new file mode 100644 index 0000000000..aa71f269d1 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_alloc.c @@ -0,0 +1,256 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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 +on 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 +ATI, PRECISION INSIGHT AND/OR THEIR 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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.7 2001/01/08 01:07:29 martin Exp $ */ + +/* + * Authors: + * Sung-Ching Lin <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include <assert.h> + +#include "sis_context.h" +#include "sis_alloc.h" + +#include "sis_common.h" + +#define Z_BUFFER_HW_ALIGNMENT 16 +#define Z_BUFFER_HW_PLUS (16 + 4) + +/* 3D engine uses 2, and bitblt uses 4 */ +#define DRAW_BUFFER_HW_ALIGNMENT 16 +#define DRAW_BUFFER_HW_PLUS (16 + 4) + +#ifdef ROUNDUP +#undef ROUNDUP +#endif +#define ROUNDUP(nbytes, pad) (((nbytes)+(pad-1))/(pad)) + +#ifdef ALIGNMENT +#undef ALIGNMENT +#endif +#define ALIGNMENT(value, align) (ROUNDUP((value),(align))*(align)) + +static int _total_video_memory_used = 0; +static int _total_video_memory_count = 0; + +void * +sisAllocFB( sisContextPtr smesa, GLuint size, void **handle ) +{ + drm_sis_mem_t fb; + + _total_video_memory_used += size; + + fb.context = smesa->hHWContext; + fb.size = size; + if (drmCommandWriteRead( smesa->driFd, DRM_SIS_FB_ALLOC, &fb, + sizeof(drm_sis_mem_t) ) || fb.offset == 0) + { + return NULL; + } + *handle = (void *)fb.free; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisAllocFB: size=%d, offset=%lu, pid=%d, count=%d\n", + size, fb.offset, (GLint)getpid(), + ++_total_video_memory_count); + } + + return (void *)(smesa->FbBase + fb.offset); +} + +void +sisFreeFB( sisContextPtr smesa, void *handle ) +{ + drm_sis_mem_t fb; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisFreeFB: free=%p, pid=%d, count=%d\n", + handle, (GLint)getpid(), --_total_video_memory_count); + } + + fb.context = smesa->hHWContext; + fb.free = handle; + drmCommandWrite( smesa->driFd, DRM_SIS_FB_FREE, &fb, sizeof(drm_sis_mem_t) ); +} + +void * +sisAllocAGP( sisContextPtr smesa, GLuint size, void **handle ) +{ + drm_sis_mem_t agp; + + if (smesa->AGPSize == 0) + return NULL; + + agp.context = smesa->hHWContext; + agp.size = size; + if (drmCommandWriteRead( smesa->driFd, DRM_SIS_AGP_ALLOC, &agp, + sizeof(drm_sis_mem_t) ) || agp.offset == 0) + { + return NULL; + } + *handle = (void *)agp.free; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisAllocAGP: size=%u, offset=%lu, pid=%d, count=%d\n", + size, agp.offset, (GLint)getpid(), + ++_total_video_memory_count); + } + + return (void *)(smesa->AGPBase + agp.offset); +} + +void +sisFreeAGP( sisContextPtr smesa, void *handle ) +{ + drm_sis_mem_t agp; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisFreeAGP: free=%p, pid=%d, count=%d\n", + handle, (GLint)getpid(), --_total_video_memory_count); + } + + agp.context = smesa->hHWContext; + agp.free = handle; + drmCommandWrite( smesa->driFd, DRM_SIS_AGP_FREE, &agp, + sizeof(drm_sis_mem_t) ); +} + +void +sisAllocZStencilBuffer( sisContextPtr smesa ) +{ + GLuint z_depth; + GLuint totalBytes; + int width2; + + GLubyte *addr; + + z_depth = ( smesa->glCtx->Visual.depthBits + + smesa->glCtx->Visual.stencilBits ) / 8; + + width2 = ALIGNMENT( smesa->width * z_depth, 4 ); + + totalBytes = smesa->height * width2 + Z_BUFFER_HW_PLUS; + + addr = sisAllocFB( smesa, totalBytes, &smesa->zbFree ); + if (addr == NULL) + { + fprintf (stderr, "SIS driver : out of video memory\n"); + sis_fatal_error (); + } + + if (SIS_VERBOSE & VERBOSE_SIS_BUFFER) { + fprintf(stderr, "sis_alloc_z_stencil_buffer: addr=%p\n", addr); + } + + addr = (GLubyte *)ALIGNMENT( (unsigned long)addr, Z_BUFFER_HW_ALIGNMENT ); + + smesa->depthbuffer = (void *) addr; + smesa->depthPitch = width2; + + /* set pZClearPacket */ + memset( &smesa->zClearPacket, 0, sizeof(ENGPACKET) ); + + smesa->zClearPacket.dwSrcPitch = (z_depth == 2) ? 0x80000000 : 0xf0000000; + smesa->zClearPacket.dwDestBaseAddr = (GLint)(addr - + (unsigned long)smesa->FbBase); + smesa->zClearPacket.wDestPitch = width2; + smesa->zClearPacket.stdwDestPos.wY = 0; + smesa->zClearPacket.stdwDestPos.wX = 0; + + smesa->zClearPacket.wDestHeight = smesa->virtualY; + smesa->zClearPacket.stdwDim.wWidth = (GLshort)width2 / z_depth; + smesa->zClearPacket.stdwDim.wHeight = (GLshort)smesa->height; + smesa->zClearPacket.stdwCmd.cRop = 0xf0; + + if (smesa->blockWrite) + smesa->zClearPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR; + else + smesa->zClearPacket.stdwCmd.cCmd0 = 0; + smesa->zClearPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; +} + +void +sisFreeZStencilBuffer( sisContextPtr smesa ) +{ + sisFreeFB( smesa, smesa->zbFree ); + smesa->zbFree = NULL; + smesa->depthbuffer = NULL; +} + +void +sisAllocBackbuffer( sisContextPtr smesa ) +{ + GLuint depth = smesa->bytesPerPixel; + GLuint size, width2; + + char *addr; + + width2 = (depth == 2) ? ALIGNMENT (smesa->width, 2) : smesa->width; + size = width2 * smesa->height * depth + DRAW_BUFFER_HW_PLUS; + + /* Fixme: unique context alloc/free back-buffer? */ + addr = sisAllocFB( smesa, size, &smesa->bbFree ); + if (addr == NULL) + { + fprintf (stderr, "SIS driver : out of video memory\n"); + sis_fatal_error (); + } + + addr = (char *)ALIGNMENT( (unsigned long)addr, DRAW_BUFFER_HW_ALIGNMENT ); + + smesa->backbuffer = addr; + smesa->backOffset = (GLint)(addr - (unsigned long)smesa->FbBase); + smesa->backPitch = width2 * depth; + + memset ( &smesa->cbClearPacket, 0, sizeof(ENGPACKET) ); + + smesa->cbClearPacket.dwSrcPitch = (depth == 2) ? 0x80000000 : 0xf0000000; + smesa->cbClearPacket.dwDestBaseAddr = smesa->backOffset; + smesa->cbClearPacket.wDestPitch = smesa->backPitch; + smesa->cbClearPacket.stdwDestPos.wY = 0; + smesa->cbClearPacket.stdwDestPos.wX = 0; + + smesa->cbClearPacket.wDestHeight = smesa->virtualY; + smesa->cbClearPacket.stdwDim.wWidth = (GLshort) width2; + smesa->cbClearPacket.stdwDim.wHeight = (GLshort) smesa->height; + smesa->cbClearPacket.stdwCmd.cRop = 0xf0; + + if (smesa->blockWrite) + smesa->cbClearPacket.stdwCmd.cCmd0 = (GLbyte)(CMD0_PAT_FG_COLOR); + else + smesa->cbClearPacket.stdwCmd.cCmd0 = 0; + smesa->cbClearPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; +} + +void +sisFreeBackbuffer( sisContextPtr smesa ) +{ + sisFreeFB( smesa, smesa->bbFree ); + smesa->backbuffer = NULL; +} |