]> git.cworth.org Git - apitrace/commitdiff
Merge branch 'directxtex'
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 6 Mar 2013 11:46:41 +0000 (11:46 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 6 Mar 2013 11:46:41 +0000 (11:46 +0000)
92 files changed:
CMakeLists.txt
INSTALL.markdown
NEWS.markdown
README.markdown
cli/CMakeLists.txt
cli/cli_dump_images.cpp
cli/cli_main.cpp
cli/cli_retrace.cpp
cli/cli_trace.cpp
cli/cli_trim.cpp
cli/trace_analyzer.cpp [new file with mode: 0644]
cli/trace_analyzer.hpp [new file with mode: 0644]
common/os_memory.hpp [new file with mode: 0644]
common/os_thread.hpp
common/trace_callset.cpp
common/trace_callset.hpp
common/trace_parser.cpp
common/trace_parser_flags.cpp
common/trace_profiler.cpp
common/trace_profiler.hpp
dispatch/d3d8imports.hpp [new file with mode: 0644]
dispatch/d3d9imports.hpp
dispatch/dxgiint.h
dispatch/dxvaint.h
dispatch/eglimports.hpp
gui/apitrace.cpp
gui/graphing/histogramview.cpp
gui/main.cpp
gui/mainwindow.cpp
gui/mainwindow.h
gui/retracer.cpp
gui/retracer.h
gui/tracedialog.cpp
gui/traceprocess.cpp
gui/trimprocess.cpp
gui/ui/mainwindow.ui
gui/ui/tracedialog.ui
helpers/d3dcommonsize.hpp
helpers/glsize.hpp
inject/inject.h
inject/injectee.cpp
inject/injector.cpp
retrace/CMakeLists.txt
retrace/d3d8state.cpp [new file with mode: 0644]
retrace/d3d8state_images.cpp [new file with mode: 0644]
retrace/d3d9retrace.py
retrace/d3d9state_images.cpp
retrace/d3dretrace_dxgi.hpp [new file with mode: 0644]
retrace/d3dstate.hpp
retrace/dxgiretrace.py
retrace/glretrace.hpp
retrace/glretrace_cgl.cpp
retrace/glretrace_main.cpp
retrace/glstate.cpp
retrace/glstate_images.cpp
retrace/glstate_internal.hpp
retrace/glstate_params.py
retrace/retrace.hpp
retrace/retrace.py
retrace/retrace_main.cpp
retrace/scoped_allocator.hpp [new file with mode: 0644]
scripts/apitrace.PIXExp [new file with mode: 0644]
scripts/convert.py [new file with mode: 0755]
specs/cglapi.py
specs/d3d9dxva2.py
specs/d3d9types.py
specs/glparams.py
specs/stdapi.py
specs/winapi.py
thirdparty/getopt/CMakeLists.txt
thirdparty/getopt/LICENSE [new file with mode: 0644]
thirdparty/less/CMakeLists.txt
thirdparty/libpng/CMakeLists.txt
thirdparty/msinttypes/.gitignore [new file with mode: 0644]
thirdparty/msinttypes/LICENSE [new file with mode: 0644]
thirdparty/msinttypes/Makefile [new file with mode: 0644]
thirdparty/msinttypes/inttypes.h [new file with mode: 0644]
thirdparty/msinttypes/stdbool.h [new file with mode: 0644]
thirdparty/msinttypes/stdint.h [new file with mode: 0644]
thirdparty/msvc/.gitignore [deleted file]
thirdparty/msvc/Makefile [deleted file]
thirdparty/msvc/inttypes.h [deleted file]
thirdparty/msvc/stdbool.h [deleted file]
thirdparty/msvc/stdint.h [deleted file]
thirdparty/qjson/CMakeLists.txt
thirdparty/snappy/CMakeLists.txt
thirdparty/zlib/CMakeLists.txt
wrappers/d3d8trace.py
wrappers/dxgitrace.py
wrappers/gltrace.py
wrappers/gltrace_state.cpp
wrappers/trace.py

index 46514aaf31934c2e1f53ff8c9e05f88f60d9bff4..3b932e1459cc3aa41300e849b1e335af83a38d09 100644 (file)
@@ -106,8 +106,8 @@ else (WIN32)
 endif ()
 
 if (MSVC)
-    # C99 includes for msvc
-    include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/msvc)
+    # C99 includes for MSVC
+    include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/msinttypes)
 
     # Enable math constants defines
     add_definitions (-D_USE_MATH_DEFINES)
@@ -181,6 +181,42 @@ endif ()
 set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 
 
+##############################################################################
+# Installation directories
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+    # Debian multiarch support
+    execute_process(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
+        OUTPUT_VARIABLE ARCH_SUBDIR
+        ERROR_QUIET
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+    CHECK_INCLUDE_FILES(proc/readproc.h READPROC_H_FOUND)
+    if (READPROC_H_FOUND)
+        add_definitions (-DHAVE_READPROC_H)
+    endif ()
+endif()
+
+if (WIN32 OR APPLE)
+    # On Windows/MacOSX, applications are usually installed on a directory of
+    # their own
+    set (DOC_INSTALL_DIR doc)
+    set (LIB_INSTALL_DIR lib)
+    set (LIB_ARCH_INSTALL_DIR lib)
+else ()
+    set (DOC_INSTALL_DIR share/doc/${CMAKE_PROJECT_NAME})
+    set (LIB_INSTALL_DIR lib/${CMAKE_PROJECT_NAME})
+    if (ARCH_SUBDIR)
+        set (LIB_ARCH_INSTALL_DIR lib/${ARCH_SUBDIR}/${CMAKE_PROJECT_NAME})
+    else ()
+        set (LIB_ARCH_INSTALL_DIR lib/${CMAKE_PROJECT_NAME})
+    endif ()
+endif ()
+
+set (SCRIPTS_INSTALL_DIR ${LIB_INSTALL_DIR}/scripts)
+set (WRAPPER_INSTALL_DIR ${LIB_ARCH_INSTALL_DIR}/wrappers)
+
+
 ##############################################################################
 # Bundled dependencies
 #
@@ -191,13 +227,13 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 
 set (ZLIB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/zlib)
 set (ZLIB_LIBRARIES z_bundled)
-add_subdirectory (thirdparty/zlib EXCLUDE_FROM_ALL)
+add_subdirectory (thirdparty/zlib)
 
 include_directories (${ZLIB_INCLUDE_DIRS})
 
 set (SNAPPY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/snappy)
 set (SNAPPY_LIBRARIES snappy_bundled)
-add_subdirectory (thirdparty/snappy EXCLUDE_FROM_ALL)
+add_subdirectory (thirdparty/snappy)
 
 include_directories (${SNAPPY_INCLUDE_DIRS})
 
@@ -205,10 +241,10 @@ set (PNG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libpng)
 set (PNG_DEFINITIONS "")
 set (PNG_LIBRARIES png_bundled)
 
-add_subdirectory (thirdparty/libpng EXCLUDE_FROM_ALL)
+add_subdirectory (thirdparty/libpng)
 
 if (MSVC)
-    add_subdirectory (thirdparty/getopt EXCLUDE_FROM_ALL)
+    add_subdirectory (thirdparty/getopt)
     include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/getopt)
     set (GETOPT_LIBRARIES getopt_bundled)
 endif ()
@@ -224,7 +260,7 @@ endif ()
 # binaries at all.
 if (QT4_FOUND)
     add_definitions (-DQJSON_EXPORT=)
-    add_subdirectory (thirdparty/qjson EXCLUDE_FROM_ALL)
+    add_subdirectory (thirdparty/qjson)
     set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
     set (QJSON_LIBRARY_DIRS)
     set (QJSON_LIBRARIES qjson_bundled)
@@ -238,51 +274,6 @@ endif ()
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/khronos)
 
 
-##############################################################################
-# Installation directories
-
-if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
-    # Debian multiarch support
-    execute_process(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
-        OUTPUT_VARIABLE ARCH_SUBDIR
-        ERROR_QUIET
-        OUTPUT_STRIP_TRAILING_WHITESPACE
-    )
-endif()
-
-if (WIN32 OR APPLE)
-    # On Windows/MacOSX, applications are usually installed on a directory of
-    # their own
-    set (DOC_INSTALL_DIR doc)
-    set (LIB_INSTALL_DIR lib)
-    set (LIB_ARCH_INSTALL_DIR lib)
-else ()
-    set (DOC_INSTALL_DIR share/doc/${CMAKE_PROJECT_NAME})
-    set (LIB_INSTALL_DIR lib/${CMAKE_PROJECT_NAME})
-    if (ARCH_SUBDIR)
-        set (LIB_ARCH_INSTALL_DIR lib/${ARCH_SUBDIR}/${CMAKE_PROJECT_NAME})
-    else ()
-        set (LIB_ARCH_INSTALL_DIR lib/${CMAKE_PROJECT_NAME})
-    endif ()
-endif ()
-
-set (SCRIPTS_INSTALL_DIR ${LIB_INSTALL_DIR}/scripts)
-set (WRAPPER_INSTALL_DIR ${LIB_ARCH_INSTALL_DIR}/wrappers)
-
-# Expose the binary/install directories to source
-#
-# TODO: Use the same directory layout, for both build and install directories,
-# so that binaries can find each other using just relative paths.
-#
-add_definitions(
-    -DAPITRACE_BINARY_DIR="${CMAKE_BINARY_DIR}"
-    -DAPITRACE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
-    -DAPITRACE_PROGRAMS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/bin"
-    -DAPITRACE_SCRIPTS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${SCRIPTS_INSTALL_DIR}"
-    -DAPITRACE_WRAPPERS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${WRAPPER_INSTALL_DIR}"
-)
-
-
 ##############################################################################
 # Common libraries / utilities
 
@@ -362,11 +353,22 @@ endif ()
 
 install (
     PROGRAMS
-        ${CMAKE_CURRENT_SOURCE_DIR}/scripts/tracediff.py
-        ${CMAKE_CURRENT_SOURCE_DIR}/scripts/jsondiff.py
-        ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snapdiff.py
+        scripts/highlight.py
+        scripts/jsondiff.py
+        scripts/profileshader.py
+        scripts/retracediff.py
+        scripts/snapdiff.py
+        scripts/tracecheck.py
+        scripts/tracediff.py
+        scripts/unpickle.py
     DESTINATION ${SCRIPTS_INSTALL_DIR}
 )
+if (WIN32)
+    install (
+        PROGRAMS scripts/convert.py
+        DESTINATION ${SCRIPTS_INSTALL_DIR}
+    )
+endif ()
 
 ##############################################################################
 # GUI
@@ -382,11 +384,22 @@ endif ()
 install (
     FILES
         BUGS.markdown
-        LICENSE
         NEWS.markdown
         README.markdown
     DESTINATION ${DOC_INSTALL_DIR}
 )
+install (
+    FILES LICENSE
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE.txt
+)
+if (MSVC)
+    install (
+        FILES thirdparty/msinttypes/LICENSE
+        DESTINATION ${DOC_INSTALL_DIR}
+        RENAME LICENSE-msinttypes.txt
+    )
+endif ()
 
 set (CPACK_PACKAGE_VERSION_MAJOR "3")
 set (CPACK_PACKAGE_VERSION_MINOR "0")
index 2228bdff860368cdf72203e97f0b62a54683b736..ed965b104333c349ed45f1c4228f7e4d9bd5f235 100644 (file)
@@ -70,6 +70,10 @@ Build as:
     cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/android.toolchain.cmake -DANDROID_API_LEVEL=9 -H. -Bbuild
     make -C build
 
+You can also choose a particular ABI by passing `ANDROID_ABI` variable to
+cmake, e.g., `-DANDROID_ABI=x86`.
+
+
 Windows
 -------
 
index 53a3f0f3d64208af0bb73bcad49ce7368451cd8d..736ec348c4a6a52947b34f45e32a8fa5c9ff2c94 100644 (file)
@@ -17,7 +17,7 @@ Version 3.0
 
 * Top-level `apitrace` command.
 
-* Trace and retrace support for EGL, GLES1, and GLES2 APIs on Linux.
+* Trace and replay support for EGL, GLES1, and GLES2 APIs on Linux.
 
 * Ability to trim traces.
 
@@ -57,4 +57,4 @@ Version 1.0
 Pre-history
 ===========
 
-* OpenGL retrace support.
+* OpenGL replay support.
index b1eb08397aa4bf1a64d1db5b2e7cf3dd11248599..5fa3ab96089b002e13a11e0cb07a35a2c8a9eea0 100644 (file)
@@ -5,7 +5,7 @@ About **apitrace**
 
 * trace OpenGL, OpenGL ES, Direct3D, and DirectDraw APIs calls to a file;
 
-* retrace OpenGL and OpenGL ES calls from a file;
+* replay OpenGL and OpenGL ES calls from a file;
 
 * inspect OpenGL state at any call while retracing;
 
@@ -18,7 +18,7 @@ Obtaining **apitrace**
 ======================
 
 To obtain apitrace either [download the latest
-binaries](https://github.com/apitrace/apitrace/downloads) for your platform if
+binaries](http://apitrace.github.com/#download) for your platform if
 available, or follow the instructions in INSTALL.markdown to build it yourself.
 On 64bits Linux and Windows platforms you'll need apitrace binaries that match
 the architecture (32bits or 64bits) of the application being traced.
@@ -49,10 +49,10 @@ View the trace with
 
 Replay an OpenGL trace with
 
-    apitrace retrace application.trace
+    apitrace replay application.trace
 
 Pass the `--sb` option to use a single buffered visual.  Pass `--help` to
-`apitrace retrace` for more options.
+`apitrace replay` for more options.
 
 
 Basic GUI usage
@@ -152,10 +152,9 @@ To trace the application inside gdb, invoke gdb as:
 ### Android ###
 
 The following instructions should work at least for Android Ice Scream
-Sandwitch:
+Sandwitch.
 
-For standalone applications the instructions above for Linux should
-work. To trace applications started from within the Android VM process
+To trace applications started from within the Android VM process
 (`app_process` aka zygote) you'll have to wrap this process and enable
 tracing dynamically for the application to be traced.
 
@@ -206,6 +205,15 @@ tracing dynamically for the application to be traced.
 
   Launch the application for example from the application menu.
 
+To trace standalone applications do:
+
+    adb push /path/to/apitrace/build/wrappers/egltrace.so /data
+    adb shell
+    # cd /data/local/tmp
+    # LD_PRELOAD=/data/egltrace.so test-opengl-gl2_basic
+    adb pull /data/local/tmp/test-opengl-gl2_basic.trace
+    apitrace replay test-opengl-gl2_basic.trace
+
 ### Mac OS X ###
 
 Run the application you want to trace as
@@ -302,7 +310,7 @@ Dump GL state at a particular call
 
 You can get a dump of the bound GL state at call 12345 by doing:
 
-    apitrace retrace -D 12345 application.trace > 12345.json
+    apitrace replay -D 12345 application.trace > 12345.json
 
 This is precisely the mechanism the GUI obtains its own state.
 
@@ -359,7 +367,7 @@ table which displays profiling results per shader.
 
 For example, to record all profiling data and utilise the per shader script:
 
-    apitrace retrace --pgpu --pcpu --ppd foo.trace | ./scripts/profileshader.py
+    apitrace replay --pgpu --pcpu --ppd foo.trace | ./scripts/profileshader.py
 
 
 Advanced usage for OpenGL implementors
index a01d3aed11e72b0da42276c3552e8935b525787c..5f8e116f5279e385ba1875ed659246bbf2c10d79 100644 (file)
@@ -1,3 +1,14 @@
+# Expose the binary/install directories to source
+#
+# TODO: Use the same directory layout, for both build and install directories,
+# so that binaries can find each other using just relative paths.
+#
+add_definitions(
+    -DAPITRACE_PROGRAMS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/bin"
+    -DAPITRACE_SCRIPTS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${SCRIPTS_INSTALL_DIR}"
+    -DAPITRACE_WRAPPERS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${WRAPPER_INSTALL_DIR}"
+)
+
 add_executable (apitrace
     cli_main.cpp
     cli_diff.cpp
@@ -12,6 +23,7 @@ add_executable (apitrace
     cli_trace.cpp
     cli_trim.cpp
     cli_resources.cpp
+    trace_analyzer.cpp
 )
 
 target_link_libraries (apitrace
index 0e2dd8c8b6cfaf6919253a0ffdc8b841fad1dd5e..86cf75c3e5da122a5fc4f7f0920ec13dfb7427a9 100644 (file)
@@ -29,6 +29,8 @@
 #include <string.h>
 #include <limits.h> // for CHAR_MAX
 #include <getopt.h>
+
+#include <string>
 #include <iostream>
 
 #include "os_string.hpp"
@@ -44,17 +46,20 @@ usage(void)
     std::cout << "usage apitrace dump-images [OPTIONS] TRACE_FILE\n"
               << synopsis << "\n"
         "\n"
-        "    -h, --help           show this help message and exit\n"
-        "        --calls=CALLSET  dump images only for specified calls\n"
-        "                         (default value is \"*/frame\" which\n"
-        "                          which dumps an image for each frame)\n"
-        "    -o, --output=PREFIX  prefix to use in naming output files\n"
-        "                         (default is trace filename without extension)\n"
+        "    -h, --help             show this help message and exit\n"
+        "        --calls=CALLSET    dump images only for specified calls\n"
+        "                           (default value is \"*/frame\" which\n"
+        "                            which dumps an image for each frame)\n"
+        "         --call-nos[=BOOL] use call numbers in image filenames,\n"
+        "                           otherwise use sequental numbers (default=yes)\n"
+        "    -o, --output=PREFIX    prefix to use in naming output files\n"
+        "                           (default is trace filename without extension)\n"
         "\n";
 }
 
 enum {
     CALLS_OPT = CHAR_MAX + 1,
+    CALL_NOS_OPT,
 };
 
 const static char *
@@ -64,6 +69,7 @@ const static struct option
 longOptions[] = {
     {"help", no_argument, 0, 'h'},
     {"calls", required_argument, 0, CALLS_OPT},
+    {"call-nos", optional_argument, 0, CALL_NOS_OPT},
     {"output", required_argument, 0, 'o'},
     {0, 0, 0, 0}
 };
@@ -75,6 +81,7 @@ command(int argc, char *argv[])
     const char *calls = NULL;
     const char *traceName = NULL;
     const char *output = NULL;
+    std::string call_nos;
 
     int opt;
     while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
@@ -85,6 +92,10 @@ command(int argc, char *argv[])
         case CALLS_OPT:
             calls = optarg;
             break;
+        case CALL_NOS_OPT:
+            call_nos = "--call-nos=";
+            call_nos.append(optarg);
+            break;
         case 'o':
             output = optarg;
             break;
@@ -126,6 +137,9 @@ command(int argc, char *argv[])
         opts.push_back(calls);
     else
         opts.push_back("*/frame");
+    if (!call_nos.empty()) {
+        opts.push_back(call_nos.c_str());
+    }
 
     return executeRetrace(opts, traceName);
 }
index 040adcf82928c56f8a35b76617ddeb72b11e1689..d6db6196121b3d5a9a158c29309c1e7f556a02c8 100644 (file)
@@ -79,6 +79,18 @@ static const Command * commands[] = {
     &help_command
 };
 
+/* Aliases provide a mechanism to allow compatibility with old command
+ * names (such as "retrace") for current commands (such as the replay
+ * command). */
+typedef struct {
+    const char *name;
+    const Command *command;
+} Alias;
+
+static const Alias aliases[] = {
+    { "retrace", &retrace_command }
+};
+
 static void
 usage(void)
 {
@@ -151,6 +163,7 @@ main(int argc, char **argv)
 {
     const char *command_name;
     const Command *command;
+    const Alias *alias;
     int i;
 
     for (i = 1; i < argc; ++i) {
@@ -186,6 +199,13 @@ main(int argc, char **argv)
             return (command->function) (argc, argv);
     }
 
+    for (i = 0; i < ARRAY_SIZE(aliases); i++) {
+        alias = &aliases[i];
+
+        if (strcmp(command_name, alias->name) == 0)
+            return (alias->command->function) (argc, argv);
+    }
+
     std::cerr << "Error: unknown command " << command_name
               << " (see \"apitrace help\").\n";
 
index d22f719bd65d6a584c416db6010d558a6a55ac9a..db799b96ba012532ccab46fe633a22f1b7afaf32 100644 (file)
@@ -144,7 +144,7 @@ command(int argc, char *argv[])
 }
 
 const Command retrace_command = {
-    "retrace",
+    "replay",
     synopsis,
     usage,
     command
index 2646ffd8a0190c1bd80b621145c3dd1162efb5e5..f87a383b009cd0c13e29754144b63b13ad16cbfb 100644 (file)
@@ -133,6 +133,7 @@ traceProgram(trace::API api,
     }
 
 #if defined(_WIN32)
+    useInject = true;
     if (useInject) {
         args.push_back("inject");
         args.push_back(wrapperPath);
@@ -219,7 +220,7 @@ usage(void)
         "    -v, --verbose       verbose output\n"
         "    -a, --api=API       specify API to trace ("
 #ifdef _WIN32
-                                                      "gl, d3d7, d3d8, d3d9, or d3d10"
+                                                      "gl, d3d7, d3d8, d3d9, or dxgi (for d3d10 and higher) "
 #else
                                                       "gl or egl"
 #endif
index eea55535e95395f8707afd7f6d1090e6edc873ec..5625a2c4f845ee2e0bccdba1cd24ed42c04b3ddb 100644 (file)
  *
  **************************************************************************/
 
-
+#include <sstream>
 #include <string.h>
 #include <limits.h> // for CHAR_MAX
 #include <getopt.h>
 
+#include <set>
+
 #include "cli.hpp"
 
 #include "os_string.hpp"
 
+#include "trace_analyzer.hpp"
 #include "trace_callset.hpp"
 #include "trace_parser.hpp"
 #include "trace_writer.hpp"
@@ -46,53 +49,350 @@ usage(void)
         << "usage: apitrace trim [OPTIONS] TRACE_FILE...\n"
         << synopsis << "\n"
         "\n"
-        "    -h, --help               show this help message and exit\n"
-        "        --calls=CALLSET      only retain specified calls\n"
-        "        --thread=THREAD_ID   only retain calls from specified thread\n"
-        "    -o, --output=TRACE_FILE  output trace file\n"
+        "    -h, --help               Show detailed help for trim options and exit\n"
+        "        --calls=CALLSET      Include specified calls in the trimmed output.\n"
+        "        --frames=FRAMESET    Include specified frames in the trimmed output.\n"
+        "        --deps               Include additional calls to satisfy dependencies\n"
+        "        --prune              Omit uninteresting calls from the trace output\n"
+        "    -a, --auto               Trim automatically to calls specified in --calls/--frames\n"
+        "                             Equivalent to both --deps and --prune\n"
+        "        --print-callset      Print the final set of calls included in output\n"
+        "        --trim-spec=SPEC     Only performing trimming as described in SPEC\n"
+        "        --thread=THREAD_ID   Only retain calls from specified thread\n"
+        "    -o, --output=TRACE_FILE  Output trace file\n"
+    ;
+}
+
+static void
+help()
+{
+    std::cout
+        << "usage: apitrace trim [OPTIONS] TRACE_FILE...\n"
+        << synopsis << "\n"
+        "\n"
+        "    -h, --help               Show this help message and exit\n"
+        "\n"
+        "        --calls=CALLSET      Include specified calls in the trimmed output.\n"
+        "        --frames=FRAMESET    Include specified frames in the trimmed output.\n"
+        "\n"
+        "        --deps               Perform dependency analysis and include dependent\n"
+        "                             calls as needed, (even if those calls were not\n"
+        "                             explicitly requested with --calls or --frames).\n"
+        "\n"
+        "        --prune              Omit calls with no side effects, even if the call\n"
+        "                             is within the range specified by --calls/--frames.\n"
+        "\n"
+        "    -a, --auto               Use dependency analysis and pruning\n"
+        "                             of uninteresting calls the resulting trace may\n"
+        "                             include more and less calls than specified.\n"
+        "                             This option is equivalent\n"
+        "                             to passing both --deps and --prune.\n"
+        "\n"
+        "        --print-callset      Print to stdout the final set of calls included\n"
+        "                             in the trim output. This can be useful for\n"
+        "                             tweaking the trimmed callset from --auto on the\n"
+        "                             command-line.\n"
+        "                             Use --calls=@FILE to read callset from a file.\n"
+        "        --trim-spec=SPEC     Specifies which classes of calls will be trimmed.\n"
+        "                             This option only has an effect if dependency\n"
+        "                             analysis is enabled. The argument is a comma-\n"
+        "                             separated list of names from the following:\n"
+        "\n"
+       "                               no-side-effects  Calls with no side effects\n"
+       "                               textures         Calls to setup unused textures\n"
+       "                               shaders          Calls to setup unused shaders\n"
+        "                               drawing          Calls that draw\n"
+        "\n"
+        "                             The default trim specification includes all of\n"
+        "                             the above, (as much as possible will be trimmed).\n"
+        "\n"
+        "        --thread=THREAD_ID   Only retain calls from specified thread\n"
+        "\n"
+        "    -o, --output=TRACE_FILE  Output trace file\n"
         "\n"
     ;
 }
 
 enum {
     CALLS_OPT = CHAR_MAX + 1,
+    FRAMES_OPT,
+    DEPS_OPT,
+    PRUNE_OPT,
     THREAD_OPT,
+    PRINT_CALLSET_OPT,
+    TRIM_SPEC_OPT
 };
 
 const static char *
-shortOptions = "ho:";
+shortOptions = "aho:x";
 
 const static struct option
 longOptions[] = {
     {"help", no_argument, 0, 'h'},
     {"calls", required_argument, 0, CALLS_OPT},
+    {"frames", required_argument, 0, FRAMES_OPT},
+    {"deps", no_argument, 0, DEPS_OPT},
+    {"prune", no_argument, 0, PRUNE_OPT},
+    {"auto", no_argument, 0, 'a'},
     {"thread", required_argument, 0, THREAD_OPT},
     {"output", required_argument, 0, 'o'},
+    {"print-callset", no_argument, 0, PRINT_CALLSET_OPT},
+    {"trim-spec", required_argument, 0, TRIM_SPEC_OPT},
     {0, 0, 0, 0}
 };
 
+struct stringCompare {
+    bool operator() (const char *a, const char *b) const {
+        return strcmp(a, b) < 0;
+    }
+};
+
+struct trim_options {
+    /* Calls to be included in trace. */
+    trace::CallSet calls;
+
+    /* Frames to be included in trace. */
+    trace::CallSet frames;
+
+    /* Whether dependency analysis should be performed. */
+    bool dependency_analysis;
+
+    /* Whether uninteresting calls should be pruned.. */
+    bool prune_uninteresting;
+
+    /* Output filename */
+    std::string output;
+
+    /* Emit only calls from this thread (-1 == all threads) */
+    int thread;
+
+    /* Print resulting callset */
+    int print_callset;
+
+    /* What kind of trimming to perform. */
+    TrimFlags trim_flags;
+};
+
+static int
+trim_trace(const char *filename, struct trim_options *options)
+{
+    trace::ParseBookmark beginning;
+    trace::Parser p;
+    TraceAnalyzer analyzer(options->trim_flags);
+    std::set<unsigned> *required;
+    unsigned frame;
+    int call_range_first, call_range_last;
+
+    if (!p.open(filename)) {
+        std::cerr << "error: failed to open " << filename << "\n";
+        return 1;
+    }
+
+    /* Mark the beginning so we can return here for pass 2. */
+    p.getBookmark(beginning);
+
+    /* In pass 1, analyze which calls are needed. */
+    frame = 0;
+    trace::Call *call;
+    while ((call = p.parse_call())) {
+
+        /* There's no use doing any work past the last call or frame
+         * requested by the user. */
+        if (call->no > options->calls.getLast() ||
+            frame > options->frames.getLast()) {
+            
+            delete call;
+            break;
+        }
+
+        /* If requested, ignore all calls not belonging to the specified thread. */
+        if (options->thread != -1 && call->thread_id != options->thread) {
+            goto NEXT;
+        }
+
+        /* Also, prune if uninteresting (unless the user asked for no pruning. */
+        if (options->prune_uninteresting && call->flags & trace::CALL_FLAG_VERBOSE) {
+            goto NEXT;
+        }
+
+        /* If this call is included in the user-specified call set,
+         * then require it (and all dependencies) in the trimmed
+         * output. */
+        if (options->calls.contains(*call) ||
+            options->frames.contains(frame, call->flags)) {
+
+            analyzer.require(call);
+        }
+
+        /* Regardless of whether we include this call or not, we do
+         * some dependency tracking (unless disabled by the user). We
+         * do this even for calls we have included in the output so
+         * that any state updates get performed. */
+        if (options->dependency_analysis) {
+            analyzer.analyze(call);
+        }
+
+    NEXT:
+        if (call->flags & trace::CALL_FLAG_END_FRAME)
+            frame++;
+
+        delete call;
+    }
+
+    /* Prepare output file and writer for output. */
+    if (options->output.empty()) {
+        os::String base(filename);
+        base.trimExtension();
+
+        options->output = std::string(base.str()) + std::string("-trim.trace");
+    }
+
+    trace::Writer writer;
+    if (!writer.open(options->output.c_str())) {
+        std::cerr << "error: failed to create " << filename << "\n";
+        return 1;
+    }
+
+    /* Reset bookmark for pass 2. */
+    p.setBookmark(beginning);
+
+    /* In pass 2, emit the calls that are required. */
+    required = analyzer.get_required();
+
+    frame = 0;
+    call_range_first = -1;
+    call_range_last = -1;
+    while ((call = p.parse_call())) {
+
+        /* There's no use doing any work past the last call or frame
+         * requested by the user. */
+        if (call->no > options->calls.getLast() ||
+            frame > options->frames.getLast()) {
+
+            break;
+        }
+
+        if (required->find(call->no) != required->end()) {
+            writer.writeCall(call);
+
+            if (options->print_callset) {
+                if (call_range_first < 0) {
+                    call_range_first = call->no;
+                    printf ("%d", call_range_first);
+                } else if (call->no != call_range_last + 1) {
+                    if (call_range_last != call_range_first)
+                        printf ("-%d", call_range_last);
+                    call_range_first = call->no;
+                    printf (",%d", call_range_first);
+                }
+                call_range_last = call->no;
+            }
+        }
+
+        if (call->flags & trace::CALL_FLAG_END_FRAME) {
+            frame++;
+        }
+
+        delete call;
+    }
+
+    if (options->print_callset) {
+        if (call_range_last != call_range_first)
+            printf ("-%d\n", call_range_last);
+    }
+
+    std::cerr << "Trimmed trace is available as " << options->output << "\n";
+
+    return 0;
+}
+
+static int
+parse_trim_spec(const char *trim_spec, TrimFlags *flags)
+{
+    std::string spec(trim_spec), word;
+    size_t start = 0, comma = 0;
+    *flags = 0;
+
+    while (start < spec.size()) {
+        comma = spec.find(',', start);
+
+        if (comma == std::string::npos)
+            word = std::string(spec, start);
+        else
+            word = std::string(spec, start, comma - start);
+
+        if (strcmp(word.c_str(), "no-side-effects") == 0)
+            *flags |= TRIM_FLAG_NO_SIDE_EFFECTS;
+        else if (strcmp(word.c_str(), "textures") == 0)
+            *flags |= TRIM_FLAG_TEXTURES;
+        else if (strcmp(word.c_str(), "shaders") == 0)
+            *flags |= TRIM_FLAG_SHADERS;
+        else if (strcmp(word.c_str(), "drawing") == 0)
+            *flags |= TRIM_FLAG_DRAWING;
+        else {
+            return 1;
+        }
+
+        if (comma == std::string::npos)
+            break;
+
+        start = comma + 1;
+    }
+
+    return 0;
+}
+
 static int
 command(int argc, char *argv[])
 {
-    std::string output;
-    trace::CallSet calls(trace::FREQUENCY_ALL);
-    int thread = -1;
-    int i;
+    struct trim_options options;
+
+    options.calls = trace::CallSet(trace::FREQUENCY_NONE);
+    options.frames = trace::CallSet(trace::FREQUENCY_NONE);
+    options.dependency_analysis = false;
+    options.prune_uninteresting = false;
+    options.output = "";
+    options.thread = -1;
+    options.print_callset = 0;
+    options.trim_flags = -1;
 
     int opt;
     while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
         switch (opt) {
         case 'h':
-            usage();
+            help();
             return 0;
         case CALLS_OPT:
-            calls = trace::CallSet(optarg);
+            options.calls = trace::CallSet(optarg);
+            break;
+        case FRAMES_OPT:
+            options.frames = trace::CallSet(optarg);
+            break;
+        case DEPS_OPT:
+            options.dependency_analysis = true;
+            break;
+        case PRUNE_OPT:
+            options.prune_uninteresting = true;
+            break;
+        case 'a':
+            options.dependency_analysis = true;
+            options.prune_uninteresting = true;
             break;
         case THREAD_OPT:
-            thread = atoi(optarg);
+            options.thread = atoi(optarg);
             break;
         case 'o':
-            output = optarg;
+            options.output = optarg;
+            break;
+        case PRINT_CALLSET_OPT:
+            options.print_callset = 1;
+            break;
+        case TRIM_SPEC_OPT:
+            if (parse_trim_spec(optarg, &options.trim_flags)) {
+                std::cerr << "error: illegal value for trim-spec: " << optarg << "\n";
+                std::cerr << "See \"apitrace help trim\" for help.\n";
+                return 1;
+            }
             break;
         default:
             std::cerr << "error: unexpected option `" << opt << "`\n";
@@ -101,49 +401,42 @@ command(int argc, char *argv[])
         }
     }
 
+    /* If neither of --calls nor --frames was set, default to the
+     * entire set of calls. */
+    if (options.calls.empty() && options.frames.empty()) {
+        options.calls = trace::CallSet(trace::FREQUENCY_ALL);
+    }
+
     if (optind >= argc) {
         std::cerr << "error: apitrace trim requires a trace file as an argument.\n";
         usage();
         return 1;
     }
 
-    for (i = optind; i < argc; ++i) {
-        trace::Parser p;
-        if (!p.open(argv[i])) {
-            return 1;
-        }
-
-        if (output.empty()) {
-            os::String base(argv[i]);
-            base.trimExtension();
-
-            output = std::string(base.str()) + std::string("-trim.trace");
-        }
-
-        trace::Writer writer;
-        if (!writer.open(output.c_str())) {
-            std::cerr << "error: failed to create " << argv[i] << "\n";
-            return 1;
-        }
-
-        trace::Call *call;
-        while ((call = p.parse_call())) {
-            if (calls.contains(*call) &&
-                (thread == -1 || call->thread_id == thread)) {
-                writer.writeCall(call);
-            }
-            delete call;
+    if (argc > optind + 1) {
+        std::cerr << "error: extraneous arguments:";
+        for (int i = optind + 1; i < argc; i++) {
+            std::cerr << " " << argv[i];
         }
+        std::cerr << "\n";
+        usage();
+        return 1;
+    }
 
-        std::cout << "Trimmed trace is available as " << output << "\n";
+    if (options.dependency_analysis) {
+        std::cerr <<
+            "Note: The dependency analysis in \"apitrace trim\" is still experimental.\n"
+            "      We hope that it will be useful, but it may lead to incorrect results.\n"
+            "      If you find a trace that misbehaves while trimming, please share that\n"
+            "      by sending email to apitrace@lists.freedesktop.org, cworth@cworth.org\n";
     }
 
-    return 0;
+    return trim_trace(argv[optind], &options);
 }
 
 const Command trim_command = {
     "trim",
     synopsis,
-    usage,
+    help,
     command
 };
diff --git a/cli/trace_analyzer.cpp b/cli/trace_analyzer.cpp
new file mode 100644 (file)
index 0000000..730dab9
--- /dev/null
@@ -0,0 +1,773 @@
+/**************************************************************************
+ * 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 <sstream>
+
+#include "trace_analyzer.hpp"
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define STRNCMP_LITERAL(var, literal) strncmp((var), (literal), sizeof (literal) -1)
+
+/* Rendering often has no side effects, but it can in some cases,
+* (such as when transform feedback is active, or when rendering
+* targets a framebuffer object). */
+bool
+TraceAnalyzer::renderingHasSideEffect(void)
+{
+    return transformFeedbackActive || framebufferObjectActive;
+}
+
+/* Provide: Record that the given call affects the given resource
+ * as a side effect. */
+void
+TraceAnalyzer::provide(std::string resource, trace::CallNo call_no)
+{
+    resources[resource].insert(call_no);
+}
+
+/* Like provide, but with a simply-formatted string, (appending an
+ * integer to the given string). */
+void
+TraceAnalyzer::providef(std::string resource,
+                        int resource_no,
+                        trace::CallNo call_no)
+{
+    std::stringstream ss;
+    ss << resource << resource_no;
+    provide(ss.str(), call_no);
+}
+
+/* Link: Establish a dependency between resource 'resource' and
+ * resource 'dependency'. This dependency is captured by name so
+ * that if the list of calls that provide 'dependency' grows
+ * before 'resource' is consumed, those calls will still be
+ * captured. */
+void
+TraceAnalyzer::link(std::string resource, std::string dependency)
+{
+    dependencies[resource].insert(dependency);
+}
+
+/* Like link, but with a simply-formatted string, (appending an
+ * integer to the given string). */
+void
+TraceAnalyzer::linkf(std::string resource, std::string dependency, int dep_no)
+{
+
+    std::stringstream ss;
+    ss << dependency << dep_no;
+    link(resource, ss.str());
+}
+
+/* Unlink: Remove dependency from 'resource' on 'dependency'. */
+void
+TraceAnalyzer::unlink(std::string resource, std::string dependency)
+{
+    dependencies[resource].erase(dependency);
+    if (dependencies[resource].size() == 0) {
+        dependencies.erase(resource);
+    }
+}
+
+/* Like unlink, but with a simply-formated string, (appending an
+ * integer to the given string). */
+void
+TraceAnalyzer::unlinkf(std::string resource, std::string dependency, int dep_no)
+{
+
+    std::stringstream ss;
+    ss << dependency << dep_no;
+    unlink(resource, ss.str());
+}
+
+/* Unlink all: Remove dependencies from 'resource' to all other
+ * resources. */
+void
+TraceAnalyzer::unlinkAll(std::string resource)
+{
+    dependencies.erase(resource);
+}
+
+/* Resolve: Recursively compute all calls providing 'resource',
+ * (including linked dependencies of 'resource' on other
+ * resources). */
+std::set<unsigned>
+TraceAnalyzer::resolve(std::string resource)
+{
+    std::set<std::string> *deps;
+    std::set<std::string>::iterator dep;
+
+    std::set<unsigned> *calls;
+    std::set<unsigned>::iterator call;
+
+    std::set<unsigned> result, deps_set;
+
+    /* Recursively chase dependencies. */
+    if (dependencies.count(resource)) {
+        deps = &dependencies[resource];
+        for (dep = deps->begin(); dep != deps->end(); dep++) {
+            deps_set = resolve(*dep);
+            for (call = deps_set.begin(); call != deps_set.end(); call++) {
+                result.insert(*call);
+            }
+        }
+    }
+
+    /* Also look for calls that directly provide 'resource' */
+    if (resources.count(resource)) {
+        calls = &resources[resource];
+        for (call = calls->begin(); call != calls->end(); call++) {
+            result.insert(*call);
+        }
+    }
+
+    return result;
+}
+
+/* Consume: Resolve all calls that provide the given resource, and
+ * add them to the required list. Then clear the call list for
+ * 'resource' along with any dependencies. */
+void
+TraceAnalyzer::consume(std::string resource)
+{
+
+    std::set<unsigned> calls;
+    std::set<unsigned>::iterator call;
+
+    calls = resolve(resource);
+
+    dependencies.erase(resource);
+    resources.erase(resource);
+
+    for (call = calls.begin(); call != calls.end(); call++) {
+        required.insert(*call);
+    }
+}
+
+void
+TraceAnalyzer::stateTrackPreCall(trace::Call *call)
+{
+
+    const char *name = call->name();
+
+    if (strcmp(name, "glBegin") == 0) {
+        insideBeginEnd = true;
+        return;
+    }
+
+    if (strcmp(name, "glBeginTransformFeedback") == 0) {
+        transformFeedbackActive = true;
+        return;
+    }
+
+    if (strcmp(name, "glActiveTexture") == 0) {
+        activeTextureUnit = static_cast<GLenum>(call->arg(0).toSInt());
+        return;
+    }
+
+    if (strcmp(name, "glBindTexture") == 0) {
+        GLenum target;
+        GLuint texture;
+
+        target = static_cast<GLenum>(call->arg(0).toSInt());
+        texture = call->arg(1).toUInt();
+
+        if (texture == 0) {
+            texture_map.erase(target);
+        } else {
+            texture_map[target] = texture;
+        }
+
+        return;
+    }
+
+    if (strcmp(name, "glUseProgram") == 0) {
+        activeProgram = call->arg(0).toUInt();
+    }
+
+    if (strcmp(name, "glBindFramebuffer") == 0) {
+        GLenum target;
+        GLuint framebuffer;
+
+        target = static_cast<GLenum>(call->arg(0).toSInt());
+        framebuffer = call->arg(1).toUInt();
+
+        if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) {
+            if (framebuffer == 0) {
+                framebufferObjectActive = false;
+            } else {
+                framebufferObjectActive = true;
+            }
+        }
+        return;
+    }
+
+    if (strcmp(name, "glNewList") == 0) {
+        GLuint list = call->arg(0).toUInt();
+
+        insideNewEndList = list;
+    }
+}
+
+void
+TraceAnalyzer::stateTrackPostCall(trace::Call *call)
+{
+
+    const char *name = call->name();
+
+    if (strcmp(name, "glEnd") == 0) {
+        insideBeginEnd = false;
+        return;
+    }
+
+    if (strcmp(name, "glEndTransformFeedback") == 0) {
+        transformFeedbackActive = false;
+        return;
+    }
+
+    /* If this swapbuffers was included in the trace then it will
+     * have already consumed all framebuffer dependencies. If not,
+     * then clear them now so that they don't carry over into the
+     * next frame. */
+    if (call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET &&
+        call->flags & trace::CALL_FLAG_END_FRAME) {
+        dependencies.erase("framebuffer");
+        resources.erase("framebuffer");
+        return;
+    }
+
+    if (strcmp(name, "glEndList") == 0) {
+        insideNewEndList = 0;
+    }
+}
+
+bool
+TraceAnalyzer::callHasNoSideEffects(trace::Call *call, const char *name)
+{
+    /* If call is flagged as no side effects, then we are done here. */
+    if (call->flags & trace::CALL_FLAG_NO_SIDE_EFFECTS) {
+        return true;
+    }
+
+    /* Similarly, swap-buffers calls don't have interesting side effects. */
+    if (call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET &&
+        call->flags & trace::CALL_FLAG_END_FRAME) {
+        return true;
+    }
+
+    /* Not known as a no-side-effect call. Return false for more analysis. */
+    return false;
+}
+
+bool
+TraceAnalyzer::recordTextureSideEffects(trace::Call *call, const char *name)
+{
+    if (strcmp(name, "glGenTextures") == 0) {
+        const trace::Array *textures = dynamic_cast<const trace::Array *>(&call->arg(1));
+        size_t i;
+        GLuint texture;
+
+        if (textures) {
+            for (i = 0; i < textures->size(); i++) {
+                texture = textures->values[i]->toUInt();
+                providef("texture-", texture, call->no);
+            }
+        }
+        return true;
+    }
+
+    /* FIXME: When we start tracking framebuffer objects as their own
+     * resources, we will want to link the FBO to the given texture
+     * resource, (and to this call). For now, just link render state
+     * to the texture, and force this call to be required. */
+    if (strcmp(name, "glFramebufferTexture2D") == 0) {
+        GLuint texture;
+
+        texture = call->arg(3).toUInt();
+
+        linkf("render-state", "texture-", texture);
+
+        provide("state", call->no);
+    }
+
+    if (strcmp(name, "glBindTexture") == 0) {
+        GLenum target;
+        GLuint texture;
+
+        std::stringstream ss_target, ss_texture;
+
+        target = static_cast<GLenum>(call->arg(0).toSInt());
+        texture = call->arg(1).toUInt();
+
+        ss_target << "texture-unit-" << activeTextureUnit << "-target-" << target;
+        ss_texture << "texture-" << texture;
+
+        resources.erase(ss_target.str());
+        provide(ss_target.str(), call->no);
+
+        unlinkAll(ss_target.str());
+        link(ss_target.str(), ss_texture.str());
+
+        /* FIXME: This really shouldn't be necessary. The effect
+         * this provide() has is that all glBindTexture calls will
+         * be preserved in the output trace (never trimmed). Carl
+         * has a trace ("btr") where a glBindTexture call should
+         * not be necessary at all, (it's immediately followed
+         * with a glBindTexture to a different texture and no
+         * intervening texture-related calls), yet this 'provide'
+         * makes the difference between a trim_stress test failing
+         * and passing.
+         *
+         * More investigation is necessary, but for now, be
+         * conservative and don't trim. */
+        provide("state", call->no);
+
+        return true;
+    }
+
+    /* FIXME: Need to handle glMultiTexImage and friends. */
+    if (STRNCMP_LITERAL(name, "glTexImage") == 0 ||
+        STRNCMP_LITERAL(name, "glTexSubImage") == 0 ||
+        STRNCMP_LITERAL(name, "glCopyTexImage") == 0 ||
+        STRNCMP_LITERAL(name, "glCopyTexSubImage") == 0 ||
+        STRNCMP_LITERAL(name, "glCompressedTexImage") == 0 ||
+        STRNCMP_LITERAL(name, "glCompressedTexSubImage") == 0 ||
+        strcmp(name, "glInvalidateTexImage") == 0 ||
+        strcmp(name, "glInvalidateTexSubImage") == 0) {
+
+        std::set<unsigned> *calls;
+        std::set<unsigned>::iterator c;
+        std::stringstream ss_target, ss_texture;
+
+        GLenum target = static_cast<GLenum>(call->arg(0).toSInt());
+
+        ss_target << "texture-unit-" << activeTextureUnit << "-target-" << target;
+        ss_texture << "texture-" << texture_map[target];
+
+        /* The texture resource depends on this call and any calls
+         * providing the given texture target. */
+        provide(ss_texture.str(), call->no);
+
+        if (resources.count(ss_target.str())) {
+            calls = &resources[ss_target.str()];
+            for (c = calls->begin(); c != calls->end(); c++) {
+                provide(ss_texture.str(), *c);
+            }
+        }
+
+        return true;
+    }
+
+    if (strcmp(name, "glEnable") == 0) {
+        GLenum cap;
+
+        cap = static_cast<GLenum>(call->arg(0).toSInt());
+
+        if (cap == GL_TEXTURE_1D ||
+            cap == GL_TEXTURE_2D ||
+            cap == GL_TEXTURE_3D ||
+            cap == GL_TEXTURE_CUBE_MAP)
+        {
+            std::stringstream ss;
+
+            ss << "texture-unit-" << activeTextureUnit << "-target-" << cap;
+
+            link("render-state", ss.str());
+        }
+
+        provide("state", call->no);
+        return true;
+    }
+
+    if (strcmp(name, "glDisable") == 0) {
+        GLenum cap;
+
+        cap = static_cast<GLenum>(call->arg(0).toSInt());
+
+        if (cap == GL_TEXTURE_1D ||
+            cap == GL_TEXTURE_2D ||
+            cap == GL_TEXTURE_3D ||
+            cap == GL_TEXTURE_CUBE_MAP)
+        {
+            std::stringstream ss;
+
+            ss << "texture-unit-" << activeTextureUnit << "-target-" << cap;
+
+            unlink("render-state", ss.str());
+        }
+
+        provide("state", call->no);
+        return true;
+    }
+
+    /* No known texture-related side effects. Return false for more analysis. */
+    return false;
+}
+
+bool
+TraceAnalyzer::recordShaderSideEffects(trace::Call *call, const char *name)
+{
+    if (strcmp(name, "glCreateShader") == 0 ||
+        strcmp(name, "glCreateShaderObjectARB") == 0) {
+
+        GLuint shader = call->ret->toUInt();
+        providef("shader-", shader, call->no);
+        return true;
+    }
+
+    if (strcmp(name, "glShaderSource") == 0 ||
+        strcmp(name, "glShaderSourceARB") == 0 ||
+        strcmp(name, "glCompileShader") == 0 ||
+        strcmp(name, "glCompileShaderARB") == 0 ||
+        strcmp(name, "glGetShaderiv") == 0 ||
+        strcmp(name, "glGetShaderInfoLog") == 0) {
+
+        GLuint shader = call->arg(0).toUInt();
+        providef("shader-", shader, call->no);
+        return true;
+    }
+
+    if (strcmp(name, "glCreateProgram") == 0 ||
+        strcmp(name, "glCreateProgramObjectARB") == 0) {
+
+        GLuint program = call->ret->toUInt();
+        providef("program-", program, call->no);
+        return true;
+    }
+
+    if (strcmp(name, "glAttachShader") == 0 ||
+        strcmp(name, "glAttachObjectARB") == 0) {
+
+        GLuint program, shader;
+        std::stringstream ss_program, ss_shader;
+
+        program = call->arg(0).toUInt();
+        shader = call->arg(1).toUInt();
+
+        ss_program << "program-" << program;
+        ss_shader << "shader-" << shader;
+
+        link(ss_program.str(), ss_shader.str());
+        provide(ss_program.str(), call->no);
+
+        return true;
+    }
+
+    if (strcmp(name, "glDetachShader") == 0 ||
+        strcmp(name, "glDetachObjectARB") == 0) {
+
+        GLuint program, shader;
+        std::stringstream ss_program, ss_shader;
+
+        program = call->arg(0).toUInt();
+        shader = call->arg(1).toUInt();
+
+        ss_program << "program-" << program;
+        ss_shader << "shader-" << shader;
+
+        unlink(ss_program.str(), ss_shader.str());
+
+        return true;
+    }
+
+    if (strcmp(name, "glUseProgram") == 0 ||
+        strcmp(name, "glUseProgramObjectARB") == 0) {
+
+        GLuint program;
+
+        program = call->arg(0).toUInt();
+
+        unlinkAll("render-program-state");
+
+        if (program == 0) {
+            unlink("render-state", "render-program-state");
+            provide("state", call->no);
+        } else {
+            std::stringstream ss;
+
+            ss << "program-" << program;
+
+            link("render-state", "render-program-state");
+            link("render-program-state", ss.str());
+
+            provide(ss.str(), call->no);
+        }
+
+        return true;
+    }
+
+    if (strcmp(name, "glGetUniformLocation") == 0 ||
+        strcmp(name, "glGetUniformLocationARB") == 0 ||
+        strcmp(name, "glGetFragDataLocation") == 0 ||
+        strcmp(name, "glGetFragDataLocationEXT") == 0 ||
+        strcmp(name, "glGetSubroutineUniformLocation") == 0 ||
+        strcmp(name, "glGetProgramResourceLocation") == 0 ||
+        strcmp(name, "glGetProgramResourceLocationIndex") == 0 ||
+        strcmp(name, "glGetVaryingLocationNV") == 0) {
+
+        GLuint program = call->arg(0).toUInt();
+
+        providef("program-", program, call->no);
+
+        return true;
+    }
+
+    /* For any call that accepts 'location' as its first argument,
+     * perform a lookup in our location->program map and add a
+     * dependence on the program we find there. */
+    if (call->sig->num_args > 0 &&
+        strcmp(call->sig->arg_names[0], "location") == 0) {
+
+        providef("program-", activeProgram, call->no);
+
+        /* We can't easily tell if this uniform is being used to
+         * associate a sampler in the shader with a texture
+         * unit. The conservative option is to assume that it is
+         * and create a link from the active program to any bound
+         * textures for the given unit number.
+         *
+         * FIXME: We should be doing the same thing for calls to
+         * glUniform1iv. */
+        if (strcmp(name, "glUniform1i") == 0 ||
+            strcmp(name, "glUniform1iARB") == 0) {
+
+            GLint max_unit = MAX(GL_MAX_TEXTURE_COORDS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+
+            GLint unit = call->arg(1).toSInt();
+            std::stringstream ss_program;
+            std::stringstream ss_texture;
+
+            if (unit < max_unit) {
+
+                ss_program << "program-" << activeProgram;
+
+                ss_texture << "texture-unit-" << GL_TEXTURE0 + unit << "-target-";
+
+                /* We don't know what target(s) might get bound to
+                 * this texture unit, so conservatively link to
+                 * all. Only bound textures will actually get inserted
+                 * into the output call stream. */
+                linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_1D);
+                linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_2D);
+                linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_3D);
+                linkf(ss_program.str(), ss_texture.str(), GL_TEXTURE_CUBE_MAP);
+            }
+        }
+
+        return true;
+    }
+
+    /* FIXME: We cut a huge swath by assuming that any unhandled
+     * call that has a first argument named "program" should not
+     * be included in the trimmed output unless the program of
+     * that number is also included.
+     *
+     * This heuristic is correct for many cases, but we should
+     * actually carefully verify if this includes some calls
+     * inappropriately, or if it misses some.
+     */
+    if (strcmp(name, "glLinkProgram") == 0 ||
+        strcmp(name, "glLinkProgramARB") == 0 ||
+        (call->sig->num_args > 0 &&
+         (strcmp(call->sig->arg_names[0], "program") == 0 ||
+          strcmp(call->sig->arg_names[0], "programObj") == 0))) {
+
+        GLuint program = call->arg(0).toUInt();
+        providef("program-", program, call->no);
+        return true;
+    }
+
+    /* No known shader-related side effects. Return false for more analysis. */
+    return false;
+}
+
+bool
+TraceAnalyzer::recordDrawingSideEffects(trace::Call *call, const char *name)
+{
+    /* Handle all rendering operations, (even though only glEnd is
+     * flagged as a rendering operation we treat everything from
+     * glBegin through glEnd as a rendering operation). */
+    if (call->flags & trace::CALL_FLAG_RENDER ||
+        insideBeginEnd) {
+
+        std::set<unsigned> calls;
+        std::set<unsigned>::iterator c;
+
+        provide("framebuffer", call->no);
+
+        calls = resolve("render-state");
+
+        for (c = calls.begin(); c != calls.end(); c++) {
+            provide("framebuffer", *c);
+        }
+
+        /* In some cases, rendering has side effects beyond the
+         * framebuffer update. */
+        if (renderingHasSideEffect()) {
+            provide("state", call->no);
+            for (c = calls.begin(); c != calls.end(); c++) {
+                provide("state", *c);
+            }
+        }
+
+        return true;
+    }
+
+    /* Though it's not flagged as a "RENDER" operation, we also want
+     * to trim swapbuffers calls when trimming drawing operations. */
+    if (call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET &&
+        call->flags & trace::CALL_FLAG_END_FRAME) {
+        return true;
+    }
+
+    /* No known drawing-related side effects. Return false for more analysis. */
+    return false;
+}
+
+void
+TraceAnalyzer::recordSideEffects(trace::Call *call)
+{
+
+    const char *name = call->name();
+
+    /* FIXME: If we encode the list of commands that are executed
+     * immediately (as opposed to those that are compiled into a
+     * display list) then we could generate a "display-list-X"
+     * resource just as we do for "texture-X" resources and only
+     * emit it in the trace if a glCallList(X) is emitted. For
+     * now, simply punt and include anything within glNewList and
+     * glEndList in the trim output. This guarantees that display
+     * lists will work, but does not trim out unused display
+     * lists. */
+    if (insideNewEndList != 0) {
+        provide("state", call->no);
+
+        /* Also, any texture bound inside a display list is
+         * conservatively considered required. */
+        if (strcmp(name, "glBindTexture") == 0) {
+            GLuint texture = call->arg(1).toUInt();
+
+            linkf("state", "texture-", texture);
+        }
+
+        return;
+    }
+
+    if (trimFlags & TRIM_FLAG_NO_SIDE_EFFECTS) {
+
+        if (callHasNoSideEffects(call, name)) {
+            return;
+        }
+    }
+
+    if (trimFlags & TRIM_FLAG_TEXTURES) {
+        
+        if (recordTextureSideEffects(call, name)) {
+            return;
+        }
+    }
+
+    if (trimFlags & TRIM_FLAG_SHADERS) {
+
+        if (recordShaderSideEffects(call, name)) {
+            return;
+        }
+    }
+
+    if (trimFlags & TRIM_FLAG_DRAWING) {
+
+        if (recordDrawingSideEffects(call, name)) {
+            return;
+        }
+    }
+
+    /* By default, assume this call affects the state somehow. */
+    resources["state"].insert(call->no);
+}
+
+void
+TraceAnalyzer::requireDependencies(trace::Call *call)
+{
+
+    /* Swap-buffers calls depend on framebuffer state. */
+    if (call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET &&
+        call->flags & trace::CALL_FLAG_END_FRAME) {
+        consume("framebuffer");
+    }
+
+    /* By default, just assume this call depends on generic state. */
+    consume("state");
+}
+
+TraceAnalyzer::TraceAnalyzer(TrimFlags trimFlagsOpt = -1):
+    transformFeedbackActive(false),
+    framebufferObjectActive(false),
+    insideBeginEnd(false),
+    insideNewEndList(0),
+    activeTextureUnit(GL_TEXTURE0),
+    trimFlags(trimFlagsOpt)
+{
+    /* Nothing needed. */
+}
+
+TraceAnalyzer::~TraceAnalyzer()
+{
+    /* Nothing needed. */
+}
+
+/* Analyze this call by tracking state and recording all the
+ * resources provided by this call as side effects.. */
+void
+TraceAnalyzer::analyze(trace::Call *call)
+{
+
+    stateTrackPreCall(call);
+
+    recordSideEffects(call);
+
+    stateTrackPostCall(call);
+}
+
+/* Require this call and all of its dependencies to be included in
+ * the final trace. */
+void
+TraceAnalyzer::require(trace::Call *call)
+{
+
+    /* First, find and insert all calls that this call depends on. */
+    requireDependencies(call);
+
+    /* Then insert this call itself. */
+    required.insert(call->no);
+}
+
+/* Return a set of all the required calls, (both those calls added
+ * explicitly with require() and those implicitly depended
+ * upon. */
+std::set<unsigned>  *
+TraceAnalyzer::get_required(void)
+{
+    return &required;
+}
diff --git a/cli/trace_analyzer.hpp b/cli/trace_analyzer.hpp
new file mode 100644 (file)
index 0000000..ef89ad7
--- /dev/null
@@ -0,0 +1,113 @@
+/**************************************************************************
+ * 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 <set>
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include "trace_callset.hpp"
+#include "trace_parser.hpp"
+
+typedef unsigned TrimFlags;
+
+/**
+ * Trim flags
+ */
+enum {
+
+    /* Whether to trim calls that have no side effects. */
+    TRIM_FLAG_NO_SIDE_EFFECTS          = (1 << 0),
+
+    /* Whether to trim calls to setup textures that are never used. */
+    TRIM_FLAG_TEXTURES                 = (1 << 1),
+
+    /* Whether to trim calls to setup shaders that are never used. */
+    TRIM_FLAG_SHADERS                  = (1 << 2),
+
+    /* Whether to trim drawing operations outside of the desired call-set. */
+    TRIM_FLAG_DRAWING                  = (1 << 3),
+};
+
+class TraceAnalyzer {
+private:
+    std::map<std::string, std::set<unsigned> > resources;
+    std::map<std::string, std::set<std::string> > dependencies;
+
+    std::map<GLenum, unsigned> texture_map;
+
+    std::set<unsigned> required;
+
+    bool transformFeedbackActive;
+    bool framebufferObjectActive;
+    bool insideBeginEnd;
+    GLuint insideNewEndList;
+    GLenum activeTextureUnit;
+    GLuint activeProgram;
+    unsigned int trimFlags;
+
+    void provide(std::string resource, trace::CallNo call_no);
+    void providef(std::string resource, int resource_no, trace::CallNo call_no);
+
+    void link(std::string resource, std::string dependency);
+    void linkf(std::string resource, std::string dependency, int dep_no);
+
+    void unlink(std::string resource, std::string dependency);
+    void unlinkf(std::string resource, std::string dependency, int dep_no);
+    void unlinkAll(std::string resource);
+
+    void stateTrackPreCall(trace::Call *call);
+
+    void recordSideEffects(trace::Call *call);
+    bool callHasNoSideEffects(trace::Call *call, const char *name);
+    bool recordTextureSideEffects(trace::Call *call, const char *name);
+    bool recordShaderSideEffects(trace::Call *call, const char *name);
+    bool recordDrawingSideEffects(trace::Call *call, const char *name);
+
+    void stateTrackPostCall(trace::Call *call);
+
+    bool renderingHasSideEffect(void);
+    std::set<unsigned> resolve(std::string resource);
+
+    void consume(std::string resource);
+    void requireDependencies(trace::Call *call);
+
+public:
+    TraceAnalyzer(TrimFlags trimFlags);
+    ~TraceAnalyzer();
+
+    /* Analyze this call by tracking state and recording all the
+     * resources provided by this call as side effects.. */
+    void analyze(trace::Call *call);
+
+    /* Require this call and all of its dependencies to be included in
+     * the final trace. */
+    void require(trace::Call *call);
+
+    /* Return a set of all the required calls, (both those calls added
+     * explicitly with require() and those implicitly depended
+     * upon. */
+    std::set<unsigned> *get_required(void);
+};
diff --git a/common/os_memory.hpp b/common/os_memory.hpp
new file mode 100644 (file)
index 0000000..4774412
--- /dev/null
@@ -0,0 +1,67 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
+ * 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.
+ *
+ **************************************************************************/
+
+/*
+ * Simple OS time measurement abstraction.
+ */
+
+#ifndef _OS_MEMORY_HPP_
+#define _OS_MEMORY_HPP_
+
+#ifdef HAVE_READPROC_H
+#include <proc/readproc.h>
+
+namespace os {
+    inline long long
+    getVsize(void) {
+        proc_t proc;
+        look_up_our_self(&proc);
+        return proc.vsize;
+    }
+
+    inline long long
+    getRss(void) {
+        proc_t proc;
+        look_up_our_self(&proc);
+        return proc.rss;
+    }
+} /* namespace os */
+
+#else
+namespace os {
+    inline long long
+    getVsize(void) {
+        return 0;
+    }
+
+    inline long long
+    getRss(void) {
+        return 0;
+    }
+} /* namespace os */
+#endif
+
+#endif /* _OS_MEMORY_HPP_ */
index 9dc656eedce84798480de480b3fa1747e1da7c9b..2c3f73250893e9beba24bc84781acedf8f1e4775 100644 (file)
@@ -312,7 +312,7 @@ namespace os {
             DWORD id = 0;
             _native_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, (LPVOID)arg, 0, &id);
 #else
-            pthread_create(&_native_handle, NULL, ( void *(*) (void *))f, arg);
+            pthread_create(&_native_handle, NULL, (void *(*) (void *))f, (void *)arg);
 #endif
         }
 
index 3c33087cbda883f11a9d8d7280bb7295ee9c8bbf..93d145fa3a2b0f881794786d3aa23e7db047fbb9 100644 (file)
@@ -224,7 +224,7 @@ public:
 };
 
 
-CallSet::CallSet(const char *string)
+CallSet::CallSet(const char *string): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max())
 {
     if (*string == '@') {
         FileCallSetParser parser(*this, &string[1]);
@@ -236,7 +236,7 @@ CallSet::CallSet(const char *string)
 }
 
 
-CallSet::CallSet(CallFlags freq) {
+CallSet::CallSet(CallFlags freq): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {
     if (freq != FREQUENCY_NONE) {
         CallNo start = std::numeric_limits<CallNo>::min();
         CallNo stop = std::numeric_limits<CallNo>::max();
index b679d94867b3f095f78b574e07c4075deccafc7e..4a4a52d397c6cef90804acfb0f16b5a7c931a6cc 100644 (file)
@@ -48,6 +48,7 @@
 #define _TRACE_CALLSET_HPP_
 
 
+#include <limits>
 #include <list>
 
 #include "trace_model.hpp"
@@ -106,12 +107,15 @@ namespace trace {
     // A collection of call ranges
     class CallSet
     {
+    private:
+        CallRange limits;
+
     public:
         // TODO: use binary tree to speed up lookups
         typedef std::list< CallRange > RangeList;
         RangeList ranges;
 
-        CallSet() {}
+        CallSet(): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {}
 
         CallSet(CallFlags freq);
 
@@ -128,6 +132,16 @@ namespace trace {
             if (range.start <= range.stop &&
                 range.freq != FREQUENCY_NONE) {
 
+                if (empty()) {
+                    limits.start = range.start;
+                    limits.stop = range.stop;
+                } else {
+                    if (range.start < limits.start)
+                        limits.start = range.start;
+                    if (range.stop > limits.stop)
+                        limits.stop = range.stop;
+                }
+
                 RangeList::iterator it = ranges.begin();
                 while (it != ranges.end() && it->start < range.start) {
                     ++it;
@@ -155,6 +169,14 @@ namespace trace {
         contains(const trace::Call &call) {
             return contains(call.no, call.flags);
         }
+
+        CallNo getFirst() {
+            return limits.start;
+        }
+
+        CallNo getLast() {
+            return limits.stop;
+        }
     };
 
 
index f3aea7e7cf482f26f69e74432691bcefbb75ab1c..095af670e2159f79299fdba9bc4e642cbb4ac5e4 100644 (file)
@@ -30,6 +30,7 @@
 #include <string.h>
 
 #include "trace_file.hpp"
+#include "trace_dump.hpp"
 #include "trace_parser.hpp"
 
 
@@ -176,9 +177,15 @@ Call *Parser::parse_call(Mode mode) {
         int c = read_byte();
         switch (c) {
         case trace::EVENT_ENTER:
+#if TRACE_VERBOSE
+            std::cerr << "\tENTER\n";
+#endif
             parse_enter(mode);
             break;
         case trace::EVENT_LEAVE:
+#if TRACE_VERBOSE
+            std::cerr << "\tLEAVE\n";
+#endif
             call = parse_leave(mode);
             adjust_call_flags(call);
             return call;
@@ -466,11 +473,20 @@ bool Parser::parse_call_details(Call *call, Mode mode) {
         int c = read_byte();
         switch (c) {
         case trace::CALL_END:
+#if TRACE_VERBOSE
+            std::cerr << "\tCALL_END\n";
+#endif
             return true;
         case trace::CALL_ARG:
+#if TRACE_VERBOSE
+            std::cerr << "\tCALL_ARG\n";
+#endif
             parse_arg(call, mode);
             break;
         case trace::CALL_RET:
+#if TRACE_VERBOSE
+            std::cerr << "\tCALL_RET\n";
+#endif
             call->ret = parse_value(mode);
             break;
         default:
@@ -570,7 +586,9 @@ Value *Parser::parse_value(void) {
     }
 #if TRACE_VERBOSE
     if (value) {
-        std::cerr << "\tVALUE " << value << "\n";
+        std::cerr << "\tVALUE ";
+        trace::dump(value, std::cerr);
+        std::cerr << "\n";
     }
 #endif
     return value;
index 1ff2b0b76677b68c5c035a62b88d1d005daf3405..bad9f5ec41afa16055697b11ffb577917b560287 100644 (file)
@@ -81,8 +81,8 @@ callFlagTable[] = {
     { "ID3D11DeviceContext::DrawInstancedIndirect",         CALL_FLAG_RENDER },
     { "ID3D11DeviceContext::OMSetRenderTargets",       CALL_FLAG_SWAP_RENDERTARGET },
     { "ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews", CALL_FLAG_SWAP_RENDERTARGET },
-    { "IDXGISwapChain::Present",                       CALL_FLAG_END_FRAME },
-    { "IDXGISwapChainDWM::Present",                    CALL_FLAG_END_FRAME },
+    { "IDXGISwapChain::Present",                       CALL_FLAG_SWAPBUFFERS },
+    { "IDXGISwapChainDWM::Present",                    CALL_FLAG_SWAPBUFFERS },
     { "IDirect3D9::CheckDeviceFormat",                 CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "IDirect3D9::EnumAdapterModes",                  CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "IDirect3D9::GetAdapterModeCount",               CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
@@ -100,7 +100,7 @@ callFlagTable[] = {
     { "IDirect3DDevice9::DrawTriPatch",                CALL_FLAG_RENDER },
     { "IDirect3DDevice9::GetDeviceCaps",               CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "IDirect3DDevice9::GetRenderTargetData",         CALL_FLAG_END_FRAME },
-    { "IDirect3DDevice9::Present",                     CALL_FLAG_END_FRAME },
+    { "IDirect3DDevice9::Present",                     CALL_FLAG_SWAPBUFFERS },
     { "IDirect3DDevice9::SetRenderTarget",             CALL_FLAG_SWAP_RENDERTARGET },
     { "IDirect3DDevice9Ex::Clear",                     CALL_FLAG_RENDER },
     { "IDirect3DDevice9Ex::DrawIndexedPrimitive",      CALL_FLAG_RENDER },
@@ -111,10 +111,11 @@ callFlagTable[] = {
     { "IDirect3DDevice9Ex::DrawTriPatch",              CALL_FLAG_RENDER },
     { "IDirect3DDevice9Ex::GetDeviceCaps",             CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "IDirect3DDevice9Ex::GetRenderTargetData",       CALL_FLAG_END_FRAME },
-    { "IDirect3DDevice9Ex::Present",                   CALL_FLAG_END_FRAME },
+    { "IDirect3DDevice9Ex::Present",                   CALL_FLAG_SWAPBUFFERS },
+    { "IDirect3DDevice9Ex::PresentEx",                 CALL_FLAG_SWAPBUFFERS },
     { "IDirect3DDevice9Ex::SetRenderTarget",           CALL_FLAG_SWAP_RENDERTARGET },
-    { "IDirect3DSwapChain9::Present",                  CALL_FLAG_END_FRAME },
-    { "IDirect3DSwapChain9Ex::Present",                CALL_FLAG_END_FRAME },
+    { "IDirect3DSwapChain9::Present",                  CALL_FLAG_SWAPBUFFERS },
+    { "IDirect3DSwapChain9Ex::Present",                CALL_FLAG_SWAPBUFFERS },
     { "eglGetProcAddress",                             CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "eglQueryString",                                CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
     { "eglSwapBuffers",                                CALL_FLAG_SWAPBUFFERS },
index 0f90ee2766318c54f790fc110efd772b8126f309..773e7cc4096876090087b6c14c3753089e674eda 100644 (file)
@@ -1,6 +1,7 @@
 /**************************************************************************
  *
  * Copyright 2012 VMware, Inc.
+ * Copyright 2013 Intel, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,9 +35,12 @@ Profiler::Profiler()
     : baseGpuTime(0),
       baseCpuTime(0),
       minCpuTime(1000),
+      baseVsizeUsage(0),
+      baseRssUsage(0),
       cpuTimes(false),
       gpuTimes(true),
-      pixelsDrawn(false)
+      pixelsDrawn(false),
+      memoryUsage(false)
 {
 }
 
@@ -44,13 +48,14 @@ Profiler::~Profiler()
 {
 }
 
-void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
+void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_)
 {
     cpuTimes = cpuTimes_;
     gpuTimes = gpuTimes_;
     pixelsDrawn = pixelsDrawn_;
+    memoryUsage = memoryUsage_;
 
-    std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
+    std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura vsize_start vsize_dura rss_start rss_dura pixels program name" << std::endl;
 }
 
 int64_t Profiler::getBaseCpuTime()
@@ -63,6 +68,16 @@ int64_t Profiler::getBaseGpuTime()
     return baseGpuTime;
 }
 
+int64_t Profiler::getBaseVsizeUsage()
+{
+    return baseVsizeUsage;
+}
+
+int64_t Profiler::getBaseRssUsage()
+{
+    return baseRssUsage;
+}
+
 void Profiler::setBaseCpuTime(int64_t cpuStart)
 {
     baseCpuTime = cpuStart;
@@ -73,6 +88,16 @@ void Profiler::setBaseGpuTime(int64_t gpuStart)
     baseGpuTime = gpuStart;
 }
 
+void Profiler::setBaseVsizeUsage(int64_t vsizeStart)
+{
+    baseVsizeUsage = vsizeStart;
+}
+
+void Profiler::setBaseRssUsage(int64_t rssStart)
+{
+    baseRssUsage = rssStart;
+}
+
 bool Profiler::hasBaseTimes()
 {
     return baseCpuTime != 0 || baseGpuTime != 0;
@@ -83,7 +108,9 @@ void Profiler::addCall(unsigned no,
                        unsigned program,
                        int64_t pixels,
                        int64_t gpuStart, int64_t gpuDuration,
-                       int64_t cpuStart, int64_t cpuDuration)
+                       int64_t cpuStart, int64_t cpuDuration,
+                       int64_t vsizeStart, int64_t vsizeDuration,
+                       int64_t rssStart, int64_t rssDuration)
 {
     if (gpuTimes && gpuStart) {
         gpuStart -= baseGpuTime;
@@ -109,12 +136,23 @@ void Profiler::addCall(unsigned no,
         pixels = 0;
     }
 
+    if (!memoryUsage || !vsizeStart || !rssStart) {
+        vsizeStart = 0;
+        vsizeDuration = 0;
+        rssStart = 0;
+        rssDuration = 0;
+    }
+
     std::cout << "call"
               << " " << no
               << " " << gpuStart
               << " " << gpuDuration
               << " " << cpuStart
               << " " << cpuDuration
+              << " " << vsizeStart
+              << " " << vsizeDuration
+              << " " << rssStart
+              << " " << rssDuration
               << " " << pixels
               << " " << program
               << " " << name
@@ -132,6 +170,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
     std::string type;
     static int64_t lastGpuTime;
     static int64_t lastCpuTime;
+    static int64_t lastVsizeUsage;
+    static int64_t lastRssUsage;
 
     if (in[0] == '#' || strlen(in) < 4)
         return;
@@ -139,6 +179,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
     if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
         lastGpuTime = 0;
         lastCpuTime = 0;
+        lastVsizeUsage = 0;
+        lastRssUsage = 0;
     }
 
     line >> type;
@@ -151,6 +193,10 @@ void Profiler::parseLine(const char* in, Profile* profile)
              >> call.gpuDuration
              >> call.cpuStart
              >> call.cpuDuration
+             >> call.vsizeStart
+             >> call.vsizeDuration
+             >> call.rssStart
+             >> call.rssDuration
              >> call.pixels
              >> call.program
              >> call.name;
@@ -163,6 +209,14 @@ void Profiler::parseLine(const char* in, Profile* profile)
             lastCpuTime = call.cpuStart + call.cpuDuration;
         }
 
+        if (lastVsizeUsage < call.vsizeStart + call.vsizeDuration) {
+            lastVsizeUsage = call.vsizeStart + call.vsizeDuration;
+        }
+
+        if (lastRssUsage < call.rssStart + call.rssDuration) {
+            lastRssUsage = call.rssStart + call.rssDuration;
+        }
+
         profile->calls.push_back(call);
 
         if (call.pixels >= 0) {
@@ -174,6 +228,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
             program.cpuTotal += call.cpuDuration;
             program.gpuTotal += call.gpuDuration;
             program.pixelTotal += call.pixels;
+            program.vsizeTotal += call.vsizeDuration;
+            program.rssTotal += call.rssDuration;
             program.calls.push_back(profile->calls.size() - 1);
         }
     } else if (type.compare("frame_end") == 0) {
@@ -183,15 +239,21 @@ void Profiler::parseLine(const char* in, Profile* profile)
         if (frame.no == 0) {
             frame.gpuStart = 0;
             frame.cpuStart = 0;
+            frame.vsizeStart = 0;
+            frame.rssStart = 0;
             frame.calls.begin = 0;
         } else {
             frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
             frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+            frame.vsizeStart = profile->frames.back().vsizeStart + profile->frames.back().vsizeDuration;
+            frame.rssStart = profile->frames.back().rssStart + profile->frames.back().rssDuration;
             frame.calls.begin = profile->frames.back().calls.end + 1;
         }
 
         frame.gpuDuration = lastGpuTime - frame.gpuStart;
         frame.cpuDuration = lastCpuTime - frame.cpuStart;
+        frame.vsizeDuration = lastVsizeUsage - frame.vsizeStart;
+        frame.rssDuration = lastRssUsage - frame.rssStart;
         frame.calls.end = profile->calls.size() - 1;
 
         profile->frames.push_back(frame);
index d8332420c63fc6ce622fd300315d275a85ba0db2..e3ae016be7fa654b99e497e64fdc3c7ef914cfb8 100644 (file)
@@ -1,6 +1,7 @@
 /**************************************************************************
  *
  * Copyright 2012 VMware, Inc.
+ * Copyright 2013 Intel, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -45,6 +46,11 @@ struct Profile {
         int64_t cpuStart;
         int64_t cpuDuration;
 
+        int64_t vsizeStart;
+        int64_t vsizeDuration;
+        int64_t rssStart;
+        int64_t rssDuration;
+
         int64_t pixels;
 
         std::string name;
@@ -59,6 +65,11 @@ struct Profile {
         int64_t cpuStart;
         int64_t cpuDuration;
 
+        int64_t vsizeStart;
+        int64_t vsizeDuration;
+        int64_t rssStart;
+        int64_t rssDuration;
+
         /* Indices to profile->calls array */
         struct {
             unsigned begin;
@@ -72,6 +83,8 @@ struct Profile {
         uint64_t gpuTotal;
         uint64_t cpuTotal;
         uint64_t pixelTotal;
+        int64_t vsizeTotal;
+        int64_t rssTotal;
 
         /* Indices to profile->calls array */
         std::vector<unsigned> calls;
@@ -88,14 +101,16 @@ public:
     Profiler();
     ~Profiler();
 
-    void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_);
+    void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_);
 
     void addCall(unsigned no,
                  const char* name,
                  unsigned program,
                  int64_t pixels,
                  int64_t gpuStart, int64_t gpuDuration,
-                 int64_t cpuStart, int64_t cpuDuration);
+                 int64_t cpuStart, int64_t cpuDuration,
+                 int64_t vsizeStart, int64_t vsizeDuration,
+                 int64_t rssStart, int64_t rssDuration);
 
     void addFrameEnd();
 
@@ -103,9 +118,13 @@ public:
 
     void setBaseCpuTime(int64_t cpuStart);
     void setBaseGpuTime(int64_t gpuStart);
+    void setBaseVsizeUsage(int64_t vsizeStart);
+    void setBaseRssUsage(int64_t rssStart);
 
     int64_t getBaseCpuTime();
     int64_t getBaseGpuTime();
+    int64_t getBaseVsizeUsage();
+    int64_t getBaseRssUsage();
 
     static void parseLine(const char* line, Profile* profile);
 
@@ -113,10 +132,13 @@ private:
     int64_t baseGpuTime;
     int64_t baseCpuTime;
     int64_t minCpuTime;
+    int64_t baseVsizeUsage;
+    int64_t baseRssUsage;
 
     bool cpuTimes;
     bool gpuTimes;
     bool pixelsDrawn;
+    bool memoryUsage;
 };
 }
 
diff --git a/dispatch/d3d8imports.hpp b/dispatch/d3d8imports.hpp
new file mode 100644 (file)
index 0000000..d081379
--- /dev/null
@@ -0,0 +1,39 @@
+/**************************************************************************
+ *
+ * Copyright 2012 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+/*
+ * Central place for all D3D8 includes, and respective OS dependent headers.
+ */
+
+#ifndef _D3D8IMPORTS_HPP_
+#define _D3D8IMPORTS_HPP_
+
+#include <windows.h>
+
+#include "compat.h"
+
+#include <d3d8.h>
+
+#endif /* _D3D8IMPORTS_HPP_ */
index a07d768bd67d1fd9707684ecf16772055c1f7e12..b4e81873dd0939a6cabd92465481790db2227a3a 100644 (file)
 #define D3DFMT_NV12 ((D3DFORMAT)MAKEFOURCC('N','V','1','2'))
 #endif
 
+#ifndef D3DFMT_YV12
+#define D3DFMT_YV12 ((D3DFORMAT)MAKEFOURCC('Y','V','1','2'))
+#endif
+
 #ifndef D3DFMT_RAWZ
 #define D3DFMT_RAWZ ((D3DFORMAT)MAKEFOURCC('R','A','W','Z'))
 #endif
index f985ed1839bf4ea3340a1529ae3afa4fc93fb227..13853b34ace26833f2884fecd66edd97a5c6c083 100644 (file)
@@ -45,18 +45,18 @@ struct IDXGIFactoryDWM: public IUnknown
     virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain) = 0;
 };
 
-struct IDXGISwapChainDWM: public IDXGIDeviceSubObject 
-{ 
-    virtual HRESULT STDMETHODCALLTYPE Present (UINT SyncInterval, UINT Flags) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetBuffer (UINT Buffer, REFIID riid, void **ppSurface) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetDesc (DXGI_SWAP_CHAIN_DESC *pDesc) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE ResizeBuffers (UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE ResizeTarget (const DXGI_MODE_DESC *pNewTargetParameters) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetContainingOutput (IDXGIOutput **ppOutput) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics (DXGI_FRAME_STATISTICS *pStats) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount (UINT *pLastPresentCount) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE SetFullscreenState (BOOL Fullscreen, IDXGIOutput *pTarget) = 0; 
-    virtual HRESULT STDMETHODCALLTYPE GetFullscreenState (BOOL *pFullscreen, IDXGIOutput **ppTarget) = 0; 
-}; 
+struct IDXGISwapChainDWM: public IDXGIDeviceSubObject
+{
+    virtual HRESULT STDMETHODCALLTYPE Present(UINT SyncInterval, UINT Flags) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetBuffer(UINT Buffer, REFIID riid, void **ppSurface) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc) = 0;
+    virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) = 0;
+    virtual HRESULT STDMETHODCALLTYPE ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget) = 0;
+};
 
 #endif /* _DXGIINT_H_ */
index ad11304361d979a76dcdbfda165eb9ec01daf790..8a5ecfdcf5c4a3821d2dfc0dc5efbe4fc2742555 100644 (file)
@@ -44,8 +44,6 @@
 #endif
 
 
-typedef struct _DXVA2_PVP_SETKEY DXVA2_PVP_SETKEY; /* XXX */
-
 typedef struct _DXVA2_DECODEBUFFERDESC {
     IDirect3DSurface9 *pRenderTarget;
     DWORD CompressedBufferType;
@@ -112,6 +110,16 @@ static const GUID IID_IDirect3DDXVAExtensionDevice9 = {0x00000000,0x0000,0x0000,
 static const GUID IID_IDirect3DDxva2Container9 = {0x126D0349,0x4787,0x4AA6,{0x8E,0x1B,0x40,0xC1,0x77,0xC6,0x0A,0x01}};
 
 
+typedef struct DECLSPEC_ALIGN(16) _DXVA2_PVP_KEY128
+{
+    BYTE Data[16];
+} DXVA2_PVP_KEY128;
+
+typedef struct _DXVA2_PVP_SETKEY
+{
+    DXVA2_PVP_KEY128  ContentKey;
+} DXVA2_PVP_SETKEY;
+
 class IDirect3DDecodeDevice9 : public IUnknown
 {
 public:
index 7f22e70dfb3953a014da36ffe38cfc9b2ec8c03d..49cf177ac91887e6cc2b9f93126ae19fcc3ab93f 100644 (file)
 #include <GLES2/gl2platform.h>
 
 
+// OpenGL ES 2.0
+
+// avoid conflicting with GL_NV_multisample_coverage
+#define GL_NV_coverage_sample
+#include "GLES2/gl2ext.h"
+
+
 // OpenGL ES 1.1
 typedef int32_t  GLfixed;
 typedef int32_t  GLclampx;
@@ -77,18 +84,8 @@ typedef int32_t  GLclampx;
 #define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES                  0x8B9F
 #endif
 
-// avoid conflict with GL_EXT_framebuffer_multisample
-#define GL_EXT_multisampled_render_to_texture
-
 #undef _glext_h_
 #include "GLES/glext.h"
 
 
-// OpenGL ES 2.0
-
-// avoid conflicting with GL_NV_multisample_coverage
-#define GL_NV_coverage_sample
-#include "GLES2/gl2ext.h"
-
-
 #endif /* _EGLIMPORTS_HPP_ */
index 6a8ebe2cd043a4608191db584f2b78274ba09143..a69ce2fff0ef25a2f0293e392e273f9b4ecc1b4d 100644 (file)
@@ -393,6 +393,9 @@ void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
 
 void ApiTrace::findFrameStart(ApiTraceFrame *frame)
 {
+    if (!frame)
+        return;
+
     if (frame->isLoaded()) {
         emit foundFrameStart(frame);
     } else {
@@ -402,6 +405,9 @@ void ApiTrace::findFrameStart(ApiTraceFrame *frame)
 
 void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
 {
+    if (!frame)
+        return;
+
     if (frame->isLoaded()) {
         emit foundFrameEnd(frame);
     } else {
index 0b945772b96916bbe470289865eedcfba9e96b33..2dd3d8e94263b3cf95d5bff59b5381282ac8f0ab 100644 (file)
@@ -228,8 +228,8 @@ void HistogramView::paintEvent(QPaintEvent *)
 qint64 HistogramView::itemAtPosition(QPoint pos) {
     double dvdx = m_viewWidth / (double)width();
 
-    qint64 left = qFloor(dvdx) * (pos.x() - 1) + m_viewLeft;
-    qint64 right = qCeil(dvdx) * (pos.x() + 1) + m_viewLeft;
+    qint64 left = qFloor(dvdx * (pos.x() - 1)) + m_viewLeft;
+    qint64 right = qCeil(dvdx * (pos.x() + 1)) + m_viewLeft;
 
     qint64 longestIndex = 0;
     qint64 longestValue = 0;
index 0ed50ed8f2b33506f931f570d9662430d59712ec..471dec7939c7eccd88c4d1c882a121ea2a587b08 100644 (file)
@@ -3,6 +3,9 @@
 #include "apitrace.h"
 #include "apitracecall.h"
 
+#include "os_string.hpp"
+#include "os_process.hpp"
+
 #include <QApplication>
 #include <QMetaType>
 #include <QVariant>
@@ -32,6 +35,15 @@ int main(int argc, char **argv)
     qRegisterMetaType<ApiTrace::SearchResult>();
     qRegisterMetaType<ApiTrace::SearchRequest>();
     qRegisterMetaType<QList<QImage> >();
+
+#ifndef Q_OS_WIN
+    os::String currentProcess = os::getProcessName();
+    currentProcess.trimFilename();
+    QString path = qgetenv("PATH");
+    path = QLatin1String(currentProcess.str()) + QLatin1String(":") + path;
+    qputenv("PATH", path.toLatin1());
+#endif
+
     QStringList args = app.arguments();
 
     int i = 1;
index caf9e370236ebed41d8aa29409cc3e253b1457a4..d6ebd2f9e1ecbe3a107222b684cda6c1e826c7e3 100644 (file)
@@ -48,6 +48,7 @@ MainWindow::MainWindow()
       m_nonDefaultsLookupEvent(0)
 {
     m_ui.setupUi(this);
+    updateActionsState(false);
     initObjects();
     initConnections();
 }
@@ -228,11 +229,7 @@ void MainWindow::replayProfile()
 void MainWindow::replayStop()
 {
     m_retracer->quit();
-    m_ui.actionStop->setEnabled(false);
-    m_ui.actionReplay->setEnabled(true);
-    m_ui.actionProfile->setEnabled(true);
-    m_ui.actionLookupState->setEnabled(true);
-    m_ui.actionShowThumbnails->setEnabled(true);
+    updateActionsState(true, true);
 }
 
 void MainWindow::newTraceFile(const QString &fileName)
@@ -243,18 +240,11 @@ void MainWindow::newTraceFile(const QString &fileName)
     m_trace->setFileName(fileName);
 
     if (fileName.isEmpty()) {
-        m_ui.actionReplay->setEnabled(false);
-        m_ui.actionProfile->setEnabled(false);
-        m_ui.actionLookupState->setEnabled(false);
-        m_ui.actionShowThumbnails->setEnabled(false);
+        updateActionsState(false);
         setWindowTitle(tr("QApiTrace"));
     } else {
+        updateActionsState(true);
         QFileInfo info(fileName);
-        m_ui.actionReplay->setEnabled(true);
-        m_ui.actionProfile->setEnabled(true);
-        m_ui.actionLookupState->setEnabled(true);
-        m_ui.actionShowThumbnails->setEnabled(true);
-        m_ui.actionTrim->setEnabled(true);
         setWindowTitle(
             tr("QApiTrace - %1").arg(info.fileName()));
     }
@@ -262,12 +252,7 @@ void MainWindow::newTraceFile(const QString &fileName)
 
 void MainWindow::replayFinished(const QString &message)
 {
-    m_ui.actionStop->setEnabled(false);
-    m_ui.actionReplay->setEnabled(true);
-    m_ui.actionProfile->setEnabled(true);
-    m_ui.actionLookupState->setEnabled(true);
-    m_ui.actionShowThumbnails->setEnabled(true);
-
+    updateActionsState(true);
     m_progressBar->hide();
     statusBar()->showMessage(message, 2000);
     m_stateEvent = 0;
@@ -280,11 +265,7 @@ void MainWindow::replayFinished(const QString &message)
 
 void MainWindow::replayError(const QString &message)
 {
-    m_ui.actionStop->setEnabled(false);
-    m_ui.actionReplay->setEnabled(true);
-    m_ui.actionProfile->setEnabled(true);
-    m_ui.actionLookupState->setEnabled(true);
-    m_ui.actionShowThumbnails->setEnabled(true);
+    updateActionsState(true);
     m_stateEvent = 0;
     m_nonDefaultsLookupEvent = 0;
 
@@ -936,6 +917,47 @@ void MainWindow::initConnections()
             this, SLOT(slotJumpTo(int)));
 }
 
+void MainWindow::updateActionsState(bool traceLoaded, bool stopped)
+{
+    if (traceLoaded) {
+        /* Edit */
+        m_ui.actionFind          ->setEnabled(true);
+        m_ui.actionGo            ->setEnabled(true);
+        m_ui.actionGoFrameStart  ->setEnabled(true);
+        m_ui.actionGoFrameEnd    ->setEnabled(true);
+
+        /* Trace */
+        if (stopped) {
+            m_ui.actionStop->setEnabled(false);
+            m_ui.actionReplay->setEnabled(true);
+        }
+        else {
+            m_ui.actionStop->setEnabled(true);
+            m_ui.actionReplay->setEnabled(false);
+        }
+
+        m_ui.actionProfile       ->setEnabled(true);
+        m_ui.actionLookupState   ->setEnabled(true);
+        m_ui.actionShowThumbnails->setEnabled(true);
+        m_ui.actionTrim          ->setEnabled(true);
+    }
+    else {
+        /* Edit */
+        m_ui.actionFind          ->setEnabled(false);
+        m_ui.actionGo            ->setEnabled(false);
+        m_ui.actionGoFrameStart  ->setEnabled(false);
+        m_ui.actionGoFrameEnd    ->setEnabled(false);
+
+        /* Trace */
+        m_ui.actionReplay        ->setEnabled(false);
+        m_ui.actionProfile       ->setEnabled(false);
+        m_ui.actionStop          ->setEnabled(false);
+        m_ui.actionLookupState   ->setEnabled(false);
+        m_ui.actionShowThumbnails->setEnabled(false);
+        m_ui.actionTrim          ->setEnabled(false);
+    }
+}
+
 void MainWindow::closeEvent(QCloseEvent * event)
 {
     m_profileDialog->close();
index 2248127f76aae57b8acd4728c7b090ad628564da..78267efca4c9f5cd98bb4eb0b48a5bc980ae3ceb 100644 (file)
@@ -98,6 +98,7 @@ private slots:
 private:
     void initObjects();
     void initConnections();
+    void updateActionsState(bool traceLoaded, bool stopped = true);
     void newTraceFile(const QString &fileName);
     void replayTrace(bool dumpState, bool dumpThumbnails);
     void trimEvent();
index 738367e1830c394f2808ab8a234355dd8de8e48a..2928ed63f321f31e34667e2448e1b8f765f2fdbf 100644 (file)
@@ -137,19 +137,6 @@ Retracer::Retracer(QObject *parent)
       m_profilePixels(false)
 {
     qRegisterMetaType<QList<ApiTraceError> >();
-
-#ifdef Q_OS_WIN
-    QString format = QLatin1String("%1;");
-#else
-    QString format = QLatin1String("%1:");
-#endif
-    QString buildPath = format.arg(APITRACE_BINARY_DIR);
-    m_processEnvironment = QProcessEnvironment::systemEnvironment();
-    m_processEnvironment.insert("PATH", buildPath +
-                                m_processEnvironment.value("PATH"));
-
-    qputenv("PATH",
-            m_processEnvironment.value("PATH").toLatin1());
 }
 
 QString Retracer::fileName() const
index e889d8887cf3753ce609d86daefa6233d7134ddf..af1a3d9f7b727b70f1173dcc058980bba590f6a6 100644 (file)
@@ -65,8 +65,6 @@ private:
     bool m_profileGpu;
     bool m_profileCpu;
     bool m_profilePixels;
-
-    QProcessEnvironment m_processEnvironment;
 };
 
 #endif
index fcfdf4661241ff30858f0f5332d83fbd30bcc126..b8e438d9ddddc3c7fe49307f2b41de6778b47854 100644 (file)
@@ -50,7 +50,7 @@ void TraceDialog::browse()
             tr("Find the application"),
             QDir::currentPath());
 
-    if (isFileOk(fileName)) {
+    if (!fileName.isEmpty() && isFileOk(fileName)) {
         applicationEdit->setText(fileName);
     }
 }
index 6f4d0b9350da147249bbf1e522fd8c51d6de4384..8d57e525f0617b901a124369f1deb07da2c995a4 100644 (file)
@@ -15,16 +15,6 @@ TraceProcess::TraceProcess(QObject *parent)
             this, SLOT(traceFinished()));
     connect(m_process, SIGNAL(error(QProcess::ProcessError)),
             this, SLOT(traceError(QProcess::ProcessError)));
-
-#ifdef Q_OS_WIN
-    QString format = QLatin1String("%1;");
-#else
-    QString format = QLatin1String("%1:");
-#endif
-    QString buildPath = format.arg(APITRACE_BINARY_DIR);
-    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-    env.insert("PATH", buildPath + env.value("PATH"));
-    qputenv("PATH", env.value("PATH").toLatin1());
 }
 
 TraceProcess::~TraceProcess()
index c23475d50d86a62e078594f6786073628f4ebd9a..34639c634d4893ad55d38617ebc0a7307c9f53c7 100644 (file)
@@ -15,16 +15,6 @@ TrimProcess::TrimProcess(QObject *parent)
             this, SLOT(trimFinished()));
     connect(m_process, SIGNAL(error(QProcess::ProcessError)),
             this, SLOT(trimError(QProcess::ProcessError)));
-
-#ifdef Q_OS_WIN
-    QString format = QLatin1String("%1;");
-#else
-    QString format = QLatin1String("%1:");
-#endif
-    QString buildPath = format.arg(APITRACE_BINARY_DIR);
-    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-    env.insert("PATH", buildPath + env.value("PATH"));
-    qputenv("PATH", env.value("PATH").toLatin1());
 }
 
 TrimProcess::~TrimProcess()
index 7cbb3d1e3bea979532b80bd7bdbf620b80822d9a..06f4503af50d92cf3015ce7baaecb3aaed588252 100644 (file)
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="url" stdset="0">
+       <property name="url">
         <url>
          <string>about:blank</string>
         </url>
    </property>
   </action>
   <action name="actionReplay">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="icon">
     <iconset resource="../qapitrace.qrc">
      <normaloff>:/resources/media-playback-start.png</normaloff>:/resources/media-playback-start.png</iconset>
    </property>
   </action>
   <action name="actionStop">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="icon">
     <iconset resource="../qapitrace.qrc">
      <normaloff>:/resources/media-playback-stop.png</normaloff>:/resources/media-playback-stop.png</iconset>
    </property>
   </action>
   <action name="actionLookupState">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="icon">
     <iconset resource="../qapitrace.qrc">
      <normaloff>:/resources/media-record.png</normaloff>:/resources/media-record.png</iconset>
    </property>
   </action>
   <action name="actionShowThumbnails">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="text">
     <string>Show &amp;Thumbnails</string>
    </property>
    </property>
   </action>
   <action name="actionTrim">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="text">
     <string>Tr&amp;im</string>
    </property>
      <normaloff>:/resources/document-new.png</normaloff>:/resources/document-new.png</iconset>
    </property>
    <property name="text">
-    <string>New</string>
+    <string>&amp;New...</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+N</string>
    </property>
   </action>
   <action name="actionFind">
      <normaloff>:/resources/edit-find.png</normaloff>:/resources/edit-find.png</iconset>
    </property>
    <property name="text">
-    <string>Find</string>
+    <string>&amp;Find</string>
    </property>
    <property name="shortcut">
     <string>Ctrl+F</string>
    </property>
   </action>
   <action name="actionProfile">
-   <property name="enabled">
-    <bool>false</bool>
-   </property>
    <property name="text">
     <string>&amp;Profile</string>
    </property>
index a3e5240a540b2ec44a2751557b9652650bb567f5..f6eccf445372471608fca231948b7c8540c20b12 100644 (file)
@@ -47,7 +47,7 @@
      <item>
       <widget class="QPushButton" name="browseButton">
        <property name="text">
-        <string>Browse</string>
+        <string>Browse...</string>
        </property>
        <property name="flat">
         <bool>false</bool>
index d4c486277ca0f84ad69fb045a09a0057a5f40472..b1f7b284d024001b83d444db5b00900fc98c4859 100644 (file)
@@ -163,6 +163,7 @@ _getLockSize(D3DFORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth
 
 #if DIRECT3D_VERSION >= 0x900
     case D3DFMT_NV12:
+    case D3DFMT_YV12:
         return (Height + ((Height + 1) / 2)) * RowPitch;
 
     case D3DFMT_NULL:
index b4ec2512e8fca0b5d72cde652055b61d422bf104..c4fe9bf9c866b5aa19c0b4283a9acf3998c39102 100644 (file)
@@ -329,11 +329,19 @@ _glArrayPointer_size(GLint size, GLenum type, GLsizei stride, GLsizei count)
 #define _glVertexAttribPointerARB_size(size, type, normalized, stride, count) _glArrayPointer_size(size, type, stride, count)
 #define _glVertexAttribPointerNV_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
 
+/**
+ * Same as glGetIntegerv, but passing the result in the return value.
+ */
+static inline GLint
+_glGetInteger(GLenum pname) {
+    GLint param = 0;
+    _glGetIntegerv(pname, &param);
+    return param;
+}
+
 static inline GLint
 _element_array_buffer_binding(void) {
-    GLint element_array_buffer = 0;
-    _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &element_array_buffer);
-    return element_array_buffer;
+    return _glGetInteger(GL_ELEMENT_ARRAY_BUFFER_BINDING);
 }
 
 static inline GLuint
index 058ada6d188554933b91283c5435c4087794336f..e915e4f4ab347c5db614a6b624c0afd480f7c84b 100644 (file)
@@ -91,6 +91,11 @@ getModuleName(char *szModuleName, size_t n, const char *szFilename) {
 }
 
 
+#define USE_SHARED_MEM 1
+
+
+#if USE_SHARED_MEM
+
 #define SHARED_MEM_SIZE 4096
 
 static LPVOID pSharedMem = NULL;
@@ -179,3 +184,5 @@ GetSharedMem(LPSTR lpszDst, size_t n) {
     *lpszDst = '\0';
 }
 
+
+#endif /* USE_SHARED_MEM */
index 86992b83e94e3923b324e42378d446fa5b2073ee..c60bc451570ce272f9e26b6bdf9d9944453bd2af 100644 (file)
@@ -57,10 +57,7 @@ static CRITICAL_SECTION Mutex = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0};
 static void
 debugPrintf(const char *format, ...)
 {
-#if VERBOSITY > 0
-    static char buf[4096];
-
-    EnterCriticalSection(&Mutex);
+    char buf[512];
 
     va_list ap;
     va_start(ap, format);
@@ -68,9 +65,6 @@ debugPrintf(const char *format, ...)
     va_end(ap);
 
     OutputDebugStringA(buf);
-
-    LeaveCriticalSection(&Mutex);
-#endif
 }
 
 
@@ -205,13 +199,15 @@ replaceModule(HMODULE hModule,
     while (pOriginalFirstThunk->u1.Function) {
         PIMAGE_IMPORT_BY_NAME pImport = (PIMAGE_IMPORT_BY_NAME)((PBYTE)hModule + pOriginalFirstThunk->u1.AddressOfData);
         const char* szFunctionName = (const char* )pImport->Name;
-        debugPrintf("      hooking %s->%s!%s\n", szModule,
-                getImportDescriptionName(hModule, pImportDescriptor),
-                szFunctionName);
+        if (VERBOSITY > 0) {
+            debugPrintf("      hooking %s->%s!%s\n", szModule,
+                    getImportDescriptionName(hModule, pImportDescriptor),
+                    szFunctionName);
+        }
 
         PROC pNewProc = GetProcAddress(hNewModule, szFunctionName);
         if (!pNewProc) {
-            debugPrintf("  warning: no replacement for %s\n", szFunctionName);
+            debugPrintf("warning: no replacement for %s\n", szFunctionName);
         } else {
             LPVOID *lpOldAddress = (LPVOID *)(&pFirstThunk->u1.Function);
             replaceAddress(lpOldAddress, (LPVOID)pNewProc);
@@ -257,9 +253,9 @@ replaceImport(HMODULE hModule,
               const char *pszDllName,
               HMODULE hNewModule)
 {
-#if NOOP
-    return TRUE;
-#endif
+    if (NOOP) {
+        return TRUE;
+    }
 
     PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = getImportDescriptor(hModule, szModule, pszDllName);
     if (pImportDescriptor == NULL) {
@@ -339,15 +335,17 @@ hookAllModules(void)
     MODULEENTRY32 me32;
     me32.dwSize = sizeof me32;
 
-    static bool first = true;
-    if (first) {
-        if (Module32First(hModuleSnap, &me32)) {
-            debugPrintf("  modules:\n");
-            do  {
-                debugPrintf("     %s\n", me32.szExePath);
-            } while (Module32Next(hModuleSnap, &me32));
+    if (VERBOSITY > 0) {
+        static bool first = true;
+        if (first) {
+            if (Module32First(hModuleSnap, &me32)) {
+                debugPrintf("  modules:\n");
+                do  {
+                    debugPrintf("     %s\n", me32.szExePath);
+                } while (Module32Next(hModuleSnap, &me32));
+            }
+            first = false;
         }
-        first = false;
     }
 
     if (Module32First(hModuleSnap, &me32)) {
@@ -382,24 +380,26 @@ MyLoadLibraryA(LPCSTR lpLibFileName)
         debugPrintf("%s(\"%s\")\n", __FUNCTION__, lpLibFileName);
     }
 
-    const char *szBaseName = getBaseName(lpLibFileName);
-    for (unsigned i = 0; i < numReplacements; ++i) {
-        if (stricmp(szBaseName, replacements[i].szMatchModule) == 0) {
-            debugPrintf("%s(\"%s\")\n", __FUNCTION__, lpLibFileName);
+    if (VERBOSITY > 0) {
+        const char *szBaseName = getBaseName(lpLibFileName);
+        for (unsigned i = 0; i < numReplacements; ++i) {
+            if (stricmp(szBaseName, replacements[i].szMatchModule) == 0) {
+                debugPrintf("%s(\"%s\")\n", __FUNCTION__, lpLibFileName);
 #ifdef __GNUC__
-            void *caller = __builtin_return_address (0);
-
-            HMODULE hModule = 0;
-            BOOL bRet = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
-                                     (LPCTSTR)caller,
-                                     &hModule);
-            assert(bRet);
-            char szCaller[256];
-            DWORD dwRet = GetModuleFileNameA(hModule, szCaller, sizeof szCaller);
-            assert(dwRet);
-            debugPrintf("  called from %s\n", szCaller);
+                void *caller = __builtin_return_address (0);
+
+                HMODULE hModule = 0;
+                BOOL bRet = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+                                         (LPCTSTR)caller,
+                                         &hModule);
+                assert(bRet);
+                char szCaller[256];
+                DWORD dwRet = GetModuleFileNameA(hModule, szCaller, sizeof szCaller);
+                assert(dwRet);
+                debugPrintf("  called from %s\n", szCaller);
 #endif
-            break;
+                break;
+            }
         }
     }
 
@@ -456,29 +456,33 @@ MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
         }
     }
 
-#if !NOOP
-    char szModule[256];
-    DWORD dwRet = GetModuleFileNameA(hModule, szModule, sizeof szModule);
-    assert(dwRet);
-    const char *szBaseName = getBaseName(szModule);
+    if (!NOOP) {
+        char szModule[256];
+        DWORD dwRet = GetModuleFileNameA(hModule, szModule, sizeof szModule);
+        assert(dwRet);
+        const char *szBaseName = getBaseName(szModule);
 
-    for (unsigned i = 0; i < numReplacements; ++i) {
+        for (unsigned i = 0; i < numReplacements; ++i) {
 
-        if (stricmp(szBaseName, replacements[i].szMatchModule) == 0) {
-            debugPrintf("  %s(\"%s\", \"%s\")\n", __FUNCTION__, szModule, lpProcName);
-            FARPROC pProcAddress = GetProcAddress(replacements[i].hReplaceModule, lpProcName);
-            if (pProcAddress) {
-                if (VERBOSITY >= 2) {
-                    debugPrintf("      replacing %s!%s\n", szBaseName, lpProcName);
+            if (stricmp(szBaseName, replacements[i].szMatchModule) == 0) {
+                if (VERBOSITY > 0) {
+                    debugPrintf("  %s(\"%s\", \"%s\")\n", __FUNCTION__, szModule, lpProcName);
+                }
+                FARPROC pProcAddress = GetProcAddress(replacements[i].hReplaceModule, lpProcName);
+                if (pProcAddress) {
+                    if (VERBOSITY >= 2) {
+                        debugPrintf("      replacing %s!%s\n", szBaseName, lpProcName);
+                    }
+                    return pProcAddress;
+                } else {
+                    if (VERBOSITY > 0) {
+                        debugPrintf("      ignoring %s!%s\n", szBaseName, lpProcName);
+                    }
+                    break;
                 }
-                return pProcAddress;
-            } else {
-                debugPrintf("      ignoring %s!%s\n", szBaseName, lpProcName);
-                break;
             }
         }
     }
-#endif
 
     return GetProcAddress(hModule, lpProcName);
 }
@@ -493,14 +497,18 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
 
     switch (fdwReason) {
     case DLL_PROCESS_ATTACH:
-        debugPrintf("DLL_PROCESS_ATTACH\n");
+        if (VERBOSITY > 0) {
+            debugPrintf("DLL_PROCESS_ATTACH\n");
+        }
 
         g_hThisModule = hinstDLL;
 
         {
             char szProcess[MAX_PATH];
             GetModuleFileNameA(NULL, szProcess, sizeof szProcess);
-            debugPrintf("  attached to %s\n", szProcess);
+            if (VERBOSITY > 0) {
+                debugPrintf("  attached to %s\n", szProcess);
+            }
         }
 
         /*
@@ -513,7 +521,7 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
          * - http://msdn.microsoft.com/en-us/library/ms682583
          */
 
-#if 0
+#if !USE_SHARED_MEM
         szNewDllName = getenv("INJECT_DLL");
         if (!szNewDllName) {
             debugPrintf("warning: INJECT_DLL not set\n");
@@ -524,7 +532,9 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
         GetSharedMem(szSharedMemCopy, sizeof szSharedMemCopy);
         szNewDllName = szSharedMemCopy;
 #endif
-        debugPrintf("  injecting %s\n", szNewDllName);
+        if (VERBOSITY > 0) {
+            debugPrintf("  injecting %s\n", szNewDllName);
+        }
 
         hNewModule = LoadLibraryA(szNewDllName);
         if (!hNewModule) {
@@ -565,7 +575,9 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
         break;
 
     case DLL_PROCESS_DETACH:
-        debugPrintf("DLL_PROCESS_DETACH\n");
+        if (VERBOSITY > 0) {
+            debugPrintf("DLL_PROCESS_DETACH\n");
+        }
         break;
     }
     return TRUE;
index 04e09598f98fa5c0d132e98597c85061b6ca24b8..5c62a72b1c067fa1ddfad9e0b40c51ae806c5b9f 100644 (file)
@@ -116,7 +116,7 @@ main(int argc, char *argv[])
     }
 
     const char *szDll = argv[1];
-#if 0
+#if !USE_SHARED_MEM
     SetEnvironmentVariableA("INJECT_DLL", szDll);
 #else
     SetSharedMem(szDll);
index 26659908ba9bd0bc46a57f6788beb6d5b0e67c87..5f831a4ef0045d2dff8a8cb090c0964485f9ea03 100644 (file)
@@ -102,6 +102,9 @@ if (WIN32 OR APPLE OR X11_FOUND)
 
         if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
             target_link_libraries (glretrace rt)
+            if (READPROC_H_FOUND)
+                target_link_libraries (glretrace proc)
+            endif ()
         endif ()
 
     endif ()
@@ -127,6 +130,9 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE)
 
     if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
         target_link_libraries (eglretrace rt)
+        if (READPROC_H_FOUND)
+            target_link_libraries (eglretrace proc)
+        endif ()
     endif ()
 
     install (TARGETS eglretrace RUNTIME DESTINATION bin) 
@@ -136,6 +142,10 @@ if (WIN32)
     if (DirectX_D3D8_INCLUDE_DIR) 
         include_directories (BEFORE SYSTEM ${DirectX_D3D8_INCLUDE_DIR})
         set (HAVE_D3D8 1)
+        set (D3DSTATE_SOURCES ${D3DSTATE_SOURCES}
+            d3d8state.cpp
+            d3d8state_images.cpp
+        )
     else ()
         set (HAVE_D3D8 0)
     endif ()
diff --git a/retrace/d3d8state.cpp b/retrace/d3d8state.cpp
new file mode 100644 (file)
index 0000000..60bdb6d
--- /dev/null
@@ -0,0 +1,134 @@
+/**************************************************************************
+ *
+ * Copyright 2011-2012 VMware, Inc.
+ * 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 <iostream>
+
+#include "d3d8imports.hpp"
+#include "d3dshader.hpp"
+#include "d3dstate.hpp"
+#include "json.hpp"
+
+
+namespace d3dstate {
+
+
+typedef HRESULT (STDMETHODCALLTYPE IDirect3DDevice8::*GetShaderFunctionMethod)(DWORD Handle, void* pData, DWORD* pSizeOfData);
+
+
+struct VertexShaderGetter
+{
+    HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
+        return pDevice->GetVertexShader(pHandle);
+    }
+    HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
+        return pDevice->GetVertexShaderFunction(Handle, pData, pSizeOfData);
+    }
+};
+
+struct PixelShaderGetter
+{
+    HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
+        return pDevice->GetPixelShader(pHandle);
+    }
+    HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
+        return pDevice->GetPixelShaderFunction(Handle, pData, pSizeOfData);
+    }
+};
+
+template<class Getter>
+inline void
+dumpShader(JSONWriter &json, IDirect3DDevice8 *pDevice, const char *name) {
+    Getter getter;
+    HRESULT hr;
+
+    DWORD dwShader = 0;
+    hr = getter.GetShader(pDevice, &dwShader);
+    if (FAILED(hr) || !dwShader) {
+        return;
+    }
+
+    DWORD SizeOfData = 0;
+
+    hr = getter.GetShaderFunction(pDevice, dwShader, NULL, &SizeOfData);
+    if (SUCCEEDED(hr)) {
+        void *pData;
+        pData = malloc(SizeOfData);
+        if (pData) {
+            hr = getter.GetShaderFunction(pDevice, dwShader, pData, &SizeOfData);
+            if (SUCCEEDED(hr)) {
+                IDisassemblyBuffer *pDisassembly = NULL;
+                hr = DisassembleShader((const DWORD *)pData, &pDisassembly);
+                if (SUCCEEDED(hr)) {
+                    json.beginMember(name);
+                    json.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */);
+                    json.endMember();
+                    pDisassembly->Release();
+                }
+
+            }
+            free(pData);
+        }
+    }
+}
+
+static void
+dumpShaders(JSONWriter &json, IDirect3DDevice8 *pDevice)
+{
+    json.beginMember("shaders");
+    json.beginObject();
+
+    dumpShader<VertexShaderGetter>(json, pDevice, "vertex");
+    dumpShader<PixelShaderGetter>(json, pDevice, "pixel");
+
+    json.endObject();
+    json.endMember(); // shaders
+}
+
+void
+dumpDevice(std::ostream &os, IDirect3DDevice8 *pDevice)
+{
+    JSONWriter json(os);
+
+    /* TODO */
+    json.beginMember("parameters");
+    json.beginObject();
+    json.endObject();
+    json.endMember(); // parameters
+
+    dumpShaders(json, pDevice);
+
+    json.beginMember("textures");
+    json.beginObject();
+    json.endObject();
+    json.endMember(); // textures
+
+    dumpFramebuffer(json, pDevice);
+}
+
+
+} /* namespace d3dstate */
diff --git a/retrace/d3d8state_images.cpp b/retrace/d3d8state_images.cpp
new file mode 100644 (file)
index 0000000..89d4e06
--- /dev/null
@@ -0,0 +1,164 @@
+/**************************************************************************
+ *
+ * Copyright 2011-2012 VMware, Inc.
+ * 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 <assert.h>
+#include <stdint.h>
+
+#include "image.hpp"
+#include "json.hpp"
+#include "d3d8imports.hpp"
+#include "d3dstate.hpp"
+
+
+namespace d3dstate {
+
+
+static image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice,
+                     IDirect3DSurface8 *pRenderTarget) {
+    image::Image *image = NULL;
+    D3DSURFACE_DESC Desc;
+    IDirect3DSurface8 *pStagingSurface = NULL;
+    D3DLOCKED_RECT LockedRect;
+    const unsigned char *src;
+    unsigned char *dst;
+    HRESULT hr;
+
+    if (!pRenderTarget) {
+        return NULL;
+    }
+
+    hr = pRenderTarget->GetDesc(&Desc);
+    assert(SUCCEEDED(hr));
+
+    if (Desc.Format != D3DFMT_X8R8G8B8 &&
+        Desc.Format != D3DFMT_A8R8G8B8 &&
+        Desc.Format != D3DFMT_R5G6B5) {
+        std::cerr << "warning: unsupported D3DFORMAT " << Desc.Format << "\n";
+        goto no_staging;
+    }
+
+    hr = pDevice->CreateImageSurface(Desc.Width, Desc.Height, Desc.Format, &pStagingSurface);
+    if (FAILED(hr)) {
+        goto no_staging;
+    }
+
+    hr = pDevice->CopyRects(pRenderTarget, NULL, 0, pStagingSurface, NULL);
+    if (FAILED(hr)) {
+        goto no_rendertargetdata;
+    }
+
+    hr = pStagingSurface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY);
+    if (FAILED(hr)) {
+        goto no_rendertargetdata;
+    }
+
+    image = new image::Image(Desc.Width, Desc.Height, 3, true);
+    if (!image) {
+        goto no_image;
+    }
+
+    dst = image->start();
+    src = (const unsigned char *)LockedRect.pBits;
+    for (unsigned y = 0; y < Desc.Height; ++y) {
+        if (Desc.Format == D3DFMT_R5G6B5) {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                uint32_t pixel = ((const uint16_t *)src)[x];
+                dst[3*x + 0] = (( pixel        & 0x1f) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 1] = (((pixel >>  5) & 0x3f) * (2*0xff) + 0x3f) / (2*0x3f);
+                dst[3*x + 2] = (( pixel >> 11        ) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 3] = 0xff;
+            }
+        } else {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                dst[3*x + 0] = src[4*x + 2];
+                dst[3*x + 1] = src[4*x + 1];
+                dst[3*x + 2] = src[4*x + 0];
+            }
+        }
+
+        src += LockedRect.Pitch;
+        dst += image->stride();
+    }
+
+no_image:
+    pStagingSurface->UnlockRect();
+no_rendertargetdata:
+    pStagingSurface->Release();
+no_staging:
+    return image;
+}
+
+
+image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice) {
+    HRESULT hr;
+
+    IDirect3DSurface8 *pRenderTarget = NULL;
+    hr = pDevice->GetRenderTarget(&pRenderTarget);
+    if (FAILED(hr)) {
+        return NULL;
+    }
+    assert(pRenderTarget);
+
+    image::Image *image = NULL;
+    if (pRenderTarget) {
+        image = getRenderTargetImage(pDevice, pRenderTarget);
+        pRenderTarget->Release();
+    }
+
+    return image;
+}
+
+
+void
+dumpFramebuffer(JSONWriter &json, IDirect3DDevice8 *pDevice)
+{
+    HRESULT hr;
+
+    json.beginMember("framebuffer");
+    json.beginObject();
+
+    IDirect3DSurface8 *pRenderTarget = NULL;
+    hr = pDevice->GetRenderTarget(&pRenderTarget);
+    if (SUCCEEDED(hr) && pRenderTarget) {
+        image::Image *image;
+        image = getRenderTargetImage(pDevice, pRenderTarget);
+        if (image) {
+            json.beginMember("RENDER_TARGET_0");
+            json.writeImage(image, "UNKNOWN");
+            json.endMember(); // RENDER_TARGET_*
+        }
+
+        pRenderTarget->Release();
+    }
+
+    json.endObject();
+    json.endMember(); // framebuffer
+}
+
+
+} /* namespace d3dstate */
index 9bc9628d59e7f398e4c6f791b8756e715fc336d9..ccd8a723e98a9c68f6abcb788d3b4cb9c7b8ab60 100644 (file)
@@ -62,6 +62,11 @@ class D3DRetracer(Retracer):
                 print r'    d3d9Dumper.unbindDevice(_this);'
             else:
                 print r'    d3d9Dumper.bindDevice(_this);'
+        if interface.name in ('IDirect3DDevice8', 'IDirect3DDevice8Ex'):
+            if method.name == 'Release':
+                print r'    d3d8Dumper.unbindDevice(_this);'
+            else:
+                print r'    d3d8Dumper.bindDevice(_this);'
 
         # create windows as neccessary
         if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
@@ -69,6 +74,31 @@ class D3DRetracer(Retracer):
             print r'    pPresentationParameters->hDeviceWindow = hWnd;'
             if 'hFocusWindow' in method.argNames():
                 print r'    hFocusWindow = hWnd;'
+        
+        if method.name in ('CreateDevice', 'CreateDeviceEx'):
+            print r'    switch (retrace::driver) {'
+            print r'    case retrace::DRIVER_HARDWARE:'
+            print r'        DeviceType = D3DDEVTYPE_HAL;'
+            print r'        break;'
+            print r'    case retrace::DRIVER_SOFTWARE:'
+            print r'    case retrace::DRIVER_REFERENCE:'
+            print r'        DeviceType = D3DDEVTYPE_REF;'
+            print r'        break;'
+            print r'    case retrace::DRIVER_NULL:'
+            if interface.name.startswith('IDirect3D9'):
+                print r'        DeviceType = D3DDEVTYPE_NULLREF;'
+            else:
+                print r'        retrace::warning(call) << "null driver not supported\n";'
+            print r'        break;'
+            print r'    case retrace::DRIVER_MODULE:'
+            print r'        retrace::warning(call) << "driver module not supported\n";'
+            print r'        break;'
+            print r'    default:'
+            print r'        assert(0);'
+            print r'        /* fall-through */'
+            print r'    case retrace::DRIVER_DEFAULT:'
+            print r'        break;'
+            print r'    }'
 
         if method.name in ('Reset', 'ResetEx'):
             print r'    if (pPresentationParameters->Windowed) {'
@@ -76,7 +106,7 @@ class D3DRetracer(Retracer):
             print r'    }'
 
         # notify frame has been completed
-        if method.name == 'Present':
+        if method.name in ('Present', 'PresentEx'):
             print r'    retrace::frameComplete(call);'
             print r'    hDestWindowOverride = NULL;'
 
@@ -91,6 +121,7 @@ class D3DRetracer(Retracer):
         # process events after presents
         if method.name == 'Present':
             print r'    d3dretrace::processEvents();'
+            print r'    Sleep(500);'
 
         if method.name in ('Lock', 'LockRect', 'LockBox'):
             print '    VOID *_pbData = NULL;'
@@ -135,12 +166,11 @@ def main():
             print
         elif moduleName == 'd3d8':
             from specs.d3d8 import d3d8
-            print r'#include <windows.h>'
-            print r'#include <d3d8.h>'
+            print r'#include "d3d8imports.hpp"'
             print r'#include "d3d8size.hpp"'
             api.addModule(d3d8)
             print
-            #print '''static d3dretrace::D3DDumper<IDirect3DDevice8> d3d8Dumper;'''
+            print '''static d3dretrace::D3DDumper<IDirect3DDevice8> d3d8Dumper;'''
             print
         else:
             assert False
index 81f7f7f08fc6ab4f760d4795f29a7feb9b286fe2..c21573cd327fb402619e8c7807c4c44f1b41c558 100644 (file)
@@ -25,6 +25,7 @@
 
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "image.hpp"
 #include "json.hpp"
@@ -53,7 +54,9 @@ getRenderTargetImage(IDirect3DDevice9 *pDevice,
     hr = pRenderTarget->GetDesc(&Desc);
     assert(SUCCEEDED(hr));
 
-    if (Desc.Format != D3DFMT_X8R8G8B8 && Desc.Format != D3DFMT_A8R8G8B8) {
+    if (Desc.Format != D3DFMT_X8R8G8B8 &&
+        Desc.Format != D3DFMT_A8R8G8B8 &&
+        Desc.Format != D3DFMT_R5G6B5) {
         std::cerr << "warning: unsupported D3DFORMAT " << Desc.Format << "\n";
         goto no_staging;
     }
@@ -81,11 +84,22 @@ getRenderTargetImage(IDirect3DDevice9 *pDevice,
     dst = image->start();
     src = (const unsigned char *)LockedRect.pBits;
     for (unsigned y = 0; y < Desc.Height; ++y) {
-        for (unsigned x = 0; x < Desc.Width; ++x) {
-            dst[3*x + 0] = src[4*x + 2];
-            dst[3*x + 1] = src[4*x + 1];
-            dst[3*x + 2] = src[4*x + 0];
+        if (Desc.Format == D3DFMT_R5G6B5) {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                uint32_t pixel = ((const uint16_t *)src)[x];
+                dst[3*x + 0] = (( pixel        & 0x1f) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 1] = (((pixel >>  5) & 0x3f) * (2*0xff) + 0x3f) / (2*0x3f);
+                dst[3*x + 2] = (( pixel >> 11        ) * (2*0xff) + 0x1f) / (2*0x1f);
+                dst[3*x + 3] = 0xff;
+            }
+        } else {
+            for (unsigned x = 0; x < Desc.Width; ++x) {
+                dst[3*x + 0] = src[4*x + 2];
+                dst[3*x + 1] = src[4*x + 1];
+                dst[3*x + 2] = src[4*x + 0];
+            }
         }
+
         src += LockedRect.Pitch;
         dst += image->stride();
     }
diff --git a/retrace/d3dretrace_dxgi.hpp b/retrace/d3dretrace_dxgi.hpp
new file mode 100644 (file)
index 0000000..6fa4900
--- /dev/null
@@ -0,0 +1,249 @@
+/**************************************************************************
+ *
+ * Copyright 2012 VMware Inc
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef _D3DRETRACE_DXGI_HPP_
+#define _D3DRETRACE_DXGI_HPP_
+
+
+#include "dxgiint.h"
+
+
+/*
+ * This module implements the IDXGIFactoryDWM and IDXGISwapChainDWM
+ * undocumented interfaces used by DWM, in terms of the standard IDXGIFactory
+ * and IDXGISwapChain interfaces, just for sake of d3dretrace.  Retracing on
+ * top of the undocumented interfaces works, but it may interfere with running
+ * DWM and causes corruption of the desktop upon exit.
+ */
+
+
+#define FORCE_WINDOWED 1
+
+
+namespace d3dretrace {
+
+
+class CDXGISwapChainDWM : public IDXGISwapChainDWM
+{
+private:
+    IDXGISwapChain *m_pSwapChain;
+
+public:
+    CDXGISwapChainDWM(IDXGISwapChain *pSwapChain);
+    ~CDXGISwapChainDWM();
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj);
+    ULONG STDMETHODCALLTYPE AddRef(void);
+    ULONG STDMETHODCALLTYPE Release(void);
+    HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData);
+    HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown);
+    HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData);
+    HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent);
+    HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppDevice);
+
+    HRESULT STDMETHODCALLTYPE Present(UINT SyncInterval, UINT Flags);
+    HRESULT STDMETHODCALLTYPE GetBuffer(UINT Buffer, REFIID riid, void **ppSurface);
+    HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc);
+    HRESULT STDMETHODCALLTYPE ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
+    HRESULT STDMETHODCALLTYPE ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters);
+    HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput);
+    HRESULT STDMETHODCALLTYPE GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats);
+    HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount);
+    HRESULT STDMETHODCALLTYPE SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget);
+    HRESULT STDMETHODCALLTYPE GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget);
+};
+
+CDXGISwapChainDWM::CDXGISwapChainDWM(IDXGISwapChain *pSwapChain) :
+    m_pSwapChain(pSwapChain)
+{
+}
+
+CDXGISwapChainDWM::~CDXGISwapChainDWM()
+{
+    m_pSwapChain->SetFullscreenState(FALSE, NULL);
+    m_pSwapChain->Release();
+}
+
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::QueryInterface(REFIID riid, void **ppvObj)
+{
+    return m_pSwapChain->QueryInterface(riid, ppvObj);
+}
+
+ULONG STDMETHODCALLTYPE CDXGISwapChainDWM::AddRef(void)
+{
+    // FIXME
+    return 1;
+}
+
+ULONG STDMETHODCALLTYPE CDXGISwapChainDWM::Release(void)
+{
+    // FIXME
+    return 1;
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetPrivateData(REFGUID Name, UINT DataSize, const void *pData)
+{
+    return m_pSwapChain->SetPrivateData(Name, DataSize, pData);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown)
+{
+    return m_pSwapChain->SetPrivateDataInterface(Name, pUnknown);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData)
+{
+    return m_pSwapChain->GetPrivateData(Name, pDataSize, pData);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetParent(REFIID riid, void **ppParent)
+{
+    return m_pSwapChain->GetParent(riid, ppParent);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetDevice(REFIID riid, void **ppDevice)
+{
+    return m_pSwapChain->GetDevice(riid, ppDevice);
+}
+
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::Present(UINT SyncInterval, UINT Flags)
+{
+    return m_pSwapChain->Present(SyncInterval, Flags);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetBuffer(UINT Buffer, REFIID riid, void **ppSurface)
+{
+    return m_pSwapChain->GetBuffer(Buffer, riid, ppSurface);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetDesc(DXGI_SWAP_CHAIN_DESC *pDesc)
+{
+    return m_pSwapChain->GetDesc(pDesc);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
+{
+    return m_pSwapChain->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::ResizeTarget(const DXGI_MODE_DESC *pNewTargetParameters)
+{
+    return m_pSwapChain->ResizeTarget(pNewTargetParameters);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetContainingOutput(IDXGIOutput **ppOutput)
+{
+    return m_pSwapChain->GetContainingOutput(ppOutput);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats)
+{
+    return m_pSwapChain->GetFrameStatistics(pStats);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetLastPresentCount(UINT *pLastPresentCount)
+{
+    return m_pSwapChain->GetLastPresentCount(pLastPresentCount);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::SetFullscreenState(BOOL Fullscreen, IDXGIOutput *pTarget)
+{
+    return m_pSwapChain->SetFullscreenState(Fullscreen, pTarget);
+}
+
+HRESULT STDMETHODCALLTYPE CDXGISwapChainDWM::GetFullscreenState(BOOL *pFullscreen, IDXGIOutput **ppTarget)
+{
+    return m_pSwapChain->GetFullscreenState(pFullscreen, ppTarget);
+}
+
+
+
+class CDXGIFactoryDWM : public IDXGIFactoryDWM
+{
+private:
+    IDXGIFactory *m_pFactory;
+
+    ~CDXGIFactoryDWM();
+
+public:
+    CDXGIFactoryDWM(IDXGIFactory *pFactory);
+
+    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj);
+    ULONG STDMETHODCALLTYPE AddRef(void);
+    ULONG STDMETHODCALLTYPE Release(void);
+    HRESULT STDMETHODCALLTYPE CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain);
+};
+
+CDXGIFactoryDWM::CDXGIFactoryDWM(IDXGIFactory *pFactory) :
+    m_pFactory(pFactory)
+{}
+
+CDXGIFactoryDWM::~CDXGIFactoryDWM()
+{
+    m_pFactory->Release();
+}
+
+
+HRESULT STDMETHODCALLTYPE CDXGIFactoryDWM::QueryInterface(REFIID riid, void **ppvObj)
+{
+    return m_pFactory->QueryInterface(riid, ppvObj);
+}
+
+ULONG STDMETHODCALLTYPE CDXGIFactoryDWM::AddRef(void)
+{
+    // FIXME
+    return 1;
+}
+
+ULONG STDMETHODCALLTYPE CDXGIFactoryDWM::Release(void)
+{
+    // FIXME
+    return 1;
+}
+
+HRESULT STDMETHODCALLTYPE CDXGIFactoryDWM::CreateSwapChain(IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGIOutput *pOutput, IDXGISwapChainDWM **ppSwapChain)
+{
+    IDXGISwapChain *pSwapChain = NULL;
+    if (FORCE_WINDOWED) {
+        pDesc->Windowed = TRUE;
+    }
+    HRESULT hr = m_pFactory->CreateSwapChain(pDevice, pDesc, &pSwapChain);
+    if (SUCCEEDED(hr)) {
+        if (!FORCE_WINDOWED) {
+            pSwapChain->SetFullscreenState(TRUE, pOutput);
+        }
+        *ppSwapChain = new CDXGISwapChainDWM(pSwapChain);
+    }
+    return hr;
+}
+
+
+
+} /* namespace d3dretrace */
+
+
+#endif /* _D3DRETRACE_DXGI_HPP_ */
index 3766a91353e6710396d8801f0ffa75bdef10aa0e..eb0e3cd4f33fd0a6d73e6302fea4dc6706613bce 100644 (file)
@@ -32,6 +32,7 @@
 #include <windows.h>
 
 
+struct IDirect3DDevice8;
 struct IDirect3DDevice9;
 struct ID3D10Device;
 struct ID3D11DeviceContext;
@@ -50,6 +51,16 @@ namespace d3dstate {
 extern const GUID GUID_D3DSTATE;
 
 
+image::Image *
+getRenderTargetImage(IDirect3DDevice8 *pDevice);
+
+void
+dumpFramebuffer(JSONWriter &json, IDirect3DDevice8 *pDevice);
+
+void
+dumpDevice(std::ostream &os, IDirect3DDevice8 *pDevice);
+
+
 image::Image *
 getRenderTargetImage(IDirect3DDevice9 *pDevice);
 
index 8de3c989efa5f46057c6b04c19cbee22665af4f0..6a51a4d4e3c5360128398e6cf184dab4ecbf13a2 100644 (file)
@@ -29,6 +29,7 @@
 
 import sys
 from dllretrace import DllRetracer as Retracer
+import specs.dxgi
 from specs.stdapi import API
 from specs.dxgi import dxgi
 from specs.d3d10 import d3d10
@@ -45,13 +46,11 @@ class D3DRetracer(Retracer):
         print r'''
 static void 
 createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
-    if (pSwapChainDesc->Windowed) {
-        UINT Width  = pSwapChainDesc->BufferDesc.Width;
-        UINT Height = pSwapChainDesc->BufferDesc.Height;
-        if (!Width)  Width = 1024;
-        if (!Height) Height = 768;
-        pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
-    }
+    UINT Width  = pSwapChainDesc->BufferDesc.Width;
+    UINT Height = pSwapChainDesc->BufferDesc.Height;
+    if (!Width)  Width = 1024;
+    if (!Height) Height = 768;
+    pSwapChainDesc->OutputWindow = d3dretrace::createWindow(Width, Height);
 }
 '''
 
@@ -163,6 +162,16 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
             else:
                 print r'    d3d11Dumper.bindDevice(_this);'
 
+        if interface.name == 'IDXGIFactory' and method.name == 'QueryInterface':
+            print r'    if (riid == IID_IDXGIFactoryDWM) {'
+            print r'        _this->AddRef();'
+            print r'        *ppvObj = new d3dretrace::CDXGIFactoryDWM(_this);'
+            print r'        _result = S_OK;'
+            print r'    } else {'
+            Retracer.invokeInterfaceMethod(self, interface, method)
+            print r'    }'
+            return
+
         # create windows as neccessary
         if method.name == 'CreateSwapChain':
             print r'    createWindow(pDesc);'
@@ -205,6 +214,46 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
             print r'    }'
             return
 
+        if interface.name.startswith('ID3D10Device') and method.name == 'OpenSharedResource':
+            print r'    retrace::warning(call) << "replacing shared resource with checker pattern\n";'
+            print r'    D3D10_TEXTURE2D_DESC Desc;'
+            print r'    memset(&Desc, 0, sizeof Desc);'
+            print r'    Desc.Width = 8;'
+            print r'    Desc.Height = 8;'
+            print r'    Desc.MipLevels = 1;'
+            print r'    Desc.ArraySize = 1;'
+            print r'    Desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;'
+            print r'    Desc.SampleDesc.Count = 1;'
+            print r'    Desc.SampleDesc.Quality = 0;'
+            print r'    Desc.Usage = D3D10_USAGE_DEFAULT;'
+            print r'    Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;'
+            print r'    Desc.CPUAccessFlags = 0x0;'
+            print r'    Desc.MiscFlags = 0 /* D3D10_RESOURCE_MISC_SHARED */;'
+            print r'''
+            const DWORD Checker[8][8] = {
+               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
+               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
+               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
+               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
+               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
+               {~0,  0, ~0,  0, ~0,  0, ~0,  0, },
+               { 0, ~0,  0, ~0,  0, ~0,  0, ~0, },
+               {~0,  0, ~0,  0, ~0,  0, ~0,  0, }
+            };
+            const D3D10_SUBRESOURCE_DATA InitialData = {Checker, sizeof Checker[0], sizeof Checker};
+            '''
+            print r'    _result = _this->CreateTexture2D(&Desc, &InitialData, (ID3D10Texture2D**)ppResource);'
+            self.checkResult(method.type)
+            return
+
+        if method.name == 'Map':
+            # Reset _DO_NOT_WAIT flags. Otherwise they may fail, and we have no
+            # way to cope with it (other than retry).
+            mapFlagsArg = method.getArgByName('MapFlags')
+            for flag in mapFlagsArg.type.values:
+                if flag.endswith('_MAP_FLAG_DO_NOT_WAIT'):
+                    print r'    MapFlags &= ~%s;' % flag
+
         Retracer.invokeInterfaceMethod(self, interface, method)
 
         # process events after presents
@@ -239,6 +288,8 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) {
 
 
 def main():
+    print r'#define INITGUID'
+    print
     print r'#include <string.h>'
     print
     print r'#include <iostream>'
@@ -251,6 +302,7 @@ def main():
     api = API()
     
     if moduleNames:
+        print r'#include "d3dretrace_dxgi.hpp"'
         api.addModule(dxgi)
     
     if 'd3d10' in moduleNames:
index 95a6d7596df230e8dd059194c493bbf58055cad3..7441b56938e22481e0110b181b74b7de81a55c98 100644 (file)
@@ -60,7 +60,7 @@ struct Context {
 
 extern bool insideList;
 extern bool insideGlBeginEnd;
-
+extern bool supportsARBShaderObjects;
 
 Context *
 getCurrentContext(void);
index a0755953b3a52059e35f9d4e0ff9447cba878305..f0d0e2d7d5b29ff4ee0232d479fab8b408374de9 100644 (file)
@@ -311,18 +311,23 @@ static void retrace_CGLTexImageIOSurface2D(trace::Call &call) {
 
 const retrace::Entry glretrace::cgl_callbacks[] = {
     {"CGLChoosePixelFormat", &retrace_CGLChoosePixelFormat},
-    {"CGLDestroyPixelFormat", &retrace::ignore},
     {"CGLCreateContext", &retrace_CGLCreateContext},
     {"CGLDestroyContext", &retrace_CGLDestroyContext},
-    {"CGLSetCurrentContext", &retrace_CGLSetCurrentContext},
-    {"CGLGetCurrentContext", &retrace::ignore},
-    {"CGLEnable", &retrace::ignore},
+    {"CGLDestroyPixelFormat", &retrace::ignore},
     {"CGLDisable", &retrace::ignore},
-    {"CGLSetParameter", &retrace::ignore},
-    {"CGLGetParameter", &retrace::ignore},
+    {"CGLEnable", &retrace::ignore},
+    {"CGLErrorString", &retrace::ignore},
     {"CGLFlushDrawable", &retrace_CGLFlushDrawable},
-    {"CGLUpdateContext", &retrace::ignore},
+    {"CGLGetCurrentContext", &retrace::ignore},
+    {"CGLGetOption", &retrace::ignore},
+    {"CGLGetParameter", &retrace::ignore},
+    {"CGLGetVersion", &retrace::ignore},
+    {"CGLGetVirtualScreen", &retrace::ignore},
+    {"CGLIsEnabled", &retrace::ignore},
+    {"CGLSetCurrentContext", &retrace_CGLSetCurrentContext},
+    {"CGLSetParameter", &retrace::ignore},
     {"CGLTexImageIOSurface2D", &retrace_CGLTexImageIOSurface2D},
+    {"CGLUpdateContext", &retrace::ignore},
     {NULL, NULL},
 };
 
index 1418ca3d0fcc9bd54326263af35763136dd656c8..1591287c22d9d254507dba27a23c5245a5e83d20 100755 (executable)
@@ -1,6 +1,8 @@
 /**************************************************************************
  *
  * Copyright 2011 Jose Fonseca
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,6 +33,7 @@
 #include "glstate.hpp"
 #include "glretrace.hpp"
 #include "os_time.hpp"
+#include "os_memory.hpp"
 
 /* Synchronous debug output may reduce performance however,
  * without it the callNo in the callback may be inaccurate
@@ -42,16 +45,28 @@ namespace glretrace {
 
 bool insideList = false;
 bool insideGlBeginEnd = false;
+bool supportsARBShaderObjects = false;
+
+enum {
+    GPU_START = 0,
+    GPU_DURATION,
+    OCCLUSION,
+    NUM_QUERIES,
+};
 
 struct CallQuery
 {
-    GLuint ids[3];
+    GLuint ids[NUM_QUERIES];
     unsigned call;
     bool isDraw;
     GLuint program;
     const trace::FunctionSig *sig;
     int64_t cpuStart;
     int64_t cpuEnd;
+    int64_t vsizeStart;
+    int64_t vsizeEnd;
+    int64_t rssStart;
+    int64_t rssEnd;
 };
 
 static bool supportsElapsed = true;
@@ -109,48 +124,55 @@ checkGlError(trace::Call &call) {
     }
 }
 
-static void
-getCurrentTimes(int64_t& cpuTime, int64_t& gpuTime) {
-    GLuint query;
-
+static inline int64_t
+getCurrentTime(void) {
     if (retrace::profilingGpuTimes && supportsTimestamp) {
-        glGenQueries(1, &query);
-        glQueryCounter(query, GL_TIMESTAMP);
-        glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &gpuTime);
+        /* Get the current GL time without stalling */
+        GLint64 timestamp = 0;
+        glGetInteger64v(GL_TIMESTAMP, &timestamp);
+        return timestamp;
     } else {
-        gpuTime = 0;
+        return os::getTime();
     }
+}
 
-    if (retrace::profilingCpuTimes) {
-        cpuTime = os::getTime();
+static inline int64_t
+getTimeFrequency(void) {
+    if (retrace::profilingGpuTimes && supportsTimestamp) {
+        return 1000000000;
     } else {
-        cpuTime = 0;
+        return os::timeFrequency;
     }
+}
 
-    if (retrace::profilingGpuTimes && supportsTimestamp) {
-        glDeleteQueries(1, &query);
-    }
+static inline void
+getCurrentVsize(int64_t& vsize) {
+    vsize = os::getVsize();
+}
+
+static inline void
+getCurrentRss(int64_t& rss) {
+    rss = os::getRss();
 }
 
 static void
 completeCallQuery(CallQuery& query) {
     /* Get call start and duration */
-    int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0;
+    int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0;
 
     if (query.isDraw) {
         if (retrace::profilingGpuTimes) {
             if (supportsTimestamp) {
-                glGetQueryObjecti64vEXT(query.ids[0], GL_QUERY_RESULT, &gpuStart);
+                glGetQueryObjecti64vEXT(query.ids[GPU_START], GL_QUERY_RESULT, &gpuStart);
             }
 
-            glGetQueryObjecti64vEXT(query.ids[1], GL_QUERY_RESULT, &gpuDuration);
+            glGetQueryObjecti64vEXT(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration);
         }
 
         if (retrace::profilingPixelsDrawn) {
-            glGetQueryObjecti64vEXT(query.ids[2], GL_QUERY_RESULT, &pixels);
+            glGetQueryObjecti64vEXT(query.ids[OCCLUSION], GL_QUERY_RESULT, &pixels);
         }
 
-        glDeleteQueries(3, query.ids);
     } else {
         pixels = -1;
     }
@@ -159,8 +181,15 @@ completeCallQuery(CallQuery& query) {
         cpuDuration = query.cpuEnd - query.cpuStart;
     }
 
+    if (retrace::profilingMemoryUsage) {
+        vsizeDuration = query.vsizeEnd - query.vsizeStart;
+        rssDuration = query.rssEnd - query.rssStart;
+    }
+
+    glDeleteQueries(NUM_QUERIES, query.ids);
+
     /* Add call to profile */
-    retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration);
+    retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration, query.vsizeStart, vsizeDuration, query.rssStart, rssDuration);
 }
 
 void
@@ -183,20 +212,20 @@ beginProfile(trace::Call &call, bool isDraw) {
     query.sig = call.sig;
     query.program = currentContext ? currentContext->activeProgram : 0;
 
+    glGenQueries(NUM_QUERIES, query.ids);
+
     /* GPU profiling only for draw calls */
     if (isDraw) {
-        glGenQueries(3, query.ids);
-
         if (retrace::profilingGpuTimes) {
             if (supportsTimestamp) {
-                glQueryCounter(query.ids[0], GL_TIMESTAMP);
+                glQueryCounter(query.ids[GPU_START], GL_TIMESTAMP);
             }
 
-            glBeginQuery(GL_TIME_ELAPSED, query.ids[1]);
+            glBeginQuery(GL_TIME_ELAPSED, query.ids[GPU_DURATION]);
         }
 
         if (retrace::profilingPixelsDrawn) {
-            glBeginQuery(GL_SAMPLES_PASSED, query.ids[2]);
+            glBeginQuery(GL_SAMPLES_PASSED, query.ids[OCCLUSION]);
         }
     }
 
@@ -204,18 +233,24 @@ beginProfile(trace::Call &call, bool isDraw) {
 
     /* CPU profiling for all calls */
     if (retrace::profilingCpuTimes) {
-       callQueries.back().cpuStart = os::getTime();
+        CallQuery& query = callQueries.back();
+        query.cpuStart = getCurrentTime();
+    }
+
+    if (retrace::profilingMemoryUsage) {
+        CallQuery& query = callQueries.back();
+        query.vsizeStart = os::getVsize();
+        query.rssStart = os::getRss();
     }
 }
 
 void
 endProfile(trace::Call &call, bool isDraw) {
-    GLint64 time = os::getTime();
 
     /* CPU profiling for all calls */
     if (retrace::profilingCpuTimes) {
         CallQuery& query = callQueries.back();
-        query.cpuEnd = time;
+        query.cpuEnd = getCurrentTime();
     }
 
     /* GPU profiling only for draw calls */
@@ -228,6 +263,12 @@ endProfile(trace::Call &call, bool isDraw) {
             glEndQuery(GL_SAMPLES_PASSED);
         }
     }
+
+    if (retrace::profilingMemoryUsage) {
+        CallQuery& query = callQueries.back();
+        query.vsizeEnd = os::getVsize();
+        query.rssEnd = os::getRss();
+    }
 }
 
 void
@@ -240,6 +281,7 @@ initContext() {
     supportsElapsed     = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp;
     supportsOcclusion   = currentContext->hasExtension("GL_ARB_occlusion_query");
     supportsDebugOutput = currentContext->hasExtension("GL_ARB_debug_output");
+    supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects");
 
     /* Check for timer query support */
     if (retrace::profilingGpuTimes) {
@@ -276,13 +318,19 @@ initContext() {
     /* Sync the gpu and cpu start times */
     if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
         if (!retrace::profiler.hasBaseTimes()) {
-            GLint64 gpuTime, cpuTime;
-
-            getCurrentTimes(cpuTime, gpuTime);
-            retrace::profiler.setBaseCpuTime(cpuTime);
-            retrace::profiler.setBaseGpuTime(gpuTime);
+            GLint64 currentTime = getCurrentTime();
+            retrace::profiler.setBaseCpuTime(currentTime);
+            retrace::profiler.setBaseGpuTime(currentTime);
         }
     }
+
+    if (retrace::profilingMemoryUsage) {
+        GLint64 currentVsize, currentRss;
+        getCurrentVsize(currentVsize);
+        retrace::profiler.setBaseVsizeUsage(currentVsize);
+        getCurrentRss(currentRss);
+        retrace::profiler.setBaseRssUsage(currentRss);
+    }
 }
 
 void
@@ -291,23 +339,6 @@ frame_complete(trace::Call &call) {
         /* Complete any remaining queries */
         flushQueries();
 
-        /* GPU time drifts due to being relative times, not absolute and can be
-         * affected by the gpu switch between processes.
-         *
-         * To attempt to compensate we resynchronise on frame end however there is
-         * still noticeable drift within a single frame which we do not account for.
-         */
-        if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
-            int64_t cpuTime, gpuTime, error;
-
-            getCurrentTimes(cpuTime, gpuTime);
-            cpuTime = cpuTime - retrace::profiler.getBaseCpuTime();
-            gpuTime = gpuTime - retrace::profiler.getBaseGpuTime();
-            error   = gpuTime - cpuTime * (1.0E9 / os::timeFrequency);
-
-            retrace::profiler.setBaseGpuTime(retrace::profiler.getBaseGpuTime() + error);
-        }
-
         /* Indicate end of current frame */
         retrace::profiler.addFrameEnd();
     }
index 0d5a5f3bd629ec2677451098f44060ad5d4525c6..e2c69785d67bc9066acf5d063648381defbdae45 100644 (file)
@@ -66,29 +66,56 @@ Context::Context(void) {
 
 void
 Context::resetPixelPackState(void) {
+    // Start with default state
+    pack_alignment = 4;
+    pack_image_height = 0;
+    pack_lsb_first = GL_FALSE;
+    pack_row_length = 0;
+    pack_skip_images = 0;
+    pack_skip_pixels = 0;
+    pack_skip_rows = 0;
+    pack_swap_bytes = GL_FALSE;
+    pixel_pack_buffer_binding = 0;
+
+    // Get current state
+    glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
     if (!ES) {
-        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
-        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-        glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
+        glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
+        glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
+        glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
+        glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
+        glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
+        glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
+        glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
+        glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pixel_pack_buffer_binding);
+    }
+
+    // Reset state for compact images
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    if (!ES) {
+        glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
         glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-        glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
-        glPixelStorei(GL_PACK_SKIP_ROWS, 0);
-        glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
         glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
-    } else {
-        packAlignment = 4;
-        glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
+        glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+        glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+        glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
     }
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
 }
 
 void
 Context::restorePixelPackState(void) {
+    glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
     if (!ES) {
-        glPopClientAttrib();
-    } else {
-        glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
+        glPixelStorei(GL_PACK_IMAGE_HEIGHT, pack_image_height);
+        glPixelStorei(GL_PACK_LSB_FIRST, pack_lsb_first);
+        glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length);
+        glPixelStorei(GL_PACK_SKIP_IMAGES, pack_skip_images);
+        glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels);
+        glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows);
+        glPixelStorei(GL_PACK_SWAP_BYTES, pack_swap_bytes);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer_binding);
     }
 }
 
index 7b0a42473fdf97cbc8c04ad4910247d078d4b2cf..598d56cceb8e2746bec9e22fc519609d33667b64 100644 (file)
@@ -745,13 +745,22 @@ getDrawBufferImage() {
             if (draw_buffer == GL_NONE) {
                 return NULL;
             }
+        } else {
+            // GL_COLOR_ATTACHMENT0 is implied
+            draw_buffer = GL_COLOR_ATTACHMENT0;
         }
 
         if (!getFramebufferAttachmentDesc(context, framebuffer_target, draw_buffer, desc)) {
             return NULL;
         }
     } else {
-        if (!context.ES) {
+        if (context.ES) {
+            // XXX: Draw buffer is always FRONT for single buffer context, BACK
+            // for double buffered contexts. There is no way to know which (as
+            // GL_DOUBLEBUFFER state is also unavailable), so always assume
+            // double-buffering.
+            draw_buffer = GL_BACK;
+        } else {
             glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
             if (draw_buffer == GL_NONE) {
                 return NULL;
@@ -968,16 +977,21 @@ dumpDrawableImages(JSONWriter &json, Context &context)
 
     GLint draw_buffer = GL_NONE;
     if (context.ES) {
+        // XXX: Draw buffer is always FRONT for single buffer context, BACK for
+        // double buffered contexts. There is no way to know which (as
+        // GL_DOUBLEBUFFER state is also unavailable), so always assume
+        // double-buffering.
         draw_buffer = GL_BACK;
     } else {
         glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
-        glReadBuffer(draw_buffer);
     }
 
     if (draw_buffer != GL_NONE) {
+        // Read from current draw buffer
         GLint read_buffer = GL_NONE;
         if (!context.ES) {
             glGetIntegerv(GL_READ_BUFFER, &read_buffer);
+            glReadBuffer(draw_buffer);
         }
 
         GLint alpha_bits = 0;
@@ -990,6 +1004,7 @@ dumpDrawableImages(JSONWriter &json, Context &context)
         dumpReadBufferImage(json, width, height, format);
         json.endMember();
 
+        // Restore original read buffer
         if (!context.ES) {
             glReadBuffer(read_buffer);
         }
index a709da3ba08ea84b97f6353be66c2509fee29a09..6b74b1d58e676f3f707bddd4af13bc78c4159cc8 100644 (file)
@@ -44,13 +44,23 @@ struct Context
 
     Context(void);
 
-    GLint packAlignment;
-
     void
     resetPixelPackState(void);
 
     void
     restorePixelPackState(void);
+
+private:
+    // Pack state
+    GLint pack_alignment;
+    GLint pack_image_height;
+    GLint pack_lsb_first;
+    GLint pack_row_length;
+    GLint pack_skip_images;
+    GLint pack_skip_pixels;
+    GLint pack_skip_rows;
+    GLint pack_swap_bytes;
+    GLint pixel_pack_buffer_binding;
 };
 
 
index 6db4b80750f1ce000069d184bcaf9f1330d4bae2..50693a97d5bd43676010c815a23ea3b7251428cf 100644 (file)
@@ -156,12 +156,21 @@ class StateGetter(Visitor):
         elem_type = self.inflector.reduced_type(array.type)
         inflection = self.inflector.inflect(array.type)
         assert inflection.endswith('v')
-        print '    %s %s[%s + 1];' % (elem_type, temp_name, array.length)
-        print '    memset(%s, 0, %s * sizeof *%s);' % (temp_name, array.length, temp_name)
-        print '    %s[%s] = (%s)0xdeadc0de;' % (temp_name, array.length, elem_type)
+        array_length = array.length
+        if array_length.isdigit():
+            # Static integer length
+            print '    %s %s[%s + 1];' % (elem_type, temp_name, array_length)
+        else:
+            # Put the length in a variable to avoid recomputing it every time
+            print '    size_t _%s_length = %s;' % (temp_name, array_length)
+            array_length = '_%s_length' % temp_name
+            # Allocate a dynamic sized array
+            print '    %s *%s = _allocator.alloc<%s>(%s + 1);' % (elem_type, temp_name, elem_type, array_length)
+        print '    memset(%s, 0, %s * sizeof *%s);' % (temp_name, array_length, temp_name)
+        print '    %s[%s] = (%s)0xdeadc0de;' % (temp_name, array_length, elem_type)
         print '    %s(%s, %s);' % (inflection + self.suffix, ', '.join(args), temp_name)
         # Simple buffer overflow detection
-        print '    assert(%s[%s] == (%s)0xdeadc0de);' % (temp_name, array.length, elem_type)
+        print '    assert(%s[%s] == (%s)0xdeadc0de);' % (temp_name, array_length, elem_type)
         return temp_name
 
     def visitOpaque(self, pointer, args):
@@ -257,6 +266,7 @@ class StateDumper:
         print '#include <string.h>'
         print
         print '#include "json.hpp"'
+        print '#include "scoped_allocator.hpp"'
         print '#include "glproc.hpp"'
         print '#include "glsize.hpp"'
         print '#include "glstate.hpp"'
@@ -316,6 +326,9 @@ class StateDumper:
 
         print 'void dumpParameters(JSONWriter &json, Context &context)'
         print '{'
+        print '    ScopedAllocator _allocator;'
+        print '    (void)_allocator;'
+        print
         print '    json.beginMember("parameters");'
         print '    json.beginObject();'
         
index 228c81352e979046ece2e8040d2f885ef7b27051..14317cffbe96d7cbbe70c718127e537ea9aff5a1 100644 (file)
@@ -1,6 +1,8 @@
 /**************************************************************************
  *
  * Copyright 2011-2012 Jose Fonseca
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,7 +30,6 @@
 
 #include <assert.h>
 #include <string.h>
-#include <stdint.h>
 
 #include <list>
 #include <map>
@@ -38,6 +39,8 @@
 #include "trace_parser.hpp"
 #include "trace_profiler.hpp"
 
+#include "scoped_allocator.hpp"
+
 
 namespace image {
     class Image;
@@ -51,37 +54,9 @@ extern trace::Parser parser;
 extern trace::Profiler profiler;
 
 
-/**
- * Similar to alloca(), but implemented with malloc.
- */
-class ScopedAllocator
+class ScopedAllocator : public ::ScopedAllocator
 {
-private:
-    uintptr_t next;
-
 public:
-    inline
-    ScopedAllocator() :
-        next(0) {
-    }
-
-    inline void *
-    alloc(size_t size) {
-        /* Always return valid address, even when size is zero */
-        size = std::max(size, sizeof(uintptr_t));
-
-        uintptr_t * buf = static_cast<uintptr_t *>(malloc(sizeof(uintptr_t) + size));
-        if (!buf) {
-            return NULL;
-        }
-
-        *buf = next;
-        next = reinterpret_cast<uintptr_t>(buf);
-        assert((next & 1) == 0);
-
-        return static_cast<void *>(&buf[1]);
-    }
-
     /**
      * Allocate an array with the same dimensions as the specified value.
      */
@@ -89,7 +64,7 @@ public:
     alloc(const trace::Value *value, size_t size) {
         const trace::Array *array = dynamic_cast<const trace::Array *>(value);
         if (array) {
-            return alloc(array->size() * size);
+            return ::ScopedAllocator::alloc(array->size() * size);
         }
         const trace::Null *null = dynamic_cast<const trace::Null *>(value);
         if (null) {
@@ -99,32 +74,6 @@ public:
         return NULL;
     }
 
-    /**
-     * Prevent this pointer from being automatically freed.
-     */
-    template< class T >
-    inline void
-    bind(T *ptr) {
-        if (ptr) {
-            reinterpret_cast<uintptr_t *>(ptr)[-1] |= 1;
-        }
-    }
-
-    inline
-    ~ScopedAllocator() {
-        while (next) {
-            uintptr_t temp = *reinterpret_cast<uintptr_t *>(next);
-
-            bool bind = temp & 1;
-            temp &= ~1;
-
-            if (!bind) {
-                free(reinterpret_cast<void *>(next));
-            }
-
-            next = temp;
-        }
-    }
 };
 
 
@@ -145,6 +94,7 @@ extern bool profiling;
 extern bool profilingCpuTimes;
 extern bool profilingGpuTimes;
 extern bool profilingPixelsDrawn;
+extern bool profilingMemoryUsage;
 
 /**
  * State dumping.
index cd5ef1d2136770f21c5097f0480c6c8b661059d7..70926c0b39d755fe293286b88e6b86fbe3df7441 100644 (file)
@@ -166,7 +166,14 @@ class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
         print '    if (retrace::verbosity >= 2) {'
         print '        std::cout << "%s " << size_t(%s) << " <- " << size_t(%s) << "\\n";' % (handle.name, lvalue, new_lvalue)
         print '    }'
-        print '    %s = %s;' % (lvalue, new_lvalue)
+        if (new_lvalue.startswith('_program_map') or new_lvalue.startswith('_shader_map')):
+            print 'if (glretrace::supportsARBShaderObjects) {'
+            print '    %s = _handleARB_map[%s];' % (lvalue, lvalue)
+            print '} else {'
+            print '    %s = %s;' % (lvalue, new_lvalue)
+            print '}'
+        else:
+            print '    %s = %s;' % (lvalue, new_lvalue)
     
     def visitBlob(self, blob, lvalue, rvalue):
         print '    %s = static_cast<%s>((%s).toPointer());' % (lvalue, blob, rvalue)
@@ -279,8 +286,15 @@ class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
         OpaqueValueDeserializer().visit(handle.type, '_origResult', rvalue);
         if handle.range is None:
             rvalue = "_origResult"
-            entry = lookupHandle(handle, rvalue) 
-            print "    %s = %s;" % (entry, lvalue)
+            entry = lookupHandle(handle, rvalue)
+            if (entry.startswith('_program_map') or entry.startswith('_shader_map')):
+                print 'if (glretrace::supportsARBShaderObjects) {'
+                print '    _handleARB_map[%s] = %s;' % (rvalue, lvalue)
+                print '} else {'
+                print '    %s = %s;' % (entry, lvalue)
+                print '}'
+            else:
+                print "    %s = %s;" % (entry, lvalue)
             print '    if (retrace::verbosity >= 2) {'
             print '        std::cout << "{handle.name} " << {rvalue} << " -> " << {lvalue} << "\\n";'.format(**locals())
             print '    }'
@@ -464,10 +478,9 @@ class Retracer:
         # On release our reference when we reach Release() == 0 call in the
         # trace.
         if method.name == 'Release':
-            print '    if (call.ret->toUInt()) {'
-            print '        return;'
+            print '    if (call.ret->toUInt() == 0) {'
+            print '        retrace::delObj(call.arg(0));'
             print '    }'
-            print '    retrace::delObj(call.arg(0));'
 
         arg_names = ", ".join(method.argNames())
         if method.type is not stdapi.Void:
index 63d3dab07064a7b2a615af967e1263440b68862a..7cc3fcab869bf0e5935d504838275de4909bd940 100644 (file)
@@ -1,6 +1,8 @@
 /**************************************************************************
  *
  * Copyright 2011 Jose Fonseca
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -35,6 +37,7 @@
 #include "image.hpp"
 #include "trace_callset.hpp"
 #include "trace_dump.hpp"
+#include "trace_option.hpp"
 #include "retrace.hpp"
 
 
@@ -71,6 +74,8 @@ bool profiling = false;
 bool profilingGpuTimes = false;
 bool profilingCpuTimes = false;
 bool profilingPixelsDrawn = false;
+bool profilingMemoryUsage = false;
+bool useCallNos = true;
 
 unsigned frameNo = 0;
 unsigned callNo = 0;
@@ -92,6 +97,8 @@ Dumper *dumper = &defaultDumper;
  */
 static void
 takeSnapshot(unsigned call_no) {
+    static unsigned snapshot_no = 0;
+
     assert(snapshotPrefix || comparePrefix);
 
     image::Image *ref = NULL;
@@ -116,10 +123,13 @@ takeSnapshot(unsigned call_no) {
     if (snapshotPrefix) {
         if (snapshotPrefix[0] == '-' && snapshotPrefix[1] == 0) {
             char comment[21];
-            snprintf(comment, sizeof comment, "%u", call_no);
+            snprintf(comment, sizeof comment, "%u",
+                     useCallNos ? call_no : snapshot_no);
             src->writePNM(std::cout, comment);
         } else {
-            os::String filename = os::String::format("%s%010u.png", snapshotPrefix, call_no);
+            os::String filename = os::String::format("%s%010u.png",
+                                                     snapshotPrefix,
+                                                     useCallNos ? call_no : snapshot_no);
             if (src->writePNG(filename) && retrace::verbosity >= 0) {
                 std::cout << "Wrote " << filename << "\n";
             }
@@ -133,6 +143,8 @@ takeSnapshot(unsigned call_no) {
 
     delete src;
 
+    snapshot_no++;
+
     return;
 }
 
@@ -505,8 +517,10 @@ usage(const char *argv0) {
         "      --pcpu              cpu profiling (cpu times per call)\n"
         "      --pgpu              gpu profiling (gpu times per draw call)\n"
         "      --ppd               pixels drawn profiling (pixels drawn per draw call)\n"
+        "      --pmem              memory usage profiling (vsize rss per call)\n"
         "  -c, --compare=PREFIX    compare against snapshots with given PREFIX\n"
         "  -C, --calls=CALLSET     calls to compare (default is every frame)\n"
+        "      --call-nos[=BOOL]   use call numbers in snapshot filenames\n"
         "      --core              use core profile\n"
         "      --db                use a double buffer visual (default)\n"
         "      --driver=DRIVER     force driver type (`hw`, `sw`, `ref`, `null`, or driver module name)\n"
@@ -519,12 +533,14 @@ usage(const char *argv0) {
 }
 
 enum {
-    CORE_OPT = CHAR_MAX + 1,
+    CALL_NOS_OPT = CHAR_MAX + 1,
+    CORE_OPT,
     DB_OPT,
     DRIVER_OPT,
     PCPU_OPT,
     PGPU_OPT,
     PPD_OPT,
+    PMEM_OPT,
     SB_OPT,
 };
 
@@ -534,6 +550,7 @@ shortOptions = "bc:C:D:hs:S:vw";
 const static struct option
 longOptions[] = {
     {"benchmark", no_argument, 0, 'b'},
+    {"call-nos", optional_argument, 0, CALL_NOS_OPT },
     {"calls", required_argument, 0, 'C'},
     {"compare", required_argument, 0, 'c'},
     {"core", no_argument, 0, CORE_OPT},
@@ -544,6 +561,7 @@ longOptions[] = {
     {"pcpu", no_argument, 0, PCPU_OPT},
     {"pgpu", no_argument, 0, PGPU_OPT},
     {"ppd", no_argument, 0, PPD_OPT},
+    {"pmem", no_argument, 0, PMEM_OPT},
     {"sb", no_argument, 0, SB_OPT},
     {"snapshot-prefix", required_argument, 0, 's'},
     {"snapshot", required_argument, 0, 'S'},
@@ -578,6 +596,9 @@ int main(int argc, char **argv)
             retrace::debug = false;
             retrace::verbosity = -1;
             break;
+        case CALL_NOS_OPT:
+            useCallNos = trace::boolOption(optarg);
+            break;
         case 'c':
             comparePrefix = optarg;
             if (compareFrequency.empty()) {
@@ -661,6 +682,13 @@ int main(int argc, char **argv)
 
             retrace::profilingPixelsDrawn = true;
             break;
+        case PMEM_OPT:
+            retrace::debug = false;
+            retrace::profiling = true;
+            retrace::verbosity = -1;
+
+            retrace::profilingMemoryUsage = true;
+            break;
         default:
             std::cerr << "error: unknown option " << opt << "\n";
             usage(argv[0]);
@@ -670,7 +698,7 @@ int main(int argc, char **argv)
 
     retrace::setUp();
     if (retrace::profiling) {
-        retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn);
+        retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn, retrace::profilingMemoryUsage);
     }
 
     os::setExceptionCallback(exceptionCallback);
diff --git a/retrace/scoped_allocator.hpp b/retrace/scoped_allocator.hpp
new file mode 100644 (file)
index 0000000..f44b74f
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************
+ *
+ * Copyright 2011-2012 Jose Fonseca
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef _SCOPED_ALLOCATOR_HPP_
+#define _SCOPED_ALLOCATOR_HPP_
+
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+
+/**
+ * Similar to alloca(), but implemented with malloc.
+ */
+class ScopedAllocator
+{
+private:
+    uintptr_t next;
+
+public:
+    inline
+    ScopedAllocator() :
+        next(0) {
+    }
+
+    inline void *
+    alloc(size_t size) {
+        /* Always return valid address, even when size is zero */
+        size = std::max(size, sizeof(uintptr_t));
+
+        uintptr_t * buf = static_cast<uintptr_t *>(malloc(sizeof(uintptr_t) + size));
+        if (!buf) {
+            return NULL;
+        }
+
+        *buf = next;
+        next = reinterpret_cast<uintptr_t>(buf);
+        assert((next & 1) == 0);
+
+        return static_cast<void *>(&buf[1]);
+    }
+    
+    template< class T >
+    inline T *
+    alloc(size_t size = 1) {
+        return static_cast<T *>(alloc(sizeof(T) * size));
+    }
+
+    /**
+     * Prevent this pointer from being automatically freed.
+     */
+    template< class T >
+    inline void
+    bind(T *ptr) {
+        if (ptr) {
+            reinterpret_cast<uintptr_t *>(ptr)[-1] |= 1;
+        }
+    }
+
+    inline
+    ~ScopedAllocator() {
+        while (next) {
+            uintptr_t temp = *reinterpret_cast<uintptr_t *>(next);
+
+            bool bind = temp & 1;
+            temp &= ~1;
+
+            if (!bind) {
+                free(reinterpret_cast<void *>(next));
+            }
+
+            next = temp;
+        }
+    }
+};
+
+
+#endif /* _SCOPED_ALLOCATOR_HPP_ */
diff --git a/scripts/apitrace.PIXExp b/scripts/apitrace.PIXExp
new file mode 100644 (file)
index 0000000..c7b031e
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<PIXExperiment><Version><ExpFileVersion>202</ExpFileVersion></Version><TargetApp><TargetPath></TargetPath><StartFolder></StartFolder><Args></Args><SkipProcesses>0</SkipProcesses><RecordDiagnosticLog>0</RecordDiagnosticLog><IncludeDebugSpew>0</IncludeDebugSpew><DisableD3DXAnalysis>1</DisableD3DXAnalysis></TargetApp><Columns><Column><Name>EDID</Name><ColumnID>1</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>Event Type</Name><ColumnID>2</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>EID</Name><ColumnID>3</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>Parent EID</Name><ColumnID>4</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>Children</Name><ColumnID>11</ColumnID><Flags>0</Flags><Type>6</Type><Format>%d</Format></Column><Column><Name>Parent</Name><ColumnID>10</ColumnID><Flags>0</Flags><Type>2</Type><Format>%d</Format></Column><Column><Name>Flags</Name><ColumnID>5</ColumnID><Flags>0</Flags><Type>2</Type><Format>0x%08X</Format></Column><Column><Name>Event</Name><ColumnID>6</ColumnID><Flags>0</Flags><Type>4</Type><Format>%s</Format></Column><Column><Name>StartTime</Name><ColumnID>7</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>Path</Name><ColumnID>13</ColumnID><Flags>0</Flags><Type>1</Type><Format>%s</Format></Column><Column><Name>Path2</Name><ColumnID>14</ColumnID><Flags>0</Flags><Type>1</Type><Format>%s</Format></Column><Column><Name>Version</Name><ColumnID>15</ColumnID><Flags>0</Flags><Type>1</Type><Format>%s</Format></Column><Column><Name>TimeLastModified</Name><ColumnID>16</ColumnID><Flags>0</Flags><Type>1</Type><Format>%s</Format></Column><Column><Name>ProcessID</Name><ColumnID>23</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>SessionStartTimeStamp</Name><ColumnID>24</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>Frame</Name><ColumnID>9</ColumnID><Flags>0</Flags><Type>3</Type><Format>%d</Format></Column><Column><Name>Duration</Name><ColumnID>8</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>Measured Est. Draw Duration (ns)</Name><ColumnID>27</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>FPS</Name><ColumnID>12</ColumnID><Flags>0</Flags><Type>0</Type><Format>%0.01f</Format></Column><Column><Name>ThisEventPos</Name><ColumnID>21</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>NextSiblingPos</Name><ColumnID>22</ColumnID><Flags>0</Flags><Type>5</Type><Format>%I64i</Format></Column><Column><Name>User Event Name</Name><ColumnID>17</ColumnID><Flags>0</Flags><Type>1</Type><Format>%s</Format></Column><Column><Name>PackedCallPackage</Name><ColumnID>19</ColumnID><Flags>0</Flags><Type>7</Type><Format></Format></Column><Column><Name>Object Pointer</Name><ColumnID>20</ColumnID><Flags>0</Flags><Type>2</Type><Format>0x%08X</Format></Column></Columns><EventDescs><EventDesc><Name>Session Start</Name><EventType>1</EventType><EDID>1</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,1</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>CalcOnLoad,Const,-1</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,Start Session</String></EventDescColumn><EventDescColumn><ColumnID>13</ColumnID><String>(expfilepath)</String></EventDescColumn><EventDescColumn><ColumnID>14</ColumnID><String>(runfilepath)</String></EventDescColumn><EventDescColumn><ColumnID>24</ColumnID><String>(sessionstarttimestamp)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Session End</Name><EventType>2</EventType><EDID>2</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,2</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>CalcOnLoad,Const,-1</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,End Session</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Process Start</Name><EventType>3</EventType><EDID>3</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,3</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>CalcOnLoad,Const,-1</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,Start Process</String></EventDescColumn><EventDescColumn><ColumnID>13</ColumnID><String>(processpath)</String></EventDescColumn><EventDescColumn><ColumnID>15</ColumnID><String>(processversion)</String></EventDescColumn><EventDescColumn><ColumnID>16</ColumnID><String>(processtimelastmodified)</String></EventDescColumn><EventDescColumn><ColumnID>23</ColumnID><String>(processid)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Process End</Name><EventType>4</EventType><EDID>4</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,4</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>CalcOnLoad,Const,-1</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,End Process</String></EventDescColumn><EventDescColumn><ColumnID>13</ColumnID><String>(processpath)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Frame Begin</Name><EventType>5</EventType><EDID>5</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,5</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>(rowflags)</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>9</ColumnID><String>(frame)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,1,Frame %d,3,MemberOf,ThisRow,Frame</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>Async,(duration)</String></EventDescColumn><EventDescColumn><ColumnID>12</ColumnID><String>CalcOnLoad,Divide,Const,1000000000.0,MemberOf,ThisRow,Duration</String></EventDescColumn><EventDescColumn><ColumnID>21</ColumnID><String>(frameeventfilepos)</String></EventDescColumn><EventDescColumn><ColumnID>22</ColumnID><String>(lastframeeventfilepos)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>User Event Begin</Name><EventType>7</EventType><EDID>6</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,7</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>17</ColumnID><String>(usereventname)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,1,%s,1,MemberOf,ThisRow,User Event Name</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>Async,(duration)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>User Marker</Name><EventType>9</EventType><EDID>7</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,9</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>17</ColumnID><String>(usereventname)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,1,User Marker: %s,1,MemberOf,ThisRow,User Event Name</String></EventDescColumn><EventDescColumn><ColumnID>8</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>D3D Call</Name><EventType>10</EventType><EDID>8</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,10</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,CallPlusParams,MemberOf,ThisRow,PackedCallPackage</String></EventDescColumn><EventDescColumn><ColumnID>19</ColumnID><String>Async,(packedcallpkg)</String></EventDescColumn><EventDescColumn><ColumnID>27</ColumnID><String>Async,(drawduration)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Object Creation</Name><EventType>11</EventType><EDID>9</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,11</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,Object Creation</String></EventDescColumn><EventDescColumn><ColumnID>20</ColumnID><String>(objpointer)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>Object Population</Name><EventType>12</EventType><EDID>10</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,12</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,FormatText,0,Object Population</String></EventDescColumn><EventDescColumn><ColumnID>20</ColumnID><String>(objpointer)</String></EventDescColumn></EventDescColumns></EventDesc><EventDesc><Name>D3D Call (Sync)</Name><EventType>13</EventType><EDID>11</EDID><EventDescColumns><EventDescColumn><ColumnID>1</ColumnID><String>(edid)</String></EventDescColumn><EventDescColumn><ColumnID>2</ColumnID><String>CalcOnLoad,Const,13</String></EventDescColumn><EventDescColumn><ColumnID>3</ColumnID><String>(eid)</String></EventDescColumn><EventDescColumn><ColumnID>4</ColumnID><String>(parenteid)</String></EventDescColumn><EventDescColumn><ColumnID>11</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>10</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>5</ColumnID><String>CalcOnLoad,Const,0</String></EventDescColumn><EventDescColumn><ColumnID>7</ColumnID><String>(time)</String></EventDescColumn><EventDescColumn><ColumnID>6</ColumnID><String>CalcOnLoad,CallPlusParams,MemberOf,ThisRow,PackedCallPackage</String></EventDescColumn><EventDescColumn><ColumnID>19</ColumnID><String>(packedcallpkg)</String></EventDescColumn></EventDescColumns></EventDesc></EventDescs><Counters/><Triggers><Trigger><Type>1</Type><Recurrence>0</Recurrence><Actions><Action><Type>1</Type><Int1>0</Int1><Str1></Str1></Action><Action><Type>3</Type><Int1>3</Int1><Int2>0</Int2></Action></Actions></Trigger></Triggers></PIXExperiment>
diff --git a/scripts/convert.py b/scripts/convert.py
new file mode 100755 (executable)
index 0000000..d5660c0
--- /dev/null
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 2012 VMware Inc.
+# 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.
+#
+##########################################################################/
+
+'''Convert traces to/from PIX.
+'''
+
+
+import optparse
+import os.path
+import subprocess
+import platform
+import sys
+
+
+def convert(inTrace, outPixrun):
+    try:
+        programFiles = os.environ['ProgramFiles(x86)']
+    except KeyError:
+        programFiles = os.environ['ProgramFiles']
+    try:
+        dxsdkDir = os.environ['DXSDK_DIR']
+    except KeyError:
+        dxsdkDir = os.path.join(programFiles, "Microsoft DirectX SDL (June 2010)")
+    pix = os.path.join(dxsdkDir, "Utilities", "bin", 'x86', 'PIXwin.exe')
+
+    pixExp = os.path.join(os.path.dirname(__file__), 'apitrace.PIXExp')
+
+    # http://social.msdn.microsoft.com/Forums/sv/devdocs/thread/15addc0c-036d-413a-854a-35637ccbb834
+    # http://src.chromium.org/svn/trunk/o3d/tests/test_driver.py
+    cmd = [
+        pix,
+        pixExp,
+        '-start',
+        '-runfile', os.path.abspath(outPixrun),
+        '-targetpath', os.path.abspath(options.retrace),
+        #'-targetstartfolder', ...,
+        '-targetargs', os.path.abspath(inTrace),
+    ]
+
+    if options.verbose:
+        sys.stderr.write(' '.join(cmd) + '\n')
+
+    ret = subprocess.call(cmd)
+    if ret:
+        sys.stderr.write('error: pix failued with exit code %u\n' % ret)
+        sys.exit(ret)
+    if os.path.exists(outPixrun):
+        sys.stderr.write('info: %s written\n' % outPixrun)
+        if False:
+            subprocess.call([pix, os.path.abspath(outPixrun)])
+    else:
+        sys.stderr.write('error: %s not written\n' % outPixrun)
+        sys.exit(1)
+
+
+def main():
+    global options
+
+    # Parse command line options
+    optparser = optparse.OptionParser(
+        usage='\n\t%prog [options] <trace> ...',
+        version='%%prog')
+    optparser.add_option(
+        '-r', '--retrace', metavar='PROGRAM',
+        type='string', dest='retrace', default='d3dretrace',
+        help='retrace command [default: %default]')
+    optparser.add_option(
+        '-v', '--verbose',
+        action='store_true', dest='verbose', default=False,
+        help='verbose output')
+    optparser.add_option(
+        '-o', '--output', metavar='FILE',
+        type="string", dest="output",
+        help="output file [default: stdout]")
+
+    (options, args) = optparser.parse_args(sys.argv[1:])
+    if not args:
+        optparser.error("incorrect number of arguments")
+    
+    for arg in args:
+        if options.output:
+            output = options.output
+        else:
+            name, ext = os.path.splitext(os.path.basename(arg))
+            output = name + '.PIXRun'
+        convert(arg, output)
+
+
+if __name__ == '__main__':
+    main()
index 6cea02887f3f3945bf9b99099a6a2a2b09d21d86..89e89172c3ded08e1ab59904d5880ffb017e625a 100644 (file)
@@ -221,19 +221,19 @@ cglapi.addFunctions([
     Function(CGLError, "CGLFlushDrawable", [(CGLContextObj, "ctx")]),
     Function(CGLError, "CGLEnable", [(CGLContextObj, "ctx"), (CGLContextEnable, "pname")]),
     Function(CGLError, "CGLDisable", [(CGLContextObj, "ctx"), (CGLContextEnable, "pname")]),
-    Function(CGLError, "CGLIsEnabled", [(CGLContextObj, "ctx"), (CGLContextEnable, "pname"), Out(Pointer(GLint), "enable")]),
+    Function(CGLError, "CGLIsEnabled", [(CGLContextObj, "ctx"), (CGLContextEnable, "pname"), Out(Pointer(GLint), "enable")], sideeffects=False),
     Function(CGLError, "CGLSetParameter", [(CGLContextObj, "ctx"), (CGLContextParameter, "pname"), (Array(Const(GLint), 1), "params")]),
-    Function(CGLError, "CGLGetParameter", [(CGLContextObj, "ctx"), (CGLContextParameter, "pname"), Out(Array(GLint, 1), "params")]),
+    Function(CGLError, "CGLGetParameter", [(CGLContextObj, "ctx"), (CGLContextParameter, "pname"), Out(Array(GLint, 1), "params")], sideeffects=False),
     Function(CGLError, "CGLSetVirtualScreen", [(CGLContextObj, "ctx"), (GLint, "screen")]),
-    Function(CGLError, "CGLGetVirtualScreen", [(CGLContextObj, "ctx"), Out(Pointer(GLint), "screen")]),
+    Function(CGLError, "CGLGetVirtualScreen", [(CGLContextObj, "ctx"), Out(Pointer(GLint), "screen")], sideeffects=False),
     Function(CGLError, "CGLSetGlobalOption", [(CGLGlobalOption, "pname"), (OpaquePointer(Const(GLint)), "params")]),
     Function(CGLError, "CGLGetGlobalOption", [(CGLGlobalOption, "pname"), Out(OpaquePointer(GLint), "params")]),
     Function(CGLError, "CGLSetOption", [(CGLGlobalOption, "pname"), (GLint, "param")]),
-    Function(CGLError, "CGLGetOption", [(CGLGlobalOption, "pname"), Out(Pointer(GLint), "param")]),
+    Function(CGLError, "CGLGetOption", [(CGLGlobalOption, "pname"), Out(Pointer(GLint), "param")], sideeffects=False),
     Function(CGLError, "CGLLockContext", [(CGLContextObj, "ctx")]),
     Function(CGLError, "CGLUnlockContext", [(CGLContextObj, "ctx")]),
-    Function(Void, "CGLGetVersion", [Out(Pointer(GLint), "majorvers"), Out(Pointer(GLint), "minorvers")]),
-    Function(ConstCString, "CGLErrorString", [(CGLError, "error")]),
+    Function(Void, "CGLGetVersion", [Out(Pointer(GLint), "majorvers"), Out(Pointer(GLint), "minorvers")], sideeffects=False),
+    Function(ConstCString, "CGLErrorString", [(CGLError, "error")], sideeffects=False),
 
     # CGLIOSurface.h, OpenGL framework
     Function(CGLError, "CGLTexImageIOSurface2D", [(CGLContextObj, "ctx"), (GLenum, "target"), (GLenum, "internal_format"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (GLenum, "type"), (IOSurfaceRef, "ioSurface"), (GLuint, "plane")]),
index 36499b7fac457a97b79cd6689ef51b10046c6967..5c52f98df72524727a95322d252604a5589abf43 100644 (file)
@@ -184,7 +184,7 @@ DXVA2_DecodeExtensionData = Struct("DXVA2_DecodeExtensionData", [
 
 DXVA2_DecodeExecuteParams = Struct("DXVA2_DecodeExecuteParams", [
     (UINT, "NumCompBuffers"),
-    (Pointer(DXVA2_DecodeBufferDesc), "pCompressedBuffers"),
+    (Array(DXVA2_DecodeBufferDesc, "{self}.NumCompBuffers"), "pCompressedBuffers"),
     (Pointer(DXVA2_DecodeExtensionData), "pExtensionData"),
 ])
 
@@ -263,7 +263,15 @@ DXVA2_VideoProcessorCaps = Struct("DXVA2_VideoProcessorCaps", [
 ])
 
 
-DXVA2_PVP_SETKEY = Opaque('DXVA2_PVP_SETKEY')
+# See also DXVADDI_PVP_KEY128
+DXVA2_PVP_KEY128 = Struct('DXVA2_PVP_KEY128', [
+    (Array(BYTE, 16), 'Data'),
+])
+
+# See also DXVADDI_PVP_SETKEY
+DXVA2_PVP_SETKEY = Struct('DXVA2_PVP_SETKEY', [
+    (DXVA2_PVP_KEY128, 'ContentKey'),
+])
 
 DXVA2_DECODEBUFFERDESC = Struct("DXVA2_DECODEBUFFERDESC", [
     (ObjPointer(IDirect3DSurface9), "pRenderTarget"),
@@ -321,7 +329,7 @@ DXVA2_DECODEBUFFERINFO = Opaque('DXVA2_DECODEBUFFERINFO')
 
 IDirect3DDecodeDevice9 = Interface("IDirect3DDecodeDevice9", IUnknown)
 IDirect3DDecodeDevice9.methods += [
-    StdMethod(HRESULT, "DecodeBeginFrame", [(OpaquePointer(DXVA2_PVP_SETKEY), "pPVPSetKey")]),
+    StdMethod(HRESULT, "DecodeBeginFrame", [(Pointer(DXVA2_PVP_SETKEY), "pPVPSetKey")]),
     StdMethod(HRESULT, "DecodeEndFrame", [(Pointer(HANDLE), "pHandleComplete")]),
     StdMethod(HRESULT, "DecodeSetRenderTarget", [(ObjPointer(IDirect3DSurface9), "pRenderTarget")]),
     StdMethod(HRESULT, "DecodeExecute", [(Pointer(DXVA2_DECODEEXECUTE), "pExecuteParams")]),
index 89797349c6ab4c3568b1e5403b028e8247641fe4..dc9e85203df21cbd63e9c86b3d4e56bf9d61194a 100644 (file)
@@ -728,6 +728,7 @@ D3DFORMAT = Enum("D3DFORMAT", [
     "D3DFMT_INTZ",
     "D3DFMT_NULL",
     "D3DFMT_NV12",
+    "D3DFMT_YV12",
     "D3DFMT_RAWZ",
 ])
 
index 3be99a89bebc9cf45513bf8817d8ede604ced25b..41b5a0f177e4f1f2c9d77689b9e943a060129f11 100644 (file)
@@ -1582,8 +1582,7 @@ parameters = [
     ("glGetTexLevelParameter", I,      1,      "GL_TEXTURE_COMPRESSED_IMAGE_SIZE"),    # 0x86A0
     ("glGetTexLevelParameter", B,      1,      "GL_TEXTURE_COMPRESSED"),       # 0x86A1
     ("glGet",  I,      1,      "GL_NUM_COMPRESSED_TEXTURE_FORMATS"),   # 0x86A2
-    #XXX: the list is GL_NUM_COMPRESSED_TEXTURES
-    #("glGet", E,      1,      "GL_COMPRESSED_TEXTURE_FORMATS"),       # 0x86A3
+    ("glGet",  E,      '_glGetInteger(GL_NUM_COMPRESSED_TEXTURE_FORMATS)',     "GL_COMPRESSED_TEXTURE_FORMATS"),       # 0x86A3
     ("glGet",  I,      1,      "GL_MAX_VERTEX_UNITS_ARB"),     # 0x86A4
     ("glGet",  I,      1,      "GL_ACTIVE_VERTEX_UNITS_ARB"),  # 0x86A5
     ("glGet",  B,      1,      "GL_WEIGHT_SUM_UNITY_ARB"),     # 0x86A6
@@ -1893,8 +1892,8 @@ parameters = [
     ("",       X,      1,      "GL_VBO_FREE_MEMORY_ATI"),      # 0x87FB
     ("",       X,      1,      "GL_TEXTURE_FREE_MEMORY_ATI"),  # 0x87FC
     ("",       X,      1,      "GL_RENDERBUFFER_FREE_MEMORY_ATI"),     # 0x87FD
-    ("",       X,      1,      "GL_NUM_PROGRAM_BINARY_FORMATS"),       # 0x87FE
-    ("",       X,      1,      "GL_PROGRAM_BINARY_FORMATS"),   # 0x87FF
+    ("glGet",  I,      1,      "GL_NUM_PROGRAM_BINARY_FORMATS"),       # 0x87FE
+    ("glGet",  E,      "_glGetInteger(GL_NUM_PROGRAM_BINARY_FORMATS)", "GL_PROGRAM_BINARY_FORMATS"),   # 0x87FF
     ("glGet",  E,      1,      "GL_STENCIL_BACK_FUNC"),        # 0x8800
     ("glGet",  E,      1,      "GL_STENCIL_BACK_FAIL"),        # 0x8801
     ("glGet",  E,      1,      "GL_STENCIL_BACK_PASS_DEPTH_FAIL"),     # 0x8802
@@ -2251,12 +2250,12 @@ parameters = [
     ("",       X,      1,      "GL_RESAMPLE_ZERO_FILL_OML"),   # 0x8987
     ("",       X,      1,      "GL_RESAMPLE_AVERAGE_OML"),     # 0x8988
     ("",       X,      1,      "GL_RESAMPLE_DECIMATE_OML"),    # 0x8989
-    #("",      X,      1,      "GL_POINT_SIZE_ARRAY_TYPE_OES"),        # 0x898A
-    #("",      X,      1,      "GL_POINT_SIZE_ARRAY_STRIDE_OES"),      # 0x898B
-    #("",      X,      1,      "GL_POINT_SIZE_ARRAY_POINTER_OES"),     # 0x898C
-    #("",      X,      1,      "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES"),   # 0x898D
-    #("",      X,      1,      "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES"),  # 0x898E
-    #("",      X,      1,      "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES"),     # 0x898F
+    ("",       X,      1,      "GL_POINT_SIZE_ARRAY_TYPE_OES"),        # 0x898A
+    ("",       X,      1,      "GL_POINT_SIZE_ARRAY_STRIDE_OES"),      # 0x898B
+    ("",       X,      1,      "GL_POINT_SIZE_ARRAY_POINTER_OES"),     # 0x898C
+    ("",       X,      1,      "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES"),   # 0x898D
+    ("",       X,      1,      "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES"),  # 0x898E
+    ("",       X,      1,      "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES"),     # 0x898F
     ("",       X,      1,      "GL_VERTEX_ATTRIB_MAP1_APPLE"), # 0x8A00
     ("",       X,      1,      "GL_VERTEX_ATTRIB_MAP2_APPLE"), # 0x8A01
     ("",       X,      1,      "GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE"),    # 0x8A02
@@ -2371,22 +2370,22 @@ parameters = [
     ("",       X,      1,      "GL_FRAGMENT_SHADER_DERIVATIVE_HINT"),  # 0x8B8B
     ("glGet",  S,      1,      "GL_SHADING_LANGUAGE_VERSION"), # 0x8B8C
     ("glGet",  I,      1,      "GL_CURRENT_PROGRAM"),  # 0x8B8D
-    #("",      X,      1,      "GL_PALETTE4_RGB8_OES"),        # 0x8B90
-    #("",      X,      1,      "GL_PALETTE4_RGBA8_OES"),       # 0x8B91
-    #("",      X,      1,      "GL_PALETTE4_R5_G6_B5_OES"),    # 0x8B92
-    #("",      X,      1,      "GL_PALETTE4_RGBA4_OES"),       # 0x8B93
-    #("",      X,      1,      "GL_PALETTE4_RGB5_A1_OES"),     # 0x8B94
-    #("",      X,      1,      "GL_PALETTE8_RGB8_OES"),        # 0x8B95
-    #("",      X,      1,      "GL_PALETTE8_RGBA8_OES"),       # 0x8B96
-    #("",      X,      1,      "GL_PALETTE8_R5_G6_B5_OES"),    # 0x8B97
-    #("",      X,      1,      "GL_PALETTE8_RGBA4_OES"),       # 0x8B98
-    #("",      X,      1,      "GL_PALETTE8_RGB5_A1_OES"),     # 0x8B99
+    ("",       X,      1,      "GL_PALETTE4_RGB8_OES"),        # 0x8B90
+    ("",       X,      1,      "GL_PALETTE4_RGBA8_OES"),       # 0x8B91
+    ("",       X,      1,      "GL_PALETTE4_R5_G6_B5_OES"),    # 0x8B92
+    ("",       X,      1,      "GL_PALETTE4_RGBA4_OES"),       # 0x8B93
+    ("",       X,      1,      "GL_PALETTE4_RGB5_A1_OES"),     # 0x8B94
+    ("",       X,      1,      "GL_PALETTE8_RGB8_OES"),        # 0x8B95
+    ("",       X,      1,      "GL_PALETTE8_RGBA8_OES"),       # 0x8B96
+    ("",       X,      1,      "GL_PALETTE8_R5_G6_B5_OES"),    # 0x8B97
+    ("",       X,      1,      "GL_PALETTE8_RGBA4_OES"),       # 0x8B98
+    ("",       X,      1,      "GL_PALETTE8_RGB5_A1_OES"),     # 0x8B99
     ("glGet",  E,      1,      "GL_IMPLEMENTATION_COLOR_READ_TYPE"),   # 0x8B9A
     ("glGet",  E,      1,      "GL_IMPLEMENTATION_COLOR_READ_FORMAT"), # 0x8B9B
-    #("",      X,      1,      "GL_POINT_SIZE_ARRAY_OES"),     # 0x8B9C
+    ("",       X,      1,      "GL_POINT_SIZE_ARRAY_OES"),     # 0x8B9C
     ("glGetTexParameter",      I,      4,      "GL_TEXTURE_CROP_RECT_OES"),    # 0x8B9D
-    #("",      X,      1,      "GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES"),    # 0x8B9E
-    #("",      X,      1,      "GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES"),      # 0x8B9F
+    ("",       X,      1,      "GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES"),    # 0x8B9E
+    ("",       X,      1,      "GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES"),      # 0x8B9F
     #("",      X,      1,      "GL_FRAGMENT_PROGRAM_POSITION_MESA"),   # 0x8BB0
     #("",      X,      1,      "GL_FRAGMENT_PROGRAM_CALLBACK_MESA"),   # 0x8BB1
     #("",      X,      1,      "GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA"),      # 0x8BB2
@@ -2504,8 +2503,8 @@ parameters = [
     ("",       X,      1,      "GL_SEPARATE_ATTRIBS"), # 0x8C8D
     ("",       X,      1,      "GL_TRANSFORM_FEEDBACK_BUFFER"),        # 0x8C8E
     ("glGet",  I,      1,      "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING"),        # 0x8C8F
-    #("",      X,      1,      "GL_ATC_RGB_AMD"),      # 0x8C92
-    #("",      X,      1,      "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD"),      # 0x8C93
+    ("",       X,      1,      "GL_ATC_RGB_AMD"),      # 0x8C92
+    ("",       X,      1,      "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD"),      # 0x8C93
     ("glGet",  E,      1,      "GL_POINT_SPRITE_COORD_ORIGIN"),        # 0x8CA0
     ("",       X,      1,      "GL_LOWER_LEFT"),       # 0x8CA1
     ("",       X,      1,      "GL_UPPER_LEFT"),       # 0x8CA2
@@ -2569,18 +2568,18 @@ parameters = [
     ("glGetRenderbufferParameter",     I,      1,      "GL_RENDERBUFFER_STENCIL_SIZE"),        # 0x8D55
     ("",       X,      1,      "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"),       # 0x8D56
     ("glGet",  I,      1,      "GL_MAX_SAMPLES"),      # 0x8D57
-    #("",      X,      1,      "GL_TEXTURE_GEN_STR_OES"),      # 0x8D60
-    #("",      X,      1,      "GL_HALF_FLOAT_OES"),   # 0x8D61
-    #("",      X,      1,      "GL_RGB565_OES"),       # 0x8D62
-    #("",      X,      1,      "GL_ETC1_RGB8_OES"),    # 0x8D64
-    #("",      X,      1,      "GL_TEXTURE_EXTERNAL_OES"),     # 0x8D65
-    #("",      X,      1,      "GL_SAMPLER_EXTERNAL_OES"),     # 0x8D66
-    #("",      X,      1,      "GL_TEXTURE_BINDING_EXTERNAL_OES"),     # 0x8D67
-    #("",      X,      1,      "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES"), # 0x8D68
+    ("",       X,      1,      "GL_TEXTURE_GEN_STR_OES"),      # 0x8D60
+    ("",       X,      1,      "GL_HALF_FLOAT_OES"),   # 0x8D61
+    ("",       X,      1,      "GL_RGB565_OES"),       # 0x8D62
+    ("",       X,      1,      "GL_ETC1_RGB8_OES"),    # 0x8D64
+    ("",       X,      1,      "GL_TEXTURE_EXTERNAL_OES"),     # 0x8D65
+    ("",       X,      1,      "GL_SAMPLER_EXTERNAL_OES"),     # 0x8D66
+    ("",       X,      1,      "GL_TEXTURE_BINDING_EXTERNAL_OES"),     # 0x8D67
+    ("",       X,      1,      "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES"), # 0x8D68
     ("",       B,      1,      "GL_PRIMITIVE_RESTART_FIXED_INDEX"),    # 0x8D69
     ("",       X,      1,      "GL_ANY_SAMPLES_PASSED_CONSERVATIVE"),  # 0x8D6A
     ("glGet",  I,      1,      "GL_MAX_ELEMENT_INDEX"),        # 0x8D6B
-    #("",      X,      1,      "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT"),       # 0x8D6C
+    ("",       X,      1,      "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT"),       # 0x8D6C
     ("",       X,      1,      "GL_RGBA32UI"), # 0x8D70
     ("",       X,      1,      "GL_RGB32UI"),  # 0x8D71
     ("",       X,      1,      "GL_ALPHA32UI_EXT"),    # 0x8D72
@@ -2850,7 +2849,7 @@ parameters = [
     ("",       X,      1,      "GL_DOUBLE_MAT3x4"),    # 0x8F4C
     ("",       X,      1,      "GL_DOUBLE_MAT4x2"),    # 0x8F4D
     ("",       X,      1,      "GL_DOUBLE_MAT4x3"),    # 0x8F4E
-    #("",      X,      1,      "GL_MALI_SHADER_BINARY_ARM"),   # 0x8F60
+    ("",       X,      1,      "GL_MALI_SHADER_BINARY_ARM"),   # 0x8F60
     ("",       X,      1,      "GL_RED_SNORM"),        # 0x8F90
     ("",       X,      1,      "GL_RG_SNORM"), # 0x8F91
     ("",       X,      1,      "GL_RGB_SNORM"),        # 0x8F92
@@ -2867,8 +2866,8 @@ parameters = [
     ("glGet",  B,      1,      "GL_PRIMITIVE_RESTART"),        # 0x8F9D
     ("glGet",  I,      1,      "GL_PRIMITIVE_RESTART_INDEX"),  # 0x8F9E
     #("",      X,      1,      "GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS"),    # 0x8F9F
-    #("",      X,      1,      "GL_PERFMON_GLOBAL_MODE_QCOM"), # 0x8FA0
-    #("",      X,      1,      "GL_SHADER_BINARY_VIV"),        # 0x8FC4
+    ("",       X,      1,      "GL_PERFMON_GLOBAL_MODE_QCOM"), # 0x8FA0
+    ("",       X,      1,      "GL_SHADER_BINARY_VIV"),        # 0x8FC4
     ("",       X,      1,      "GL_INT8_NV"),  # 0x8FE0
     ("",       X,      1,      "GL_INT8_VEC2_NV"),     # 0x8FE1
     ("",       X,      1,      "GL_INT8_VEC3_NV"),     # 0x8FE2
@@ -3157,11 +3156,11 @@ parameters = [
     ("",       X,      1,      "GL_PACK_COMPRESSED_BLOCK_DEPTH"),      # 0x912D
     ("",       X,      1,      "GL_PACK_COMPRESSED_BLOCK_SIZE"),       # 0x912E
     ("",       X,      1,      "GL_TEXTURE_IMMUTABLE_FORMAT"), # 0x912F
-    #("",      X,      1,      "GL_SGX_PROGRAM_BINARY_IMG"),   # 0x9130
-    #("",      X,      1,      "GL_RENDERBUFFER_SAMPLES_IMG"), # 0x9133
-    #("",      X,      1,      "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG"),   # 0x9134
-    #("",      X,      1,      "GL_MAX_SAMPLES_IMG"),  # 0x9135
-    #("",      X,      1,      "GL_TEXTURE_SAMPLES_IMG"),      # 0x9136
+    ("",       X,      1,      "GL_SGX_PROGRAM_BINARY_IMG"),   # 0x9130
+    ("",       X,      1,      "GL_RENDERBUFFER_SAMPLES_IMG"), # 0x9133
+    ("",       X,      1,      "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG"),   # 0x9134
+    ("",       X,      1,      "GL_MAX_SAMPLES_IMG"),  # 0x9135
+    ("",       X,      1,      "GL_TEXTURE_SAMPLES_IMG"),      # 0x9136
     ("glGet",  I,      1,      "GL_MAX_DEBUG_MESSAGE_LENGTH"), # 0x9143
     ("glGet",  I,      1,      "GL_MAX_DEBUG_LOGGED_MESSAGES"),        # 0x9144
     ("glGet",  I,      1,      "GL_DEBUG_LOGGED_MESSAGES"),    # 0x9145
@@ -3325,14 +3324,14 @@ parameters = [
     ("",       X,      1,      "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"),   # 0x93DB
     ("",       X,      1,      "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"),   # 0x93DC
     ("",       X,      1,      "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"),   # 0x93DD
-    #("",      X,      1,      "GL_RESTART_PATH_NV"),  # 0xF0
-    #("",      X,      1,      "GL_DUP_FIRST_CUBIC_CURVE_TO_NV"),      # 0xF2
-    #("",      X,      1,      "GL_DUP_LAST_CUBIC_CURVE_TO_NV"),       # 0xF4
-    #("",      X,      1,      "GL_RECT_NV"),  # 0xF6
-    #("",      X,      1,      "GL_CIRCULAR_CCW_ARC_TO_NV"),   # 0xF8
-    #("",      X,      1,      "GL_CIRCULAR_CW_ARC_TO_NV"),    # 0xFA
-    #("",      X,      1,      "GL_CIRCULAR_TANGENT_ARC_TO_NV"),       # 0xFC
-    #("",      X,      1,      "GL_ARC_TO_NV"),        # 0xFE
+    ("",       X,      1,      "GL_RESTART_PATH_NV"),  # 0xF0
+    ("",       X,      1,      "GL_DUP_FIRST_CUBIC_CURVE_TO_NV"),      # 0xF2
+    ("",       X,      1,      "GL_DUP_LAST_CUBIC_CURVE_TO_NV"),       # 0xF4
+    ("",       X,      1,      "GL_RECT_NV"),  # 0xF6
+    ("",       X,      1,      "GL_CIRCULAR_CCW_ARC_TO_NV"),   # 0xF8
+    ("",       X,      1,      "GL_CIRCULAR_CW_ARC_TO_NV"),    # 0xFA
+    ("",       X,      1,      "GL_CIRCULAR_TANGENT_ARC_TO_NV"),       # 0xFC
+    ("",       X,      1,      "GL_ARC_TO_NV"),        # 0xFE
     #("",      X,      1,      "GL_TIMEOUT_IGNORED"),  # 0xFFFFFFFFFFFFFFFFull
     ("",       X,      1,      "GL_INVALID_INDEX"),    # 0xFFFFFFFFu
 ]
index b86668bd13be9d2a44b34227fbf5d06eee7733f5..c652736a8383e9156e5bd7e88af34dde79760382 100644 (file)
@@ -385,6 +385,12 @@ class Function:
     def argNames(self):
         return [arg.name for arg in self.args]
 
+    def getArgByName(self, name):
+        for arg in self.args:
+            if arg.name == name:
+                return arg
+        return None
+
 
 def StdFunction(*args, **kwargs):
     kwargs.setdefault('call', '__stdcall')
index 031c83475583176465952bba06576f18d735feae..4436c6ddb971d494329db0e1a2dd1f9d7b798407 100644 (file)
@@ -206,7 +206,7 @@ IUnknown = Interface("IUnknown")
 
 IUnknown.methods = (
        StdMethod(HRESULT, "QueryInterface", ((REFIID, "riid"), Out(Pointer(ObjPointer(Void)), "ppvObj"))),
-       StdMethod(ULONG, "AddRef", (), sideeffects=False),
+       StdMethod(ULONG, "AddRef", ()),
        StdMethod(ULONG, "Release", ()),
 )
 
index fc46f7d1dc262a849b40e1ea774e92a1356c031c..224fc1ea508754dbf0d522c02f5fa1b58deb3a93 100644 (file)
@@ -1,5 +1,11 @@
 include_directories (${CMAKE_CURRENT_SOURCE_DIR})
 
-add_library (getopt_bundled STATIC
+add_library (getopt_bundled STATIC EXCLUDE_FROM_ALL
     getopt_long.c
 )
+
+install (
+    FILES LICENSE
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-getopt.txt
+)
diff --git a/thirdparty/getopt/LICENSE b/thirdparty/getopt/LICENSE
new file mode 100644 (file)
index 0000000..1a9141b
--- /dev/null
@@ -0,0 +1,45 @@
+Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Sponsored in part by the Defense Advanced Research Projects
+Agency (DARPA) and Air Force Research Laboratory, Air Force
+Materiel Command, USAF, under agreement number F39502-99-1-0512.
+
+
+Copyright (c) 2000 The NetBSD Foundation, Inc.
+All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation
+by Dieter Baron and Thomas Klausner.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
index 95e71755598cab1e5921e25a84995445ed8d1ad8..ef4eba63fd711f1fb9da9c9abcd02527f14d7a00 100644 (file)
@@ -31,6 +31,6 @@ install (
 
 install (
     FILES LICENSE
-    DESTINATION doc
-    RENAME LICENSE.less
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-less.txt
 )
index 7775f915a9c1a0fd5f9d72f4d5e4db3214e4cda5..7cf2be909ac16bb512f0a362e3a244f6a7cf1521 100644 (file)
@@ -1,6 +1,6 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
-add_library (png_bundled STATIC
+add_library (png_bundled STATIC EXCLUDE_FROM_ALL
     png.c
     pngerror.c
     pngget.c
@@ -21,3 +21,9 @@ add_library (png_bundled STATIC
 set_target_properties (png_bundled PROPERTIES
     COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}"
 )
+
+install (
+    FILES LICENSE
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-libpng.txt
+)
diff --git a/thirdparty/msinttypes/.gitignore b/thirdparty/msinttypes/.gitignore
new file mode 100644 (file)
index 0000000..2460008
--- /dev/null
@@ -0,0 +1 @@
+!Makefile
diff --git a/thirdparty/msinttypes/LICENSE b/thirdparty/msinttypes/LICENSE
new file mode 100644 (file)
index 0000000..7af067d
--- /dev/null
@@ -0,0 +1,25 @@
+Copyright (c) 2006-2008 Alexander Chemeris
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+
+  3. The name of the author may be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/thirdparty/msinttypes/Makefile b/thirdparty/msinttypes/Makefile
new file mode 100644 (file)
index 0000000..ab18b4d
--- /dev/null
@@ -0,0 +1,10 @@
+update: \
+       inttypes.h \
+       stdint.h
+
+%.h: FORCE
+       wget -N http://msinttypes.googlecode.com/svn/trunk/$@
+
+.PHONY: update
+
+FORCE:
diff --git a/thirdparty/msinttypes/inttypes.h b/thirdparty/msinttypes/inttypes.h
new file mode 100644 (file)
index 0000000..4b3828a
--- /dev/null
@@ -0,0 +1,305 @@
+// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+   intmax_t quot;
+   intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8       "d"
+#define PRIi8       "i"
+#define PRIdLEAST8  "d"
+#define PRIiLEAST8  "i"
+#define PRIdFAST8   "d"
+#define PRIiFAST8   "i"
+
+#define PRId16       "hd"
+#define PRIi16       "hi"
+#define PRIdLEAST16  "hd"
+#define PRIiLEAST16  "hi"
+#define PRIdFAST16   "hd"
+#define PRIiFAST16   "hi"
+
+#define PRId32       "I32d"
+#define PRIi32       "I32i"
+#define PRIdLEAST32  "I32d"
+#define PRIiLEAST32  "I32i"
+#define PRIdFAST32   "I32d"
+#define PRIiFAST32   "I32i"
+
+#define PRId64       "I64d"
+#define PRIi64       "I64i"
+#define PRIdLEAST64  "I64d"
+#define PRIiLEAST64  "I64i"
+#define PRIdFAST64   "I64d"
+#define PRIiFAST64   "I64i"
+
+#define PRIdMAX     "I64d"
+#define PRIiMAX     "I64i"
+
+#define PRIdPTR     "Id"
+#define PRIiPTR     "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8       "o"
+#define PRIu8       "u"
+#define PRIx8       "x"
+#define PRIX8       "X"
+#define PRIoLEAST8  "o"
+#define PRIuLEAST8  "u"
+#define PRIxLEAST8  "x"
+#define PRIXLEAST8  "X"
+#define PRIoFAST8   "o"
+#define PRIuFAST8   "u"
+#define PRIxFAST8   "x"
+#define PRIXFAST8   "X"
+
+#define PRIo16       "ho"
+#define PRIu16       "hu"
+#define PRIx16       "hx"
+#define PRIX16       "hX"
+#define PRIoLEAST16  "ho"
+#define PRIuLEAST16  "hu"
+#define PRIxLEAST16  "hx"
+#define PRIXLEAST16  "hX"
+#define PRIoFAST16   "ho"
+#define PRIuFAST16   "hu"
+#define PRIxFAST16   "hx"
+#define PRIXFAST16   "hX"
+
+#define PRIo32       "I32o"
+#define PRIu32       "I32u"
+#define PRIx32       "I32x"
+#define PRIX32       "I32X"
+#define PRIoLEAST32  "I32o"
+#define PRIuLEAST32  "I32u"
+#define PRIxLEAST32  "I32x"
+#define PRIXLEAST32  "I32X"
+#define PRIoFAST32   "I32o"
+#define PRIuFAST32   "I32u"
+#define PRIxFAST32   "I32x"
+#define PRIXFAST32   "I32X"
+
+#define PRIo64       "I64o"
+#define PRIu64       "I64u"
+#define PRIx64       "I64x"
+#define PRIX64       "I64X"
+#define PRIoLEAST64  "I64o"
+#define PRIuLEAST64  "I64u"
+#define PRIxLEAST64  "I64x"
+#define PRIXLEAST64  "I64X"
+#define PRIoFAST64   "I64o"
+#define PRIuFAST64   "I64u"
+#define PRIxFAST64   "I64x"
+#define PRIXFAST64   "I64X"
+
+#define PRIoMAX     "I64o"
+#define PRIuMAX     "I64u"
+#define PRIxMAX     "I64x"
+#define PRIXMAX     "I64X"
+
+#define PRIoPTR     "Io"
+#define PRIuPTR     "Iu"
+#define PRIxPTR     "Ix"
+#define PRIXPTR     "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8       "d"
+#define SCNi8       "i"
+#define SCNdLEAST8  "d"
+#define SCNiLEAST8  "i"
+#define SCNdFAST8   "d"
+#define SCNiFAST8   "i"
+
+#define SCNd16       "hd"
+#define SCNi16       "hi"
+#define SCNdLEAST16  "hd"
+#define SCNiLEAST16  "hi"
+#define SCNdFAST16   "hd"
+#define SCNiFAST16   "hi"
+
+#define SCNd32       "ld"
+#define SCNi32       "li"
+#define SCNdLEAST32  "ld"
+#define SCNiLEAST32  "li"
+#define SCNdFAST32   "ld"
+#define SCNiFAST32   "li"
+
+#define SCNd64       "I64d"
+#define SCNi64       "I64i"
+#define SCNdLEAST64  "I64d"
+#define SCNiLEAST64  "I64i"
+#define SCNdFAST64   "I64d"
+#define SCNiFAST64   "I64i"
+
+#define SCNdMAX     "I64d"
+#define SCNiMAX     "I64i"
+
+#ifdef _WIN64 // [
+#  define SCNdPTR     "I64d"
+#  define SCNiPTR     "I64i"
+#else  // _WIN64 ][
+#  define SCNdPTR     "ld"
+#  define SCNiPTR     "li"
+#endif  // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8       "o"
+#define SCNu8       "u"
+#define SCNx8       "x"
+#define SCNX8       "X"
+#define SCNoLEAST8  "o"
+#define SCNuLEAST8  "u"
+#define SCNxLEAST8  "x"
+#define SCNXLEAST8  "X"
+#define SCNoFAST8   "o"
+#define SCNuFAST8   "u"
+#define SCNxFAST8   "x"
+#define SCNXFAST8   "X"
+
+#define SCNo16       "ho"
+#define SCNu16       "hu"
+#define SCNx16       "hx"
+#define SCNX16       "hX"
+#define SCNoLEAST16  "ho"
+#define SCNuLEAST16  "hu"
+#define SCNxLEAST16  "hx"
+#define SCNXLEAST16  "hX"
+#define SCNoFAST16   "ho"
+#define SCNuFAST16   "hu"
+#define SCNxFAST16   "hx"
+#define SCNXFAST16   "hX"
+
+#define SCNo32       "lo"
+#define SCNu32       "lu"
+#define SCNx32       "lx"
+#define SCNX32       "lX"
+#define SCNoLEAST32  "lo"
+#define SCNuLEAST32  "lu"
+#define SCNxLEAST32  "lx"
+#define SCNXLEAST32  "lX"
+#define SCNoFAST32   "lo"
+#define SCNuFAST32   "lu"
+#define SCNxFAST32   "lx"
+#define SCNXFAST32   "lX"
+
+#define SCNo64       "I64o"
+#define SCNu64       "I64u"
+#define SCNx64       "I64x"
+#define SCNX64       "I64X"
+#define SCNoLEAST64  "I64o"
+#define SCNuLEAST64  "I64u"
+#define SCNxLEAST64  "I64x"
+#define SCNXLEAST64  "I64X"
+#define SCNoFAST64   "I64o"
+#define SCNuFAST64   "I64u"
+#define SCNxFAST64   "I64x"
+#define SCNXFAST64   "I64X"
+
+#define SCNoMAX     "I64o"
+#define SCNuMAX     "I64u"
+#define SCNxMAX     "I64x"
+#define SCNXMAX     "I64X"
+
+#ifdef _WIN64 // [
+#  define SCNoPTR     "I64o"
+#  define SCNuPTR     "I64u"
+#  define SCNxPTR     "I64x"
+#  define SCNXPTR     "I64X"
+#else  // _WIN64 ][
+#  define SCNoPTR     "lo"
+#  define SCNuPTR     "lu"
+#  define SCNxPTR     "lx"
+#  define SCNXPTR     "lX"
+#endif  // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+   imaxdiv_t result;
+
+   result.quot = numer / denom;
+   result.rem = numer % denom;
+
+   if (numer < 0 && result.rem > 0) {
+      // did division wrong; must fix up
+      ++result.quot;
+      result.rem -= denom;
+   }
+
+   return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/thirdparty/msinttypes/stdbool.h b/thirdparty/msinttypes/stdbool.h
new file mode 100644 (file)
index 0000000..99a735d
--- /dev/null
@@ -0,0 +1,46 @@
+/**************************************************************************
+ *
+ * Copyright 2007-2010 VMware, Inc.
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+#ifndef _STDBOOL_H_
+#define _STDBOOL_H_
+
+#ifndef __cplusplus
+
+#define false   0
+#define true    1
+#define bool    _Bool
+
+/* For compilers that don't have the builtin _Bool type. */
+#if defined(_MSC_VER) || (__STDC_VERSION__ < 199901L && __GNUC__ < 3)
+typedef unsigned char _Bool;
+#endif
+
+#endif /* !__cplusplus */
+
+#define __bool_true_false_are_defined   1
+
+#endif /* !_STDBOOL_H_ */
diff --git a/thirdparty/msinttypes/stdint.h b/thirdparty/msinttypes/stdint.h
new file mode 100644 (file)
index 0000000..d02608a
--- /dev/null
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/thirdparty/msvc/.gitignore b/thirdparty/msvc/.gitignore
deleted file mode 100644 (file)
index 2460008..0000000
+++ /dev/null
@@ -1 +0,0 @@
-!Makefile
diff --git a/thirdparty/msvc/Makefile b/thirdparty/msvc/Makefile
deleted file mode 100644 (file)
index ab18b4d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-update: \
-       inttypes.h \
-       stdint.h
-
-%.h: FORCE
-       wget -N http://msinttypes.googlecode.com/svn/trunk/$@
-
-.PHONY: update
-
-FORCE:
diff --git a/thirdparty/msvc/inttypes.h b/thirdparty/msvc/inttypes.h
deleted file mode 100644 (file)
index 4b3828a..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_INTTYPES_H_ // [
-#define _MSC_INTTYPES_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include "stdint.h"
-
-// 7.8 Format conversion of integer types
-
-typedef struct {
-   intmax_t quot;
-   intmax_t rem;
-} imaxdiv_t;
-
-// 7.8.1 Macros for format specifiers
-
-#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
-
-// The fprintf macros for signed integers are:
-#define PRId8       "d"
-#define PRIi8       "i"
-#define PRIdLEAST8  "d"
-#define PRIiLEAST8  "i"
-#define PRIdFAST8   "d"
-#define PRIiFAST8   "i"
-
-#define PRId16       "hd"
-#define PRIi16       "hi"
-#define PRIdLEAST16  "hd"
-#define PRIiLEAST16  "hi"
-#define PRIdFAST16   "hd"
-#define PRIiFAST16   "hi"
-
-#define PRId32       "I32d"
-#define PRIi32       "I32i"
-#define PRIdLEAST32  "I32d"
-#define PRIiLEAST32  "I32i"
-#define PRIdFAST32   "I32d"
-#define PRIiFAST32   "I32i"
-
-#define PRId64       "I64d"
-#define PRIi64       "I64i"
-#define PRIdLEAST64  "I64d"
-#define PRIiLEAST64  "I64i"
-#define PRIdFAST64   "I64d"
-#define PRIiFAST64   "I64i"
-
-#define PRIdMAX     "I64d"
-#define PRIiMAX     "I64i"
-
-#define PRIdPTR     "Id"
-#define PRIiPTR     "Ii"
-
-// The fprintf macros for unsigned integers are:
-#define PRIo8       "o"
-#define PRIu8       "u"
-#define PRIx8       "x"
-#define PRIX8       "X"
-#define PRIoLEAST8  "o"
-#define PRIuLEAST8  "u"
-#define PRIxLEAST8  "x"
-#define PRIXLEAST8  "X"
-#define PRIoFAST8   "o"
-#define PRIuFAST8   "u"
-#define PRIxFAST8   "x"
-#define PRIXFAST8   "X"
-
-#define PRIo16       "ho"
-#define PRIu16       "hu"
-#define PRIx16       "hx"
-#define PRIX16       "hX"
-#define PRIoLEAST16  "ho"
-#define PRIuLEAST16  "hu"
-#define PRIxLEAST16  "hx"
-#define PRIXLEAST16  "hX"
-#define PRIoFAST16   "ho"
-#define PRIuFAST16   "hu"
-#define PRIxFAST16   "hx"
-#define PRIXFAST16   "hX"
-
-#define PRIo32       "I32o"
-#define PRIu32       "I32u"
-#define PRIx32       "I32x"
-#define PRIX32       "I32X"
-#define PRIoLEAST32  "I32o"
-#define PRIuLEAST32  "I32u"
-#define PRIxLEAST32  "I32x"
-#define PRIXLEAST32  "I32X"
-#define PRIoFAST32   "I32o"
-#define PRIuFAST32   "I32u"
-#define PRIxFAST32   "I32x"
-#define PRIXFAST32   "I32X"
-
-#define PRIo64       "I64o"
-#define PRIu64       "I64u"
-#define PRIx64       "I64x"
-#define PRIX64       "I64X"
-#define PRIoLEAST64  "I64o"
-#define PRIuLEAST64  "I64u"
-#define PRIxLEAST64  "I64x"
-#define PRIXLEAST64  "I64X"
-#define PRIoFAST64   "I64o"
-#define PRIuFAST64   "I64u"
-#define PRIxFAST64   "I64x"
-#define PRIXFAST64   "I64X"
-
-#define PRIoMAX     "I64o"
-#define PRIuMAX     "I64u"
-#define PRIxMAX     "I64x"
-#define PRIXMAX     "I64X"
-
-#define PRIoPTR     "Io"
-#define PRIuPTR     "Iu"
-#define PRIxPTR     "Ix"
-#define PRIXPTR     "IX"
-
-// The fscanf macros for signed integers are:
-#define SCNd8       "d"
-#define SCNi8       "i"
-#define SCNdLEAST8  "d"
-#define SCNiLEAST8  "i"
-#define SCNdFAST8   "d"
-#define SCNiFAST8   "i"
-
-#define SCNd16       "hd"
-#define SCNi16       "hi"
-#define SCNdLEAST16  "hd"
-#define SCNiLEAST16  "hi"
-#define SCNdFAST16   "hd"
-#define SCNiFAST16   "hi"
-
-#define SCNd32       "ld"
-#define SCNi32       "li"
-#define SCNdLEAST32  "ld"
-#define SCNiLEAST32  "li"
-#define SCNdFAST32   "ld"
-#define SCNiFAST32   "li"
-
-#define SCNd64       "I64d"
-#define SCNi64       "I64i"
-#define SCNdLEAST64  "I64d"
-#define SCNiLEAST64  "I64i"
-#define SCNdFAST64   "I64d"
-#define SCNiFAST64   "I64i"
-
-#define SCNdMAX     "I64d"
-#define SCNiMAX     "I64i"
-
-#ifdef _WIN64 // [
-#  define SCNdPTR     "I64d"
-#  define SCNiPTR     "I64i"
-#else  // _WIN64 ][
-#  define SCNdPTR     "ld"
-#  define SCNiPTR     "li"
-#endif  // _WIN64 ]
-
-// The fscanf macros for unsigned integers are:
-#define SCNo8       "o"
-#define SCNu8       "u"
-#define SCNx8       "x"
-#define SCNX8       "X"
-#define SCNoLEAST8  "o"
-#define SCNuLEAST8  "u"
-#define SCNxLEAST8  "x"
-#define SCNXLEAST8  "X"
-#define SCNoFAST8   "o"
-#define SCNuFAST8   "u"
-#define SCNxFAST8   "x"
-#define SCNXFAST8   "X"
-
-#define SCNo16       "ho"
-#define SCNu16       "hu"
-#define SCNx16       "hx"
-#define SCNX16       "hX"
-#define SCNoLEAST16  "ho"
-#define SCNuLEAST16  "hu"
-#define SCNxLEAST16  "hx"
-#define SCNXLEAST16  "hX"
-#define SCNoFAST16   "ho"
-#define SCNuFAST16   "hu"
-#define SCNxFAST16   "hx"
-#define SCNXFAST16   "hX"
-
-#define SCNo32       "lo"
-#define SCNu32       "lu"
-#define SCNx32       "lx"
-#define SCNX32       "lX"
-#define SCNoLEAST32  "lo"
-#define SCNuLEAST32  "lu"
-#define SCNxLEAST32  "lx"
-#define SCNXLEAST32  "lX"
-#define SCNoFAST32   "lo"
-#define SCNuFAST32   "lu"
-#define SCNxFAST32   "lx"
-#define SCNXFAST32   "lX"
-
-#define SCNo64       "I64o"
-#define SCNu64       "I64u"
-#define SCNx64       "I64x"
-#define SCNX64       "I64X"
-#define SCNoLEAST64  "I64o"
-#define SCNuLEAST64  "I64u"
-#define SCNxLEAST64  "I64x"
-#define SCNXLEAST64  "I64X"
-#define SCNoFAST64   "I64o"
-#define SCNuFAST64   "I64u"
-#define SCNxFAST64   "I64x"
-#define SCNXFAST64   "I64X"
-
-#define SCNoMAX     "I64o"
-#define SCNuMAX     "I64u"
-#define SCNxMAX     "I64x"
-#define SCNXMAX     "I64X"
-
-#ifdef _WIN64 // [
-#  define SCNoPTR     "I64o"
-#  define SCNuPTR     "I64u"
-#  define SCNxPTR     "I64x"
-#  define SCNXPTR     "I64X"
-#else  // _WIN64 ][
-#  define SCNoPTR     "lo"
-#  define SCNuPTR     "lu"
-#  define SCNxPTR     "lx"
-#  define SCNXPTR     "lX"
-#endif  // _WIN64 ]
-
-#endif // __STDC_FORMAT_MACROS ]
-
-// 7.8.2 Functions for greatest-width integer types
-
-// 7.8.2.1 The imaxabs function
-#define imaxabs _abs64
-
-// 7.8.2.2 The imaxdiv function
-
-// This is modified version of div() function from Microsoft's div.c found
-// in %MSVC.NET%\crt\src\div.c
-#ifdef STATIC_IMAXDIV // [
-static
-#else // STATIC_IMAXDIV ][
-_inline
-#endif // STATIC_IMAXDIV ]
-imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
-{
-   imaxdiv_t result;
-
-   result.quot = numer / denom;
-   result.rem = numer % denom;
-
-   if (numer < 0 && result.rem > 0) {
-      // did division wrong; must fix up
-      ++result.quot;
-      result.rem -= denom;
-   }
-
-   return result;
-}
-
-// 7.8.2.3 The strtoimax and strtoumax functions
-#define strtoimax _strtoi64
-#define strtoumax _strtoui64
-
-// 7.8.2.4 The wcstoimax and wcstoumax functions
-#define wcstoimax _wcstoi64
-#define wcstoumax _wcstoui64
-
-
-#endif // _MSC_INTTYPES_H_ ]
diff --git a/thirdparty/msvc/stdbool.h b/thirdparty/msvc/stdbool.h
deleted file mode 100644 (file)
index 99a735d..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007-2010 VMware, Inc.
- * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- **************************************************************************/
-
-#ifndef _STDBOOL_H_
-#define _STDBOOL_H_
-
-#ifndef __cplusplus
-
-#define false   0
-#define true    1
-#define bool    _Bool
-
-/* For compilers that don't have the builtin _Bool type. */
-#if defined(_MSC_VER) || (__STDC_VERSION__ < 199901L && __GNUC__ < 3)
-typedef unsigned char _Bool;
-#endif
-
-#endif /* !__cplusplus */
-
-#define __bool_true_false_are_defined   1
-
-#endif /* !_STDBOOL_H_ */
diff --git a/thirdparty/msvc/stdint.h b/thirdparty/msvc/stdint.h
deleted file mode 100644 (file)
index d02608a..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-// ISO C9x  compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006-2008 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
-//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#ifdef __cplusplus
-extern "C" {
-#endif
-#  include <wchar.h>
-#ifdef __cplusplus
-}
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-#     define _W64 __w64
-#  else
-#     define _W64
-#  endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-
-// Visual Studio 6 and Embedded Visual C++ 4 doesn't
-// realize that, e.g. char has the same size as __int8
-// so we give up on __intX for them.
-#if (_MSC_VER < 1300)
-   typedef signed char       int8_t;
-   typedef signed short      int16_t;
-   typedef signed int        int32_t;
-   typedef unsigned char     uint8_t;
-   typedef unsigned short    uint16_t;
-   typedef unsigned int      uint32_t;
-#else
-   typedef signed __int8     int8_t;
-   typedef signed __int16    int16_t;
-   typedef signed __int32    int32_t;
-   typedef unsigned __int8   uint8_t;
-   typedef unsigned __int16  uint16_t;
-   typedef unsigned __int32  uint32_t;
-#endif
-typedef signed __int64       int64_t;
-typedef unsigned __int64     uint64_t;
-
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t    int_least8_t;
-typedef int16_t   int_least16_t;
-typedef int32_t   int_least32_t;
-typedef int64_t   int_least64_t;
-typedef uint8_t   uint_least8_t;
-typedef uint16_t  uint_least16_t;
-typedef uint32_t  uint_least32_t;
-typedef uint64_t  uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t    int_fast8_t;
-typedef int16_t   int_fast16_t;
-typedef int32_t   int_fast32_t;
-typedef int64_t   int_fast64_t;
-typedef uint8_t   uint_fast8_t;
-typedef uint16_t  uint_fast16_t;
-typedef uint32_t  uint_fast32_t;
-typedef uint64_t  uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
-   typedef signed __int64    intptr_t;
-   typedef unsigned __int64  uintptr_t;
-#else // _WIN64 ][
-   typedef _W64 signed int   intptr_t;
-   typedef _W64 unsigned int uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t   intmax_t;
-typedef uint64_t  uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN     ((int8_t)_I8_MIN)
-#define INT8_MAX     _I8_MAX
-#define INT16_MIN    ((int16_t)_I16_MIN)
-#define INT16_MAX    _I16_MAX
-#define INT32_MIN    ((int32_t)_I32_MIN)
-#define INT32_MAX    _I32_MAX
-#define INT64_MIN    ((int64_t)_I64_MIN)
-#define INT64_MAX    _I64_MAX
-#define UINT8_MAX    _UI8_MAX
-#define UINT16_MAX   _UI16_MAX
-#define UINT32_MAX   _UI32_MAX
-#define UINT64_MAX   _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN    INT8_MIN
-#define INT_LEAST8_MAX    INT8_MAX
-#define INT_LEAST16_MIN   INT16_MIN
-#define INT_LEAST16_MAX   INT16_MAX
-#define INT_LEAST32_MIN   INT32_MIN
-#define INT_LEAST32_MAX   INT32_MAX
-#define INT_LEAST64_MIN   INT64_MIN
-#define INT_LEAST64_MAX   INT64_MAX
-#define UINT_LEAST8_MAX   UINT8_MAX
-#define UINT_LEAST16_MAX  UINT16_MAX
-#define UINT_LEAST32_MAX  UINT32_MAX
-#define UINT_LEAST64_MAX  UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN    INT8_MIN
-#define INT_FAST8_MAX    INT8_MAX
-#define INT_FAST16_MIN   INT16_MIN
-#define INT_FAST16_MAX   INT16_MAX
-#define INT_FAST32_MIN   INT32_MIN
-#define INT_FAST32_MAX   INT32_MAX
-#define INT_FAST64_MIN   INT64_MIN
-#define INT_FAST64_MAX   INT64_MAX
-#define UINT_FAST8_MAX   UINT8_MAX
-#define UINT_FAST16_MAX  UINT16_MAX
-#define UINT_FAST32_MAX  UINT32_MAX
-#define UINT_FAST64_MAX  UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-#  define INTPTR_MIN   INT64_MIN
-#  define INTPTR_MAX   INT64_MAX
-#  define UINTPTR_MAX  UINT64_MAX
-#else // _WIN64 ][
-#  define INTPTR_MIN   INT32_MIN
-#  define INTPTR_MAX   INT32_MAX
-#  define UINTPTR_MAX  UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN   INT64_MIN
-#define INTMAX_MAX   INT64_MAX
-#define UINTMAX_MAX  UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-#  define PTRDIFF_MIN  _I64_MIN
-#  define PTRDIFF_MAX  _I64_MAX
-#else  // _WIN64 ][
-#  define PTRDIFF_MIN  _I32_MIN
-#  define PTRDIFF_MAX  _I32_MAX
-#endif  // _WIN64 ]
-
-#define SIG_ATOMIC_MIN  INT_MIN
-#define SIG_ATOMIC_MAX  INT_MAX
-
-#ifndef SIZE_MAX // [
-#  ifdef _WIN64 // [
-#     define SIZE_MAX  _UI64_MAX
-#  else // _WIN64 ][
-#     define SIZE_MAX  _UI32_MAX
-#  endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-#  define WCHAR_MIN  0
-#endif  // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-#  define WCHAR_MAX  _UI16_MAX
-#endif  // WCHAR_MAX ]
-
-#define WINT_MIN  0
-#define WINT_MAX  _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val)  val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val)  val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-#define INTMAX_C   INT64_C
-#define UINTMAX_C  UINT64_C
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-
-#endif // _MSC_STDINT_H_ ]
index 512efc83ef33629a5a7cc9bdf4fb96f68fa260fc..f142371af94d433086aeed869da2fa6b26415c7f 100644 (file)
@@ -27,4 +27,13 @@ set (qjson_SRCS
     #serializerrunnable.cpp
 )
 
-add_library (qjson_bundled STATIC ${qjson_SRCS} ${qjson_MOC_SRCS})
+add_library (qjson_bundled STATIC EXCLUDE_FROM_ALL
+    ${qjson_SRCS}
+    ${qjson_MOC_SRCS}
+)
+
+install (
+    FILES COPYING.lib
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-qjson.txt
+)
index 9bbecdba6d2b9971654f8a7bb706ea702c252626..25281a6b981cbadb818dced2f75dec654582c011 100644 (file)
@@ -8,7 +8,7 @@ if (CMAKE_COMPILER_IS_GNUCXX)
     add_definitions (-Wno-unused-function)
 endif ()
 
-add_library (snappy_bundled STATIC
+add_library (snappy_bundled STATIC EXCLUDE_FROM_ALL
     snappy.cc
     snappy-sinksource.cc
     snappy-stubs-internal.cc
@@ -18,3 +18,9 @@ add_library (snappy_bundled STATIC
 set_target_properties (snappy_bundled PROPERTIES
     COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
 )
+
+install (
+    FILES COPYING
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-snappy.txt
+)
index b1e953d12bac221e6da86380bc4221c9129dd02a..3cf970ee552ff2331a97396106801856ee0770b2 100644 (file)
@@ -9,7 +9,7 @@ else ()
     add_definitions (-DHAVE_UNISTD_H)
 endif ()
 
-add_library (z_bundled STATIC
+add_library (z_bundled STATIC EXCLUDE_FROM_ALL
     adler32.c
     compress.c
     crc32.c
@@ -30,3 +30,9 @@ add_library (z_bundled STATIC
 set_target_properties (z_bundled PROPERTIES
     COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}"
 )
+
+install (
+    FILES README
+    DESTINATION ${DOC_INSTALL_DIR}
+    RENAME LICENSE-zlib.txt
+)
index fd2c8f5303fc759c7712f03cdef8c235f7bc3e0c..9ce3aad08f802144c7ec3ebf7441b0b051aa9c82 100644 (file)
@@ -77,8 +77,7 @@ if __name__ == '__main__':
     print '#include "trace_writer_local.hpp"'
     print '#include "os.hpp"'
     print
-    print '#include <windows.h>'
-    print '#include <d3d8.h>'
+    print '#include "d3d8imports.hpp"'
     print '#include "d3d8size.hpp"'
     print '#include "d3d9shader.hpp"'
     print
index ef4a458187a563baae061546338ba87d408475dc..0ecaed254217ad23c54af84a9043cba3c40cbd4e 100644 (file)
@@ -42,6 +42,36 @@ class D3DCommonTracer(DllTracer):
             print '    DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size)
             return
 
+        # Serialize the swapchain dimensions
+        if function.name == 'CreateSwapChain' and arg.name == 'pDesc' \
+           or arg.name == 'pSwapChainDesc':
+            print r'    DXGI_SWAP_CHAIN_DESC *_pSwapChainDesc = NULL;'
+            print r'    DXGI_SWAP_CHAIN_DESC _SwapChainDesc;'
+            print r'    if (%s) {' % arg.name
+            print r'        _SwapChainDesc = *%s;' % arg.name
+            if function.name != 'CreateSwapChain' or not self.interface.name.endswith('DWM'):
+                # Obtain size from the window
+                print r'        RECT _rect;'
+                print r'        if (GetClientRect(%s->OutputWindow, &_rect)) {' % arg.name
+                print r'            if (%s->BufferDesc.Width == 0) {' % arg.name
+                print r'                _SwapChainDesc.BufferDesc.Width = _rect.right  - _rect.left;'
+                print r'            }'
+                print r'            if (%s->BufferDesc.Height == 0) {' % arg.name
+                print r'                _SwapChainDesc.BufferDesc.Height = _rect.bottom - _rect.top;'
+                print r'            }'
+                print r'        }'
+            else:
+                # Obtain size from the output
+                print r'        DXGI_OUTPUT_DESC _OutputDesc;'
+                print r'        if (SUCCEEDED(pOutput->GetDesc(&_OutputDesc))) {'
+                print r'            _SwapChainDesc.BufferDesc.Width  = _OutputDesc.DesktopCoordinates.right  - _OutputDesc.DesktopCoordinates.left;'
+                print r'            _SwapChainDesc.BufferDesc.Height = _OutputDesc.DesktopCoordinates.bottom - _OutputDesc.DesktopCoordinates.top;'
+                print r'        }'
+            print r'        _pSwapChainDesc = &_SwapChainDesc;'
+            print r'    }'
+            self.serializeValue(arg.type, '_pSwapChainDesc')
+            return
+
         DllTracer.serializeArgValue(self, function, arg)
     
     def enumWrapperInterfaceVariables(self, interface):
index 4ee9373439f9baa3fba04844a8599fd48b61dd81..853a4bc36ec81d192ab70f28814fa81a28d5d827 100644 (file)
@@ -298,12 +298,7 @@ class GlTracer(Tracer):
         print '    switch (pname) {'
         for function, type, count, name in glparams.parameters:
             if type is not None:
-                print '    case %s: return %u;' % (name, count)
-        print '    case GL_COMPRESSED_TEXTURE_FORMATS: {'
-        print '            GLint num_compressed_texture_formats = 0;'
-        print '            _glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
-        print '            return num_compressed_texture_formats;'
-        print '        }'
+                print '    case %s: return %s;' % (name, count)
         print '    default:'
         print r'        os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
         print '        return 1;'
index 68bda100354db46025c678618d3d66f2a9d6749e..031b5cceb431155a480eebc1d0dd2dd84fde7a8c 100644 (file)
@@ -94,7 +94,7 @@ static bool _releaseContext(context_ptr_t ctx)
  */
 bool releaseContext(uintptr_t context_id)
 {
-    bool res;
+    bool res = false;
 
     context_map_mutex.lock();
     /*
index de020869db76089b3abc2caefbbb7e0139fc736a..61a2cb95fcf8249c13719464a36bee5891f8f76a 100644 (file)
@@ -493,6 +493,8 @@ class Tracer:
             for arg in function.args:
                 if not arg.output:
                     self.unwrapArg(function, arg)
+            for arg in function.args:
+                if not arg.output:
                     self.serializeArg(function, arg)
             print '    trace::localWriter.endEnter();'
         self.invokeFunction(function)
@@ -564,9 +566,6 @@ class Tracer:
     def wrapRet(self, function, instance):
         self.wrapValue(function.type, instance)
 
-    def unwrapRet(self, function, instance):
-        self.unwrapValue(function.type, instance)
-
     def needsWrapping(self, type):
         visitor = WrapDecider()
         visitor.visit(type)
@@ -697,6 +696,8 @@ class Tracer:
         for arg in method.args:
             if not arg.output:
                 self.unwrapArg(method, arg)
+        for arg in method.args:
+            if not arg.output:
                 self.serializeArg(method, arg)
         print '    trace::localWriter.endEnter();'