Add more error checking.
[mesa.git] / src / mesa / shader / arbvertparse.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.2
4 *
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #define DEBUG_VP 0
26
27 /**
28 * \file arbvertparse.c
29 * ARB_vertex_program parser.
30 * \author Karl Rasche
31 */
32
33 #include "glheader.h"
34 #include "context.h"
35 #include "arbvertparse.h"
36 #include "hash.h"
37 #include "imports.h"
38 #include "macros.h"
39 #include "mtypes.h"
40 #include "program.h"
41 #include "nvprogram.h"
42 #include "nvvertparse.h"
43 #include "nvvertprog.h"
44
45 #include "arbprogparse.h"
46
47
48 /**
49 * XXX this is probably redundant. We've already got code like this
50 * in the nvvertparse.c file. Combine/clean-up someday.
51 */
52 void _mesa_debug_vp_inst(GLint num, struct vp_instruction *vp)
53 {
54 GLint a;
55 static const char *opcode_string[] = {
56 "ABS",
57 "ADD",
58 "ARL",
59 "DP3",
60 "DP4",
61 "DPH",
62 "DST",
63 "END", /* Placeholder */
64 "EX2", /* ARB only */
65 "EXP",
66 "FLR", /* ARB */
67 "FRC", /* ARB */
68 "LG2", /* ARB only */
69 "LIT",
70 "LOG",
71 "MAD",
72 "MAX",
73 "MIN",
74 "MOV",
75 "MUL",
76 "POW", /* ARB only */
77 "PRINT", /* Mesa only */
78 "RCC",
79 "RCP",
80 "RSQ",
81 "SGE",
82 "SLT",
83 "SUB",
84 "SWZ", /* ARB only */
85 "XPD" /* ARB only */
86 };
87
88 static const char *file_string[] = {
89 "TEMP",
90 "INPUT",
91 "OUTPUT",
92 "LOCAL",
93 "ENV",
94 "NAMED",
95 "STATE",
96 "WRITE_ONLY",
97 "ADDR"
98 };
99
100 static const char swz[] = "xyzw01??";
101
102 for (a=0; a<num; a++) {
103 _mesa_printf("%s", opcode_string[vp[a].Opcode]);
104
105 if (vp[a].DstReg.File != 0xf) {
106 if (vp[a].DstReg.WriteMask != 0xf)
107 _mesa_printf(" %s[%d].%s%s%s%s ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index,
108 GET_BIT(vp[a].DstReg.WriteMask, 0) ? "x" : "",
109 GET_BIT(vp[a].DstReg.WriteMask, 1) ? "y" : "",
110 GET_BIT(vp[a].DstReg.WriteMask, 2) ? "z" : "",
111 GET_BIT(vp[a].DstReg.WriteMask, 3) ? "w" : "");
112 else
113 _mesa_printf(" %s[%d] ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index);
114 }
115
116 if (vp[a].SrcReg[0].File != 0xf) {
117 if (vp[a].SrcReg[0].Swizzle != SWIZZLE_NOOP)
118 _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index,
119 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 0)],
120 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 1)],
121 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 2)],
122 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 3)]);
123 else
124 _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index);
125 }
126
127 if (vp[a].SrcReg[1].File != 0xf) {
128 if (vp[a].SrcReg[1].Swizzle != SWIZZLE_NOOP)
129 _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index,
130 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 0)],
131 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 1)],
132 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 2)],
133 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 3)]);
134 else
135 _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index);
136 }
137
138 if (vp[a].SrcReg[2].File != 0xf) {
139 if (vp[a].SrcReg[2].Swizzle != SWIZZLE_NOOP)
140 _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index,
141 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 0)],
142 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 1)],
143 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 2)],
144 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 3)]);
145 else
146 _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index);
147 }
148
149 _mesa_printf("\n");
150 }
151 }
152
153
154 void
155 _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
156 const GLubyte * str, GLsizei len,
157 struct vertex_program *program)
158 {
159 GLuint retval;
160 struct arb_program ap;
161 (void) target;
162
163 /* set the program target before parsing */
164 ap.Base.Target = GL_VERTEX_PROGRAM_ARB;
165
166 retval = _mesa_parse_arb_program(ctx, str, len, &ap);
167
168 /* Parse error. Allocate a dummy program and return */
169 if (retval)
170 {
171 program->Instructions = (struct vp_instruction *)
172 _mesa_malloc ( sizeof(struct vp_instruction) );
173 program->Instructions[0].Opcode = VP_OPCODE_END;
174 return;
175 }
176
177 /* copy the relvant contents of the arb_program struct into the
178 * fragment_program struct
179 */
180 program->Base.String = ap.Base.String;
181 program->Base.NumInstructions = ap.Base.NumInstructions;
182 program->Base.NumTemporaries = ap.Base.NumTemporaries;
183 program->Base.NumParameters = ap.Base.NumParameters;
184 program->Base.NumAttributes = ap.Base.NumAttributes;
185 program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
186
187 program->IsPositionInvariant = ap.HintPositionInvariant;
188 program->InputsRead = ap.InputsRead;
189 program->OutputsWritten = ap.OutputsWritten;
190 program->Parameters = ap.Parameters;
191
192 program->Instructions = ap.VPInstructions;
193
194 #if DEBUG_VP
195 _mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
196 #endif
197
198 }