1 /* 2 * Copyright (C) 2011-2012 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 24 #include "rsdCore.h" 25 #include "rsdAllocation.h" 26 #include "rsdShader.h" 27 #include "rsdShaderCache.h" 28 29 using namespace android; 30 using namespace android::renderscript; 31 32 RsdShader::RsdShader(const Program *p, uint32_t type, 33 const char * shaderText, size_t shaderLength, 34 const char** textureNames, size_t textureNamesCount, 35 const size_t *textureNamesLength) { 36 mUserShader.setTo(shaderText, shaderLength); 37 mRSProgram = p; 38 mType = type; 39 initMemberVars(); 40 initAttribAndUniformArray(); 41 init(textureNames, textureNamesCount, textureNamesLength); 42 43 for(size_t i=0; i < textureNamesCount; i++) { 44 mTextureNames.push(String8(textureNames[i], textureNamesLength[i])); 45 } 46 } 47 48 RsdShader::~RsdShader() { 49 for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) { 50 StateBasedKey *state = mStateBasedShaders.itemAt(i); 51 if (state->mShaderID) { 52 glDeleteShader(state->mShaderID); 53 } 54 delete state; 55 } 56 57 delete[] mAttribNames; 58 delete[] mUniformNames; 59 delete[] mUniformArraySizes; 60 } 61 62 void RsdShader::initMemberVars() { 63 mDirty = true; 64 mAttribCount = 0; 65 mUniformCount = 0; 66 67 mAttribNames = NULL; 68 mUniformNames = NULL; 69 mUniformArraySizes = NULL; 70 mCurrentState = NULL; 71 72 mIsValid = false; 73 } 74 75 RsdShader::StateBasedKey *RsdShader::getExistingState() { 76 RsdShader::StateBasedKey *returnKey = NULL; 77 78 for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) { 79 returnKey = mStateBasedShaders.itemAt(i); 80 81 for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) { 82 uint32_t texType = 0; 83 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) { 84 Allocation *a = mRSProgram->mHal.state.textures[ct]; 85 if (a && a->mHal.state.surfaceTextureID) { 86 texType = GL_TEXTURE_EXTERNAL_OES; 87 } else { 88 texType = GL_TEXTURE_2D; 89 } 90 } else { 91 texType = GL_TEXTURE_CUBE_MAP; 92 } 93 if (texType != returnKey->mTextureTargets[ct]) { 94 returnKey = NULL; 95 break; 96 } 97 } 98 } 99 return returnKey; 100 } 101 102 uint32_t RsdShader::getStateBasedShaderID(const Context *rsc) { 103 StateBasedKey *state = getExistingState(); 104 if (state != NULL) { 105 mCurrentState = state; 106 return mCurrentState->mShaderID; 107 } 108 // We have not created a shader for this particular state yet 109 state = new StateBasedKey(mTextureCount); 110 mCurrentState = state; 111 mStateBasedShaders.add(state); 112 createShader(); 113 loadShader(rsc); 114 return mCurrentState->mShaderID; 115 } 116 117 void RsdShader::init(const char** textureNames, size_t textureNamesCount, 118 const size_t *textureNamesLength) { 119 uint32_t attribCount = 0; 120 uint32_t uniformCount = 0; 121 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { 122 initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, 123 NULL, &attribCount, RS_SHADER_ATTR); 124 } 125 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 126 initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), 127 mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI); 128 } 129 130 mTextureUniformIndexStart = uniformCount; 131 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) { 132 mUniformNames[uniformCount].setTo("UNI_"); 133 mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]); 134 mUniformArraySizes[uniformCount] = 1; 135 uniformCount++; 136 } 137 } 138 139 String8 RsdShader::getGLSLInputString() const { 140 String8 s; 141 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { 142 const Element *e = mRSProgram->mHal.state.inputElements[ct]; 143 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) { 144 const Element *f = e->mHal.state.fields[field]; 145 146 // Cannot be complex 147 rsAssert(!f->mHal.state.fieldsCount); 148 switch (f->mHal.state.vectorSize) { 149 case 1: s.append("attribute float ATTRIB_"); break; 150 case 2: s.append("attribute vec2 ATTRIB_"); break; 151 case 3: s.append("attribute vec3 ATTRIB_"); break; 152 case 4: s.append("attribute vec4 ATTRIB_"); break; 153 default: 154 rsAssert(0); 155 } 156 157 s.append(e->mHal.state.fieldNames[field]); 158 s.append(";\n"); 159 } 160 } 161 return s; 162 } 163 164 void RsdShader::appendAttributes() { 165 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { 166 const Element *e = mRSProgram->mHal.state.inputElements[ct]; 167 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) { 168 const Element *f = e->mHal.state.fields[field]; 169 const char *fn = e->mHal.state.fieldNames[field]; 170 171 // Cannot be complex 172 rsAssert(!f->mHal.state.fieldsCount); 173 switch (f->mHal.state.vectorSize) { 174 case 1: mShader.append("attribute float ATTRIB_"); break; 175 case 2: mShader.append("attribute vec2 ATTRIB_"); break; 176 case 3: mShader.append("attribute vec3 ATTRIB_"); break; 177 case 4: mShader.append("attribute vec4 ATTRIB_"); break; 178 default: 179 rsAssert(0); 180 } 181 182 mShader.append(fn); 183 mShader.append(";\n"); 184 } 185 } 186 } 187 188 void RsdShader::appendTextures() { 189 190 // TODO: this does not yet handle cases where the texture changes between IO 191 // input and local 192 bool appendUsing = true; 193 for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) { 194 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) { 195 Allocation *a = mRSProgram->mHal.state.textures[ct]; 196 if (a && a->mHal.state.surfaceTextureID) { 197 if(appendUsing) { 198 mShader.append("#extension GL_OES_EGL_image_external : require\n"); 199 appendUsing = false; 200 } 201 mShader.append("uniform samplerExternalOES UNI_"); 202 mCurrentState->mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES; 203 } else { 204 mShader.append("uniform sampler2D UNI_"); 205 mCurrentState->mTextureTargets[ct] = GL_TEXTURE_2D; 206 } 207 } else { 208 mShader.append("uniform samplerCube UNI_"); 209 mCurrentState->mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP; 210 } 211 212 mShader.append(mTextureNames[ct]); 213 mShader.append(";\n"); 214 } 215 } 216 217 bool RsdShader::createShader() { 218 mShader.clear(); 219 if (mType == GL_FRAGMENT_SHADER) { 220 mShader.append("precision mediump float;\n"); 221 } 222 appendUserConstants(); 223 appendAttributes(); 224 appendTextures(); 225 mShader.append(mUserShader); 226 227 return true; 228 } 229 230 bool RsdShader::loadShader(const Context *rsc) { 231 mCurrentState->mShaderID = glCreateShader(mType); 232 rsAssert(mCurrentState->mShaderID); 233 234 if(!mShader.length()) { 235 createShader(); 236 } 237 238 if (rsc->props.mLogShaders) { 239 ALOGV("Loading shader type %x, ID %i", mType, mCurrentState->mShaderID); 240 ALOGV("%s", mShader.string()); 241 } 242 243 if (mCurrentState->mShaderID) { 244 const char * ss = mShader.string(); 245 RSD_CALL_GL(glShaderSource, mCurrentState->mShaderID, 1, &ss, NULL); 246 RSD_CALL_GL(glCompileShader, mCurrentState->mShaderID); 247 248 GLint compiled = 0; 249 RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_COMPILE_STATUS, &compiled); 250 if (!compiled) { 251 GLint infoLen = 0; 252 RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_INFO_LOG_LENGTH, &infoLen); 253 if (infoLen) { 254 char* buf = (char*) malloc(infoLen); 255 if (buf) { 256 RSD_CALL_GL(glGetShaderInfoLog, mCurrentState->mShaderID, infoLen, NULL, buf); 257 rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf); 258 free(buf); 259 } 260 RSD_CALL_GL(glDeleteShader, mCurrentState->mShaderID); 261 mCurrentState->mShaderID = 0; 262 return false; 263 } 264 } 265 } 266 267 if (rsc->props.mLogShaders) { 268 ALOGV("--Shader load result %x ", glGetError()); 269 } 270 mIsValid = true; 271 return true; 272 } 273 274 void RsdShader::appendUserConstants() { 275 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 276 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement(); 277 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) { 278 const Element *f = e->mHal.state.fields[field]; 279 const char *fn = e->mHal.state.fieldNames[field]; 280 281 // Cannot be complex 282 rsAssert(!f->mHal.state.fieldsCount); 283 if (f->mHal.state.dataType == RS_TYPE_MATRIX_4X4) { 284 mShader.append("uniform mat4 UNI_"); 285 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_3X3) { 286 mShader.append("uniform mat3 UNI_"); 287 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_2X2) { 288 mShader.append("uniform mat2 UNI_"); 289 } else { 290 switch (f->mHal.state.vectorSize) { 291 case 1: mShader.append("uniform float UNI_"); break; 292 case 2: mShader.append("uniform vec2 UNI_"); break; 293 case 3: mShader.append("uniform vec3 UNI_"); break; 294 case 4: mShader.append("uniform vec4 UNI_"); break; 295 default: 296 rsAssert(0); 297 } 298 } 299 300 mShader.append(fn); 301 if (e->mHal.state.fieldArraySizes[field] > 1) { 302 mShader.appendFormat("[%d]", e->mHal.state.fieldArraySizes[field]); 303 } 304 mShader.append(";\n"); 305 } 306 } 307 } 308 309 void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) { 310 RsDataType dataType = field->mHal.state.dataType; 311 uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float); 312 for (uint32_t i = 0; i < arraySize; i ++) { 313 if (arraySize > 1) { 314 ALOGV("Array Element [%u]", i); 315 } 316 if (dataType == RS_TYPE_MATRIX_4X4) { 317 ALOGV("Matrix4x4"); 318 ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]); 319 ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]); 320 ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]); 321 ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]); 322 } else if (dataType == RS_TYPE_MATRIX_3X3) { 323 ALOGV("Matrix3x3"); 324 ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]); 325 ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]); 326 ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]); 327 } else if (dataType == RS_TYPE_MATRIX_2X2) { 328 ALOGV("Matrix2x2"); 329 ALOGV("{%f, %f", fd[0], fd[2]); 330 ALOGV(" %f, %f}", fd[1], fd[3]); 331 } else { 332 switch (field->mHal.state.vectorSize) { 333 case 1: 334 ALOGV("Uniform 1 = %f", fd[0]); 335 break; 336 case 2: 337 ALOGV("Uniform 2 = %f %f", fd[0], fd[1]); 338 break; 339 case 3: 340 ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]); 341 break; 342 case 4: 343 ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]); 344 break; 345 default: 346 rsAssert(0); 347 } 348 } 349 ALOGV("Element size %u data=%p", elementSize, fd); 350 fd += elementSize; 351 ALOGV("New data=%p", fd); 352 } 353 } 354 355 void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd, 356 int32_t slot, uint32_t arraySize ) { 357 RsDataType dataType = field->mHal.state.dataType; 358 if (dataType == RS_TYPE_MATRIX_4X4) { 359 RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd); 360 } else if (dataType == RS_TYPE_MATRIX_3X3) { 361 RSD_CALL_GL(glUniformMatrix3fv, slot, arraySize, GL_FALSE, fd); 362 } else if (dataType == RS_TYPE_MATRIX_2X2) { 363 RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd); 364 } else { 365 switch (field->mHal.state.vectorSize) { 366 case 1: 367 RSD_CALL_GL(glUniform1fv, slot, arraySize, fd); 368 break; 369 case 2: 370 RSD_CALL_GL(glUniform2fv, slot, arraySize, fd); 371 break; 372 case 3: 373 RSD_CALL_GL(glUniform3fv, slot, arraySize, fd); 374 break; 375 case 4: 376 RSD_CALL_GL(glUniform4fv, slot, arraySize, fd); 377 break; 378 default: 379 rsAssert(0); 380 } 381 } 382 } 383 384 void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) { 385 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 386 387 GLenum trans[] = { 388 GL_NEAREST, //RS_SAMPLER_NEAREST, 389 GL_LINEAR, //RS_SAMPLER_LINEAR, 390 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR, 391 GL_REPEAT, //RS_SAMPLER_WRAP, 392 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP 393 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST 394 }; 395 396 GLenum transNP[] = { 397 GL_NEAREST, //RS_SAMPLER_NEAREST, 398 GL_LINEAR, //RS_SAMPLER_LINEAR, 399 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR, 400 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP, 401 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP 402 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST, 403 }; 404 405 // This tells us the correct texture type 406 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv; 407 const GLenum target = drvTex->glTarget; 408 if (!target) { 409 // this can happen if the user set the wrong allocation flags. 410 rsc->setError(RS_ERROR_BAD_VALUE, "Allocation not compatible with sampler"); 411 return; 412 } 413 414 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) { 415 if (tex->getHasGraphicsMipmaps() && 416 (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) { 417 if (dc->gl.gl.NV_texture_npot_2D_mipmap) { 418 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 419 trans[s->mHal.state.minFilter]); 420 } else { 421 switch (trans[s->mHal.state.minFilter]) { 422 case GL_LINEAR_MIPMAP_LINEAR: 423 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 424 GL_LINEAR_MIPMAP_NEAREST); 425 break; 426 default: 427 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 428 trans[s->mHal.state.minFilter]); 429 break; 430 } 431 } 432 } else { 433 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 434 transNP[s->mHal.state.minFilter]); 435 } 436 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, 437 transNP[s->mHal.state.magFilter]); 438 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]); 439 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]); 440 } else { 441 if (tex->getHasGraphicsMipmaps()) { 442 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 443 trans[s->mHal.state.minFilter]); 444 } else { 445 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 446 transNP[s->mHal.state.minFilter]); 447 } 448 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]); 449 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]); 450 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]); 451 } 452 453 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso); 454 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) { 455 RSD_CALL_GL(glTexParameterf, target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue); 456 } 457 458 rsdGLCheckError(rsc, "Sampler::setup tex env"); 459 } 460 461 void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { 462 if (mRSProgram->mHal.state.texturesCount == 0) { 463 return; 464 } 465 466 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 467 468 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount; 469 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits; 470 if (numTexturesToBind >= numTexturesAvailable) { 471 ALOGE("Attempting to bind %u textures on shader id %u, but only %u are available", 472 mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable); 473 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available"); 474 numTexturesToBind = numTexturesAvailable; 475 } 476 477 for (uint32_t ct=0; ct < numTexturesToBind; ct++) { 478 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct); 479 RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct); 480 481 if (!mRSProgram->mHal.state.textures[ct]) { 482 // if nothing is bound, reset to default GL texture 483 RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], 0); 484 continue; 485 } 486 487 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv; 488 489 if (mCurrentState->mTextureTargets[ct] != GL_TEXTURE_2D && 490 mCurrentState->mTextureTargets[ct] != GL_TEXTURE_CUBE_MAP && 491 mCurrentState->mTextureTargets[ct] != GL_TEXTURE_EXTERNAL_OES) { 492 ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", 493 (uint)this, ct); 494 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); 495 } 496 RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], drvTex->textureID); 497 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind"); 498 if (mRSProgram->mHal.state.samplers[ct]) { 499 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct], 500 mRSProgram->mHal.state.textures[ct]); 501 } else { 502 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 503 GL_TEXTURE_MIN_FILTER, GL_NEAREST); 504 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 505 GL_TEXTURE_MAG_FILTER, GL_NEAREST); 506 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 507 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 508 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 509 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 510 rsdGLCheckError(rsc, "ProgramFragment::setup basic tex env"); 511 } 512 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms"); 513 } 514 515 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0); 516 mDirty = false; 517 rsdGLCheckError(rsc, "ProgramFragment::setup"); 518 } 519 520 void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) { 521 uint32_t uidx = 0; 522 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 523 Allocation *alloc = mRSProgram->mHal.state.constants[ct]; 524 525 if (!alloc) { 526 ALOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", 527 (uint32_t)this, ct); 528 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound"); 529 continue; 530 } 531 532 const uint8_t *data = static_cast<const uint8_t *>(alloc->mHal.drvState.lod[0].mallocPtr); 533 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement(); 534 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) { 535 const Element *f = e->mHal.state.fields[field]; 536 const char *fieldName = e->mHal.state.fieldNames[field]; 537 538 uint32_t offset = e->mHal.state.fieldOffsetBytes[field]; 539 const float *fd = reinterpret_cast<const float *>(&data[offset]); 540 541 int32_t slot = -1; 542 uint32_t arraySize = 1; 543 if (!isFragment) { 544 slot = sc->vtxUniformSlot(uidx); 545 arraySize = sc->vtxUniformSize(uidx); 546 } else { 547 slot = sc->fragUniformSlot(uidx); 548 arraySize = sc->fragUniformSize(uidx); 549 } 550 if (rsc->props.mLogShadersUniforms) { 551 ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", 552 slot, offset, ct, field, uidx, fieldName); 553 } 554 uidx ++; 555 if (slot < 0) { 556 continue; 557 } 558 559 if (rsc->props.mLogShadersUniforms) { 560 logUniform(f, fd, arraySize); 561 } 562 setUniform(rsc, f, fd, slot, arraySize); 563 } 564 } 565 } 566 567 void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) { 568 569 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER); 570 setupTextures(rsc, sc); 571 } 572 573 void RsdShader::initAttribAndUniformArray() { 574 mAttribCount = 0; 575 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { 576 const Element *elem = mRSProgram->mHal.state.inputElements[ct]; 577 mAttribCount += elem->mHal.state.fieldsCount; 578 } 579 580 mUniformCount = 0; 581 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 582 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement(); 583 mUniformCount += elem->mHal.state.fieldsCount; 584 } 585 mUniformCount += mRSProgram->mHal.state.texturesCount; 586 587 if (mAttribCount) { 588 mAttribNames = new String8[mAttribCount]; 589 } 590 if (mUniformCount) { 591 mUniformNames = new String8[mUniformCount]; 592 mUniformArraySizes = new uint32_t[mUniformCount]; 593 } 594 595 mTextureCount = mRSProgram->mHal.state.texturesCount; 596 } 597 598 void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, 599 uint32_t *count, const char *prefix) { 600 rsAssert(e->mHal.state.fieldsCount); 601 for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) { 602 const Element *ce = e->mHal.state.fields[ct]; 603 if (ce->mHal.state.fieldsCount) { 604 initAddUserElement(ce, names, arrayLengths, count, prefix); 605 } else { 606 String8 tmp(prefix); 607 tmp.append(e->mHal.state.fieldNames[ct]); 608 names[*count].setTo(tmp.string()); 609 if (arrayLengths) { 610 arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct]; 611 } 612 (*count)++; 613 } 614 } 615 } 616