Home | History | Annotate | Download | only in test
      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