chmod a-x
[mesa.git] / src / mesa / shader / slang / slang_export.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_export.c
27 * interface between assembly code and the application
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_export.h"
33
34 /*
35 * slang_export_data_quant
36 */
37
38 GLvoid slang_export_data_quant_ctr (slang_export_data_quant *self)
39 {
40 self->name = SLANG_ATOM_NULL;
41 self->size = 0;
42 self->array_len = 0;
43 self->structure = NULL;
44 self->u.basic_type = GL_FLOAT;
45 }
46
47 GLvoid slang_export_data_quant_dtr (slang_export_data_quant *self)
48 {
49 if (self->structure != NULL)
50 {
51 GLuint i;
52
53 for (i = 0; i < self->u.field_count; i++)
54 slang_export_data_quant_dtr (&self->structure[i]);
55 slang_alloc_free (self->structure);
56 }
57 }
58
59 slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *self)
60 {
61 const GLuint n = self->u.field_count;
62
63 self->structure = (slang_export_data_quant *) slang_alloc_realloc (self->structure,
64 n * sizeof (slang_export_data_quant), (n + 1) * sizeof (slang_export_data_quant));
65 if (self->structure == NULL)
66 return NULL;
67 slang_export_data_quant_ctr (&self->structure[n]);
68 self->u.field_count++;
69 return &self->structure[n];
70 }
71
72 GLboolean slang_export_data_quant_array (slang_export_data_quant *self)
73 {
74 return self->array_len != 0;
75 }
76
77 GLboolean slang_export_data_quant_struct (slang_export_data_quant *self)
78 {
79 return self->structure != NULL;
80 }
81
82 GLboolean slang_export_data_quant_simple (slang_export_data_quant *self)
83 {
84 return self->array_len == 0 && self->structure == NULL;
85 }
86
87 GLenum slang_export_data_quant_type (slang_export_data_quant *self)
88 {
89 assert (self->structure == NULL);
90 return self->u.basic_type;
91 }
92
93 GLuint slang_export_data_quant_fields (slang_export_data_quant *self)
94 {
95 assert (self->structure != NULL);
96 return self->u.field_count;
97 }
98
99 GLuint slang_export_data_quant_elements (slang_export_data_quant *self)
100 {
101 if (self->array_len == 0)
102 return 1;
103 return self->array_len;
104 }
105
106 GLuint slang_export_data_quant_components (slang_export_data_quant *self)
107 {
108 return self->size / 4;
109 }
110
111 GLuint slang_export_data_quant_size (slang_export_data_quant *self)
112 {
113 return self->size;
114 }
115
116 /*
117 * slang_export_data_entry
118 */
119
120 GLvoid slang_export_data_entry_ctr (slang_export_data_entry *self)
121 {
122 slang_export_data_quant_ctr (&self->quant);
123 self->access = slang_exp_uniform;
124 self->address = ~0;
125 }
126
127 GLvoid slang_export_data_entry_dtr (slang_export_data_entry *self)
128 {
129 slang_export_data_quant_dtr (&self->quant);
130 }
131
132 /*
133 * slang_export_data_table
134 */
135
136 GLvoid slang_export_data_table_ctr (slang_export_data_table *self)
137 {
138 self->entries = NULL;
139 self->count = 0;
140 self->atoms = NULL;
141 }
142
143 GLvoid slang_export_data_table_dtr (slang_export_data_table *self)
144 {
145 if (self->entries != NULL)
146 {
147 GLuint i;
148
149 for (i = 0; i < self->count; i++)
150 slang_export_data_entry_dtr (&self->entries[i]);
151 slang_alloc_free (self->entries);
152 }
153 }
154
155 slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *self)
156 {
157 const GLuint n = self->count;
158
159 self->entries = (slang_export_data_entry *) slang_alloc_realloc (self->entries,
160 n * sizeof (slang_export_data_entry), (n + 1) * sizeof (slang_export_data_entry));
161 if (self->entries == NULL)
162 return NULL;
163 slang_export_data_entry_ctr (&self->entries[n]);
164 self->count++;
165 return &self->entries[n];
166 }
167
168 /*
169 * slang_export_code_entry
170 */
171
172 static GLvoid slang_export_code_entry_ctr (slang_export_code_entry *self)
173 {
174 self->name = SLANG_ATOM_NULL;
175 self->address = ~0;
176 }
177
178 static GLvoid slang_export_code_entry_dtr (slang_export_code_entry *self)
179 {
180 }
181
182 /*
183 * slang_export_code_table
184 */
185
186 GLvoid slang_export_code_table_ctr (slang_export_code_table *self)
187 {
188 self->entries = NULL;
189 self->count = 0;
190 self->atoms = NULL;
191 }
192
193 GLvoid slang_export_code_table_dtr (slang_export_code_table *self)
194 {
195 if (self->entries != NULL)
196 {
197 GLuint i;
198
199 for (i = 0; i < self->count; i++)
200 slang_export_code_entry_dtr (&self->entries[i]);
201 slang_alloc_free (self->entries);
202 }
203 }
204
205 slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *self)
206 {
207 const GLuint n = self->count;
208
209 self->entries = (slang_export_code_entry *) slang_alloc_realloc (self->entries,
210 n * sizeof (slang_export_code_entry), (n + 1) * sizeof (slang_export_code_entry));
211 if (self->entries == NULL)
212 return NULL;
213 slang_export_code_entry_ctr (&self->entries[n]);
214 self->count++;
215 return &self->entries[n];
216 }
217
218 /*
219 * _slang_find_exported_data()
220 */
221
222 #define EXTRACT_ERROR 0
223 #define EXTRACT_BASIC 1
224 #define EXTRACT_ARRAY 2
225 #define EXTRACT_STRUCT 3
226 #define EXTRACT_STRUCT_ARRAY 4
227
228 #define EXTRACT_MAXLEN 255
229
230 static GLuint extract_name (const char *name, char *parsed, GLuint *element, const char **end)
231 {
232 GLuint i;
233
234 if ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z') || name[0] == '_')
235 {
236 parsed[0] = name[0];
237
238 for (i = 1; i < EXTRACT_MAXLEN; i++)
239 {
240 if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') ||
241 (name[i] >= '0' && name[i] <= '9') || name[0] == '_')
242 {
243 parsed[i] = name[i];
244 }
245 else
246 {
247 if (name[i] == '\0')
248 {
249 parsed[i] = '\0';
250 return EXTRACT_BASIC;
251 }
252 if (name[i] == '.')
253 {
254 parsed[i] = '\0';
255 *end = &name[i + 1];
256 return EXTRACT_STRUCT;
257 }
258 if (name[i] == '[')
259 {
260 parsed[i] = '\0';
261 i++;
262 if (name[i] >= '0' && name[i] <= '9')
263 {
264 *element = name[i] - '0';
265 for (i++; ; i++)
266 {
267 if (name[i] >= '0' && name[i] <= '9')
268 *element = *element * 10 + (name[i] - '0');
269 else
270 {
271 if (name[i] == ']')
272 {
273 i++;
274 if (name[i] == '.')
275 {
276 *end = &name[i + 1];
277 return EXTRACT_STRUCT_ARRAY;
278 }
279 *end = &name[i];
280 return EXTRACT_ARRAY;
281 }
282 break;
283 }
284 }
285 }
286 }
287 break;
288 }
289 }
290 }
291 return EXTRACT_ERROR;
292 }
293
294 static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element, GLuint extr)
295 {
296 switch (extr)
297 {
298 case EXTRACT_BASIC:
299 return GL_TRUE;
300 case EXTRACT_ARRAY:
301 return element < slang_export_data_quant_elements (q);
302 case EXTRACT_STRUCT:
303 return slang_export_data_quant_struct (q);
304 case EXTRACT_STRUCT_ARRAY:
305 return slang_export_data_quant_struct (q) && element < slang_export_data_quant_elements (q);
306 }
307 return GL_FALSE;
308 }
309
310 static GLuint calculate_offset (slang_export_data_quant *q, GLuint element)
311 {
312 if (slang_export_data_quant_array (q))
313 return element * slang_export_data_quant_size (q);
314 return 0;
315 }
316
317 static GLboolean find_exported_data (slang_export_data_quant *q, const char *name,
318 slang_export_data_quant **quant, GLuint *offset, slang_atom_pool *atoms)
319 {
320 char parsed[EXTRACT_MAXLEN];
321 GLuint result, element, i;
322 const char *end;
323 slang_atom atom;
324 const GLuint fields = slang_export_data_quant_fields (q);
325
326 result = extract_name (name, parsed, &element, &end);
327 if (result == EXTRACT_ERROR)
328 return GL_FALSE;
329
330 atom = slang_atom_pool_atom (atoms, parsed);
331 if (atom == SLANG_ATOM_NULL)
332 return GL_FALSE;
333
334 for (i = 0; i < fields; i++)
335 if (q->structure[i].name == atom)
336 {
337 if (!validate_extracted (&q->structure[i], element, result))
338 return GL_FALSE;
339 *offset += calculate_offset (&q->structure[i], element);
340 if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY)
341 {
342 if (*end != '\0')
343 return GL_FALSE;
344 *quant = &q->structure[i];
345 return GL_TRUE;
346 }
347 return find_exported_data (&q->structure[i], end, quant, offset, atoms);
348 }
349 return GL_FALSE;
350 }
351
352 GLboolean _slang_find_exported_data (slang_export_data_table *table, const char *name,
353 slang_export_data_entry **entry, slang_export_data_quant **quant, GLuint *offset)
354 {
355 char parsed[EXTRACT_MAXLEN];
356 GLuint result, element, i;
357 const char *end;
358 slang_atom atom;
359
360 result = extract_name (name, parsed, &element, &end);
361 if (result == EXTRACT_ERROR)
362 return GL_FALSE;
363
364 atom = slang_atom_pool_atom (table->atoms, parsed);
365 if (atom == SLANG_ATOM_NULL)
366 return GL_FALSE;
367
368 for (i = 0; i < table->count; i++)
369 if (table->entries[i].quant.name == atom)
370 {
371 if (!validate_extracted (&table->entries[i].quant, element, result))
372 return GL_FALSE;
373 *entry = &table->entries[i];
374 *offset = calculate_offset (&table->entries[i].quant, element);
375 if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY)
376 {
377 if (*end != '\0')
378 return GL_FALSE;
379 *quant = &table->entries[i].quant;
380 return GL_TRUE;
381 }
382 return find_exported_data (&table->entries[i].quant, end, quant, offset, table->atoms);
383 }
384 return GL_FALSE;
385 }
386