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