Files
third_party_mesa3d/src/mesa/tnl/t_context.h
2000-11-20 13:39:36 +00:00

630 lines
18 KiB
C

/* $Id: t_context.h,v 1.2 2000/11/20 13:39:36 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 { \
ctx->swtnl_im = (void *)im; \
_mesa_CurrentInput = im; \
} while (0)
#endif
#endif