blob: e90e21ba09bf74597021bfc7e08339d84ac54652 [file] [log] [blame]
Keith Whitwell23caf202000-11-16 21:05:34 +00001
2/*
3 * Mesa 3-D graphics library
Brian Paul27558a12003-03-01 01:50:20 +00004 * Version: 5.1
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00005 *
Brian Paul27558a12003-03-01 01:50:20 +00006 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00007 *
Keith Whitwell23caf202000-11-16 21:05:34 +00008 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000014 *
Keith Whitwell23caf202000-11-16 21:05:34 +000015 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000017 *
Keith Whitwell23caf202000-11-16 21:05:34 +000018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Keith Whitwellcab974c2000-12-26 05:09:27 +000024 *
Gareth Hughes22144ab2001-03-12 00:48:37 +000025 * Authors:
Brian Paul05a4b372002-10-29 20:28:36 +000026 * Keith Whitwell <keith@tungstengraphics.com>
Keith Whitwell23caf202000-11-16 21:05:34 +000027 */
28
29#include "glheader.h"
30#include "context.h"
Brian Paul3c634522002-10-24 23:57:19 +000031#include "imports.h"
Keith Whitwell23caf202000-11-16 21:05:34 +000032#include "state.h"
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000033#include "mtypes.h"
Keith Whitwell23caf202000-11-16 21:05:34 +000034
35#include "math/m_translate.h"
36#include "math/m_xform.h"
37
Keith Whitwellcab974c2000-12-26 05:09:27 +000038#include "t_context.h"
Keith Whitwell23caf202000-11-16 21:05:34 +000039#include "t_pipeline.h"
Keith Whitwell23caf202000-11-16 21:05:34 +000040
41
Gareth Hughes22144ab2001-03-12 00:48:37 +000042void _tnl_install_pipeline( GLcontext *ctx,
Keith Whitwellae0eaf92003-11-24 15:23:18 +000043 const struct tnl_pipeline_stage **stages )
Keith Whitwell23caf202000-11-16 21:05:34 +000044{
Keith Whitwell23caf202000-11-16 21:05:34 +000045 TNLcontext *tnl = TNL_CONTEXT(ctx);
Keith Whitwellae0eaf92003-11-24 15:23:18 +000046 struct tnl_pipeline *pipe = &tnl->pipeline;
Keith Whitwell23caf202000-11-16 21:05:34 +000047 GLuint i;
Keith Whitwell23caf202000-11-16 21:05:34 +000048
Keith Whitwellcab974c2000-12-26 05:09:27 +000049 ASSERT(pipe->nr_stages == 0);
Keith Whitwell23caf202000-11-16 21:05:34 +000050
Keith Whitwellcab974c2000-12-26 05:09:27 +000051 pipe->run_state_changes = ~0;
52 pipe->run_input_changes = ~0;
53 pipe->build_state_changes = ~0;
54 pipe->build_state_trigger = 0;
55 pipe->inputs = 0;
Keith Whitwell23caf202000-11-16 21:05:34 +000056
Keith Whitwellcab974c2000-12-26 05:09:27 +000057 /* Create a writeable copy of each stage.
Keith Whitwell23caf202000-11-16 21:05:34 +000058 */
Keith Whitwellcab974c2000-12-26 05:09:27 +000059 for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) {
60 MEMCPY( &pipe->stages[i], stages[i], sizeof( **stages ));
61 pipe->build_state_trigger |= pipe->stages[i].check_state;
Keith Whitwell23caf202000-11-16 21:05:34 +000062 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000063
Keith Whitwell7954a0c2001-05-10 12:18:38 +000064 MEMSET( &pipe->stages[i], 0, sizeof( **stages ));
65
Keith Whitwellcab974c2000-12-26 05:09:27 +000066 pipe->nr_stages = i;
67}
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000068
Keith Whitwellcab974c2000-12-26 05:09:27 +000069void _tnl_destroy_pipeline( GLcontext *ctx )
70{
71 TNLcontext *tnl = TNL_CONTEXT(ctx);
72 GLuint i;
73
Gareth Hughes22144ab2001-03-12 00:48:37 +000074 for (i = 0 ; i < tnl->pipeline.nr_stages ; i++)
Keith Whitwellcab974c2000-12-26 05:09:27 +000075 tnl->pipeline.stages[i].destroy( &tnl->pipeline.stages[i] );
76
77 tnl->pipeline.nr_stages = 0;
78}
79
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +000080/* TODO: merge validate with run.
81 */
Keith Whitwellcab974c2000-12-26 05:09:27 +000082void _tnl_validate_pipeline( GLcontext *ctx )
83{
84 TNLcontext *tnl = TNL_CONTEXT(ctx);
Keith Whitwellae0eaf92003-11-24 15:23:18 +000085 struct tnl_pipeline *pipe = &tnl->pipeline;
86 struct tnl_pipeline_stage *s = pipe->stages;
Keith Whitwellcab974c2000-12-26 05:09:27 +000087 GLuint newstate = pipe->build_state_changes;
88 GLuint generated = 0;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +000089 GLuint changed_inputs = 0;
Keith Whitwellcab974c2000-12-26 05:09:27 +000090
91 pipe->inputs = 0;
92 pipe->build_state_changes = 0;
93
Keith Whitwell7954a0c2001-05-10 12:18:38 +000094 for ( ; s->check ; s++) {
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +000095
96 s->changed_inputs |= s->inputs & changed_inputs;
Gareth Hughes22144ab2001-03-12 00:48:37 +000097
98 if (s->check_state & newstate) {
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +000099 if (s->active) {
100 GLuint old_outputs = s->outputs;
101 s->check(ctx, s);
102 if (!s->active)
103 changed_inputs |= old_outputs;
104 }
Gareth Hughes22144ab2001-03-12 00:48:37 +0000105 else
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000106 s->check(ctx, s);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000107 }
108
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000109 if (s->active) {
110 pipe->inputs |= s->inputs & ~generated;
111 generated |= s->outputs;
Gareth Hughes22144ab2001-03-12 00:48:37 +0000112 }
Keith Whitwellcab974c2000-12-26 05:09:27 +0000113 }
114}
115
116
117
Keith Whitwellcab974c2000-12-26 05:09:27 +0000118void _tnl_run_pipeline( GLcontext *ctx )
119{
120 TNLcontext *tnl = TNL_CONTEXT(ctx);
Keith Whitwellae0eaf92003-11-24 15:23:18 +0000121 struct tnl_pipeline *pipe = &tnl->pipeline;
122 struct tnl_pipeline_stage *s = pipe->stages;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000123 GLuint changed_state = pipe->run_state_changes;
124 GLuint changed_inputs = pipe->run_input_changes;
125 GLboolean running = GL_TRUE;
Brian Paulb3050282003-12-04 03:19:46 +0000126#ifdef HAVE_FAST_MATH
Keith Whitwellcab974c2000-12-26 05:09:27 +0000127 unsigned short __tmp;
Brian Paulb3050282003-12-04 03:19:46 +0000128#endif
Keith Whitwellcab974c2000-12-26 05:09:27 +0000129
Keith Whitwell79073402004-01-05 09:43:42 +0000130 if (!tnl->vb.Count)
131 return;
132
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000133 pipe->run_state_changes = 0;
134 pipe->run_input_changes = 0;
135
Keith Whitwellcab974c2000-12-26 05:09:27 +0000136 /* Done elsewhere.
137 */
138 ASSERT(pipe->build_state_changes == 0);
Gareth Hughese7e38a42001-05-21 16:33:41 +0000139
Brian Paulb3050282003-12-04 03:19:46 +0000140#ifdef HAVE_FAST_MATH
Keith Whitwellcab974c2000-12-26 05:09:27 +0000141 START_FAST_MATH(__tmp);
Brian Paulb3050282003-12-04 03:19:46 +0000142#endif
Keith Whitwell23caf202000-11-16 21:05:34 +0000143
144 /* If something changes in the pipeline, tag all subsequent stages
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000145 * using this value for recalculation. Inactive stages have their
146 * state and inputs examined to try to keep cached data alive over
Gareth Hughese7e38a42001-05-21 16:33:41 +0000147 * state-changes.
Keith Whitwell23caf202000-11-16 21:05:34 +0000148 */
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000149 for ( ; s->run ; s++) {
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000150 s->changed_inputs |= s->inputs & changed_inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000151
Gareth Hughese7e38a42001-05-21 16:33:41 +0000152 if (s->run_state & changed_state)
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000153 s->changed_inputs = s->inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000154
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000155 if (s->active && running) {
156 if (s->changed_inputs)
157 changed_inputs |= s->outputs;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000158
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000159 running = s->run( ctx, s );
Keith Whitwell16837e42001-04-30 09:04:00 +0000160
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000161 s->changed_inputs = 0;
Keith Whitwell23caf202000-11-16 21:05:34 +0000162 }
163 }
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000164
Brian Paulb3050282003-12-04 03:19:46 +0000165#ifdef HAVE_FAST_MATH
Keith Whitwellcab974c2000-12-26 05:09:27 +0000166 END_FAST_MATH(__tmp);
Brian Paulb3050282003-12-04 03:19:46 +0000167#endif
Keith Whitwell23caf202000-11-16 21:05:34 +0000168}
169
170
171
Keith Whitwellcab974c2000-12-26 05:09:27 +0000172/* The default pipeline. This is useful for software rasterizers, and
173 * simple hardware rasterizers. For customization, I don't recommend
174 * tampering with the internals of these stages in the way that
175 * drivers did in Mesa 3.4. These stages are basically black boxes,
Gareth Hughes22144ab2001-03-12 00:48:37 +0000176 * and should be left intact.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000177 *
Gareth Hughes22144ab2001-03-12 00:48:37 +0000178 * To customize the pipeline, consider:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000179 *
180 * - removing redundant stages (making sure that the software rasterizer
181 * can cope with this on fallback paths). An example is fog
182 * coordinate generation, which is not required in the FX driver.
183 *
184 * - replacing general-purpose machine-independent stages with
185 * general-purpose machine-specific stages. There is no example of
186 * this to date, though it must be borne in mind that all subsequent
187 * stages that reference the output of the new stage must cope with
188 * any machine-specific data introduced. This may not be easy
189 * unless there are no such stages (ie the new stage is the last in
190 * the pipe).
191 *
192 * - inserting optimized (but specialized) stages ahead of the
193 * general-purpose fallback implementation. For example, the old
Keith Whitwellae0eaf92003-11-24 15:23:18 +0000194 * fastpath mechanism, which only works when the VB->Elts input is
Keith Whitwellcab974c2000-12-26 05:09:27 +0000195 * available, can be duplicated by placing the fastpath stage at the
196 * head of this pipeline. Such specialized stages are currently
197 * constrained to have no outputs (ie. they must either finish the *
198 * pipeline by returning GL_FALSE from run(), or do nothing).
199 *
200 * Some work can be done to lift some of the restrictions in the final
Gareth Hughes22144ab2001-03-12 00:48:37 +0000201 * case, if it becomes necessary to do so.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000202 */
Keith Whitwellae0eaf92003-11-24 15:23:18 +0000203const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
Gareth Hughes22144ab2001-03-12 00:48:37 +0000204 &_tnl_vertex_transform_stage,
205 &_tnl_normal_transform_stage,
206 &_tnl_lighting_stage,
207 &_tnl_fog_coordinate_stage,
208 &_tnl_texgen_stage,
209 &_tnl_texture_transform_stage,
210 &_tnl_point_attenuation_stage,
Brian Paul1e71d2a2004-01-31 19:49:10 +0000211#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
Brian Paul86b84272001-12-14 02:50:01 +0000212 &_tnl_vertex_program_stage,
Brian Paul8dfc5b92002-10-16 17:57:51 +0000213#endif
Keith Whitwellcab974c2000-12-26 05:09:27 +0000214 &_tnl_render_stage,
215 0
216};