aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/tnl/t_context.h
blob: ebaae6335b942d906bacce86ae0dc9ac08d21a50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
/*
 * 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/bitset.h"
#include "main/mtypes.h"

#include "math/m_matrix.h"
#include "math/m_vector.h"
#include "math/m_xform.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 = 16, /* doesn't really exist! */
	_TNL_ATTRIB_GENERIC1 = 17,
	_TNL_ATTRIB_GENERIC2 = 18,
	_TNL_ATTRIB_GENERIC3 = 19,
	_TNL_ATTRIB_GENERIC4 = 20,
	_TNL_ATTRIB_GENERIC5 = 21,
	_TNL_ATTRIB_GENERIC6 = 22,
	_TNL_ATTRIB_GENERIC7 = 23,
	_TNL_ATTRIB_GENERIC8 = 24,
	_TNL_ATTRIB_GENERIC9 = 25,
	_TNL_ATTRIB_GENERIC10 = 26,
	_TNL_ATTRIB_GENERIC11 = 27,
	_TNL_ATTRIB_GENERIC12 = 28,
	_TNL_ATTRIB_GENERIC13 = 29,
	_TNL_ATTRIB_GENERIC14 = 30,
	_TNL_ATTRIB_GENERIC15 = 31,

	/* 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 = 16,
	_TNL_ATTRIB_MAT_BACK_AMBIENT = 17,
	_TNL_ATTRIB_MAT_FRONT_DIFFUSE = 18,
	_TNL_ATTRIB_MAT_BACK_DIFFUSE = 19,
	_TNL_ATTRIB_MAT_FRONT_SPECULAR = 20,
	_TNL_ATTRIB_MAT_BACK_SPECULAR = 21,
	_TNL_ATTRIB_MAT_FRONT_EMISSION = 22,
	_TNL_ATTRIB_MAT_BACK_EMISSION = 23,
	_TNL_ATTRIB_MAT_FRONT_SHININESS = 24,
	_TNL_ATTRIB_MAT_BACK_SHININESS = 25,
	_TNL_ATTRIB_MAT_FRONT_INDEXES = 26,
	_TNL_ATTRIB_MAT_BACK_INDEXES = 27,

	/* This is really a VERT_RESULT, not an attrib.  Need to fix
	 * tnl to understand the difference.
	 */
	_TNL_ATTRIB_POINTSIZE = 16,

	_TNL_ATTRIB_MAX = 32
} ;

#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 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)( GLcontext *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)( GLcontext *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)( GLcontext *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)( GLcontext *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)( GLcontext *ctx, GLuint first, GLuint last );
typedef void (*tnl_line_func)( GLcontext *ctx, GLuint v1, GLuint v2 );
typedef void (*tnl_triangle_func)( GLcontext *ctx,
				   GLuint v1, GLuint v2, GLuint v3 );
typedef void (*tnl_quad_func)( GLcontext *ctx, GLuint v1, GLuint v2,
			       GLuint v3, GLuint v4 );
typedef void (*tnl_render_func)( GLcontext *ctx, GLuint start, GLuint count,
				 GLuint flags );
typedef void (*tnl_interp_func)( GLcontext *ctx,
				 GLfloat t, GLuint dst, GLuint out, GLuint in,
				 GLboolean force_boundary );
typedef void (*tnl_copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
typedef void (*tnl_setup_func)( GLcontext *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)( GLcontext *ctx );
};


struct tnl_device_driver
{
   /***
    *** TNL Pipeline
    ***/

   void (*RunPipeline)(GLcontext *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)(GLcontext *ctx);
   /* Alert tnl-aware drivers of changes to material.
    */

   /***
    *** Rendering -- These functions called only from t_vb_render.c
    ***/
   struct
   {
      void (*Start)(GLcontext *ctx);
      void (*Finish)(GLcontext *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)(GLcontext *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)( GLcontext *ctx, const GLuint *elts, GLuint n );
      /* Render a polygon with <n> vertices whose indexes are in the <elts>
       * array.
       */

      void (*ClippedLine)( GLcontext *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)( GLcontext *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)( GLcontext *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;
};


#define DECLARE_RENDERINPUTS(name) BITSET64_DECLARE(name, _TNL_ATTRIB_MAX)
#define RENDERINPUTS_COPY BITSET64_COPY
#define RENDERINPUTS_EQUAL BITSET64_EQUAL
#define RENDERINPUTS_ZERO BITSET64_ZERO
#define RENDERINPUTS_ONES BITSET64_ONES
#define RENDERINPUTS_TEST BITSET64_TEST
#define RENDERINPUTS_SET BITSET64_SET
#define RENDERINPUTS_CLEAR BITSET64_CLEAR
#define RENDERINPUTS_TEST_RANGE BITSET64_TEST_RANGE
#define RENDERINPUTS_SET_RANGE BITSET64_SET_RANGE
#define RENDERINPUTS_CLEAR_RANGE BITSET64_CLEAR_RANGE


/**
 * 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? */

   DECLARE_RENDERINPUTS(render_inputs_bitset);

   GLvector4f tmp_inputs[VERT_ATTRIB_MAX];

   /* Temp storage for t_draw.c: 
    */
   GLubyte *block[VERT_ATTRIB_MAX];
   GLuint nr_blocks;

} 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(GLcontext *ctx);


#endif