⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 savagerender.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
字号:
/* * Copyright 2005  Felix Kuehling * 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 FELIX KUEHLING 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. *//* * Render unclipped vertex buffers by emitting vertices directly to * dma buffers.  Use strip/fan hardware primitives where possible. * Simulate missing primitives with indexed vertices. */#include "glheader.h"#include "context.h"#include "macros.h"#include "imports.h"#include "mtypes.h"#include "tnl/t_context.h"#include "savagecontext.h"#include "savagetris.h"#include "savagestate.h"#include "savageioctl.h"/* * Standard render tab for Savage4 and smooth shading on Savage3D */#define HAVE_POINTS      0#define HAVE_LINES       0#define HAVE_LINE_STRIPS 0#define HAVE_TRIANGLES   1#define HAVE_TRI_STRIPS  1#define HAVE_TRI_STRIP_1 0#define HAVE_TRI_FANS    1#define HAVE_POLYGONS    0#define HAVE_QUADS       0#define HAVE_QUAD_STRIPS 0#define HAVE_ELTS        1#define LOCAL_VARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx) #define INIT( prim ) do {						\   if (0) fprintf(stderr, "%s\n", __FUNCTION__);			\   savageFlushVertices(imesa);						\   switch (prim) {							\   case GL_TRIANGLES:	   imesa->HwPrim = SAVAGE_PRIM_TRILIST; break;	\   case GL_TRIANGLE_STRIP: imesa->HwPrim = SAVAGE_PRIM_TRISTRIP; break;	\   case GL_TRIANGLE_FAN:   imesa->HwPrim = SAVAGE_PRIM_TRIFAN; break;	\   }									\} while (0)#define FLUSH()		savageFlushElts(imesa), savageFlushVertices(imesa)#define GET_CURRENT_VB_MAX_VERTS() \   ((imesa->bufferSize/4 - imesa->vtxBuf->used) / imesa->HwVertexSize)#define GET_SUBSEQUENT_VB_MAX_VERTS() \   (imesa->bufferSize/4 / imesa->HwVertexSize)#define ALLOC_VERTS( nr ) \	savageAllocVtxBuf( imesa, (nr) * imesa->HwVertexSize )#define EMIT_VERTS( ctx, j, nr, buf ) \	_tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )#define ELTS_VARS( buf ) GLushort *dest = buf, firstElt = imesa->firstElt#define ELT_INIT( prim ) INIT(prim)/* (size - used - 1 qword for drawing command) * 4 elts per qword */#define GET_CURRENT_VB_MAX_ELTS() \   ((imesa->cmdBuf.size - (imesa->cmdBuf.write - imesa->cmdBuf.base) - 1)*4)/* (size - space for initial state - 1 qword for drawing command) * 4 elts * imesa is not defined in validate_render :( */#define GET_SUBSEQUENT_VB_MAX_ELTS()					\   ((SAVAGE_CONTEXT(ctx)->cmdBuf.size - 				\     (SAVAGE_CONTEXT(ctx)->cmdBuf.start - 				\      SAVAGE_CONTEXT(ctx)->cmdBuf.base) - 1)*4)#define ALLOC_ELTS(nr) savageAllocElts(imesa, nr)#define EMIT_ELT(offset, x) do {					\   (dest)[offset] = (GLushort) ((x)+firstElt);				\} while (0)#define EMIT_TWO_ELTS(offset, x, y) do {				\   *(GLuint *)(dest + offset) = (((y)+firstElt) << 16) |		\				((x)+firstElt);				\} while (0)#define INCR_ELTS( nr ) dest += nr#define ELTPTR dest#define RELEASE_ELT_VERTS() \   savageReleaseIndexedVerts(imesa)#define EMIT_INDEXED_VERTS( ctx, start, count ) do {			\   GLuint *buf = savageAllocIndexedVerts(imesa, count-start);		\   EMIT_VERTS(ctx, start, count-start, buf);				\} while (0)#define TAG(x) savage_##x#include "tnl_dd/t_dd_dmatmp.h"/* * On Savage3D triangle fans and strips are broken with flat * shading. With triangles it wants the color for flat shading in the * first vertex! So we make another template instance which uses * triangles only (with reordered vertices: SAVAGE_PRIM_TRILIST_201). * The reordering is done by the DRM. */#undef  HAVE_TRI_STRIPS#undef  HAVE_TRI_FANS#define HAVE_TRI_STRIPS	0#define HAVE_TRI_FANS	0#undef  INIT#define INIT( prim ) do {						\   if (0) fprintf(stderr, "%s\n", __FUNCTION__);			\   savageFlushVertices(imesa);						\   imesa->HwPrim = SAVAGE_PRIM_TRILIST_201;				\} while(0)#undef  TAG#define TAG(x) savage_flat_##x##_s3d#include "tnl_dd/t_dd_dmatmp.h"/**********************************************************************//*                          Render pipeline stage                     *//**********************************************************************/static GLboolean savage_run_render( GLcontext *ctx,				    struct tnl_pipeline_stage *stage ){   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);   TNLcontext *tnl = TNL_CONTEXT(ctx);   struct vertex_buffer *VB = &tnl->vb;    tnl_render_func *tab, *tab_elts;   GLboolean valid;   GLuint i;   if (savageHaveIndexedVerts(imesa))      savageReleaseIndexedVerts(imesa);   if (imesa->savageScreen->chipset < S3_SAVAGE4 &&       (ctx->_TriangleCaps & DD_FLATSHADE)) {      tab = savage_flat_render_tab_verts_s3d;      tab_elts = savage_flat_render_tab_elts_s3d;      valid = savage_flat_validate_render_s3d( ctx, VB );   } else {      tab = savage_render_tab_verts;      tab_elts = savage_render_tab_elts;      valid = savage_validate_render( ctx, VB );   }   /* Don't handle clipping or vertex manipulations.    */   if (imesa->RenderIndex != 0 || !valid) {      return GL_TRUE;   }      tnl->Driver.Render.Start( ctx );   /* Check RenderIndex again. The ptexHack is detected late in RenderStart.    * Also check for ptex fallbacks detected late.    */   if (imesa->RenderIndex != 0 || imesa->Fallback != 0) {      return GL_TRUE;   }   /* setup for hardware culling */   imesa->raster_primitive = GL_TRIANGLES;   imesa->new_state |= SAVAGE_NEW_CULL;   /* update and emit state */   savageDDUpdateHwState(ctx);   savageEmitChangedState(imesa);   if (VB->Elts) {      tab = tab_elts;      if (!savageHaveIndexedVerts(imesa)) {	 if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())	    return GL_TRUE;	 EMIT_INDEXED_VERTS(ctx, 0, VB->Count);      }   }   for (i = 0 ; i < VB->PrimitiveCount ; i++)   {      GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);      GLuint start = VB->Primitive[i].start;      GLuint length = VB->Primitive[i].count;      if (length)	 tab[prim & PRIM_MODE_MASK]( ctx, start, start+length, prim);   }   tnl->Driver.Render.Finish( ctx );   return GL_FALSE;		/* finished the pipe */}struct tnl_pipeline_stage _savage_render_stage = {    "savage render",   NULL,   NULL,   NULL,   NULL,   savage_run_render		/* run */};/**********************************************************************//*         Pipeline stage for texture coordinate normalization        *//**********************************************************************/struct texnorm_stage_data {   GLboolean active;   GLvector4f texcoord[MAX_TEXTURE_UNITS];};#define TEXNORM_STAGE_DATA(stage) ((struct texnorm_stage_data *)stage->privatePtr)static GLboolean run_texnorm_stage( GLcontext *ctx,				    struct tnl_pipeline_stage *stage ){   struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage);   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);   TNLcontext *tnl = TNL_CONTEXT(ctx);   struct vertex_buffer *VB = &tnl->vb;   GLuint i;   if (imesa->Fallback || !store->active)      return GL_TRUE;   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {      const GLbitfield reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled;      if (reallyEnabled) {         const struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;         const GLboolean normalizeS = (texObj->WrapS == GL_REPEAT);         const GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) &&            (texObj->WrapT == GL_REPEAT);         const GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;         const GLint instride = VB->TexCoordPtr[i]->stride;         GLfloat (*out)[4] = store->texcoord[i].data;         GLint j;         if (!ctx->Texture.Unit[i]._ReallyEnabled ||             VB->TexCoordPtr[i]->size == 4)            /* Never try to normalize homogenous tex coords! */            continue;         if (normalizeS && normalizeT) {            /* take first texcoords as rough estimate of mean value */            GLfloat correctionS = -floor(in[0]+0.5);            GLfloat correctionT = -floor(in[1]+0.5);            for (j = 0; j < VB->Count; ++j) {               out[j][0] = in[0] + correctionS;               out[j][1] = in[1] + correctionT;               in = (GLfloat *)((GLubyte *)in + instride);            }         } else if (normalizeS) {            /* take first texcoords as rough estimate of mean value */            GLfloat correctionS = -floor(in[0]+0.5);            if (reallyEnabled & TEXTURE_2D_BIT) {               for (j = 0; j < VB->Count; ++j) {                  out[j][0] = in[0] + correctionS;                  out[j][1] = in[1];                  in = (GLfloat *)((GLubyte *)in + instride);               }            } else {               for (j = 0; j < VB->Count; ++j) {                  out[j][0] = in[0] + correctionS;                  in = (GLfloat *)((GLubyte *)in + instride);               }            }         } else if (normalizeT) {            /* take first texcoords as rough estimate of mean value */            GLfloat correctionT = -floor(in[1]+0.5);            for (j = 0; j < VB->Count; ++j) {               out[j][0] = in[0];               out[j][1] = in[1] + correctionT;               in = (GLfloat *)((GLubyte *)in + instride);            }         }         if (normalizeS || normalizeT)            VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];      }   }   return GL_TRUE;}/* Called the first time stage->run() is invoked. */static GLboolean alloc_texnorm_data( GLcontext *ctx,				     struct tnl_pipeline_stage *stage ){   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;   struct texnorm_stage_data *store;   GLuint i;   stage->privatePtr = CALLOC(sizeof(*store));   store = TEXNORM_STAGE_DATA(stage);   if (!store)      return GL_FALSE;   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)      _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );      return GL_TRUE;}static void validate_texnorm( GLcontext *ctx,			      struct tnl_pipeline_stage *stage ){   struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage);   GLuint flags = 0;   if (((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&	(ctx->Texture.Unit[0]._Current->WrapS == GL_REPEAT)) ||       ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&	(ctx->Texture.Unit[0]._Current->WrapT == GL_REPEAT)))      flags |= VERT_BIT_TEX0;   if (((ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&	(ctx->Texture.Unit[1]._Current->WrapS == GL_REPEAT)) ||       ((ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) &&	(ctx->Texture.Unit[1]._Current->WrapT == GL_REPEAT)))      flags |= VERT_BIT_TEX1;   store->active = (flags != 0);}static void free_texnorm_data( struct tnl_pipeline_stage *stage ){   struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage);   GLuint i;   if (store) {      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)	 if (store->texcoord[i].data)	    _mesa_vector4f_free( &store->texcoord[i] );      FREE( store );      stage->privatePtr = 0;   }}struct tnl_pipeline_stage _savage_texnorm_stage ={   "savage texture coordinate normalization stage", /* name */   NULL,				/* private data */   alloc_texnorm_data,			/* run -- initially set to init */   free_texnorm_data,			/* destructor */   validate_texnorm,   run_texnorm_stage};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -