~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/shader/slang/slang_simplify.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 * Version:  7.1
4
 
 *
5
 
 * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the "Software"),
9
 
 * to deal in the Software without restriction, including without limitation
10
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 
 * and/or sell copies of the Software, and to permit persons to whom the
12
 
 * Software is furnished to do so, subject to the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice shall be included
15
 
 * in all copies or substantial portions of the Software.
16
 
 *
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 
 */
24
 
 
25
 
/**
26
 
 * Functions for constant folding, built-in constant lookup, and function
27
 
 * call casting.
28
 
 */
29
 
 
30
 
 
31
 
#include "main/imports.h"
32
 
#include "main/macros.h"
33
 
#include "main/get.h"
34
 
#include "slang_compile.h"
35
 
#include "slang_codegen.h"
36
 
#include "slang_simplify.h"
37
 
#include "slang_print.h"
38
 
 
39
 
 
40
 
#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
41
 
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
42
 
#endif
43
 
#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
44
 
#define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
45
 
#endif
46
 
#ifndef GL_MAX_VARYING_VECTORS
47
 
#define GL_MAX_VARYING_VECTORS              0x8DFC
48
 
#endif
49
 
 
50
 
 
51
 
/**
52
 
 * Lookup the value of named constant, such as gl_MaxLights.
53
 
 * \return value of constant, or -1 if unknown
54
 
 */
55
 
GLint
56
 
_slang_lookup_constant(const char *name)
57
 
{
58
 
   struct constant_info {
59
 
      const char *Name;
60
 
      const GLenum Token;
61
 
   };
62
 
   static const struct constant_info info[] = {
63
 
      { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
64
 
      { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
65
 
      { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
66
 
      { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
67
 
      { "gl_MaxLights", GL_MAX_LIGHTS },
68
 
      { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
69
 
      { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
70
 
      { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
71
 
      { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
72
 
      { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
73
 
      { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
74
 
      { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
75
 
#if FEATURE_es2_glsl
76
 
      { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
77
 
      { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
78
 
      { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
79
 
#endif
80
 
      { NULL, 0 }
81
 
   };
82
 
   GLuint i;
83
 
 
84
 
   for (i = 0; info[i].Name; i++) {
85
 
      if (strcmp(info[i].Name, name) == 0) {
86
 
         /* found */
87
 
         GLint values[16];
88
 
         values[0] = -1;
89
 
         _mesa_GetIntegerv(info[i].Token, values);
90
 
         ASSERT(values[0] >= 0);  /* sanity check that glGetFloatv worked */
91
 
         return values[0];
92
 
      }
93
 
   }
94
 
   return -1;
95
 
}
96
 
 
97
 
 
98
 
static slang_operation_type
99
 
literal_type(slang_operation_type t1, slang_operation_type t2)
100
 
{
101
 
   if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
102
 
      return SLANG_OPER_LITERAL_FLOAT;
103
 
   else
104
 
      return SLANG_OPER_LITERAL_INT;
105
 
}
106
 
 
107
 
 
108
 
/**
109
 
 * Recursively traverse an AST tree, applying simplifications wherever
110
 
 * possible.
111
 
 * At the least, we do constant folding.  We need to do that much so that
112
 
 * compile-time expressions can be evaluated for things like array
113
 
 * declarations.  I.e.:  float foo[3 + 5];
114
 
 */
115
 
void
116
 
_slang_simplify(slang_operation *oper,
117
 
                const slang_name_space * space,
118
 
                slang_atom_pool * atoms)
119
 
{
120
 
   GLboolean isFloat[4];
121
 
   GLboolean isBool[4];
122
 
   GLuint i, n;
123
 
 
124
 
   if (oper->type == SLANG_OPER_IDENTIFIER) {
125
 
      /* see if it's a named constant */
126
 
      GLint value = _slang_lookup_constant((char *) oper->a_id);
127
 
      /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
128
 
      if (value >= 0) {
129
 
         oper->literal[0] =
130
 
         oper->literal[1] =
131
 
         oper->literal[2] =
132
 
         oper->literal[3] = (GLfloat) value;
133
 
         oper->type = SLANG_OPER_LITERAL_INT;
134
 
         return;
135
 
      }
136
 
      /* look for user-defined constant */
137
 
      {
138
 
         slang_variable *var;
139
 
         var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
140
 
         if (var) {
141
 
            if (var->type.qualifier == SLANG_QUAL_CONST &&
142
 
                var->initializer &&
143
 
                (var->initializer->type == SLANG_OPER_LITERAL_INT ||
144
 
                 var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
145
 
               oper->literal[0] = var->initializer->literal[0];
146
 
               oper->literal[1] = var->initializer->literal[1];
147
 
               oper->literal[2] = var->initializer->literal[2];
148
 
               oper->literal[3] = var->initializer->literal[3];
149
 
               oper->literal_size = var->initializer->literal_size;
150
 
               oper->type = var->initializer->type;
151
 
               /*
152
 
               printf("value[%s] = %f\n",
153
 
                      (char*) oper->a_id, oper->literal[0]);
154
 
               */
155
 
               return;
156
 
            }
157
 
         }
158
 
      }
159
 
   }
160
 
 
161
 
   /* first, simplify children */
162
 
   for (i = 0; i < oper->num_children; i++) {
163
 
      _slang_simplify(&oper->children[i], space, atoms);
164
 
   }
165
 
 
166
 
   /* examine children */
167
 
   n = MIN2(oper->num_children, 4);
168
 
   for (i = 0; i < n; i++) {
169
 
      isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
170
 
                   oper->children[i].type == SLANG_OPER_LITERAL_INT);
171
 
      isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
172
 
   }
173
 
                              
174
 
   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
175
 
      /* probably simple arithmetic */
176
 
      switch (oper->type) {
177
 
      case SLANG_OPER_ADD:
178
 
         for (i = 0; i < 4; i++) {
179
 
            oper->literal[i]
180
 
               = oper->children[0].literal[i] + oper->children[1].literal[i];
181
 
         }
182
 
         oper->literal_size = oper->children[0].literal_size;
183
 
         oper->type = literal_type(oper->children[0].type, 
184
 
                                   oper->children[1].type);
185
 
         slang_operation_destruct(oper);  /* frees unused children */
186
 
         return;
187
 
      case SLANG_OPER_SUBTRACT:
188
 
         for (i = 0; i < 4; i++) {
189
 
            oper->literal[i]
190
 
               = oper->children[0].literal[i] - oper->children[1].literal[i];
191
 
         }
192
 
         oper->literal_size = oper->children[0].literal_size;
193
 
         oper->type = literal_type(oper->children[0].type, 
194
 
                                   oper->children[1].type);
195
 
         slang_operation_destruct(oper);
196
 
         return;
197
 
      case SLANG_OPER_MULTIPLY:
198
 
         for (i = 0; i < 4; i++) {
199
 
            oper->literal[i]
200
 
               = oper->children[0].literal[i] * oper->children[1].literal[i];
201
 
         }
202
 
         oper->literal_size = oper->children[0].literal_size;
203
 
         oper->type = literal_type(oper->children[0].type, 
204
 
                                   oper->children[1].type);
205
 
         slang_operation_destruct(oper);
206
 
         return;
207
 
      case SLANG_OPER_DIVIDE:
208
 
         for (i = 0; i < 4; i++) {
209
 
            oper->literal[i]
210
 
               = oper->children[0].literal[i] / oper->children[1].literal[i];
211
 
         }
212
 
         oper->literal_size = oper->children[0].literal_size;
213
 
         oper->type = literal_type(oper->children[0].type, 
214
 
                                   oper->children[1].type);
215
 
         slang_operation_destruct(oper);
216
 
         return;
217
 
      default:
218
 
         ; /* nothing */
219
 
      }
220
 
   }
221
 
 
222
 
   if (oper->num_children == 1 && isFloat[0]) {
223
 
      switch (oper->type) {
224
 
      case SLANG_OPER_MINUS:
225
 
         for (i = 0; i < 4; i++) {
226
 
            oper->literal[i] = -oper->children[0].literal[i];
227
 
         }
228
 
         oper->literal_size = oper->children[0].literal_size;
229
 
         slang_operation_destruct(oper);
230
 
         oper->type = SLANG_OPER_LITERAL_FLOAT;
231
 
         return;
232
 
      case SLANG_OPER_PLUS:
233
 
         COPY_4V(oper->literal, oper->children[0].literal);
234
 
         oper->literal_size = oper->children[0].literal_size;
235
 
         slang_operation_destruct(oper);
236
 
         oper->type = SLANG_OPER_LITERAL_FLOAT;
237
 
         return;
238
 
      default:
239
 
         ; /* nothing */
240
 
      }
241
 
   }
242
 
 
243
 
   if (oper->num_children == 2 && isBool[0] && isBool[1]) {
244
 
      /* simple boolean expression */
245
 
      switch (oper->type) {
246
 
      case SLANG_OPER_LOGICALAND:
247
 
         for (i = 0; i < 4; i++) {
248
 
            const GLint a = oper->children[0].literal[i] ? 1 : 0;
249
 
            const GLint b = oper->children[1].literal[i] ? 1 : 0;
250
 
            oper->literal[i] = (GLfloat) (a && b);
251
 
         }
252
 
         oper->literal_size = oper->children[0].literal_size;
253
 
         slang_operation_destruct(oper);
254
 
         oper->type = SLANG_OPER_LITERAL_BOOL;
255
 
         return;
256
 
      case SLANG_OPER_LOGICALOR:
257
 
         for (i = 0; i < 4; i++) {
258
 
            const GLint a = oper->children[0].literal[i] ? 1 : 0;
259
 
            const GLint b = oper->children[1].literal[i] ? 1 : 0;
260
 
            oper->literal[i] = (GLfloat) (a || b);
261
 
         }
262
 
         oper->literal_size = oper->children[0].literal_size;
263
 
         slang_operation_destruct(oper);
264
 
         oper->type = SLANG_OPER_LITERAL_BOOL;
265
 
         return;
266
 
      case SLANG_OPER_LOGICALXOR:
267
 
         for (i = 0; i < 4; i++) {
268
 
            const GLint a = oper->children[0].literal[i] ? 1 : 0;
269
 
            const GLint b = oper->children[1].literal[i] ? 1 : 0;
270
 
            oper->literal[i] = (GLfloat) (a ^ b);
271
 
         }
272
 
         oper->literal_size = oper->children[0].literal_size;
273
 
         slang_operation_destruct(oper);
274
 
         oper->type = SLANG_OPER_LITERAL_BOOL;
275
 
         return;
276
 
      default:
277
 
         ; /* nothing */
278
 
      }
279
 
   }
280
 
 
281
 
   if (oper->num_children == 4
282
 
       && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
283
 
      /* vec4(flt, flt, flt, flt) constructor */
284
 
      if (oper->type == SLANG_OPER_CALL) {
285
 
         if (strcmp((char *) oper->a_id, "vec4") == 0) {
286
 
            oper->literal[0] = oper->children[0].literal[0];
287
 
            oper->literal[1] = oper->children[1].literal[0];
288
 
            oper->literal[2] = oper->children[2].literal[0];
289
 
            oper->literal[3] = oper->children[3].literal[0];
290
 
            oper->literal_size = 4;
291
 
            slang_operation_destruct(oper);
292
 
            oper->type = SLANG_OPER_LITERAL_FLOAT;
293
 
            return;
294
 
         }
295
 
      }
296
 
   }
297
 
 
298
 
   if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
299
 
      /* vec3(flt, flt, flt) constructor */
300
 
      if (oper->type == SLANG_OPER_CALL) {
301
 
         if (strcmp((char *) oper->a_id, "vec3") == 0) {
302
 
            oper->literal[0] = oper->children[0].literal[0];
303
 
            oper->literal[1] = oper->children[1].literal[0];
304
 
            oper->literal[2] = oper->children[2].literal[0];
305
 
            oper->literal[3] = oper->literal[2];
306
 
            oper->literal_size = 3;
307
 
            slang_operation_destruct(oper);
308
 
            oper->type = SLANG_OPER_LITERAL_FLOAT;
309
 
            return;
310
 
         }
311
 
      }
312
 
   }
313
 
 
314
 
   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
315
 
      /* vec2(flt, flt) constructor */
316
 
      if (oper->type == SLANG_OPER_CALL) {
317
 
         if (strcmp((char *) oper->a_id, "vec2") == 0) {
318
 
            oper->literal[0] = oper->children[0].literal[0];
319
 
            oper->literal[1] = oper->children[1].literal[0];
320
 
            oper->literal[2] = oper->literal[1];
321
 
            oper->literal[3] = oper->literal[1];
322
 
            oper->literal_size = 2;
323
 
            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
324
 
            oper->type = SLANG_OPER_LITERAL_FLOAT;
325
 
            assert(oper->num_children == 0);
326
 
            return;
327
 
         }
328
 
      }
329
 
   }
330
 
 
331
 
   if (oper->num_children == 1 && isFloat[0]) {
332
 
      /* vec2/3/4(flt, flt) constructor */
333
 
      if (oper->type == SLANG_OPER_CALL) {
334
 
         const char *func = (const char *) oper->a_id;
335
 
         if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
336
 
            oper->literal[0] =
337
 
            oper->literal[1] =
338
 
            oper->literal[2] =
339
 
            oper->literal[3] = oper->children[0].literal[0];
340
 
            oper->literal_size = func[3] - '0';
341
 
            assert(oper->literal_size >= 2);
342
 
            assert(oper->literal_size <= 4);
343
 
            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
344
 
            oper->type = SLANG_OPER_LITERAL_FLOAT;
345
 
            assert(oper->num_children == 0);
346
 
            return;
347
 
         }
348
 
      }
349
 
   }
350
 
}
351
 
 
352
 
 
353
 
 
354
 
/**
355
 
 * Insert casts to try to adapt actual parameters to formal parameters for a
356
 
 * function call when an exact match for the parameter types is not found.
357
 
 * Example:
358
 
 *   void foo(int i, bool b) {}
359
 
 *   x = foo(3.15, 9);
360
 
 * Gets translated into:
361
 
 *   x = foo(int(3.15), bool(9))
362
 
 */
363
 
GLboolean
364
 
_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
365
 
                        const slang_name_space * space,
366
 
                        slang_atom_pool * atoms, slang_info_log *log)
367
 
{
368
 
   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
369
 
   const int numParams = fun->param_count - haveRetValue;
370
 
   int i;
371
 
   int dbg = 0;
372
 
 
373
 
   if (dbg)
374
 
      printf("Adapt call of %d args to func %s (%d params)\n",
375
 
             callOper->num_children, (char*) fun->header.a_name, numParams);
376
 
 
377
 
   for (i = 0; i < numParams; i++) {
378
 
      slang_typeinfo argType;
379
 
      slang_variable *paramVar = fun->parameters->variables[i];
380
 
 
381
 
      /* Get type of arg[i] */
382
 
      if (!slang_typeinfo_construct(&argType))
383
 
         return GL_FALSE;
384
 
      if (!_slang_typeof_operation(&callOper->children[i], space,
385
 
                                    &argType, atoms, log)) {
386
 
         slang_typeinfo_destruct(&argType);
387
 
         return GL_FALSE;
388
 
      }
389
 
 
390
 
      /* see if arg type matches parameter type */
391
 
      if (!slang_type_specifier_equal(&argType.spec,
392
 
                                      &paramVar->type.specifier)) {
393
 
         /* need to adapt arg type to match param type */
394
 
         const char *constructorName =
395
 
            slang_type_specifier_type_to_string(paramVar->type.specifier.type);
396
 
         slang_operation *child = slang_operation_new(1);
397
 
 
398
 
         if (dbg)
399
 
            printf("Need to adapt types of arg %d\n", i);
400
 
 
401
 
         slang_operation_copy(child, &callOper->children[i]);
402
 
         child->locals->outer_scope = callOper->children[i].locals;
403
 
 
404
 
#if 0
405
 
         if (_slang_sizeof_type_specifier(&argType.spec) >
406
 
             _slang_sizeof_type_specifier(&paramVar->type.specifier)) {
407
 
         }
408
 
#endif
409
 
 
410
 
         callOper->children[i].type = SLANG_OPER_CALL;
411
 
         callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
412
 
         callOper->children[i].num_children = 1;
413
 
         callOper->children[i].children = child;
414
 
      }
415
 
 
416
 
      slang_typeinfo_destruct(&argType);
417
 
   }
418
 
 
419
 
   if (dbg) {
420
 
      printf("===== New call to %s with cast arguments ===============\n",
421
 
             (char*) fun->header.a_name);
422
 
      slang_print_tree(callOper, 5);
423
 
   }
424
 
 
425
 
   return GL_TRUE;
426
 
}
427
 
 
428
 
 
429
 
/**
430
 
 * Adapt the arguments for a function call to match the parameters of
431
 
 * the given function.
432
 
 * This is for:
433
 
 * 1. converting/casting argument types to match parameters
434
 
 * 2. breaking up vector/matrix types into individual components to
435
 
 *    satisfy constructors.
436
 
 */
437
 
GLboolean
438
 
_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
439
 
                  const slang_name_space * space,
440
 
                  slang_atom_pool * atoms, slang_info_log *log)
441
 
{
442
 
   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
443
 
   const int numParams = fun->param_count - haveRetValue;
444
 
   int i;
445
 
   int dbg = 0;
446
 
 
447
 
   if (dbg)
448
 
      printf("Adapt %d args to %d parameters for %s\n",
449
 
             callOper->num_children, numParams, (char *) fun->header.a_name);
450
 
 
451
 
   /* Only try adapting for constructors */
452
 
   if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
453
 
      return GL_FALSE;
454
 
 
455
 
   if (callOper->num_children != numParams) {
456
 
      /* number of arguments doesn't match number of parameters */
457
 
 
458
 
      /* For constructor calls, we can try to unroll vector/matrix args
459
 
       * into individual floats/ints and try to match the function params.
460
 
       */
461
 
      for (i = 0; i < numParams; i++) {
462
 
         slang_typeinfo argType;
463
 
         GLint argSz, j;
464
 
 
465
 
         /* Get type of arg[i] */
466
 
         if (!slang_typeinfo_construct(&argType))
467
 
            return GL_FALSE;
468
 
         if (!_slang_typeof_operation(&callOper->children[i], space,
469
 
                                       &argType, atoms, log)) {
470
 
            slang_typeinfo_destruct(&argType);
471
 
            return GL_FALSE;
472
 
         }
473
 
 
474
 
         /*
475
 
           paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
476
 
           assert(paramSz == 1);
477
 
         */
478
 
         argSz = _slang_sizeof_type_specifier(&argType.spec);
479
 
         if (argSz > 1) {
480
 
            slang_operation origArg;
481
 
            /* break up arg[i] into components */
482
 
            if (dbg)
483
 
               printf("Break up arg %d from 1 to %d elements\n", i, argSz);
484
 
 
485
 
            slang_operation_construct(&origArg);
486
 
            slang_operation_copy(&origArg, &callOper->children[i]);
487
 
 
488
 
            /* insert argSz-1 new children/args */
489
 
            for (j = 0; j < argSz - 1; j++) {
490
 
               (void) slang_operation_insert(&callOper->num_children,
491
 
                                             &callOper->children, i);
492
 
            }
493
 
 
494
 
            /* replace arg[i+j] with subscript/index oper */
495
 
            for (j = 0; j < argSz; j++) {
496
 
               callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
497
 
               callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
498
 
               callOper->children[i + j].num_children = 2;
499
 
               callOper->children[i + j].children = slang_operation_new(2);
500
 
               slang_operation_copy(&callOper->children[i + j].children[0],
501
 
                                    &origArg);
502
 
               callOper->children[i + j].children[1].type
503
 
                  = SLANG_OPER_LITERAL_INT;
504
 
               callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
505
 
            }
506
 
         }
507
 
      }
508
 
   }
509
 
 
510
 
   if (callOper->num_children < (GLuint) numParams) {
511
 
      /* still not enough args for all params */
512
 
      return GL_FALSE;
513
 
   }
514
 
   else if (callOper->num_children > (GLuint) numParams) {
515
 
      /* now too many arguments */
516
 
      /* just truncate */
517
 
      callOper->num_children = (GLuint) numParams;
518
 
   }
519
 
 
520
 
   if (dbg) {
521
 
      printf("===== New call to %s with adapted arguments ===============\n",
522
 
             (char*) fun->header.a_name);
523
 
      slang_print_tree(callOper, 5);
524
 
   }
525
 
 
526
 
   return GL_TRUE;
527
 
}