blob: 90fe4b237164ae0c70e19aa09e2606034af55397 [file] [log] [blame]
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -07001/*
2 * Copyright (C) 2011 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 <GLES2/gl2.h>
18#include <GLES2/gl2ext.h>
19
20#include <rs_hal.h>
21#include <rsContext.h>
22#include <rsProgram.h>
23
Alex Sakhartchouk43850542011-05-05 16:56:27 -070024#include "rsdCore.h"
Jason Sams7e8aae72011-05-26 16:33:01 -070025#include "rsdAllocation.h"
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070026#include "rsdShader.h"
27#include "rsdShaderCache.h"
28
29using namespace android;
30using namespace android::renderscript;
31
32RsdShader::RsdShader(const Program *p, uint32_t type,
33 const char * shaderText, uint32_t shaderLength) {
34
35 mUserShader.setTo(shaderText, shaderLength);
36 mRSProgram = p;
37 mType = type;
38 initMemberVars();
39 initAttribAndUniformArray();
40 init();
41}
42
43RsdShader::~RsdShader() {
44 if (mShaderID) {
45 glDeleteShader(mShaderID);
46 }
47
48 delete[] mAttribNames;
49 delete[] mUniformNames;
50 delete[] mUniformArraySizes;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070051 delete[] mTextureTargets;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070052}
53
54void RsdShader::initMemberVars() {
55 mDirty = true;
56 mShaderID = 0;
57 mAttribCount = 0;
58 mUniformCount = 0;
59
60 mAttribNames = NULL;
61 mUniformNames = NULL;
62 mUniformArraySizes = NULL;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070063 mTextureTargets = NULL;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070064
65 mIsValid = false;
66}
67
68void RsdShader::init() {
69 uint32_t attribCount = 0;
70 uint32_t uniformCount = 0;
71 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
72 initAddUserElement(mRSProgram->mHal.state.inputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
73 }
74 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
75 initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
76 }
77
78 mTextureUniformIndexStart = uniformCount;
79 char buf[256];
80 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
81 snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
82 mUniformNames[uniformCount].setTo(buf);
83 mUniformArraySizes[uniformCount] = 1;
84 uniformCount++;
85 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070086
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070087}
88
89String8 RsdShader::getGLSLInputString() const {
90 String8 s;
91 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
92 const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
93 for (uint32_t field=0; field < e->getFieldCount(); field++) {
94 const Element *f = e->getField(field);
95
96 // Cannot be complex
97 rsAssert(!f->getFieldCount());
98 switch (f->getComponent().getVectorSize()) {
99 case 1: s.append("attribute float ATTRIB_"); break;
100 case 2: s.append("attribute vec2 ATTRIB_"); break;
101 case 3: s.append("attribute vec3 ATTRIB_"); break;
102 case 4: s.append("attribute vec4 ATTRIB_"); break;
103 default:
104 rsAssert(0);
105 }
106
107 s.append(e->getFieldName(field));
108 s.append(";\n");
109 }
110 }
111 return s;
112}
113
114void RsdShader::appendAttributes() {
115 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
116 const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
117 for (uint32_t field=0; field < e->getFieldCount(); field++) {
118 const Element *f = e->getField(field);
119 const char *fn = e->getFieldName(field);
120
121 if (fn[0] == '#') {
122 continue;
123 }
124
125 // Cannot be complex
126 rsAssert(!f->getFieldCount());
127 switch (f->getComponent().getVectorSize()) {
128 case 1: mShader.append("attribute float ATTRIB_"); break;
129 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
130 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
131 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
132 default:
133 rsAssert(0);
134 }
135
136 mShader.append(fn);
137 mShader.append(";\n");
138 }
139 }
140}
141
142void RsdShader::appendTextures() {
143 char buf[256];
144 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
145 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
146 snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700147 mTextureTargets[ct] = GL_TEXTURE_2D;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700148 } else {
149 snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700150 mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700151 }
152 mShader.append(buf);
153 }
154}
155
156bool RsdShader::createShader() {
157
158 if (mType == GL_FRAGMENT_SHADER) {
159 mShader.append("precision mediump float;\n");
160 }
161 appendUserConstants();
162 appendAttributes();
163 appendTextures();
164
165 mShader.append(mUserShader);
166
167 return true;
168}
169
170bool RsdShader::loadShader(const Context *rsc) {
171 mShaderID = glCreateShader(mType);
172 rsAssert(mShaderID);
173
174 if (rsc->props.mLogShaders) {
175 LOGV("Loading shader type %x, ID %i", mType, mShaderID);
176 LOGV("%s", mShader.string());
177 }
178
179 if (mShaderID) {
180 const char * ss = mShader.string();
181 glShaderSource(mShaderID, 1, &ss, NULL);
182 glCompileShader(mShaderID);
183
184 GLint compiled = 0;
185 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
186 if (!compiled) {
187 GLint infoLen = 0;
188 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
189 if (infoLen) {
190 char* buf = (char*) malloc(infoLen);
191 if (buf) {
192 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
193 LOGE("Could not compile shader \n%s\n", buf);
194 free(buf);
195 }
196 glDeleteShader(mShaderID);
197 mShaderID = 0;
198 rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
199 return false;
200 }
201 }
202 }
203
204 if (rsc->props.mLogShaders) {
205 LOGV("--Shader load result %x ", glGetError());
206 }
207 mIsValid = true;
208 return true;
209}
210
211void RsdShader::appendUserConstants() {
212 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
213 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
214 for (uint32_t field=0; field < e->getFieldCount(); field++) {
215 const Element *f = e->getField(field);
216 const char *fn = e->getFieldName(field);
217
218 if (fn[0] == '#') {
219 continue;
220 }
221
222 // Cannot be complex
223 rsAssert(!f->getFieldCount());
224 if (f->getType() == RS_TYPE_MATRIX_4X4) {
225 mShader.append("uniform mat4 UNI_");
226 } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
227 mShader.append("uniform mat3 UNI_");
228 } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
229 mShader.append("uniform mat2 UNI_");
230 } else {
231 switch (f->getComponent().getVectorSize()) {
232 case 1: mShader.append("uniform float UNI_"); break;
233 case 2: mShader.append("uniform vec2 UNI_"); break;
234 case 3: mShader.append("uniform vec3 UNI_"); break;
235 case 4: mShader.append("uniform vec4 UNI_"); break;
236 default:
237 rsAssert(0);
238 }
239 }
240
241 mShader.append(fn);
242 if (e->getFieldArraySize(field) > 1) {
243 mShader.appendFormat("[%d]", e->getFieldArraySize(field));
244 }
245 mShader.append(";\n");
246 }
247 }
248}
249
250void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
251 RsDataType dataType = field->getType();
252 uint32_t elementSize = field->getSizeBytes() / sizeof(float);
253 for (uint32_t i = 0; i < arraySize; i ++) {
254 if (arraySize > 1) {
255 LOGV("Array Element [%u]", i);
256 }
257 if (dataType == RS_TYPE_MATRIX_4X4) {
258 LOGV("Matrix4x4");
259 LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
260 LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
261 LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
262 LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
263 } else if (dataType == RS_TYPE_MATRIX_3X3) {
264 LOGV("Matrix3x3");
265 LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
266 LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
267 LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
268 } else if (dataType == RS_TYPE_MATRIX_2X2) {
269 LOGV("Matrix2x2");
270 LOGV("{%f, %f", fd[0], fd[2]);
271 LOGV(" %f, %f}", fd[1], fd[3]);
272 } else {
273 switch (field->getComponent().getVectorSize()) {
274 case 1:
275 LOGV("Uniform 1 = %f", fd[0]);
276 break;
277 case 2:
278 LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
279 break;
280 case 3:
281 LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
282 break;
283 case 4:
284 LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
285 break;
286 default:
287 rsAssert(0);
288 }
289 }
290 LOGE("Element size %u data=%p", elementSize, fd);
291 fd += elementSize;
292 LOGE("New data=%p", fd);
293 }
294}
295
296void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
297 int32_t slot, uint32_t arraySize ) {
298 RsDataType dataType = field->getType();
299 if (dataType == RS_TYPE_MATRIX_4X4) {
300 glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
301 } else if (dataType == RS_TYPE_MATRIX_3X3) {
302 glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
303 } else if (dataType == RS_TYPE_MATRIX_2X2) {
304 glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
305 } else {
306 switch (field->getComponent().getVectorSize()) {
307 case 1:
308 glUniform1fv(slot, arraySize, fd);
309 break;
310 case 2:
311 glUniform2fv(slot, arraySize, fd);
312 break;
313 case 3:
314 glUniform3fv(slot, arraySize, fd);
315 break;
316 case 4:
317 glUniform4fv(slot, arraySize, fd);
318 break;
319 default:
320 rsAssert(0);
321 }
322 }
323}
324
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700325void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) {
326 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
327
328 GLenum trans[] = {
329 GL_NEAREST, //RS_SAMPLER_NEAREST,
330 GL_LINEAR, //RS_SAMPLER_LINEAR,
331 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
332 GL_REPEAT, //RS_SAMPLER_WRAP,
333 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
334 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
335 };
336
337 GLenum transNP[] = {
338 GL_NEAREST, //RS_SAMPLER_NEAREST,
339 GL_LINEAR, //RS_SAMPLER_LINEAR,
340 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
341 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
342 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
343 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
344 };
345
346 // This tells us the correct texture type
Jason Sams7e8aae72011-05-26 16:33:01 -0700347 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv;
348 const GLenum target = drvTex->glTarget;
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700349
350 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
351 if (tex->getHasGraphicsMipmaps() &&
352 (dc->gl.gl.GL_NV_texture_npot_2D_mipmap || dc->gl.gl.GL_IMG_texture_npot)) {
353 if (dc->gl.gl.GL_NV_texture_npot_2D_mipmap) {
354 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
355 } else {
356 switch (trans[s->mHal.state.minFilter]) {
357 case GL_LINEAR_MIPMAP_LINEAR:
358 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
359 break;
360 default:
361 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
362 break;
363 }
364 }
365 } else {
366 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[s->mHal.state.minFilter]);
367 }
368 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[s->mHal.state.magFilter]);
369 glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]);
370 glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]);
371 } else {
372 if (tex->getHasGraphicsMipmaps()) {
373 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
374 } else {
375 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[s->mHal.state.minFilter]);
376 }
377 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]);
378 glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]);
379 glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]);
380 }
381
382 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso);
383 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) {
384 glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
385 }
386
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700387 rsdGLCheckError(rsc, "Sampler::setup tex env");
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700388}
389
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700390void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
391 if (mRSProgram->mHal.state.texturesCount == 0) {
392 return;
393 }
394
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700395 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
396
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700397 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700398 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700399 if (numTexturesToBind >= numTexturesAvailable) {
400 LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
401 mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
402 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
403 numTexturesToBind = numTexturesAvailable;
404 }
405
406 for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
407 glActiveTexture(GL_TEXTURE0 + ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700408 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
409
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700410 if (!mRSProgram->mHal.state.textures[ct].get()) {
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700411 // if nothing is bound, reset to default GL texture
412 glBindTexture(mTextureTargets[ct], 0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700413 continue;
414 }
415
Jason Sams7e8aae72011-05-26 16:33:01 -0700416 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
417 if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700418 LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
419 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
420 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700421 glBindTexture(drvTex->glTarget, drvTex->textureID);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700422 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700423 if (mRSProgram->mHal.state.samplers[ct].get()) {
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700424 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct].get(), mRSProgram->mHal.state.textures[ct].get());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700425 } else {
Jason Sams7e8aae72011-05-26 16:33:01 -0700426 glTexParameteri(drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
427 glTexParameteri(drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
428 glTexParameteri(drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
429 glTexParameteri(drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700430 rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700431 }
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700432 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700433 }
434
435 glActiveTexture(GL_TEXTURE0);
436 mDirty = false;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700437 rsdGLCheckError(rsc, "ProgramFragment::setup");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700438}
439
440void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
441 uint32_t uidx = 0;
442 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
443 Allocation *alloc = mRSProgram->mHal.state.constants[ct].get();
444 if (!alloc) {
445 LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
446 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
447 continue;
448 }
449
450 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
451 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
452 for (uint32_t field=0; field < e->getFieldCount(); field++) {
453 const Element *f = e->getField(field);
454 const char *fieldName = e->getFieldName(field);
455 // If this field is padding, skip it
456 if (fieldName[0] == '#') {
457 continue;
458 }
459
460 uint32_t offset = e->getFieldOffsetBytes(field);
461 const float *fd = reinterpret_cast<const float *>(&data[offset]);
462
463 int32_t slot = -1;
464 uint32_t arraySize = 1;
465 if (!isFragment) {
466 slot = sc->vtxUniformSlot(uidx);
467 arraySize = sc->vtxUniformSize(uidx);
468 } else {
469 slot = sc->fragUniformSlot(uidx);
470 arraySize = sc->fragUniformSize(uidx);
471 }
472 if (rsc->props.mLogShadersUniforms) {
473 LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
474 }
475 uidx ++;
476 if (slot < 0) {
477 continue;
478 }
479
480 if (rsc->props.mLogShadersUniforms) {
481 logUniform(f, fd, arraySize);
482 }
483 setUniform(rsc, f, fd, slot, arraySize);
484 }
485 }
486}
487
488void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
489
490 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
491 setupTextures(rsc, sc);
492}
493
494void RsdShader::initAttribAndUniformArray() {
495 mAttribCount = 0;
496 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
497 const Element *elem = mRSProgram->mHal.state.inputElements[ct].get();
498 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
499 if (elem->getFieldName(field)[0] != '#') {
500 mAttribCount ++;
501 }
502 }
503 }
504
505 mUniformCount = 0;
506 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
507 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
508
509 for (uint32_t field=0; field < elem->getFieldCount(); field++) {
510 if (elem->getFieldName(field)[0] != '#') {
511 mUniformCount ++;
512 }
513 }
514 }
515 mUniformCount += mRSProgram->mHal.state.texturesCount;
516
517 if (mAttribCount) {
518 mAttribNames = new String8[mAttribCount];
519 }
520 if (mUniformCount) {
521 mUniformNames = new String8[mUniformCount];
522 mUniformArraySizes = new uint32_t[mUniformCount];
523 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700524
525 mTextureCount = mRSProgram->mHal.state.texturesCount;
526 if (mTextureCount) {
527 mTextureTargets = new uint32_t[mTextureCount];
528 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700529}
530
531void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
532 rsAssert(e->getFieldCount());
533 for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
534 const Element *ce = e->getField(ct);
535 if (ce->getFieldCount()) {
536 initAddUserElement(ce, names, arrayLengths, count, prefix);
537 } else if (e->getFieldName(ct)[0] != '#') {
538 String8 tmp(prefix);
539 tmp.append(e->getFieldName(ct));
540 names[*count].setTo(tmp.string());
541 if (arrayLengths) {
542 arrayLengths[*count] = e->getFieldArraySize(ct);
543 }
544 (*count)++;
545 }
546 }
547}