Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / program / prog_uniform.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.1
4  *
5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * \file prog_uniform.c
27  * Shader uniform functions.
28  * \author Brian Paul
29  */
30
31 #include "main/imports.h"
32 #include "main/mtypes.h"
33 #include "prog_uniform.h"
34
35
36 struct gl_uniform_list *
37 _mesa_new_uniform_list(void)
38 {
39    return CALLOC_STRUCT(gl_uniform_list);
40 }
41
42
43 void
44 _mesa_free_uniform_list(struct gl_uniform_list *list)
45 {
46    GLuint i;
47
48    if (!list)
49       return;
50
51    for (i = 0; i < list->NumUniforms; i++) {
52       free((void *) list->Uniforms[i].Name);
53    }
54    free(list->Uniforms);
55    free(list);
56 }
57
58
59 struct gl_uniform *
60 _mesa_append_uniform(struct gl_uniform_list *list,
61                      const char *name, GLenum target, GLuint progPos)
62 {
63    const GLuint oldNum = list->NumUniforms;
64    struct gl_uniform *uniform;
65    GLint index;
66
67    assert(target == GL_VERTEX_PROGRAM_ARB ||
68           target == GL_FRAGMENT_PROGRAM_ARB ||
69           target == MESA_GEOMETRY_PROGRAM);
70
71    index = _mesa_lookup_uniform(list, name);
72    if (index < 0) {
73       /* not found - append to list */
74
75       if (oldNum + 1 > list->Size) {
76          /* Need to grow the list array (alloc some extra) */
77          list->Size += 4;
78
79          /* realloc arrays */
80          list->Uniforms = (struct gl_uniform *)
81             _mesa_realloc(list->Uniforms,
82                           oldNum * sizeof(struct gl_uniform),
83                           list->Size * sizeof(struct gl_uniform));
84       }
85
86       if (!list->Uniforms) {
87          /* out of memory */
88          list->NumUniforms = 0;
89          list->Size = 0;
90          return GL_FALSE;
91       }
92
93       uniform = list->Uniforms + oldNum;
94
95       uniform->Name = _mesa_strdup(name);
96       uniform->VertPos = -1;
97       uniform->FragPos = -1;
98       uniform->GeomPos = -1;
99       uniform->Initialized = GL_FALSE;
100
101       list->NumUniforms++;
102    }
103    else {
104       /* found */
105       uniform = list->Uniforms + index;
106    }
107
108    /* update position for the vertex or fragment program */
109    if (target == GL_VERTEX_PROGRAM_ARB) {
110       if (uniform->VertPos != -1) {
111          /* this uniform is already in the list - that shouldn't happen */
112          return GL_FALSE;
113       }
114       uniform->VertPos = progPos;
115    } else if (target == GL_FRAGMENT_PROGRAM_ARB) {
116       if (uniform->FragPos != -1) {
117          /* this uniform is already in the list - that shouldn't happen */
118          return GL_FALSE;
119       }
120       uniform->FragPos = progPos;
121    } else {
122       if (uniform->GeomPos != -1) {
123          /* this uniform is already in the list - that shouldn't happen */
124          return GL_FALSE;
125       }
126       uniform->GeomPos = progPos;
127    }
128
129    return uniform;
130 }
131
132
133 /**
134  * Return the location/index of the named uniform in the uniform list,
135  * or -1 if not found.
136  */
137 GLint
138 _mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
139 {
140    GLuint i;
141    for (i = 0; list && i < list->NumUniforms; i++) {
142       if (!strcmp(list->Uniforms[i].Name, name)) {
143          return i;
144       }
145    }
146    return -1;
147 }
148
149
150 GLint
151 _mesa_longest_uniform_name(const struct gl_uniform_list *list)
152 {
153    GLint max = 0;
154    GLuint i;
155    for (i = 0; list && i < list->NumUniforms; i++) {
156       GLint len = (GLint) strlen(list->Uniforms[i].Name);
157       if (len > max)
158          max = len;
159    }
160    return max;
161 }
162
163
164 void
165 _mesa_print_uniforms(const struct gl_uniform_list *list)
166 {
167    GLuint i;
168    printf("Uniform list %p:\n", (void *) list);
169    for (i = 0; i < list->NumUniforms; i++) {
170       printf("%d: %s %d %d %d\n",
171              i,
172              list->Uniforms[i].Name,
173              list->Uniforms[i].VertPos,
174              list->Uniforms[i].FragPos,
175              list->Uniforms[i].GeomPos);
176    }
177 }