/** * 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(¶mList->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; }
/** * 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(¶mList->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; }