ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

prog_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(&paramList->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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.