blob: 5e40309cd0dc120efbf8317989bbd2df373636c9 [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;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000126 unsigned short __tmp;
127
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000128 pipe->run_state_changes = 0;
129 pipe->run_input_changes = 0;
130
Keith Whitwellcab974c2000-12-26 05:09:27 +0000131 /* Done elsewhere.
132 */
133 ASSERT(pipe->build_state_changes == 0);
Gareth Hughese7e38a42001-05-21 16:33:41 +0000134
Keith Whitwellcab974c2000-12-26 05:09:27 +0000135 START_FAST_MATH(__tmp);
Keith Whitwell23caf202000-11-16 21:05:34 +0000136
137 /* If something changes in the pipeline, tag all subsequent stages
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000138 * using this value for recalculation. Inactive stages have their
139 * state and inputs examined to try to keep cached data alive over
Gareth Hughese7e38a42001-05-21 16:33:41 +0000140 * state-changes.
Keith Whitwell23caf202000-11-16 21:05:34 +0000141 */
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000142 for ( ; s->run ; s++) {
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000143 s->changed_inputs |= s->inputs & changed_inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000144
Gareth Hughese7e38a42001-05-21 16:33:41 +0000145 if (s->run_state & changed_state)
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000146 s->changed_inputs = s->inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000147
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000148 if (s->active && running) {
149 if (s->changed_inputs)
150 changed_inputs |= s->outputs;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000151
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000152 running = s->run( ctx, s );
Keith Whitwell16837e42001-04-30 09:04:00 +0000153
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000154 s->changed_inputs = 0;
Keith Whitwell23caf202000-11-16 21:05:34 +0000155 }
156 }
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000157
Keith Whitwellcab974c2000-12-26 05:09:27 +0000158 END_FAST_MATH(__tmp);
Keith Whitwell23caf202000-11-16 21:05:34 +0000159}
160
161
162
Keith Whitwellcab974c2000-12-26 05:09:27 +0000163/* The default pipeline. This is useful for software rasterizers, and
164 * simple hardware rasterizers. For customization, I don't recommend
165 * tampering with the internals of these stages in the way that
166 * drivers did in Mesa 3.4. These stages are basically black boxes,
Gareth Hughes22144ab2001-03-12 00:48:37 +0000167 * and should be left intact.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000168 *
Gareth Hughes22144ab2001-03-12 00:48:37 +0000169 * To customize the pipeline, consider:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000170 *
171 * - removing redundant stages (making sure that the software rasterizer
172 * can cope with this on fallback paths). An example is fog
173 * coordinate generation, which is not required in the FX driver.
174 *
175 * - replacing general-purpose machine-independent stages with
176 * general-purpose machine-specific stages. There is no example of
177 * this to date, though it must be borne in mind that all subsequent
178 * stages that reference the output of the new stage must cope with
179 * any machine-specific data introduced. This may not be easy
180 * unless there are no such stages (ie the new stage is the last in
181 * the pipe).
182 *
183 * - inserting optimized (but specialized) stages ahead of the
184 * general-purpose fallback implementation. For example, the old
Keith Whitwellae0eaf92003-11-24 15:23:18 +0000185 * fastpath mechanism, which only works when the VB->Elts input is
Keith Whitwellcab974c2000-12-26 05:09:27 +0000186 * available, can be duplicated by placing the fastpath stage at the
187 * head of this pipeline. Such specialized stages are currently
188 * constrained to have no outputs (ie. they must either finish the *
189 * pipeline by returning GL_FALSE from run(), or do nothing).
190 *
191 * Some work can be done to lift some of the restrictions in the final
Gareth Hughes22144ab2001-03-12 00:48:37 +0000192 * case, if it becomes necessary to do so.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000193 */
Keith Whitwellae0eaf92003-11-24 15:23:18 +0000194const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
Gareth Hughes22144ab2001-03-12 00:48:37 +0000195 &_tnl_vertex_transform_stage,
196 &_tnl_normal_transform_stage,
197 &_tnl_lighting_stage,
198 &_tnl_fog_coordinate_stage,
199 &_tnl_texgen_stage,
200 &_tnl_texture_transform_stage,
201 &_tnl_point_attenuation_stage,
Brian Paul8dfc5b92002-10-16 17:57:51 +0000202#if FEATURE_NV_vertex_program
Brian Paul86b84272001-12-14 02:50:01 +0000203 &_tnl_vertex_program_stage,
Brian Paul8dfc5b92002-10-16 17:57:51 +0000204#endif
Keith Whitwellcab974c2000-12-26 05:09:27 +0000205 &_tnl_render_stage,
206 0
207};