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

« back to all changes in this revision

Viewing changes to src/mesa/shader/atifragshader.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
 
 * \file atifragshader.c
3
 
 * \author David Airlie
4
 
 * Copyright (C) 2004  David Airlie   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 "Software"),
8
 
 * to deal in the Software without restriction, including without limitation
9
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 
 * and/or sell copies of the Software, and to permit persons to whom the
11
 
 * Software is furnished to do so, subject to the following conditions:
12
 
 *
13
 
 * The above copyright notice and this permission notice shall be included
14
 
 * in all copies or substantial portions of the Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 
 * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 
 */
23
 
 
24
 
#include "main/glheader.h"
25
 
#include "main/context.h"
26
 
#include "main/hash.h"
27
 
#include "main/imports.h"
28
 
#include "main/macros.h"
29
 
#include "main/enums.h"
30
 
#include "main/mtypes.h"
31
 
#include "atifragshader.h"
32
 
 
33
 
#define MESA_DEBUG_ATI_FS 0
34
 
 
35
 
static struct ati_fragment_shader DummyShader;
36
 
 
37
 
 
38
 
/**
39
 
 * Allocate and initialize a new ATI fragment shader object.
40
 
 */
41
 
struct ati_fragment_shader *
42
 
_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
43
 
{
44
 
   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
45
 
   (void) ctx;
46
 
   if (s) {
47
 
      s->Id = id;
48
 
      s->RefCount = 1;
49
 
   }
50
 
   return s;
51
 
}
52
 
 
53
 
 
54
 
/**
55
 
 * Delete the given ati fragment shader
56
 
 */
57
 
void
58
 
_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
59
 
{
60
 
   GLuint i;
61
 
   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
62
 
      if (s->Instructions[i])
63
 
         free(s->Instructions[i]);
64
 
      if (s->SetupInst[i])
65
 
         free(s->SetupInst[i]);
66
 
   }
67
 
   free(s);
68
 
}
69
 
 
70
 
 
71
 
 
72
 
static void
73
 
new_arith_inst(struct ati_fragment_shader *prog)
74
 
{
75
 
/* set "default" instruction as not all may get defined.
76
 
   there is no specified way to express a nop with ati fragment shaders we use
77
 
   GL_NONE as the op enum and just set some params to 0 - so nothing to do here */
78
 
   prog->numArithInstr[prog->cur_pass >> 1]++;
79
 
}
80
 
 
81
 
static void
82
 
new_tex_inst(struct ati_fragment_shader *prog)
83
 
{
84
 
}
85
 
 
86
 
static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype)
87
 
{
88
 
   if (optype == curProg->last_optype) {
89
 
      curProg->last_optype = 1;
90
 
   }
91
 
}
92
 
 
93
 
#if MESA_DEBUG_ATI_FS
94
 
static char *
95
 
create_dst_mod_str(GLuint mod)
96
 
{
97
 
   static char ret_str[1024];
98
 
 
99
 
   memset(ret_str, 0, 1024);
100
 
   if (mod & GL_2X_BIT_ATI)
101
 
      strncat(ret_str, "|2X", 1024);
102
 
 
103
 
   if (mod & GL_4X_BIT_ATI)
104
 
      strncat(ret_str, "|4X", 1024);
105
 
 
106
 
   if (mod & GL_8X_BIT_ATI)
107
 
      strncat(ret_str, "|8X", 1024);
108
 
   if (mod & GL_HALF_BIT_ATI)
109
 
      strncat(ret_str, "|HA", 1024);
110
 
   if (mod & GL_QUARTER_BIT_ATI)
111
 
      strncat(ret_str, "|QU", 1024);
112
 
   if (mod & GL_EIGHTH_BIT_ATI)
113
 
      strncat(ret_str, "|EI", 1024);
114
 
 
115
 
   if (mod & GL_SATURATE_BIT_ATI)
116
 
      strncat(ret_str, "|SAT", 1024);
117
 
 
118
 
   if (strlen(ret_str) == 0)
119
 
      strncat(ret_str, "NONE", 1024);
120
 
   return ret_str;
121
 
}
122
 
 
123
 
static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 
124
 
                            "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" };
125
 
 
126
 
static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
127
 
                     GLuint dstMask, GLuint dstMod, GLuint arg1,
128
 
                     GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
129
 
                     GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
130
 
                     GLuint arg3Rep, GLuint arg3Mod)
131
 
{
132
 
  char *op_name;
133
 
 
134
 
  op_name = atifs_ops[(arg_count-1)+(optype?3:0)];
135
 
  
136
 
  fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),
137
 
              _mesa_lookup_enum_by_nr(dst));
138
 
  if (!optype)
139
 
    fprintf(stderr, ", %d", dstMask);
140
 
  
141
 
  fprintf(stderr, ", %s", create_dst_mod_str(dstMod));
142
 
  
143
 
  fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),
144
 
              _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);
145
 
  if (arg_count>1)
146
 
    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),
147
 
              _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);
148
 
  if (arg_count>2)
149
 
    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),
150
 
              _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);
151
 
 
152
 
  fprintf(stderr,")\n");
153
 
 
154
 
}
155
 
#endif
156
 
 
157
 
static int check_arith_arg(struct ati_fragment_shader *curProg,
158
 
                        GLuint optype, GLuint arg, GLuint argRep)
159
 
{
160
 
   GET_CURRENT_CONTEXT(ctx);
161
 
 
162
 
   if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&
163
 
      ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&
164
 
      (arg != GL_ZERO) && (arg != GL_ONE) &&
165
 
      (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) {
166
 
      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");
167
 
      return 0;
168
 
   }
169
 
   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
170
 
      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
171
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
172
 
      return 0;
173
 
   }
174
 
   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
175
 
      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
176
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
177
 
      return 0;
178
 
   }
179
 
   if ((curProg->cur_pass == 1) &&
180
 
      ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) {
181
 
      curProg->interpinp1 = GL_TRUE;
182
 
   }
183
 
   return 1;
184
 
}
185
 
 
186
 
GLuint GLAPIENTRY
187
 
_mesa_GenFragmentShadersATI(GLuint range)
188
 
{
189
 
   GLuint first;
190
 
   GLuint i;
191
 
   GET_CURRENT_CONTEXT(ctx);
192
 
 
193
 
   if (range == 0) {
194
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)");
195
 
      return 0;
196
 
   }
197
 
 
198
 
   if (ctx->ATIFragmentShader.Compiling) {
199
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)");
200
 
      return 0;
201
 
   }
202
 
 
203
 
   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
204
 
   for (i = 0; i < range; i++) {
205
 
      _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
206
 
   }
207
 
 
208
 
   return first;
209
 
}
210
 
 
211
 
void GLAPIENTRY
212
 
_mesa_BindFragmentShaderATI(GLuint id)
213
 
{
214
 
   GET_CURRENT_CONTEXT(ctx);
215
 
   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
216
 
   struct ati_fragment_shader *newProg;
217
 
 
218
 
   if (ctx->ATIFragmentShader.Compiling) {
219
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
220
 
      return;
221
 
   }
222
 
 
223
 
   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
224
 
 
225
 
   if (curProg->Id == id) {
226
 
      return;
227
 
   }
228
 
 
229
 
   /* unbind current */
230
 
   if (curProg->Id != 0) {
231
 
      curProg->RefCount--;
232
 
      if (curProg->RefCount <= 0) {
233
 
         _mesa_HashRemove(ctx->Shared->ATIShaders, id);
234
 
      }
235
 
   }
236
 
 
237
 
   /* find new shader */
238
 
   if (id == 0) {
239
 
      newProg = ctx->Shared->DefaultFragmentShader;
240
 
   }
241
 
   else {
242
 
      newProg = (struct ati_fragment_shader *)
243
 
         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
244
 
      if (!newProg || newProg == &DummyShader) {
245
 
         /* allocate a new program now */
246
 
         newProg = _mesa_new_ati_fragment_shader(ctx, id);
247
 
         if (!newProg) {
248
 
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
249
 
            return;
250
 
         }
251
 
         _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
252
 
      }
253
 
 
254
 
   }
255
 
 
256
 
   /* do actual bind */
257
 
   ctx->ATIFragmentShader.Current = newProg;
258
 
 
259
 
   ASSERT(ctx->ATIFragmentShader.Current);
260
 
   if (newProg)
261
 
      newProg->RefCount++;
262
 
 
263
 
   /*if (ctx->Driver.BindProgram)
264
 
      ctx->Driver.BindProgram(ctx, target, prog); */
265
 
}
266
 
 
267
 
void GLAPIENTRY
268
 
_mesa_DeleteFragmentShaderATI(GLuint id)
269
 
{
270
 
   GET_CURRENT_CONTEXT(ctx);
271
 
 
272
 
   if (ctx->ATIFragmentShader.Compiling) {
273
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)");
274
 
      return;
275
 
   }
276
 
 
277
 
   if (id != 0) {
278
 
      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
279
 
         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
280
 
      if (prog == &DummyShader) {
281
 
         _mesa_HashRemove(ctx->Shared->ATIShaders, id);
282
 
      }
283
 
      else if (prog) {
284
 
         if (ctx->ATIFragmentShader.Current &&
285
 
             ctx->ATIFragmentShader.Current->Id == id) {
286
 
             FLUSH_VERTICES(ctx, _NEW_PROGRAM);
287
 
            _mesa_BindFragmentShaderATI(0);
288
 
         }
289
 
      }
290
 
 
291
 
      /* The ID is immediately available for re-use now */
292
 
      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
293
 
      if (prog) {
294
 
         prog->RefCount--;
295
 
         if (prog->RefCount <= 0) {
296
 
            free(prog);
297
 
         }
298
 
      }
299
 
   }
300
 
}
301
 
 
302
 
 
303
 
void GLAPIENTRY
304
 
_mesa_BeginFragmentShaderATI(void)
305
 
{
306
 
   GLint i;
307
 
   GET_CURRENT_CONTEXT(ctx);
308
 
 
309
 
   if (ctx->ATIFragmentShader.Compiling) {
310
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)");
311
 
      return;
312
 
   }
313
 
 
314
 
   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
315
 
 
316
 
   /* if the shader was already defined free instructions and get new ones
317
 
      (or, could use the same mem but would need to reinitialize) */
318
 
   /* no idea if it's allowed to redefine a shader */
319
 
   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
320
 
         if (ctx->ATIFragmentShader.Current->Instructions[i])
321
 
            free(ctx->ATIFragmentShader.Current->Instructions[i]);
322
 
         if (ctx->ATIFragmentShader.Current->SetupInst[i])
323
 
            free(ctx->ATIFragmentShader.Current->SetupInst[i]);
324
 
   }
325
 
 
326
 
   /* malloc the instructions here - not sure if the best place but its
327
 
      a start */
328
 
   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
329
 
      ctx->ATIFragmentShader.Current->Instructions[i] =
330
 
         (struct atifs_instruction *)
331
 
         calloc(1, sizeof(struct atifs_instruction) *
332
 
                   (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI));
333
 
      ctx->ATIFragmentShader.Current->SetupInst[i] =
334
 
         (struct atifs_setupinst *)
335
 
         calloc(1, sizeof(struct atifs_setupinst) *
336
 
                   (MAX_NUM_FRAGMENT_REGISTERS_ATI));
337
 
   }
338
 
 
339
 
/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
340
 
   ctx->ATIFragmentShader.Current->LocalConstDef = 0;
341
 
   ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
342
 
   ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
343
 
   ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
344
 
   ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;
345
 
   ctx->ATIFragmentShader.Current->NumPasses = 0;
346
 
   ctx->ATIFragmentShader.Current->cur_pass = 0;
347
 
   ctx->ATIFragmentShader.Current->last_optype = 0;
348
 
   ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;
349
 
   ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
350
 
   ctx->ATIFragmentShader.Current->swizzlerq = 0;
351
 
   ctx->ATIFragmentShader.Compiling = 1;
352
 
}
353
 
 
354
 
void GLAPIENTRY
355
 
_mesa_EndFragmentShaderATI(void)
356
 
{
357
 
   GET_CURRENT_CONTEXT(ctx);
358
 
   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
359
 
#if MESA_DEBUG_ATI_FS
360
 
   GLint i, j;
361
 
#endif
362
 
 
363
 
   if (!ctx->ATIFragmentShader.Compiling) {
364
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)");
365
 
      return;
366
 
   }
367
 
   if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {
368
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)");
369
 
   /* according to spec, DON'T return here */
370
 
   }
371
 
 
372
 
   match_pair_inst(curProg, 0);
373
 
   ctx->ATIFragmentShader.Compiling = 0;
374
 
   ctx->ATIFragmentShader.Current->isValid = GL_TRUE;
375
 
   if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||
376
 
      (ctx->ATIFragmentShader.Current->cur_pass == 2)) {
377
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)");
378
 
   }
379
 
   if (ctx->ATIFragmentShader.Current->cur_pass > 1)
380
 
      ctx->ATIFragmentShader.Current->NumPasses = 2;
381
 
   else
382
 
      ctx->ATIFragmentShader.Current->NumPasses = 1;
383
 
 
384
 
   ctx->ATIFragmentShader.Current->cur_pass = 0;
385
 
 
386
 
#if MESA_DEBUG_ATI_FS
387
 
   for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
388
 
      for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
389
 
         GLuint op = curProg->SetupInst[j][i].Opcode;
390
 
         const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0";
391
 
         GLuint src = curProg->SetupInst[j][i].src;
392
 
         GLuint swizzle = curProg->SetupInst[j][i].swizzle;
393
 
         fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
394
 
              swizzle);
395
 
      }
396
 
      for (i = 0; i < curProg->numArithInstr[j]; i++) {
397
 
         GLuint op0 = curProg->Instructions[j][i].Opcode[0];
398
 
         GLuint op1 = curProg->Instructions[j][i].Opcode[1];
399
 
         const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0";
400
 
         const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0";
401
 
         GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
402
 
         GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
403
 
         fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0,
404
 
              op1, op1_enum, count1);
405
 
      }
406
 
   }
407
 
#endif
408
 
 
409
 
   if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
410
 
      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
411
 
      /* XXX is this the right error? */
412
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
413
 
                  "glEndFragmentShaderATI(driver rejected shader)");
414
 
   }
415
 
}
416
 
 
417
 
void GLAPIENTRY
418
 
_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
419
 
{
420
 
   GET_CURRENT_CONTEXT(ctx);
421
 
   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
422
 
   struct atifs_setupinst *curI;
423
 
 
424
 
   if (!ctx->ATIFragmentShader.Compiling) {
425
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)");
426
 
      return;
427
 
   }
428
 
 
429
 
   if (curProg->cur_pass == 1) {
430
 
      match_pair_inst(curProg, 0);
431
 
      curProg->cur_pass = 2;
432
 
   }
433
 
   if ((curProg->cur_pass > 2) ||
434
 
      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
435
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
436
 
      return;
437
 
   }
438
 
   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
439
 
      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
440
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
441
 
      return;
442
 
   }
443
 
   if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
444
 
       ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
445
 
       ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
446
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
447
 
      return;
448
 
   }
449
 
   if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
450
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
451
 
      return;
452
 
   }
453
 
   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
454
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
455
 
      return;
456
 
   }
457
 
   if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) {
458
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
459
 
      return;
460
 
   }
461
 
   if (coord <= GL_TEXTURE7_ARB) {
462
 
      GLuint tmp = coord - GL_TEXTURE0_ARB;
463
 
      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
464
 
           (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
465
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
466
 
         return;
467
 
      } else {
468
 
         curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
469
 
      }
470
 
   }
471
 
 
472
 
   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
473
 
   new_tex_inst(curProg);
474
 
 
475
 
   /* add the instructions */
476
 
   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
477
 
 
478
 
   curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP;
479
 
   curI->src = coord;
480
 
   curI->swizzle = swizzle;
481
 
 
482
 
#if MESA_DEBUG_ATI_FS
483
 
   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
484
 
               _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
485
 
               _mesa_lookup_enum_by_nr(swizzle));
486
 
#endif
487
 
}
488
 
 
489
 
void GLAPIENTRY
490
 
_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
491
 
{
492
 
   GET_CURRENT_CONTEXT(ctx);
493
 
   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
494
 
   struct atifs_setupinst *curI;
495
 
 
496
 
   if (!ctx->ATIFragmentShader.Compiling) {
497
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)");
498
 
      return;
499
 
   }
500
 
 
501
 
   if (curProg->cur_pass == 1) {
502
 
      match_pair_inst(curProg, 0);
503
 
      curProg->cur_pass = 2;
504
 
   }
505
 
   if ((curProg->cur_pass > 2) ||
506
 
      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
507
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
508
 
      return;
509
 
   }
510
 
   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
511
 
      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
512
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
513
 
      return;
514
 
   }
515
 
   if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
516
 
       ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
517
 
       ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
518
 
   /* is this texture5 or texture7? spec is a bit unclear there */
519
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
520
 
      return;
521
 
   }
522
 
   if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
523
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
524
 
      return;
525
 
   }
526
 
   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
527
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
528
 
      return;
529
 
   }
530
 
   if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) {
531
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
532
 
      return;
533
 
   }
534
 
   if (interp <= GL_TEXTURE7_ARB) {
535
 
      GLuint tmp = interp - GL_TEXTURE0_ARB;
536
 
      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
537
 
           (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
538
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
539
 
         return;
540
 
      } else {
541
 
         curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
542
 
      }
543
 
   }
544
 
 
545
 
   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
546
 
   new_tex_inst(curProg);
547
 
 
548
 
   /* add the instructions */
549
 
   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
550
 
 
551
 
   curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP;
552
 
   curI->src = interp;
553
 
   curI->swizzle = swizzle;
554
 
 
555
 
#if MESA_DEBUG_ATI_FS
556
 
   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
557
 
               _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
558
 
               _mesa_lookup_enum_by_nr(swizzle));
559
 
#endif
560
 
}
561
 
 
562
 
static void
563
 
_mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
564
 
                     GLuint dstMask, GLuint dstMod, GLuint arg1,
565
 
                     GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
566
 
                     GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
567
 
                     GLuint arg3Rep, GLuint arg3Mod)
568
 
{
569
 
   GET_CURRENT_CONTEXT(ctx);
570
 
   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
571
 
   GLint ci;
572
 
   struct atifs_instruction *curI;
573
 
   GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI;
574
 
 
575
 
   if (!ctx->ATIFragmentShader.Compiling) {
576
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)");
577
 
      return;
578
 
   }
579
 
 
580
 
   if (curProg->cur_pass==0)
581
 
      curProg->cur_pass=1;
582
 
 
583
 
   else if (curProg->cur_pass==2)
584
 
      curProg->cur_pass=3;
585
 
 
586
 
   /* decide whether this is a new instruction or not ... all color instructions are new,
587
 
      and alpha instructions might also be new if there was no preceding color inst */
588
 
   if ((optype == 0) || (curProg->last_optype == optype)) {
589
 
      if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) {
590
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)");
591
 
         return;
592
 
      }
593
 
      /* easier to do that here slight side effect invalid instr will still be inserted as nops */
594
 
      match_pair_inst(curProg, optype);
595
 
      new_arith_inst(curProg);
596
 
   }
597
 
   curProg->last_optype = optype;
598
 
   ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1;
599
 
 
600
 
   /* add the instructions */
601
 
   curI = &curProg->Instructions[curProg->cur_pass >> 1][ci];
602
 
 
603
 
   /* error checking */
604
 
   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
605
 
      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)");
606
 
      return;
607
 
   }
608
 
   if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) &&
609
 
      (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) &&
610
 
      (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) &&
611
 
      (modtemp != GL_EIGHTH_BIT_ATI)) {
612
 
      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp);
613
 
      return;
614
 
   }
615
 
   /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */
616
 
   if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) {
617
 
      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)");
618
 
      return;
619
 
   }
620
 
   if (optype == 1) {
621
 
      if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) ||
622
 
         ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) ||
623
 
         ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) ||
624
 
         ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) {
625
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)");
626
 
         return;
627
 
      }
628
 
   }
629
 
   if ((op == GL_DOT4_ATI) &&
630
 
      (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) ||
631
 
      (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) {
632
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
633
 
   }
634
 
 
635
 
   if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) {
636
 
      return;
637
 
   }
638
 
   if (arg2) {
639
 
      if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) {
640
 
         return;
641
 
      }
642
 
   }
643
 
   if (arg3) {
644
 
      if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) {
645
 
         return;
646
 
      }
647
 
      if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) &&
648
 
          (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) &&
649
 
          (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) &&
650
 
          (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) {
651
 
         _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)");
652
 
         return;
653
 
      }
654
 
   }
655
 
 
656
 
   /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */
657
 
 
658
 
   curI->Opcode[optype] = op;
659
 
   curI->SrcReg[optype][0].Index = arg1;
660
 
   curI->SrcReg[optype][0].argRep = arg1Rep;
661
 
   curI->SrcReg[optype][0].argMod = arg1Mod;
662
 
   curI->ArgCount[optype] = arg_count;
663
 
 
664
 
   if (arg2) {
665
 
      curI->SrcReg[optype][1].Index = arg2;
666
 
      curI->SrcReg[optype][1].argRep = arg2Rep;
667
 
      curI->SrcReg[optype][1].argMod = arg2Mod;
668
 
   }
669
 
 
670
 
   if (arg3) {
671
 
      curI->SrcReg[optype][2].Index = arg3;
672
 
      curI->SrcReg[optype][2].argRep = arg3Rep;
673
 
      curI->SrcReg[optype][2].argMod = arg3Mod;
674
 
   }
675
 
 
676
 
   curI->DstReg[optype].Index = dst;
677
 
   curI->DstReg[optype].dstMod = dstMod;
678
 
   curI->DstReg[optype].dstMask = dstMask;
679
 
 
680
 
#if MESA_DEBUG_ATI_FS
681
 
   debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);
682
 
#endif
683
 
 
684
 
}
685
 
 
686
 
void GLAPIENTRY
687
 
_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
688
 
                          GLuint dstMod, GLuint arg1, GLuint arg1Rep,
689
 
                          GLuint arg1Mod)
690
 
{
691
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask,
692
 
                        dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
693
 
}
694
 
 
695
 
void GLAPIENTRY
696
 
_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
697
 
                          GLuint dstMod, GLuint arg1, GLuint arg1Rep,
698
 
                          GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
699
 
                          GLuint arg2Mod)
700
 
{
701
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask,
702
 
                        dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
703
 
                        arg2Mod, 0, 0, 0);
704
 
}
705
 
 
706
 
void GLAPIENTRY
707
 
_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
708
 
                          GLuint dstMod, GLuint arg1, GLuint arg1Rep,
709
 
                          GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
710
 
                          GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
711
 
                          GLuint arg3Mod)
712
 
{
713
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask,
714
 
                        dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
715
 
                        arg2Mod, arg3, arg3Rep, arg3Mod);
716
 
}
717
 
 
718
 
void GLAPIENTRY
719
 
_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
720
 
                          GLuint arg1Rep, GLuint arg1Mod)
721
 
{
722
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod,
723
 
                        arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
724
 
}
725
 
 
726
 
void GLAPIENTRY
727
 
_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
728
 
                          GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
729
 
                          GLuint arg2Rep, GLuint arg2Mod)
730
 
{
731
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod,
732
 
                        arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0,
733
 
                        0);
734
 
}
735
 
 
736
 
void GLAPIENTRY
737
 
_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
738
 
                          GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
739
 
                          GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
740
 
                          GLuint arg3Rep, GLuint arg3Mod)
741
 
{
742
 
   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod,
743
 
                        arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3,
744
 
                        arg3Rep, arg3Mod);
745
 
}
746
 
 
747
 
void GLAPIENTRY
748
 
_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value)
749
 
{
750
 
   GLuint dstindex;
751
 
   GET_CURRENT_CONTEXT(ctx);
752
 
 
753
 
   if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) {
754
 
      /* spec says nothing about what should happen here but we can't just segfault...*/
755
 
      _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)");
756
 
      return;
757
 
   }
758
 
 
759
 
   dstindex = dst - GL_CON_0_ATI;
760
 
   if (ctx->ATIFragmentShader.Compiling) {
761
 
      struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
762
 
      COPY_4V(curProg->Constants[dstindex], value);
763
 
      curProg->LocalConstDef |= 1 << dstindex;
764
 
   }
765
 
   else {
766
 
      FLUSH_VERTICES(ctx, _NEW_PROGRAM);
767
 
      COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
768
 
   }
769
 
}