diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/aniso.c | 3 | ||||
-rw-r--r-- | tests/cases/2xi40.ll | 42 | ||||
-rw-r--r-- | tests/cases/2xi40.txt | 1 | ||||
-rw-r--r-- | tests/cases/caall.ll | 2 | ||||
-rw-r--r-- | tests/cases/emptyasm_le32.ll | 16 | ||||
-rw-r--r-- | tests/embind/shell.html | 2 | ||||
-rw-r--r-- | tests/hello_world_gles_shell.html | 2 | ||||
-rw-r--r-- | tests/sdl_canvas_size.c | 191 | ||||
-rw-r--r-- | tests/sdl_canvas_size.html | 93 | ||||
-rw-r--r-- | tests/test_browser.py | 47 | ||||
-rw-r--r-- | tests/test_core.py | 148 | ||||
-rw-r--r-- | tests/test_other.py | 44 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_common.c | 262 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_glfw.c | 47 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_glut.c | 42 | ||||
-rw-r--r-- | tests/test_webgl_context_attributes_sdl.c | 50 |
16 files changed, 945 insertions, 47 deletions
diff --git a/tests/aniso.c b/tests/aniso.c index e8d7bd3f..f1674cad 100644 --- a/tests/aniso.c +++ b/tests/aniso.c @@ -66,6 +66,9 @@ int main(int argc, char *argv[]) const char *exts = (const char *)glGetString(GL_EXTENSIONS); assert(hasext(exts, "GL_EXT_texture_filter_anisotropic")); + const char *vendor = (const char *)glGetString(GL_VENDOR); + printf("vendor: %s\n", vendor); + GLint aniso; glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso); printf("Max anisotropy: %d (using that)\n", aniso); diff --git a/tests/cases/2xi40.ll b/tests/cases/2xi40.ll new file mode 100644 index 00000000..592f1ba4 --- /dev/null +++ b/tests/cases/2xi40.ll @@ -0,0 +1,42 @@ +; ModuleID = '/tmp/tmpe4Pk1F/a.out.bc' +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" +target triple = "le32-unknown-nacl" + +%struct.pair = type { [5 x i8], [5 x i8] } + +@.str = private unnamed_addr constant [6 x i8] c"|%d|\0A\00", align 1 +@.str1 = private unnamed_addr constant [7 x i8] c"%s,%s\0A\00", align 1 + +define i32 @main() { + %1 = alloca i32, align 4 + %pp = alloca [2 x i40], align 8 + %p = bitcast [2 x i40]* %pp to %struct.pair* + store i32 0, i32* %1 + %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i32 10) + %3 = bitcast %struct.pair* %p to i8* + call void @llvm.memset.p0i8.i32(i8* %3, i8 120, i32 10, i32 1, i1 false) + %4 = getelementptr inbounds [2 x i40]* %pp, i32 0, i32 0 + %b4 = bitcast i40* %4 to [5 x i8]* + %5 = getelementptr inbounds [5 x i8]* %b4, i32 0, i32 2 + store i8 97, i8* %5, align 1 + %6 = getelementptr inbounds %struct.pair* %p, i32 0, i32 0 + %7 = getelementptr inbounds [5 x i8]* %6, i32 0, i32 4 + store i8 0, i8* %7, align 1 + %8 = getelementptr inbounds %struct.pair* %p, i32 0, i32 1 + %9 = getelementptr inbounds [5 x i8]* %8, i32 0, i32 3 + store i8 98, i8* %9, align 1 + %10 = getelementptr inbounds [2 x i40]* %pp, i32 0, i32 1 + %b10 = bitcast i40* %10 to [5 x i8]* + %11 = getelementptr inbounds [5 x i8]* %b10, i32 0, i32 4 + store i8 0, i8* %11, align 1 + %12 = getelementptr inbounds %struct.pair* %p, i32 0, i32 0 + %13 = getelementptr inbounds [5 x i8]* %12, i32 0, i32 0 + %14 = getelementptr inbounds %struct.pair* %p, i32 0, i32 1 + %15 = getelementptr inbounds [5 x i8]* %14, i32 0, i32 0 + %16 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str1, i32 0, i32 0), i8* %13, i8* %15) + ret i32 0 +} + +declare i32 @printf(i8*, ...) + +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind diff --git a/tests/cases/2xi40.txt b/tests/cases/2xi40.txt new file mode 100644 index 00000000..59a1104e --- /dev/null +++ b/tests/cases/2xi40.txt @@ -0,0 +1 @@ +xxax,xxxb diff --git a/tests/cases/caall.ll b/tests/cases/caall.ll index 313116e6..5b8f7f29 100644 --- a/tests/cases/caall.ll +++ b/tests/cases/caall.ll @@ -18,7 +18,7 @@ entry: define (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 %x) { entry: %ret = inttoptr i32 0 to (i32*)** - ret %ret + ret (i32*)** %ret } ; [#uses=1] diff --git a/tests/cases/emptyasm_le32.ll b/tests/cases/emptyasm_le32.ll new file mode 100644 index 00000000..e123d3d5 --- /dev/null +++ b/tests/cases/emptyasm_le32.ll @@ -0,0 +1,16 @@ +; ModuleID = 'tests/hello_world.bc' + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + store i32 0, i32* %retval + call void asm sideeffect "", "~{memory}"() nounwind, !srcloc !0 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32] + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/embind/shell.html b/tests/embind/shell.html index c3655e03..f0ee10f8 100644 --- a/tests/embind/shell.html +++ b/tests/embind/shell.html @@ -85,6 +85,6 @@ }; Module.setStatus('Downloading...'); </script> - <script type='text/javascript'>{{{ SCRIPT_CODE }}}</script> + {{{ SCRIPT }}} </body> </html> diff --git a/tests/hello_world_gles_shell.html b/tests/hello_world_gles_shell.html index 2459d755..22ecee7b 100644 --- a/tests/hello_world_gles_shell.html +++ b/tests/hello_world_gles_shell.html @@ -49,7 +49,7 @@ Module.postRun = doTest; </script> - <script>{{{ SCRIPT_CODE }}}</script> + {{{ SCRIPT }}} </body> </html> diff --git a/tests/sdl_canvas_size.c b/tests/sdl_canvas_size.c new file mode 100644 index 00000000..923a9014 --- /dev/null +++ b/tests/sdl_canvas_size.c @@ -0,0 +1,191 @@ +/******************************************************************* + * * + * Using SDL With OpenGL * + * * + * Tutorial by Kyle Foley (sdw) * + * * + * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL * + * * + *******************************************************************/ + +/* +THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION +AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN. + +THE ORIGINAL AUTHOR IS KYLE FOLEY. + +THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY +OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF +MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, +ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE +RESULTING FROM THE USE, MODIFICATION, OR +REDISTRIBUTION OF THIS SOFTWARE. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#ifdef EMSCRIPTEN +#include <emscripten.h> +#endif + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new* + +#ifdef EMSCRIPTEN + // Test 1: Check that initializing video mode with size (0,0) will use the size from the <canvas> element. + screen = SDL_SetVideoMode( 0, 0, 16, SDL_OPENGL ); // *changed* + + // Test 2: Check that getting current canvas size works. + int w, h, fs; + emscripten_get_canvas_size(&w, &h, &fs); + printf("w:%d,h:%d\n", w,h); + assert(w == 700); + assert(h == 200); + + // Test 3: Check that resizing the canvas works as well. + emscripten_set_canvas_size(640, 480); + // Set the OpenGL state after creating the context with SDL_SetVideoMode +#else + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* +#endif + + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + glClearColor( 0, 0, 0, 0 ); + + glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline. + + glViewport( 0, 0, 640, 480 ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1, 1 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Load the OpenGL texture + + GLuint texture; // Texture object handle + SDL_Surface *surface; // Gives us the information to make the texture + + if ( (surface = IMG_Load("screenshot.png")) ) { + + // Check that the image's width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + printf("warning: image.bmp's width is not a power of 2\n"); + } + + // Also check if the height is a power of 2 + if ( (surface->h & (surface->h - 1)) != 0 ) { + printf("warning: image.bmp's height is not a power of 2\n"); + } + + // Have OpenGL generate a texture object handle for us + glGenTextures( 1, &texture ); + + // Bind the texture object + glBindTexture( GL_TEXTURE_2D, texture ); + + // Set the texture's stretching properties + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + //SDL_LockSurface(surface); + + // Add some greyness + memset(surface->pixels, 0x66, surface->w*surface->h); + + // Edit the texture object's image data using the information SDL_Surface gives us + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); + + //SDL_UnlockSurface(surface); + } + else { + printf("SDL could not load image.bmp: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + // Free the SDL_Surface only if it was successfully created + if ( surface ) { + SDL_FreeSurface( surface ); + } + + // Clear the screen before drawing + glClear( GL_COLOR_BUFFER_BIT ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 0 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 0 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 0 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 0 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 0 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 ); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, 0 ); + glVertex3f( 300, 410, 0 ); + glVertex3f( 300, 480, 0 ); + glVertex3f( 10, 470, 0 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 0 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 0 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 0 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 0 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(3000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} diff --git a/tests/sdl_canvas_size.html b/tests/sdl_canvas_size.html new file mode 100644 index 00000000..50495049 --- /dev/null +++ b/tests/sdl_canvas_size.html @@ -0,0 +1,93 @@ +<!doctype html> +<html lang="en-us"> + <head> + <meta charset="utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>Emscripten-Generated Code</title> + <style> + .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } + textarea.emscripten { font-family: monospace; width: 80%; } + div.emscripten { text-align: center; } + div.emscripten_border { border: 1px solid black; } + /* the canvas *must not* have any border or padding, or mouse coords will be wrong */ + canvas.emscripten { border: 0px none; } + </style> + </head> + <body> + <hr/> + <div class="emscripten" id="status">Downloading...</div> + <div class="emscripten"> + <progress value="0" max="100" id="progress" hidden=1></progress> + </div> + <div class="emscripten_border"> + <!-- Pass custom width/height to test that SDL_SetVideoMode(0,0, ...) will use these. --> + <canvas class="emscripten" id="canvas" width="700" height="200" oncontextmenu="event.preventDefault()"></canvas> + </div> + <hr/> + <div class="emscripten"> + <input type="checkbox" id="resize">Resize canvas + <input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer + + <input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked, + document.getElementById('resize').checked)"> + </div> + + <hr/> + <textarea class="emscripten" id="output" rows="8"></textarea> + <hr> + <script type='text/javascript'> + // connect to canvas + var Module = { + preRun: [], + postRun: [], + print: (function() { + var element = document.getElementById('output'); + element.value = ''; // clear browser cache + return function(text) { + text = Array.prototype.slice.call(arguments).join(' '); + // These replacements are necessary if you render to raw HTML + //text = text.replace(/&/g, "&"); + //text = text.replace(/</g, "<"); + //text = text.replace(/>/g, ">"); + //text = text.replace('\n', '<br>', 'g'); + element.value += text + "\n"; + element.scrollTop = 99999; // focus on bottom + }; + })(), + printErr: function(text) { + text = Array.prototype.slice.call(arguments).join(' '); + if (0) { // XXX disabled for safety typeof dump == 'function') { + dump(text + '\n'); // fast, straight to the real console + } else { + console.log(text); + } + }, + canvas: document.getElementById('canvas'), + setStatus: function(text) { + if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + var statusElement = document.getElementById('status'); + var progressElement = document.getElementById('progress'); + if (m) { + text = m[1]; + progressElement.value = parseInt(m[2])*100; + progressElement.max = parseInt(m[4])*100; + progressElement.hidden = false; + } else { + progressElement.value = null; + progressElement.max = null; + progressElement.hidden = true; + } + statusElement.innerHTML = text; + }, + totalDependencies: 0, + monitorRunDependencies: function(left) { + this.totalDependencies = Math.max(this.totalDependencies, left); + Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); + } + }; + Module.setStatus('Downloading...'); + </script> + {{{ SCRIPT }}} + </body> +</html> diff --git a/tests/test_browser.py b/tests/test_browser.py index ecd331fd..2ff9106b 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -869,6 +869,48 @@ keydown(100);keyup(100); // trigger the end def test_glut_wheelevents(self): self.btest('glut_wheelevents.c', '1') + def test_webgl_context_attributes(self): + # Javascript code to check the attributes support we want to test in the WebGL implementation + # (request the attribute, create a context and check its value afterwards in the context attributes). + # Tests will succeed when an attribute is not supported. + open(os.path.join(self.get_dir(), 'check_webgl_attributes_support.js'), 'w').write(''' + mergeInto(LibraryManager.library, { + webglAntialiasSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {antialias: true}); + attributes = context.getContextAttributes(); + return attributes.antialias; + }, + webglDepthSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {depth: true}); + attributes = context.getContextAttributes(); + return attributes.depth; + }, + webglStencilSupported: function() { + canvas = document.createElement('canvas'); + context = canvas.getContext('experimental-webgl', {stencil: true}); + attributes = context.getContextAttributes(); + return attributes.stencil; + } + }); + ''') + + # Copy common code file to temporary directory + filepath = path_from_root('tests/test_webgl_context_attributes_common.c') + temp_filepath = os.path.join(self.get_dir(), os.path.basename(filepath)) + shutil.copyfile(filepath, temp_filepath) + + # perform tests with attributes activated + self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED']) + + # perform tests with attributes desactivated + self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js']) + def test_emscripten_get_now(self): self.btest('emscripten_get_now.cpp', '1') @@ -942,6 +984,11 @@ keydown(100);keyup(100); // trigger the end Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?1') + def test_sdl_canvas_size(self): + self.btest('sdl_canvas_size.c', reference='screenshot-gray-purple.png', reference_slack=1, + args=['-O2', '--minify', '0', '--shell-file', path_from_root('tests', 'sdl_canvas_size.html'), '--preload-file', path_from_root('tests', 'screenshot.png') + '@/', '-s', 'LEGACY_GL_EMULATION=1'], + message='You should see an image with gray at the top.') + def test_sdl_gl_read(self): # SDL, OpenGL, readPixels open(os.path.join(self.get_dir(), 'sdl_gl_read.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_gl_read.c')).read())) diff --git a/tests/test_core.py b/tests/test_core.py index 69fb31f3..c196adf3 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -2949,6 +2949,23 @@ Exiting setjmp function, level: 0, prev_jmp: -1 ''' self.do_run(src, '3.14159') + def test_iswdigit(self): + if self.emcc_args is None: return self.skip('no libcxx inclusion without emcc') + + src = ''' + #include <stdio.h> + #include <cctype> + #include <cwctype> + + int main() { + using namespace std; + printf("%d ", isdigit('0')); + printf("%d ", iswdigit(L'0')); + return 0; + } + ''' + self.do_run(src, '1 1') + def test_polymorph(self): if self.emcc_args is None: return self.skip('requires emcc') src = ''' @@ -7268,6 +7285,18 @@ date: 18.07.2013w; day 18, month 7, year 2013, extra: 201, 3 ''' self.do_run(src, '4779 4779') + def test_sscanf_float(self): + src = r''' + #include "stdio.h" + + int main(){ + float f1, f2, f3, f4, f5, f6, f7, f8, f9; + sscanf("0.512 0.250x5.129_-9.98 1.12*+54.32E3 +54.32E3^87.5E-3 87.5E-3$", "%f %fx%f_%f %f*%f %f^%f %f$", &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9); + printf("\n%f, %f, %f, %f, %f, %f, %f, %f, %f\n", f1, f2, f3, f4, f5, f6, f7, f8, f9); + } + ''' + self.do_run(src, '\n0.512000, 0.250000, 5.129000, -9.980000, 1.120000, 54320.000000, 54320.000000, 0.087500, 0.087500\n') + def test_langinfo(self): src = open(path_from_root('tests', 'langinfo', 'test.c'), 'r').read() expected = open(path_from_root('tests', 'langinfo', 'output.txt'), 'r').read() @@ -8631,6 +8660,122 @@ void*:16 main = main[:main.find('\n}')] assert main.count('\n') == 7, 'must not emit too many postSets: %d' % main.count('\n') + def test_simd(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2') + if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate + src = r''' +#include <stdio.h> + +#include <emscripten/vector.h> + +static inline float32x4 __attribute__((always_inline)) +_mm_set_ps(const float __Z, const float __Y, const float __X, const float __W) +{ + return (float32x4){ __W, __X, __Y, __Z }; +} + +static __inline__ float32x4 __attribute__((__always_inline__)) +_mm_setzero_ps(void) +{ + return (float32x4){ 0.0, 0.0, 0.0, 0.0 }; +} + +int main(int argc, char **argv) { + float data[8]; + for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc); + { + float32x4 *a = (float32x4*)&data[0]; + float32x4 *b = (float32x4*)&data[4]; + float32x4 c, d; + c = *a; + d = *b; + printf("1floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + c = c+d; + printf("2floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + d = c*d; + printf("3floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + c = _mm_setzero_ps(); + printf("zeros %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3]); + } + { + uint32x4 *a = (uint32x4*)&data[0]; + uint32x4 *b = (uint32x4*)&data[4]; + uint32x4 c, d, e, f; + c = *a; + d = *b; + printf("4uints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]); + e = c+d; + f = c-d; + printf("5uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]); + } + { + float32x4 c, d, e, f; + c = _mm_set_ps(9.0, 4.0, 0, -9.0); + d = _mm_set_ps(10.0, 14.0, -12, -2.0); + printf("6floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); + printf("7calcs: %d\n", emscripten_float32x4_signmask(c)); // TODO: just not just compilation but output as well + } + + return 0; +} + ''' + + self.do_run(src, '''1floats! 6, 12, 20, 30 42, 56, 72, 90 +2floats! 48, 68, 92, 120 42, 56, 72, 90 +3floats! 48, 68, 92, 120 2016, 3808, 6624, 10800 +zeros 0, 0, 0, 0 +4uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736 +5uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056 +6floats! -9, 0, 4, 9 -2, -12, 14, 10 +''') + + def test_simd2(self): + if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate + + self.do_run(r''' + #include <stdio.h> + + typedef float __m128 __attribute__ ((__vector_size__ (16))); + + static inline __m128 __attribute__((always_inline)) + _mm_set_ps(const float __Z, const float __Y, const float __X, const float __W) + { + return (__m128){ __W, __X, __Y, __Z }; + } + + static inline void __attribute__((always_inline)) + _mm_store_ps(float *__P, __m128 __A) + { + *(__m128 *)__P = __A; + } + + static inline __m128 __attribute__((always_inline)) + _mm_add_ps(__m128 __A, __m128 __B) + { + return __A + __B; + } + + using namespace std; + + int main(int argc, char ** argv) { + float __attribute__((__aligned__(16))) ar[4]; + __m128 v1 = _mm_set_ps(9.0, 4.0, 0, -9.0); + __m128 v2 = _mm_set_ps(7.0, 3.0, 2.5, 1.0); + __m128 v3 = _mm_add_ps(v1, v2); + _mm_store_ps(ar, v3); + + for (int i = 0; i < 4; i++) { + printf("%f\n", ar[i]); + } + + return 0; + } + ''', '''-8.000000 +2.500000 +7.000000 +16.000000 +''') + def test_gcc_unmangler(self): Settings.NAMED_GLOBALS = 1 # test coverage for this @@ -9044,6 +9189,9 @@ def process(filename): if '_noasm' in shortname and Settings.ASM_JS: print self.skip('case "%s" not relevant for asm.js' % shortname) continue + if '_le32' in shortname and not self.is_le32(): + print self.skip('case "%s" not relevant for non-le32 target' % shortname) + continue self.emcc_args = emcc_args if os.path.exists(shortname + '.emcc'): if not self.emcc_args: continue diff --git a/tests/test_other.py b/tests/test_other.py index e251da5d..86e0eadf 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2015,47 +2015,3 @@ a(int [32], char [5]*) Popen([PYTHON, EMCC, path_from_root('tests', 'linpack.c'), '-O2', '-DSP', '--llvm-opts', '''['-O3', '-vectorize', '-vectorize-loops', '-bb-vectorize-vector-bits=128', '-force-vector-width=4']''']).communicate() self.assertContained('Unrolled Single Precision', run_js('a.out.js')) - def test_simd2(self): - self.clear() - open('src.cpp', 'w').write(r''' -#include <stdio.h> - -#include <emscripten/vector.h> - -int main(int argc, char **argv) { - float data[8]; - for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc); - { - float32x4 *a = (float32x4*)&data[0]; - float32x4 *b = (float32x4*)&data[4]; - float32x4 c, d; - c = *a; - d = *b; - printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); - c = c+d; - printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); - d = c*d; - printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]); - } - { - uint32x4 *a = (uint32x4*)&data[0]; - uint32x4 *b = (uint32x4*)&data[4]; - uint32x4 c, d, e, f; - c = *a; - d = *b; - printf("uints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]); - e = c+d; - f = c-d; - printf("uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]); - } - return 0; -} - ''') - Popen([PYTHON, EMCC, 'src.cpp', '-O2']).communicate() - self.assertContained('''floats! 6, 12, 20, 30 42, 56, 72, 90 -floats! 48, 68, 92, 120 42, 56, 72, 90 -floats! 48, 68, 92, 120 2016, 3808, 6624, 10800 -uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736 -uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056 -''', run_js('a.out.js')) - diff --git a/tests/test_webgl_context_attributes_common.c b/tests/test_webgl_context_attributes_common.c new file mode 100644 index 00000000..7131203b --- /dev/null +++ b/tests/test_webgl_context_attributes_common.c @@ -0,0 +1,262 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#include <emscripten.h> + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +static const int WINDOWS_SIZE = 500; + +static GLfloat vertices[] = { 0.0f, 250.f, 0.0f, + -250.f, -250.f, 0.0f, + 250.f, -250.f, 0.0f }; + +static GLfloat vertices2[] = { 0.0f, 250.f, -1.0f, + -250.f, -250.f, -1.0f, + 250.f, -250.f, -1.0f }; + +static GLuint shaderProgram = 0; +static GLuint verticesVBO = 0; +static GLuint verticesVBO2 = 0; + +static unsigned char backgroundColor[4] = {255, 255, 255, 255}; +static unsigned char triangleColor[4] = {255, 0, 0, 255}; +static unsigned char triangleColor2[4] = {0, 255, 0, 255}; + +static char vertexShaderSrc[] = + "precision highp float;" + "precision highp int;" + + "uniform mat4 u_mvpMatrix;" + "uniform vec4 u_color;" + + "attribute vec3 a_position;" + + "varying vec4 v_color;" + + "void main() {" + " gl_Position = u_mvpMatrix * vec4(a_position, 1.0);" + " v_color = u_color;" + "}" + ; + +static char fragmentShaderSrc[] = + "precision highp float;" + "precision highp int;" + + "varying vec4 v_color;" + + "void main() {" + " gl_FragColor = v_color;" + "}" + ; + +static GLuint createShader(const char *source, int type) { + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, (const GLchar**)(&source), NULL); + glCompileShader(shader); + return shader; +} + +static GLuint createShaderProgram(const char *vertexShaderSrc, const char *fragmentShaderSrc) { + GLuint program = glCreateProgram(); + glAttachShader(program, createShader(vertexShaderSrc, GL_VERTEX_SHADER)); + glAttachShader(program, createShader(fragmentShaderSrc, GL_FRAGMENT_SHADER)); + glLinkProgram(program); + return program; +} + +void ortho(float left, float right, float bottom, float top, float nearVal, float farVal, GLfloat *projMatrix) { + float tx = -(right+left)/(right-left); + float ty = -(top+bottom)/(top-bottom); + float tz = -(farVal+nearVal)/(farVal-nearVal); + memset(projMatrix, 0, 16 * sizeof(GLfloat)); + projMatrix[0] = 2.0f / (right-left); + projMatrix[3] = tx; + projMatrix[1*4+1] = 2.0f / (top-bottom); + projMatrix[1*4+3] = ty; + projMatrix[2*4+2] = -2.0f / (farVal-nearVal); + projMatrix[2*4+3] = tz; + projMatrix[3*4+3] = 1.0f; +} + +static void initGlObjects() { + glGenBuffers(1, &verticesVBO); + glBindBuffer(GL_ARRAY_BUFFER, verticesVBO); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGenBuffers(1, &verticesVBO2); + glBindBuffer(GL_ARRAY_BUFFER, verticesVBO2); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices2, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + shaderProgram = createShaderProgram(vertexShaderSrc, fragmentShaderSrc); +} + +static void drawTriangle(GLuint verticesVBO, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + glUseProgram(shaderProgram); + GLuint posLoc = glGetAttribLocation(shaderProgram, "a_position"); + GLuint mvpLoc = glGetUniformLocation(shaderProgram, "u_mvpMatrix"); + GLuint colorLoc = glGetUniformLocation(shaderProgram, "u_color"); + + GLfloat mvpMat[16]; + ortho(-WINDOWS_SIZE/2, WINDOWS_SIZE/2, -WINDOWS_SIZE/2, WINDOWS_SIZE/2, -100, 100, mvpMat); + + glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat); + glUniform4f(colorLoc, r/255.f, g/255.f, b/255.f, a/255.f); + + glBindBuffer(GL_ARRAY_BUFFER, verticesVBO); + glEnableVertexAttribArray(posLoc); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), BUFFER_OFFSET(0)); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glBindBuffer(GL_ARRAY_B |