1 #include <assert.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <time.h> 6 #include <math.h> 7 #include <unistd.h> 8 9 10 #define DRAW_TO_SCREEN 1 11 #define USE_16BPP_TEXTURE 0 // forces texture to load as 16bpp, define before image_file.h 12 13 #ifdef __arm__ 14 #define PATH_PREFIX "/data/" 15 #else 16 #define PATH_PREFIX "" 17 #endif 18 19 #include <pixelflinger2/pixelflinger2_interface.h> 20 #include "image_file.h" 21 #include "m_matrix.h" 22 23 #ifdef __arm__ 24 extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned * bpp); 25 extern "C" void * PresentDrawingSurface(); 26 extern "C" void DisposeDrawingSurface(); 27 #endif 28 29 GGLInterface * ggl = NULL; 30 31 gl_shader * load_shader(const unsigned type, const char * path) 32 { 33 FILE * file = NULL; 34 file = fopen(path, "rb"); 35 if (!file) 36 printf("failed to open '%s' \n", path); 37 38 fseek(file, 0, SEEK_END); 39 unsigned fileSize = ftell(file); 40 fseek(file, 0, SEEK_SET); 41 42 char * shader_string = (char *)malloc(fileSize + 1); 43 printf("fileSize=%dB \n", fileSize); 44 int read = fread(shader_string, 1, fileSize, file); 45 shader_string[read] = '\0'; 46 fclose(file); 47 48 puts(shader_string); 49 puts("compiling shader..."); 50 51 gl_shader * shader = ggl->ShaderCreate(ggl, type); 52 const char * infoLog = NULL; 53 GLboolean compileStatus = ggl->ShaderCompile(ggl, shader, shader_string, &infoLog); 54 55 printf("shader.InfoLog = %s \nshader.CompileStatus = %d \n\n", 56 infoLog, compileStatus); 57 if (!compileStatus) 58 exit(1); 59 60 free(shader_string); 61 return shader; 62 } 63 64 gl_shader_program * init_shader() 65 { 66 puts("\n -- load vertex shader -- \n"); 67 struct gl_shader * vertShader = load_shader(GL_VERTEX_SHADER, PATH_PREFIX"vs.vert"); 68 69 puts("\n -- load fragment shader -- \n"); 70 struct gl_shader * fragShader = load_shader(GL_FRAGMENT_SHADER, PATH_PREFIX"fs.frag"); 71 72 gl_shader_program * program = ggl->ShaderProgramCreate(ggl); 73 // current scan_test assumes the following attribute layout 74 ggl->ShaderAttributeBind(program, 0, "aPosition"); 75 ggl->ShaderAttributeBind(program, 1, "aTexCoord"); 76 77 puts("\n -- linking -- \n"); 78 ggl->ShaderAttach(ggl, program, vertShader); 79 ggl->ShaderAttach(ggl, program, fragShader); 80 const char * infoLog = NULL; 81 GLboolean linkStatus = ggl->ShaderProgramLink(program, &infoLog); 82 83 printf("finished linking, LinkStatus=%d \n %s \n", linkStatus, infoLog); 84 85 if (!linkStatus) 86 exit(1); 87 88 ggl->ShaderUse(ggl, program); 89 90 return program; 91 } 92 93 void test_scan() 94 { 95 srand(1337); 96 ggl = CreateGGLInterface(); 97 98 GGLSurface frameSurface = {0}; 99 #if defined __arm__ && DRAW_TO_SCREEN 100 unsigned width = 0, height = 0, bpp = 0; 101 SetupDrawingSurface(&width, &height, &bpp); 102 frameSurface.data = PresentDrawingSurface(); 103 #else 104 const unsigned width = 640, height = 400; 105 frameSurface.data = (unsigned int *)malloc(width * height * 4); 106 #endif 107 108 frameSurface.format = GGL_PIXEL_FORMAT_RGBA_8888; 109 frameSurface.width = width; 110 frameSurface.height = height; 111 112 GGLSurface depthSurface = {0}; 113 depthSurface.width = width; 114 depthSurface.height = height; 115 depthSurface.format = GGL_PIXEL_FORMAT_Z_32; 116 depthSurface.data = malloc(width * height * 4); 117 ggl->SetBuffer(ggl, GL_DEPTH_BUFFER_BIT, &depthSurface); 118 119 GGLSurface stencilSurface = {0}; 120 stencilSurface.width = width; 121 stencilSurface.height = height; 122 stencilSurface.format = GGL_PIXEL_FORMAT_S_8; 123 stencilSurface.data = malloc(width * height); 124 125 ggl->SetBuffer(ggl, GL_STENCIL_BUFFER_BIT, &stencilSurface); 126 ggl->ClearStencil(ggl, 0); 127 ggl->StencilFuncSeparate(ggl, GL_FRONT_AND_BACK, GL_EQUAL, 0, 0xff); 128 ggl->StencilOpSeparate(ggl, GL_FRONT_AND_BACK, GL_INCR, GL_KEEP, GL_KEEP); 129 //ggl->EnableDisable(ggl, GL_STENCIL_TEST, true); 130 131 gl_shader_program * program = init_shader(); // change states after to test code cache 132 133 GGLTexture texture = {0}; 134 LoadTGA(PATH_PREFIX"android.tga", &texture.width, &texture.height, 135 &texture.levels); 136 // for (unsigned i = 0; i < texture.width * texture.height; i++) 137 // { 138 // const unsigned x = i % 480, y = i / 480; 139 // ((unsigned *)texture.levels[0])[i] = ((x + y) % 2) * 0xffffff | 0xff000000; 140 // } 141 #if USE_16BPP_TEXTURE 142 texture.format = GGL_PIXEL_FORMAT_RGB_565; 143 #else 144 texture.format = GGL_PIXEL_FORMAT_RGBA_8888; 145 #endif 146 texture.type = GL_TEXTURE_2D; 147 texture.levelCount = 1; 148 texture.wrapS = texture.wrapT = GGLTexture::GGL_REPEAT; // repeat = 0 fastest, clamp = 1, mirrored = 2 149 texture.minFilter = texture.magFilter = GGLTexture::GGL_NEAREST; // nearest = 0, linear = 1 150 //texture.levelCount = GenerateMipmaps(texture.levels, texture.width, texture.height); 151 152 // static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000, 153 // 0xff00ffff, 0xffffff00, 0xffff00ff}; 154 // memcpy(texture.levels[0], texels, sizeof texels); 155 // texture.format = GGL_PIXEL_FORMAT_RGBA_8888; 156 // texture.width = texture.height = 1; 157 //texture.height /= 6; 158 //texture.type = GL_TEXTURE_CUBE_MAP; 159 160 ggl->SetSampler(ggl, 0, &texture); 161 162 //ggl->EnableDisable(ggl, GL_CULL_FACE, true); 163 ggl->FrontFace(ggl, GL_CW); 164 ggl->CullFace(ggl, GL_BACK); 165 166 ggl->EnableDisable(ggl, GL_BLEND, true); 167 ggl->BlendFuncSeparate(ggl, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR, 168 GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR); 169 ggl->BlendEquationSeparate(ggl, GL_FUNC_ADD, GL_FUNC_ADD); 170 ggl->BlendColor(ggl, 0.7, 0.7, 0.7, 1); 171 172 ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &frameSurface); 173 174 175 ggl->EnableDisable(ggl, GL_DEPTH_TEST, true); 176 ggl->DepthFunc(ggl, GL_LESS); 177 178 ggl->DepthRangef(ggl, 0.0f, 1.0f); 179 ggl->Viewport(ggl, 0, 0, width, height); 180 181 const unsigned scale = 1, portWidth = 640, portHeight = 400; 182 //const unsigned scale = 1, portWidth = width / scale, portHeight = height / scale; 183 ggl->Viewport(ggl, 0, 0, portWidth, portHeight); 184 //ggl->Viewport(ggl, (width - portWidth) / 2, (height - portHeight) / 2, 185 //portWidth, portHeight); 186 187 GLmatrix m0, m1, m2, m3, m4; 188 _math_matrix_ctr(&m0); 189 _math_matrix_ctr(&m1); 190 _math_matrix_ctr(&m2); 191 _math_matrix_ctr(&m3); 192 _math_matrix_ctr(&m4); 193 194 int uMatrixLoc = ggl->ShaderUniformLocation(program, "uMatrix"); 195 int uRotMLoc = ggl->ShaderUniformLocation(program, "uRotM"); 196 int uTLoc = ggl->ShaderUniformLocation(program, "t"); 197 198 GGLTexture cubeTexture = {GL_TEXTURE_CUBE_MAP, GGL_PIXEL_FORMAT_RGBA_8888, 1, 1, 1, NULL, GGLTexture::GGL_CLAMP_TO_EDGE, GGLTexture::GGL_MIRRORED_REPEAT, GGLTexture::GGL_LINEAR, GGLTexture::GGL_LINEAR}; 199 unsigned cubeTextureSurface [6] = {0xff0000ff, 0xff00ff00, 0xffff0000, 200 0xff00ffff, 0xffffff00, 0xffff00ff 201 }; 202 void * levels [1] = {cubeTextureSurface}; 203 cubeTexture.levels = levels; 204 if (program) { 205 ggl->ShaderUniformMatrix(program, 4, 4, uMatrixLoc, 1, GL_FALSE, m0.m); 206 int sampler2dLoc = ggl->ShaderUniformLocation(program, "sampler2d"); 207 int samplercubeLoc = ggl->ShaderUniformLocation(program, "samplercube"); 208 int samplerUnit = -1; 209 if (0 <= sampler2dLoc) { // set 2d texture to sampler if used 210 samplerUnit = sampler2dLoc;//ggl->ShaderUniformGetiv(ggl, program, sampler2dLoc, &samplerUnit); 211 ggl->SetSampler(ggl, samplerUnit, &texture); 212 } 213 if (0 <= samplercubeLoc) { // set cube texture to sampler if used 214 samplerUnit = samplercubeLoc;//ggl->ShaderUniformGetiv(ggl, program, samplercubeLoc, &samplerUnit); 215 ggl->SetSampler(ggl, samplerUnit, &cubeTexture); 216 } 217 } 218 219 VertexInput v0, v1, v2, v3; 220 const float z = +0.5; 221 // const float vcMin = -10, vcMax = 10; 222 // const float tcMin = -4.5, tcMax = 5.5; 223 const float vcMin = -1, vcMax = 1; 224 const float tcMin = 0, tcMax = 1; 225 v0.attributes[0] = Vector4_CTR(vcMin,vcMin,z,1); 226 v0.attributes[1] = Vector4_CTR(tcMin,tcMin,0,1); 227 228 v1.attributes[0] = Vector4_CTR(vcMin,vcMax,z,1); 229 v1.attributes[1] = Vector4_CTR(tcMin,tcMax,0,1); 230 231 v2.attributes[0] = Vector4_CTR(vcMax,vcMax,z,1); 232 v2.attributes[1] = Vector4_CTR(tcMax,tcMax,0,1); 233 234 v3.attributes[0] = Vector4_CTR(vcMax,vcMin,z,1); 235 v3.attributes[1] = Vector4_CTR(tcMax,tcMin,0,1); 236 237 VertexInput vertices[8] = { 238 // pos texcoord 239 {{Vector4_CTR(-1,-1,-1,1), Vector4_CTR(tcMin,tcMin,0,1)}}, 240 {{Vector4_CTR(-1,-1, 1,1), Vector4_CTR(tcMin,tcMax,0,1)}}, 241 {{Vector4_CTR( 1,-1, 1,1), Vector4_CTR(tcMax,tcMax,0,1)}}, 242 {{Vector4_CTR( 1,-1,-1,1), Vector4_CTR(tcMax,tcMin,0,1)}}, 243 {{Vector4_CTR(-1, 1,-1,1), Vector4_CTR(tcMin,tcMin,0,1)}}, 244 {{Vector4_CTR(-1, 1, 1,1), Vector4_CTR(tcMin,tcMax,0,1)}}, 245 {{Vector4_CTR( 1, 1, 1,1), Vector4_CTR(tcMax,tcMax,0,1)}}, 246 {{Vector4_CTR( 1, 1,-1,1), Vector4_CTR(tcMax,tcMin,0,1)}}, 247 }; 248 249 unsigned indices[] = { 250 0,1,2, 0,2,3, 251 4,5,6, 4,6,7, 252 0,3,4, 3,4,7, 253 1,2,5, 2,5,6, 254 0,1,4, 1,4,5, 255 2,3,6, 3,6,7, 256 }; 257 258 Vector4 pos = v0.attributes[0]; 259 ggl->ViewportTransform(ggl, &pos); 260 261 ggl->ClearColor(ggl, 0.8f, 0.8f, 1, 1); 262 //ggl->ClearDepthf(ggl, pos.z + 0.0001f); // when there is no transform in vs 263 ggl->ClearDepthf(ggl, 1); 264 ggl->EnableDisable(ggl, GL_BLEND, false); 265 ggl->EnableDisable(ggl, GL_DEPTH_TEST, true); 266 ggl->EnableDisable(ggl, GL_STENCIL_TEST, false); 267 268 269 ggl->DrawTriangle(ggl, &v0, &v0, &v0); // cause re-JIT to not mess up timing 270 271 puts("\n -- begin rendering -- \n"); 272 273 unsigned frames = 0; 274 clock_t c0 = clock(); 275 276 #ifdef __arm__ 277 //while (true) 278 #endif 279 for ( 280 #ifdef __arm__ 281 unsigned i = 0; i <= 90; i++ 282 #else 283 unsigned i = 0; i <= 10; i+= 1 284 #endif 285 ) { 286 // printf("frame=%d \n", i); 287 ggl->Clear(ggl, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 288 //ggl->Clear(ggl, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 289 290 _math_matrix_set_identity(&m0); 291 _math_matrix_set_identity(&m1); 292 _math_matrix_set_identity(&m2); 293 //_math_matrix_set_identity(&m3); 294 295 296 //_math_matrix_ortho(&m0, 0, 480, 0, 800, 0.1, 1); 297 _math_matrix_perspective(&m0, 60, (float)width / height, 0.1f, 100); 298 //float ratio = (float)width / height; 299 //_math_matrix_frustum(&m0, -ratio, ratio, -1, 1, 3, 7); 300 301 _math_matrix_lookat(&m1, 0, 0, -6, 302 0, 0, 2, 303 0, 1, 0); 304 305 //_math_matrix_scale(&m0, 0.2, 0.2, 0.2); 306 //_math_matrix_translate(&m2, 1, 1, 1); 307 _math_matrix_rotate(&m2, i * 2, 1, 2, 3); 308 //_math_matrix_rotate(&m2, i, 0, 0, 1); 309 310 // matrix on the right is applied to vector first 311 _math_matrix_mul_matrix(&m3, &m1, &m2); 312 _math_matrix_mul_matrix(&m4, &m0, &m3); 313 314 315 float t = i * 0.6f; 316 if (program) { 317 ggl->ShaderUniformMatrix(program, 4, 4, uMatrixLoc, 1, GL_FALSE, m4.m); 318 ggl->ShaderUniformMatrix(program, 4, 4, uRotMLoc, 1, GL_FALSE, m2.m); 319 ggl->ShaderUniform(program, uTLoc, 1, &t, GL_FLOAT); 320 } 321 322 //ggl->EnableDisable(ggl, GL_BLEND, true); 323 //ggl->EnableDisable(ggl, GL_BLEND, false); 324 //ggl->EnableDisable(ggl, GL_BLEND, (i + 1) % 2); 325 //ggl->EnableDisable(ggl, GL_STENCIL_TEST, i / 2 % 2); 326 //ggl->BlendColor(ggl,(float)i / 10, (float) i / 15, (float)i < 20, 1); 327 328 for (unsigned j = 0; j < sizeof(indices) / sizeof(*indices); j += 3) 329 ggl->DrawTriangle(ggl, vertices + indices[j], vertices + indices[j+1], vertices + indices[j+2]); 330 331 // including clear, depth, and other ops, direct ScanLine calls are 4% faster than DrawTriangle 332 // X86 memcpy is 0.60ms vs 4.90ms for 480*800 fs texturing 333 // Nexus One memcpy is 8.7ms vs 71ms for 480*800 fs texturing 334 // Nexus One fixed point 480*800 fs texturing is 61ms 335 // texture * vtexcoord is 70ms, floating texture * vtexcoord is 170ms 336 //memcpy(((GGLContext *)ggl)->frameSurface.data, ((GGLContext *)ggl)->textureState.textures[0].levels[0], width * height * 4); 337 338 // ggl->DrawTriangle(ggl, &v0, &v1, &v2); 339 // ggl->DrawTriangle(ggl, &v2, &v3, &v0); 340 341 // VertexOutput tl = {0, Vector4(0,0,0,1), Vector4(0,0,0,1)}; 342 // VertexOutput tr = {0, Vector4(portWidth - 1,0,0,1), Vector4(1,0,0,1)}; 343 // VertexOutput bl = {0, Vector4(0, portHeight-1,0,1), Vector4(0,1,0,1)}; 344 // VertexOutput br = {0, Vector4(portWidth - 1, portHeight - 1,0,1), Vector4(1,1,0,1)}; 345 // ggl->RasterTrapezoid(ggl, &tl, &tr, &bl, &br); 346 // 347 // for (unsigned y = 0; y < portHeight; y++) 348 // { 349 // VertexOutput vo0 = {0, Vector4(0,y,0,1), Vector4(0,float(y) / (portHeight - 1),0,1)}; 350 // VertexOutput vo1 = {0, Vector4(portWidth - 1,y,0,1), Vector4(1,float(y) / (portHeight - 1),0,1)}; 351 // ggl->ScanLine(ggl, &vo0, &vo1); 352 // } 353 354 //#if !USE_LLVM_TEXTURE_SAMPLER 355 // extern const GGLContext * textureGGLContext; 356 // textureGGLContext = (GGLContext *)ggl; 357 //#endif 358 // for (unsigned y = 0; y < height; y++) 359 // for (unsigned x = 0; x < width; x++) 360 // { 361 // const unsigned index = y * width + x; 362 //// ((unsigned *)frameSurface.data)[index] = ((unsigned *)textureGGLContext->textureState.textures[0].levels[0])[index]; 363 // Vector4 tc(float(x) / (width - 1), float(y) / (height - 1), 0, 0); 364 // unsigned color[4]; 365 // tex2d_int32<GGL_PIXEL_FORMAT_RGBA_8888>(color, (const float *)&tc, 0); 366 // ((unsigned *)frameSurface.data)[index] = color[0]; 367 // } 368 //#if !USE_LLVM_TEXTURE_SAMPLER 369 // textureGGLContext = NULL; 370 //#endif 371 372 frames++; 373 if (scale > 1) 374 for (int y = portHeight - 1; y >= 0; y--) 375 for (int x = portWidth - 1; x >= 0; x--) { 376 unsigned pixel = ((unsigned *)frameSurface.data)[y * width + x]; 377 for (unsigned xx = 0; xx < scale; xx++) 378 for (unsigned yy = 0; yy < scale; yy++) 379 ((unsigned *)frameSurface.data)[(y * scale + yy) * width + x * scale + xx] = pixel; 380 } 381 382 #if defined __arm__ && DRAW_TO_SCREEN 383 frameSurface.data = PresentDrawingSurface(); 384 ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &frameSurface); 385 #endif 386 //puts("frame completed, press ENTER"); getchar(); 387 } 388 389 /* 390 #ifndef __arm__ 391 __attribute__ ((aligned (16))) // LLVM generates movaps on X86, needs 16 bytes align 392 #endif 393 float data [64]; 394 ShaderFunction_t function = ((GGLContext *)ggl)->glCtx->Shader.CurrentProgram->GLVMFP->function; 395 float * inputs = data; 396 float * outputs = data + 24; 397 float * constants = data + 48; 398 const unsigned wd = 200, ht = 200; 399 for (unsigned y = 0; y < ht; y++) 400 for (unsigned x = 0; x < wd; x++) 401 { 402 inputs[4] = ((float)x) / wd; 403 inputs[5] = ((float)y) / ht; 404 inputs[6] = 0; 405 inputs[7] = 1; 406 constants[0] = 0.0f; 407 function(inputs, outputs, constants); 408 unsigned r = outputs[0] * 255; 409 unsigned g = outputs[1] * 255; 410 unsigned b = outputs[2] * 255; 411 unsigned a = outputs[3] * 255; 412 ((unsigned *)frameSurface.data)[y * width + x] = (a << 24) | (b << 16) | (g << 8) | r; 413 } 414 printf("gl_FragColor=%.2f, %.2f, %.2f %.2f \n", outputs[0], outputs[1], outputs[2], outputs[3]); 415 frames = 1; 416 //*/ 417 418 float elapsed = (float)(clock() - c0) / CLOCKS_PER_SEC; 419 printf ("\n *** test_scan elapsed CPU time: %fs \n *** fps=%.2f, tpf=%.2fms \n", 420 elapsed, frames / elapsed, elapsed / frames * 1000); 421 #if USE_16BPP_TEXTURE 422 puts("USE_16BPP_TEXTURE"); 423 #endif 424 #ifdef __arm__ 425 SaveBMP("/sdcard/mesa.bmp", (unsigned *)frameSurface.data, frameSurface.width, frameSurface.height); 426 #else 427 SaveBMP("mesa.bmp", (unsigned *)frameSurface.data, frameSurface.width, frameSurface.height); 428 #endif 429 430 ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, NULL); 431 #if defined __arm__ && DRAW_TO_SCREEN 432 DisposeDrawingSurface(); 433 #else 434 free(frameSurface.data); 435 #endif 436 437 ggl->SetBuffer(ggl, GL_DEPTH_BUFFER_BIT, NULL); 438 free(depthSurface.data); 439 440 ggl->SetBuffer(ggl, GL_STENCIL_BUFFER_BIT, NULL); 441 free(stencilSurface.data); 442 443 if (program) 444 ggl->ShaderProgramDelete(ggl, program); 445 446 free(texture.levels); 447 448 DestroyGGLInterface(ggl); 449 ggl = NULL; 450 } 451 452 extern "C" int cmain(int,char**); 453 454 #include "llvm/LLVMContext.h" 455 456 void GLContextDctr(); 457 458 extern "C" void hieralloc_report(const void *, FILE *); 459 extern "C" void hieralloc_report_brief(const void *, FILE *); 460 461 int main (int argc, char * const argv[]) 462 { 463 cmain(0,NULL); 464 465 // contextless_test(); 466 467 // contextless_test(); 468 469 test_scan(); 470 471 // hieralloc_report(NULL, stdout); 472 hieralloc_report_brief(NULL, stdout); 473 puts("mesa done"); 474 return 0; 475 } 476