blob: 180286bdb5c55b88a2e3f61415472a4f7a64af07 [file] [log] [blame]
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gl/GrGLShaderBuilder.h"
9#include "gl/GrGLProgram.h"
10#include "gl/GrGLUniformHandle.h"
11
12#define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, OFFSET, COUNT) \
13 GrAssert(offset + arrayCount <= uni.fArrayCount || \
14 (0 == offset && 1 == arrayCount && GrGLShaderVar::kNonArray == uni.fArrayCount))
15
16GrGLUniformManager::UniformHandle GrGLUniformManager::appendUniform(GrSLType type, int arrayCount) {
17 int idx = fUniforms.count();
18 Uniform& uni = fUniforms.push_back();
19 GrAssert(GrGLShaderVar::kNonArray == arrayCount || arrayCount > 0);
20 uni.fArrayCount = arrayCount;
21 uni.fType = type;
22 uni.fVSLocation = kUnusedUniform;
23 uni.fFSLocation = kUnusedUniform;
24 return index_to_handle(idx);
25}
26
27void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const {
28 const Uniform& uni = fUniforms[handle_to_index(u)];
29 GrAssert(uni.fType == kSampler2D_GrSLType);
30 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
31 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
32 if (kUnusedUniform != uni.fFSLocation) {
33 GR_GL_CALL(fContext.interface(), Uniform1i(uni.fFSLocation, texUnit));
34 }
35 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
36 GR_GL_CALL(fContext.interface(), Uniform1i(uni.fVSLocation, texUnit));
37 }
38}
39
40void GrGLUniformManager::set1f(UniformHandle u, GrGLfloat v0) const {
41 const Uniform& uni = fUniforms[handle_to_index(u)];
42 GrAssert(uni.fType == kFloat_GrSLType);
43 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
44 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
45 if (kUnusedUniform != uni.fFSLocation) {
46 GR_GL_CALL(fContext.interface(), Uniform1f(uni.fFSLocation, v0));
47 }
48 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
49 GR_GL_CALL(fContext.interface(), Uniform1f(uni.fVSLocation, v0));
50 }
51}
52
53void GrGLUniformManager::set1fv(UniformHandle u,
54 int offset,
55 int arrayCount,
56 const GrGLfloat v[]) const {
57 const Uniform& uni = fUniforms[handle_to_index(u)];
58 GrAssert(uni.fType == kFloat_GrSLType);
59 GrAssert(arrayCount > 0);
60 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount);
61 // This assert fires in some instances of the two-pt gradient for its VSParams.
62 // Once the uniform manager is responsible for inserting the duplicate uniform
63 // arrays in VS and FS driver bug workaround, this can be enabled.
64 //GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
65 if (kUnusedUniform != uni.fFSLocation) {
66 GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fFSLocation + offset, arrayCount, v));
67 }
68 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
69 GR_GL_CALL(fContext.interface(), Uniform1fv(uni.fVSLocation + offset, arrayCount, v));
70 }
71}
72
73void GrGLUniformManager::set2f(UniformHandle u, GrGLfloat v0, GrGLfloat v1) const {
74 const Uniform& uni = fUniforms[handle_to_index(u)];
75 GrAssert(uni.fType == kVec2f_GrSLType);
76 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
77 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
78 if (kUnusedUniform != uni.fFSLocation) {
79 GR_GL_CALL(fContext.interface(), Uniform2f(uni.fFSLocation, v0, v1));
80 }
81 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
82 GR_GL_CALL(fContext.interface(), Uniform2f(uni.fVSLocation, v0, v1));
83 }
84}
85
86void GrGLUniformManager::set2fv(UniformHandle u,
87 int offset,
88 int arrayCount,
89 const GrGLfloat v[]) const {
90 const Uniform& uni = fUniforms[handle_to_index(u)];
91 GrAssert(uni.fType == kVec2f_GrSLType);
92 GrAssert(arrayCount > 0);
93 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount);
94 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
95 if (kUnusedUniform != uni.fFSLocation) {
96 GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fFSLocation + offset, arrayCount, v));
97 }
98 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
99 GR_GL_CALL(fContext.interface(), Uniform2fv(uni.fVSLocation + offset, arrayCount, v));
100 }
101}
102
103void GrGLUniformManager::set3f(UniformHandle u, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const {
104 const Uniform& uni = fUniforms[handle_to_index(u)];
105 GrAssert(uni.fType == kVec3f_GrSLType);
106 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
107 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
108 if (kUnusedUniform != uni.fFSLocation) {
109 GR_GL_CALL(fContext.interface(), Uniform3f(uni.fFSLocation, v0, v1, v2));
110 }
111 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
112 GR_GL_CALL(fContext.interface(), Uniform3f(uni.fVSLocation, v0, v1, v2));
113 }
114}
115
116void GrGLUniformManager::set3fv(UniformHandle u,
117 int offset,
118 int arrayCount,
119 const GrGLfloat v[]) const {
120 const Uniform& uni = fUniforms[handle_to_index(u)];
121 GrAssert(uni.fType == kVec3f_GrSLType);
122 GrAssert(arrayCount > 0);
123 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount);
124 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
125 if (kUnusedUniform != uni.fFSLocation) {
126 GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fFSLocation + offset, arrayCount, v));
127 }
128 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
129 GR_GL_CALL(fContext.interface(), Uniform3fv(uni.fVSLocation + offset, arrayCount, v));
130 }
131}
132
133void GrGLUniformManager::set4f(UniformHandle u,
134 GrGLfloat v0,
135 GrGLfloat v1,
136 GrGLfloat v2,
137 GrGLfloat v3) const {
138 const Uniform& uni = fUniforms[handle_to_index(u)];
139 GrAssert(uni.fType == kVec4f_GrSLType);
140 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
141 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
142 if (kUnusedUniform != uni.fFSLocation) {
143 GR_GL_CALL(fContext.interface(), Uniform4f(uni.fFSLocation, v0, v1, v2, v3));
144 }
145 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
146 GR_GL_CALL(fContext.interface(), Uniform4f(uni.fVSLocation, v0, v1, v2, v3));
147 }
148}
149
150void GrGLUniformManager::set4fv(UniformHandle u,
151 int offset,
152 int arrayCount,
153 const GrGLfloat v[]) const {
154 const Uniform& uni = fUniforms[handle_to_index(u)];
155 GrAssert(uni.fType == kVec4f_GrSLType);
156 GrAssert(arrayCount > 0);
157 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
158 if (kUnusedUniform != uni.fFSLocation) {
159 GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fFSLocation + offset, arrayCount, v));
160 }
161 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
162 GR_GL_CALL(fContext.interface(), Uniform4fv(uni.fVSLocation + offset, arrayCount, v));
163 }
164}
165
166void GrGLUniformManager::setMatrix3f(UniformHandle u, const GrGLfloat matrix[]) const {
167 const Uniform& uni = fUniforms[handle_to_index(u)];
168 GrAssert(uni.fType == kMat33f_GrSLType);
169 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
bsalomon@google.combfb459d2012-07-25 18:13:32 +0000170 // TODO: Re-enable this assert once texture matrices aren't forced on all custom effects
171 // GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000172 if (kUnusedUniform != uni.fFSLocation) {
173 GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fFSLocation, 1, false, matrix));
174 }
175 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
176 GR_GL_CALL(fContext.interface(), UniformMatrix3fv(uni.fVSLocation, 1, false, matrix));
177 }
178}
179
180void GrGLUniformManager::setMatrix4f(UniformHandle u, const GrGLfloat matrix[]) const {
181 const Uniform& uni = fUniforms[handle_to_index(u)];
182 GrAssert(uni.fType == kMat44f_GrSLType);
183 GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
184 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
185 if (kUnusedUniform != uni.fFSLocation) {
186 GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fFSLocation, 1, false, matrix));
187 }
188 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
189 GR_GL_CALL(fContext.interface(), UniformMatrix4fv(uni.fVSLocation, 1, false, matrix));
190 }
191}
192
193void GrGLUniformManager::setMatrix3fv(UniformHandle u,
194 int offset,
195 int arrayCount,
196 const GrGLfloat matrices[]) const {
197 const Uniform& uni = fUniforms[handle_to_index(u)];
198 GrAssert(uni.fType == kMat33f_GrSLType);
199 GrAssert(arrayCount > 0);
200 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount);
201 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
202 if (kUnusedUniform != uni.fFSLocation) {
203 GR_GL_CALL(fContext.interface(),
204 UniformMatrix3fv(uni.fFSLocation + offset, arrayCount, false, matrices));
205 }
206 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
207 GR_GL_CALL(fContext.interface(),
208 UniformMatrix3fv(uni.fVSLocation + offset, arrayCount, false, matrices));
209 }
210}
211
212void GrGLUniformManager::setMatrix4fv(UniformHandle u,
213 int offset,
214 int arrayCount,
215 const GrGLfloat matrices[]) const {
216 const Uniform& uni = fUniforms[handle_to_index(u)];
217 GrAssert(uni.fType == kMat44f_GrSLType);
218 GrAssert(arrayCount > 0);
219 ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, offset, arrayCount);
220 GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
221 if (kUnusedUniform != uni.fFSLocation) {
222 GR_GL_CALL(fContext.interface(),
223 UniformMatrix4fv(uni.fFSLocation + offset, arrayCount, false, matrices));
224 }
225 if (kUnusedUniform != uni.fVSLocation && uni.fVSLocation != uni.fFSLocation) {
226 GR_GL_CALL(fContext.interface(),
227 UniformMatrix4fv(uni.fVSLocation + offset, arrayCount, false, matrices));
228 }
229}
230
231void GrGLUniformManager::getUniformLocations(GrGLuint programID, const BuilderUniformArray& uniforms) {
232 GrAssert(uniforms.count() == fUniforms.count());
233 int count = fUniforms.count();
234 for (int i = 0; i < count; ++i) {
235 GrAssert(uniforms[i].fVariable.getType() == fUniforms[i].fType);
236 GrAssert(uniforms[i].fVariable.getArrayCount() == fUniforms[i].fArrayCount);
237 GrGLint location;
238 // TODO: Move the Xoom uniform array in both FS and VS bug workaround here.
239 GR_GL_CALL_RET(fContext.interface(), location,
240 GetUniformLocation(programID, uniforms[i].fVariable.c_str()));
241 if (GrGLShaderBuilder::kVertex_ShaderType & uniforms[i].fVisibility) {
242 fUniforms[i].fVSLocation = location;
243 }
244 if (GrGLShaderBuilder::kFragment_ShaderType & uniforms[i].fVisibility) {
245 fUniforms[i].fFSLocation = location;
246 }
247 }
248}