From 78f3329f3481c13886be0189c58b98ee29a4c484 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 15 Feb 2013 17:19:57 -0800 Subject: [PATCH] Rework testing of trimming of operations with no side effects The previous test was bogus. The only call it trimmed was glxSwapBuffers which is actually invalid, (this call definitely does have side effects, but can easily be trimmed if desired with --trim-spec=drawing). The new testing here uses a trace from a new program, (source included), called few-side-effects which simply makes various calls that do not have side effects, (such as glGetIntegerv and glIsEnabled). Then, the testing exercises the two independent mechanisms available for trimming calls without side effects: trim --prune Trims calls within the user-specified range without side effects. trim --deps --trim-spec=no-side-effects Trims calls outside the user-specific range without side effects. Three new tests are added here, one for each of the above cases and one for both combined, (prune, trim, and prune-and-trim). --- cli/.gitignore | 1 + cli/CMakeLists.txt | 4 +- ...trim-no-side-effects-prune-and-trim.script | 39 ++++ cli/cli-trim-no-side-effects-prune.script | 33 +++ cli/cli-trim-no-side-effects-trim.script | 36 ++++ cli/cli-trim-spec-no-side-effects.script | 97 --------- cli/few-side-effects.trace | Bin 0 -> 57235 bytes cli/src/.gitignore | 1 + cli/src/Makefile | 2 +- cli/src/few-side-effects.c | 188 ++++++++++++++++++ 10 files changed, 302 insertions(+), 99 deletions(-) create mode 100644 cli/cli-trim-no-side-effects-prune-and-trim.script create mode 100644 cli/cli-trim-no-side-effects-prune.script create mode 100644 cli/cli-trim-no-side-effects-trim.script delete mode 100644 cli/cli-trim-spec-no-side-effects.script create mode 100644 cli/few-side-effects.trace create mode 100644 cli/src/few-side-effects.c diff --git a/cli/.gitignore b/cli/.gitignore index cc6da65..2bbc06b 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -5,3 +5,4 @@ glxsimple-ref glxsimple-out glxsimple-trim.trace glxsimple-trim-unused-textures.trace +few-side-effects-trim.trace diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index d3aca6c..c5776ef 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -24,11 +24,13 @@ endfunction () add_cli_test(NAME "cli-diff-images.script") add_cli_test(NAME "cli-diff-images-mismatch.script") +add_cli_test(NAME "cli-trim-no-side-effects-prune.script") +add_cli_test(NAME "cli-trim-no-side-effects-trim.script") +add_cli_test(NAME "cli-trim-no-side-effects-prune-and-trim.script") add_cli_test(NAME "cli-trim-single-swapbuffers.script") add_cli_test(NAME "cli-trim-unused-textures.script") add_cli_test(NAME "cli-trim-unused-shaders.script") add_cli_test(NAME "cli-trim-spec-all.script") -add_cli_test(NAME "cli-trim-spec-no-side-effects.script") add_cli_test(NAME "cli-trim-spec-textures.script") add_cli_test(NAME "cli-trim-spec-shaders.script") add_cli_test(NAME "cli-trim-spec-drawing.script") diff --git a/cli/cli-trim-no-side-effects-prune-and-trim.script b/cli/cli-trim-no-side-effects-prune-and-trim.script new file mode 100644 index 0000000..8d84f0e --- /dev/null +++ b/cli/cli-trim-no-side-effects-prune-and-trim.script @@ -0,0 +1,39 @@ +# Verify that "trim --trim-spec=no-side-effects" can be used in +# concert with --prune. This is effectively the union of the behavior +# in the other tests: cli-trim-no-side-effects-prune and +# cli-trim-no-side-effects-trim. + +# Trim trace to frame 1. Use --trim-spec=no-side-effects to drop calls +# in frame 0 with no side effects, and use --prunt to drop calls in +# frame 1 with no side effects. + +apitrace trim --prune --deps --trim-spec=no-side-effects --frames=1 few-side-effects.trace + +# Verify that we actually trimmed what we wanted to (just calls with +# no side effects) + +apitrace diff --diff=python few-side-effects.trace few-side-effects-trim.trace +expect r""" glXChooseVisual(31941248, 0, (GLX_RGBA, GLX_RED_SIZE, GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_RED_SIZE, GLX_BLUE_SIZE, GLX_RED_SIZE, GLX_ALPHA_SIZE, GLX_RED_SIZE, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, GLX_RED_SIZE, GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR, 0)) = ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]) + glXCreateContext(31941248, ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]), 0, True) = 32022336 + glXMakeCurrent(31941248, 60817409, 32022336) = True +- glXQueryVersion(31941248, (1), (4)) = True + glViewport(0, 0, 64, 64) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(0.0, 64.0, 64.0, 0.0, 0.0, 1.0) + glMatrixMode(GL_MODELVIEW) +- glGetIntegerv(GL_LINE_WIDTH, (1)) +- glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) +- glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) +- glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXSwapBuffers(31941248, 60817409) +- glGetIntegerv(GL_LINE_WIDTH, (1)) +- glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) +- glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) +- glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXDestroyContext(31941248, 32022336) +""" diff --git a/cli/cli-trim-no-side-effects-prune.script b/cli/cli-trim-no-side-effects-prune.script new file mode 100644 index 0000000..9710f1c --- /dev/null +++ b/cli/cli-trim-no-side-effects-prune.script @@ -0,0 +1,33 @@ +# Verify that "trim --prune" drops calls with no side effects + +# Tell trim to trim to the entire trace, but pruning calls +apitrace trim --prune few-side-effects.trace + +# Verify that we actually trimmed what we wanted to (just calls with +# no side effects) + +apitrace diff --diff=python few-side-effects.trace few-side-effects-trim.trace +expect r""" glXChooseVisual(31941248, 0, (GLX_RGBA, GLX_RED_SIZE, GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_RED_SIZE, GLX_BLUE_SIZE, GLX_RED_SIZE, GLX_ALPHA_SIZE, GLX_RED_SIZE, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, GLX_RED_SIZE, GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR, 0)) = ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]) + glXCreateContext(31941248, ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]), 0, True) = 32022336 + glXMakeCurrent(31941248, 60817409, 32022336) = True +- glXQueryVersion(31941248, (1), (4)) = True + glViewport(0, 0, 64, 64) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(0.0, 64.0, 64.0, 0.0, 0.0, 1.0) + glMatrixMode(GL_MODELVIEW) +- glGetIntegerv(GL_LINE_WIDTH, (1)) +- glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) +- glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) +- glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXSwapBuffers(31941248, 60817409) +- glGetIntegerv(GL_LINE_WIDTH, (1)) +- glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) +- glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) +- glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXDestroyContext(31941248, 32022336) +""" diff --git a/cli/cli-trim-no-side-effects-trim.script b/cli/cli-trim-no-side-effects-trim.script new file mode 100644 index 0000000..179df98 --- /dev/null +++ b/cli/cli-trim-no-side-effects-trim.script @@ -0,0 +1,36 @@ +# Verify that trim can be used to drop calls outside the specified range +# that have no side effects. + +# Trim trace to frame 1, but dropping calls from first frame 0 with no +# side effects. + +apitrace trim --deps --trim-spec=no-side-effects --frames=1 few-side-effects.trace + +# Verify that we actually trimmed what we wanted to (just calls with +# no side effects) + +apitrace diff --diff=python few-side-effects.trace few-side-effects-trim.trace +expect r""" glXChooseVisual(31941248, 0, (GLX_RGBA, GLX_RED_SIZE, GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_RED_SIZE, GLX_BLUE_SIZE, GLX_RED_SIZE, GLX_ALPHA_SIZE, GLX_RED_SIZE, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, GLX_RED_SIZE, GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR, 0)) = ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]) + glXCreateContext(31941248, ([31985400, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]), 0, True) = 32022336 + glXMakeCurrent(31941248, 60817409, 32022336) = True +- glXQueryVersion(31941248, (1), (4)) = True + glViewport(0, 0, 64, 64) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(0.0, 64.0, 64.0, 0.0, 0.0, 1.0) + glMatrixMode(GL_MODELVIEW) +- glGetIntegerv(GL_LINE_WIDTH, (1)) +- glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) +- glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) +- glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXSwapBuffers(31941248, 60817409) + glGetIntegerv(GL_LINE_WIDTH, (1)) + glGetIntegerv(GL_LOGIC_OP_MODE, (5379)) + glIsEnabled(GL_BLEND) = GL_FALSE + glEnable(GL_BLEND) + glIsEnabled(GL_BLEND) = GL_TRUE + glDisable(GL_BLEND) + glXDestroyContext(31941248, 32022336) +""" diff --git a/cli/cli-trim-spec-no-side-effects.script b/cli/cli-trim-spec-no-side-effects.script deleted file mode 100644 index aa4527c..0000000 --- a/cli/cli-trim-spec-no-side-effects.script +++ /dev/null @@ -1,97 +0,0 @@ -# Trim trace to the final glxDestroyContext, eliminating almost everything - -apitrace trim --auto --trim-spec=no-side-effects --calls=88 glxsimple.trace - -# Verify that we actually trimmed what we wanted to (just calls with no side effects) - -apitrace diff --diff=python glxsimple.trace glxsimple-trim.trace -expect r""" glXChooseVisual(37134976, 0, (GLX_RGBA, GLX_RED_SIZE, GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_RED_SIZE, GLX_BLUE_SIZE, GLX_RED_SIZE, GLX_ALPHA_SIZE, GLX_RED_SIZE, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, GLX_RED_SIZE, GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR, 0)) = ([37179128, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]) - glXCreateContext(37134976, ([37179128, 34, 0, 24, 5, 16711680, 65280, 255, 256, 8]), 0, True) = 37241648 - glXMakeCurrent(37134976, 41943041, 37241648) = True - glViewport(0, 0, 64, 64) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glOrtho(0.0, 64.0, 64.0, 0.0, 0.0, 1.0) - glMatrixMode(GL_MODELVIEW) - glClearColor(0.0, 0.0, 1.0, 1.0) - glClear((GL_COLOR_BUFFER_BIT)) -- glXSwapBuffers(37134976, 41943041) - glCreateShader(GL_VERTEX_SHADER) = 7 - glShaderSource(7, 1, ('void main()\n{\n gl_Position = ftransform();\n}\n'), 0) - glCompileShader(7) - glCreateShader(GL_FRAGMENT_SHADER) = 8 - glShaderSource(8, 1, ('#version 120\nuniform vec4 color;\nvoid main()\n{\n gl_FragColor = color;\n}\n'), 0) - glCompileShader(8) - glCreateProgram() = 9 - glAttachShader(9, 7) - glAttachShader(9, 8) - glLinkProgram(9) - glUseProgram(9) - glGetUniformLocation(9, color) = 0 - glUniform4f(0, 0.0, 1.0, 0.0, 1.0) - glBegin(GL_QUADS) - glVertex2f(0.0, 0.0) - glVertex2f(64.0, 0.0) - glVertex2f(64.0, 64.0) - glVertex2f(0.0, 64.0) - glEnd() - glUseProgram(0) -- glXSwapBuffers(37134976, 41943041) - glGenTextures(1, (1)) - glBindTexture(GL_TEXTURE_2D, 1) - glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, blob(3)) - glEnable(GL_TEXTURE_2D) - glBegin(GL_QUADS) - glTexCoord2f(0.0, 0.0) - glVertex2f(0.0, 0.0) - glTexCoord2f(1.0, 0.0) - glVertex2f(64.0, 0.0) - glTexCoord2f(1.0, 1.0) - glVertex2f(64.0, 64.0) - glTexCoord2f(0.0, 1.0) - glVertex2f(0.0, 64.0) - glEnd() - glDisable(GL_TEXTURE_2D) -- glXSwapBuffers(37134976, 41943041) - glClearColor(1.0, 0.0, 0.0, 1.0) - glClear((GL_COLOR_BUFFER_BIT)) -- glXSwapBuffers(37134976, 41943041) - glCreateShader(GL_VERTEX_SHADER) = 10 - glShaderSource(10, 1, ('void main()\n{\n gl_Position = ftransform();\n}\n'), 0) - glCompileShader(10) - glCreateShader(GL_FRAGMENT_SHADER) = 11 - glShaderSource(11, 1, ('#version 120\nuniform vec4 color;\nvoid main()\n{\n gl_FragColor = color;\n}\n'), 0) - glCompileShader(11) - glCreateProgram() = 12 - glAttachShader(12, 10) - glAttachShader(12, 11) - glLinkProgram(12) - glUseProgram(12) - glGetUniformLocation(12, color) = 0 - glUniform4f(0, 1.0, 0.0, 1.0, 1.0) - glBegin(GL_QUADS) - glVertex2f(0.0, 0.0) - glVertex2f(64.0, 0.0) - glVertex2f(64.0, 64.0) - glVertex2f(0.0, 64.0) - glEnd() - glUseProgram(0) -- glXSwapBuffers(37134976, 41943041) - glGenTextures(1, (2)) - glBindTexture(GL_TEXTURE_2D, 2) - glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, blob(3)) - glEnable(GL_TEXTURE_2D) - glBegin(GL_QUADS) - glTexCoord2f(0.0, 0.0) - glVertex2f(0.0, 0.0) - glTexCoord2f(1.0, 0.0) - glVertex2f(64.0, 0.0) - glTexCoord2f(1.0, 1.0) - glVertex2f(64.0, 64.0) - glTexCoord2f(0.0, 1.0) - glVertex2f(0.0, 64.0) - glEnd() - glDisable(GL_TEXTURE_2D) -- glXSwapBuffers(37134976, 41943041) - glXDestroyContext(37134976, 37241648) -""" diff --git a/cli/few-side-effects.trace b/cli/few-side-effects.trace new file mode 100644 index 0000000000000000000000000000000000000000..efd918232a53d77833c1f228707b48d4bab26a75 GIT binary patch literal 57235 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 Kgu?-(6a7C3it=9o literal 0 HcmV?d00001 diff --git a/cli/src/.gitignore b/cli/src/.gitignore index db85a30..8a76f3c 100644 --- a/cli/src/.gitignore +++ b/cli/src/.gitignore @@ -1,2 +1,3 @@ *~ glxsimple +few-side-effects diff --git a/cli/src/Makefile b/cli/src/Makefile index 87102fc..93ce4af 100644 --- a/cli/src/Makefile +++ b/cli/src/Makefile @@ -1,4 +1,4 @@ -PROGS=glxsimple +PROGS=glxsimple few-side-effects all: $(PROGS) diff --git a/cli/src/few-side-effects.c b/cli/src/few-side-effects.c new file mode 100644 index 0000000..73374ce --- /dev/null +++ b/cli/src/few-side-effects.c @@ -0,0 +1,188 @@ +/************************************************************************** + * Copyright 2012 Intel corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +int width = 64; +int height = 64; + +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +static void +set_2d_projection (void) +{ + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, width, height, 0, 0, 1); + glMatrixMode (GL_MODELVIEW); +} + +static void +draw (Display *dpy, Window window, int width, int height) +{ + GLenum glew_err; + int visual_attr[] = { + GLX_RGBA, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + GLX_X_VISUAL_TYPE, GLX_DIRECT_COLOR, + None + }; + + /* Window and context setup. */ + XVisualInfo *visual_info = glXChooseVisual(dpy, 0, visual_attr); + GLXContext ctx = glXCreateContext(dpy, visual_info, NULL, True); + glXMakeCurrent(dpy, window, ctx); + + glew_err = glewInit(); + if (glew_err != GLEW_OK) + { + fprintf (stderr, "glewInit failed: %s\n", + glewGetErrorString(glew_err)); + exit (1); + } + + glViewport(0, 0, width, height); + + set_2d_projection (); + + /* Frame 1. Perform a few operations, most without side effects. */ + { + GLint line_width UNUSED, logic_op UNUSED; + GLboolean blend_enabled UNUSED; + + glGetIntegerv(GL_LINE_WIDTH, &line_width); + glGetIntegerv(GL_LOGIC_OP_MODE, &logic_op); + + blend_enabled = glIsEnabled(GL_BLEND); + + glEnable(GL_BLEND); + + blend_enabled = glIsEnabled(GL_BLEND); + + glDisable(GL_BLEND); + } + + glXSwapBuffers (dpy, window); + /* Frame 2. Again, more operations, most with side effects. */ + { + GLint line_width UNUSED, logic_op UNUSED; + GLboolean blend_enabled UNUSED; + + glGetIntegerv(GL_LINE_WIDTH, &line_width); + glGetIntegerv(GL_LOGIC_OP_MODE, &logic_op); + + blend_enabled = glIsEnabled(GL_BLEND); + + glEnable(GL_BLEND); + + blend_enabled = glIsEnabled(GL_BLEND); + + glDisable(GL_BLEND); + } + + /* Cleanup */ + glXDestroyContext (dpy, ctx); +} + +static void +handle_events(Display *dpy, Window window, int width, int height) +{ + XEvent xev; + KeyCode quit_code = XKeysymToKeycode (dpy, XStringToKeysym("Q")); + + XNextEvent (dpy, &xev); + + while (1) { + XNextEvent (dpy, &xev); + switch (xev.type) { + case KeyPress: + if (xev.xkey.keycode == quit_code) { + return; + } + break; + case ConfigureNotify: + width = xev.xconfigure.width; + height = xev.xconfigure.height; + break; + case Expose: + if (xev.xexpose.count == 0) { + draw (dpy, window, width, height); + return; + } + break; + } + } +} + +int +main (void) +{ + Display *dpy; + Window window; + + dpy = XOpenDisplay (NULL); + + if (dpy == NULL) { + fprintf(stderr, "Failed to open display %s\n", + XDisplayName(NULL)); + return 1; + } + + window = XCreateSimpleWindow(dpy, DefaultRootWindow (dpy), + 0, 0, width, height, 0, + BlackPixel (dpy, DefaultScreen (dpy)), + BlackPixel (dpy, DefaultScreen (dpy))); + + XSelectInput(dpy, window, + KeyPressMask | StructureNotifyMask | ExposureMask); + + XMapWindow (dpy, window); + + handle_events (dpy, window, width, height); + + XDestroyWindow (dpy, window); + XCloseDisplay (dpy); + + return 0; +} -- 2.43.0