shader.cpp revision 36ffccf19c02a54a6dc9952dc9c181d4fda2a020
1/* 2 * Copyright (C) 2010 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 21#include <llvm/LLVMContext.h> 22 23static gl_shader * ShaderCreate(const GGLInterface * iface, GLenum type) 24{ 25 if (GL_VERTEX_SHADER != type && GL_FRAGMENT_SHADER != type) 26 { 27 gglError(GL_INVALID_ENUM); 28 return NULL; 29 } 30// gl_shader * shader = _mesa_new_shader(0, type); 31// if(!shader) 32// gglError(GL_OUT_OF_MEMORY); 33// return shader; 34 return NULL; 35} 36 37static GLboolean ShaderCompile(const GGLInterface * iface, gl_shader * shader, 38 const char * glsl, char ** infoLog) 39{ 40 GGL_GET_CONST_CONTEXT(ctx, iface); 41 if (!glsl) 42 { 43 gglError(GL_INVALID_VALUE); 44 return GL_FALSE; 45 } 46// shader->Source = glsl; 47// _slang_compile(ctx->glCtx, shader); 48// shader->Source = NULL; 49// if (infoLog) 50// *infoLog = shader->InfoLog; 51// return shader->CompileStatus; 52 return GL_FALSE; 53} 54 55static void ShaderFree(const GGLInterface * iface, gl_shader * shader) 56{ 57 GGL_GET_CONST_CONTEXT(ctx, iface); 58// _mesa_free_shader(ctx->glCtx, shader); 59} 60 61static gl_shader_program * ShaderProgramCreate(const GGLInterface * iface) 62{ 63// gl_shader_program * program = _mesa_new_shader_program(0); 64// if (!program) 65// gglError(GL_OUT_OF_MEMORY); 66// return program; 67 return NULL; 68} 69 70static GLboolean ShaderProgramLink(const GGLInterface * iface, gl_shader_program * program, 71 const unsigned count, gl_shader ** shaders, char ** infoLog) 72{ 73 GGL_GET_CONST_CONTEXT(ctx, iface); 74 75// program->NumShaders = count; 76// program->Shaders = shaders; 77// 78// _slang_link(ctx->glCtx, program); 79// 80// program->NumShaders = 0; 81// program->Shaders = NULL; 82// 83// if (infoLog) 84// *infoLog = program->InfoLog; 85// 86// return program->LinkStatus; 87 return GL_FALSE; 88} 89 90struct gl_program; 91struct ShaderKey; 92 93static void GetShaderKey(const GGLContext * ctx, const gl_program * shader, ShaderKey * key) 94{ 95// memset(key, 0, sizeof(*key)); 96// if (GL_FRAGMENT_SHADER == shader->Target) 97// { 98// key->scanLineKey.frontStencil = ctx->frontStencil; 99// key->scanLineKey.backStencil = ctx->backStencil; 100// key->scanLineKey.bufferState = ctx->bufferState; 101// key->scanLineKey.blendState = ctx->blendState; 102// } 103// 104// for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) 105// if (shader->SamplersUsed & (1 << i)) 106// { 107// const GGLTexture & texture = ctx->textureState.textures[i]; 108// key->textureFormats[i] = texture.format; 109// assert((1 << 2) > texture.wrapS); 110// key->textureParameters[i] |= texture.wrapS; 111// assert((1 << 2) > texture.wrapT); 112// key->textureParameters[i] |= texture.wrapT << 2; 113// assert((1 << 3) > texture.minFilter); 114// key->textureParameters[i] |= texture.minFilter << (2 + 2); 115// assert((1 << 1) > texture.magFilter); 116// key->textureParameters[i] |= texture.magFilter << (2 + 2 + 3); 117// } 118} 119 120static inline char HexDigit(unsigned char d) 121{ 122 return (d > 9 ? d + 'A' - 10 : d + '0'); 123} 124 125static const unsigned SHADER_KEY_STRING_LEN = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS * 4 + 2; 126 127static void GetShaderKeyString(const GLenum type, const ShaderKey * key, 128 char * buffer, const unsigned bufferSize) 129{ 130// assert(1 == sizeof(char)); 131// assert(0xff >= GGL_PIXEL_FORMAT_COUNT); 132// assert(SHADER_KEY_STRING_LEN <= bufferSize); 133// char * str = buffer; 134// if (GL_VERTEX_SHADER == type) 135// *str++ = 'v'; 136// else if (GL_FRAGMENT_SHADER == type) 137// *str++ = 'f'; 138// else 139// assert(0); 140// for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) 141// { 142// *str++ = HexDigit(key->textureFormats[i] / 16); 143// *str++ = HexDigit(key->textureFormats[i] % 16); 144// *str++ = HexDigit(key->textureParameters[i] / 16); 145// *str++ = HexDigit(key->textureParameters[i] % 16); 146// } 147// *str++ = '\0'; 148} 149 150//static const unsigned SCANLINE_KEY_STRING_LEN = 2 * sizeof(((ShaderKey *)0)->scanLineKey) + 151// 3 + SHADER_KEY_STRING_LEN; 152 153static char * GetScanlineKeyString(const ShaderKey * key, char * buffer, 154 const unsigned bufferSize) 155{ 156// assert(1 == sizeof(char)); 157// assert(0xff >= GGL_PIXEL_FORMAT_COUNT); 158// assert(SCANLINE_KEY_STRING_LEN <= bufferSize); 159// char * str = buffer; 160// *str++ = 's'; 161// const unsigned char * start = (const unsigned char *)&key->scanLineKey; 162// const unsigned char * const end = start + sizeof(key->scanLineKey); 163// for (; start < end; start++) 164// { 165// *str++ = HexDigit(*start / 16); 166// *str++ = HexDigit(*start % 16); 167// } 168// GetShaderKeyString(GL_FRAGMENT_SHADER, key, str, bufferSize - (str - buffer)); 169// return buffer; 170 return NULL; 171} 172 173static void ShaderUse(GGLInterface * iface, gl_shader_program * program) 174{ 175 GGL_GET_CONST_CONTEXT(ctx, iface); 176 assert(program); 177 if (!program) 178 { 179// ctx->glCtx->Shader.CurrentProgram = NULL; 180 // so drawing calls will do nothing until ShaderUse with a program 181 SetShaderVerifyFunctions(iface); 182 return; 183 } 184 185// if (program->VertexProgram) 186// { 187// if (!program->STVP) 188// { 189// program->STVP = CALLOC_STRUCT(st_vertex_program); 190// program->STVP->Base = *program->VertexProgram; 191// st_translate_vertex_program(ctx->glCtx, program->STVP, NULL, NULL, NULL); 192// } 193// 194// _mesa_update_shader_textures_used(program->VertexProgram); 195// 196// ShaderKey shaderKey; 197// GetShaderKey(ctx, program->VertexProgram, &shaderKey); 198// ShaderFunction_t function = NULL; 199// if (!program->GLVMVP || NULL == (function = program->GLVMVP->functions[shaderKey])) 200// { 201// char shaderName [SHADER_KEY_STRING_LEN] = {0}; 202// GetShaderKeyString(GL_VERTEX_SHADER, &shaderKey, shaderName, Elements(shaderName)); 203// create_program(program->STVP->state.tokens, GALLIVM_VS, &program->GLVMVP, 204// &ctx->glCtx->Shader.cpu, ctx, program->VertexProgram, 205// shaderName, NULL); 206// program->GLVMVP->functions[shaderKey] = program->GLVMVP->function; 207// debug_printf("jit new vertex shader %p \n", program->GLVMVP->function); //getchar(); 208// } 209// else 210// { 211// program->GLVMVP->function = function; 212// //debug_printf("use cached vertex shader %p \n", function); 213// } 214// ctx->PickRaster(iface); 215// } 216// if (program->FragmentProgram) 217// { 218// if (!program->STFP) 219// { 220// program->STFP = CALLOC_STRUCT(st_fragment_program); 221// program->STFP->Base = *program->FragmentProgram; 222// st_translate_fragment_program(ctx->glCtx, program->STFP, NULL); 223// } 224// 225// _mesa_update_shader_textures_used(program->FragmentProgram); 226// 227// ShaderKey shaderKey; 228// GetShaderKey(ctx, program->FragmentProgram, &shaderKey); 229// ShaderFunction_t function = NULL; 230// if (!program->GLVMFP || NULL == (function = program->GLVMFP->functions[shaderKey])) 231// { 232// char shaderName [SHADER_KEY_STRING_LEN] = {0}; 233// GetShaderKeyString(GL_FRAGMENT_SHADER, &shaderKey, shaderName, Elements(shaderName)); 234// 235// char scanlineName [SCANLINE_KEY_STRING_LEN] = {0}; 236// GetScanlineKeyString(&shaderKey, scanlineName, Elements(scanlineName)); 237// create_program(program->STFP->state.tokens, GALLIVM_FS, &program->GLVMFP, 238// &ctx->glCtx->Shader.cpu, ctx, program->FragmentProgram, 239// shaderName, scanlineName); 240// program->GLVMFP->functions[shaderKey] = program->GLVMFP->function; 241// debug_printf("jit new fragment shader %p \n", program->GLVMFP->function); 242// } 243// else 244// { 245// program->GLVMFP->function = function; 246// //debug_printf("use cached fragment shader %p \n", function); 247// } 248// ctx->PickScanLine(iface); 249// } 250// ctx->glCtx->Shader.CurrentProgram = program; 251} 252 253static void ShaderProgramFree(const GGLInterface * iface, gl_shader_program * program) 254{ 255 GGL_GET_CONST_CONTEXT(ctx, iface); 256// if (ctx->glCtx->Shader.CurrentProgram == program) 257// { 258// ctx->glCtx->Shader.CurrentProgram = NULL; 259// SetShaderVerifyFunctions(const_cast<GGLInterface *>(iface)); 260// } 261// assert(program); 262// if (program->GLVMVP) 263// gallivm_prog_delete(ctx->glCtx->Shader.cpu, program->GLVMVP); 264// program->GLVMVP = NULL; 265// if (program->GLVMFP) 266// gallivm_prog_delete(ctx->glCtx->Shader.cpu, program->GLVMFP); 267// program->GLVMFP = NULL; 268// SAFE_FREE(program->STVP); 269// SAFE_FREE(program->STFP); 270// _mesa_free_shader_program(ctx->glCtx, program); 271} 272 273static void ShaderAttributeBind(const GGLInterface * iface, const gl_shader_program * program, 274 GLuint index, const GLchar * name) 275{ 276 GGL_GET_CONST_CONTEXT(ctx, iface); 277// _mesa_bind_attrib_location(ctx->glCtx, program, index, name, DEFAULTP); 278} 279 280static GLint ShaderAttributeLocation(const GGLInterface * iface, const gl_shader_program * program, 281 const char * name) 282{ 283 GGL_GET_CONST_CONTEXT(ctx, iface); 284// return _mesa_get_attrib_location(ctx->glCtx, program, name); 285 return -2; 286} 287 288static GLint ShaderUniformLocation(const GGLInterface * iface, const gl_shader_program * program, 289 const char * name) 290{ 291 GGL_GET_CONST_CONTEXT(ctx, iface); 292// return _mesa_get_shader_uniform_location(ctx->glCtx, program, name); 293 return -2; 294} 295 296static void ShaderUniformGetfv(const GGLInterface * iface, gl_shader_program * program, 297 GLint location, GLfloat * params) 298{ 299 GGL_GET_CONST_CONTEXT(ctx, iface); 300// _mesa_get_uniformfv(ctx->glCtx, program, location, params); 301} 302 303static void ShaderUniformGetiv(const GGLInterface * iface, gl_shader_program * program, 304 GLint location, GLint * params) 305{ 306 GGL_GET_CONST_CONTEXT(ctx, iface); 307// _mesa_get_uniformiv(ctx->glCtx, program, location, params); 308} 309 310static GLint ShaderUniform(const GGLInterface * iface, gl_shader_program * program, 311 GLint location, GLsizei count, const GLvoid *values, GLenum type) 312{ 313 GGL_GET_CONST_CONTEXT(ctx, iface); 314// if (!program) 315// { 316// gglError(GL_INVALID_OPERATION); 317// return -2; 318// } 319// return _mesa_uniform(ctx->glCtx, program, location, count, values, type); 320 return -2; 321} 322 323static void ShaderUniformMatrix(const GGLInterface * iface, gl_shader_program * program, 324 GLint cols, GLint rows, GLint location, GLsizei count, 325 GLboolean transpose, const GLfloat *values) 326{ 327 GGL_GET_CONST_CONTEXT(ctx, iface); 328// if (!program) 329// return gglError(GL_INVALID_OPERATION); 330// _mesa_uniform_matrix(ctx->glCtx, program, cols, rows, location, count, transpose, values); 331} 332 333static void ShaderVerifyProcessVertex(const GGLInterface * iface, const VertexInput * input, 334 VertexOutput * output) 335{ 336 GGL_GET_CONST_CONTEXT(ctx, iface); 337// if (ctx->glCtx->Shader.CurrentProgram) 338// { 339// ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram); 340// if (ShaderVerifyProcessVertex != iface->ProcessVertex) 341// iface->ProcessVertex(iface, input, output); 342// } 343} 344 345static void ShaderVerifyDrawTriangle(const GGLInterface * iface, const VertexInput * v0, 346 const VertexInput * v1, const VertexInput * v2) 347{ 348// GGL_GET_CONST_CONTEXT(ctx, iface); 349// if (ctx->glCtx->Shader.CurrentProgram) 350// { 351// ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram); 352// if (ShaderVerifyDrawTriangle != iface->DrawTriangle) 353// iface->DrawTriangle(iface, v0, v1, v2); 354// } 355} 356 357static void ShaderVerifyRasterTriangle(const GGLInterface * iface, const VertexOutput * v1, 358 const VertexOutput * v2, const VertexOutput * v3) 359{ 360// GGL_GET_CONST_CONTEXT(ctx, iface); 361// if (ctx->glCtx->Shader.CurrentProgram) 362// { 363// ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram); 364// if (ShaderVerifyRasterTriangle != iface->RasterTriangle) 365// iface->RasterTriangle(iface, v1, v2, v3); 366// } 367} 368 369static void ShaderVerifyRasterTrapezoid(const GGLInterface * iface, const VertexOutput * tl, 370 const VertexOutput * tr, const VertexOutput * bl, 371 const VertexOutput * br) 372{ 373 GGL_GET_CONST_CONTEXT(ctx, iface); 374// if (ctx->glCtx->Shader.CurrentProgram) 375// { 376// ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram); 377// if (ShaderVerifyRasterTrapezoid != iface->RasterTrapezoid) 378// iface->RasterTrapezoid(iface, tl, tr, bl, br); 379// } 380} 381 382static void ShaderVerifyScanLine(const GGLInterface * iface, const VertexOutput * v1, 383 const VertexOutput * v2) 384{ 385 GGL_GET_CONST_CONTEXT(ctx, iface); 386// if (ctx->glCtx->Shader.CurrentProgram) 387// { 388// ShaderUse(const_cast<GGLInterface *>(iface), ctx->glCtx->Shader.CurrentProgram); 389// if (ShaderVerifyScanLine != iface->ScanLine) 390// iface->ScanLine(iface, v1, v2); 391// } 392} 393 394// called after state changes so that drawing calls will trigger JIT 395void SetShaderVerifyFunctions(struct GGLInterface * iface) 396{ 397 iface->ProcessVertex = ShaderVerifyProcessVertex; 398 iface->DrawTriangle = ShaderVerifyDrawTriangle; 399 iface->RasterTriangle = ShaderVerifyRasterTriangle; 400 iface->RasterTrapezoid = ShaderVerifyRasterTrapezoid; 401 iface->ScanLine = ShaderVerifyScanLine; 402} 403 404void InitializeShaderFunctions(struct GGLInterface * iface) 405{ 406 GGL_GET_CONTEXT(ctx, iface); 407 ctx->llvmCtx = new llvm::LLVMContext(); 408 409 iface->ShaderCreate = ShaderCreate; 410 iface->ShaderCompile = ShaderCompile; 411 iface->ShaderFree = ShaderFree; 412 iface->ShaderProgramCreate = ShaderProgramCreate; 413 iface->ShaderProgramLink = ShaderProgramLink; 414 iface->ShaderUse = ShaderUse; 415 iface->ShaderProgramFree = ShaderProgramFree; 416 iface->ShaderAttributeBind = ShaderAttributeBind; 417 iface->ShaderAttributeLocation = ShaderAttributeLocation; 418 iface->ShaderUniformLocation = ShaderUniformLocation; 419 iface->ShaderUniformGetfv = ShaderUniformGetfv; 420 iface->ShaderUniformGetiv = ShaderUniformGetiv; 421 iface->ShaderUniform = ShaderUniform; 422 iface->ShaderUniformMatrix = ShaderUniformMatrix; 423} 424 425void DestroyShaderFunctions(GGLInterface * iface) 426{ 427 GGL_GET_CONTEXT(ctx, iface); 428// if (ctx->glCtx->Shader.cpu) 429// { 430// gallivm_cpu_engine_delete(ctx->glCtx->Shader.cpu); 431// ctx->glCtx->Shader.cpu = NULL; 432// } 433// SAFE_DELETE(ctx->llvmCtx); 434}