blob: 4ef05bf4372f9405997cc649b9ce1a4119acb47a [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080018#ifndef ANDROID_RS_SERIALIZE
Jason Samsc460e552009-11-25 13:22:07 -080019#include <GLES2/gl2.h>
20#include <GLES2/gl2ext.h>
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080021#endif //ANDROID_RS_SERIALIZE
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070022
23#include "rsProgram.h"
Jason Samsc460e552009-11-25 13:22:07 -080024
Jason Sams326e0dd2009-05-22 14:03:28 -070025using namespace android;
26using namespace android::renderscript;
27
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080028Program::Program(Context *rsc) : ObjectBase(rsc) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080029 initMemberVars();
Jason Sams4815c0d2009-12-15 12:58:36 -080030}
31
32Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080033 const uint32_t * params, uint32_t paramLength)
34 : ObjectBase(rsc) {
Jason Sams4815c0d2009-12-15 12:58:36 -080035
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080036 initMemberVars();
Jason Sams4815c0d2009-12-15 12:58:36 -080037 for (uint32_t ct=0; ct < paramLength; ct+=2) {
38 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
39 mInputCount++;
40 }
41 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
42 mOutputCount++;
43 }
44 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
45 mConstantCount++;
46 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -080047 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
48 mTextureCount++;
Jason Samsf2e4fa22009-12-15 13:27:04 -080049 }
Jason Sams4815c0d2009-12-15 12:58:36 -080050 }
51
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -070052 mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
53 mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
Alex Sakhartchouk84e40272010-11-18 15:22:43 -080054 mTextureTargets = new RsTextureTarget[mTextureCount];
Jason Sams4815c0d2009-12-15 12:58:36 -080055 mInputElements = new ObjectBaseRef<Element>[mInputCount];
56 mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
57 mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080058 mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
Jason Sams4815c0d2009-12-15 12:58:36 -080059
60 uint32_t input = 0;
61 uint32_t output = 0;
62 uint32_t constant = 0;
Alex Sakhartchouk84e40272010-11-18 15:22:43 -080063 uint32_t texture = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -080064 for (uint32_t ct=0; ct < paramLength; ct+=2) {
65 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
66 mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
67 }
68 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
69 mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
70 }
71 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
72 mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
73 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -080074 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
75 mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
76 }
Jason Sams4815c0d2009-12-15 12:58:36 -080077 }
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -070078 mIsInternal = false;
79 uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080080 if (shaderLength > internalTokenLen &&
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -070081 strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) {
82 mIsInternal = true;
83 shaderText += internalTokenLen;
84 shaderLength -= internalTokenLen;
85 }
Jason Sams4815c0d2009-12-15 12:58:36 -080086 mUserShader.setTo(shaderText, shaderLength);
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -080087
88 initAttribAndUniformArray();
Jason Sams326e0dd2009-05-22 14:03:28 -070089}
90
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080091Program::~Program() {
92 if (mRSC->props.mLogShaders) {
Alex Sakhartchouk889fe502010-10-01 10:54:06 -070093 LOGV("Program::~Program with shader id %u", mShaderID);
94 }
95
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080096 if (mShaderID) {
Alex Sakhartchouk889fe502010-10-01 10:54:06 -070097 glDeleteShader(mShaderID);
98 }
99
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800100 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700101 bindAllocation(NULL, NULL, ct);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800102 }
Jason Sams4815c0d2009-12-15 12:58:36 -0800103
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700104 for (uint32_t ct=0; ct < mTextureCount; ct++) {
105 bindTexture(NULL, ct, NULL);
106 bindSampler(NULL, ct, NULL);
107 }
108 delete[] mTextures;
109 delete[] mSamplers;
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800110 delete[] mTextureTargets;
Jason Sams4815c0d2009-12-15 12:58:36 -0800111 delete[] mInputElements;
112 delete[] mOutputElements;
113 delete[] mConstantTypes;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800114 delete[] mConstants;
115 delete[] mAttribNames;
116 delete[] mUniformNames;
117 delete[] mUniformArraySizes;
Jason Sams4815c0d2009-12-15 12:58:36 -0800118 mInputCount = 0;
119 mOutputCount = 0;
120 mConstantCount = 0;
Jason Sams326e0dd2009-05-22 14:03:28 -0700121}
122
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800123void Program::initMemberVars() {
124 mDirty = true;
125 mShaderID = 0;
126 mAttribCount = 0;
127 mUniformCount = 0;
128 mTextureCount = 0;
129
130 mTextures = NULL;
131 mSamplers = NULL;
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800132 mTextureTargets = NULL;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800133 mInputElements = NULL;
134 mOutputElements = NULL;
135 mConstantTypes = NULL;
136 mConstants = NULL;
137 mAttribNames = NULL;
138 mUniformNames = NULL;
139 mUniformArraySizes = NULL;
140 mInputCount = 0;
141 mOutputCount = 0;
142 mConstantCount = 0;
143 mIsValid = false;
144 mIsInternal = false;
145}
Jason Sams326e0dd2009-05-22 14:03:28 -0700146
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800147void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700148 if (alloc != NULL) {
149 if (slot >= mConstantCount) {
150 LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
151 slot, (uint32_t)this, mConstantCount);
152 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
153 return;
154 }
155 if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
156 LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
157 slot, (uint32_t)this);
158 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
159 return;
160 }
161 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800162 if (mConstants[slot].get() == alloc) {
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700163 return;
164 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800165 if (mConstants[slot].get()) {
166 mConstants[slot].get()->removeProgramToDirty(this);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700167 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800168 mConstants[slot].set(alloc);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700169 if (alloc) {
170 alloc->addProgramToDirty(this);
171 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700172 mDirty = true;
173}
174
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800175void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700176 if (slot >= mTextureCount) {
177 LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
178 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
Jason Sams7dad9c32009-12-17 16:55:08 -0800179 return;
180 }
181
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800182 if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
183 LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
184 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
185 return;
186 }
187
Jason Sams7dad9c32009-12-17 16:55:08 -0800188 //LOGE("bindtex %i %p", slot, a);
189 mTextures[slot].set(a);
190 mDirty = true;
191}
192
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800193void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700194 if (slot >= mTextureCount) {
195 LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
196 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
Jason Sams7dad9c32009-12-17 16:55:08 -0800197 return;
198 }
199
200 mSamplers[slot].set(s);
201 mDirty = true;
202}
203
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800204String8 Program::getGLSLInputString() const {
Jason Samsb4d35682010-01-04 16:52:27 -0800205 String8 s;
206 for (uint32_t ct=0; ct < mInputCount; ct++) {
207 const Element *e = mInputElements[ct].get();
208 for (uint32_t field=0; field < e->getFieldCount(); field++) {
209 const Element *f = e->getField(field);
210
211 // Cannot be complex
212 rsAssert(!f->getFieldCount());
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800213 switch (f->getComponent().getVectorSize()) {
Jason Samsb4d35682010-01-04 16:52:27 -0800214 case 1: s.append("attribute float ATTRIB_"); break;
215 case 2: s.append("attribute vec2 ATTRIB_"); break;
216 case 3: s.append("attribute vec3 ATTRIB_"); break;
217 case 4: s.append("attribute vec4 ATTRIB_"); break;
218 default:
219 rsAssert(0);
220 }
221
222 s.append(e->getFieldName(field));
223 s.append(";\n");
224 }
225 }
226 return s;
227}
228
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800229String8 Program::getGLSLOutputString() const {
Jason Samsb4d35682010-01-04 16:52:27 -0800230 return String8();
231}
232
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800233String8 Program::getGLSLConstantString() const {
Jason Samsb4d35682010-01-04 16:52:27 -0800234 return String8();
235}
236
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800237void Program::createShader() {
Jason Samsc460e552009-11-25 13:22:07 -0800238}
Jason Samscfb1d112009-08-05 13:57:03 -0700239
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800240bool Program::loadShader(Context *rsc, uint32_t type) {
Jason Samsc460e552009-11-25 13:22:07 -0800241 mShaderID = glCreateShader(type);
242 rsAssert(mShaderID);
243
Jason Samscd506532009-12-15 19:10:11 -0800244 if (rsc->props.mLogShaders) {
245 LOGV("Loading shader type %x, ID %i", type, mShaderID);
Nick Kralevich8492a702010-05-13 14:46:27 -0700246 LOGV("%s", mShader.string());
Jason Samscd506532009-12-15 19:10:11 -0800247 }
Jason Samsc460e552009-11-25 13:22:07 -0800248
249 if (mShaderID) {
250 const char * ss = mShader.string();
251 glShaderSource(mShaderID, 1, &ss, NULL);
252 glCompileShader(mShaderID);
253
254 GLint compiled = 0;
255 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
256 if (!compiled) {
257 GLint infoLen = 0;
258 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
259 if (infoLen) {
260 char* buf = (char*) malloc(infoLen);
261 if (buf) {
262 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
263 LOGE("Could not compile shader \n%s\n", buf);
264 free(buf);
265 }
266 glDeleteShader(mShaderID);
267 mShaderID = 0;
Jason Samsa2cf7552010-03-03 13:03:18 -0800268 rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
Jason Samsc460e552009-11-25 13:22:07 -0800269 return false;
270 }
271 }
272 }
Jason Samscd506532009-12-15 19:10:11 -0800273
274 if (rsc->props.mLogShaders) {
275 LOGV("--Shader load result %x ", glGetError());
276 }
Jason Samsa2cf7552010-03-03 13:03:18 -0800277 mIsValid = true;
Jason Samsc460e552009-11-25 13:22:07 -0800278 return true;
279}
Jason Samsf2a5d732009-11-30 14:49:55 -0800280
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800281void Program::setShader(const char *txt, uint32_t len) {
Jason Samsf2a5d732009-11-30 14:49:55 -0800282 mUserShader.setTo(txt, len);
283}
284
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700285void Program::appendUserConstants() {
286 for (uint32_t ct=0; ct < mConstantCount; ct++) {
287 const Element *e = mConstantTypes[ct]->getElement();
288 for (uint32_t field=0; field < e->getFieldCount(); field++) {
289 const Element *f = e->getField(field);
290 const char *fn = e->getFieldName(field);
Jason Sams4815c0d2009-12-15 12:58:36 -0800291
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700292 if (fn[0] == '#') {
293 continue;
294 }
295
296 // Cannot be complex
297 rsAssert(!f->getFieldCount());
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800298 if (f->getType() == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700299 mShader.append("uniform mat4 UNI_");
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800300 } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700301 mShader.append("uniform mat3 UNI_");
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800302 } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700303 mShader.append("uniform mat2 UNI_");
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800304 } else {
305 switch (f->getComponent().getVectorSize()) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700306 case 1: mShader.append("uniform float UNI_"); break;
307 case 2: mShader.append("uniform vec2 UNI_"); break;
308 case 3: mShader.append("uniform vec3 UNI_"); break;
309 case 4: mShader.append("uniform vec4 UNI_"); break;
310 default:
311 rsAssert(0);
312 }
313 }
314
315 mShader.append(fn);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800316 if (e->getFieldArraySize(field) > 1) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800317 mShader.appendFormat("[%d]", e->getFieldArraySize(field));
318 }
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700319 mShader.append(";\n");
320 }
321 }
322}
323
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800324void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
325 RsDataType dataType = field->getType();
326 uint32_t elementSize = field->getSizeBytes() / sizeof(float);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800327 for (uint32_t i = 0; i < arraySize; i ++) {
328 if (arraySize > 1) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800329 LOGV("Array Element [%u]", i);
330 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800331 if (dataType == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800332 LOGV("Matrix4x4");
333 LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
334 LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
335 LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
336 LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800337 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800338 LOGV("Matrix3x3");
339 LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
340 LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
341 LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800342 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800343 LOGV("Matrix2x2");
344 LOGV("{%f, %f", fd[0], fd[2]);
345 LOGV(" %f, %f}", fd[1], fd[3]);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800346 } else {
347 switch (field->getComponent().getVectorSize()) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800348 case 1:
349 LOGV("Uniform 1 = %f", fd[0]);
350 break;
351 case 2:
352 LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
353 break;
354 case 3:
355 LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
356 break;
357 case 4:
358 LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
359 break;
360 default:
361 rsAssert(0);
362 }
363 }
364 LOGE("Element size %u data=%p", elementSize, fd);
365 fd += elementSize;
366 LOGE("New data=%p", fd);
367 }
368}
369
370void Program::setUniform(Context *rsc, const Element *field, const float *fd,
371 int32_t slot, uint32_t arraySize ) {
372 RsDataType dataType = field->getType();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800373 if (dataType == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800374 glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800375 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800376 glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800377 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800378 glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800379 } else {
380 switch (field->getComponent().getVectorSize()) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800381 case 1:
382 glUniform1fv(slot, arraySize, fd);
383 break;
384 case 2:
385 glUniform2fv(slot, arraySize, fd);
386 break;
387 case 3:
388 glUniform3fv(slot, arraySize, fd);
389 break;
390 case 4:
391 glUniform4fv(slot, arraySize, fd);
392 break;
393 default:
394 rsAssert(0);
395 }
396 }
397}
398
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700399void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700400 uint32_t uidx = 0;
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700401 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700402 Allocation *alloc = mConstants[ct].get();
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700403 if (!alloc) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700404 LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
405 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700406 continue;
407 }
408
409 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
410 const Element *e = mConstantTypes[ct]->getElement();
411 for (uint32_t field=0; field < e->getFieldCount(); field++) {
412 const Element *f = e->getField(field);
413 const char *fieldName = e->getFieldName(field);
414 // If this field is padding, skip it
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800415 if (fieldName[0] == '#') {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700416 continue;
417 }
418
419 uint32_t offset = e->getFieldOffsetBytes(field);
420 const float *fd = reinterpret_cast<const float *>(&data[offset]);
421
422 int32_t slot = -1;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800423 uint32_t arraySize = 1;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800424 if (!isFragment) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700425 slot = sc->vtxUniformSlot(uidx);
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800426 arraySize = sc->vtxUniformSize(uidx);
427 } else {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700428 slot = sc->fragUniformSlot(uidx);
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800429 arraySize = sc->fragUniformSize(uidx);
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700430 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800431 if (rsc->props.mLogShadersUniforms) {
Alex Sakhartchouk886f11a2010-09-29 09:49:13 -0700432 LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
433 }
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700434 uidx ++;
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800435 if (slot < 0) {
436 continue;
437 }
438
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800439 if (rsc->props.mLogShadersUniforms) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800440 logUniform(f, fd, arraySize);
441 }
442 setUniform(rsc, f, fd, slot, arraySize);
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700443 }
444 }
445}
446
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800447void Program::initAttribAndUniformArray() {
448 mAttribCount = 0;
449 for (uint32_t ct=0; ct < mInputCount; ct++) {
450 const Element *elem = mInputElements[ct].get();
451 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800452 if (elem->getFieldName(field)[0] != '#') {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800453 mAttribCount ++;
454 }
455 }
456 }
457
458 mUniformCount = 0;
459 for (uint32_t ct=0; ct < mConstantCount; ct++) {
460 const Element *elem = mConstantTypes[ct]->getElement();
461
462 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800463 if (elem->getFieldName(field)[0] != '#') {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800464 mUniformCount ++;
465 }
466 }
467 }
468 mUniformCount += mTextureCount;
469
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800470 if (mAttribCount) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800471 mAttribNames = new String8[mAttribCount];
472 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800473 if (mUniformCount) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800474 mUniformNames = new String8[mUniformCount];
475 mUniformArraySizes = new uint32_t[mUniformCount];
476 }
477}
478
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800479void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700480 rsAssert(e->getFieldCount());
481 for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
482 const Element *ce = e->getField(ct);
483 if (ce->getFieldCount()) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800484 initAddUserElement(ce, names, arrayLengths, count, prefix);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800485 } else if (e->getFieldName(ct)[0] != '#') {
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700486 String8 tmp(prefix);
487 tmp.append(e->getFieldName(ct));
488 names[*count].setTo(tmp.string());
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800489 if (arrayLengths) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800490 arrayLengths[*count] = e->getFieldArraySize(ct);
491 }
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700492 (*count)++;
493 }
494 }
495}
Jason Sams4815c0d2009-12-15 12:58:36 -0800496
497namespace android {
498namespace renderscript {
499
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800500void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) {
Jason Sams4815c0d2009-12-15 12:58:36 -0800501 Program *p = static_cast<Program *>(vp);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700502 p->bindAllocation(rsc, static_cast<Allocation *>(constants), slot);
Jason Sams4815c0d2009-12-15 12:58:36 -0800503}
504
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800505void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800506 Program *p = static_cast<Program *>(vpf);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700507 p->bindTexture(rsc, slot, static_cast<Allocation *>(a));
Jason Sams7dad9c32009-12-17 16:55:08 -0800508}
509
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800510void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800511 Program *p = static_cast<Program *>(vpf);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700512 p->bindSampler(rsc, slot, static_cast<Sampler *>(s));
Jason Sams7dad9c32009-12-17 16:55:08 -0800513}
Jason Sams4815c0d2009-12-15 12:58:36 -0800514
515}
516}
517