blob: c187cf56a10957c0268280abd07a2f39b20d2678 [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 Whitwellcab974c2000-12-26 05:09:27 +000043 const struct gl_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 Whitwellcab974c2000-12-26 05:09:27 +000046 struct gl_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);
85 struct gl_pipeline *pipe = &tnl->pipeline;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +000086 struct gl_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 Whitwell3004bf82001-04-19 12:23:07 +0000121 struct vertex_buffer *VB = &tnl->vb;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000122 struct gl_pipeline *pipe = &tnl->pipeline;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000123 struct gl_pipeline_stage *s = pipe->stages;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000124 GLuint changed_state = pipe->run_state_changes;
125 GLuint changed_inputs = pipe->run_input_changes;
126 GLboolean running = GL_TRUE;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000127 unsigned short __tmp;
128
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000129 pipe->run_state_changes = 0;
130 pipe->run_input_changes = 0;
131
Keith Whitwellcab974c2000-12-26 05:09:27 +0000132 /* Done elsewhere.
133 */
134 ASSERT(pipe->build_state_changes == 0);
Gareth Hughese7e38a42001-05-21 16:33:41 +0000135
Keith Whitwellcab974c2000-12-26 05:09:27 +0000136 START_FAST_MATH(__tmp);
Keith Whitwell23caf202000-11-16 21:05:34 +0000137
138 /* If something changes in the pipeline, tag all subsequent stages
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000139 * using this value for recalculation. Inactive stages have their
140 * state and inputs examined to try to keep cached data alive over
Gareth Hughese7e38a42001-05-21 16:33:41 +0000141 * state-changes.
Keith Whitwell23caf202000-11-16 21:05:34 +0000142 */
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000143 for ( ; s->run ; s++) {
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000144 s->changed_inputs |= s->inputs & changed_inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000145
Gareth Hughese7e38a42001-05-21 16:33:41 +0000146 if (s->run_state & changed_state)
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000147 s->changed_inputs = s->inputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000148
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000149 if (s->active && running) {
150 if (s->changed_inputs)
151 changed_inputs |= s->outputs;
Keith Whitwell5c1e7fa2001-01-29 20:47:39 +0000152
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000153 running = s->run( ctx, s );
Keith Whitwell16837e42001-04-30 09:04:00 +0000154
Keith Whitwell7954a0c2001-05-10 12:18:38 +0000155 s->changed_inputs = 0;
156 VB->importable_data &= ~s->outputs;
Keith Whitwell23caf202000-11-16 21:05:34 +0000157 }
158 }
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000159
Keith Whitwellcab974c2000-12-26 05:09:27 +0000160 END_FAST_MATH(__tmp);
Keith Whitwell23caf202000-11-16 21:05:34 +0000161}
162
163
164
Keith Whitwellcab974c2000-12-26 05:09:27 +0000165/* The default pipeline. This is useful for software rasterizers, and
166 * simple hardware rasterizers. For customization, I don't recommend
167 * tampering with the internals of these stages in the way that
168 * drivers did in Mesa 3.4. These stages are basically black boxes,
Gareth Hughes22144ab2001-03-12 00:48:37 +0000169 * and should be left intact.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000170 *
Gareth Hughes22144ab2001-03-12 00:48:37 +0000171 * To customize the pipeline, consider:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000172 *
173 * - removing redundant stages (making sure that the software rasterizer
174 * can cope with this on fallback paths). An example is fog
175 * coordinate generation, which is not required in the FX driver.
176 *
177 * - replacing general-purpose machine-independent stages with
178 * general-purpose machine-specific stages. There is no example of
179 * this to date, though it must be borne in mind that all subsequent
180 * stages that reference the output of the new stage must cope with
181 * any machine-specific data introduced. This may not be easy
182 * unless there are no such stages (ie the new stage is the last in
183 * the pipe).
184 *
185 * - inserting optimized (but specialized) stages ahead of the
186 * general-purpose fallback implementation. For example, the old
Brian Paul4c8fadc62002-01-22 14:35:16 +0000187 * fastpath mechanism, which only works when the VERT_BIT_ELT input is
Keith Whitwellcab974c2000-12-26 05:09:27 +0000188 * available, can be duplicated by placing the fastpath stage at the
189 * head of this pipeline. Such specialized stages are currently
190 * constrained to have no outputs (ie. they must either finish the *
191 * pipeline by returning GL_FALSE from run(), or do nothing).
192 *
193 * Some work can be done to lift some of the restrictions in the final
Gareth Hughes22144ab2001-03-12 00:48:37 +0000194 * case, if it becomes necessary to do so.
Keith Whitwellcab974c2000-12-26 05:09:27 +0000195 */
196const struct gl_pipeline_stage *_tnl_default_pipeline[] = {
Gareth Hughes22144ab2001-03-12 00:48:37 +0000197 &_tnl_vertex_transform_stage,
198 &_tnl_normal_transform_stage,
199 &_tnl_lighting_stage,
200 &_tnl_fog_coordinate_stage,
201 &_tnl_texgen_stage,
202 &_tnl_texture_transform_stage,
203 &_tnl_point_attenuation_stage,
Brian Paul8dfc5b92002-10-16 17:57:51 +0000204#if FEATURE_NV_vertex_program
Brian Paul86b84272001-12-14 02:50:01 +0000205 &_tnl_vertex_program_stage,
Brian Paul8dfc5b92002-10-16 17:57:51 +0000206#endif
Keith Whitwellcab974c2000-12-26 05:09:27 +0000207 &_tnl_render_stage,
208 0
209};