Rework testing of trimming of operations with no side effects
authorCarl Worth <cworth@cworth.org>
Sat, 16 Feb 2013 01:19:57 +0000 (17:19 -0800)
committerCarl Worth <cworth@cworth.org>
Fri, 12 Apr 2013 21:27:06 +0000 (14:27 -0700)
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
cli/CMakeLists.txt
cli/cli-trim-no-side-effects-prune-and-trim.script [new file with mode: 0644]
cli/cli-trim-no-side-effects-prune.script [new file with mode: 0644]
cli/cli-trim-no-side-effects-trim.script [new file with mode: 0644]
cli/cli-trim-spec-no-side-effects.script [deleted file]
cli/few-side-effects.trace [new file with mode: 0644]
cli/src/.gitignore
cli/src/Makefile
cli/src/few-side-effects.c [new file with mode: 0644]

index cc6da65af387e504aa33df663c6c589323e32cc5..2bbc06b286bc65a2d7069335f1271cf6c29b7d45 100644 (file)
@@ -5,3 +5,4 @@ glxsimple-ref
 glxsimple-out
 glxsimple-trim.trace
 glxsimple-trim-unused-textures.trace
+few-side-effects-trim.trace
index d3aca6ce4e1c417b25fb32f0d7617bd683c2e455..c5776ef5d713865a79db02f7961375e424db826f 100644 (file)
@@ -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 (file)
index 0000000..8d84f0e
--- /dev/null
@@ -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 (file)
index 0000000..9710f1c
--- /dev/null
@@ -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 (file)
index 0000000..179df98
--- /dev/null
@@ -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 (file)
index aa4527c..0000000
+++ /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 (file)
index 0000000..efd9182
Binary files /dev/null and b/cli/few-side-effects.trace differ
index db85a30816d05f35d299970486a2efed25f0570a..8a76f3cf69eb850d88477f28845b29e9c1b4afac 100644 (file)
@@ -1,2 +1,3 @@
 *~
 glxsimple
+few-side-effects
index 87102fc4d2ae0809933ad5b606e382ed98ec564e..93ce4aff27ceaebdbbc9c329f73708a79faeb226 100644 (file)
@@ -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 (file)
index 0000000..73374ce
--- /dev/null
@@ -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 <stdio.h>
+
+#include <X11/Xlib.h>
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+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;
+}