1 /* 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 #include "src/pixelflinger2/pixelflinger2.h" 17 18 #include <assert.h> 19 #include <stdio.h> 20 #include <string.h> 21 #include <map> 22 23 #include <llvm/LLVMContext.h> 24 #include <llvm/Module.h> 25 #include <llvm/Support/raw_ostream.h> 26 #include <dlfcn.h> 27 28 #include <bcc/BCCContext.h> 29 #include <bcc/Compiler.h> 30 #include <bcc/ExecutionEngine/ObjectLoader.h> 31 #include <bcc/ExecutionEngine/SymbolResolvers.h> 32 #include <bcc/Script.h> 33 #include <bcc/Source.h> 34 #include <bcc/Support/Initialization.h> 35 #include <bcc/Support/TargetCompilerConfigs.h> 36 37 38 #include "src/talloc/hieralloc.h" 39 #include "src/mesa/main/shaderobj.h" 40 #include "src/mesa/program/prog_parameter.h" 41 #include "src/mesa/program/prog_uniform.h" 42 #include "src/glsl/glsl_types.h" 43 #include "src/glsl/ir_to_llvm.h" 44 #include "src/glsl/ir_print_visitor.h" 45 46 //#undef ALOGD 47 //#define ALOGD(...) 48 49 static void InitializeGLContext(struct gl_context *ctx) 50 { 51 memset(ctx, 0, sizeof(*ctx)); 52 ctx->API = API_OPENGLES2; 53 ctx->Extensions.ARB_draw_buffers = GL_TRUE; 54 ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; 55 ctx->Extensions.EXT_texture_array = GL_TRUE; 56 ctx->Extensions.NV_texture_rectangle = GL_TRUE; 57 58 /* 1.10 minimums. */ 59 ctx->Const.MaxLights = 8; 60 ctx->Const.MaxClipPlanes = 8; 61 ctx->Const.MaxTextureUnits = 2; 62 63 /* More than the 1.10 minimum to appease parser tests taken from 64 * apps that (hopefully) already checked the number of coords. 65 */ 66 ctx->Const.MaxTextureCoordUnits = 4; 67 68 ctx->Const.VertexProgram.MaxAttribs = 16; 69 ctx->Const.VertexProgram.MaxUniformComponents = 512; 70 ctx->Const.MaxVarying = 8; 71 ctx->Const.MaxVertexTextureImageUnits = 0; 72 ctx->Const.MaxCombinedTextureImageUnits = 2; 73 ctx->Const.MaxTextureImageUnits = 2; 74 ctx->Const.FragmentProgram.MaxUniformComponents = 64; 75 76 ctx->Const.MaxDrawBuffers = 2; 77 } 78 79 void * llvmCtx = NULL; 80 static const struct GLContext { 81 const gl_context * ctx; 82 GLContext() { 83 ctx = hieralloc_zero(NULL, gl_context); 84 // ctx = (const gl_context*)calloc(1,sizeof(gl_context)); 85 InitializeGLContext(const_cast<gl_context *>(ctx)); 86 llvmCtx = new llvm::LLVMContext(); 87 } 88 ~GLContext() { 89 _mesa_glsl_release_types(); // TODO: find when to release to minize memory 90 _mesa_glsl_release_functions(); // the IR has pointers to types 91 hieralloc_free(const_cast<gl_context *>(ctx)); 92 // free(const_cast<gl_context *>(ctx)); 93 ctx = NULL; 94 delete (llvm::LLVMContext *)llvmCtx; 95 } 96 } glContext; 97 98 extern "C" void GLContextDctr() 99 { 100 _mesa_glsl_release_types(); // TODO: find when to release to minize memory 101 _mesa_glsl_release_functions(); 102 //glContext.~GLContext(); 103 } 104 105 struct ShaderKey { 106 struct ScanLineKey { 107 GGLStencilState frontStencil, backStencil; 108 GGLBufferState bufferState; 109 GGLBlendState blendState; 110 } scanLineKey; 111 GGLPixelFormat textureFormats[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; 112 unsigned char textureParameters[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // wrap and filter 113 bool operator <(const ShaderKey & rhs) const { 114 return memcmp(this, &rhs, sizeof(*this)) < 0; 115 } 116 }; 117 118 struct Instance { 119 bcc::Script * script; 120 llvm::SmallVector<char, 1024> resultObj; 121 bcc::ObjectLoader * exec; 122 void (* function)(); 123 ~Instance() { 124 delete script; 125 delete exec; 126 } 127 }; 128 129 struct Executable { // codegen info 130 std::map<ShaderKey, Instance *> instances; 131 }; 132 133 bool do_mat_op_to_vec(exec_list *instructions); 134 135 extern void link_shaders(const struct gl_context *ctx, struct gl_shader_program *prog); 136 137 extern "C" void compile_shader(const struct gl_context *ctx, struct gl_shader *shader); 138 139 gl_shader * GGLShaderCreate(GLenum type) 140 { 141 return _mesa_new_shader(NULL, 0, type); 142 } 143 144 static gl_shader * ShaderCreate(const GGLInterface * iface, GLenum type) 145 { 146 GGL_GET_CONST_CONTEXT(ctx, iface); 147 if (GL_VERTEX_SHADER != type && GL_FRAGMENT_SHADER != type) { 148 gglError(GL_INVALID_ENUM); 149 return NULL; 150 } 151 gl_shader * shader = _mesa_new_shader(NULL, 0, type); 152 if (!shader) 153 gglError(GL_OUT_OF_MEMORY); 154 assert(1 == shader->RefCount); 155 return shader; 156 } 157 158 void GGLShaderSource(gl_shader_t * shader, GLsizei count, const char ** string, const int * length) 159 { 160 hieralloc_free(const_cast<GLchar *>(shader->Source)); 161 for (unsigned i = 0; i < count; i++) { 162 int len = strlen(string[i]); 163 if (length && length[i] >= 0) 164 len = length[i]; 165 shader->Source = hieralloc_strndup_append(const_cast<GLchar *>(shader->Source), string[i], len); 166 } 167 // ALOGD("pf2: GGLShaderSource: \n '%s' \n", shader->Source); 168 } 169 170 GLboolean GGLShaderCompile(gl_shader * shader, const char * glsl, const char ** infoLog) 171 { 172 if (glsl) 173 shader->Source = glsl; 174 assert(shader->Source); 175 compile_shader(glContext.ctx, shader); 176 if (glsl) 177 shader->Source = NULL; 178 if (infoLog) 179 *infoLog = shader->InfoLog; 180 return shader->CompileStatus; 181 } 182 183 static GLboolean ShaderCompile(const GGLInterface * iface, gl_shader * shader, 184 const char * glsl, const char ** infoLog) 185 { 186 GGL_GET_CONST_CONTEXT(ctx, iface); 187 if (!glsl && !shader->Source) { 188 gglError(GL_INVALID_VALUE); 189 assert(0); 190 return GL_FALSE; 191 } 192 return GGLShaderCompile(shader, glsl, infoLog); 193 } 194 195 void GGLShaderDelete(gl_shader * shader) 196 { 197 if (shader && shader->executable) { 198 for (std::map<ShaderKey, Instance *>::iterator it=shader->executable->instances.begin(); 199 it != shader->executable->instances.end(); it++) 200 (*it).second->~Instance(); 201 shader->executable->instances.~map(); 202 } 203 _mesa_delete_shader(NULL, shader); 204 } 205 206 static void ShaderDelete(const GGLInterface * iface, gl_shader * shader) 207 { 208 GGLShaderDelete(shader); 209 } 210 211 gl_shader_program * GGLShaderProgramCreate() 212 { 213 gl_shader_program * program = hieralloc_zero(NULL, struct gl_shader_program); 214 if (!program) 215 return NULL; 216 program->Attributes = hieralloc_zero(program, gl_program_parameter_list); 217 if (!program->Attributes) { 218 hieralloc_free(program); 219 return NULL; 220 } 221 program->Varying = hieralloc_zero(program, gl_program_parameter_list); 222 if (!program->Varying) { 223 hieralloc_free(program); 224 return NULL; 225 } 226 return program; 227 } 228 229 static gl_shader_program * ShaderProgramCreate(const GGLInterface * iface) 230 { 231 GGL_GET_CONST_CONTEXT(ctx, iface); 232 gl_shader_program * program = GGLShaderProgramCreate(); 233 if (!program) 234 gglError(GL_OUT_OF_MEMORY); 235 return program; 236 } 237 238 unsigned GGLShaderAttach(gl_shader_program * program, gl_shader * shader) 239 { 240 for (unsigned i = 0; i < program->NumShaders; i++) 241 if (program->Shaders[i]->Type == shader->Type || program->Shaders[i] == shader) 242 return GL_INVALID_OPERATION; 243 244 program->Shaders = (gl_shader **)hieralloc_realloc 245 (program, program->Shaders, gl_shader *, program->NumShaders + 1); 246 if (!program->Shaders) { 247 assert(0); 248 return GL_OUT_OF_MEMORY; 249 } 250 program->Shaders[program->NumShaders] = shader; 251 program->NumShaders++; 252 shader->RefCount++; 253 return GL_NO_ERROR; 254 } 255 256 static void ShaderAttach(const GGLInterface * iface, gl_shader_program * program, 257 gl_shader * shader) 258 { 259 unsigned error = GGLShaderAttach(program, shader); 260 if (GL_NO_ERROR != error) 261 gglError(error); 262 } 263 264 GLboolean GGLShaderProgramLink(gl_shader_program * program, const char ** infoLog) 265 { 266 link_shaders(glContext.ctx, program); 267 if (infoLog) 268 *infoLog = program->InfoLog; 269 if (!program->LinkStatus) 270 return program->LinkStatus; 271 ALOGD("slots: attribute=%d varying=%d uniforms=%d \n", program->AttributeSlots, program->VaryingSlots, program->Uniforms->Slots); 272 // for (unsigned i = 0; i < program->Attributes->NumParameters; i++) { 273 // const gl_program_parameter & attribute = program->Attributes->Parameters[i]; 274 // ALOGD("attribute '%s': location=%d slots=%d \n", attribute.Name, attribute.Location, attribute.Slots); 275 // } 276 // for (unsigned i = 0; i < program->Varying->NumParameters; i++) { 277 // const gl_program_parameter & varying = program->Varying->Parameters[i]; 278 // ALOGD("varying '%s': vs_location=%d fs_location=%d \n", varying.Name, varying.BindLocation, varying.Location); 279 // } 280 for (unsigned i = 0; i < program->Uniforms->NumUniforms; i++) { 281 const gl_uniform & uniform = program->Uniforms->Uniforms[i]; 282 ALOGD("uniform '%s': location=%d type=%s \n", uniform.Name, uniform.Pos, uniform.Type->name); 283 } 284 return program->LinkStatus; 285 } 286 287 static GLboolean ShaderProgramLink(gl_shader_program * program, const char ** infoLog) 288 { 289 return GGLShaderProgramLink(program, infoLog); 290 } 291 292 static void GetShaderKey(const GGLState * ctx, const gl_shader * shader, ShaderKey * key) 293 { 294 memset(key, 0, sizeof(*key)); 295 if (GL_FRAGMENT_SHADER == shader->Type) { 296 key->scanLineKey.frontStencil = ctx->frontStencil; 297 key->scanLineKey.backStencil = ctx->backStencil; 298 key->scanLineKey.bufferState = ctx->bufferState; 299 key->scanLineKey.blendState = ctx->blendState; 300 } 301 302 for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) 303 if (shader->SamplersUsed & (1 << i)) { 304 const GGLTexture & texture = ctx->textureState.textures[i]; 305 key->textureFormats[i] = texture.format; 306 assert((1 << 2) > texture.wrapS); 307 key->textureParameters[i] |= texture.wrapS; 308 assert((1 << 2) > texture.wrapT); 309 key->textureParameters[i] |= texture.wrapT << 2; 310 assert((1 << 3) > texture.minFilter); 311 key->textureParameters[i] |= texture.minFilter << (2 + 2); 312 assert((1 << 1) > texture.magFilter); 313 key->textureParameters[i] |= texture.magFilter << (2 + 2 + 3); 314 } 315 } 316 317 static inline char HexDigit(unsigned char d) 318 { 319 return (d > 9 ? d + 'A' - 10 : d + '0'); 320 } 321 322 static const unsigned SHADER_KEY_STRING_LEN = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS * 4 + 2; 323 324 static void GetShaderKeyString(const GLenum type, const ShaderKey * key, 325 char * buffer, const unsigned bufferSize) 326 { 327 assert(1 == sizeof(char)); 328 assert(0xff >= GGL_PIXEL_FORMAT_COUNT); 329 assert(SHADER_KEY_STRING_LEN <= bufferSize); 330 char * str = buffer; 331 if (GL_VERTEX_SHADER == type) 332 *str++ = 'v'; 333 else if (GL_FRAGMENT_SHADER == type) 334 *str++ = 'f'; 335 else 336 assert(0); 337 for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) { 338 *str++ = HexDigit(key->textureFormats[i] / 16); 339 *str++ = HexDigit(key->textureFormats[i] % 16); 340 *str++ = HexDigit(key->textureParameters[i] / 16); 341 *str++ = HexDigit(key->textureParameters[i] % 16); 342 } 343 *str++ = '\0'; 344 } 345 346 static const unsigned SCANLINE_KEY_STRING_LEN = 2 * sizeof(ShaderKey::ScanLineKey) + 3 + SHADER_KEY_STRING_LEN; 347 348 static char * GetScanlineKeyString(const ShaderKey * key, char * buffer, 349 const unsigned bufferSize) 350 { 351 assert(1 == sizeof(char)); 352 assert(0xff >= GGL_PIXEL_FORMAT_COUNT); 353 assert(SCANLINE_KEY_STRING_LEN <= bufferSize); 354 char * str = buffer; 355 *str++ = 's'; 356 const unsigned char * start = (const unsigned char *)&key->scanLineKey; 357 const unsigned char * const end = start + sizeof(key->scanLineKey); 358 for (; start < end; start++) { 359 *str++ = HexDigit(*start / 16); 360 *str++ = HexDigit(*start % 16); 361 } 362 GetShaderKeyString(GL_FRAGMENT_SHADER, key, str, bufferSize - (str - buffer)); 363 return buffer; 364 } 365 366 struct SymbolLookupContext { 367 const GGLState * gglCtx; 368 const gl_shader_program * program; 369 const gl_shader * shader; 370 }; 371 372 static void* SymbolLookup(void* pContext, const char* name) 373 { 374 SymbolLookupContext * ctx = (SymbolLookupContext *)pContext; 375 const GGLState * gglCtx = ctx->gglCtx; 376 const void * symbol = (void*)dlsym(RTLD_DEFAULT, name); 377 if (NULL == symbol) { 378 if (!strcmp(_PF2_TEXTURE_DATA_NAME_, name)) 379 symbol = (void *)gglCtx->textureState.textureData; 380 else if (!strcmp(_PF2_TEXTURE_DIMENSIONS_NAME_, name)) 381 symbol = (void *)gglCtx->textureState.textureDimensions; 382 else // attributes, varyings and uniforms are mapped to locations in pointers 383 { 384 ALOGD("pf2: SymbolLookup unknown symbol: '%s'", name); 385 assert(0); 386 } 387 } 388 // printf("symbolLookup '%s'=%p \n", name, symbol); 389 assert(symbol); 390 return (void *)symbol; 391 } 392 393 static void CodeGen(Instance * instance, const char * mainName, gl_shader * shader, 394 gl_shader_program * program, const GGLState * gglCtx) 395 { 396 bcc::Compiler compiler; 397 bcc::Compiler::ErrorCode compile_result; 398 llvm::raw_svector_ostream out(instance->resultObj); 399 400 // instance->module->dump(); 401 402 compile_result = compiler.config(bcc::DefaultCompilerConfig()); 403 if (compile_result != bcc::Compiler::kSuccess) { 404 ALOGD("failed config compiler (%s)", bcc::Compiler::GetErrorString(compile_result)); 405 assert(0); 406 return; 407 } 408 409 compiler.enableLTO(/* pEnable */false); // Disable LTO passes execution. 410 411 compile_result = compiler.compile(*instance->script, out); 412 if (compile_result != bcc::Compiler::kSuccess) { 413 ALOGD("failed to compile (%s)", bcc::Compiler::GetErrorString(compile_result)); 414 assert(0); 415 return; 416 } 417 418 SymbolLookupContext ctx = {gglCtx, program, shader}; 419 bcc::LookupFunctionSymbolResolver<void*> resolver(SymbolLookup, &ctx); 420 421 instance->exec = bcc::ObjectLoader::Load(instance->resultObj.begin(), instance->resultObj.size(), 422 /* pName */"glsl", resolver, /* pEnableGDBDebug */false); 423 424 if (!instance->exec) { 425 ALOGD("failed to load the result object"); 426 assert(0); 427 return; 428 } 429 430 instance->function = reinterpret_cast<void (*)()>(instance->exec->getSymbolAddress(mainName)); 431 assert(instance->function); 432 if (!instance->function) { 433 ALOGD("Could not find '%s'\n", mainName); 434 } 435 // else 436 // printf("bcc_compile %s=%p \n", mainName, instance->function); 437 438 // assert(0); 439 } 440 441 void GenerateScanLine(const GGLState * gglCtx, const gl_shader_program * program, llvm::Module * mod, 442 const char * shaderName, const char * scanlineName); 443 444 void GGLShaderUse(void * bccCtx, const GGLState * gglState, gl_shader_program * program) 445 { 446 // ALOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source); 447 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 448 if (!program->_LinkedShaders[i]) 449 continue; 450 gl_shader * shader = program->_LinkedShaders[i]; 451 shader->function = NULL; 452 if (!shader->executable) { 453 shader->executable = hieralloc_zero(shader, Executable); 454 shader->executable->instances = std::map<ShaderKey, Instance *>(); 455 } 456 457 ShaderKey shaderKey; 458 GetShaderKey(gglState, shader, &shaderKey); 459 Instance * instance = shader->executable->instances[shaderKey]; 460 bcc::BCCContext * compilerCtx = reinterpret_cast<bcc::BCCContext *>(bccCtx); 461 if (!instance) { 462 // puts("begin jit new shader"); 463 instance = hieralloc_zero(shader->executable, Instance); 464 465 llvm::Module * module = new llvm::Module("glsl", compilerCtx->getLLVMContext()); 466 467 char shaderName [SHADER_KEY_STRING_LEN] = {0}; 468 GetShaderKeyString(shader->Type, &shaderKey, shaderName, sizeof shaderName / sizeof *shaderName); 469 470 char mainName [SHADER_KEY_STRING_LEN + 6] = {"main"}; 471 strcat(mainName, shaderName); 472 473 do_mat_op_to_vec(shader->ir); // TODO: move these passes to link? 474 //#ifdef __arm__ 475 // static const char fileName[] = "/data/pf2.txt"; 476 // FILE * file = freopen(fileName, "w", stdout); 477 // assert(file); 478 // *stdout = *file; 479 // std::ios_base::sync_with_stdio(true); 480 //#endif 481 // _mesa_print_ir(shader->ir, NULL); 482 //#ifdef __arm__ 483 // fclose(file); 484 // file = fopen(fileName, "r"); 485 // assert(file); 486 // static char str[256]; 487 // while (!feof(file)) { 488 // fgets(str, sizeof(str) - 1, file); 489 // str[sizeof(str) - 1] = 0; 490 // ALOGD("%s", str); 491 // } 492 // fclose(file); 493 //#endif 494 if (!glsl_ir_to_llvm_module(shader->ir, module, gglState, shaderName)) { 495 assert(0); 496 delete module; 497 } 498 bcc::Source * source = bcc::Source::CreateFromModule(*compilerCtx, *module); 499 if (!source) { 500 delete module; 501 assert(0); 502 } 503 instance->script = new bcc::Script(*source); 504 if (!instance->script) { 505 delete source; 506 assert(0); 507 } 508 //#ifdef __arm__ 509 // static const char fileName[] = "/data/pf2.txt"; 510 // FILE * file = freopen(fileName, "w", stderr); 511 // assert(file); 512 // *stderr = *file; 513 // std::ios_base::sync_with_stdio(true); 514 //#endif 515 516 // if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, 517 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;")) { 518 // if (i == MESA_SHADER_VERTEX) { 519 // for (unsigned i = 0; i < program->Attributes->NumParameters; i++) { 520 // const gl_program_parameter & attribute = program->Attributes->Parameters[i]; 521 // ALOGD("attribute '%s': location=%d slots=%d \n", attribute.Name, attribute.Location, attribute.Slots); 522 // } 523 // for (unsigned i = 0; i < program->Varying->NumParameters; i++) { 524 // const gl_program_parameter & varying = program->Varying->Parameters[i]; 525 // ALOGD("varying '%s': vs_location=%d fs_location=%d \n", varying.Name, varying.BindLocation, varying.Location); 526 // } 527 // ALOGD("%s", program->Shaders[MESA_SHADER_VERTEX]->Source); 528 // module->dump(); 529 // } 530 // } 531 532 //#ifdef __arm__ 533 // fputs("end of bcc disassembly", stderr); 534 // fclose(stderr); 535 // 536 // file = fopen(fileName, "r"); 537 // assert(file); 538 // fseek(file , 0 , SEEK_END); 539 // long lSize = ftell(file); 540 // rewind(file); 541 // assert(0 <= lSize); 542 // static char str[256]; 543 // while (!feof(file)) { 544 // fgets(str, sizeof(str) - 1, file); 545 // str[sizeof(str) - 1] = 0; 546 // ALOGD("%s", str); 547 // } 548 // fclose(file); 549 //#endif 550 551 #if USE_LLVM_SCANLINE 552 if (GL_FRAGMENT_SHADER == shader->Type) { 553 char scanlineName [SCANLINE_KEY_STRING_LEN] = {0}; 554 GetScanlineKeyString(&shaderKey, scanlineName, sizeof scanlineName / sizeof *scanlineName); 555 GenerateScanLine(gglState, program, module, mainName, scanlineName); 556 CodeGen(instance, scanlineName, shader, program, gglState); 557 } else 558 #endif 559 CodeGen(instance, mainName, shader, program, gglState); 560 561 shader->executable->instances[shaderKey] = instance; 562 // debug_printf("jit new shader '%s'(%p) \n", mainName, instance->function); 563 } else 564 // debug_printf("use cached shader %p \n", instance->function); 565 ; 566 567 shader->function = instance->function; 568 } 569 // puts("pf2: GGLShaderUse end"); 570 571 // assert(0); 572 } 573 574 static void ShaderUse(GGLInterface * iface, gl_shader_program * program) 575 { 576 GGL_GET_CONTEXT(ctx, iface); 577 // so drawing calls will do nothing until ShaderUse with a program 578 SetShaderVerifyFunctions(iface); 579 if (!program) { 580 ctx->CurrentProgram = NULL; 581 return; 582 } 583 584 GGLShaderUse(ctx->bccCtx, &ctx->state, program); 585 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 586 if (!program->_LinkedShaders[i]) 587 continue; 588 if (!program->_LinkedShaders[i]->function) 589 continue; 590 if (GL_VERTEX_SHADER == program->_LinkedShaders[i]->Type) 591 ctx->PickRaster(iface); 592 else if (GL_FRAGMENT_SHADER == program->_LinkedShaders[i]->Type) 593 ctx->PickScanLine(iface); 594 else 595 assert(0); 596 } 597 ctx->CurrentProgram = program; 598 } 599 600 unsigned GGLShaderDetach(gl_shader_program * program, gl_shader * shader) 601 { 602 for (unsigned i = 0; i < program->NumShaders; i++) 603 if (program->Shaders[i] == shader) { 604 program->NumShaders--; 605 // just swap end to deleted shader 606 program->Shaders[i] = program->Shaders[program->NumShaders]; 607 shader->RefCount--; 608 if (1 == shader->RefCount && shader->DeletePending) 609 GGLShaderDelete(shader); 610 return GL_NO_ERROR; 611 } 612 return (GL_INVALID_OPERATION); 613 } 614 615 static void ShaderDetach(const GGLInterface * iface, gl_shader_program * program, 616 gl_shader * shader) 617 { 618 unsigned error = GGLShaderDetach(program, shader); 619 if (GL_NO_ERROR != error) 620 gglError(error); 621 } 622 623 void GGLShaderProgramDelete(gl_shader_program * program) 624 { 625 for (unsigned i = 0; i < program->NumShaders; i++) { 626 GGLShaderDelete(program->Shaders[i]); // actually just mark for delete 627 GGLShaderDetach(program, program->Shaders[i]); // detach will delete if ref == 1 628 i--; // GGLShaderDetach just swaps end to detached shader 629 } 630 631 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) 632 GGLShaderDelete(program->_LinkedShaders[i]); 633 634 hieralloc_free(program); 635 } 636 637 static void ShaderProgramDelete(GGLInterface * iface, gl_shader_program * program) 638 { 639 GGL_GET_CONTEXT(ctx, iface); 640 if (ctx->CurrentProgram == program) { 641 ctx->CurrentProgram = NULL; 642 SetShaderVerifyFunctions(iface); 643 } 644 GGLShaderProgramDelete(program); 645 } 646 647 void GGLShaderGetiv(const gl_shader_t * shader, const GLenum pname, GLint * params) 648 { 649 switch (pname) { 650 case GL_SHADER_TYPE: 651 *params = shader->Type; 652 break; 653 case GL_DELETE_STATUS: 654 *params = shader->DeletePending; 655 break; 656 case GL_COMPILE_STATUS: 657 *params = shader->CompileStatus; 658 break; 659 case GL_INFO_LOG_LENGTH: 660 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0; 661 break; 662 case GL_SHADER_SOURCE_LENGTH: 663 *params = shader->Source ? strlen(shader->Source) + 1 : 0; 664 break; 665 default: 666 assert(0); 667 break; 668 } 669 } 670 671 void GGLShaderGetInfoLog(const gl_shader_t * shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) 672 { 673 unsigned len = 0; 674 infolog[0] = 0; 675 if (shader->InfoLog) 676 { 677 len = strlen(shader->InfoLog); 678 strncpy(infolog, shader->InfoLog, bufsize); 679 infolog[bufsize] = 0; 680 } 681 if (length) 682 *length = strlen(infolog); 683 } 684 685 void GGLShaderProgramGetiv(const gl_shader_program_t * program, const GLenum pname, GLint * params) 686 { 687 switch (pname) { 688 case GL_DELETE_STATUS: 689 *params = program->DeletePending; 690 break; 691 case GL_LINK_STATUS: 692 *params = program->LinkStatus; 693 break; 694 case GL_VALIDATE_STATUS: 695 *params = program->LinkStatus; 696 break; 697 case GL_INFO_LOG_LENGTH: 698 *params = program->InfoLog ? strlen(program->InfoLog) + 1 : 0; 699 break; 700 case GL_ATTACHED_SHADERS: 701 *params = program->NumShaders; 702 break; 703 case GL_ACTIVE_ATTRIBUTES: 704 *params = program->AttributeSlots; 705 break; 706 case GL_ACTIVE_UNIFORMS: 707 *params = program->Uniforms->Slots; 708 break; 709 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 710 case GL_ACTIVE_UNIFORM_MAX_LENGTH: 711 printf("pf2:GGLShaderProgramGetiv not implemented: %d \n", pname); 712 default: 713 assert(0); 714 break; 715 } 716 } 717 718 void GGLShaderProgramGetInfoLog(const gl_shader_program_t * program, GLsizei bufsize, GLsizei* length, GLchar* infolog) 719 { 720 unsigned len = 0; 721 infolog[0] = 0; 722 if (program->InfoLog) 723 { 724 len = strlen(program->InfoLog); 725 strncpy(infolog, program->InfoLog, bufsize); 726 infolog[bufsize] = 0; 727 } 728 if (length) 729 *length = strlen(infolog); 730 } 731 732 void GGLShaderAttributeBind(const gl_shader_program * program, GLuint index, const GLchar * name) 733 { 734 int i = _mesa_add_parameter(program->Attributes, name); 735 program->Attributes->Parameters[i].BindLocation = index; 736 } 737 738 GLint GGLShaderAttributeLocation(const gl_shader_program * program, const char * name) 739 { 740 int i = _mesa_get_parameter(program->Attributes, name); 741 if (i >= 0) 742 return program->Attributes->Parameters[i].Location; 743 return -1; 744 } 745 746 GLint GGLShaderVaryingLocation(const gl_shader_program_t * program, 747 const char * name, GLint * vertexOutputLocation) 748 { 749 for (unsigned int i = 0; i < program->Varying->NumParameters; i++) 750 if (!strcmp(program->Varying->Parameters[i].Name, name)) { 751 if (vertexOutputLocation) 752 *vertexOutputLocation = program->Varying->Parameters[i].BindLocation; 753 return program->Varying->Parameters[i].Location; 754 } 755 return -1; 756 } 757 758 GLint GGLShaderUniformLocation(const gl_shader_program * program, 759 const char * name) 760 { 761 for (unsigned i = 0; i < program->Uniforms->NumUniforms; i++) 762 if (!strcmp(program->Uniforms->Uniforms[i].Name, name)) 763 return i; 764 return -1; 765 } 766 767 void GGLShaderUniformGetfv(gl_shader_program * program, GLint location, GLfloat * params) 768 { 769 assert(0 <= location && program->Uniforms->NumUniforms > location); 770 int index = program->Uniforms->Uniforms[location].Pos; 771 assert(0 <= index && program->Uniforms->Slots > index); 772 memcpy(params, program->ValuesUniform + index, sizeof(*program->ValuesUniform)); 773 } 774 775 void GGLShaderUniformGetiv(gl_shader_program * program, GLint location, GLint * params) 776 { 777 assert(0 <= location && program->Uniforms->NumUniforms > location); 778 int index = program->Uniforms->Uniforms[location].Pos; 779 assert(0 <= index && program->Uniforms->Slots > index); 780 const float * uniform = program->ValuesUniform[index]; 781 params[0] = uniform[0]; 782 params[1] = uniform[1]; 783 params[2] = uniform[2]; 784 params[3] = uniform[3]; 785 } 786 787 void GGLShaderUniformGetSamplers(const gl_shader_program_t * program, 788 int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]) 789 { 790 // ALOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source); 791 // for (unsigned i = 0; i < program->Uniforms->Slots + program->Uniforms->SamplerSlots; i++) 792 // ALOGD("%d: %.2f \t %.2f \t %.2f \t %.2f", i, program->ValuesUniform[i][0], program->ValuesUniform[i][1], 793 // program->ValuesUniform[i][2], program->ValuesUniform[i][3]); 794 for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) 795 sampler2tmu[i] = -1; 796 for (unsigned i = 0; i < program->Uniforms->NumUniforms; i++) { 797 const gl_uniform & uniform = program->Uniforms->Uniforms[i]; 798 if (uniform.Type->is_sampler()) { 799 // ALOGD("%d uniform.Pos=%d tmu=%d", program->Uniforms->Slots, uniform.Pos, (int)program->ValuesUniform[program->Uniforms->Slots + uniform.Pos][0]); 800 sampler2tmu[uniform.Pos] = program->ValuesUniform[program->Uniforms->Slots + uniform.Pos][0]; 801 } else if (uniform.Type->is_array() && uniform.Type->fields.array->is_sampler()) 802 assert(0); 803 } 804 } 805 806 GLint GGLShaderUniform(gl_shader_program * program, GLint location, GLsizei count, 807 const GLvoid *values, GLenum type) 808 { 809 // ALOGD("pf2: GGLShaderUniform location=%d count=%d type=0x%.4X", location, count, type); 810 // TODO: sampler uniform and type checking 811 if (!program) { 812 //gglError(GL_INVALID_OPERATION); 813 return -2; 814 } 815 if (-1 == location) 816 return -1; 817 assert(0 <= location && program->Uniforms->NumUniforms > location); 818 const gl_uniform & uniform = program->Uniforms->Uniforms[location]; 819 int start = -1; 820 if (uniform.Type->is_sampler()) 821 { 822 start = uniform.Pos + program->Uniforms->Slots; 823 assert(GL_INT == type && 1 == count); 824 program->ValuesUniform[start][0] = *(float *)values; 825 return uniform.Pos; 826 } 827 else if (uniform.Type->is_array() && uniform.Type->fields.array->is_sampler()) { 828 assert(0); // not implemented 829 } else 830 start = uniform.Pos; 831 int slots = 0, elems = 0; 832 switch (type) { 833 case GL_INT: 834 case GL_FLOAT: 835 case GL_BOOL: 836 slots = count; 837 elems = 1; 838 break; 839 case GL_FLOAT_VEC2: // fall through 840 case GL_INT_VEC2: // fall through 841 case GL_BOOL_VEC2: 842 slots = count; 843 elems = 2; 844 break; 845 case GL_INT_VEC3: // fall through 846 case GL_BOOL_VEC3: // fall through 847 case GL_FLOAT_VEC3: // fall through 848 slots = count; 849 elems = 3; 850 break; 851 case GL_INT_VEC4: // fall through 852 case GL_FLOAT_VEC4: // fall through 853 case GL_BOOL_VEC4: // fall through 854 slots = count; 855 elems = 4; 856 break; 857 default: 858 assert(0); 859 } 860 // ALOGD("pf2: GGLShaderUniform start=%d slots=%d elems=%d", start, slots, elems); 861 if (0 > start) 862 assert(0); 863 if (start + slots > program->Uniforms->Slots) 864 assert(0); 865 for (int i = 0; i < slots; i++) 866 memcpy(program->ValuesUniform + start + i, values, elems * sizeof(float)); 867 // ALOGD("pf2: GGLShaderUniform copied"); 868 return -2; 869 } 870 871 void GGLShaderUniformMatrix(gl_shader_program * program, GLint cols, GLint rows, 872 GLint location, GLsizei count, GLboolean transpose, const GLfloat *values) 873 { 874 if (location == -1) 875 return; 876 assert(!transpose); 877 assert(cols == rows); 878 assert(0 <= location && program->Uniforms->NumUniforms > location); 879 int start = program->Uniforms->Uniforms[location].Pos; 880 unsigned slots = cols * count; 881 if (start < 0 || start + slots > program->Uniforms->Slots) 882 return gglError(GL_INVALID_OPERATION); 883 for (unsigned i = 0; i < slots; i++) { 884 float * column = program->ValuesUniform[start + i]; 885 for (unsigned j = 0; j < rows; j++) 886 column[j] = values[i * 4 + j]; 887 } 888 889 // if (!strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, 890 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;")) 891 // return; 892 // 893 // ALOGD("pf2: GGLShaderUniformMatrix location=%d cols=%d count=%d", location, cols, count); 894 // 895 // for (unsigned i = 0; i < 4; i++) 896 // ALOGD("pf2: GGLShaderUniformMatrix %.2f \t %.2f \t %.2f \t %.2f \n", values[i * 4 + 0], 897 // values[i * 4 + 1], values[i * 4 + 2], values[i * 4 + 3]); 898 899 } 900 901 static void ShaderVerifyProcessVertex(const GGLInterface * iface, const VertexInput * input, 902 VertexOutput * output) 903 { 904 GGL_GET_CONST_CONTEXT(ctx, iface); 905 if (ctx->CurrentProgram) { 906 ShaderUse(const_cast<GGLInterface *>(iface), ctx->CurrentProgram); 907 if (ShaderVerifyProcessVertex != iface->ProcessVertex) 908 iface->ProcessVertex(iface, input, output); 909 } 910 } 911 912 static void ShaderVerifyDrawTriangle(const GGLInterface * iface, const VertexInput * v0, 913 const VertexInput * v1, const VertexInput * v2) 914 { 915 GGL_GET_CONST_CONTEXT(ctx, iface); 916 if (ctx->CurrentProgram) { 917 ShaderUse(const_cast<GGLInterface *>(iface), ctx->CurrentProgram); 918 if (ShaderVerifyDrawTriangle != iface->DrawTriangle) 919 iface->DrawTriangle(iface, v0, v1, v2); 920 } 921 } 922 923 static void ShaderVerifyRasterTriangle(const GGLInterface * iface, const VertexOutput * v1, 924 const VertexOutput * v2, const VertexOutput * v3) 925 { 926 GGL_GET_CONST_CONTEXT(ctx, iface); 927 if (ctx->CurrentProgram) { 928 ShaderUse(const_cast<GGLInterface *>(iface), ctx->CurrentProgram); 929 if (ShaderVerifyRasterTriangle != iface->RasterTriangle) 930 iface->RasterTriangle(iface, v1, v2, v3); 931 } 932 } 933 934 static void ShaderVerifyRasterTrapezoid(const GGLInterface * iface, const VertexOutput * tl, 935 const VertexOutput * tr, const VertexOutput * bl, 936 const VertexOutput * br) 937 { 938 GGL_GET_CONST_CONTEXT(ctx, iface); 939 if (ctx->CurrentProgram) { 940 ShaderUse(const_cast<GGLInterface *>(iface), ctx->CurrentProgram); 941 if (ShaderVerifyRasterTrapezoid != iface->RasterTrapezoid) 942 iface->RasterTrapezoid(iface, tl, tr, bl, br); 943 } 944 } 945 946 static void ShaderVerifyScanLine(const GGLInterface * iface, const VertexOutput * v1, 947 const VertexOutput * v2) 948 { 949 GGL_GET_CONST_CONTEXT(ctx, iface); 950 if (ctx->CurrentProgram) { 951 ShaderUse(const_cast<GGLInterface *>(iface), ctx->CurrentProgram); 952 if (ShaderVerifyScanLine != iface->ScanLine) 953 iface->ScanLine(iface, v1, v2); 954 } 955 } 956 957 // called after state changes so that drawing calls will trigger JIT 958 void SetShaderVerifyFunctions(struct GGLInterface * iface) 959 { 960 iface->ProcessVertex = ShaderVerifyProcessVertex; 961 iface->DrawTriangle = ShaderVerifyDrawTriangle; 962 iface->RasterTriangle = ShaderVerifyRasterTriangle; 963 iface->RasterTrapezoid = ShaderVerifyRasterTrapezoid; 964 iface->ScanLine = ShaderVerifyScanLine; 965 } 966 967 void InitializeShaderFunctions(struct GGLInterface * iface) 968 { 969 GGL_GET_CONTEXT(ctx, iface); 970 bcc::init::Initialize(); 971 972 ctx->bccCtx = new bcc::BCCContext(); 973 974 iface->ShaderCreate = ShaderCreate; 975 iface->ShaderSource = GGLShaderSource; 976 iface->ShaderCompile = ShaderCompile; 977 iface->ShaderDelete = ShaderDelete; 978 iface->ShaderProgramCreate = ShaderProgramCreate; 979 iface->ShaderAttach = ShaderAttach; 980 iface->ShaderDetach = ShaderDetach; 981 iface->ShaderProgramLink = ShaderProgramLink; 982 iface->ShaderUse = ShaderUse; 983 iface->ShaderProgramDelete = ShaderProgramDelete; 984 iface->ShaderGetiv = GGLShaderGetiv; 985 iface->ShaderGetInfoLog = GGLShaderGetInfoLog; 986 iface->ShaderProgramGetiv = GGLShaderProgramGetiv; 987 iface->ShaderProgramGetInfoLog = GGLShaderProgramGetInfoLog; 988 iface->ShaderAttributeBind = GGLShaderAttributeBind; 989 iface->ShaderAttributeLocation = GGLShaderAttributeLocation; 990 iface->ShaderVaryingLocation = GGLShaderVaryingLocation; 991 iface->ShaderUniformLocation = GGLShaderUniformLocation; 992 iface->ShaderUniformGetfv = GGLShaderUniformGetfv; 993 iface->ShaderUniformGetiv = GGLShaderUniformGetiv; 994 iface->ShaderUniformGetSamplers = GGLShaderUniformGetSamplers; 995 iface->ShaderUniform = GGLShaderUniform; 996 iface->ShaderUniformMatrix = GGLShaderUniformMatrix; 997 } 998 999 void DestroyShaderFunctions(GGLInterface * iface) 1000 { 1001 GGL_GET_CONTEXT(ctx, iface); 1002 _mesa_glsl_release_types(); 1003 _mesa_glsl_release_functions(); 1004 delete ctx->bccCtx; 1005 ctx->bccCtx = NULL; 1006 } 1007