t_context.c revision c1f859d4
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.2 4 * 5 * Copyright (C) 1999-2008 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@tungstengraphics.com> 26 */ 27 28 29#include "main/glheader.h" 30#include "main/imports.h" 31#include "main/context.h" 32#include "main/macros.h" 33#include "main/mtypes.h" 34#include "main/light.h" 35 36#include "tnl.h" 37#include "t_context.h" 38#include "t_pipeline.h" 39#include "t_vp_build.h" 40 41#include "vbo/vbo.h" 42 43GLboolean 44_tnl_CreateContext( GLcontext *ctx ) 45{ 46 TNLcontext *tnl; 47 48 /* Create the TNLcontext structure 49 */ 50 ctx->swtnl_context = tnl = (TNLcontext *) CALLOC( sizeof(TNLcontext) ); 51 52 if (!tnl) { 53 return GL_FALSE; 54 } 55 56 /* Initialize the VB. 57 */ 58 tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; 59 60 61 /* Initialize tnl state. 62 */ 63 if (ctx->VertexProgram._MaintainTnlProgram) { 64 _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); 65 } else { 66 _tnl_install_pipeline( ctx, _tnl_default_pipeline ); 67 } 68 69 tnl->NeedNdcCoords = GL_TRUE; 70 tnl->AllowVertexFog = GL_TRUE; 71 tnl->AllowPixelFog = GL_TRUE; 72 73 /* Set a few default values in the driver struct. 74 */ 75 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; 76 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; 77 tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; 78 79 tnl->nr_blocks = 0; 80 81 return GL_TRUE; 82} 83 84 85void 86_tnl_DestroyContext( GLcontext *ctx ) 87{ 88 TNLcontext *tnl = TNL_CONTEXT(ctx); 89 90 _tnl_destroy_pipeline( ctx ); 91 92 FREE(tnl); 93 ctx->swtnl_context = NULL; 94} 95 96 97void 98_tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) 99{ 100 TNLcontext *tnl = TNL_CONTEXT(ctx); 101 const struct gl_vertex_program *vp = ctx->VertexProgram._Current; 102 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 103 104 if (new_state & (_NEW_HINT | _NEW_PROGRAM)) { 105 ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog); 106 tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 107 || !tnl->AllowPixelFog) && !fp; 108 } 109 110 tnl->pipeline.new_state |= new_state; 111 112 /* Calculate tnl->render_inputs. This bitmask indicates which vertex 113 * attributes need to be emitted to the rasterizer. 114 */ 115 if (ctx->Visual.rgbMode) { 116 GLuint i; 117 118 RENDERINPUTS_ZERO( tnl->render_inputs_bitset ); 119 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); 120 121 if (!fp || (fp->Base.InputsRead & FRAG_BIT_COL0)) { 122 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 ); 123 } 124 125 if (NEED_SECONDARY_COLOR(ctx)) 126 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 ); 127 128 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 129 if (ctx->Texture._EnabledCoordUnits & (1 << i) || 130 (fp && fp->Base.InputsRead & FRAG_BIT_TEX(i))) { 131 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) ); 132 } 133 } 134 } 135 else { 136 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); 137 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR_INDEX ); 138 } 139 140 if (ctx->Fog.Enabled) { 141 /* fixed-function fog */ 142 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); 143 } 144 else if (ctx->FragmentProgram._Current) { 145 struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 146 if (fp) { 147 if (fp->FogOption != GL_NONE || (fp->Base.InputsRead & FRAG_BIT_FOGC)) { 148 /* fragment program needs fog coord */ 149 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); 150 } 151 } 152 } 153 154 if (ctx->Polygon.FrontMode != GL_FILL || 155 ctx->Polygon.BackMode != GL_FILL) 156 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_EDGEFLAG ); 157 158 if (ctx->RenderMode == GL_FEEDBACK) 159 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 ); 160 161 if (ctx->Point._Attenuated || 162 (ctx->VertexProgram._Enabled && ctx->VertexProgram.PointSizeEnabled)) 163 RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE ); 164 165 /* check for varying vars which are written by the vertex program */ 166 if (vp) { 167 GLuint i; 168 for (i = 0; i < MAX_VARYING; i++) { 169 if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) { 170 RENDERINPUTS_SET(tnl->render_inputs_bitset, 171 _TNL_ATTRIB_GENERIC(i)); 172 } 173 } 174 } 175} 176 177 178void 179_tnl_wakeup( GLcontext *ctx ) 180{ 181 /* Assume we haven't been getting state updates either: 182 */ 183 _tnl_InvalidateState( ctx, ~0 ); 184 185#if 0 186 if (ctx->Light.ColorMaterialEnabled) { 187 _mesa_update_color_material( ctx, 188 ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); 189 } 190#endif 191} 192 193 194 195 196/** 197 * Drivers call this function to tell the TCL module whether or not 198 * it wants Normalized Device Coords (NDC) computed. I.e. whether 199 * we should "Divide-by-W". Software renders will want that. 200 */ 201void 202_tnl_need_projected_coords( GLcontext *ctx, GLboolean mode ) 203{ 204 TNLcontext *tnl = TNL_CONTEXT(ctx); 205 tnl->NeedNdcCoords = mode; 206} 207 208void 209_tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 210{ 211 TNLcontext *tnl = TNL_CONTEXT(ctx); 212 tnl->AllowVertexFog = value; 213 tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 214 || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; 215 216} 217 218void 219_tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 220{ 221 TNLcontext *tnl = TNL_CONTEXT(ctx); 222 tnl->AllowPixelFog = value; 223 tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 224 || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; 225} 226 227