Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprog_parameter.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.3 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00032 #include "main/glheader.h" 00033 #include "main/imports.h" 00034 #include "main/macros.h" 00035 #include "prog_instruction.h" 00036 #include "prog_parameter.h" 00037 #include "prog_statevars.h" 00038 00039 00040 struct gl_program_parameter_list * 00041 _mesa_new_parameter_list(void) 00042 { 00043 return CALLOC_STRUCT(gl_program_parameter_list); 00044 } 00045 00046 00050 void 00051 _mesa_free_parameter_list(struct gl_program_parameter_list *paramList) 00052 { 00053 GLuint i; 00054 for (i = 0; i < paramList->NumParameters; i++) { 00055 if (paramList->Parameters[i].Name) 00056 _mesa_free((void *) paramList->Parameters[i].Name); 00057 } 00058 _mesa_free(paramList->Parameters); 00059 if (paramList->ParameterValues) 00060 _mesa_align_free(paramList->ParameterValues); 00061 _mesa_free(paramList); 00062 } 00063 00064 00079 GLint 00080 _mesa_add_parameter(struct gl_program_parameter_list *paramList, 00081 enum register_file type, const char *name, 00082 GLuint size, GLenum datatype, const GLfloat *values, 00083 const gl_state_index state[STATE_LENGTH], 00084 GLbitfield flags) 00085 { 00086 const GLuint oldNum = paramList->NumParameters; 00087 const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */ 00088 00089 assert(size > 0); 00090 00091 if (oldNum + sz4 > paramList->Size) { 00092 /* Need to grow the parameter list array (alloc some extra) */ 00093 paramList->Size = paramList->Size + 4 * sz4; 00094 00095 /* realloc arrays */ 00096 paramList->Parameters = (struct gl_program_parameter *) 00097 _mesa_realloc(paramList->Parameters, 00098 oldNum * sizeof(struct gl_program_parameter), 00099 paramList->Size * sizeof(struct gl_program_parameter)); 00100 00101 paramList->ParameterValues = (GLfloat (*)[4]) 00102 _mesa_align_realloc(paramList->ParameterValues, /* old buf */ 00103 oldNum * 4 * sizeof(GLfloat), /* old size */ 00104 paramList->Size * 4 *sizeof(GLfloat), /* new sz */ 00105 16); 00106 } 00107 00108 if (!paramList->Parameters || 00109 !paramList->ParameterValues) { 00110 /* out of memory */ 00111 paramList->NumParameters = 0; 00112 paramList->Size = 0; 00113 return -1; 00114 } 00115 else { 00116 GLuint i; 00117 00118 paramList->NumParameters = oldNum + sz4; 00119 00120 _mesa_memset(¶mList->Parameters[oldNum], 0, 00121 sz4 * sizeof(struct gl_program_parameter)); 00122 00123 for (i = 0; i < sz4; i++) { 00124 struct gl_program_parameter *p = paramList->Parameters + oldNum + i; 00125 p->Name = name ? _mesa_strdup(name) : NULL; 00126 p->Type = type; 00127 p->Size = size; 00128 p->DataType = datatype; 00129 p->Flags = flags; 00130 if (values) { 00131 COPY_4V(paramList->ParameterValues[oldNum + i], values); 00132 values += 4; 00133 p->Initialized = GL_TRUE; 00134 } 00135 else { 00136 /* silence valgrind */ 00137 ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0); 00138 } 00139 size -= 4; 00140 } 00141 00142 if (state) { 00143 for (i = 0; i < STATE_LENGTH; i++) 00144 paramList->Parameters[oldNum].StateIndexes[i] = state[i]; 00145 } 00146 00147 return (GLint) oldNum; 00148 } 00149 } 00150 00151 00156 GLint 00157 _mesa_add_named_parameter(struct gl_program_parameter_list *paramList, 00158 const char *name, const GLfloat values[4]) 00159 { 00160 return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name, 00161 4, GL_NONE, values, NULL, 0x0); 00162 00163 } 00164 00165 00176 GLint 00177 _mesa_add_named_constant(struct gl_program_parameter_list *paramList, 00178 const char *name, const GLfloat values[4], 00179 GLuint size) 00180 { 00181 #if 0 /* disable this for now -- we need to save the name! */ 00182 GLint pos; 00183 GLuint swizzle; 00184 ASSERT(size == 4); /* XXX future feature */ 00185 /* check if we already have this constant */ 00186 if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { 00187 return pos; 00188 } 00189 #endif 00190 return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, 00191 size, GL_NONE, values, NULL, 0x0); 00192 } 00193 00194 00208 GLint 00209 _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, 00210 const GLfloat values[4], GLuint size, 00211 GLuint *swizzleOut) 00212 { 00213 GLint pos; 00214 ASSERT(size >= 1); 00215 ASSERT(size <= 4); 00216 00217 if (_mesa_lookup_parameter_constant(paramList, values, 00218 size, &pos, swizzleOut)) { 00219 return pos; 00220 } 00221 00222 /* Look for empty space in an already unnamed constant parameter 00223 * to add this constant. This will only work for single-element 00224 * constants because we rely on smearing (i.e. .yyyy or .zzzz). 00225 */ 00226 if (size == 1 && swizzleOut) { 00227 for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { 00228 struct gl_program_parameter *p = paramList->Parameters + pos; 00229 if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { 00230 /* ok, found room */ 00231 GLfloat *pVal = paramList->ParameterValues[pos]; 00232 GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */ 00233 pVal[p->Size] = values[0]; 00234 p->Size++; 00235 *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz); 00236 return pos; 00237 } 00238 } 00239 } 00240 00241 /* add a new parameter to store this constant */ 00242 pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, 00243 size, GL_NONE, values, NULL, 0x0); 00244 if (pos >= 0 && swizzleOut) { 00245 if (size == 1) 00246 *swizzleOut = SWIZZLE_XXXX; 00247 else 00248 *swizzleOut = SWIZZLE_NOOP; 00249 } 00250 return pos; 00251 } 00252 00253 00262 GLint 00263 _mesa_add_uniform(struct gl_program_parameter_list *paramList, 00264 const char *name, GLuint size, GLenum datatype, 00265 const GLfloat *values) 00266 { 00267 GLint i = _mesa_lookup_parameter_index(paramList, -1, name); 00268 ASSERT(datatype != GL_NONE); 00269 if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) { 00270 ASSERT(paramList->Parameters[i].Size == size); 00271 ASSERT(paramList->Parameters[i].DataType == datatype); 00272 /* already in list */ 00273 return i; 00274 } 00275 else { 00276 i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name, 00277 size, datatype, values, NULL, 0x0); 00278 return i; 00279 } 00280 } 00281 00282 00286 void 00287 _mesa_use_uniform(struct gl_program_parameter_list *paramList, 00288 const char *name) 00289 { 00290 GLuint i; 00291 for (i = 0; i < paramList->NumParameters; i++) { 00292 struct gl_program_parameter *p = paramList->Parameters + i; 00293 if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) && 00294 _mesa_strcmp(p->Name, name) == 0) { 00295 p->Used = GL_TRUE; 00296 /* Note that large uniforms may occupy several slots so we're 00297 * not done searching yet. 00298 */ 00299 } 00300 } 00301 } 00302 00303 00311 GLint 00312 _mesa_add_sampler(struct gl_program_parameter_list *paramList, 00313 const char *name, GLenum datatype) 00314 { 00315 GLint i = _mesa_lookup_parameter_index(paramList, -1, name); 00316 if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { 00317 ASSERT(paramList->Parameters[i].Size == 1); 00318 ASSERT(paramList->Parameters[i].DataType == datatype); 00319 /* already in list */ 00320 return (GLint) paramList->ParameterValues[i][0]; 00321 } 00322 else { 00323 GLuint i; 00324 const GLint size = 1; /* a sampler is basically a texture unit number */ 00325 GLfloat value; 00326 GLint numSamplers = 0; 00327 for (i = 0; i < paramList->NumParameters; i++) { 00328 if (paramList->Parameters[i].Type == PROGRAM_SAMPLER) 00329 numSamplers++; 00330 } 00331 value = (GLfloat) numSamplers; 00332 (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, 00333 size, datatype, &value, NULL, 0x0); 00334 return numSamplers; 00335 } 00336 } 00337 00338 00342 GLint 00343 _mesa_add_varying(struct gl_program_parameter_list *paramList, 00344 const char *name, GLuint size, GLbitfield flags) 00345 { 00346 GLint i = _mesa_lookup_parameter_index(paramList, -1, name); 00347 if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) { 00348 /* already in list */ 00349 return i; 00350 } 00351 else { 00352 /*assert(size == 4);*/ 00353 i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name, 00354 size, GL_NONE, NULL, NULL, flags); 00355 return i; 00356 } 00357 } 00358 00359 00365 GLint 00366 _mesa_add_attribute(struct gl_program_parameter_list *paramList, 00367 const char *name, GLint size, GLenum datatype, GLint attrib) 00368 { 00369 GLint i = _mesa_lookup_parameter_index(paramList, -1, name); 00370 if (i >= 0) { 00371 /* replace */ 00372 if (attrib < 0) 00373 attrib = i; 00374 paramList->Parameters[i].StateIndexes[0] = attrib; 00375 } 00376 else { 00377 /* add */ 00378 gl_state_index state[STATE_LENGTH]; 00379 state[0] = (gl_state_index) attrib; 00380 if (size < 0) 00381 size = 4; 00382 i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name, 00383 size, datatype, NULL, state, 0x0); 00384 } 00385 return i; 00386 } 00387 00388 00389 00390 #if 0 /* not used yet */ 00391 00397 static GLuint 00398 sizeof_state_reference(const GLint *stateTokens) 00399 { 00400 if (stateTokens[0] == STATE_MATRIX) { 00401 GLuint rows = stateTokens[4] - stateTokens[3] + 1; 00402 assert(rows >= 1); 00403 assert(rows <= 4); 00404 return rows; 00405 } 00406 else { 00407 return 1; 00408 } 00409 } 00410 #endif 00411 00412 00422 GLint 00423 _mesa_add_state_reference(struct gl_program_parameter_list *paramList, 00424 const gl_state_index stateTokens[STATE_LENGTH]) 00425 { 00426 const GLuint size = 4; /* XXX fix */ 00427 const char *name; 00428 GLint index; 00429 00430 /* Check if the state reference is already in the list */ 00431 for (index = 0; index < (GLint) paramList->NumParameters; index++) { 00432 GLuint i, match = 0; 00433 for (i = 0; i < STATE_LENGTH; i++) { 00434 if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) { 00435 match++; 00436 } 00437 else { 00438 break; 00439 } 00440 } 00441 if (match == STATE_LENGTH) { 00442 /* this state reference is already in the parameter list */ 00443 return index; 00444 } 00445 } 00446 00447 name = _mesa_program_state_string(stateTokens); 00448 index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name, 00449 size, GL_NONE, 00450 NULL, (gl_state_index *) stateTokens, 0x0); 00451 paramList->StateFlags |= _mesa_program_state_flags(stateTokens); 00452 00453 /* free name string here since we duplicated it in add_parameter() */ 00454 _mesa_free((void *) name); 00455 00456 return index; 00457 } 00458 00459 00464 GLfloat * 00465 _mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, 00466 GLsizei nameLen, const char *name) 00467 { 00468 GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name); 00469 if (i < 0) 00470 return NULL; 00471 else 00472 return paramList->ParameterValues[i]; 00473 } 00474 00475 00484 GLint 00485 _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, 00486 GLsizei nameLen, const char *name) 00487 { 00488 GLint i; 00489 00490 if (!paramList) 00491 return -1; 00492 00493 if (nameLen == -1) { 00494 /* name is null-terminated */ 00495 for (i = 0; i < (GLint) paramList->NumParameters; i++) { 00496 if (paramList->Parameters[i].Name && 00497 _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) 00498 return i; 00499 } 00500 } 00501 else { 00502 /* name is not null-terminated, use nameLen */ 00503 for (i = 0; i < (GLint) paramList->NumParameters; i++) { 00504 if (paramList->Parameters[i].Name && 00505 _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 00506 && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) 00507 return i; 00508 } 00509 } 00510 return -1; 00511 } 00512 00513 00526 GLboolean 00527 _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, 00528 const GLfloat v[], GLuint vSize, 00529 GLint *posOut, GLuint *swizzleOut) 00530 { 00531 GLuint i; 00532 00533 assert(vSize >= 1); 00534 assert(vSize <= 4); 00535 00536 if (!list) 00537 return -1; 00538 00539 for (i = 0; i < list->NumParameters; i++) { 00540 if (list->Parameters[i].Type == PROGRAM_CONSTANT) { 00541 if (!swizzleOut) { 00542 /* swizzle not allowed */ 00543 GLuint j, match = 0; 00544 for (j = 0; j < vSize; j++) { 00545 if (v[j] == list->ParameterValues[i][j]) 00546 match++; 00547 } 00548 if (match == vSize) { 00549 *posOut = i; 00550 return GL_TRUE; 00551 } 00552 } 00553 else { 00554 /* try matching w/ swizzle */ 00555 if (vSize == 1) { 00556 /* look for v[0] anywhere within float[4] value */ 00557 GLuint j; 00558 for (j = 0; j < 4; j++) { 00559 if (list->ParameterValues[i][j] == v[0]) { 00560 /* found it */ 00561 *posOut = i; 00562 *swizzleOut = MAKE_SWIZZLE4(j, j, j, j); 00563 return GL_TRUE; 00564 } 00565 } 00566 } 00567 else if (vSize <= list->Parameters[i].Size) { 00568 /* see if we can match this constant (with a swizzle) */ 00569 GLuint swz[4]; 00570 GLuint match = 0, j, k; 00571 for (j = 0; j < vSize; j++) { 00572 if (v[j] == list->ParameterValues[i][j]) { 00573 swz[j] = j; 00574 match++; 00575 } 00576 else { 00577 for (k = 0; k < list->Parameters[i].Size; k++) { 00578 if (v[j] == list->ParameterValues[i][k]) { 00579 swz[j] = k; 00580 match++; 00581 break; 00582 } 00583 } 00584 } 00585 } 00586 /* smear last value to remaining positions */ 00587 for (; j < 4; j++) 00588 swz[j] = swz[j-1]; 00589 00590 if (match == vSize) { 00591 *posOut = i; 00592 *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 00593 return GL_TRUE; 00594 } 00595 } 00596 } 00597 } 00598 } 00599 00600 *posOut = -1; 00601 return GL_FALSE; 00602 } 00603 00604 00605 struct gl_program_parameter_list * 00606 _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) 00607 { 00608 struct gl_program_parameter_list *clone; 00609 GLuint i; 00610 00611 clone = _mesa_new_parameter_list(); 00612 if (!clone) 00613 return NULL; 00614 00616 for (i = 0; i < list->NumParameters; i++) { 00617 struct gl_program_parameter *p = list->Parameters + i; 00618 struct gl_program_parameter *pCopy; 00619 GLuint size = MIN2(p->Size, 4); 00620 GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType, 00621 list->ParameterValues[i], NULL, 0x0); 00622 ASSERT(j >= 0); 00623 pCopy = clone->Parameters + j; 00624 pCopy->Used = p->Used; 00625 pCopy->Flags = p->Flags; 00626 /* copy state indexes */ 00627 if (p->Type == PROGRAM_STATE_VAR) { 00628 GLint k; 00629 for (k = 0; k < STATE_LENGTH; k++) { 00630 pCopy->StateIndexes[k] = p->StateIndexes[k]; 00631 } 00632 } 00633 else { 00634 clone->Parameters[j].Size = p->Size; 00635 } 00636 00637 } 00638 00639 clone->StateFlags = list->StateFlags; 00640 00641 return clone; 00642 } 00643 00644 00648 struct gl_program_parameter_list * 00649 _mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA, 00650 const struct gl_program_parameter_list *listB) 00651 { 00652 struct gl_program_parameter_list *list; 00653 00654 if (listA) { 00655 list = _mesa_clone_parameter_list(listA); 00656 if (list && listB) { 00657 GLuint i; 00658 for (i = 0; i < listB->NumParameters; i++) { 00659 struct gl_program_parameter *param = listB->Parameters + i; 00660 _mesa_add_parameter(list, param->Type, param->Name, param->Size, 00661 param->DataType, 00662 listB->ParameterValues[i], 00663 param->StateIndexes, 00664 param->Flags); 00665 } 00666 } 00667 } 00668 else if (listB) { 00669 list = _mesa_clone_parameter_list(listB); 00670 } 00671 else { 00672 list = NULL; 00673 } 00674 return list; 00675 } 00676 00677 00678 00682 GLuint 00683 _mesa_longest_parameter_name(const struct gl_program_parameter_list *list, 00684 enum register_file type) 00685 { 00686 GLuint i, maxLen = 0; 00687 if (!list) 00688 return 0; 00689 for (i = 0; i < list->NumParameters; i++) { 00690 if (list->Parameters[i].Type == type) { 00691 GLuint len = _mesa_strlen(list->Parameters[i].Name); 00692 if (len > maxLen) 00693 maxLen = len; 00694 } 00695 } 00696 return maxLen; 00697 } 00698 00699 00703 GLuint 00704 _mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, 00705 enum register_file type) 00706 { 00707 GLuint i, count = 0; 00708 if (list) { 00709 for (i = 0; i < list->NumParameters; i++) { 00710 if (list->Parameters[i].Type == type) 00711 count++; 00712 } 00713 } 00714 return count; 00715 } Generated on Sat May 26 2012 04:19:21 for ReactOS by
1.7.6.1
|