/* * mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 1999-2006 Brian Paul 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, sublicense, * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL 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 t_context.h * \brief TnL module datatypes and definitions. * \author Keith Whitwell */ /** * \mainpage The TNL-module * * TNL stands for "transform and lighting", i.e. this module implements * a pipeline that receives as input a buffer of vertices and does all * necessary transformations (rotations, clipping, vertex shader etc.) * and passes then the output to the rasterizer. * * The tnl_pipeline contains the array of all stages, which should be * applied. Each stage is a black-box, which is described by an * tnl_pipeline_stage. The function ::_tnl_run_pipeline applies all the * stages to the vertex_buffer TNLcontext::vb, where the vertex data * is stored. The last stage in the pipeline is the rasterizer. * */ #ifndef _T_CONTEXT_H #define _T_CONTEXT_H #include "main/glheader.h" #include "main/imports.h" #include "main/mtypes.h" #include "math/m_vector.h" #include "vbo/vbo.h" #define MAX_PIPELINE_STAGES 30 /* * Note: The first attributes match the VERT_ATTRIB_* definitions * in mtypes.h. However, the tnl module has additional attributes * for materials, color indexes, edge flags, etc. */ /* Although it's nice to use these as bit indexes in a DWORD flag, we * could manage without if necessary. Another limit currently is the * number of bits allocated for these numbers in places like vertex * program instruction formats and register layouts. */ /* The bit space exhaustion is a fact now, done by _TNL_ATTRIB_ATTRIBUTE* for * GLSL vertex shader which cannot be aliased with conventional vertex attribs. * Compacting _TNL_ATTRIB_MAT_* attribs would not work, they would not give * as many free bits (11 plus already 1 free bit) as _TNL_ATTRIB_ATTRIBUTE* * attribs want (16). */ enum { _TNL_ATTRIB_POS = 0, _TNL_ATTRIB_WEIGHT = 1, _TNL_ATTRIB_NORMAL = 2, _TNL_ATTRIB_COLOR0 = 3, _TNL_ATTRIB_COLOR1 = 4, _TNL_ATTRIB_FOG = 5, _TNL_ATTRIB_COLOR_INDEX = 6, _TNL_ATTRIB_EDGEFLAG = 7, _TNL_ATTRIB_TEX0 = 8, _TNL_ATTRIB_TEX1 = 9, _TNL_ATTRIB_TEX2 = 10, _TNL_ATTRIB_TEX3 = 11, _TNL_ATTRIB_TEX4 = 12, _TNL_ATTRIB_TEX5 = 13, _TNL_ATTRIB_TEX6 = 14, _TNL_ATTRIB_TEX7 = 15, _TNL_ATTRIB_GENERIC0 = 17, /* doesn't really exist! */ _TNL_ATTRIB_GENERIC1 = 18, _TNL_ATTRIB_GENERIC2 = 19, _TNL_ATTRIB_GENERIC3 = 20, _TNL_ATTRIB_GENERIC4 = 21, _TNL_ATTRIB_GENERIC5 = 22, _TNL_ATTRIB_GENERIC6 = 23, _TNL_ATTRIB_GENERIC7 = 24, _TNL_ATTRIB_GENERIC8 = 25, _TNL_ATTRIB_GENERIC9 = 26, _TNL_ATTRIB_GENERIC10 = 27, _TNL_ATTRIB_GENERIC11 = 28, _TNL_ATTRIB_GENERIC12 = 29, _TNL_ATTRIB_GENERIC13 = 30, _TNL_ATTRIB_GENERIC14 = 31, _TNL_ATTRIB_GENERIC15 = 32, /* These alias with the generics, but they are not active * concurrently, so it's not a problem. The TNL module * doesn't have to do anything about this as this is how they * are passed into the _draw_prims callback. * * When we generate fixed-function replacement programs (in * t_vp_build.c currently), they refer to the appropriate * generic attribute in order to pick up per-vertex material * data. */ _TNL_ATTRIB_MAT_FRONT_AMBIENT = 17, _TNL_ATTRIB_MAT_BACK_AMBIENT = 18, _TNL_ATTRIB_MAT_FRONT_DIFFUSE = 19, _TNL_ATTRIB_MAT_BACK_DIFFUSE = 20, _TNL_ATTRIB_MAT_FRONT_SPECULAR = 21, _TNL_ATTRIB_MAT_BACK_SPECULAR = 22, _TNL_ATTRIB_MAT_FRONT_EMISSION = 23, _TNL_ATTRIB_MAT_BACK_EMISSION = 24, _TNL_ATTRIB_MAT_FRONT_SHININESS = 25, _TNL_ATTRIB_MAT_BACK_SHININESS = 26, _TNL_ATTRIB_MAT_FRONT_INDEXES = 27, _TNL_ATTRIB_MAT_BACK_INDEXES = 28, /* This is really a VERT_RESULT, not an attrib. Need to fix * tnl to understand the difference. */ _TNL_ATTRIB_POINTSIZE = 16, _TNL_ATTRIB_MAX = 33 } ; #define _TNL_ATTRIB_TEX(u) (_TNL_ATTRIB_TEX0 + (u)) #define _TNL_ATTRIB_GENERIC(n) (_TNL_ATTRIB_GENERIC0 + (n)) /* special index used for handing invalid glVertexAttribute() indices */ #define _TNL_ATTRIB_ERROR (_TNL_ATTRIB_GENERIC15 + 1) /** * Handy attribute ranges: */ #define _TNL_FIRST_PROG _TNL_ATTRIB_WEIGHT #define _TNL_LAST_PROG _TNL_ATTRIB_TEX7 #define _TNL_FIRST_TEX _TNL_ATTRIB_TEX0 #define _TNL_LAST_TEX _TNL_ATTRIB_TEX7 #define _TNL_FIRST_GENERIC _TNL_ATTRIB_GENERIC0 #define _TNL_LAST_GENERIC _TNL_ATTRIB_GENERIC15 #define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC0 */ #define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC11 */ /* Number of available texture attributes */ #define _TNL_NUM_TEX 8 /* Number of available generic attributes */ #define _TNL_NUM_GENERIC 16 /* Number of attributes used for evaluators */ #define _TNL_NUM_EVAL 16 #define PRIM_BEGIN 0x10 #define PRIM_END 0x20 #define PRIM_MODE_MASK 0x0f static inline GLuint _tnl_translate_prim( const struct _mesa_prim *prim ) { GLuint flag; flag = prim->mode; if (prim->begin) flag |= PRIM_BEGIN; if (prim->end) flag |= PRIM_END; return flag; } /** * Contains the current state of a running pipeline. */ struct vertex_buffer { GLuint Size; /**< Max vertices per vertex buffer, constant */ /* Constant over the pipeline. */ GLuint Count; /**< Number of vertices currently in buffer */ /* Pointers to current data. Most of the data is in AttribPtr -- all of * it that is one of VERT_ATTRIB_X. For things only produced by TNL, * such as backface color or eye-space coordinates, they are stored * here. */ GLuint *Elts; GLvector4f *EyePtr; /* _TNL_BIT_POS */ GLvector4f *ClipPtr; /* _TNL_BIT_POS */ GLvector4f *NdcPtr; /* _TNL_BIT_POS */ GLubyte ClipOrMask; /* _TNL_BIT_POS */ GLubyte ClipAndMask; /* _TNL_BIT_POS */ GLubyte *ClipMask; /* _TNL_BIT_POS */ GLfloat *NormalLengthPtr; /* _TNL_BIT_NORMAL */ GLboolean *EdgeFlag; /* _TNL_BIT_EDGEFLAG */ GLvector4f *BackfaceIndexPtr; GLvector4f *BackfaceColorPtr; GLvector4f *BackfaceSecondaryColorPtr; const struct _mesa_prim *Primitive; GLuint PrimitiveCount; /* Inputs to the vertex program stage */ GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; /* GL_NV_vertex_program */ }; /** * Describes an individual operation on the pipeline. */ struct tnl_pipeline_stage { const char *name; /* Private data for the pipeline stage: */ void *privatePtr; /* Allocate private data */ GLboolean (*create)( struct gl_context *ctx, struct tnl_pipeline_stage * ); /* Free private data. */ void (*destroy)( struct tnl_pipeline_stage * ); /* Called on any statechange or input array size change or * input array change to/from zero stride. */ void (*validate)( struct gl_context *ctx, struct tnl_pipeline_stage * ); /* Called from _tnl_run_pipeline(). The stage.changed_inputs value * encodes all inputs to thee struct which have changed. If * non-zero, recompute all affected outputs of the stage, otherwise * execute any 'sideeffects' of the stage. * * Return value: GL_TRUE - keep going * GL_FALSE - finished pipeline */ GLboolean (*run)( struct gl_context *ctx, struct tnl_pipeline_stage * ); }; /** Contains the array of all pipeline stages. * The default values are defined at the end of t_pipeline.c */ struct tnl_pipeline { GLuint last_attrib_stride[_TNL_ATTRIB_MAX]; GLuint last_attrib_size[_TNL_ATTRIB_MAX]; GLuint input_changes; GLuint new_state; struct tnl_pipeline_stage stages[MAX_PIPELINE_STAGES+1]; GLuint nr_stages; }; struct tnl_clipspace; struct tnl_clipspace_attr; typedef void (*tnl_extract_func)( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ); typedef void (*tnl_insert_func)( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ); typedef void (*tnl_emit_func)( struct gl_context *ctx, GLuint count, GLubyte *dest ); /** * Describes how to convert/move a vertex attribute from a vertex array * to a vertex structure. */ struct tnl_clipspace_attr { GLuint attrib; /* which vertex attrib (0=position, etc) */ GLuint format; GLuint vertoffset; /* position of the attrib in the vertex struct */ GLuint vertattrsize; /* size of the attribute in bytes */ GLubyte *inputptr; GLuint inputstride; GLuint inputsize; const tnl_insert_func *insert; tnl_insert_func emit; tnl_extract_func extract; const GLfloat *vp; /* NDC->Viewport mapping matrix */ }; typedef void (*tnl_points_func)( struct gl_context *ctx, GLuint first, GLuint last ); typedef void (*tnl_line_func)( struct gl_context *ctx, GLuint v1, GLuint v2 ); typedef void (*tnl_triangle_func)( struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3 ); typedef void (*tnl_quad_func)( struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4 ); typedef void (*tnl_render_func)( struct gl_context *ctx, GLuint start, GLuint count, GLuint flags ); typedef void (*tnl_interp_func)( struct gl_context *ctx, GLfloat t, GLuint dst, GLuint out, GLuint in, GLboolean force_boundary ); typedef void (*tnl_copy_pv_func)( struct gl_context *ctx, GLuint dst, GLuint src ); typedef void (*tnl_setup_func)( struct gl_context *ctx, GLuint start, GLuint end, GLuint new_inputs); struct tnl_attr_type { GLuint format; GLuint size; GLuint stride; GLuint offset; }; struct tnl_clipspace_fastpath { GLuint vertex_size; GLuint attr_count; GLboolean match_strides; struct tnl_attr_type *attr; tnl_emit_func func; struct tnl_clipspace_fastpath *next; }; /** * Used to describe conversion of vertex arrays to vertex structures. * I.e. Structure of arrays to arrays of structs. */ struct tnl_clipspace { GLboolean need_extras; GLuint new_inputs; GLubyte *vertex_buf; GLuint vertex_size; GLuint max_vertex_size; struct tnl_clipspace_attr attr[_TNL_ATTRIB_MAX]; GLuint attr_count; tnl_emit_func emit; tnl_interp_func interp; tnl_copy_pv_func copy_pv; /* Parameters and constants for codegen: */ GLboolean need_viewport; GLfloat vp_scale[4]; GLfloat vp_xlate[4]; GLfloat chan_scale[4]; GLfloat identity[4]; struct tnl_clipspace_fastpath *fastpath; void (*codegen_emit)( struct gl_context *ctx ); }; #define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */ /** * Material shininess lookup table. */ struct tnl_shine_tab { struct tnl_shine_tab *next, *prev; GLfloat tab[SHINE_TABLE_SIZE+1]; GLfloat shininess; GLuint refcount; }; struct tnl_device_driver { /*** *** TNL Pipeline ***/ void (*RunPipeline)(struct gl_context *ctx); /* Replaces PipelineStart/PipelineFinish -- intended to allow * drivers to wrap _tnl_run_pipeline() with code to validate state * and grab/release hardware locks. */ void (*NotifyMaterialChange)(struct gl_context *ctx); /* Alert tnl-aware drivers of changes to material. */ /*** *** Rendering -- These functions called only from t_vb_render.c ***/ struct { void (*Start)(struct gl_context *ctx); void (*Finish)(struct gl_context *ctx); /* Called before and after all rendering operations, including DrawPixels, * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands. * These are a suitable place for grabbing/releasing hardware locks. */ void (*PrimitiveNotify)(struct gl_context *ctx, GLenum mode); /* Called between RenderStart() and RenderFinish() to indicate the * type of primitive we're about to draw. Mode will be one of the * modes accepted by glBegin(). */ tnl_interp_func Interp; /* The interp function is called by the clipping routines when we need * to generate an interpolated vertex. All pertinant vertex ancilliary * data should be computed by interpolating between the 'in' and 'out' * vertices. */ tnl_copy_pv_func CopyPV; /* The copy function is used to make a copy of a vertex. All pertinant * vertex attributes should be copied. */ void (*ClippedPolygon)( struct gl_context *ctx, const GLuint *elts, GLuint n ); /* Render a polygon with <n> vertices whose indexes are in the <elts> * array. */ void (*ClippedLine)( struct gl_context *ctx, GLuint v0, GLuint v1 ); /* Render a line between the two vertices given by indexes v0 and v1. */ tnl_points_func Points; /* must now respect vb->elts */ tnl_line_func Line; tnl_triangle_func Triangle; tnl_quad_func Quad; /* These functions are called in order to render points, lines, * triangles and quads. These are only called via the T&L module. */ tnl_render_func *PrimTabVerts; tnl_render_func *PrimTabElts; /* Render whole unclipped primitives (points, lines, linestrips, * lineloops, etc). The tables are indexed by the GL enum of the * primitive to be rendered. RenderTabVerts is used for non-indexed * arrays of vertices. RenderTabElts is used for indexed arrays of * vertices. */ void (*ResetLineStipple)( struct gl_context *ctx ); /* Reset the hardware's line stipple counter. */ tnl_setup_func BuildVertices; /* This function is called whenever new vertices are required for * rendering. The vertices in question are those n such that start * <= n < end. The new_inputs parameter indicates those fields of * the vertex which need to be updated, if only a partial repair of * the vertex is required. * * This function is called only from _tnl_render_stage in tnl/t_render.c. */ GLboolean (*Multipass)( struct gl_context *ctx, GLuint passno ); /* Driver may request additional render passes by returning GL_TRUE * when this function is called. This function will be called * after the first pass, and passes will be made until the function * returns GL_FALSE. If no function is registered, only one pass * is made. * * This function will be first invoked with passno == 1. */ } Render; }; /** * Context state for T&L context. */ typedef struct { /* Driver interface. */ struct tnl_device_driver Driver; /* Pipeline */ struct tnl_pipeline pipeline; struct vertex_buffer vb; /* Clipspace/ndc/window vertex managment: */ struct tnl_clipspace clipspace; /* Probably need a better configuration mechanism: */ GLboolean NeedNdcCoords; GLboolean AllowVertexFog; GLboolean AllowPixelFog; GLboolean _DoVertexFog; /* eval fog function at each vertex? */ GLbitfield64 render_inputs_bitset; GLvector4f tmp_inputs[VERT_ATTRIB_MAX]; /* Temp storage for t_draw.c: */ GLubyte *block[VERT_ATTRIB_MAX]; GLuint nr_blocks; GLuint CurInstance; struct tnl_shine_tab *_ShineTable[2]; /**< Active shine tables */ struct tnl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ /**@}*/ } TNLcontext; #define TNL_CONTEXT(ctx) ((TNLcontext *)((ctx)->swtnl_context)) #define TYPE_IDX(t) ((t) & 0xf) #define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ extern void tnl_clip_prepare(struct gl_context *ctx); #endif