1 /* 2 * Mesa 3-D graphics library 3 * Version: 6.3 4 * 5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keith (at) tungstengraphics.com> 26 */ 27 28 29 #include "main/api_arrayelt.h" 30 #include "main/glheader.h" 31 #include "main/mtypes.h" 32 #include "main/vtxfmt.h" 33 #include "vbo_context.h" 34 35 36 37 void vbo_exec_init( struct gl_context *ctx ) 38 { 39 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 40 41 exec->ctx = ctx; 42 43 /* Initialize the arrayelt helper 44 */ 45 if (!ctx->aelt_context && 46 !_ae_create_context( ctx )) 47 return; 48 49 vbo_exec_vtx_init( exec ); 50 vbo_exec_array_init( exec ); 51 52 /* Hook our functions into exec and compile dispatch tables. 53 */ 54 _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); 55 56 ctx->Driver.NeedFlush = 0; 57 ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; 58 ctx->Driver.BeginVertices = vbo_exec_BeginVertices; 59 ctx->Driver.FlushVertices = vbo_exec_FlushVertices; 60 61 vbo_exec_invalidate_state( ctx, ~0 ); 62 } 63 64 65 void vbo_exec_destroy( struct gl_context *ctx ) 66 { 67 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 68 69 if (ctx->aelt_context) { 70 _ae_destroy_context( ctx ); 71 ctx->aelt_context = NULL; 72 } 73 74 vbo_exec_vtx_destroy( exec ); 75 vbo_exec_array_destroy( exec ); 76 } 77 78 79 /** 80 * Really want to install these callbacks to a central facility to be 81 * invoked according to the state flags. That will have to wait for a 82 * mesa rework: 83 */ 84 void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state ) 85 { 86 struct vbo_exec_context *exec = &vbo_context(ctx)->exec; 87 88 if (new_state & (_NEW_PROGRAM|_NEW_ARRAY)) { 89 exec->array.recalculate_inputs = GL_TRUE; 90 } 91 92 if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) 93 exec->eval.recalculate_maps = 1; 94 95 _ae_invalidate_state(ctx, new_state); 96 } 97 98 99 /** 100 * Figure out the number of transform feedback primitives that will be output 101 * by the given _mesa_prim command, assuming that no geometry shading is done 102 * and primitive restart is not used. 103 * 104 * This is intended for use by driver back-ends in implementing the 105 * PRIMITIVES_GENERATED and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries. 106 */ 107 size_t 108 count_tessellated_primitives(const struct _mesa_prim *prim) 109 { 110 size_t num_primitives; 111 switch (prim->mode) { 112 case GL_POINTS: 113 num_primitives = prim->count; 114 break; 115 case GL_LINE_STRIP: 116 num_primitives = prim->count >= 2 ? prim->count - 1 : 0; 117 break; 118 case GL_LINE_LOOP: 119 num_primitives = prim->count >= 2 ? prim->count : 0; 120 break; 121 case GL_LINES: 122 num_primitives = prim->count / 2; 123 break; 124 case GL_TRIANGLE_STRIP: 125 case GL_TRIANGLE_FAN: 126 case GL_POLYGON: 127 num_primitives = prim->count >= 3 ? prim->count - 2 : 0; 128 break; 129 case GL_TRIANGLES: 130 num_primitives = prim->count / 3; 131 break; 132 case GL_QUAD_STRIP: 133 num_primitives = prim->count >= 4 ? ((prim->count / 2) - 1) * 2 : 0; 134 break; 135 case GL_QUADS: 136 num_primitives = (prim->count / 4) * 2; 137 break; 138 default: 139 assert(!"Unexpected primitive type in count_tessellated_primitives"); 140 num_primitives = 0; 141 break; 142 } 143 return num_primitives * prim->num_instances; 144 } 145