Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
4 | * All Rights Reserved. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the |
||
8 | * "Software"), to deal in the Software without restriction, including |
||
9 | * without limitation the rights to use, copy, modify, merge, publish, |
||
10 | * distribute, sub license, and/or sell copies of the Software, and to |
||
11 | * permit persons to whom the Software is furnished to do so, subject to |
||
12 | * the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice (including the |
||
15 | * next paragraph) shall be included in all copies or substantial portions |
||
16 | * of the Software. |
||
17 | * |
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
25 | * |
||
26 | **************************************************************************/ |
||
27 | |||
28 | /** |
||
29 | * TGSI program transformation utility. |
||
30 | * |
||
31 | * Authors: Brian Paul |
||
32 | */ |
||
33 | |||
34 | #include "util/u_debug.h" |
||
35 | |||
36 | #include "tgsi_transform.h" |
||
37 | |||
38 | |||
39 | |||
40 | static void |
||
41 | emit_instruction(struct tgsi_transform_context *ctx, |
||
42 | const struct tgsi_full_instruction *inst) |
||
43 | { |
||
44 | uint ti = ctx->ti; |
||
45 | |||
46 | ti += tgsi_build_full_instruction(inst, |
||
47 | ctx->tokens_out + ti, |
||
48 | ctx->header, |
||
49 | ctx->max_tokens_out - ti); |
||
50 | ctx->ti = ti; |
||
51 | } |
||
52 | |||
53 | |||
54 | static void |
||
55 | emit_declaration(struct tgsi_transform_context *ctx, |
||
56 | const struct tgsi_full_declaration *decl) |
||
57 | { |
||
58 | uint ti = ctx->ti; |
||
59 | |||
60 | ti += tgsi_build_full_declaration(decl, |
||
61 | ctx->tokens_out + ti, |
||
62 | ctx->header, |
||
63 | ctx->max_tokens_out - ti); |
||
64 | ctx->ti = ti; |
||
65 | } |
||
66 | |||
67 | |||
68 | static void |
||
69 | emit_immediate(struct tgsi_transform_context *ctx, |
||
70 | const struct tgsi_full_immediate *imm) |
||
71 | { |
||
72 | uint ti = ctx->ti; |
||
73 | |||
74 | ti += tgsi_build_full_immediate(imm, |
||
75 | ctx->tokens_out + ti, |
||
76 | ctx->header, |
||
77 | ctx->max_tokens_out - ti); |
||
78 | ctx->ti = ti; |
||
79 | } |
||
80 | |||
81 | |||
82 | static void |
||
83 | emit_property(struct tgsi_transform_context *ctx, |
||
84 | const struct tgsi_full_property *prop) |
||
85 | { |
||
86 | uint ti = ctx->ti; |
||
87 | |||
88 | ti += tgsi_build_full_property(prop, |
||
89 | ctx->tokens_out + ti, |
||
90 | ctx->header, |
||
91 | ctx->max_tokens_out - ti); |
||
92 | ctx->ti = ti; |
||
93 | } |
||
94 | |||
95 | |||
96 | /** |
||
97 | * Apply user-defined transformations to the input shader to produce |
||
98 | * the output shader. |
||
99 | * For example, a register search-and-replace operation could be applied |
||
100 | * by defining a transform_instruction() callback that examined and changed |
||
101 | * the instruction src/dest regs. |
||
102 | * |
||
103 | * \return number of tokens emitted |
||
104 | */ |
||
105 | int |
||
106 | tgsi_transform_shader(const struct tgsi_token *tokens_in, |
||
107 | struct tgsi_token *tokens_out, |
||
108 | uint max_tokens_out, |
||
109 | struct tgsi_transform_context *ctx) |
||
110 | { |
||
111 | uint procType; |
||
112 | |||
113 | /* input shader */ |
||
114 | struct tgsi_parse_context parse; |
||
115 | |||
116 | /* output shader */ |
||
117 | struct tgsi_processor *processor; |
||
118 | |||
119 | |||
120 | /** |
||
121 | ** callback context init |
||
122 | **/ |
||
123 | ctx->emit_instruction = emit_instruction; |
||
124 | ctx->emit_declaration = emit_declaration; |
||
125 | ctx->emit_immediate = emit_immediate; |
||
126 | ctx->emit_property = emit_property; |
||
127 | ctx->tokens_out = tokens_out; |
||
128 | ctx->max_tokens_out = max_tokens_out; |
||
129 | |||
130 | |||
131 | /** |
||
132 | ** Setup to begin parsing input shader |
||
133 | **/ |
||
134 | if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { |
||
135 | debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); |
||
136 | return -1; |
||
137 | } |
||
138 | procType = parse.FullHeader.Processor.Processor; |
||
139 | assert(procType == TGSI_PROCESSOR_FRAGMENT || |
||
140 | procType == TGSI_PROCESSOR_VERTEX || |
||
141 | procType == TGSI_PROCESSOR_GEOMETRY); |
||
142 | |||
143 | |||
144 | /** |
||
145 | ** Setup output shader |
||
146 | **/ |
||
147 | ctx->header = (struct tgsi_header *)tokens_out; |
||
148 | *ctx->header = tgsi_build_header(); |
||
149 | |||
150 | processor = (struct tgsi_processor *) (tokens_out + 1); |
||
151 | *processor = tgsi_build_processor( procType, ctx->header ); |
||
152 | |||
153 | ctx->ti = 2; |
||
154 | |||
155 | |||
156 | /** |
||
157 | ** Loop over incoming program tokens/instructions |
||
158 | */ |
||
159 | while( !tgsi_parse_end_of_tokens( &parse ) ) { |
||
160 | |||
161 | tgsi_parse_token( &parse ); |
||
162 | |||
163 | switch( parse.FullToken.Token.Type ) { |
||
164 | case TGSI_TOKEN_TYPE_INSTRUCTION: |
||
165 | { |
||
166 | struct tgsi_full_instruction *fullinst |
||
167 | = &parse.FullToken.FullInstruction; |
||
168 | |||
169 | if (ctx->transform_instruction) |
||
170 | ctx->transform_instruction(ctx, fullinst); |
||
171 | else |
||
172 | ctx->emit_instruction(ctx, fullinst); |
||
173 | } |
||
174 | break; |
||
175 | |||
176 | case TGSI_TOKEN_TYPE_DECLARATION: |
||
177 | { |
||
178 | struct tgsi_full_declaration *fulldecl |
||
179 | = &parse.FullToken.FullDeclaration; |
||
180 | |||
181 | if (ctx->transform_declaration) |
||
182 | ctx->transform_declaration(ctx, fulldecl); |
||
183 | else |
||
184 | ctx->emit_declaration(ctx, fulldecl); |
||
185 | } |
||
186 | break; |
||
187 | |||
188 | case TGSI_TOKEN_TYPE_IMMEDIATE: |
||
189 | { |
||
190 | struct tgsi_full_immediate *fullimm |
||
191 | = &parse.FullToken.FullImmediate; |
||
192 | |||
193 | if (ctx->transform_immediate) |
||
194 | ctx->transform_immediate(ctx, fullimm); |
||
195 | else |
||
196 | ctx->emit_immediate(ctx, fullimm); |
||
197 | } |
||
198 | break; |
||
199 | case TGSI_TOKEN_TYPE_PROPERTY: |
||
200 | { |
||
201 | struct tgsi_full_property *fullprop |
||
202 | = &parse.FullToken.FullProperty; |
||
203 | |||
204 | if (ctx->transform_property) |
||
205 | ctx->transform_property(ctx, fullprop); |
||
206 | else |
||
207 | ctx->emit_property(ctx, fullprop); |
||
208 | } |
||
209 | break; |
||
210 | |||
211 | default: |
||
212 | assert( 0 ); |
||
213 | } |
||
214 | } |
||
215 | |||
216 | if (ctx->epilog) { |
||
217 | ctx->epilog(ctx); |
||
218 | } |
||
219 | |||
220 | tgsi_parse_free (&parse); |
||
221 | |||
222 | return ctx->ti; |
||
223 | } |
||
224 | |||
225 | |||
226 | #include "tgsi_text.h" |
||
227 | |||
228 | extern int tgsi_transform_foo( struct tgsi_token *tokens_out, |
||
229 | uint max_tokens_out ); |
||
230 | |||
231 | /* This function exists only so that tgsi_text_translate() doesn't get |
||
232 | * magic-ed out of the libtgsi.a archive by the build system. Don't |
||
233 | * remove unless you know this has been fixed - check on mingw/scons |
||
234 | * builds as well. |
||
235 | */ |
||
236 | int |
||
237 | tgsi_transform_foo( struct tgsi_token *tokens_out, |
||
238 | uint max_tokens_out ) |
||
239 | { |
||
240 | const char *text = |
||
241 | "FRAG\n" |
||
242 | "DCL IN[0], COLOR, CONSTANT\n" |
||
243 | "DCL OUT[0], COLOR\n" |
||
244 | " 0: MOV OUT[0], IN[0]\n" |
||
245 | " 1: END"; |
||
246 | |||
247 | return tgsi_text_translate( text, |
||
248 | tokens_out, |
||
249 | max_tokens_out ); |
||
250 | } |