Subversion Repositories Kolibri OS

Rev

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
}