Ejemplo n.º 1
0
/**
 * Add a new parameter to a parameter list.
 * Note that parameter values are usually 4-element GLfloat vectors.
 * When size > 4 we'll allocate a sequential block of parameters to
 * store all the values (in blocks of 4).
 *
 * \param paramList  the list to add the parameter to
 * \param type  type of parameter, such as 
 * \param name  the parameter name, will be duplicated/copied!
 * \param size  number of elements in 'values' vector (1..4, or more)
 * \param datatype  GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE.
 * \param values  initial parameter value, up to 4 gl_constant_values, or NULL
 * \param state  state indexes, or NULL
 * \return  index of new parameter in the list, or -1 if error (out of mem)
 */
GLint
_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 GLuint oldNum = paramList->NumParameters;
   const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */

   assert(size > 0);

   _mesa_reserve_parameter_storage(paramList, sz4);

   if (!paramList->Parameters ||
       !paramList->ParameterValues) {
      /* out of memory */
      paramList->NumParameters = 0;
      paramList->Size = 0;
      return -1;
   }

   GLuint i, j;

   paramList->NumParameters = oldNum + sz4;

   memset(&paramList->Parameters[oldNum], 0,
          sz4 * sizeof(struct gl_program_parameter));

   for (i = 0; i < sz4; i++) {
      struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
      p->Name = name ? strdup(name) : NULL;
      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;
            }
         }
         values += 4;
         p->Initialized = GL_TRUE;
      } else {
         /* silence valgrind */
         for (j = 0; j < 4; j++)
            paramList->ParameterValues[oldNum + i][j].f = 0;
      }
      size -= 4;
   }

   if (state) {
      for (i = 0; i < STATE_LENGTH; i++)
         paramList->Parameters[oldNum].StateIndexes[i] = state[i];
   }

   return (GLint) oldNum;
}
Ejemplo n.º 2
0
/**
 * Add a new parameter to a parameter list.
 * Note that parameter values are usually 4-element GLfloat vectors.
 * When size > 4 we'll allocate a sequential block of parameters to
 * store all the values (in blocks of 4).
 *
 * \param paramList  the list to add the parameter to
 * \param type  type of parameter, such as 
 * \param name  the parameter name, will be duplicated/copied!
 * \param size  number of elements in 'values' vector (1..4, or more)
 * \param datatype  GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE.
 * \param values  initial parameter value, up to 4 gl_constant_values, or NULL
 * \param state  state indexes, or NULL
 * \return  index of new parameter in the list, or -1 if error (out of mem)
 */
GLint
_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_index16 state[STATE_LENGTH],
                    bool pad_and_align)
{
   assert(0 < size && size <=4);
   const GLuint oldNum = paramList->NumParameters;
   unsigned oldValNum = paramList->NumParameterValues;

   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, 1);

   if (!paramList->Parameters || !paramList->ParameterValueOffset ||
       !paramList->ParameterValues) {
      /* out of memory */
      paramList->NumParameters = 0;
      paramList->Size = 0;
      return -1;
   }

   paramList->NumParameters = oldNum + 1;

   unsigned pad = pad_and_align ? align(size, 4) : size;
   paramList->NumParameterValues = oldValNum + pad;

   memset(&paramList->Parameters[oldNum], 0,
          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;
         }

         /* Zero out padding (if any) to avoid valgrind errors */
         for (; j < pad; j++) {
            paramList->ParameterValues[oldValNum + j].f = 0;
         }
      }
   } else {
      for (unsigned j = 0; j < 4; j++) {
         paramList->ParameterValues[oldValNum + j].f = 0;
      }
   }

   if (state) {
      for (unsigned i = 0; i < STATE_LENGTH; i++)
         paramList->Parameters[oldNum].StateIndexes[i] = state[i];
   }

   return (GLint) oldNum;
}