📄 via_context.c
字号:
/* * 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. *//** * \file via_context.c * * \author John Sheng (presumably of either VIA Technologies or S3 Graphics) * \author Others at VIA Technologies? * \author Others at S3 Graphics? */#include "glheader.h"#include "context.h"#include "matrix.h"#include "state.h"#include "simple_list.h"#include "extensions.h"#include "framebuffer.h"#include "renderbuffer.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/tnl.h"#include "vbo/vbo.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_ioctl.h"#include "via_fb.h"#include <stdio.h>#include "macros.h"#include "drirenderbuffer.h"#define need_GL_ARB_multisample#define need_GL_ARB_point_parameters#define need_GL_ARB_vertex_buffer_object#define need_GL_EXT_fog_coord#define need_GL_EXT_secondary_color#include "extension_helper.h"#define DRIVER_DATE "20060710"#include "vblank.h"#include "utils.h"GLuint VIA_DEBUG = 0;/** * Return various strings for \c glGetString. * * \sa glGetString */static const GLubyte *viaGetString(GLcontext *ctx, GLenum name){ static char buffer[128]; unsigned offset; switch (name) { case GL_VENDOR: return (GLubyte *)"VIA Technology"; case GL_RENDERER: { static const char * const chipset_names[] = { "UniChrome", "CastleRock (CLE266)", "UniChrome (KM400)", "UniChrome (K8M800)", "UniChrome (PM8x0/CN400)", }; struct via_context *vmesa = VIA_CONTEXT(ctx); unsigned id = vmesa->viaScreen->deviceID; offset = driGetRendererString( buffer, chipset_names[(id > VIA_PM800) ? 0 : id], DRIVER_DATE, 0 ); return (GLubyte *)buffer; } default: return NULL; }}/** * Calculate a width that satisfies the hardware's alignment requirements. * On the Unichrome hardware, each scanline must be aligned to a multiple of * 16 pixels. * * \param width Minimum buffer width, in pixels. * * \returns A pixel width that meets the alignment requirements. */static INLINE unsignedbuffer_align( unsigned width ){ return (width + 0x0f) & ~0x0f;}static voidviaDeleteRenderbuffer(struct gl_renderbuffer *rb){ /* Don't free() since we're contained in via_context struct. */}static GLbooleanviaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height){ rb->Width = width; rb->Height = height; rb->InternalFormat = internalFormat; return GL_TRUE;}static voidviaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format, __DRIdrawablePrivate *dPriv){ const GLuint name = 0; struct gl_renderbuffer *rb = & vrb->Base; vrb->dPriv = dPriv; _mesa_init_renderbuffer(rb, name); /* Make sure we're using a null-valued GetPointer routine */ assert(rb->GetPointer(NULL, rb, 0, 0) == NULL); rb->InternalFormat = format; if (format == GL_RGBA) { /* Color */ rb->_BaseFormat = GL_RGBA; rb->DataType = GL_UNSIGNED_BYTE; } else if (format == GL_DEPTH_COMPONENT16) { /* Depth */ rb->_BaseFormat = GL_DEPTH_COMPONENT; /* we always Get/Put 32-bit Z values */ rb->DataType = GL_UNSIGNED_INT; } else if (format == GL_DEPTH_COMPONENT24) { /* Depth */ rb->_BaseFormat = GL_DEPTH_COMPONENT; /* we always Get/Put 32-bit Z values */ rb->DataType = GL_UNSIGNED_INT; } else { /* Stencil */ ASSERT(format == GL_STENCIL_INDEX8_EXT); rb->_BaseFormat = GL_STENCIL_INDEX; rb->DataType = GL_UNSIGNED_BYTE; } rb->Delete = viaDeleteRenderbuffer; rb->AllocStorage = viaRenderbufferStorage;}/** * Calculate the framebuffer parameters for all buffers (front, back, depth, * and stencil) associated with the specified context. * * \warning * This function also calls \c AllocateBuffer to actually allocate the * buffers. * * \sa AllocateBuffer */static GLbooleancalculate_buffer_parameters(struct via_context *vmesa, struct gl_framebuffer *fb, __DRIdrawablePrivate *dPriv){ const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16; const unsigned extra = 32; unsigned w; unsigned h; /* Normally, the renderbuffer would be added to the framebuffer just once * when the framebuffer was created. The VIA driver is a bit funny * though in that the front/back/depth renderbuffers are in the per-context * state! * That should be fixed someday. */ if (!vmesa->front.Base.InternalFormat) { /* do one-time init for the renderbuffers */ viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv); viaSetSpanFunctions(&vmesa->front, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base); if (fb->Visual.doubleBufferMode) { viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv); viaSetSpanFunctions(&vmesa->back, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base); } if (vmesa->glCtx->Visual.depthBits > 0) { viaInitRenderbuffer(&vmesa->depth, (vmesa->glCtx->Visual.depthBits == 16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24), dPriv); viaSetSpanFunctions(&vmesa->depth, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base); } if (vmesa->glCtx->Visual.stencilBits > 0) { viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT, dPriv); viaSetSpanFunctions(&vmesa->stencil, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base); } } assert(vmesa->front.Base.InternalFormat); assert(vmesa->front.Base.AllocStorage); if (fb->Visual.doubleBufferMode) { assert(vmesa->back.Base.AllocStorage); } if (fb->Visual.depthBits) { assert(vmesa->depth.Base.AllocStorage); } /* Allocate front-buffer */ if (vmesa->drawType == GLX_PBUFFER_BIT) { w = vmesa->driDrawable->w; h = vmesa->driDrawable->h; vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel; vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */ vmesa->front.size = vmesa->front.pitch * h; if (vmesa->front.map) via_free_draw_buffer(vmesa, &vmesa->front); if (!via_alloc_draw_buffer(vmesa, &vmesa->front)) return GL_FALSE; } else { w = vmesa->viaScreen->width; h = vmesa->viaScreen->height; vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel; vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */ vmesa->front.size = vmesa->front.pitch * h; if (getenv("ALTERNATE_SCREEN")) vmesa->front.offset = vmesa->front.size; else vmesa->front.offset = 0; vmesa->front.map = (char *) vmesa->driScreen->pFB; } /* Allocate back-buffer */ if (vmesa->hasBack) { vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel; vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift); vmesa->back.pitch += extra; vmesa->back.pitch = MIN2(vmesa->back.pitch, vmesa->front.pitch); vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h; if (vmesa->back.map) via_free_draw_buffer(vmesa, &vmesa->back); if (!via_alloc_draw_buffer(vmesa, &vmesa->back)) return GL_FALSE; } else { if (vmesa->back.map) via_free_draw_buffer(vmesa, &vmesa->back); (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) ); } /* Allocate depth-buffer */ if ( vmesa->hasStencil || vmesa->hasDepth ) { vmesa->depth.bpp = vmesa->depthBits; if (vmesa->depth.bpp == 24) vmesa->depth.bpp = 32; vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) * (vmesa->depth.bpp/8)) + extra; vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h; if (vmesa->depth.map) via_free_draw_buffer(vmesa, &vmesa->depth); if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) { return GL_FALSE; } } else { if (vmesa->depth.map) via_free_draw_buffer(vmesa, &vmesa->depth); (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) ); } /* stencil buffer is same as depth buffer */ vmesa->stencil.handle = vmesa->depth.handle; vmesa->stencil.size = vmesa->depth.size; vmesa->stencil.offset = vmesa->depth.offset; vmesa->stencil.index = vmesa->depth.index; vmesa->stencil.pitch = vmesa->depth.pitch; vmesa->stencil.bpp = vmesa->depth.bpp; vmesa->stencil.map = vmesa->depth.map; vmesa->stencil.orig = vmesa->depth.orig; vmesa->stencil.origMap = vmesa->depth.origMap; if( vmesa->viaScreen->width == vmesa->driDrawable->w && vmesa->viaScreen->height == vmesa->driDrawable->h ) { vmesa->doPageFlip = vmesa->allowPageFlip; if (vmesa->hasBack) { assert(vmesa->back.pitch == vmesa->front.pitch); } } else vmesa->doPageFlip = GL_FALSE; return GL_TRUE;}void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer, GLuint width, GLuint height){ struct via_context *vmesa = VIA_CONTEXT(ctx); calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable); _mesa_resize_framebuffer(ctx, drawbuffer, width, height);}/* Extension strings exported by the Unichrome driver. */const struct dri_extension card_extensions[] ={ { "GL_ARB_multisample", GL_ARB_multisample_functions }, { "GL_ARB_multitexture", NULL }, { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, { "GL_ARB_texture_env_add", NULL }, { "GL_ARB_texture_env_combine", NULL },/* { "GL_ARB_texture_env_dot3", NULL }, */ { "GL_ARB_texture_mirrored_repeat", NULL }, { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, { "GL_EXT_stencil_wrap", NULL }, { "GL_EXT_texture_env_combine", NULL },/* { "GL_EXT_texture_env_dot3", NULL }, */ { "GL_EXT_texture_lod_bias", NULL }, { "GL_NV_blend_square", NULL }, { NULL, NULL }};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 */#endif &_tnl_render_stage, 0,};static const struct dri_debug_control debug_control[] ={ { "fall", DEBUG_FALLBACKS }, { "tex", DEBUG_TEXTURE }, { "ioctl", DEBUG_IOCTL }, { "prim", DEBUG_PRIMS }, { "vert", DEBUG_VERTS }, { "state", DEBUG_STATE }, { "verb", DEBUG_VERBOSE }, { "dri", DEBUG_DRI }, { "dma", DEBUG_DMA }, { "san", DEBUG_SANITY }, { "sync", DEBUG_SYNC }, { "sleep", DEBUG_SLEEP }, { "pix", DEBUG_PIXEL }, { "2d", DEBUG_2D }, { NULL, 0 }};static GLbooleanAllocateDmaBuffer(struct via_context *vmesa){ if (vmesa->dma) via_free_dma_buffer(vmesa); if (!via_alloc_dma_buffer(vmesa)) return GL_FALSE; vmesa->dmaLow = 0; vmesa->dmaCliprectAddr = ~0; return GL_TRUE;}static voidFreeBuffer(struct via_context *vmesa){ if (vmesa->front.map && vmesa->drawType == GLX_PBUFFER_BIT) via_free_draw_buffer(vmesa, &vmesa->front); if (vmesa->back.map) via_free_draw_buffer(vmesa, &vmesa->back); if (vmesa->depth.map) via_free_draw_buffer(vmesa, &vmesa->depth); if (vmesa->breadcrumb.map) via_free_draw_buffer(vmesa, &vmesa->breadcrumb); if (vmesa->dma) via_free_dma_buffer(vmesa);}GLbooleanviaCreateContext(const __GLcontextModes *visual, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate){ GLcontext *ctx, *shareCtx; struct via_context *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 = (struct via_context *) CALLOC_STRUCT(via_context); if (!vmesa) { return GL_FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -