util: use standard name for strdup()
[mesa.git] / src / mesa / program / prog_parameter.c
index 44e680c048c31223da2df0dcde0e9456f3f78b16..2f3520bf750055bbefc98df429ed0ca20a1ddab3 100644 (file)
@@ -66,11 +66,13 @@ lookup_parameter_constant(const struct gl_program_parameter_list *list,
 
    for (i = 0; i < list->NumParameters; i++) {
       if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
+         unsigned offset = list->ParameterValueOffset[i];
+
          if (!swizzleOut) {
             /* swizzle not allowed */
             GLuint j, match = 0;
             for (j = 0; j < vSize; j++) {
-               if (v[j].u == list->ParameterValues[i][j].u)
+               if (v[j].u == list->ParameterValues[offset + j].u)
                   match++;
             }
             if (match == vSize) {
@@ -84,7 +86,7 @@ lookup_parameter_constant(const struct gl_program_parameter_list *list,
                 /* look for v[0] anywhere within float[4] value */
                 GLuint j;
                 for (j = 0; j < list->Parameters[i].Size; j++) {
-                   if (list->ParameterValues[i][j].u == v[0].u) {
+                   if (list->ParameterValues[offset + j].u == v[0].u) {
                       /* found it */
                       *posOut = i;
                       *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
@@ -97,13 +99,13 @@ lookup_parameter_constant(const struct gl_program_parameter_list *list,
                 GLuint swz[4];
                 GLuint match = 0, j, k;
                 for (j = 0; j < vSize; j++) {
-                   if (v[j].u == list->ParameterValues[i][j].u) {
+                   if (v[j].u == list->ParameterValues[offset + j].u) {
                       swz[j] = j;
                       match++;
                    }
                    else {
                       for (k = 0; k < list->Parameters[i].Size; k++) {
-                         if (v[j].u == list->ParameterValues[i][k].u) {
+                         if (v[j].u == list->ParameterValues[offset + k].u) {
                             swz[j] = k;
                             match++;
                             break;
@@ -149,7 +151,9 @@ _mesa_new_parameter_list_sized(unsigned size)
       p->Parameters = (struct gl_program_parameter *)
          calloc(size, sizeof(struct gl_program_parameter));
 
-      p->ParameterValues = (gl_constant_value (*)[4])
+      p->ParameterValueOffset = (unsigned *) calloc(size, sizeof(unsigned));
+
+      p->ParameterValues = (gl_constant_value *)
          _mesa_align_malloc(size * 4 *sizeof(gl_constant_value), 16);
 
 
@@ -176,6 +180,7 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
       free((void *)paramList->Parameters[i].Name);
    }
    free(paramList->Parameters);
+   free(paramList->ParameterValueOffset);
    _mesa_align_free(paramList->ParameterValues);
    free(paramList);
 }
@@ -203,7 +208,11 @@ _mesa_reserve_parameter_storage(struct gl_program_parameter_list *paramList,
          realloc(paramList->Parameters,
                  paramList->Size * sizeof(struct gl_program_parameter));
 
-      paramList->ParameterValues = (gl_constant_value (*)[4])
+      paramList->ParameterValueOffset =
+         realloc(paramList->ParameterValueOffset,
+                 paramList->Size * sizeof(unsigned));
+
+      paramList->ParameterValues = (gl_constant_value *)
          _mesa_align_realloc(paramList->ParameterValues,         /* old buf */
                              oldNum * 4 * sizeof(gl_constant_value),/* old sz */
                              paramList->Size*4*sizeof(gl_constant_value),/*new*/
@@ -232,16 +241,21 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
                     gl_register_file type, const char *name,
                     GLuint size, GLenum datatype,
                     const gl_constant_value *values,
-                    const gl_state_index state[STATE_LENGTH])
+                    const gl_state_index16 state[STATE_LENGTH],
+                    bool pad_and_align)
 {
+   assert(0 < size && size <=4);
    const GLuint oldNum = paramList->NumParameters;
-   const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+   unsigned oldValNum = paramList->NumParameterValues;
 
-   assert(size > 0);
+   if (pad_and_align)
+      oldValNum = align(oldValNum, 4); /* pad start to a vec4 boundary */
+   else if (_mesa_gl_datatype_is_64bit(datatype))
+      oldValNum = align(oldValNum, 2); /* pad start to 64-bit */
 
-   _mesa_reserve_parameter_storage(paramList, sz4);
+   _mesa_reserve_parameter_storage(paramList, 1);
 
-   if (!paramList->Parameters ||
+   if (!paramList->Parameters || !paramList->ParameterValueOffset ||
        !paramList->ParameterValues) {
       /* out of memory */
       paramList->NumParameters = 0;
@@ -249,45 +263,46 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
       return -1;
    }
 
-   GLuint i, j;
+   paramList->NumParameters = oldNum + 1;
 
-   paramList->NumParameters = oldNum + sz4;
+   unsigned pad = pad_and_align ? align(size, 4) : size;
+   paramList->NumParameterValues = oldValNum + pad;
 
    memset(&paramList->Parameters[oldNum], 0,
-          sz4 * sizeof(struct gl_program_parameter));
+          sizeof(struct gl_program_parameter));
+
+   struct gl_program_parameter *p = paramList->Parameters + oldNum;
+   p->Name = strdup(name ? name : "");
+   p->Type = type;
+   p->Size = size;
+   p->Padded = pad_and_align;
+   p->DataType = datatype;
+
+   paramList->ParameterValueOffset[oldNum] = oldValNum;
+   if (values) {
+      if (size >= 4) {
+         COPY_4V(paramList->ParameterValues + oldValNum, values);
+      } else {
+         /* copy 1, 2 or 3 values */
+         assert(size < 4);
+         unsigned j;
+         for (j = 0; j < size; j++) {
+            paramList->ParameterValues[oldValNum + j].f = values[j].f;
+         }
 
-   for (i = 0; i < sz4; i++) {
-      struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
-      p->Name = strdup(name ? name : "");
-      p->Type = type;
-      p->Size = size;
-      p->DataType = datatype;
-      if (values) {
-         if (size >= 4) {
-            COPY_4V(paramList->ParameterValues[oldNum + i], values);
-         } else {
-            /* copy 1, 2 or 3 values */
-            GLuint remaining = size % 4;
-            assert(remaining < 4);
-            for (j = 0; j < remaining; j++) {
-               paramList->ParameterValues[oldNum + i][j].f = values[j].f;
-            }
-            /* fill in remaining positions with zeros */
-            for (; j < 4; j++) {
-               paramList->ParameterValues[oldNum + i][j].f = 0.0f;
-            }
+         /* Zero out padding (if any) to avoid valgrind errors */
+         for (; j < pad; j++) {
+            paramList->ParameterValues[oldValNum + j].f = 0;
          }
-         values += 4;
-      } else {
-         /* silence valgrind */
-         for (j = 0; j < 4; j++)
-            paramList->ParameterValues[oldNum + i][j].f = 0;
       }
-      size -= 4;
+   } else {
+      for (unsigned j = 0; j < 4; j++) {
+         paramList->ParameterValues[oldValNum + j].f = 0;
+      }
    }
 
    if (state) {
-      for (i = 0; i < STATE_LENGTH; i++)
+      for (unsigned i = 0; i < STATE_LENGTH; i++)
          paramList->Parameters[oldNum].StateIndexes[i] = state[i];
    }
 
@@ -328,9 +343,10 @@ _mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
    if (size == 1 && swizzleOut) {
       for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
          struct gl_program_parameter *p = paramList->Parameters + pos;
+         unsigned offset = paramList->ParameterValueOffset[pos];
          if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
             /* ok, found room */
-            gl_constant_value *pVal = paramList->ParameterValues[pos];
+            gl_constant_value *pVal = paramList->ParameterValues + offset;
             GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
             pVal[p->Size] = values[0];
             p->Size++;
@@ -342,7 +358,7 @@ _mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
 
    /* add a new parameter to store this constant */
    pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
-                             size, datatype, values, NULL);
+                             size, datatype, values, NULL, true);
    if (pos >= 0 && swizzleOut) {
       if (size == 1)
          *swizzleOut = SWIZZLE_XXXX;
@@ -352,36 +368,27 @@ _mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
    return pos;
 }
 
-
-/**
- * Add a new state reference to the parameter list.
- * This will be used when the program contains something like this:
- *    PARAM ambient = state.material.front.ambient;
- *
- * \param paramList  the parameter list
- * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
- * \return index of the new parameter.
- */
 GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
-                          const gl_state_index stateTokens[STATE_LENGTH])
+_mesa_add_sized_state_reference(struct gl_program_parameter_list *paramList,
+                                const gl_state_index16 stateTokens[STATE_LENGTH],
+                                const unsigned size, bool pad_and_align)
 {
-   const GLuint size = 4; /* XXX fix */
    char *name;
    GLint index;
 
    /* Check if the state reference is already in the list */
    for (index = 0; index < (GLint) paramList->NumParameters; index++) {
       if (!memcmp(paramList->Parameters[index].StateIndexes,
-                  stateTokens, STATE_LENGTH * sizeof(gl_state_index))) {
+                  stateTokens,
+                  sizeof(paramList->Parameters[index].StateIndexes))) {
          return index;
       }
    }
 
    name = _mesa_program_state_string(stateTokens);
    index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
-                               size, GL_NONE,
-                               NULL, (gl_state_index *) stateTokens);
+                               size, GL_NONE, NULL, stateTokens,
+                               pad_and_align);
    paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
 
    /* free name string here since we duplicated it in add_parameter() */
@@ -389,3 +396,20 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
 
    return index;
 }
+
+
+/**
+ * Add a new state reference to the parameter list.
+ * This will be used when the program contains something like this:
+ *    PARAM ambient = state.material.front.ambient;
+ *
+ * \param paramList  the parameter list
+ * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
+ * \return index of the new parameter.
+ */
+GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+                          const gl_state_index16 stateTokens[STATE_LENGTH])
+{
+   return _mesa_add_sized_state_reference(paramList, stateTokens, 4, true);
+}