17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg * 247117f1b4Smrg * Authors: 25af69d88dSmrg * Keith Whitwell <keithw@vmware.com> 267117f1b4Smrg */ 277117f1b4Smrg 287117f1b4Smrg 29c1f859d4Smrg#include "main/glheader.h" 307ec681f3Smrg 31c1f859d4Smrg#include "main/context.h" 32c1f859d4Smrg#include "main/macros.h" 33c1f859d4Smrg#include "main/mtypes.h" 34c1f859d4Smrg#include "main/light.h" 354a49301eSmrg#include "math/m_translate.h" 364a49301eSmrg#include "math/m_xform.h" 373464ebd5Sriastradh#include "main/state.h" 3801e04c3fSmrg#include "main/viewport.h" 3901e04c3fSmrg#include "util/simple_list.h" 407ec681f3Smrg#include "util/u_memory.h" 417117f1b4Smrg 427117f1b4Smrg#include "tnl.h" 437117f1b4Smrg#include "t_context.h" 447117f1b4Smrg#include "t_pipeline.h" 457117f1b4Smrg 467117f1b4Smrg#include "vbo/vbo.h" 477117f1b4Smrg 487117f1b4SmrgGLboolean 493464ebd5Sriastradh_tnl_CreateContext( struct gl_context *ctx ) 507117f1b4Smrg{ 517117f1b4Smrg TNLcontext *tnl; 52af69d88dSmrg GLuint i; 537117f1b4Smrg 547117f1b4Smrg /* Create the TNLcontext structure 557117f1b4Smrg */ 56af69d88dSmrg ctx->swtnl_context = tnl = calloc(1, sizeof(TNLcontext)); 577117f1b4Smrg 587117f1b4Smrg if (!tnl) { 597117f1b4Smrg return GL_FALSE; 607117f1b4Smrg } 617117f1b4Smrg 627117f1b4Smrg /* Initialize the VB. 637117f1b4Smrg */ 647117f1b4Smrg tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; 657117f1b4Smrg 667117f1b4Smrg 677117f1b4Smrg /* Initialize tnl state. 687117f1b4Smrg */ 697117f1b4Smrg if (ctx->VertexProgram._MaintainTnlProgram) { 707117f1b4Smrg _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); 717117f1b4Smrg } else { 727117f1b4Smrg _tnl_install_pipeline( ctx, _tnl_default_pipeline ); 737117f1b4Smrg } 747117f1b4Smrg 7501e04c3fSmrg _math_matrix_ctr(&tnl->_WindowMap); 7601e04c3fSmrg 777117f1b4Smrg tnl->NeedNdcCoords = GL_TRUE; 787117f1b4Smrg tnl->AllowVertexFog = GL_TRUE; 797117f1b4Smrg tnl->AllowPixelFog = GL_TRUE; 807117f1b4Smrg 817117f1b4Smrg /* Set a few default values in the driver struct. 827117f1b4Smrg */ 837117f1b4Smrg tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; 847117f1b4Smrg tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; 85af69d88dSmrg tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables; 867117f1b4Smrg 877117f1b4Smrg tnl->nr_blocks = 0; 887117f1b4Smrg 89af69d88dSmrg /* Lighting miscellaneous */ 90af69d88dSmrg tnl->_ShineTabList = MALLOC_STRUCT( tnl_shine_tab ); 91af69d88dSmrg make_empty_list( tnl->_ShineTabList ); 92af69d88dSmrg /* Allocate 10 (arbitrary) shininess lookup tables */ 93af69d88dSmrg for (i = 0 ; i < 10 ; i++) { 94af69d88dSmrg struct tnl_shine_tab *s = MALLOC_STRUCT( tnl_shine_tab ); 95af69d88dSmrg s->shininess = -1; 96af69d88dSmrg s->refcount = 0; 97af69d88dSmrg insert_at_tail( tnl->_ShineTabList, s ); 98af69d88dSmrg } 99af69d88dSmrg 1004a49301eSmrg _math_init_transformation(); 1014a49301eSmrg _math_init_translate(); 1024a49301eSmrg 10301e04c3fSmrg /* Keep our list of tnl_vertex_array inputs */ 10401e04c3fSmrg _tnl_init_inputs(&tnl->draw_arrays); 10501e04c3fSmrg 1067117f1b4Smrg return GL_TRUE; 1077117f1b4Smrg} 1087117f1b4Smrg 1097117f1b4Smrg 1107117f1b4Smrgvoid 1113464ebd5Sriastradh_tnl_DestroyContext( struct gl_context *ctx ) 1127117f1b4Smrg{ 113af69d88dSmrg struct tnl_shine_tab *s, *tmps; 1147117f1b4Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 1157117f1b4Smrg 116af69d88dSmrg /* Free lighting shininess exponentiation table */ 117af69d88dSmrg foreach_s( s, tmps, tnl->_ShineTabList ) { 118af69d88dSmrg free( s ); 119af69d88dSmrg } 120af69d88dSmrg free( tnl->_ShineTabList ); 121af69d88dSmrg 1227117f1b4Smrg _tnl_destroy_pipeline( ctx ); 1237117f1b4Smrg 124af69d88dSmrg free(tnl); 1257117f1b4Smrg ctx->swtnl_context = NULL; 1267117f1b4Smrg} 1277117f1b4Smrg 1287117f1b4Smrg 1297117f1b4Smrgvoid 1303464ebd5Sriastradh_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state ) 1317117f1b4Smrg{ 1327117f1b4Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 13301e04c3fSmrg const struct gl_program *vp = ctx->VertexProgram._Current; 13401e04c3fSmrg const struct gl_program *fp = ctx->FragmentProgram._Current; 135cdc920a0Smrg GLuint i; 1367117f1b4Smrg 1377ec681f3Smrg if (new_state & (_NEW_LIGHT_CONSTANTS | _NEW_MATERIAL)) 1387ec681f3Smrg _mesa_update_light_materials(ctx); 1397ec681f3Smrg 140c1f859d4Smrg if (new_state & (_NEW_HINT | _NEW_PROGRAM)) { 14101e04c3fSmrg assert(tnl->AllowVertexFog || tnl->AllowPixelFog); 142c1f859d4Smrg tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 143c1f859d4Smrg || !tnl->AllowPixelFog) && !fp; 1447117f1b4Smrg } 1457117f1b4Smrg 1467117f1b4Smrg tnl->pipeline.new_state |= new_state; 1477117f1b4Smrg 148c1f859d4Smrg /* Calculate tnl->render_inputs. This bitmask indicates which vertex 149c1f859d4Smrg * attributes need to be emitted to the rasterizer. 1507117f1b4Smrg */ 151af69d88dSmrg tnl->render_inputs_bitset = BITFIELD64_BIT(_TNL_ATTRIB_POS); 1527117f1b4Smrg 15301e04c3fSmrg if (!fp || (fp->info.inputs_read & VARYING_BIT_COL0)) { 154af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR0); 155cdc920a0Smrg } 156c1f859d4Smrg 1573464ebd5Sriastradh if (_mesa_need_secondary_color(ctx)) 158af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR1); 159c1f859d4Smrg 160cdc920a0Smrg for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 161cdc920a0Smrg if (ctx->Texture._EnabledCoordUnits & (1 << i) || 16201e04c3fSmrg (fp && fp->info.inputs_read & VARYING_BIT_TEX(i)) || 16301e04c3fSmrg _mesa_ati_fragment_shader_enabled(ctx)) { 164af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX(i)); 165cdc920a0Smrg } 1667117f1b4Smrg } 1677117f1b4Smrg 1683464ebd5Sriastradh if (ctx->Fog.Enabled 16901e04c3fSmrg || (fp != NULL && (fp->info.inputs_read & VARYING_BIT_FOGC) != 0)) { 1703464ebd5Sriastradh /* Either fixed-function fog or a fragment program needs fog coord. 1713464ebd5Sriastradh */ 172af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_FOG); 173c1f859d4Smrg } 1747117f1b4Smrg 1757ec681f3Smrg if (ctx->Polygon.FrontMode != GL_FILL || 1767117f1b4Smrg ctx->Polygon.BackMode != GL_FILL) 177af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_EDGEFLAG); 1787117f1b4Smrg 1797117f1b4Smrg if (ctx->RenderMode == GL_FEEDBACK) 180af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX0); 1817117f1b4Smrg 182af69d88dSmrg if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) 183af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE); 1847117f1b4Smrg 1857117f1b4Smrg /* check for varying vars which are written by the vertex program */ 1867117f1b4Smrg if (vp) { 1877117f1b4Smrg GLuint i; 1887117f1b4Smrg for (i = 0; i < MAX_VARYING; i++) { 18901e04c3fSmrg if (vp->info.outputs_written & 19001e04c3fSmrg BITFIELD64_BIT(VARYING_SLOT_VAR0 + i)) { 191af69d88dSmrg tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i)); 1927117f1b4Smrg } 1937117f1b4Smrg } 1947117f1b4Smrg } 19501e04c3fSmrg 19601e04c3fSmrg if (new_state & (_NEW_VIEWPORT | _NEW_BUFFERS)) { 19701e04c3fSmrg float scale[3], translate[3]; 19801e04c3fSmrg _mesa_get_viewport_xform(ctx, 0, scale, translate); 19901e04c3fSmrg _math_matrix_viewport(&tnl->_WindowMap, scale, translate, 20001e04c3fSmrg ctx->DrawBuffer->_DepthMaxF); 20101e04c3fSmrg } 2027117f1b4Smrg} 2037117f1b4Smrg 2047117f1b4Smrg 2057117f1b4Smrgvoid 2063464ebd5Sriastradh_tnl_wakeup( struct gl_context *ctx ) 2077117f1b4Smrg{ 2087117f1b4Smrg /* Assume we haven't been getting state updates either: 2097117f1b4Smrg */ 2107117f1b4Smrg _tnl_InvalidateState( ctx, ~0 ); 2117117f1b4Smrg 2127117f1b4Smrg#if 0 2137117f1b4Smrg if (ctx->Light.ColorMaterialEnabled) { 2147ec681f3Smrg _mesa_update_color_material( ctx, 2157117f1b4Smrg ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); 2167117f1b4Smrg } 2177117f1b4Smrg#endif 2187117f1b4Smrg} 2197117f1b4Smrg 2207117f1b4Smrg 2217117f1b4Smrg 2227117f1b4Smrg 2237117f1b4Smrg/** 2247117f1b4Smrg * Drivers call this function to tell the TCL module whether or not 2257117f1b4Smrg * it wants Normalized Device Coords (NDC) computed. I.e. whether 2267117f1b4Smrg * we should "Divide-by-W". Software renders will want that. 2277117f1b4Smrg */ 2287117f1b4Smrgvoid 2293464ebd5Sriastradh_tnl_need_projected_coords( struct gl_context *ctx, GLboolean mode ) 2307117f1b4Smrg{ 2317117f1b4Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 2327117f1b4Smrg tnl->NeedNdcCoords = mode; 2337117f1b4Smrg} 2347117f1b4Smrg 2357117f1b4Smrgvoid 2363464ebd5Sriastradh_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value ) 2377117f1b4Smrg{ 2387117f1b4Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 2397117f1b4Smrg tnl->AllowVertexFog = value; 240c1f859d4Smrg tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 241c1f859d4Smrg || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; 2427117f1b4Smrg 2437117f1b4Smrg} 2447117f1b4Smrg 2457117f1b4Smrgvoid 2463464ebd5Sriastradh_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value ) 2477117f1b4Smrg{ 2487117f1b4Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 2497117f1b4Smrg tnl->AllowPixelFog = value; 250c1f859d4Smrg tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) 251c1f859d4Smrg || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; 2527117f1b4Smrg} 2537117f1b4Smrg 254