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

« back to all changes in this revision

Viewing changes to src/mesa/shader/slang/slang_link.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.3
4
 
 *
5
 
 * Copyright (C) 2008  Brian Paul   All Rights Reserved.
6
 
 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7
 
 *
8
 
 * 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:
14
 
 *
15
 
 * The above copyright notice and this permission notice shall be included
16
 
 * in all copies or substantial portions 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 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.
24
 
 */
25
 
 
26
 
/**
27
 
 * \file slang_link.c
28
 
 * GLSL linker
29
 
 * \author Brian Paul
30
 
 */
31
 
 
32
 
#include "main/imports.h"
33
 
#include "main/context.h"
34
 
#include "main/macros.h"
35
 
#include "shader/program.h"
36
 
#include "shader/prog_instruction.h"
37
 
#include "shader/prog_parameter.h"
38
 
#include "shader/prog_print.h"
39
 
#include "shader/prog_statevars.h"
40
 
#include "shader/prog_uniform.h"
41
 
#include "shader/shader_api.h"
42
 
#include "slang_builtin.h"
43
 
#include "slang_link.h"
44
 
 
45
 
 
46
 
/** cast wrapper */
47
 
static struct gl_vertex_program *
48
 
vertex_program(struct gl_program *prog)
49
 
{
50
 
   assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
51
 
   return (struct gl_vertex_program *) prog;
52
 
}
53
 
 
54
 
 
55
 
/** cast wrapper */
56
 
static struct gl_fragment_program *
57
 
fragment_program(struct gl_program *prog)
58
 
{
59
 
   assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
60
 
   return (struct gl_fragment_program *) prog;
61
 
}
62
 
 
63
 
 
64
 
/**
65
 
 * Record a linking error.
66
 
 */
67
 
static void
68
 
link_error(struct gl_shader_program *shProg, const char *msg)
69
 
{
70
 
   if (shProg->InfoLog) {
71
 
      free(shProg->InfoLog);
72
 
   }
73
 
   shProg->InfoLog = _mesa_strdup(msg);
74
 
   shProg->LinkStatus = GL_FALSE;
75
 
}
76
 
 
77
 
 
78
 
 
79
 
/**
80
 
 * Check if the given bit is either set or clear in both bitfields.
81
 
 */
82
 
static GLboolean
83
 
bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit)
84
 
{
85
 
   return (flags1 & bit) == (flags2 & bit);
86
 
}
87
 
 
88
 
 
89
 
/**
90
 
 * Linking varying vars involves rearranging varying vars so that the
91
 
 * vertex program's output varyings matches the order of the fragment
92
 
 * program's input varyings.
93
 
 * We'll then rewrite instructions to replace PROGRAM_VARYING with either
94
 
 * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or
95
 
 * fragment shader.
96
 
 * This is also where we set program Input/OutputFlags to indicate
97
 
 * which inputs are centroid-sampled, invariant, etc.
98
 
 */
99
 
static GLboolean
100
 
link_varying_vars(GLcontext *ctx,
101
 
                  struct gl_shader_program *shProg, struct gl_program *prog)
102
 
{
103
 
   GLuint *map, i, firstVarying, newFile;
104
 
   GLbitfield *inOutFlags;
105
 
 
106
 
   map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
107
 
   if (!map)
108
 
      return GL_FALSE;
109
 
 
110
 
   /* Varying variables are treated like other vertex program outputs
111
 
    * (and like other fragment program inputs).  The position of the
112
 
    * first varying differs for vertex/fragment programs...
113
 
    * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
114
 
    */
115
 
   if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
116
 
      firstVarying = VERT_RESULT_VAR0;
117
 
      newFile = PROGRAM_OUTPUT;
118
 
      inOutFlags = prog->OutputFlags;
119
 
   }
120
 
   else {
121
 
      assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
122
 
      firstVarying = FRAG_ATTRIB_VAR0;
123
 
      newFile = PROGRAM_INPUT;
124
 
      inOutFlags = prog->InputFlags;
125
 
   }
126
 
 
127
 
   for (i = 0; i < prog->Varying->NumParameters; i++) {
128
 
      /* see if this varying is in the linked varying list */
129
 
      const struct gl_program_parameter *var = prog->Varying->Parameters + i;
130
 
      GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
131
 
      if (j >= 0) {
132
 
         /* varying is already in list, do some error checking */
133
 
         const struct gl_program_parameter *v =
134
 
            &shProg->Varying->Parameters[j];
135
 
         if (var->Size != v->Size) {
136
 
            link_error(shProg, "mismatched varying variable types");
137
 
            free(map);
138
 
            return GL_FALSE;
139
 
         }
140
 
         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) {
141
 
            char msg[100];
142
 
            _mesa_snprintf(msg, sizeof(msg),
143
 
                     "centroid modifier mismatch for '%s'", var->Name);
144
 
            link_error(shProg, msg);
145
 
            free(map);
146
 
            return GL_FALSE;
147
 
         }
148
 
         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) {
149
 
            char msg[100];
150
 
            _mesa_snprintf(msg, sizeof(msg),
151
 
                     "invariant modifier mismatch for '%s'", var->Name);
152
 
            link_error(shProg, msg);
153
 
            free(map);
154
 
            return GL_FALSE;
155
 
         }
156
 
      }
157
 
      else {
158
 
         /* not already in linked list */
159
 
         j = _mesa_add_varying(shProg->Varying, var->Name, var->Size,
160
 
                               var->Flags);
161
 
      }
162
 
 
163
 
      if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) {
164
 
         link_error(shProg, "Too many varying variables");
165
 
         free(map);
166
 
         return GL_FALSE;
167
 
      }
168
 
 
169
 
      /* Map varying[i] to varying[j].
170
 
       * Note: the loop here takes care of arrays or large (sz>4) vars.
171
 
       */
172
 
      {
173
 
         GLint sz = var->Size;
174
 
         while (sz > 0) {
175
 
            inOutFlags[firstVarying + j] = var->Flags;
176
 
            /*printf("Link varying from %d to %d\n", i, j);*/
177
 
            map[i++] = j++;
178
 
            sz -= 4;
179
 
         }
180
 
         i--; /* go back one */
181
 
      }
182
 
   }
183
 
 
184
 
 
185
 
   /* OK, now scan the program/shader instructions looking for varying vars,
186
 
    * replacing the old index with the new index.
187
 
    */
188
 
   for (i = 0; i < prog->NumInstructions; i++) {
189
 
      struct prog_instruction *inst = prog->Instructions + i;
190
 
      GLuint j;
191
 
 
192
 
      if (inst->DstReg.File == PROGRAM_VARYING) {
193
 
         inst->DstReg.File = newFile;
194
 
         inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
195
 
      }
196
 
 
197
 
      for (j = 0; j < 3; j++) {
198
 
         if (inst->SrcReg[j].File == PROGRAM_VARYING) {
199
 
            inst->SrcReg[j].File = newFile;
200
 
            inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
201
 
         }
202
 
      }
203
 
   }
204
 
 
205
 
   free(map);
206
 
 
207
 
   /* these will get recomputed before linking is completed */
208
 
   prog->InputsRead = 0x0;
209
 
   prog->OutputsWritten = 0x0;
210
 
 
211
 
   return GL_TRUE;
212
 
}
213
 
 
214
 
 
215
 
/**
216
 
 * Build the shProg->Uniforms list.
217
 
 * This is basically a list/index of all uniforms found in either/both of
218
 
 * the vertex and fragment shaders.
219
 
 *
220
 
 * About uniforms:
221
 
 * Each uniform has two indexes, one that points into the vertex
222
 
 * program's parameter array and another that points into the fragment
223
 
 * program's parameter array.  When the user changes a uniform's value
224
 
 * we have to change the value in the vertex and/or fragment program's
225
 
 * parameter array.
226
 
 *
227
 
 * This function will be called twice to set up the two uniform->parameter
228
 
 * mappings.
229
 
 *
230
 
 * If a uniform is only present in the vertex program OR fragment program
231
 
 * then the fragment/vertex parameter index, respectively, will be -1.
232
 
 */
233
 
static GLboolean
234
 
link_uniform_vars(GLcontext *ctx,
235
 
                  struct gl_shader_program *shProg,
236
 
                  struct gl_program *prog,
237
 
                  GLuint *numSamplers)
238
 
{
239
 
   GLuint samplerMap[200]; /* max number of samplers declared, not used */
240
 
   GLuint i;
241
 
 
242
 
   for (i = 0; i < prog->Parameters->NumParameters; i++) {
243
 
      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
244
 
 
245
 
      /*
246
 
       * XXX FIX NEEDED HERE
247
 
       * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR.
248
 
       * For example, modelview matrix, light pos, etc.
249
 
       * Also, we need to update the state-var name-generator code to
250
 
       * generate GLSL-style names, like "gl_LightSource[0].position".
251
 
       * Furthermore, we'll need to fix the state-var's size/datatype info.
252
 
       */
253
 
 
254
 
      if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER)
255
 
          && p->Used) {
256
 
         /* add this uniform, indexing into the target's Parameters list */
257
 
         struct gl_uniform *uniform =
258
 
            _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
259
 
         if (uniform)
260
 
            uniform->Initialized = p->Initialized;
261
 
      }
262
 
 
263
 
      /* The samplerMap[] table we build here is used to remap/re-index
264
 
       * sampler references by TEX instructions.
265
 
       */
266
 
      if (p->Type == PROGRAM_SAMPLER && p->Used) {
267
 
         /* Allocate a new sampler index */
268
 
         GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
269
 
         GLuint newSampNum = *numSamplers;
270
 
         if (newSampNum >= ctx->Const.MaxTextureImageUnits) {
271
 
            char s[100];
272
 
            sprintf(s, "Too many texture samplers (%u, max is %u)",
273
 
                    newSampNum, ctx->Const.MaxTextureImageUnits);
274
 
            link_error(shProg, s);
275
 
            return GL_FALSE;
276
 
         }
277
 
         /* save old->new mapping in the table */
278
 
         if (oldSampNum < Elements(samplerMap))
279
 
            samplerMap[oldSampNum] = newSampNum;
280
 
         /* update parameter's sampler index */
281
 
         prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum;
282
 
         (*numSamplers)++;
283
 
      }
284
 
   }
285
 
 
286
 
   /* OK, now scan the program/shader instructions looking for texture
287
 
    * instructions using sampler vars.  Replace old sampler indexes with
288
 
    * new ones.
289
 
    */
290
 
   prog->SamplersUsed = 0x0;
291
 
   for (i = 0; i < prog->NumInstructions; i++) {
292
 
      struct prog_instruction *inst = prog->Instructions + i;
293
 
      if (_mesa_is_tex_instruction(inst->Opcode)) {
294
 
         /* here, inst->TexSrcUnit is really the sampler unit */
295
 
         const GLint oldSampNum = inst->TexSrcUnit;
296
 
 
297
 
#if 0
298
 
         printf("====== remap sampler from %d to %d\n",
299
 
                inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
300
 
#endif
301
 
 
302
 
         if (oldSampNum < Elements(samplerMap)) {
303
 
            const GLuint newSampNum = samplerMap[oldSampNum];
304
 
            inst->TexSrcUnit = newSampNum;
305
 
            prog->SamplerTargets[newSampNum] = inst->TexSrcTarget;
306
 
            prog->SamplersUsed |= (1 << newSampNum);
307
 
            if (inst->TexShadow) {
308
 
               prog->ShadowSamplers |= (1 << newSampNum);
309
 
            }
310
 
         }
311
 
      }
312
 
   }
313
 
 
314
 
   return GL_TRUE;
315
 
}
316
 
 
317
 
 
318
 
/**
319
 
 * Resolve binding of generic vertex attributes.
320
 
 * For example, if the vertex shader declared "attribute vec4 foobar" we'll
321
 
 * allocate a generic vertex attribute for "foobar" and plug that value into
322
 
 * the vertex program instructions.
323
 
 * But if the user called glBindAttributeLocation(), those bindings will
324
 
 * have priority.
325
 
 */
326
 
static GLboolean
327
 
_slang_resolve_attributes(struct gl_shader_program *shProg,
328
 
                          const struct gl_program *origProg,
329
 
                          struct gl_program *linkedProg)
330
 
{
331
 
   GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
332
 
   GLuint i, j;
333
 
   GLbitfield usedAttributes; /* generics only, not legacy attributes */
334
 
   GLbitfield inputsRead = 0x0;
335
 
 
336
 
   assert(origProg != linkedProg);
337
 
   assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
338
 
   assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB);
339
 
 
340
 
   if (!shProg->Attributes)
341
 
      shProg->Attributes = _mesa_new_parameter_list();
342
 
 
343
 
   if (linkedProg->Attributes) {
344
 
      _mesa_free_parameter_list(linkedProg->Attributes);
345
 
   }
346
 
   linkedProg->Attributes = _mesa_new_parameter_list();
347
 
 
348
 
 
349
 
   /* Build a bitmask indicating which attribute indexes have been
350
 
    * explicitly bound by the user with glBindAttributeLocation().
351
 
    */
352
 
   usedAttributes = 0x0;
353
 
   for (i = 0; i < shProg->Attributes->NumParameters; i++) {
354
 
      GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0];
355
 
      usedAttributes |= (1 << attr);
356
 
   }
357
 
 
358
 
   /* If gl_Vertex is used, that actually counts against the limit
359
 
    * on generic vertex attributes.  This avoids the ambiguity of
360
 
    * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos)
361
 
    * or generic attribute[0].  If gl_Vertex is used, we want the former.
362
 
    */
363
 
   if (origProg->InputsRead & VERT_BIT_POS) {
364
 
      usedAttributes |= 0x1;
365
 
   }
366
 
 
367
 
   /* initialize the generic attribute map entries to -1 */
368
 
   for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) {
369
 
      attribMap[i] = -1;
370
 
   }
371
 
 
372
 
   /*
373
 
    * Scan program for generic attribute references
374
 
    */
375
 
   for (i = 0; i < linkedProg->NumInstructions; i++) {
376
 
      struct prog_instruction *inst = linkedProg->Instructions + i;
377
 
      for (j = 0; j < 3; j++) {
378
 
         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
379
 
            inputsRead |= (1 << inst->SrcReg[j].Index);
380
 
         }
381
 
 
382
 
         if (inst->SrcReg[j].File == PROGRAM_INPUT &&
383
 
             inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
384
 
            /*
385
 
             * OK, we've found a generic vertex attribute reference.
386
 
             */
387
 
            const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
388
 
 
389
 
            GLint attr = attribMap[k];
390
 
 
391
 
            if (attr < 0) {
392
 
               /* Need to figure out attribute mapping now.
393
 
                */
394
 
               const char *name = origProg->Attributes->Parameters[k].Name;
395
 
               const GLint size = origProg->Attributes->Parameters[k].Size;
396
 
               const GLenum type =origProg->Attributes->Parameters[k].DataType;
397
 
               GLint index;
398
 
 
399
 
               /* See if there's a user-defined attribute binding for
400
 
                * this name.
401
 
                */
402
 
               index = _mesa_lookup_parameter_index(shProg->Attributes,
403
 
                                                    -1, name);
404
 
               if (index >= 0) {
405
 
                  /* Found a user-defined binding */
406
 
                  attr = shProg->Attributes->Parameters[index].StateIndexes[0];
407
 
               }
408
 
               else {
409
 
                  /* No user-defined binding, choose our own attribute number.
410
 
                   * Start at 1 since generic attribute 0 always aliases
411
 
                   * glVertex/position.
412
 
                   */
413
 
                  for (attr = 0; attr < MAX_VERTEX_GENERIC_ATTRIBS; attr++) {
414
 
                     if (((1 << attr) & usedAttributes) == 0)
415
 
                        break;
416
 
                  }
417
 
                  if (attr == MAX_VERTEX_GENERIC_ATTRIBS) {
418
 
                     link_error(shProg, "Too many vertex attributes");
419
 
                     return GL_FALSE;
420
 
                  }
421
 
 
422
 
                  /* mark this attribute as used */
423
 
                  usedAttributes |= (1 << attr);
424
 
               }
425
 
 
426
 
               attribMap[k] = attr;
427
 
 
428
 
               /* Save the final name->attrib binding so it can be queried
429
 
                * with glGetAttributeLocation().
430
 
                */
431
 
               _mesa_add_attribute(linkedProg->Attributes, name,
432
 
                                   size, type, attr);
433
 
            }
434
 
 
435
 
            assert(attr >= 0);
436
 
 
437
 
            /* update the instruction's src reg */
438
 
            inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
439
 
         }
440
 
      }
441
 
   }
442
 
 
443
 
   /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
444
 
    * When the user queries the active attributes we need to include both
445
 
    * the user-defined attributes and the built-in ones.
446
 
    */
447
 
   for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
448
 
      if (inputsRead & (1 << i)) {
449
 
         _mesa_add_attribute(linkedProg->Attributes,
450
 
                             _slang_vert_attrib_name(i),
451
 
                             4, /* size in floats */
452
 
                             _slang_vert_attrib_type(i),
453
 
                             -1 /* attrib/input */);
454
 
      }
455
 
   }
456
 
 
457
 
   return GL_TRUE;
458
 
}
459
 
 
460
 
 
461
 
/**
462
 
 * Scan program instructions to update the program's NumTemporaries field.
463
 
 * Note: this implemenation relies on the code generator allocating
464
 
 * temps in increasing order (0, 1, 2, ... ).
465
 
 */
466
 
static void
467
 
_slang_count_temporaries(struct gl_program *prog)
468
 
{
469
 
   GLuint i, j;
470
 
   GLint maxIndex = -1;
471
 
 
472
 
   for (i = 0; i < prog->NumInstructions; i++) {
473
 
      const struct prog_instruction *inst = prog->Instructions + i;
474
 
      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
475
 
      for (j = 0; j < numSrc; j++) {
476
 
         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
477
 
            if (maxIndex < inst->SrcReg[j].Index)
478
 
               maxIndex = inst->SrcReg[j].Index;
479
 
         }
480
 
         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
481
 
            if (maxIndex < (GLint) inst->DstReg.Index)
482
 
               maxIndex = inst->DstReg.Index;
483
 
         }
484
 
      }
485
 
   }
486
 
 
487
 
   prog->NumTemporaries = (GLuint) (maxIndex + 1);
488
 
}
489
 
 
490
 
 
491
 
/**
492
 
 * Scan program instructions to update the program's InputsRead and
493
 
 * OutputsWritten fields.
494
 
 */
495
 
static void
496
 
_slang_update_inputs_outputs(struct gl_program *prog)
497
 
{
498
 
   GLuint i, j;
499
 
   GLuint maxAddrReg = 0;
500
 
 
501
 
   prog->InputsRead = 0x0;
502
 
   prog->OutputsWritten = 0x0;
503
 
 
504
 
   for (i = 0; i < prog->NumInstructions; i++) {
505
 
      const struct prog_instruction *inst = prog->Instructions + i;
506
 
      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
507
 
      for (j = 0; j < numSrc; j++) {
508
 
         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
509
 
            prog->InputsRead |= 1 << inst->SrcReg[j].Index;
510
 
         }
511
 
         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
512
 
            maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
513
 
         }
514
 
      }
515
 
 
516
 
      if (inst->DstReg.File == PROGRAM_OUTPUT) {
517
 
         prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
518
 
         if (inst->DstReg.RelAddr) {
519
 
            /* If the output attribute is indexed with relative addressing
520
 
             * we know that it must be a varying or texcoord such as
521
 
             * gl_TexCoord[i] = v;  In this case, mark all the texcoords
522
 
             * or varying outputs as being written.  It's not an error if
523
 
             * a vertex shader writes varying vars that aren't used by the
524
 
             * fragment shader.  But it is an error for a fragment shader
525
 
             * to use varyings that are not written by the vertex shader.
526
 
             */
527
 
            if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
528
 
               if (inst->DstReg.Index == VERT_RESULT_TEX0) {
529
 
                  /* mark all texcoord outputs as written */
530
 
                  const GLbitfield64 mask =
531
 
                     BITFIELD64_RANGE(VERT_RESULT_TEX0,
532
 
                                      (VERT_RESULT_TEX0
533
 
                                       + MAX_TEXTURE_COORD_UNITS - 1));
534
 
                  prog->OutputsWritten |= mask;
535
 
               }
536
 
               else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
537
 
                  /* mark all generic varying outputs as written */
538
 
                  const GLbitfield64 mask =
539
 
                     BITFIELD64_RANGE(VERT_RESULT_VAR0,
540
 
                                      (VERT_RESULT_VAR0 + MAX_VARYING - 1));
541
 
                  prog->OutputsWritten |= mask;
542
 
               }
543
 
            }
544
 
         }
545
 
      }
546
 
      else if (inst->DstReg.File == PROGRAM_ADDRESS) {
547
 
         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
548
 
      }
549
 
   }
550
 
   prog->NumAddressRegs = maxAddrReg;
551
 
}
552
 
 
553
 
 
554
 
 
555
 
/**
556
 
 * Remove extra #version directives from the concatenated source string.
557
 
 * Disable the extra ones by converting first two chars to //, a comment.
558
 
 * This is a bit of hack to work around a preprocessor bug that only
559
 
 * allows one #version directive per source.
560
 
 */
561
 
static void
562
 
remove_extra_version_directives(GLchar *source)
563
 
{
564
 
   GLuint verCount = 0;
565
 
   while (1) {
566
 
      char *ver = strstr(source, "#version");
567
 
      if (ver) {
568
 
         verCount++;
569
 
         if (verCount > 1) {
570
 
            ver[0] = '/';
571
 
            ver[1] = '/';
572
 
         }
573
 
         source += 8;
574
 
      }
575
 
      else {
576
 
         break;
577
 
      }
578
 
   }
579
 
}
580
 
 
581
 
 
582
 
 
583
 
/**
584
 
 * Return a new shader whose source code is the concatenation of
585
 
 * all the shader sources of the given type.
586
 
 */
587
 
static struct gl_shader *
588
 
concat_shaders(struct gl_shader_program *shProg, GLenum shaderType)
589
 
{
590
 
   struct gl_shader *newShader;
591
 
   const struct gl_shader *firstShader = NULL;
592
 
   GLuint *shaderLengths;
593
 
   GLchar *source;
594
 
   GLuint totalLen = 0, len = 0;
595
 
   GLuint i;
596
 
 
597
 
   shaderLengths = (GLuint *)malloc(shProg->NumShaders * sizeof(GLuint));
598
 
   if (!shaderLengths) {
599
 
      return NULL;
600
 
   }
601
 
 
602
 
   /* compute total size of new shader source code */
603
 
   for (i = 0; i < shProg->NumShaders; i++) {
604
 
      const struct gl_shader *shader = shProg->Shaders[i];
605
 
      if (shader->Type == shaderType) {
606
 
         shaderLengths[i] = strlen(shader->Source);
607
 
         totalLen += shaderLengths[i];
608
 
         if (!firstShader)
609
 
            firstShader = shader;
610
 
      }
611
 
   }
612
 
 
613
 
   if (totalLen == 0) {
614
 
      free(shaderLengths);
615
 
      return NULL;
616
 
   }
617
 
 
618
 
   source = (GLchar *) malloc(totalLen + 1);
619
 
   if (!source) {
620
 
      free(shaderLengths);
621
 
      return NULL;
622
 
   }
623
 
 
624
 
   /* concatenate shaders */
625
 
   for (i = 0; i < shProg->NumShaders; i++) {
626
 
      const struct gl_shader *shader = shProg->Shaders[i];
627
 
      if (shader->Type == shaderType) {
628
 
         memcpy(source + len, shader->Source, shaderLengths[i]);
629
 
         len += shaderLengths[i];
630
 
      }
631
 
   }
632
 
   source[len] = '\0';
633
 
   /*
634
 
   printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
635
 
   */
636
 
 
637
 
   free(shaderLengths);
638
 
 
639
 
   remove_extra_version_directives(source);
640
 
 
641
 
   newShader = CALLOC_STRUCT(gl_shader);
642
 
   if (!newShader) {
643
 
      free(source);
644
 
      return NULL;
645
 
   }
646
 
 
647
 
   newShader->Type = shaderType;
648
 
   newShader->Source = source;
649
 
   newShader->Pragmas = firstShader->Pragmas;
650
 
 
651
 
   return newShader;
652
 
}
653
 
 
654
 
 
655
 
/**
656
 
 * Search the shader program's list of shaders to find the one that
657
 
 * defines main().
658
 
 * This will involve shader concatenation and recompilation if needed.
659
 
 */
660
 
static struct gl_shader *
661
 
get_main_shader(GLcontext *ctx,
662
 
                struct gl_shader_program *shProg, GLenum type)
663
 
{
664
 
   struct gl_shader *shader = NULL;
665
 
   GLuint i;
666
 
 
667
 
   /*
668
 
    * Look for a shader that defines main() and has no unresolved references.
669
 
    */
670
 
   for (i = 0; i < shProg->NumShaders; i++) {
671
 
      shader = shProg->Shaders[i];
672
 
      if (shader->Type == type &&
673
 
          shader->Main &&
674
 
          !shader->UnresolvedRefs) {
675
 
         /* All set! */
676
 
         return shader;
677
 
      }
678
 
   }
679
 
 
680
 
   /*
681
 
    * There must have been unresolved references during the original
682
 
    * compilation.  Try concatenating all the shaders of the given type
683
 
    * and recompile that.
684
 
    */
685
 
   shader = concat_shaders(shProg, type);
686
 
 
687
 
   if (shader) {
688
 
      _slang_compile(ctx, shader);
689
 
 
690
 
      /* Finally, check if recompiling failed */
691
 
      if (!shader->CompileStatus ||
692
 
          !shader->Main ||
693
 
          shader->UnresolvedRefs) {
694
 
         link_error(shProg, "Unresolved symbols");
695
 
         _mesa_free_shader(ctx, shader);
696
 
         return NULL;
697
 
      }
698
 
   }
699
 
 
700
 
   return shader;
701
 
}
702
 
 
703
 
 
704
 
/**
705
 
 * Shader linker.  Currently:
706
 
 *
707
 
 * 1. The last attached vertex shader and fragment shader are linked.
708
 
 * 2. Varying vars in the two shaders are combined so their locations
709
 
 *    agree between the vertex and fragment stages.  They're treated as
710
 
 *    vertex program output attribs and as fragment program input attribs.
711
 
 * 3. The vertex and fragment programs are cloned and modified to update
712
 
 *    src/dst register references so they use the new, linked varying
713
 
 *    storage locations.
714
 
 */
715
 
void
716
 
_slang_link(GLcontext *ctx,
717
 
            GLhandleARB programObj,
718
 
            struct gl_shader_program *shProg)
719
 
{
720
 
   const struct gl_vertex_program *vertProg = NULL;
721
 
   const struct gl_fragment_program *fragProg = NULL;
722
 
   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
723
 
   GLuint numSamplers = 0;
724
 
   GLuint i;
725
 
 
726
 
   _mesa_clear_shader_program_data(ctx, shProg);
727
 
 
728
 
   /* Initialize LinkStatus to "success".  Will be cleared if error. */
729
 
   shProg->LinkStatus = GL_TRUE;
730
 
 
731
 
   /* check that all programs compiled successfully */
732
 
   for (i = 0; i < shProg->NumShaders; i++) {
733
 
      if (!shProg->Shaders[i]->CompileStatus) {
734
 
         link_error(shProg, "linking with uncompiled shader\n");
735
 
         return;
736
 
      }
737
 
   }
738
 
 
739
 
   shProg->Uniforms = _mesa_new_uniform_list();
740
 
   shProg->Varying = _mesa_new_parameter_list();
741
 
 
742
 
   /*
743
 
    * Find the vertex and fragment shaders which define main()
744
 
    */
745
 
   {
746
 
      struct gl_shader *vertShader, *fragShader;
747
 
      vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER);
748
 
      fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER);
749
 
      if (vertShader)
750
 
         vertProg = vertex_program(vertShader->Program);
751
 
      if (fragShader)
752
 
         fragProg = fragment_program(fragShader->Program);
753
 
      if (!shProg->LinkStatus)
754
 
         return;
755
 
   }
756
 
 
757
 
#if FEATURE_es2_glsl
758
 
   /* must have both a vertex and fragment program for ES2 */
759
 
   if (!vertProg) {
760
 
      link_error(shProg, "missing vertex shader\n");
761
 
      return;
762
 
   }
763
 
   if (!fragProg) {
764
 
      link_error(shProg, "missing fragment shader\n");
765
 
      return;
766
 
   }
767
 
#endif
768
 
 
769
 
   /*
770
 
    * Make copies of the vertex/fragment programs now since we'll be
771
 
    * changing src/dst registers after merging the uniforms and varying vars.
772
 
    */
773
 
   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
774
 
   if (vertProg) {
775
 
      struct gl_vertex_program *linked_vprog =
776
 
         _mesa_clone_vertex_program(ctx, vertProg);
777
 
      shProg->VertexProgram = linked_vprog; /* refcount OK */
778
 
      /* vertex program ID not significant; just set Id for debugging purposes */
779
 
      shProg->VertexProgram->Base.Id = shProg->Name;
780
 
      ASSERT(shProg->VertexProgram->Base.RefCount == 1);
781
 
   }
782
 
 
783
 
   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
784
 
   if (fragProg) {
785
 
      struct gl_fragment_program *linked_fprog = 
786
 
         _mesa_clone_fragment_program(ctx, fragProg);
787
 
      shProg->FragmentProgram = linked_fprog; /* refcount OK */
788
 
      /* vertex program ID not significant; just set Id for debugging purposes */
789
 
      shProg->FragmentProgram->Base.Id = shProg->Name;
790
 
      ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
791
 
   }
792
 
 
793
 
   /* link varying vars */
794
 
   if (shProg->VertexProgram) {
795
 
      if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base))
796
 
         return;
797
 
   }
798
 
   if (shProg->FragmentProgram) {
799
 
      if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base))
800
 
         return;
801
 
   }
802
 
 
803
 
   /* link uniform vars */
804
 
   if (shProg->VertexProgram) {
805
 
      if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base,
806
 
                             &numSamplers)) {
807
 
         return;
808
 
      }
809
 
   }
810
 
   if (shProg->FragmentProgram) {
811
 
      if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base,
812
 
                             &numSamplers)) {
813
 
         return;
814
 
      }
815
 
   }
816
 
 
817
 
   /*_mesa_print_uniforms(shProg->Uniforms);*/
818
 
 
819
 
   if (shProg->VertexProgram) {
820
 
      if (!_slang_resolve_attributes(shProg, &vertProg->Base,
821
 
                                     &shProg->VertexProgram->Base)) {
822
 
         return;
823
 
      }
824
 
   }
825
 
 
826
 
   if (shProg->VertexProgram) {
827
 
      _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
828
 
      _slang_count_temporaries(&shProg->VertexProgram->Base);
829
 
      if (!(shProg->VertexProgram->Base.OutputsWritten
830
 
            & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
831
 
         /* the vertex program did not compute a vertex position */
832
 
         link_error(shProg,
833
 
                    "gl_Position was not written by vertex shader\n");
834
 
         return;
835
 
      }
836
 
   }
837
 
   if (shProg->FragmentProgram) {
838
 
      _slang_count_temporaries(&shProg->FragmentProgram->Base);
839
 
      _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
840
 
   }
841
 
 
842
 
   /* Check that all the varying vars needed by the fragment shader are
843
 
    * actually produced by the vertex shader.
844
 
    */
845
 
   if (shProg->FragmentProgram) {
846
 
      const GLbitfield varyingRead
847
 
         = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
848
 
      const GLbitfield64 varyingWritten = shProg->VertexProgram ?
849
 
         shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
850
 
      if ((varyingRead & varyingWritten) != varyingRead) {
851
 
         link_error(shProg,
852
 
          "Fragment program using varying vars not written by vertex shader\n");
853
 
         return;
854
 
      }         
855
 
   }
856
 
 
857
 
   /* check that gl_FragColor and gl_FragData are not both written to */
858
 
   if (shProg->FragmentProgram) {
859
 
      const GLbitfield64 outputsWritten =
860
 
         shProg->FragmentProgram->Base.OutputsWritten;
861
 
      if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
862
 
          (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
863
 
         link_error(shProg, "Fragment program cannot write both gl_FragColor"
864
 
                    " and gl_FragData[].\n");
865
 
         return;
866
 
      }         
867
 
   }
868
 
 
869
 
 
870
 
   if (fragProg && shProg->FragmentProgram) {
871
 
      /* Compute initial program's TexturesUsed info */
872
 
      _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
873
 
 
874
 
      /* notify driver that a new fragment program has been compiled/linked */
875
 
      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
876
 
                                                 &shProg->FragmentProgram->Base);
877
 
      if (ctx->Shader.Flags & GLSL_DUMP) {
878
 
         printf("Mesa pre-link fragment program:\n");
879
 
         _mesa_print_program(&fragProg->Base);
880
 
         _mesa_print_program_parameters(ctx, &fragProg->Base);
881
 
 
882
 
         printf("Mesa post-link fragment program:\n");
883
 
         _mesa_print_program(&shProg->FragmentProgram->Base);
884
 
         _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
885
 
      }
886
 
   }
887
 
 
888
 
   if (vertProg && shProg->VertexProgram) {
889
 
      /* Compute initial program's TexturesUsed info */
890
 
      _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
891
 
 
892
 
      /* notify driver that a new vertex program has been compiled/linked */
893
 
      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
894
 
                                                   &shProg->VertexProgram->Base);
895
 
      if (ctx->Shader.Flags & GLSL_DUMP) {
896
 
         printf("Mesa pre-link vertex program:\n");
897
 
         _mesa_print_program(&vertProg->Base);
898
 
         _mesa_print_program_parameters(ctx, &vertProg->Base);
899
 
 
900
 
         printf("Mesa post-link vertex program:\n");
901
 
         _mesa_print_program(&shProg->VertexProgram->Base);
902
 
         _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
903
 
      }
904
 
   }
905
 
 
906
 
   /* Debug: */
907
 
   if (0) {
908
 
      if (shProg->VertexProgram)
909
 
         _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base);
910
 
      if (shProg->FragmentProgram)
911
 
         _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base);
912
 
   }
913
 
 
914
 
   if (ctx->Shader.Flags & GLSL_DUMP) {
915
 
      printf("Varying vars:\n");
916
 
      _mesa_print_parameter_list(shProg->Varying);
917
 
      if (shProg->InfoLog) {
918
 
         printf("Info Log: %s\n", shProg->InfoLog);
919
 
      }
920
 
   }
921
 
 
922
 
   if (!vertNotify || !fragNotify) {
923
 
      /* driver rejected one/both of the vertex/fragment programs */
924
 
      if (!shProg->InfoLog) {
925
 
         link_error(shProg,
926
 
                    "Vertex and/or fragment program rejected by driver\n");
927
 
      }
928
 
   }
929
 
   else {
930
 
      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
931
 
   }
932
 
}
933