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.replace(0, shaderLength, shaderText); 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 = nullptr; 68 mUniformNames = nullptr; 69 mUniformArraySizes = nullptr; 70 mCurrentState = nullptr; 71 72 mIsValid = false; 73 } 74 75 RsdShader::StateBasedKey *RsdShader::getExistingState() { 76 RsdShader::StateBasedKey *returnKey = nullptr; 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 = nullptr; 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 != nullptr) { 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 nullptr, &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] = "UNI_"; 133 mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]); 134 mUniformArraySizes[uniformCount] = 1; 135 uniformCount++; 136 } 137 } 138 139 std::string RsdShader::getGLSLInputString() const { 140 std::string 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.c_str()); 241 } 242 243 if (mCurrentState->mShaderID) { 244 const char * ss = mShader.c_str(); 245 RSD_CALL_GL(glShaderSource, mCurrentState->mShaderID, 1, &ss, nullptr); 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, nullptr, 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 += "["; 303 mShader += std::to_string(e->mHal.state.fieldArraySizes[field]); 304 mShader += "]"; 305 } 306 mShader.append(";\n"); 307 } 308 } 309 } 310 311 void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) { 312 RsDataType dataType = field->mHal.state.dataType; 313 uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float); 314 for (uint32_t i = 0; i < arraySize; i ++) { 315 if (arraySize > 1) { 316 ALOGV("Array Element [%u]", i); 317 } 318 if (dataType == RS_TYPE_MATRIX_4X4) { 319 ALOGV("Matrix4x4"); 320 ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]); 321 ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]); 322 ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]); 323 ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]); 324 } else if (dataType == RS_TYPE_MATRIX_3X3) { 325 ALOGV("Matrix3x3"); 326 ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]); 327 ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]); 328 ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]); 329 } else if (dataType == RS_TYPE_MATRIX_2X2) { 330 ALOGV("Matrix2x2"); 331 ALOGV("{%f, %f", fd[0], fd[2]); 332 ALOGV(" %f, %f}", fd[1], fd[3]); 333 } else { 334 switch (field->mHal.state.vectorSize) { 335 case 1: 336 ALOGV("Uniform 1 = %f", fd[0]); 337 break; 338 case 2: 339 ALOGV("Uniform 2 = %f %f", fd[0], fd[1]); 340 break; 341 case 3: 342 ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]); 343 break; 344 case 4: 345 ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]); 346 break; 347 default: 348 rsAssert(0); 349 } 350 } 351 ALOGV("Element size %u data=%p", elementSize, fd); 352 fd += elementSize; 353 ALOGV("New data=%p", fd); 354 } 355 } 356 357 void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd, 358 int32_t slot, uint32_t arraySize ) { 359 RsDataType dataType = field->mHal.state.dataType; 360 if (dataType == RS_TYPE_MATRIX_4X4) { 361 RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd); 362 } else if (dataType == RS_TYPE_MATRIX_3X3) { 363 RSD_CALL_GL(glUniformMatrix3fv, slot, arraySize, GL_FALSE, fd); 364 } else if (dataType == RS_TYPE_MATRIX_2X2) { 365 RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd); 366 } else { 367 switch (field->mHal.state.vectorSize) { 368 case 1: 369 RSD_CALL_GL(glUniform1fv, slot, arraySize, fd); 370 break; 371 case 2: 372 RSD_CALL_GL(glUniform2fv, slot, arraySize, fd); 373 break; 374 case 3: 375 RSD_CALL_GL(glUniform3fv, slot, arraySize, fd); 376 break; 377 case 4: 378 RSD_CALL_GL(glUniform4fv, slot, arraySize, fd); 379 break; 380 default: 381 rsAssert(0); 382 } 383 } 384 } 385 386 void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) { 387 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 388 389 GLenum trans[] = { 390 GL_NEAREST, //RS_SAMPLER_NEAREST, 391 GL_LINEAR, //RS_SAMPLER_LINEAR, 392 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR, 393 GL_REPEAT, //RS_SAMPLER_WRAP, 394 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP 395 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST 396 }; 397 398 GLenum transNP[] = { 399 GL_NEAREST, //RS_SAMPLER_NEAREST, 400 GL_LINEAR, //RS_SAMPLER_LINEAR, 401 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR, 402 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP, 403 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP 404 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST, 405 }; 406 407 // This tells us the correct texture type 408 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv; 409 const GLenum target = drvTex->glTarget; 410 if (!target) { 411 // this can happen if the user set the wrong allocation flags. 412 rsc->setError(RS_ERROR_BAD_VALUE, "Allocation not compatible with sampler"); 413 return; 414 } 415 416 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) { 417 if (tex->getHasGraphicsMipmaps() && 418 (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) { 419 if (dc->gl.gl.NV_texture_npot_2D_mipmap) { 420 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 421 trans[s->mHal.state.minFilter]); 422 } else { 423 switch (trans[s->mHal.state.minFilter]) { 424 case GL_LINEAR_MIPMAP_LINEAR: 425 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 426 GL_LINEAR_MIPMAP_NEAREST); 427 break; 428 default: 429 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 430 trans[s->mHal.state.minFilter]); 431 break; 432 } 433 } 434 } else { 435 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 436 transNP[s->mHal.state.minFilter]); 437 } 438 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, 439 transNP[s->mHal.state.magFilter]); 440 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]); 441 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]); 442 } else { 443 if (tex->getHasGraphicsMipmaps()) { 444 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 445 trans[s->mHal.state.minFilter]); 446 } else { 447 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER, 448 transNP[s->mHal.state.minFilter]); 449 } 450 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]); 451 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]); 452 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]); 453 } 454 455 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso); 456 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) { 457 RSD_CALL_GL(glTexParameterf, target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue); 458 } 459 460 rsdGLCheckError(rsc, "Sampler::setup tex env"); 461 } 462 463 void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { 464 if (mRSProgram->mHal.state.texturesCount == 0) { 465 return; 466 } 467 468 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 469 470 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount; 471 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits; 472 if (numTexturesToBind >= numTexturesAvailable) { 473 ALOGE("Attempting to bind %u textures on shader id %p, but only %u are available", 474 mRSProgram->mHal.state.texturesCount, this, numTexturesAvailable); 475 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available"); 476 numTexturesToBind = numTexturesAvailable; 477 } 478 479 for (uint32_t ct=0; ct < numTexturesToBind; ct++) { 480 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct); 481 RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct); 482 483 if (!mRSProgram->mHal.state.textures[ct]) { 484 // if nothing is bound, reset to default GL texture 485 RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], 0); 486 continue; 487 } 488 489 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv; 490 491 if (mCurrentState->mTextureTargets[ct] != GL_TEXTURE_2D && 492 mCurrentState->mTextureTargets[ct] != GL_TEXTURE_CUBE_MAP && 493 mCurrentState->mTextureTargets[ct] != GL_TEXTURE_EXTERNAL_OES) { 494 ALOGE("Attempting to bind unknown texture to shader id %p, texture unit %u", 495 this, ct); 496 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); 497 } 498 RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], drvTex->textureID); 499 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind"); 500 if (mRSProgram->mHal.state.samplers[ct]) { 501 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct], 502 mRSProgram->mHal.state.textures[ct]); 503 } else { 504 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 505 GL_TEXTURE_MIN_FILTER, GL_NEAREST); 506 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 507 GL_TEXTURE_MAG_FILTER, GL_NEAREST); 508 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 509 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 510 RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct], 511 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 512 rsdGLCheckError(rsc, "ProgramFragment::setup basic tex env"); 513 } 514 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms"); 515 } 516 517 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0); 518 mDirty = false; 519 rsdGLCheckError(rsc, "ProgramFragment::setup"); 520 } 521 522 void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) { 523 uint32_t uidx = 0; 524 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 525 Allocation *alloc = mRSProgram->mHal.state.constants[ct]; 526 527 if (!alloc) { 528 ALOGE("Attempting to set constants on shader id %p, but alloc at slot %u is not set", 529 this, ct); 530 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound"); 531 continue; 532 } 533 534 const uint8_t *data = static_cast<const uint8_t *>(alloc->mHal.drvState.lod[0].mallocPtr); 535 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement(); 536 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) { 537 const Element *f = e->mHal.state.fields[field]; 538 const char *fieldName = e->mHal.state.fieldNames[field]; 539 540 uint32_t offset = e->mHal.state.fieldOffsetBytes[field]; 541 const float *fd = reinterpret_cast<const float *>(&data[offset]); 542 543 int32_t slot = -1; 544 uint32_t arraySize = 1; 545 if (!isFragment) { 546 slot = sc->vtxUniformSlot(uidx); 547 arraySize = sc->vtxUniformSize(uidx); 548 } else { 549 slot = sc->fragUniformSlot(uidx); 550 arraySize = sc->fragUniformSize(uidx); 551 } 552 if (rsc->props.mLogShadersUniforms) { 553 ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", 554 slot, offset, ct, field, uidx, fieldName); 555 } 556 uidx ++; 557 if (slot < 0) { 558 continue; 559 } 560 561 if (rsc->props.mLogShadersUniforms) { 562 logUniform(f, fd, arraySize); 563 } 564 setUniform(rsc, f, fd, slot, arraySize); 565 } 566 } 567 } 568 569 void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) { 570 571 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER); 572 setupTextures(rsc, sc); 573 } 574 575 void RsdShader::initAttribAndUniformArray() { 576 mAttribCount = 0; 577 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { 578 const Element *elem = mRSProgram->mHal.state.inputElements[ct]; 579 mAttribCount += elem->mHal.state.fieldsCount; 580 } 581 582 mUniformCount = 0; 583 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { 584 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement(); 585 mUniformCount += elem->mHal.state.fieldsCount; 586 } 587 mUniformCount += mRSProgram->mHal.state.texturesCount; 588 589 if (mAttribCount) { 590 mAttribNames = new std::string[mAttribCount]; 591 } 592 if (mUniformCount) { 593 mUniformNames = new std::string[mUniformCount]; 594 mUniformArraySizes = new uint32_t[mUniformCount]; 595 } 596 597 mTextureCount = mRSProgram->mHal.state.texturesCount; 598 } 599 600 void RsdShader::initAddUserElement(const Element *e, std::string *names, 601 uint32_t *arrayLengths, uint32_t *count, 602 const char *prefix) { 603 rsAssert(e->mHal.state.fieldsCount); 604 for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) { 605 const Element *ce = e->mHal.state.fields[ct]; 606 if (ce->mHal.state.fieldsCount) { 607 initAddUserElement(ce, names, arrayLengths, count, prefix); 608 } else { 609 std::string tmp(prefix); 610 tmp.append(e->mHal.state.fieldNames[ct]); 611 names[*count] = tmp; 612 if (arrayLengths) { 613 arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct]; 614 } 615 (*count)++; 616 } 617 } 618 } 619