diff options
author | Keith Whitwell <[email protected]> | 2000-11-16 21:05:34 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2000-11-16 21:05:34 +0000 |
commit | 23caf20169ac38436ee9c13914f1d6aa7cf6bb5e (patch) | |
tree | 21307f7bbcaf9ee1e841d7e7bee130570a7b5b95 /src/mesa/tnl/t_context.h | |
parent | 179516673211a2350e479d5321840291f339f5dd (diff) |
Move the transform and lighting code to two new directories
math: Provides basic matrix and vector functionality that
might be useful to multiple software t&l
implementations, and is used by core mesa to
manage the Model, Project, etc matrices.
tnl: The real transform & lighting code from core mesa,
including everything from glVertex3f through vertex
buffer handling, transformation, clipping, lighting
and handoff to a driver for rasterization.
The interfaces of these can be further tightened up, but the basic
splitting up of state and code move is done.
Diffstat (limited to 'src/mesa/tnl/t_context.h')
-rw-r--r-- | src/mesa/tnl/t_context.h | 629 |
1 files changed, 629 insertions, 0 deletions
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h new file mode 100644 index 00000000000..992c2a58f9b --- /dev/null +++ b/src/mesa/tnl/t_context.h @@ -0,0 +1,629 @@ + +/* $Id: t_context.h,v 1.1 2000/11/16 21:05:42 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 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. + */ + +#ifndef _T_CONTEXT_H +#define _T_CONTEXT_H + +#include "glheader.h" +#include "types.h" + +#include "math/m_matrix.h" +#include "math/m_vector.h" +#include "math/m_xform.h" + +#include "t_trans_elt.h" + + + +/* + * Bits to indicate which faces a vertex participates in, + * what facing the primitive provoked by that vertex has, + * and some misc. flags. + */ +#define VERT_FACE_FRONT 0x1 /* is in a front-color primitive */ +#define VERT_FACE_REAR 0x2 /* is in a rear-color primitive */ +#define PRIM_FACE_FRONT 0x4 /* use front color */ +#define PRIM_FACE_REAR 0x8 /* use rear color */ +#define PRIM_CLIPPED 0x10 /* needs clipping */ +#define PRIM_USER_CLIPPED CLIP_USER_BIT /* 0x40 */ + + +#define PRIM_FLAG_SHIFT 2 +#define PRIM_FACE_FLAGS (PRIM_FACE_FRONT|PRIM_FACE_REAR) +#define VERT_FACE_FLAGS (VERT_FACE_FRONT|VERT_FACE_REAR) + +#define PRIM_ANY_CLIP (PRIM_CLIPPED|PRIM_USER_CLIPPED) +#define PRIM_NOT_CULLED (PRIM_ANY_CLIP|PRIM_FACE_FLAGS) + +/* Flags for VB->CullMode. + */ +#define CULL_MASK_ACTIVE 0x1 +#define COMPACTED_NORMALS 0x2 +#define CLIP_MASK_ACTIVE 0x4 + +/* Flags for selecting a shading function. The first two bits are + * shared with the cull mode (ie. cull_mask_active and + * compacted_normals.) + */ +#define SHADE_TWOSIDE 0x4 + + +/* KW: Flags that describe the current vertex state, and the contents + * of a vertex in a vertex-cassette. + * + * For really major expansion, consider a 'VERT_ADDITIONAL_FLAGS' flag, + * which means there is data in another flags array (eg, extra_flags[]). + */ + +#define VERT_OBJ_2 0x1 /* glVertex2 */ +#define VERT_OBJ_3 0x2 /* glVertex3 */ +#define VERT_OBJ_4 0x4 /* glVertex4 */ +#define VERT_BEGIN 0x8 /* glBegin */ +#define VERT_END 0x10 /* glEnd */ +#define VERT_ELT 0x20 /* glArrayElement */ +#define VERT_RGBA 0x40 /* glColor */ +#define VERT_NORM 0x80 /* glNormal */ +#define VERT_INDEX 0x100 /* glIndex */ +#define VERT_EDGE 0x200 /* glEdgeFlag */ +#define VERT_MATERIAL 0x400 /* glMaterial */ +#define VERT_END_VB 0x800 /* end vb marker */ +#define VERT_TEX0_12 0x1000 +#define VERT_TEX0_3 0x2000 +#define VERT_TEX0_4 0x4000 +#define VERT_TEX1_12 0x8000 +#define VERT_TEX1_3 0x10000 +#define VERT_TEX1_4 0x20000 +#define VERT_TEX2_12 0x40000 +#define VERT_TEX2_3 0x80000 +#define VERT_TEX2_4 0x100000 +#define VERT_TEX3_12 0x200000 +#define VERT_TEX3_3 0x400000 +#define VERT_TEX3_4 0x800000 +#define VERT_EVAL_C1 0x1000000 /* could reuse OBJ bits for this? */ +#define VERT_EVAL_C2 0x2000000 /* - or just use 3 bits */ +#define VERT_EVAL_P1 0x4000000 /* */ +#define VERT_EVAL_P2 0x8000000 /* */ +#define VERT_SPEC_RGB 0x10000000 +#define VERT_FOG_COORD 0x20000000 /* internal use only, currently */ + +#define VERT_EYE VERT_BEGIN /* reuse */ +#define VERT_WIN VERT_END /* reuse */ +#define VERT_SETUP_FULL VERT_EVAL_P1 /* Rastersetup has been done */ +#define VERT_PRECALC_DATA VERT_END_VB /* reuse */ + +/* Shorthands. + */ +#define VERT_TEX0_SHIFT 11 + +#define VERT_EVAL_ANY (VERT_EVAL_C1|VERT_EVAL_P1| \ + VERT_EVAL_C2|VERT_EVAL_P2) + +#define VERT_OBJ_23 (VERT_OBJ_3|VERT_OBJ_2) +#define VERT_OBJ_234 (VERT_OBJ_4|VERT_OBJ_23) +#define VERT_OBJ_ANY VERT_OBJ_2 + +#define VERT_TEX0_123 (VERT_TEX0_3|VERT_TEX0_12) +#define VERT_TEX0_1234 (VERT_TEX0_4|VERT_TEX0_123) +#define VERT_TEX0_ANY VERT_TEX0_12 + +#define VERT_TEX1_123 (VERT_TEX1_3|VERT_TEX1_12) +#define VERT_TEX1_1234 (VERT_TEX1_4|VERT_TEX1_123) +#define VERT_TEX1_ANY VERT_TEX1_12 + +#define VERT_TEX2_123 (VERT_TEX2_3|VERT_TEX2_12) +#define VERT_TEX2_1234 (VERT_TEX2_4|VERT_TEX2_123) +#define VERT_TEX2_ANY VERT_TEX2_12 + +#define VERT_TEX3_123 (VERT_TEX3_3|VERT_TEX3_12) +#define VERT_TEX3_1234 (VERT_TEX3_4|VERT_TEX3_123) +#define VERT_TEX3_ANY VERT_TEX3_12 + +#define NR_TEXSIZE_BITS 3 +#define VERT_TEX_ANY(i) (VERT_TEX0_ANY << ((i) * NR_TEXSIZE_BITS)) + +#define VERT_FIXUP (VERT_TEX0_ANY | \ + VERT_TEX1_ANY | \ + VERT_TEX2_ANY | \ + VERT_TEX3_ANY | \ + VERT_RGBA | \ + VERT_SPEC_RGB | \ + VERT_FOG_COORD | \ + VERT_INDEX | \ + VERT_EDGE | \ + VERT_NORM) + +#define VERT_DATA (VERT_TEX0_ANY | \ + VERT_TEX1_ANY | \ + VERT_TEX2_ANY | \ + VERT_TEX3_ANY | \ + VERT_RGBA | \ + VERT_SPEC_RGB | \ + VERT_FOG_COORD | \ + VERT_INDEX | \ + VERT_EDGE | \ + VERT_NORM | \ + VERT_OBJ_ANY | \ + VERT_MATERIAL | \ + VERT_ELT | \ + VERT_EVAL_ANY | \ + VERT_FOG_COORD) + + +/* For beginstate + */ +#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */ +#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */ +#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */ +#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */ + + +struct gl_pipeline; +struct tnl_context; + +/** + ** Vertex buffer/array structures + **/ + +struct vertex_data +{ + GLfloat (*Obj)[4]; + GLfloat (*Normal)[3]; + GLchan (*Color)[4]; + GLuint *Index; + GLubyte *EdgeFlag; + GLfloat (*TexCoord[MAX_TEXTURE_UNITS])[4]; + GLuint *Elt; + GLfloat *FogCoord; + GLubyte (*SecondaryColor)[4]; +}; + +struct vertex_arrays +{ + GLvector4f Obj; + GLvector3f Normal; + GLvector4ub Color; + GLvector1ui Index; + GLvector1ub EdgeFlag; + GLvector4f TexCoord[MAX_TEXTURE_UNITS]; + GLvector1ui Elt; + GLvector4ub SecondaryColor; + GLvector1f FogCoord; +}; + +struct vertex_array_pointers +{ + GLvector4f *Obj; + GLvector3f *Normal; + GLvector4ub *Color; + GLvector1ui *Index; + GLvector1ub *EdgeFlag; + GLvector4f *TexCoord[MAX_TEXTURE_UNITS]; + GLvector1ui *Elt; + GLvector4ub *SecondaryColor; + GLvector1f *FogCoord; +}; + +/* Values for VB->Type */ +enum { + VB_IMMEDIATE, + VB_CVA_PRECALC +}; + + +/* Values for immediate->BeginState */ +#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */ +#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */ +#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */ +#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */ + + +/* KW: Represents everything that can take place between a begin and + * end, and can represent multiple begin/end pairs. This plus *any* + * state variable (GLcontext) should be all you need to replay the + * represented begin/end pairs as if they took place in that state. + * + * Thus this is sufficient for both immediate and compiled modes, but + * we could/should throw some elements away for compiled mode if we + * know they were empty. + */ +struct immediate +{ + struct immediate *next; /* for cache of free IM's */ + GLuint id, ref_count; + + /* This must be saved when immediates are shared in display lists. + */ + GLuint Start, Count; + GLuint LastData; /* count or count+1 */ + GLuint AndFlag, OrFlag, BeginState; + GLuint LastPrimitive; + + GLuint ArrayAndFlags; /* precalc'ed for glArrayElt */ + GLuint ArrayIncr; + GLuint ArrayEltFlush; + GLuint FlushElt; + + GLuint TF1[MAX_TEXTURE_UNITS]; /* precalc'ed for glTexCoord */ + GLuint TF2[MAX_TEXTURE_UNITS]; + GLuint TF3[MAX_TEXTURE_UNITS]; + GLuint TF4[MAX_TEXTURE_UNITS]; + + GLuint Primitive[VB_SIZE]; /* GLubyte would do... */ + GLuint NextPrimitive[VB_SIZE]; + + /* allocate storage for these on demand: + */ + struct gl_material (*Material)[2]; + GLuint *MaterialMask; + + GLfloat (*TexCoordPtr[MAX_TEXTURE_UNITS])[4]; + + struct vertex_arrays v; + + struct __GLcontextRec *backref; + + /* Normal lengths, zero if not available. + */ + GLfloat *NormalLengths; + GLuint LastCalcedLength; + + GLuint Flag[VB_SIZE]; /* bitwise-OR of VERT_ flags */ + GLchan Color[VB_SIZE][4]; + GLfloat Obj[VB_SIZE][4]; + GLfloat Normal[VB_SIZE][3]; + GLfloat TexCoord[MAX_TEXTURE_UNITS][VB_SIZE][4]; + GLuint Elt[VB_SIZE]; + GLubyte EdgeFlag[VB_SIZE]; + GLuint Index[VB_SIZE]; + GLubyte SecondaryColor[VB_SIZE][4]; + GLfloat FogCoord[VB_SIZE]; +}; + + +/* Not so big on storage these days, although still has pointers to + * arrays used for temporary results. + */ +typedef struct vertex_buffer +{ + /* Backpointers. + */ + struct __GLcontextRec *ctx; + struct tnl_context *tnlctx; + + /* Driver_data is allocated in Driver.RegisterVB(), if required. + */ + void *driver_data; + + /* List of operations to process vertices in current state. + */ + struct gl_pipeline *pipeline; + + /* Temporary storage used by immediate mode functions and various + * operations in the pipeline. + */ + struct immediate *IM; + struct vertex_array_pointers store; + + /* Where to find outstanding untransformed vertices. + */ + struct immediate *prev_buffer; + + GLuint Type; /* Either VB_IMMEDIATE or VB_CVA_PRECALC */ + + GLuint Size, Start, Count; + GLuint Free, FirstFree; + GLuint CopyStart; + GLuint Parity, Ovf; + GLuint PurgeFlags; + GLuint IndirectCount; /* defaults to count */ + GLuint OrFlag, SavedOrFlag; + GLuint EarlyCull; + GLuint Culled, CullDone; + + /* Pointers to input data - default to buffers in 'im' above. + */ + GLvector4f *ObjPtr; + GLvector3f *NormalPtr; + GLvector4ub *ColorPtr; + GLvector1ui *IndexPtr; + GLvector1ub *EdgeFlagPtr; + GLvector4f *TexCoordPtr[MAX_TEXTURE_UNITS]; + GLvector1ui *EltPtr; + GLvector4ub *SecondaryColorPtr; + GLvector1f *FogCoordPtr; + GLuint *Flag, FlagMax; + struct gl_material (*Material)[2]; + GLuint *MaterialMask; + + GLuint *NextPrimitive; + GLuint *Primitive; + GLuint LastPrimitive; + + GLfloat (*BoundsPtr)[3]; /* Bounds for cull check */ + GLfloat *NormalLengthPtr; /* Array of precomputed inv. normal lengths */ + + /* Holds malloced storage for pipeline data not supplied by + * the immediate struct. + */ + GLvector4f Eye; + GLvector4f Clip; + GLvector4f Win; + GLvector4ub BColor; /* not used in cva vb's */ + GLvector1ui BIndex; /* not used in cva vb's */ + GLvector4ub BSecondary; /* not used in cva vb's */ + + /* Temporary storage - may point into IM, or be dynamically + * allocated (for cva). + */ + GLubyte *ClipMask; + GLubyte *UserClipMask; + + /* Internal values. Where these point depends on whether + * there were any identity matrices defined as transformations + * in the pipeline. + */ + GLvector4f *EyePtr; + GLvector4f *ClipPtr; + GLvector4f *Unprojected; + GLvector4f *Projected; + GLvector4f *CurrentTexCoord; + GLuint *Indirect; /* For eval rescue and cva render */ + + /* Currently active colors + */ + GLvector4ub *Color[2]; + GLvector1ui *Index[2]; + GLvector4ub *SecondaryColor[2]; + + /* Storage for colors which have been lit but not yet fogged. + * Required for CVA, just point into store for normal VB's. + */ + GLvector4ub *LitColor[2]; + GLvector1ui *LitIndex[2]; + GLvector4ub *LitSecondary[2]; + + /* Temporary values used in texgen. + */ + GLfloat (*tmp_f)[3]; + GLfloat *tmp_m; + + /* Temporary values used in eval. + */ + GLuint *EvaluatedFlags; + + /* Not used for cva: + */ + GLubyte *NormCullStart; + GLubyte *CullMask; /* Results of vertex culling */ + GLubyte *NormCullMask; /* Compressed onto shared normals */ + + GLubyte ClipOrMask; /* bitwise-OR of all ClipMask[] values */ + GLubyte ClipAndMask; /* bitwise-AND of all ClipMask[] values */ + GLubyte CullFlag[2]; + GLubyte CullMode; /* see flags below */ + + GLuint CopyCount; /* max 3 vertices to copy after transform */ + GLuint Copy[3]; + GLfloat CopyProj[3][4]; /* temporary store for projected clip coords */ + + /* Hooks for module private data + */ + void *swsetup_vb; + +} TNLvertexbuffer; + + +typedef void (*gl_shade_func)( struct vertex_buffer *VB ); + +typedef void (*clip_interp_func)( struct vertex_buffer *VB, GLuint dst, + GLfloat t, GLuint in, GLuint out ); + +typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, + GLuint *i, GLuint *j, + GLubyte mask); + +typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB, + GLuint n, GLuint vlist[], + GLubyte mask ); + + +#define MAX_PIPELINE_STAGES 30 + +#define PIPE_IMMEDIATE 0x1 +#define PIPE_PRECALC 0x2 + +#define PIPE_OP_VERT_XFORM 0x1 +#define PIPE_OP_NORM_XFORM 0x2 +#define PIPE_OP_LIGHT 0x4 +#define PIPE_OP_FOG 0x8 +#define PIPE_OP_TEX0 0x10 +#define PIPE_OP_TEX1 0x20 +#define PIPE_OP_TEX2 0x40 +#define PIPE_OP_TEX3 0x80 +#define PIPE_OP_RAST_SETUP_0 0x100 +#define PIPE_OP_RAST_SETUP_1 0x200 +#define PIPE_OP_RENDER 0x400 +#define PIPE_OP_CVA_PREPARE 0x800 + + + +struct gl_pipeline_stage { + const char *name; + GLuint ops; /* PIPE_OP flags */ + GLuint type; /* VERT flags */ + GLuint special; /* VERT flags - force update_inputs() */ + GLuint state_change; /* state flags - trigger update_inputs() */ + GLuint cva_state_change; /* state flags - recalc cva buffer */ + GLuint elt_forbidden_inputs; /* VERT flags - force a pipeline recalc */ + GLuint pre_forbidden_inputs; /* VERT flags - force a pipeline recalc */ + GLuint active; /* VERT flags */ + GLuint inputs; /* VERT flags */ + GLuint outputs; /* VERT flags */ + void (*check)( GLcontext *ctx, struct gl_pipeline_stage * ); + void (*run)( struct vertex_buffer *VB ); +}; + + +struct gl_pipeline { + GLuint state_change; /* state changes which require recalc */ + GLuint cva_state_change; /* ... which require re-run */ + GLuint forbidden_inputs; /* inputs which require recalc */ + GLuint ops; /* what gets done in this pipe */ + GLuint changed_ops; + GLuint inputs; + GLuint outputs; + GLuint new_inputs; + GLuint new_outputs; + GLuint fallback; + GLuint type; + GLuint pipeline_valid:1; + GLuint data_valid:1; + GLuint copy_transformed_data:1; + GLuint replay_copied_vertices:1; + GLuint new_state; /* state changes since last recalc */ + struct gl_pipeline_stage *stages[MAX_PIPELINE_STAGES]; +}; + + + +/* All fields are derived. + */ +struct gl_cva { + struct gl_pipeline pre; + struct gl_pipeline elt; + + struct gl_client_array Elt; + trans_1ui_func EltFunc; + + struct vertex_buffer *VB; + struct vertex_arrays v; + struct vertex_data store; + + GLuint elt_count; + GLenum elt_mode; + GLuint elt_size; + + GLuint forbidden_inputs; + GLuint orflag; + GLuint merge; + + GLuint lock_changed; + GLuint last_orflag; + GLuint last_array_flags; + GLuint last_array_new_state; +}; + + + +typedef void (*texgen_func)( struct vertex_buffer *VB, + GLuint textureSet); + + + +typedef struct tnl_context { + + GLuint _ArrayFlag[VB_SIZE]; /* crock */ + GLuint _ArrayFlags; + GLuint _ArraySummary; /* Like flags, but no size information */ + GLuint _ArrayNewState; /* Tracks which arrays have been changed. */ + + + /* Pipeline stages - shared between the two pipelines, + * which live in CVA. + */ + struct gl_pipeline_stage PipelineStage[MAX_PIPELINE_STAGES]; + GLuint NrPipelineStages; + + /* Per-texunit derived state. + */ + GLuint _TexgenSize[MAX_TEXTURE_UNITS]; + GLuint _TexgenHoles[MAX_TEXTURE_UNITS]; + texgen_func *_TexgenFunc[MAX_TEXTURE_UNITS]; + + + /* Display list extensions + */ + GLuint opcode_vertex_cassette; + + /* Cva + */ + struct gl_cva CVA; + GLboolean CompileCVAFlag; + + clip_poly_func *_poly_clip_tab; + clip_line_func *_line_clip_tab; + clip_interp_func _ClipInterpFunc; /* Clip interpolation function */ + normal_func *_NormalTransform; + gl_shade_func *_shade_func_tab; /* Current shading function table */ + + GLenum _CurrentPrimitive; /* Prim or GL_POLYGON+1 */ + GLuint _CurrentFlag; + + GLuint _RenderFlags; /* Active inputs to render stage */ + + /* Cache of unused immediate structs */ + struct immediate *freed_im_queue; + GLuint nr_im_queued; + +} TNLcontext; + + + +#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context)) +#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im)) +#define TNL_VB(ctx) ((struct vertex_buffer *)(ctx->swtnl_vb)) + +extern void _tnl_reset_immediate( GLcontext *ctx ); +extern GLboolean _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags ); + + +extern void +_tnl_MakeCurrent( GLcontext *ctx, + GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + + +extern void +_tnl_LightingSpaceChange( GLcontext *ctx ); + +/* + * Macros for fetching current input buffer. + */ +#ifdef THREADS +#define GET_IMMEDIATE struct immediate *IM = TNL_CURRENT_IM(((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()))) +#define SET_IMMEDIATE(ctx, im) ctx->swtnl_im = (void *)im +#else +extern struct immediate *_mesa_CurrentInput; +#define GET_IMMEDIATE struct immediate *IM = _mesa_CurrentInput +#define SET_IMMEDIATE(ctx, im) \ +do { \ + TNL_CURRENT_IM(ctx) = im; \ + _mesa_CurrentInput = im; \ +} while (0) +#endif + +#endif |