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