• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
load_shader(const unsigned type,const char * path)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 
init_shader()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 
test_scan()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 
main(int argc,char * const argv[])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