Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * Version: 7.3 |
||
4 | * |
||
5 | * Copyright (C) 1999-2008 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 prog_parameter.c |
||
27 | * Program parameter lists and functions. |
||
28 | * \author Brian Paul |
||
29 | */ |
||
30 | |||
31 | |||
32 | #include "main/glheader.h" |
||
33 | #include "main/imports.h" |
||
34 | #include "main/macros.h" |
||
35 | #include "prog_instruction.h" |
||
36 | #include "prog_parameter.h" |
||
37 | #include "prog_statevars.h" |
||
38 | |||
39 | |||
40 | struct gl_program_parameter_list * |
||
41 | _mesa_new_parameter_list(void) |
||
42 | { |
||
43 | return CALLOC_STRUCT(gl_program_parameter_list); |
||
44 | } |
||
45 | |||
46 | |||
47 | struct gl_program_parameter_list * |
||
48 | _mesa_new_parameter_list_sized(unsigned size) |
||
49 | { |
||
50 | struct gl_program_parameter_list *p = _mesa_new_parameter_list(); |
||
51 | |||
52 | if ((p != NULL) && (size != 0)) { |
||
53 | p->Size = size; |
||
54 | |||
55 | /* alloc arrays */ |
||
56 | p->Parameters = (struct gl_program_parameter *) |
||
57 | calloc(1, size * sizeof(struct gl_program_parameter)); |
||
58 | |||
59 | p->ParameterValues = (GLfloat (*)[4]) |
||
60 | _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16); |
||
61 | |||
62 | |||
63 | if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) { |
||
64 | free(p->Parameters); |
||
65 | _mesa_align_free(p->ParameterValues); |
||
66 | free(p); |
||
67 | p = NULL; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | return p; |
||
72 | } |
||
73 | |||
74 | |||
75 | /** |
||
76 | * Free a parameter list and all its parameters |
||
77 | */ |
||
78 | void |
||
79 | _mesa_free_parameter_list(struct gl_program_parameter_list *paramList) |
||
80 | { |
||
81 | GLuint i; |
||
82 | for (i = 0; i < paramList->NumParameters; i++) { |
||
83 | if (paramList->Parameters[i].Name) |
||
84 | free((void *) paramList->Parameters[i].Name); |
||
85 | } |
||
86 | free(paramList->Parameters); |
||
87 | if (paramList->ParameterValues) |
||
88 | _mesa_align_free(paramList->ParameterValues); |
||
89 | free(paramList); |
||
90 | } |
||
91 | |||
92 | |||
93 | /** |
||
94 | * Add a new parameter to a parameter list. |
||
95 | * Note that parameter values are usually 4-element GLfloat vectors. |
||
96 | * When size > 4 we'll allocate a sequential block of parameters to |
||
97 | * store all the values (in blocks of 4). |
||
98 | * |
||
99 | * \param paramList the list to add the parameter to |
||
100 | * \param type type of parameter, such as |
||
101 | * \param name the parameter name, will be duplicated/copied! |
||
102 | * \param size number of elements in 'values' vector (1..4, or more) |
||
103 | * \param datatype GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE. |
||
104 | * \param values initial parameter value, up to 4 GLfloats, or NULL |
||
105 | * \param state state indexes, or NULL |
||
106 | * \return index of new parameter in the list, or -1 if error (out of mem) |
||
107 | */ |
||
108 | GLint |
||
109 | _mesa_add_parameter(struct gl_program_parameter_list *paramList, |
||
110 | gl_register_file type, const char *name, |
||
111 | GLuint size, GLenum datatype, const GLfloat *values, |
||
112 | const gl_state_index state[STATE_LENGTH], |
||
113 | GLbitfield flags) |
||
114 | { |
||
115 | const GLuint oldNum = paramList->NumParameters; |
||
116 | const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */ |
||
117 | |||
118 | assert(size > 0); |
||
119 | |||
120 | if (oldNum + sz4 > paramList->Size) { |
||
121 | /* Need to grow the parameter list array (alloc some extra) */ |
||
122 | paramList->Size = paramList->Size + 4 * sz4; |
||
123 | |||
124 | /* realloc arrays */ |
||
125 | paramList->Parameters = (struct gl_program_parameter *) |
||
126 | _mesa_realloc(paramList->Parameters, |
||
127 | oldNum * sizeof(struct gl_program_parameter), |
||
128 | paramList->Size * sizeof(struct gl_program_parameter)); |
||
129 | |||
130 | paramList->ParameterValues = (GLfloat (*)[4]) |
||
131 | _mesa_align_realloc(paramList->ParameterValues, /* old buf */ |
||
132 | oldNum * 4 * sizeof(GLfloat), /* old size */ |
||
133 | paramList->Size * 4 *sizeof(GLfloat), /* new sz */ |
||
134 | 16); |
||
135 | } |
||
136 | |||
137 | if (!paramList->Parameters || |
||
138 | !paramList->ParameterValues) { |
||
139 | /* out of memory */ |
||
140 | paramList->NumParameters = 0; |
||
141 | paramList->Size = 0; |
||
142 | return -1; |
||
143 | } |
||
144 | else { |
||
145 | GLuint i; |
||
146 | |||
147 | paramList->NumParameters = oldNum + sz4; |
||
148 | |||
149 | memset(¶mList->Parameters[oldNum], 0, |
||
150 | sz4 * sizeof(struct gl_program_parameter)); |
||
151 | |||
152 | for (i = 0; i < sz4; i++) { |
||
153 | struct gl_program_parameter *p = paramList->Parameters + oldNum + i; |
||
154 | p->Name = name ? _mesa_strdup(name) : NULL; |
||
155 | p->Type = type; |
||
156 | p->Size = size; |
||
157 | p->DataType = datatype; |
||
158 | p->Flags = flags; |
||
159 | if (values) { |
||
160 | COPY_4V(paramList->ParameterValues[oldNum + i], values); |
||
161 | values += 4; |
||
162 | p->Initialized = GL_TRUE; |
||
163 | } |
||
164 | else { |
||
165 | /* silence valgrind */ |
||
166 | ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0); |
||
167 | } |
||
168 | size -= 4; |
||
169 | } |
||
170 | |||
171 | if (state) { |
||
172 | for (i = 0; i < STATE_LENGTH; i++) |
||
173 | paramList->Parameters[oldNum].StateIndexes[i] = state[i]; |
||
174 | } |
||
175 | |||
176 | return (GLint) oldNum; |
||
177 | } |
||
178 | } |
||
179 | |||
180 | |||
181 | /** |
||
182 | * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement) |
||
183 | * \return index of the new entry in the parameter list |
||
184 | */ |
||
185 | GLint |
||
186 | _mesa_add_named_parameter(struct gl_program_parameter_list *paramList, |
||
187 | const char *name, const GLfloat values[4]) |
||
188 | { |
||
189 | return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name, |
||
190 | 4, GL_NONE, values, NULL, 0x0); |
||
191 | |||
192 | } |
||
193 | |||
194 | |||
195 | /** |
||
196 | * Add a new named constant to the parameter list. |
||
197 | * This will be used when the program contains something like this: |
||
198 | * PARAM myVals = { 0, 1, 2, 3 }; |
||
199 | * |
||
200 | * \param paramList the parameter list |
||
201 | * \param name the name for the constant |
||
202 | * \param values four float values |
||
203 | * \return index/position of the new parameter in the parameter list |
||
204 | */ |
||
205 | GLint |
||
206 | _mesa_add_named_constant(struct gl_program_parameter_list *paramList, |
||
207 | const char *name, const GLfloat values[4], |
||
208 | GLuint size) |
||
209 | { |
||
210 | /* first check if this is a duplicate constant */ |
||
211 | GLint pos; |
||
212 | for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) { |
||
213 | const GLfloat *pvals = paramList->ParameterValues[pos]; |
||
214 | if (pvals[0] == values[0] && |
||
215 | pvals[1] == values[1] && |
||
216 | pvals[2] == values[2] && |
||
217 | pvals[3] == values[3] && |
||
218 | strcmp(paramList->Parameters[pos].Name, name) == 0) { |
||
219 | /* Same name and value is already in the param list - reuse it */ |
||
220 | return pos; |
||
221 | } |
||
222 | } |
||
223 | /* not found, add new parameter */ |
||
224 | return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, |
||
225 | size, GL_NONE, values, NULL, 0x0); |
||
226 | } |
||
227 | |||
228 | |||
229 | /** |
||
230 | * Add a new unnamed constant to the parameter list. This will be used |
||
231 | * when a fragment/vertex program contains something like this: |
||
232 | * MOV r, { 0, 1, 2, 3 }; |
||
233 | * If swizzleOut is non-null we'll search the parameter list for an |
||
234 | * existing instance of the constant which matches with a swizzle. |
||
235 | * |
||
236 | * \param paramList the parameter list |
||
237 | * \param values four float values |
||
238 | * \param swizzleOut returns swizzle mask for accessing the constant |
||
239 | * \return index/position of the new parameter in the parameter list. |
||
240 | */ |
||
241 | GLint |
||
242 | _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, |
||
243 | const GLfloat values[4], GLuint size, |
||
244 | GLuint *swizzleOut) |
||
245 | { |
||
246 | GLint pos; |
||
247 | ASSERT(size >= 1); |
||
248 | ASSERT(size <= 4); |
||
249 | |||
250 | if (swizzleOut && |
||
251 | _mesa_lookup_parameter_constant(paramList, values, |
||
252 | size, &pos, swizzleOut)) { |
||
253 | return pos; |
||
254 | } |
||
255 | |||
256 | /* Look for empty space in an already unnamed constant parameter |
||
257 | * to add this constant. This will only work for single-element |
||
258 | * constants because we rely on smearing (i.e. .yyyy or .zzzz). |
||
259 | */ |
||
260 | if (size == 1 && swizzleOut) { |
||
261 | for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { |
||
262 | struct gl_program_parameter *p = paramList->Parameters + pos; |
||
263 | if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { |
||
264 | /* ok, found room */ |
||
265 | GLfloat *pVal = paramList->ParameterValues[pos]; |
||
266 | GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */ |
||
267 | pVal[p->Size] = values[0]; |
||
268 | p->Size++; |
||
269 | *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz); |
||
270 | return pos; |
||
271 | } |
||
272 | } |
||
273 | } |
||
274 | |||
275 | /* add a new parameter to store this constant */ |
||
276 | pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, |
||
277 | size, GL_NONE, values, NULL, 0x0); |
||
278 | if (pos >= 0 && swizzleOut) { |
||
279 | if (size == 1) |
||
280 | *swizzleOut = SWIZZLE_XXXX; |
||
281 | else |
||
282 | *swizzleOut = SWIZZLE_NOOP; |
||
283 | } |
||
284 | return pos; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Add parameter representing a varying variable. |
||
289 | */ |
||
290 | GLint |
||
291 | _mesa_add_varying(struct gl_program_parameter_list *paramList, |
||
292 | const char *name, GLuint size, GLenum datatype, |
||
293 | GLbitfield flags) |
||
294 | { |
||
295 | GLint i = _mesa_lookup_parameter_index(paramList, -1, name); |
||
296 | if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) { |
||
297 | /* already in list */ |
||
298 | return i; |
||
299 | } |
||
300 | else { |
||
301 | /*assert(size == 4);*/ |
||
302 | i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name, |
||
303 | size, datatype, NULL, NULL, flags); |
||
304 | return i; |
||
305 | } |
||
306 | } |
||
307 | |||
308 | |||
309 | /** |
||
310 | * Add parameter representing a vertex program attribute. |
||
311 | * \param size size of attribute (in floats), may be -1 if unknown |
||
312 | * \param attrib the attribute index, or -1 if unknown |
||
313 | */ |
||
314 | GLint |
||
315 | _mesa_add_attribute(struct gl_program_parameter_list *paramList, |
||
316 | const char *name, GLint size, GLenum datatype, GLint attrib) |
||
317 | { |
||
318 | GLint i = _mesa_lookup_parameter_index(paramList, -1, name); |
||
319 | if (i >= 0) { |
||
320 | /* replace */ |
||
321 | if (attrib < 0) |
||
322 | attrib = i; |
||
323 | paramList->Parameters[i].StateIndexes[0] = attrib; |
||
324 | } |
||
325 | else { |
||
326 | /* add */ |
||
327 | gl_state_index state[STATE_LENGTH]; |
||
328 | state[0] = (gl_state_index) attrib; |
||
329 | if (size < 0) |
||
330 | size = 4; |
||
331 | i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name, |
||
332 | size, datatype, NULL, state, 0x0); |
||
333 | } |
||
334 | return i; |
||
335 | } |
||
336 | |||
337 | |||
338 | |||
339 | #if 0 /* not used yet */ |
||
340 | /** |
||
341 | * Returns the number of 4-component registers needed to store a piece |
||
342 | * of GL state. For matrices this may be as many as 4 registers, |
||
343 | * everything else needs |
||
344 | * just 1 register. |
||
345 | */ |
||
346 | static GLuint |
||
347 | sizeof_state_reference(const GLint *stateTokens) |
||
348 | { |
||
349 | if (stateTokens[0] == STATE_MATRIX) { |
||
350 | GLuint rows = stateTokens[4] - stateTokens[3] + 1; |
||
351 | assert(rows >= 1); |
||
352 | assert(rows <= 4); |
||
353 | return rows; |
||
354 | } |
||
355 | else { |
||
356 | return 1; |
||
357 | } |
||
358 | } |
||
359 | #endif |
||
360 | |||
361 | |||
362 | /** |
||
363 | * Add a new state reference to the parameter list. |
||
364 | * This will be used when the program contains something like this: |
||
365 | * PARAM ambient = state.material.front.ambient; |
||
366 | * |
||
367 | * \param paramList the parameter list |
||
368 | * \param stateTokens an array of 5 (STATE_LENGTH) state tokens |
||
369 | * \return index of the new parameter. |
||
370 | */ |
||
371 | GLint |
||
372 | _mesa_add_state_reference(struct gl_program_parameter_list *paramList, |
||
373 | const gl_state_index stateTokens[STATE_LENGTH]) |
||
374 | { |
||
375 | const GLuint size = 4; /* XXX fix */ |
||
376 | char *name; |
||
377 | GLint index; |
||
378 | |||
379 | /* Check if the state reference is already in the list */ |
||
380 | for (index = 0; index < (GLint) paramList->NumParameters; index++) { |
||
381 | if (!memcmp(paramList->Parameters[index].StateIndexes, |
||
382 | stateTokens, STATE_LENGTH * sizeof(gl_state_index))) { |
||
383 | return index; |
||
384 | } |
||
385 | } |
||
386 | |||
387 | name = _mesa_program_state_string(stateTokens); |
||
388 | index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name, |
||
389 | size, GL_NONE, |
||
390 | NULL, (gl_state_index *) stateTokens, 0x0); |
||
391 | paramList->StateFlags |= _mesa_program_state_flags(stateTokens); |
||
392 | |||
393 | /* free name string here since we duplicated it in add_parameter() */ |
||
394 | free(name); |
||
395 | |||
396 | return index; |
||
397 | } |
||
398 | |||
399 | |||
400 | /** |
||
401 | * Lookup a parameter value by name in the given parameter list. |
||
402 | * \return pointer to the float[4] values. |
||
403 | */ |
||
404 | GLfloat * |
||
405 | _mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, |
||
406 | GLsizei nameLen, const char *name) |
||
407 | { |
||
408 | GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name); |
||
409 | if (i < 0) |
||
410 | return NULL; |
||
411 | else |
||
412 | return paramList->ParameterValues[i]; |
||
413 | } |
||
414 | |||
415 | |||
416 | /** |
||
417 | * Given a program parameter name, find its position in the list of parameters. |
||
418 | * \param paramList the parameter list to search |
||
419 | * \param nameLen length of name (in chars). |
||
420 | * If length is negative, assume that name is null-terminated. |
||
421 | * \param name the name to search for |
||
422 | * \return index of parameter in the list. |
||
423 | */ |
||
424 | GLint |
||
425 | _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, |
||
426 | GLsizei nameLen, const char *name) |
||
427 | { |
||
428 | GLint i; |
||
429 | |||
430 | if (!paramList) |
||
431 | return -1; |
||
432 | |||
433 | if (nameLen == -1) { |
||
434 | /* name is null-terminated */ |
||
435 | for (i = 0; i < (GLint) paramList->NumParameters; i++) { |
||
436 | if (paramList->Parameters[i].Name && |
||
437 | strcmp(paramList->Parameters[i].Name, name) == 0) |
||
438 | return i; |
||
439 | } |
||
440 | } |
||
441 | else { |
||
442 | /* name is not null-terminated, use nameLen */ |
||
443 | for (i = 0; i < (GLint) paramList->NumParameters; i++) { |
||
444 | if (paramList->Parameters[i].Name && |
||
445 | strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 |
||
446 | && strlen(paramList->Parameters[i].Name) == (size_t)nameLen) |
||
447 | return i; |
||
448 | } |
||
449 | } |
||
450 | return -1; |
||
451 | } |
||
452 | |||
453 | |||
454 | /** |
||
455 | * Look for a float vector in the given parameter list. The float vector |
||
456 | * may be of length 1, 2, 3 or 4. If swizzleOut is non-null, we'll try |
||
457 | * swizzling to find a match. |
||
458 | * \param list the parameter list to search |
||
459 | * \param v the float vector to search for |
||
460 | * \param vSize number of element in v |
||
461 | * \param posOut returns the position of the constant, if found |
||
462 | * \param swizzleOut returns a swizzle mask describing location of the |
||
463 | * vector elements if found. |
||
464 | * \return GL_TRUE if found, GL_FALSE if not found |
||
465 | */ |
||
466 | GLboolean |
||
467 | _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, |
||
468 | const GLfloat v[], GLuint vSize, |
||
469 | GLint *posOut, GLuint *swizzleOut) |
||
470 | { |
||
471 | GLuint i; |
||
472 | |||
473 | assert(vSize >= 1); |
||
474 | assert(vSize <= 4); |
||
475 | |||
476 | if (!list) { |
||
477 | *posOut = -1; |
||
478 | return GL_FALSE; |
||
479 | } |
||
480 | |||
481 | for (i = 0; i < list->NumParameters; i++) { |
||
482 | if (list->Parameters[i].Type == PROGRAM_CONSTANT) { |
||
483 | if (!swizzleOut) { |
||
484 | /* swizzle not allowed */ |
||
485 | GLuint j, match = 0; |
||
486 | for (j = 0; j < vSize; j++) { |
||
487 | if (v[j] == list->ParameterValues[i][j]) |
||
488 | match++; |
||
489 | } |
||
490 | if (match == vSize) { |
||
491 | *posOut = i; |
||
492 | return GL_TRUE; |
||
493 | } |
||
494 | } |
||
495 | else { |
||
496 | /* try matching w/ swizzle */ |
||
497 | if (vSize == 1) { |
||
498 | /* look for v[0] anywhere within float[4] value */ |
||
499 | GLuint j; |
||
500 | for (j = 0; j < list->Parameters[i].Size; j++) { |
||
501 | if (list->ParameterValues[i][j] == v[0]) { |
||
502 | /* found it */ |
||
503 | *posOut = i; |
||
504 | *swizzleOut = MAKE_SWIZZLE4(j, j, j, j); |
||
505 | return GL_TRUE; |
||
506 | } |
||
507 | } |
||
508 | } |
||
509 | else if (vSize <= list->Parameters[i].Size) { |
||
510 | /* see if we can match this constant (with a swizzle) */ |
||
511 | GLuint swz[4]; |
||
512 | GLuint match = 0, j, k; |
||
513 | for (j = 0; j < vSize; j++) { |
||
514 | if (v[j] == list->ParameterValues[i][j]) { |
||
515 | swz[j] = j; |
||
516 | match++; |
||
517 | } |
||
518 | else { |
||
519 | for (k = 0; k < list->Parameters[i].Size; k++) { |
||
520 | if (v[j] == list->ParameterValues[i][k]) { |
||
521 | swz[j] = k; |
||
522 | match++; |
||
523 | break; |
||
524 | } |
||
525 | } |
||
526 | } |
||
527 | } |
||
528 | /* smear last value to remaining positions */ |
||
529 | for (; j < 4; j++) |
||
530 | swz[j] = swz[j-1]; |
||
531 | |||
532 | if (match == vSize) { |
||
533 | *posOut = i; |
||
534 | *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); |
||
535 | return GL_TRUE; |
||
536 | } |
||
537 | } |
||
538 | } |
||
539 | } |
||
540 | } |
||
541 | |||
542 | *posOut = -1; |
||
543 | return GL_FALSE; |
||
544 | } |
||
545 | |||
546 | |||
547 | struct gl_program_parameter_list * |
||
548 | _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) |
||
549 | { |
||
550 | struct gl_program_parameter_list *clone; |
||
551 | GLuint i; |
||
552 | |||
553 | clone = _mesa_new_parameter_list(); |
||
554 | if (!clone) |
||
555 | return NULL; |
||
556 | |||
557 | /** Not too efficient, but correct */ |
||
558 | for (i = 0; i < list->NumParameters; i++) { |
||
559 | struct gl_program_parameter *p = list->Parameters + i; |
||
560 | struct gl_program_parameter *pCopy; |
||
561 | GLuint size = MIN2(p->Size, 4); |
||
562 | GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType, |
||
563 | list->ParameterValues[i], NULL, 0x0); |
||
564 | ASSERT(j >= 0); |
||
565 | pCopy = clone->Parameters + j; |
||
566 | pCopy->Flags = p->Flags; |
||
567 | /* copy state indexes */ |
||
568 | if (p->Type == PROGRAM_STATE_VAR) { |
||
569 | GLint k; |
||
570 | for (k = 0; k < STATE_LENGTH; k++) { |
||
571 | pCopy->StateIndexes[k] = p->StateIndexes[k]; |
||
572 | } |
||
573 | } |
||
574 | else { |
||
575 | clone->Parameters[j].Size = p->Size; |
||
576 | } |
||
577 | |||
578 | } |
||
579 | |||
580 | clone->StateFlags = list->StateFlags; |
||
581 | |||
582 | return clone; |
||
583 | } |
||
584 | |||
585 | |||
586 | /** |
||
587 | * Return a new parameter list which is listA + listB. |
||
588 | */ |
||
589 | struct gl_program_parameter_list * |
||
590 | _mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA, |
||
591 | const struct gl_program_parameter_list *listB) |
||
592 | { |
||
593 | struct gl_program_parameter_list *list; |
||
594 | |||
595 | if (listA) { |
||
596 | list = _mesa_clone_parameter_list(listA); |
||
597 | if (list && listB) { |
||
598 | GLuint i; |
||
599 | for (i = 0; i < listB->NumParameters; i++) { |
||
600 | struct gl_program_parameter *param = listB->Parameters + i; |
||
601 | _mesa_add_parameter(list, param->Type, param->Name, param->Size, |
||
602 | param->DataType, |
||
603 | listB->ParameterValues[i], |
||
604 | param->StateIndexes, |
||
605 | param->Flags); |
||
606 | } |
||
607 | } |
||
608 | } |
||
609 | else if (listB) { |
||
610 | list = _mesa_clone_parameter_list(listB); |
||
611 | } |
||
612 | else { |
||
613 | list = NULL; |
||
614 | } |
||
615 | return list; |
||
616 | } |
||
617 | |||
618 | |||
619 | |||
620 | /** |
||
621 | * Find longest name of all uniform parameters in list. |
||
622 | */ |
||
623 | GLuint |
||
624 | _mesa_longest_parameter_name(const struct gl_program_parameter_list *list, |
||
625 | gl_register_file type) |
||
626 | { |
||
627 | GLuint i, maxLen = 0; |
||
628 | if (!list) |
||
629 | return 0; |
||
630 | for (i = 0; i < list->NumParameters; i++) { |
||
631 | if (list->Parameters[i].Type == type) { |
||
632 | GLuint len = strlen(list->Parameters[i].Name); |
||
633 | if (len > maxLen) |
||
634 | maxLen = len; |
||
635 | } |
||
636 | } |
||
637 | return maxLen; |
||
638 | } |
||
639 | |||
640 | |||
641 | /** |
||
642 | * Count the number of parameters in the last that match the given type. |
||
643 | */ |
||
644 | GLuint |
||
645 | _mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, |
||
646 | gl_register_file type) |
||
647 | { |
||
648 | GLuint i, count = 0; |
||
649 | if (list) { |
||
650 | for (i = 0; i < list->NumParameters; i++) { |
||
651 | if (list->Parameters[i].Type == type) |
||
652 | count++; |
||
653 | } |
||
654 | } |
||
655 | return count; |
||
656 | }>>>>>>>>=>>>>=>>>>>=>>>=>>=>>>>> |