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