* \author Brian Paul
*/
-
#include "main/glheader.h"
-#include "main/imports.h"
#include "main/macros.h"
+#include "util/u_memory.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
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) {
/* 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);
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;
p->Parameters = (struct gl_program_parameter *)
calloc(size, sizeof(struct gl_program_parameter));
- p->ParameterValues = (gl_constant_value (*)[4])
- _mesa_align_malloc(size * 4 *sizeof(gl_constant_value), 16);
+ p->ParameterValueOffset = (unsigned *) calloc(size, sizeof(unsigned));
+
+ p->ParameterValues = (gl_constant_value *)
+ align_malloc(size * 4 *sizeof(gl_constant_value), 16);
if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
free(p->Parameters);
- _mesa_align_free(p->ParameterValues);
+ align_free(p->ParameterValues);
free(p);
p = NULL;
}
free((void *)paramList->Parameters[i].Name);
}
free(paramList->Parameters);
- _mesa_align_free(paramList->ParameterValues);
+ free(paramList->ParameterValueOffset);
+ align_free(paramList->ParameterValues);
free(paramList);
}
realloc(paramList->Parameters,
paramList->Size * sizeof(struct gl_program_parameter));
- paramList->ParameterValues = (gl_constant_value (*)[4])
- _mesa_align_realloc(paramList->ParameterValues, /* old buf */
- oldNum * 4 * sizeof(gl_constant_value),/* old sz */
- paramList->Size*4*sizeof(gl_constant_value),/*new*/
- 16);
+ paramList->ParameterValueOffset =
+ realloc(paramList->ParameterValueOffset,
+ paramList->Size * sizeof(unsigned));
+
+ paramList->ParameterValues = (gl_constant_value *)
+ align_realloc(paramList->ParameterValues, /* old buf */
+ oldNum * 4 * sizeof(gl_constant_value),/* old sz */
+ paramList->Size*4*sizeof(gl_constant_value),/*new*/
+ 16);
}
}
* 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 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.
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;
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(¶mList->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;
- p->Initialized = GL_TRUE;
- } 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];
}
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++;
/* 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;
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() */
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);
+}